Skip to content

/

Design system

One Figma and React system for KFintech’s digital products

Library templates, sample data

The KFintech Design System’s bonds dashboard template with sample data, cut by the right and bottom edges: the left half in Light and the right half in Dark, the same screen in both modes. A pencil note points at the seam: same screen, one switch, Light to Dark.The KFintech Design System’s bonds dashboard template with sample data, cut by the right and bottom edges: the left half in Light and the right half in Dark, the same screen in both modes. A pencil note points at the seam: same screen, one switch, Light to Dark.
The bonds dashboard template, split down the middle: Light on the left, Dark on the right.
In 15 secondsDesign system
Problem
KFintech, an Indian registrar (it keeps investor records), had no design system. Its investor-relations portal, KYC (identity check) registry and dashboards drew one button in at least seven heights.
My role
Self-initiated, sole designer. I set the rules and reviewed every page; AI agents did the volume work.
Key move
Colour mode, screen size, motion and sidebar state switch independently, so one screen can be Dark and Mobile.
Result
v1.0 is ready in Figma and React for KFintech’s next products. Button colours match across both in all 432 renders.
Company
KFintech
Role
Product Designer, self-initiated, sole owner
Team
Me, 4 developers, my manager reviewed
Timeline
Aug 2026 – Oct 2026
Platform
Figma library and React library
Status
v1.0, ready, not yet in a product
Built for
KFintech’s next products; current ones not decided
7 → 3primary button heights, product files vs the library
439tokens in 5 collections
10contrast defects in my own tokens, found by computing every pair
94 / 94components in React, AI-written, each checked by me
A Figma-style canvas with six frames from the KFintech Design System: the dashboard overview split into Light and Dark, selected at 1440 by 810, then the records list in Dark, the record detail, the bond application, and two phones showing a record and the assistant in Dark.A Figma-style canvas with six frames from the KFintech Design System: the dashboard overview split into Light and Dark, selected at 1440 by 810, then the records list in Dark, the record detail, the bond application, and two phones showing a record and the assistant in Dark.
From my Design System Figma file: library templates with sample data, in Light and Dark.

Shared with KFintech’s written OK. Fund-house logos and all data are placeholders. Happy to walk through the real files on a call.

Problem

I was the reference

Before this system, I was the design system. Developers asked me about everything before building it: padding, font sizes, colours, dark mode. Nothing live existed to learn from.

It showed across products, mine included. One primary button had at least seven heights and three hex values for one blue. Developers restyled MUI, their React component kit, by eye, so builds drifted further.

The goal was one set of rules for design and code, in both modes, for the products KFintech builds next. It also had to fit Indian finance data, like ₹12,40,000 (1.24 million rupees, grouped the Indian way).

One primary button, three products

IR portal#2058A6

Blue button with a plus: Add New Child Mapping, set in Arial.
32 px, radius 8, Arial
Blue button with a camera icon: Join Meeting, set in Arimo.
36 px, radius 8, Arimo
Blue button with a plus: Add New user, set in Roboto Medium.
40 px, radius 8, Roboto
Blue button with rounder corners: Upload.
44 px, radius 12, Roboto
Tall blue button with a download icon: Download recording.
48 px, radius 12, Roboto

KYC registry#2057A6

Short blue button with a pencil icon: Initiate.
28 px, radius 4, SemiBold
Wide blue button: Approve.
40 px, radius 4, SemiBold
Tall blue button with a plus: New KYC Application.
48 px, radius 4, SemiBold

Dashboards#2563EB

Brighter blue button, 56 pixels tall, with a sheet icon: Download Full Excel.
56 px, radius 12, SemiBold

The library: one token, three sizes

Three library buttons in one blue with the same corners: Export, Approve, Add application.
24 / 32 / 40 px, radius 8, color/control/primary/brand

Crops at true size from three products: the main action in seven heights. The library has three sizes.

How I worked

My rules, the agent’s hands

