Case studyReliance Jewels · Design System

Rebuilt a design system so we could design with AI

Reliance Jewels is a jewellery chain, part of India's largest retailer. Our design team wanted to work with AI. We could not, because our design system was a page of swatches with no rules and no reasons in it. So I rebuilt it to hold the reasons. That turned out to be the same thing the engineers had been waiting for.

What it is
The design system behind a jewellery storefront
What I owned
The whole rebuild, from the audit to the docs site
Who it was for
Our designers first, then the engineers building from it
What changed
A brief now becomes a finished screen the same day
The live documentation site. Every swatch, specimen and component on it renders from the .less token files.
The live documentation site. Every swatch, specimen and component on it renders from the .less token files.
The 30-second version
Problem
We wanted to design with AI and we could not. Our design system had no reasons in it. One Figma page of swatches and two typefaces, no rule for when to use which. A new designer could not build from it and neither could a model. The engineers had quietly stopped following it too.
My move
Rewrote the system so every value carries its reason: what it is, when to use it, what never to do with it. Then I asked the frontend team what format they actually needed, and built it in that. 1552 named values and 45 components, each one shipped with its spec, its code, its docs and its Figma in step.
Outcome
A brief now becomes a designed, on-system screen the same day instead of the same fortnight. Engineering builds from the same file, because following the system is finally faster than working around it.
Learning
I started this as a design-team problem and it was never only that. The day I asked the engineers what the old system cost them, the whole architecture changed.
A design system with no reasons in it cannot be followed. Not by a new designer, and not by a machine.

The line the whole rebuild came out of

02Context

We wanted to design with AI. The system would not let us.

A model can only build from a system that says why. Ours only said what.

A jewellery store carries unusual weight online. Nobody impulse-buys a ₹2 lakh necklace. They research, they visit a showroom, they come back a week later. The site has to extend the showroom and never once feel cheaper than it.

Our team had started using AI to draft screens. It was fast and it was useless. Everything it gave back looked like a generic dashboard, because we had nothing to point it at that described how a Reliance Jewels screen is supposed to behave.

That is when the design system stopped being a tidy-up job and became the actual problem. A model needs the same thing a new designer needs on their first week: not a swatch, but the reason behind the swatch.

03Problem

One Figma page, and not a single reason on it

It could not answer “why” for one value on it. Meanwhile the page where people actually spend money scored 1/5, and both teams had quietly stopped opening the thing meant to hold it together.

The design system I inherited was a single Figma frame titled Brand Guidelines. It looks tidy. Look closer and there is nothing to build from:

123
  1. 1Two typefaces shown as specimens. No scale, no sizes, no rule for when either is used.
  2. 2Colour as decoration: two wheels with no token names, no roles, no contrast pairs.
  3. 3This one page is the entire system. Zero interaction states documented anywhere.

A poster can't hold a product together. I walked all nine live surfaces and scored each on two passes, functional and emotional. On a trust product, the emotional score is the one that matters, and the product page, the screen where a wedding budget becomes a decision, scored 1/5:

123
  1. 1SKU code (“18K-S-RING”) shown where the product name belongs.
  2. 2A price-breakup table where every value is a dash.
  3. 3Buy Now and Add to Cart hierarchy inverted. No occasion, no story.
Two My Account layouts, live at the same time on the same site. Drift, not design.
Two My Account layouts, live at the same time on the same site. Drift, not design.

On a jewellery store, inconsistency reads as carelessness, and carelessness is the one thing a lakhs-spending buyer can't forgive.

Then the part I was slow to see. This was not a system that had never been finished. It was a system that had been abandoned, by both the people it was meant to serve.

The engineers had stopped following it at code level. We were deviating from it in Figma. Two teams walking away from the same document, and nobody saying so out loud, because from either side it just looked like the other one had moved.

It stayed that way because the design team could not see the technical reasons it was failing. You cannot fix what you cannot see, and I could not see it from inside Figma. So for a long time there was nothing anyone could put on a roadmap. The system was not broken and being repaired. It was broken and being routed around.

04Process · the turn

Then I asked the engineers what they needed it in

The format that made the system readable by a model was the same one their build already used. I was solving two problems and only knew about one.

I had to pick a format to write all this down in, and I did not want to pick it from taste. So I asked the people who would have to build from it.

What came back was not a list of preferences, it was a cost. The storefront runs on Vue 2 and a commerce platform called Fynd, which builds its styles from Less files. A design system in any other format is something an engineer translates by hand, every time, on every component. They had never rejected the old system. They had worked out that following it was slower than ignoring it.

