Skip to content
Design Systems

A scalable design system for a modern CRM.

Umbre CRM is a sales dashboard built on its own end-to-end design system — a token layer and a component library that runs live, in the same app as this portfolio, without either bleeding into the other. Everything below is documented from the real tokens and rendered from the real components. No mockups.

Role
Product Designer · Design Systems
Timeline
2025
Built with
Figma · React · Recharts · Lucide
Umbre CRM dashboard shown as a mockup
colour ramps (~48 tokens)
6
type styles in Inter Tight
10
scoped components
20+
chart types (Recharts)
2
01

Overview

Umbre is a CRM dashboard, but the real work is the system underneath it — a design language that stays consistent from a status pill to a full data table to a two-series revenue chart.

It's built on three principles: token-driven (components read semantic tokens, never raw hex), accessible by default (colour is never the only signal, every control is keyboard-operable), and scoped by construction — every token is namespaced `--umbre-*` and defined only inside a scoped container, so Umbre's indigo and Inter Tight can never leak into the portfolio, and the portfolio's theme can never touch Umbre.

What follows is that system, documented: the foundations, then the component library by category, then accessibility — and finally the whole thing composed into the running product.

02

Colour

Six ramps. Components never read a raw step — they read the semantic tokens below, which map roles onto the ramps and can remap per theme. An indigo Primary carries brand and action; a 12-step Greyscale covers every surface and text level; Sky, Success, Warning, and Error handle informational and status colour, because a CRM needs categorical status, not a binary good/bad.

Ramps

Primary
50#F8F5FF
100#D3C4FC
200#B59CFA
300#9774F7
400#7A4DF5
500#6B39F4
Greyscale
0#F8F9FB
25#F6F8FA
50#ECEFF3
100#DFE1E6
200#C1C7CF
300#A4ABB8
400#808897
500#686D80
600#353849
700#272835
800#141B25
900#0D0D12
Additional / Sky
0#EFFBFF
25#D1F0F9
50#7EDCF1
100#33CFFF
200#106A97
300#0C4D6E
Alert / Success
0#EFFEFA
25#DDF2EE
50#9DE0D3
100#4CC4AA
200#287F6E
300#174E43
Alert / Warning
0#FFF6E0
25#F9ECCB
50#FBD982
100#FFBD4C
200#956321
300#583D1E
Alert / Error
0#FEEFF2
25#FADAE1
50#ED8296
100#DF1C41
200#95122B
300#710E21

Semantic tokens

Roles the components actually read. Change one here and every component follows.

TokenValueUsage
--umbre-color-bgPage background behind cards
--umbre-color-surfaceCards, sidebar, table
--umbre-color-borderDividers, hairlines
--umbre-color-text-primaryHeadings, values, primary text
--umbre-color-text-secondaryLabels, table meta
--umbre-color-text-mutedPlaceholder, captions
--umbre-color-accentPrimary actions, focus
--umbre-color-positivePositive status, gains
--umbre-color-infoIn-progress status
--umbre-color-warningCaution status
--umbre-color-negativeErrors, destructive, losses
03

Typography

One typeface — Inter Tight — across two groups: a six-step Heading scale (Semibold) and a four-step Body scale in Regular, Medium, and Semibold. Size, line-height, and weight are fixed per step, so text stays consistent across the system.

Inter Tight
Umbre CRMHeading 1 · 48px / 120% · 600Hero, page titles
Umbre CRMHeading 2 · 40px / 110% · 600Section titles
DashboardHeading 3 · 32px / 125% · 600Stat values
DashboardHeading 4 · 24px / 130% · 600Sub-sections
Revenue ReportHeading 5 · 20px / 135% · 600Card titles
Revenue ReportHeading 6 · 18px / 135% · 600Group titles
The quick brown fox jumps over the lazy dogBody XLarge · 18px / 140% · 400Lead paragraphs
The quick brown fox jumps over the lazy dogBody Large · 16px / 150% · 400Default reading text
The quick brown fox jumps over the lazy dogBody Medium · 14px / 150% · 400Table cells, nav
The quick brown fox jumps over the lazy dogBody Small · 12px / 150% · 400Labels, meta, captions
04

Space, shape & elevation

A 4px spacing scale keeps rhythm consistent without one-off values. Radii run soft — small for inputs, medium for buttons and cards, large for surfaces, full for pills and avatars. Elevation stays quiet: shadows sit on Greyscale-900 at very low opacity, enough to lift a card off the grey without a heavy drop.

Spacing
4px · 0.25rem
8px · 0.5rem
12px · 0.75rem
16px · 1rem
24px · 1.5rem
32px · 2rem
48px · 3rem
64px · 4rem
Radius
sm · 8px
md · 12px
lg · 18px
full · 9999px
Shadow
xs
sm
md
05

Motion

Three durations and one easing curve. Motion is functional, never decorative — and every transition is disabled under `prefers-reduced-motion`.

TokenValueUsage
--umbre-duration-fast120msHover, small state changes
--umbre-duration-base200msMost transitions, popovers
--umbre-duration-slow320msDialogs, drawers, entrances
--umbre-easecubic-bezier(0.16, 1, 0.3, 1)The one easing curve
06

Iconography

A single-weight, ~18px line set (Lucide), scoped to Umbre so it stays distinct from the portfolio's own icons.