I owned the architecture, the rules and every visual call, and reviewed every page in both modes. AI agents did the volume: variants, token binding, docs from my specs, and contrast maths.

  1. Aug 2026Foundations. Compared my two token systems; kept the simple one.
  2. Aug–Oct 2026Components. 94 components and 8 templates, in batches.
  3. 8–10 Oct 2026v1.0. Changelog dated in the Figma file.
  4. Oct 2026React. All 94 components on MUI.
  5. 13–20 Oct 2026Parity check. Figma Button against React, both modes.

What failed

The agent invented four tokens

The agent was fast and confidently wrong. When it bound colours, it once used four token names that did not exist, each plausible at a glance. Another AI check marked five chart tokens as verified that didn’t exist either.

So I wrote a rulebook: small batches, append and never rebuild, a count report after every prompt, exact token names pasted in. No AI report counts until I’ve opened the file.

  1. 01

    Exact names

    Token names pasted from the file, never guessed.

  2. 02

    Small batch

    20 to 30 variants. Append, never rebuild.

  3. 03

    Count report

    Built versus expected, after every prompt.

  4. 04

    Check the file

    A script reads what exists, not what the agent says.

  5. 05

    My review

    Every page by eye in Light and Dark; every prototype link clicked.

The loop every build prompt went through. Drawn for this case study from my written rules.

Decision 01

Modes are separate axes

Light or dark, desktop to mobile, standard or reduced motion, sidebar open or collapsed are four independent choices. A Figma variable collection switches along only one.

So each axis got its own collection, beside one for raw values. The sidebar mode reaches content inside a component’s slots (open areas), so one switch collapses every item and saves 6 variants.

Options
Combined modes in one collection, a variant per state, or one collection per axis
I chose
One per axis, since each changes on its own.
Trade-off
Five collections to keep in sync.
The KFintech Design System’s four layers, two by two in reading order: 187 primitive values as colour ramps; 216 semantic tokens, one card shown in Light and in Dark with its token names; a sheet of components with eight named (Button, Chip, Toggle, Selection card, Field, Metric card, Alert, Stepper); and a record detail template.The KFintech Design System’s four layers, two by two in reading order: 187 primitive values as colour ramps; 216 semantic tokens, one card shown in Light and in Dark with its token names; a sheet of components with eight named (Button, Chip, Toggle, Selection card, Field, Metric card, Alert, Stepper); and a record detail template.

Independent mode axes

  • 26ResponsiveWidths, spacing, display typeDesktopTabletMobile
  • 7MotionDurations and easingStandardReduced
  • 3NavigationSidebar stateExpandedCollapsed

Because each axis is its own collection, one frame can be Dark, Mobile and Reduced motion at once.

Raw values, role tokens, components, templates. Real values, drawn for this case study; three more collections switch separately.
Animation of the 54EC bond application template: the sidebar folds to icons, the form widens, then the labels come back.Animation of the 54EC bond application template: the sidebar folds to icons, the form widens, then the labels come back.
One mode, Navigation set to Collapsed. Every sidebar item follows and the form widens; no collapsed variants exist.

Decision 02

Every rule has a number

I had every contrast ratio computed in both modes instead of judging by eye. WCAG, the accessibility standard, asks 4.5:1 for text.

Semi-transparent colours never carry text: their contrast shifts with what sits underneath. Green, yellow and teal fills take dark labels: green measures 2.91:1 with white and 6.17:1 with near-black.

The same maths found ten defects the eye missed, like input borders at 1.19:1.

Options
Spot-check screens with a contrast plugin, or compute every token pair
I chose
Compute every pair, again whenever a token moves.
Trade-off
Slower: one review meant recomputing the figures across 104 documentation frames and 7 foundation sheets.
Pair, on the page backgroundBefore (fails)FixLight now (passes)Dark now (passes)
Input border1.19:1Control-border tokens, then one step darker3.35:17.15:1
Placeholder text2.51:1A darker grey step4.72:17.15:1
Label on a green fill2.91:1 whiteDark label instead6.17:1Same rule

Computed from the token values in the library, both modes. Pass marks: 4.5:1 for text, 3:1 for edges.

Decision 03

Fewer variants, more capability

