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

- colour ramps (~48 tokens)
- 6
- type styles in Inter Tight
- 10
- scoped components
- 20+
- chart types (Recharts)
- 2
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.
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
Semantic tokens
Roles the components actually read. Change one here and every component follows.
| Token | Value | Usage |
|---|---|---|
--umbre-color-bg | Page background behind cards | |
--umbre-color-surface | Cards, sidebar, table | |
--umbre-color-border | Dividers, hairlines | |
--umbre-color-text-primary | Headings, values, primary text | |
--umbre-color-text-secondary | Labels, table meta | |
--umbre-color-text-muted | Placeholder, captions | |
--umbre-color-accent | Primary actions, focus | |
--umbre-color-positive | Positive status, gains | |
--umbre-color-info | In-progress status | |
--umbre-color-warning | Caution status | |
--umbre-color-negative | Errors, destructive, losses |
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.
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.
Motion
Three durations and one easing curve. Motion is functional, never decorative — and every transition is disabled under `prefers-reduced-motion`.
| Token | Value | Usage |
|---|---|---|
--umbre-duration-fast | 120ms | Hover, small state changes |
--umbre-duration-base | 200ms | Most transitions, popovers |
--umbre-duration-slow | 320ms | Dialogs, drawers, entrances |
--umbre-ease | cubic-bezier(0.16, 1, 0.3, 1) | The one easing curve |
Iconography
A single-weight, ~18px line set (Lucide), scoped to Umbre so it stays distinct from the portfolio's own icons.
Icons are decorative by default (aria-hidden). When an icon is a control's only label, that control carries an aria-label.
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.
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.
Members
| Member | Status | ||
|---|---|---|---|
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
- Website45%
- Social25%
- Referral20%
- Email10%
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
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.
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.
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.
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
Revenue Report
$6,379.00- This period
- Last period
Lead by Sources
- Website45%
- Social25%
- Referral20%
- Email10%
Recent New Contacts
| Name | Company | Status | Deal | ||
|---|---|---|---|---|---|
DR Dianne Russell | Acme Co | Interested | $2,480 | ||
CF Cody Fisher | Binford | Followed Up | $1,200 | ||
JC Jane Cooper | Umbrella | Contacted | $3,900 | ||
RF Robert Fox | Soylent | Lost | $540 | ||
LA Leslie Alexander | Initech | Interested | $4,120 |
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.