I wrote the questions. The engineers wrote the answers. I could not diagnose their side of this, but I could work out what I needed to know, so I put together a questionnaire aimed at the gaps and asked the RJ frontend team to fill it in. Their answers are the most useful document in the project, and none of the content is mine.

Here is the part I did not expect. The thing that makes a system readable by a model and the thing that makes it cheap for an engineer are the same thing: every value named, in one place, with the reason attached. I had started this so our designers could work faster. It turned out to be the fix for a problem the engineers had stopped complaining about.

Once that was the brief, most of the architecture stopped being a matter of taste.

Figma audit · mine

The old components were built to “good enough”: hard-coded hex, raw pixels, zero variable bindings. The first job was an architecture, not a reskin.

Product audit · mine

Nine live surfaces walked and scored twice, functional then emotional. The failures became the component priority order, transaction-critical first.

Engineering audit · my questions, their answers

A questionnaire I wrote for the gaps, filled in by the RJ frontend team. It decided the token format on the spot: Less variables, because that is what their build already consumes.

The audit documents as written: page-by-page Figma findings, the two-pass product audit, and the engineering Q&A the RJ frontend team answered.
The audit documents as written: page-by-page Figma findings, the two-pass product audit, and the engineering Q&A the RJ frontend team answered.

Every value has to earn its place. If you cannot say why, it does not ship.

That one rule is what later made the system machine-readable.

05Decisions · taste with reasons

The calls that gave the system its character

Not a component library with a coat of paint: type, colour, depth and motion were each re-decided against the brand's emotional framework.

Decision 01

Make the .less file the single source of truth

The last system did not die of bad taste. It died the day its docs drifted from its code, and after that nobody had a reason to open it. So I removed the possibility. A build script parses every token file, resolves the alias chain and emits the JSON and CSS that drive the live docs site. Figma variable names mirror the .less names. The spec, the docs, the code and the design tool cannot silently disagree, because there is only one of them now and the rest are generated from it.

One name in three places: the .less source, the docs site and the Figma variables. Change the .less and the other two follow.
One name in three places: the .less source, the docs site and the Figma variables. Change the .less and the other two follow.
Decision 02

Two type voices where there was one

The old system set everything in sans. Jewellery needs ceremony, so the rebuild pairs Cormorant Garamond for display moments with JioType Var for UI and body. The pairing has guardrails born from real misuse: numerals never render in the serif, because its figures read badly at UI sizes, and the display face stays scarce so it still feels special when it appears.

The pairing and its rules on the live docs site: where each family is allowed, and why every number is set in the sans.
The pairing and its rules on the live docs site: where each family is allowed, and why every number is set in the sans.
Decision 03

A colour language per persona, without touching the core

Maroon and gold could not stretch to every audience the brand serves. So each sub-brand gets its own family that extends the core system instead of modifying it: Vivaham's bridal rouge, NITARA's contemporary teal, Bella's everyday sage, Mahalaya's festive ochre. Each is a five-tint primitive ramp with its own primary, surface and accent semantics, rendered from the same token pipeline as everything else.

Sub-brand colours on the docs site: a visual language per persona, built on the same primitive ramp discipline as the core.
Sub-brand colours on the docs site: a visual language per persona, built on the same primitive ramp discipline as the core.
Decision 04

Depth where the product was flat: gradient, motif, material, motion

The live product was flat in every sense. The rebuild adds a depth layer with jewellery restraint: a gradient system where gold shimmers like foil and most surfaces stay flat, a motif vocabulary (the sparkle, the deco corner, the RJ crest) that is geometric because the luxury of jewellery is precision, glass and grain as tokenised surface treatments, and motion that is delicate and quick. Nothing bounces.

The depth layer on the docs site: the restrained gradient system, the motif vocabulary and the material treatments, each rendered from its token file.
The depth layer on the docs site: the restrained gradient system, the motif vocabulary and the material treatments, each rendered from its token file.
Motion taste in a working component: the select opens with the system's easing. Delicate, quick, no bounce.

Motion rules live in the same token files as colour: durations and easings are named values, so “smooth and delicate” is not a vibe, it is a spec a component either honours or fails.

Decision 05

One language for “selected”, one voice for icons

“This is selected” now has exactly one vocabulary across all 45 components: the maroon fill with a drawn check, the maroon left-border, the maroon underline. Icons are Phosphor instances from the system, Light by default, Fill only to mean active or saved. And because JioType Var has no semibold, the system bans faking one. The drift I started the audit with is now structurally impossible.