I cut variants that added count without capability. Page header has none; properties carry it from desktop to mobile. Eleven vertical tab variants with no use case went. Button keeps 216, each a real mix of type, tone, size and state.

Options
A variant per layout, or properties, slots and modes
I chose
Variants only where structure changes.
Trade-off
Properties are harder to find, so every component page has anatomy and usage frames.
The same record detail page from the KFintech Design System on a laptop at 1440 px, a tablet at 768 px and a phone at 375 px. On each, the page header is outlined with its size: 1104 by 160, 704 by 180 and 343 by 128.The same record detail page from the KFintech Design System on a laptop at 1440 px, a tablet at 768 px and a phone at 375 px. On each, the page header is outlined with its size: 1104 by 160, 704 by 180 and 343 by 128.
One page header on desktop, tablet and phone. No variants: properties and Responsive tokens do the work.

Into code

Same name in Figma and CSS

Developers asked for ready components, so the system went into React. I had never opened a code editor; it became the most fun part. Four developers set the stack and reviewed the components.

A script turns my Figma export into CSS variables with the same names, so both sides say var(--color-text-primary). I approved how tokens feed the MUI theme. An AI coding agent wrote the code; I checked every component against Figma.

Code caught something Figma missed. On inverted buttons in dark mode, the focus ring vanished. A script compared Button’s 216 variants in both modes against Storybook, the developers’ live component catalogue. The first run matched 423 of 432; the nine were that ring. After React took Figma’s dark ring, all 432 match.

Drag, or use the arrow keys
React: the Button grid rendered in Storybook, Light mode on the left and Dark mode on the right.Figma: the same Button grid built from library instances at the same positions.
Light mode, dark panelDark mode, light panel
Figma and React at the same pixels, after the focus-ring fix. Drag across: all 432 renders match.
Animation of the KYC records queue template: a pointer presses Dark on a Light and Dark control drawn for this animation, the whole screen turns dark, then Light brings it back.Animation of the KYC records queue template: a pointer presses Dark on a Light and Dark control drawn for this animation, the whole screen turns dark, then Light brings it back.
One mode switch, Light to Dark and back. The components stay the same; only the Semantic tokens change.

Dark mode

Lift surfaces, drop tints

No black shadow shows on a near-black page. So in dark mode, surfaces get lighter as they rise, and floating menus get their own border at 3.81:1.

My dashboards used tinted metric cards, because my manager likes colour. In dark mode those tints sat up to 2.2:1 off the page and glowed. I kept the library’s cards neutral; colour goes only to the change and the warning.

Before and after. Before: four metric cards from my dark Funding dashboard, each with its own tinted gradient and coloured icon: Reported 800, Ported 52, Not Ported 677, Endorsed 543. After: the same four numbers in the library’s neutral Metric cards in Dark. Pencil notes: tinted tops sit up to 2.2:1 off the page; neutral cards, a step lighter than the page. All values are sample data.Before and after. Before: four metric cards from my dark Funding dashboard, each with its own tinted gradient and coloured icon: Reported 800, Ported 52, Not Ported 677, Endorsed 543. After: the same four numbers in the library’s neutral Metric cards in Dark. Pencil notes: tinted tops sit up to 2.2:1 off the page; neutral cards, a step lighter than the page. All values are sample data.
Tints glowed on a dark page. The library card carries the same numbers on a neutral surface.
Deep dive: nine more calls from the decision log
  • Selection is never colour alone. A selected tint can sit 1.04:1 from its neighbours, too close to see. So a selected item in any set also turns semibold.
  • Intent colours, fixed. Info was yellow and warning was rust, the reverse of convention. I moved info to teal and warning to yellow. Highlight stayed violet rather than rust, because rust sits only 26° from the new yellow warning and their palest tints blurred together in tables.
  • Closing my own exception. After the first fix, field borders measured 2.51:1, under the 3:1 WCAG asks of control edges. I first documented it as a deliberate exception, then added one grey step, grey/450, and closed it at 3.35:1.
  • Brand over taste. IBM Plex Sans came out ahead in a side-by-side type comparison in my design review. I kept Roboto, because it is KFintech’s brand typeface.
  • A sign-in page that doesn’t move. My manager asked for a rotating carousel of fund-house (mutual fund company) logos on the sign-in page. Moving content needs a pause control and pulls attention from the one-time password (OTP). It would also show a fund house its competitors on its own sign-in. I proposed a still preview built from real components, and my manager agreed.
  • Charts that work without colour. Seven series colours can’t all clear 3:1 against each other: even the two most different reach only 1.49:1 in lightness. So from the second series on, bars and slices also carry a pattern. Chart bodies stay templates, because their geometry is data.
