Tathagata Sarkar

Designer

Mumbai, India

Contact

← Back to Work

A saree shop that now sells every week.

  • Developer handoff
  • Design system
  • Figma library
  • Brand identity
  • Photography
  • Storefront design

Problem

The shop sold, but its styles were typed by hand: 378 colours, 43 font sizes. Most values had no stated purpose, two text colours were hard to read, and keyboard focus could leave the filter.

Solution

I designed one token system with three layers, wrote down what each value is for, fixed contrast and focus, and gave Figma and the code the same names. Our developer built it into the shop. The token file is live. The written purposes and the contrast and focus fixes are built, not shipped.

  • +395%Orders a month, by the founder’s count, before launch vs since
  • 378 → 4Colours typed by hand
  • 206 / 206Values with a written purpose: built, not shipped
Timeline
3 months of shoots, 2–3 weeks to build
Team
Me, a project manager and a developer, with the founder
Status
Shop live · pass 2 built, not shipped · checkout waits on payments
A woman in an olive-green Anubhuti silk saree with gold zari stripes, photographed for the shop
One of the photographs I shot for the shop.

The shop sold well, but how it worked lived in our heads.

The shopAnubhuti India sells silk sarees online. I designed the brand, shot the photographs and designed the shop with the founder, and our developer built it. Orders come through the website.

The riskThe catalogue now comes from a Google Sheet the founder edits, so the shop changes without us. Its styles only made sense if you remembered why.

The shop’s collection page
Collection
A saree’s product page in the shop
Product detail
The shop’s shortlist page
Shortlist

Three of us, and one handoff.

Project managerBrought the idea, set the numbers we’d judge it by, and wrote the PRDs.

Me, product designerThe whole design, end to end: the brand, the photographs, every screen of the shop, and the design system behind it, in Figma and in the token names the code uses.

DeveloperBuilt the shop from my handoff: the screens, their specs and the tokens.

The shop looked fine.
The code didn’t.

20 October378 colours, 43 font sizes and 21 line heights were typed straight into the pages. Customers couldn’t see it. The next person would.

24 OctoberAfter the first fix, 36 of 155 values said what they were for. Timings were typed by hand 93 times, two text colours failed contrast, and focus could leave the filter.

Both code blocks are copied from the shop’s stylesheet. Red marks a value typed by hand; green marks a token. The 12px positions stayed hand-typed, and show it.
DOCUMENTATION

36 of 155

Values said what they were for.

↓206 of 206 now doEach with what it’s for and where it’s used.
MOTION

93 timings

Typed by hand.

↓0 now11 shared timings instead.
READABILITY

2 colours too faint

The muted text and the copper numbers.

4.16 → 5.22:12.68 → 4.91:1
↓9 text pairs passIn light and dark.
Keyboard auditTabbing could leave the open filter→The filter now keeps focus inside→Escape closes it and puts you back
From my audit of the code on 24 October 2026. The total grew as I added values. These are code checks, not customer research. The “now” numbers are pass 2: built, not shipped.

We fixed it in two passes, and customers saw no change.

Two rulesCustomers see no change, and checkout stays off until payments are verified.

OrderFix whatever reaches the most pages first. Write the reason for each value as it moves.

  1. The catalogue moves to a Google SheetThe founder publishes sarees without meLive
  2. Pass 1: one token file378 → 4 hand-typed coloursLive
  3. Figma libraryThe same names as the codeDone
  4. Audit36 of 155 values explainedDone
  5. Pass 2: purposes, timings, contrast, focus206 of 206 explainedBuilt, not shipped
  6. CheckoutBuilt, then switched offHeld back
Dates from the shop’s git history and my audit file.

What the system is made of

Every value lives in one file, tokens/tokens.json, with a name and a written reason.

Colour

Before378 colour values typed by hand, 35 of them different.

Now26 named colours, each with one job. Sindoor rust is the only action colour, and green belongs to WhatsApp. Every text pair is checked for contrast.

All 26 colours from the token file, then the 9 text pairs from my contrast audit. Switch to library dark to see the same pairs in the dark mode.

Type

Before43 font sizes and 21 line heights, picked page by page.