The quick filter live on the docs site: selected takes the maroon fill with a drawn check. Hallmarked is disabled because nothing matches it.
The quick filter live on the docs site: selected takes the maroon fill with a drawn check. Hallmarked is disabled because nothing matches it.
06Decisions · the check

Nothing is finished until a script says it is

Design systems rot because 'done' is a matter of opinion. So I gave it a definition. Every component ships four ways: a written spec, its code, a live page you can click, and a Figma component. Then a script runs on every change and fails the build if those four have drifted apart. Nobody has to remember to check, which is the only reason it is still true months later.
45/45
Components passing that check today
1552
Named values every screen shares
0
Colours typed in by hand instead of named
48px
Touch floor, even when the control looks smaller

Don't take the spec's word for it. These three components are rebuilt right here from the system's own token values: the maroon, the cream, the radius, the 48px targets, the all-caps labels. Hover, press, toggle the state.

JioType is proprietary, so these demos substitute a stand-in sans

Live · rebuilt from the token files · press things
1
Twelve of the 45, exactly as they render on the live docs site: buttons, inputs, search, filters, toasts, the slider, cards, the GSS chart, product-card states, the price breakup, ratings, the checkout stepper.
Twelve of the 45, exactly as they render on the live docs site: buttons, inputs, search, filters, toasts, the slider, cards, the GSS chart, product-card states, the price breakup, ratings, the checkout stepper.
07Proof · flows

Then I caught myself making the same thing again

Excellent documentation is not a design system. It is exactly what the last one was.

Mid-project I wrote a critique of my own work. One line of it stopped the build:

The documentation is excellent. The design system does not exist yet.

From the critique I wrote against my own work, mid-project.

Which is, word for word, the thing I had spent three audits diagnosing. A beautiful document nobody builds from. I was on my way to handing the frontend team a better-looking version of the artefact they had already abandoned once.

So I stopped making parts and started making sentences. The homepage, discovery, the product page and the cart, rebuilt entirely from documented components, on desktop and the mobile web. If the system could not compose its own storefront, it was not done.

The homepage flow, scrolling live on the docs site: navigation, the gold-rate ticker, category pictograms, curated collections. Every element is a documented component.
The purchase journey end to end: the listing, the full product page with price breakup and delivery check, the bag and the confirmation. Composed from system parts, nothing improvised.
The purchase journey end to end: the listing, the full product page with price breakup and delivery check, the bag and the confirmation. Composed from system parts, nothing improvised.
Done means every state designed: out of stock routes to the showroom, unserviceable pincode, size guide, disabled variant.
Done means every state designed: out of stock routes to the showroom, unserviceable pincode, size guide, disabled variant.
Checkout on the mobile web, where most RJ customers actually are: delivery details, OTP, save and continue.

Mobile is not a variant here, it is the primary surface. The system's base CSS is mobile, the touch floor is 48px, and the flows were rebuilt phone-first before the desktop frames existed.

08Proof · the bar

Two bars every screen has to clear. I published my own failing score.

I scored my own flows on the same bars and published the 2.4, with the fix plan attached.

Before any flow counts as done it runs two written checks. The UX bar goes first: feature parity, every state designed, accessibility. Then the luxury bar, eight tests of restraint and finish that end with one question: would this sit beside Cartier without apology? Both live in the governance folder as specs, not as taste in someone's head.

The bars as written: the quality gate spec and the luxury bar's eight tests, straight from the governance folder.
The bars as written: the quality gate spec and the luxury bar's eight tests, straight from the governance folder.

Components are the vocabulary. Flows are the sentences. So I scored my own rebuilt journeys on those bars and published the scorecard with the weak numbers in it: my product-page flow scored 2.4 on UX. I wrote the fix plan in priority order rather than hiding the gap.

I published the 2.4 because a bar you can quietly lower isn't a bar.

Flow audit · 22 Jun 2026

1–5 · below 4 = fix before done

FlowUXUIVerdict
Homepage4.14.4good, parity gaps
Discover (PLP)3.44.2needs work
Consider (PDP)2.44.3major rework
Add to cart3.34.2needs work
Checkout3.34.2needs work
Confirmed4.44.5strong
Autopay setup3.23.0needs work
Return journey3.23.0needs work

Published with the fix plan, sequenced PDP-first

09Proof · the machine-readable layer

Three files that let a model build a real screen

This is what the rebuild was aiming at from the start. Because every value had to be named and reasoned before it shipped, the finished system could be handed to a model as easily as to an engineer. I delivered that as three files, then ran the result back through the same check that polices my own work.
manifest.json