dashboard
tasks
notes
mail
calendar
contacts
companies
reports
search
bell
plus
chevron
collapse
more
filter
sort
external
refresh
check
close
sales
revenue
reply
home

Icons are decorative by default (aria-hidden). When an icon is a control's only label, that control carries an aria-label.

07

Buttons & controls

Buttons

Four variants, three sizes, icon-only, and a disabled state. Real buttons — keyboard focusable, with a visible focus ring.

Variants
Sizes
Icon-only & disabled

Inputs & controls

Text field (with an error state), search, select, and the full set of selection controls — checkbox, radio group, and toggle. Every control is labelled and keyboard-operable; errors show an icon and text, never colour alone.

Text field — default / error
Search & select
⌘K
Checkbox — unchecked / checked / indeterminate
Radio group
Toggle
08

Status & feedback

Badges & status

Badges, the trend delta pill, and categorical lead-status tags. Status always pairs a hue with a dot, icon, or text — meaning never rests on colour.

Badges
DraftBetaLivePendingFailedInfo
Delta — trend pill
+6.5%−4.3%
Status — categorical (dot + text)
InterestedFollowed UpContactedLostNew
09

Data & charts

Data display

Avatars and stacks, a stat card, and a sortable, selectable data table built as a real <table> — header scope, per-row accessible names, and status pills in cells.

Avatars & stack
AOLMPR
AOLMPRSC+1
Stat card
+6.5%
Total Sales$6,379.00
See Details
Data table — selectable rows, status pills

Members

MemberStatus
AO
Ada Okafor
Interested
LM
Leo Marsh
Followed Up
PR
Priya Raman
Lost

Charts

Two chart types built with Recharts, their series colours read from --umbre-chart-* tokens so they re-theme with the scope. The area chart has a two-value hover tooltip.

Line / area

  • This period
  • Last period

Donut gauge

$13,420Total Lead
  • Website45%
  • Social25%
  • Referral20%
  • Email10%
10

Cards & calendar

Cards

The record cards a CRM lives on — a task card, a company card, and a contact card — composing avatars, tags, status pills, detail rows, and the overflow menu.

Call Alice for feedback

MarketingInternal
AOLMPR
2 12
June 09
Spotify
Active
Customer Relationship
spotify.com
United States
2 12
2d
DRDianne Russel
Interested
diannerussler@gmail.com
(555) 234-5678
Lafayette, California

Calendar

A month grid with accent-tinted event chips, a today badge, muted out-of-month days, and a “+N more” overflow. Scrolls horizontally on narrow screens.

Sun
Mon
Tue
Wed
Thu
Fri
Sat
28
29
30
1
2
3
Product Demo
4
5
6
7
Discovery Call
8
9
10
Discovery Call
Product Demo
+2 more
11
12
13
14
15
Discovery Call
Product Demo
+5 more
16
17
18
Discovery Call1–2 PM
19
20
21
22
Product Demo1–2 PM
23
24
25
26
27
Discovery Call
28
29
30
31
1
11

Responsive design

The system isn't desktop-only — Umbre has a full mobile design, and the components adapt rather than shrink: the same tokens and primitives, re-laid-out for one column and touch. The phone below runs the real components.

The dashboard, adapted for mobile

Live — the same stat cards, charts, and list re-composed for a 375px screen.

Live build at a 375px viewport — scroll and tap inside

  • Navigation → drawerThe fixed sidebar collapses behind a hamburger in the top bar; the page title and quick actions take its place.
  • Grids → single columnThe four-up stat row and the two-up chart row stack vertically, each card going full-width.
  • Actions → full-widthPrimary actions like Download span the screen — sized for a thumb, not a cursor.
  • Tables → condensed listsDense tables become compact rows (avatar + name + status). Horizontal scroll is kept only where a true grid is essential, like the calendar.
  • One token setNothing is re-styled for mobile — type, colour, spacing, and radii all come from the identical --umbre-* scale, so both form factors stay in lockstep.
12

Accessibility

Accessibility is a property of the system, not a coat of paint. Because colour is only ever one of the signals, status pills and delta badges always pair a hue with a dot, an arrow, or text — so meaning survives colour-blindness and greyscale.

13

The system in use

Everything above composes into the real product. The dashboard below is running React — the sidebar collapses, the table rows select, the overflow menus open, and the revenue chart shows a live tooltip on hover.

Umbre CRM — Dashboard

PB
+6.5%
Total Sales$6,379.00
See Details
−4.3%
Product Revenue$2,415.00
See Details
+2.1%
Total Deals1,062
See Details
+0.8%
Reply Rate90.4%
See Details

Revenue Report

$6,379.00
  • This period
  • Last period

Lead by Sources

$13,420Total Lead
  • Website45%
  • Social25%
  • Referral20%
  • Email10%

Recent New Contacts

NameCompanyStatusDeal
DR
Dianne Russell
Acme CoInterested$2,480
CF
Cody Fisher
BinfordFollowed Up$1,200
JC
Jane Cooper
UmbrellaContacted$3,900
RF
Robert Fox
SoylentLost$540
LA
Leslie Alexander
InitechInterested$4,120
Live components running in-page — not a mockup.
14

See it live

View the live dashboard

Open the full-scale Umbre CRM in its own window — a realistic, interactive product experience with the whole component library at work.

View the live dashboard
Venus business-banking reliability-routing case study cover

Next Project

Venus

Designing reliability on rails you don't control.