Donut chart of ₹12.4 lakh invested: Equity solid, then Debt, Hybrid, Liquid and Gold slices each with a different stripe or crosshatch pattern.
Stacked bar chart of allocation from October to March: Equity solid, Debt and Hybrid striped in opposite directions.
From the second series on, chart marks carry a pattern, so colour is never the only key.
  • Prototypes that behave like the product. A Figma component can only change itself, so clicking a second tab left the first one selected. I built a recipe on variable modes that keeps one item selected at a time, and wired 313 items across 28 template frames.
  • Two token systems, one kept. I had started a simple system (268 variables) and a three-tier one (615 tokens). The three-tier one had tokens pointing at values that didn’t exist and a radius scale where medium was smaller than small. I kept the simple one, ported what was good and archived the rest.
  • Icons chosen on licence. Untitled UI’s free tier forbids publishing a company library built on its assets, and Remix Icon moved to a custom licence in January 2026. Tabler is MIT-licensed, so the library carries 6,166 Tabler icons, each coloured by a token.
A phone showing the bond application form from the KFintech Design System, with four parts outlined and named: Progress bar, Alert, Selection card and a Field in its error state. Each part is pulled out at a larger size on the right; the alert sits on a white card.A phone showing the bond application form from the KFintech Design System, with four parts outlined and named: Progress bar, Alert, Selection card and a Field in its error state. Each part is pulled out at a larger size on the right; the alert sits on a white card.
v1.0 in one sample form: progress bar, alert, selection card and field are all library parts.

Outcome

Ready, not adopted yet

Version 1.0 isn’t in a product yet, so there’s no adoption number.

What I’d measure after rollout: questions developers bring me per screen, Figma-to-build time, and drift found in testing.

“Amandeep worked out why our designs never fully made it into the final product. He didn’t argue. He proposed a fix and gave it everything he had. What we got was a working solution, not code handed over for us to rewrite and polish.”
Senior developer, KFintech

Names left out for privacy. Happy to share references.

Deep dive: what ships beyond the components
AreaIn the library
AccessibilityEvery text, icon and border pair computed in both modes and printed in the docs; a 2px focus ring outside a 2px gap; small buttons at the 24px minimum target
Dark modeA designed elevation stack, its own floating border, state layers on the resting fill
VariantsSlots, properties and modes; variants only where structure changes
Domain₹ in Indian grouping, tabular figures, folio (an investor’s account with a fund house) and NAV (a fund’s price per unit) copy, fund-house co-branding, OTP sign-in
ChartsChart templates, patterns from the second series, a sequential ramp where every step clears 3:1
Documentation104 anatomy, layout and usage frames across 46 component pages, figures recomputed when tokens change
Design to codeIdentical token names in Figma and CSS, generated from an export, never retyped
MotionDuration and easing tokens, with a Reduced mode that makes transitions instant

Retrospective

Check everything two ways

Next time I’d write the AI rulebook before the first prompt and bring developers in on day one.

A script once passed an avatar ring that never drew; one screenshot caught it. Since then, every computed check gets a rendered one. Next: release both libraries to the team and build from their feedback.

Next case, BurpyDesigning an all-in-one AI health app for how India eats
Let’s work together

Open to new work and collaborations. Email is the quickest way to reach me.

Resume (PDF, opens in a new tab)
hi@amandeepux.com
Based in Hyderabad, India.© 2026 Amandeep Singh. Designed and built in Framer by me.Privacy