The whole system in one generated file: token groups, all 45 components with problems, variants, states and rules. Regenerates on every build, so it never drifts.

11 hard constraints

Explicit, checkable rules carried inside the manifest. They are listed below, in full.

Generation prompt

Tells a model to reuse before creating, use only tokens, honour the one active language, and flag a missing token instead of inlining a literal.

  1. 01No hex, no raw pixel, no hard-coded string in any component. Every value references a token.
  2. 02Three tiers: components reference semantics, semantics reference primitives. Components never touch a primitive.
  3. 03The .less file is the single source of truth. Figma variable names match the .less names.
  4. 04JioType Var has no semibold. Medium instead, always.
  5. 05Icons come from the DS Phosphor set: Light by default, Fill for active. Never a text glyph or a CSS-drawn shape.
  6. 06The maroon active language is one system across every component.
  7. 07Every component documents all its states. No half-built states ship.
  8. 08Touch targets stay at least 48px, even when the visible control is smaller.
  9. 09Indian English everywhere. One price format. No em-dashes. No Oxford comma.
  10. 10Cormorant Garamond owns display moments. JioType Var owns body, UI and every numeral.
  11. 11Components compose components: any reusable inner element comes from the system, never rebuilt inline.
The machine-facing layer is a page on the same site: the generated manifest with the live token and component counts, the constraints and the generation prompt.
The machine-facing layer is a page on the same site: the generated manifest with the live token and component counts, the constraints and the generation prompt.
manifestmodel assemblesnpm run evalproof it stayed in the system
I did not automate design. The machine assembles; the human still decides what is worth assembling and whether the result is good.
10Proof · what it unlocked

What we set out to do in the first place

A brief goes in. Flows, screens, a prototype and the documentation come back the same day, all of it on-system.

This is the part the whole rebuild was for. Once every value carried its reason, we could point a model at the system and trust what came back.

A brief lands
  1. 01

    Flows and edge cases

    The states nobody thought to ask about, drafted the same day.

  2. 02

    Screens, already on-system

    Right colours, right spacing, right components. Nothing to clean up.

  3. 03

    A prototype that behaves

    Motion and real states, so people react to it instead of imagining it.

  4. 04

    Docs back in Figma

    The work writes itself into the library, so the system stays current.

every one of them reads from

The design system: 1552 named values and 45 components, each one carrying the reason it exists

Not yet

The same system pushes code we can merge ourselves. That is the goal and it is not built yet.

The fourth box is the one I would defend hardest. Plenty of people can show you a screen a model made. Almost nobody sends it back into the design file afterwards, so their documentation is stale a week later and the next designer is guessing again. That loop is the difference between a demo and a system.

Work that used to run in weeks now runs in hours, alignment meetings included. I have never instrumented that properly, because nobody here was measuring design timelines in the first place, so I will describe it and leave the percentage off.

11Outcome

Both teams are using it, which is the part that was never true before

Designers get a finished screen the same day. Engineers build from the same file, because following it is now the fast path.

Product and engineering are both adopting the system. The old one had a typeface page and a colour wheel and nobody opening it. This one gets opened because it is quicker than not opening it, which is the only reason any system survives.

What exists now: 45 components, 1552 named values shared by every screen, a documentation site that rebuilds itself from the code, a Figma library on the same names, and the storefront's main journeys rebuilt from those parts as proof. One change in one file reaches every screen, so the system is safe to change rather than safe to admire.

Some of it I deliberately did not finish. I held the line on naming, states and accessibility, and accepted good enough on visual flourish so the thing could ship. Knowing where not to gold-plate is part of the job.

8/10 polish, 10/10 fundamentalsFigma deferred to a later batchDocs as a site, not Figma pagesShipped my own 2.4

The system is built and gated. It has not yet been rolled out across the live store; rollout is the next phase.

12Learning

What I'd do differently

The conversation with the engineers should have been the first thing I did, not the thing I arrived at.

The thing I would change is at the start, not the end. I spent the opening stretch of this treating a design system as a design deliverable, and scoring the product from the buyer's side only. The people who had walked away from the old system had good reasons, and none of those reasons were visible from inside Figma. That conversation should have been week one, not the thing I eventually got round to.

The rest is unfinished business rather than regret. I would wire the quality gate into CI on the product repo from day one, so a component that breaks token discipline cannot merge. I would run adoption surface by surface against the live store instead of waiting for a big-bang rollout. And I would have the AI layer assemble a genuinely new surface end to end and count how much I correct. That correction rate is the honest score of the whole project, and I want the number.