NowGilda Display for names and headings, Instrument Sans for everything you read or tap. 10 sizes, 14 roles, and headings that scale with the screen.

Every role is set in its own style, at the size the shop gives it for the width you pick.

Spacing

BeforeGaps were chosen page by page.

Now21 steps from 2px to 120px, plus 10 named gaps for sections and layout that scale with the screen.

Recorded on anubhutiindia.com. Each label is read from the stylesheet rule that sets the gap, not guessed from its size.

Corners and depth

CornersThree. Photos and layout stay square. Tags, fields and buttons get 2px. Hearts and the WhatsApp button are round.

DepthTwo shadows. One lifts menus, sheets and the quick view. A 1px ring marks the selected swatch. Nothing else floats.

Real parts, styled only with the shop’s tokens. The sheet opens at the shop’s own overlay timing, 300ms.

Icons and motion

IconsThe shop’s own stroked icons, drawn on a 24px grid. The WhatsApp logo is the one exception.

Motion11 named timings, each with a job: 100ms for a press, 300ms for a sheet. Reduced motion switches decorative movement off.

The 12 icons are copied from the shop’s templates. Each dot runs at its token’s timing.

A button asks for the action colour, not a hex code.

Three layers90 raw values, 77 meanings, 39 component values. Change the raw rust once and every button follows.

Two modesThe library also has a dark mode. Meanings swap, component names stay. The shop itself stays light.

Tap a part or any token to trace it. Every chain is read from the token file; library dark swaps the meanings, not the names.

Every component documents its states.

ComponentsButton, field, tag, product card, WhatsApp button, filter sheet and header. Each asks for meanings, never raw values.

DocsThe system library shows what each one is for, its states and the tokens behind them. The filter sheet keeps focus inside and closes on Escape.

Live parts built from the tokens. A cursor plays the states; tap or type anywhere and it stops, so you can try them yourself.
The system library, recorded: search a token, open a component’s states and usage, and read the release checks.

How the system stays in one piece.

NamingNames say what a value is for, not what it looks like: color.action.primary, never “rust”. Figma uses the same names as the code, so nothing gets lost between the two.

DocumentationEvery value has a written reason and a note on where it’s used. Each component in the system library shows what it’s for, its states and the tokens behind it.

GovernanceA release check fails if a value has no purpose, a text pair fails contrast, or a timing is typed by hand. It passes locally and ships with pass 2, so for now it’s built, not shipped.

Who uses itI work in the Figma library and our developer works in the token file, with the same names on both sides. The founder edits the catalogue in a Google Sheet and never has to touch the system.

How changes get reviewedI design the change and write down its reason, our developer builds it into the token file, and it has to pass the release check before it ships.

We built checkout,
then kept it switched off.

BuiltBag, delivery and review all work, with validation.

Held backA saree costs thousands of rupees, and a payment that fails halfway loses a small label a customer. Until payments are verified, customers order through the founder.

Bag
Checkout preview: the bag, with sample details

Quantity, price and order summary.

Delivery
Checkout preview: delivery details, with sample details

Required fields and validation.

Review
Checkout preview: order review, with sample details

Order check. Payment remains disabled.

Tap a crop to see the full screenshot.

What changed, in numbers

Live numbers are true on anubhutiindia.com today. Pass 2 is built and checked, but not shipped yet. I don’t credit all of the order growth to this work.

What I’d do differently

Write the reason down the day I make the thing.

Explaining 206 values afterwards was the slow way. Next time each value gets its note the day it’s made, and the audit only has to check.

What’s next

Watch real people shop.

I haven’t measured how long it takes to find a saree. Next: sit with a few customers as they browse, then turn on payments and measure checkout.

Appendix

How the token file reaches the shop, the library and Figma.

Codetokens.json runs through a small Python compiler into CSS variables. The shop and the system library both read them.

Figma and checksFigma uses the same names; I checked all 188 of its values against the code. A release check fails if a value has no purpose, a text pair fails contrast, or a timing is typed by hand.

One value, color.action.primary, shown at each step. The release check is written and passes locally; it ships with pass 2.

Let's talk.