Skip to content
Tajdid Rahman
Tajdid Rahman
Back to Work

Relay · Design system

Building a shared language between design and code

Exploring how Figma, reusable components, design tokens and AI-assisted development can work together as one connected system.

Role
Senior product designer
Focus
Design systems, Design engineering, AI
Platform
Figma and React
Year
2026

Overview

A working library across Figma and React, so Relay’s screens, interactions and interface language stayed consistent as the prototype evolved.

The approach
Foundations recreated in Figma with AI’s help and reviewed by me, every screen mapped to reusable components before building, then Claude Code to translate the library into React.
What it produced
Foundations, form and core components, a coded reference inside the prototype, one contradictory state corrected in both places, and six key screens recreated in Figma from the implemented experience.
What I learned
A design system has to connect how an experience looks, behaves and communicates. Keeping Figma and code in step took deliberate reconciliation, not matching screenshots.

A component library is useful only if it supports the states and decisions a product needs.

While developing Relay, a referral experience for property agents, I built a working library across Figma and React. The aim was to make screens, interactions and interface language consistent as the prototype evolved.

The Relay library: the Foundations, Forms and Core components boards from Figma, beside the coded design system reference showing extended components such as buttons, fields, status pills and the rewards card.
The library began in Figma and developed through implementation.

Establishing the foundations

I started in Figma, using AI to help recreate foundations and reusable components from existing interface references. That provided a starting point for typography, colour, spacing, radii, form controls and common interaction patterns.

The generated foundations required review. I treated them as a working interpretation of the references, rather than a verified specification of the original product.

I used Claude Code to help build the foundations and reusable components before developing the prototype screens. My role was to direct the work, review the results and decide where the system needed to change.

  • neutral/0#FFFFFFBase surface
  • neutral/50#F5F5F5Subtle surface
  • neutral/100#EEEEEESoft fill
  • neutral/200#D5D5D5Borders · disabled
  • neutral/400#9A9A9ADisabled text
  • neutral/600#666666Supporting copy
  • neutral/800#333333Pressed extension
  • neutral/1000#000000Text · primary action
  • purple/50#F4EBFEOutgoing · tint
  • purple/100#EAD5FFFocus halo extension
  • purple/500#9B3AFDReference accent
  • purple/700#7721B5Focus extension
  • ink/950#0D093BIncoming message
  • red/600#D92D3EValidation error
The colour primitives, as documented in the library. Neutrals carry most of the interface; purple marks selections, interactive elements and key moments.

Spacing · a 4px scale

  • 4px
  • 8px
  • 12px
  • 16px
  • 24px
  • 32px
  • 48px
  • 64px

Corner radius

  • 4px
  • 6px
  • 8px
  • 12px

Reuse before adding

Before implementing a screen, I worked through a simple sequence:

  1. 1

    Inventory the existing components.

  2. 2

    Map the screen to reusable elements.

  3. 3

    Identify missing states or patterns.

  4. 4

    Implement the gaps, then compose the screen.

This made reuse a decision made before implementation. It also gave me a way to distinguish a missing component from a missing variant or an unclear content rule.

For example, a referral form needs more than fields and a submit button. It also needs validation feedback, a consent interaction and a confirmation state. A referral detail view needs a consistent relationship between its status, timeline and next action.

Screen needReusable responsibilityState or gap to inspect
Referral formField, consent control, primary actionInvalid input, consent absent, submitting, confirmation
Referral detailStatus summary, adviser identity, timelineActive, needs agent action, unreachable, completed
EarningsAmount and status presentationEstimated, payable, paid
RewardsPoints summary and reward progressPending, available, illustrative redemption
ViewerScenario control, language control, notes controlActive selection, keyboard focus, expanded notes
Inventory first, map the screen, identify gaps, then implement.

Connecting visual roles to product meaning

The foundations included colour primitives and semantic roles, along with typography, spacing and radii.

The important distinction was between a visual value and its purpose. A status colour cannot explain whether a case needs the agent’s attention. That meaning also needs a label, supporting copy and the right action.

As the prototype developed, I added missing components and semantic tokens instead of treating every screen difference as a one-off style.

The portfolio uses Archivo and a paper-and-forest palette. Those are the presentation styles for these case studies. They should not be mistaken for the prototype’s original token values.

  1. purple/700#7721B5Role state/focusThe border of a focused field
  2. red/600#D92D3ERole state/errorValidation messages and invalid fields
  3. neutral/1000#000000Role action/primaryThe primary button
  4. ink/950#0D093BRole message/incomingAn incoming chat message
  5. purple/500#9B3AFDRole brand/accentSelections and key brand moments
Semantic roles connect visual decisions to the meaning of a state.

When implementation reveals a design problem

One referral state showed that the client could not be reached. Its timeline also suggested that an adviser had already spoken to them.

Both messages could not describe the same moment.

I revised the timeline to communicate that contact was still being attempted, then updated the corresponding Figma screen. The correction aligned the status, progress language and next step across both environments.

This was a useful reminder that system consistency includes content and behaviour. A reusable timeline can still communicate the wrong thing if its completed states do not match the scenario.

Before

Described, not a capture

Status
The client could not be reached.
Timeline
An adviser had already spoken to the client.

After

The corrected state in the prototype

Corrected timeline: received, then reaching your client, with the adviser still trying and no answer yet.
The unreachable status and timeline were brought into agreement in the prototype and Figma.

Refining states and access

The work included clearer form validation, accessible names, contrast adjustments and reduced-motion support. I used labels alongside visual treatments so meaning did not depend on colour alone.

I also checked the coded experience at a 390px viewport in English and Arabic. The RTL variant made layout direction, mixed-language content and the relationship between labels and controls part of the design work.

These refinements are evidence of attention to access and interaction quality. They are not a claim of a comprehensive accessibility audit or validated Arabic localisation. Both would need further review before production.

The earnings progression was another example of state design. Estimated, payable and paid earnings needed different meanings, not simply different colours. The same applied to pending and available points.

Home in English at 390px.The same home screen in Arabic, laid out right to left.Referral form with an incomplete phone number and missing consent, each with its own error message.
Narrow-screen, language and interaction checks informed the refinements. Further accessibility and localisation review is still needed.

Bringing implementation back into Figma

As the implemented experience developed, I recreated six key screens in Figma using the working library, adding missing components and semantic tokens where needed.

The workflow became a loop:

  1. 1Figma foundations
  2. 2Component mapping
  3. 3React implementation
  4. 4Interaction refinement
  5. 5Updated Figma library

Deliberate reconciliation across two environments, not an automated sync.

This was deliberate reconciliation across two environments. It was not an automated synchronisation pipeline.

Figma helped establish the visual foundations. The working prototype exposed questions about behaviour and content. Bringing those decisions back into Figma kept the design artefacts useful after implementation had moved forward.

Agent home.Quick referral form.Referral confirmation.Referral details.Earnings and commissions.Rewards.
Six key screens were recreated in Figma from the implemented experience.

What the project established

The project gave me a working set of components, screens and interactions that could be explored in design and code.

It did not establish adoption, engineering time saved or production performance. I did not measure those outcomes.

The strongest evidence is more concrete: reuse decisions made before implementation, a contradictory state corrected in both environments, and six screens brought back into Figma from the coded experience.

What I would improve next

I would document component responsibilities and state rules more explicitly, verify token mappings against the implementation and define a repeatable review process for changes in either environment.

I would also extend the accessibility review beyond the refinements made during prototyping and have Arabic-speaking users review substantive flows.

The lesson I would carry forward is that a design system should connect how an experience looks, behaves and communicates. Keeping that connection requires more than matching screenshots.

All work