Dashboard Design System

Good dashboards are just clarity. Simple rules, great UI. This page codifies the recurring patterns observed across 12 production-grade admin dashboards (Classic, E-commerce, Sales, CRM, Project Management, File Manager, Crypto, Academy, Hospital Management, Website Analytics, Finance, Payment) into an authoritative, reusable design system.

Reference screenshots archived at wiki/assets/dashboards/ (24 images: 12 light + 12 dark).

Base Typography

Role Size Weight Notes
Page title 24px semibold (600) Only place semibold appears reliably
Card title 14px medium (500) Paired with 16px icon to the left
Hero stat 28-36px semibold (600) The single number the card exists to communicate
Body / cell text 14px regular (400) The base - everything defaults here
Secondary label 13px regular (400) Muted color, never smaller than 12px
Badge / tag 12px medium (500) All-caps optional, pill-shaped container

The 14px rule. 14px is the base font size for dashboard UI. Not 16px (too editorial), not 13px (too dense for scanning). 14px lets stat cards, tables, and labels coexist without competing.

Letter spacing. Body text at 14px uses -0.2px letter-spacing. This tightens the default browser tracking just enough to feel intentional without hurting readability. Don't go tighter - -0.3px starts collapsing at small sizes.

Weight discipline. Three weights maximum: regular (400) for body, medium (500) for labels and card titles, semibold (600) only for page headings and hero stat numbers. Bold (700) is almost never used. If everything is bold, nothing is.

The AliGrids/@_heyrico dashboard artifact independently reinforces the same density contract: 14px base text, 16px base icons, 1/1.2/1.5px icon strokes, and regular/medium/rare semibold weights. The reviewed image is a dark finance dashboard with a quiet sidebar, search, notification badges, stat cards, and charts; the useful lesson is small, consistent primitives instead of oversized dashboard chrome. Source: X/@AliGrids and local image review, 2026-07-03

Tabular numbers. Every number that updates or compares uses font-variant-numeric: tabular-nums. KPIs, prices, percentages, table columns, dates. No exceptions.

Base Iconography

Property Value
Base size 16px (in sidebar nav, card titles, action buttons)
Large 20px (page-level actions, empty states)
Small 14px (inside badges, inline with 13px text)
Stroke width - default 1.5px
Stroke width - navigation 1.5px
Stroke width - decorative 1.2px (lighter, for visual accents in stat cards)
Stroke width - emphasized 2px (rare - only active states or primary actions)
Library Lucide React

Optical alignment. Icons in sidebar nav items align to the text baseline, not the container center. The icon sits 12px from the left edge, 8-10px gap to the label text. Asymmetric SVGs (play, volume) need 1-2px nudges.

Layout Architecture

Shell Structure

┌──────────────────────────────────────────────────────┐
│ Sidebar (240px)  │  Top Bar (56px height)            │
│                  │  ┌─────────────────────────────┐  │
│  Logo + Brand    │  │ Page Title    │ Date │ CTA  │  │
│  Search          │  ├─────────────────────────────┤  │
│  ─────────────   │  │                             │  │
│  Nav Group       │  │  Stat Cards (row of 3-4)    │  │
│    Active ███    │  │                             │  │
│    Item          │  ├──────────┬──────────────────┤  │
│    Item    (6)   │  │          │                  │  │
│  ─────────────   │  │  Chart   │  Chart / List   │  │
│  Nav Group       │  │          │                  │  │
│    Item          │  ├──────────┴──────────────────┤  │
│    Item          │  │                             │  │
│  ─────────────   │  │  Table / Transaction List   │  │
│  User Avatar     │  │                             │  │
└──────────────────┴──────────────────────────────────┘

Dimensions

Element Value
Sidebar width 240px (collapsed: 64px icon-only)
Top bar height 56px
Content padding 24px (outer), 16px (between cards)
Card gap 16px (grid gap between all cards)
Card padding 20-24px
Card radius 8px (consistent across all card types)
Content max-width None - fluid fill, sidebar constrains
Sidebar nav item height 36-40px

Grid

Stat cards at the top use a responsive grid: 4 columns on wide screens, 2 on medium, 1 on narrow. Below the stat row, content cards fill a 2-column or 3-column grid depending on the dashboard variant. The grid uses 16px gap uniformly.

Stat Cards

The single most repeated pattern across all 12 dashboards. Every dashboard opens with a row of 3-4 stat cards.

Anatomy

┌─────────────────────────────┐
│ [icon]  Label          [▲]  │
│                             │
│ $125,430                    │
│ +12.5% compared to last mo  │
│                             │
│ [Transfer] [Request]        │  ← optional actions
└─────────────────────────────┘
Part Spec
Icon 16px, muted color, top-left next to label
Label 14px medium, muted text color
Value 28-36px semibold, primary text color
Delta 13px regular, green (#10b981) positive / red (#ef4444) negative
Context 13px regular, muted ("from last month", "vs last month")
Sparkline Optional, 48px tall, below or beside the value

Delta formatting. Always show direction: +12.5% or -3.1%. Use an upward/downward trend icon (12px) paired with the percentage. Green and red are the only delta colors - no orange, no yellow.

Value formatting. Large numbers use comma separators. Currency uses $ prefix and 2 decimal places for amounts under $1,000, no decimals above. Percentages show 1 decimal place. Use K and M suffixes above 10,000 and 1,000,000.

Charts

Chart Types by Use Case

Type When Examples
Vertical bar Period comparison, distribution Revenue by day/week, income sources
Line Trends over time Exercise minutes, balance history
Area (filled line) Volume trends Daily sales, user activity
Donut / Ring Composition, progress Category split, completion %, budget allocation
Horizontal bar Ranked comparison Sales pipeline stages, traffic sources
Sparkline Inline trend in stat card Revenue trend, subscriber growth

Chart Styling

Property Value
Bar corner radius 4px top corners, 0 bottom
Bar width 60-70% of available slot
Line stroke width 2px
Area fill opacity 0.1-0.15
Grid lines Horizontal only, 1px, muted border color
Axis labels 12px regular, muted color
Tooltip Card-style, 8px radius, subtle shadow
Legend Below or inside chart, dot + label, 12px

Color discipline. One primary color per chart. Secondary series use the same hue at lower opacity, or a single contrasting accent. Never more than 5 colors in one chart. Donut charts can use 4-5 distinct category colors.

Dark mode charts. Grid lines use rgba(255, 255, 255, 0.06). Bars and areas use slightly higher saturation than light mode to maintain contrast against dark backgrounds.

Shadcn's "50+ sidebars" anecdote is a useful warning: the sidebar is the product shell's shared contract, not a disposable component. Treat it like a design-system primitive with stable grouping, active-state semantics, collapse behavior, badges, keyboard/focus behavior, and product-area naming that can scale across many apps without every team inventing a cousin. Source: X/@shadcn, 2026-06-20

Structure

The sidebar has 3-4 sections, each with a group heading:

  1. Dashboards - the main dashboard views
  2. Apps - Kanban, Chat, Mail, Calendar, etc.
  3. Pages - Settings, Profile, Error pages
  4. Others - Help, Documentation

Specs

Element Spec
Group heading 11-12px, uppercase, medium weight, muted color, 12px left padding
Nav item 14px regular, 36px height, 12px left padding, 8px icon-label gap
Active item Medium weight, primary text color, subtle background fill (8px radius)
Hover Slightly lighter background fill
Icon 16px, 1.5px stroke, muted color (active: primary)
Badge Right-aligned, red dot or pill with count, 12px text
Chevron Right-aligned, 14px, indicates expandable submenu
Section divider 1px border, muted, 8px vertical margin
Bottom section User avatar (32px), name (14px medium), email (12px muted)

Collapse Behavior

Sidebar collapses to 64px icon-only rail. Icons center-align. Tooltip shows label on hover. Group headings hide. Active indicator becomes a vertical bar or dot.

Top Bar

[Sidebar Toggle]  [Search ⌘K]                    [CTA]  [🔔]  [🌙]  [⚙]  [Avatar]
Element Spec
Height 56px
Search Input with ⌘K shortcut hint, ~400px wide, rounded, muted border
CTA Primary button ("Download", "Get Pro"), 14px medium, always top-right
Icons 16px, 1.5px stroke, 24px spacing between
Notification dot Red, 8px, positioned top-right of bell icon
Avatar 32px circle, right-aligned
Border 1px bottom border, muted

Empty States

Every view that can be empty needs an empty state. "No data" is not an empty state.

Part Spec
Illustration 120-160px, muted/grayscale, centered above text
Heading 16px medium, primary text color
Description 14px regular, muted text, 1-2 lines max
CTA Primary button below description, clear action verb ("Create project", "Import data")
Vertical spacing 16px between illustration → heading → description → CTA

The rule. Illustration + CTA, not just "No data." Empty states are onboarding moments - they tell users what belongs here and how to fill it. A table with zero rows shows the illustration stack. A chart with no data shows a placeholder with the CTA to configure the data source.

Tables

Anatomy

Part Spec
Header row 13px medium, muted color, uppercase optional, bottom border
Body row 14px regular, 48-52px height, bottom border (subtle)
Cell padding 12-16px horizontal
Status badge Pill shape, 12px medium, colored background at 10% opacity + text color
Actions Icon buttons (16px), right-aligned, appear on hover or always visible
Pagination Bottom of table, "Previous / Next" buttons + page indicator
Filter Text input above table, or dropdown selects
Column selector "Columns" dropdown button, right-aligned above table
Hover row Subtle background tint
Checkbox 16px, left column, for batch actions

Status Badge Colors

Status Background Text
Completed / Success green-100 / green-500 green-700
In Progress blue-100 / blue-500 blue-700
New / Pending amber-100 / amber-500 amber-700
On Hold / Warning orange-100 / orange-500 orange-700
Cancelled / Error red-100 / red-500 red-700

Color System

Light Mode

Token Value Usage
Background #ffffff Page background
Surface #ffffff Card backgrounds (borders create separation)
Border #e5e7eb Card borders, dividers
Border muted #f3f4f6 Table row borders, subtle separators
Text primary #09090b Headings, stat values
Text secondary #71717a Labels, descriptions
Text muted #a1a1aa Timestamps, helper text
Accent #18181b CTA buttons, active sidebar

Dark Mode

Token Value Usage
Background #09090b Page background
Surface #0f0f11 or #111113 Card backgrounds
Border #27272a Card borders, dividers
Border muted #1e1e21 Subtle separators
Text primary #fafafa Headings, stat values
Text secondary #a1a1aa Labels, descriptions
Text muted #71717a Timestamps, helper text
Accent #fafafa CTA buttons (inverted from light)

Semantic Colors (Both Modes)

Token Value Usage
Positive #10b981 Revenue up, growth, success
Negative #ef4444 Revenue down, errors, decline
Info #3b82f6 Links, informational badges
Warning #f59e0b Attention, pending items

One accent rule. Each dashboard variant uses at most one brand accent beyond the semantic colors. Finance uses amber for income. Crypto uses orange for Bitcoin. CRM uses green for deals. The accent never competes with the positive/negative semantic pair.

Dark Mode Card Shadows (The 1px Rule)

Every card in dark mode uses two shadows to create physicality:

box-shadow:
  inset 0 1px 0 0 rgba(255, 255, 255, 0.02),
  0 0px 0 0 rgba(0, 0, 0, 0.25);

Inner shadow (white at 2%, inset) simulates a top-edge catch-light. Drop shadow (black at 25%) grounds the card. Together they make a flat rectangle read as a physical surface. See Interface Micro-Polish for the full rationale.

Spacing System

Token Value Usage
gap-cards 16px Between all cards in the grid
pad-card 20-24px Internal card padding
pad-content 24px Main content area outer padding
pad-sidebar 12px horizontal Sidebar internal padding
gap-stat-parts 4px Between label and value in stat cards
gap-icon-text 8px Icon to adjacent text (nav items, card titles)
gap-section 24px Between major content sections

All spacing uses 4px granularity. The 16px card gap is the rhythm unit - everything else is a multiple or fraction.

Motion

Dashboards are mostly static. Animation is reserved for:

  1. Sidebar collapse/expand - 200ms ease-out width transition
  2. Chart entrance - 300ms staggered bar/line draw on first load
  3. Tooltip appearance - 100ms opacity + translateY(4px)
  4. Page transitions - 150ms content fade on sidebar nav click
  5. Dropdown menus - 150ms scale(0.95) → scale(1) + opacity

No animation on stat card number changes (just swap the value). No skeleton loaders for above-the-fold content that loads instantly. Skeleton only for data that has genuine latency (charts, tables).

Dashboard Variants Catalog

Type Stat Cards Primary Chart Secondary Content Demo
Classic Subscriptions, Revenue Bar + Line Team members, Chat, Payments table demo
E-commerce MRR, Users, Growth Bar (Revenue) Product list, Returning rate line demo
Sales Balance, Income, Expense, Tax Bar (Revenue) Best selling products, Order table demo
CRM Customers, Deals, Revenue Donut (Leads) Tasks list, Pipeline horizontal bar demo
Project Management Tasks, Progress, Team Gantt-style Task board, Calendar demo
File Manager Storage used, Files Usage bar File grid, Recent files demo
Crypto Balance, Wallets Line (Balance) Wallet cards, Transaction list demo
Academy Students, Courses Bar (Enrollment) Course cards, Schedule demo
Hospital Patients, Appointments Line (Admissions) Doctor schedule, Patient table demo
Analytics Active users, Sessions, Duration, Conversion Bar (Earnings) Donut (completion), Traffic sources demo
Finance Balance, Profit, Expenses, Invoices Bar (Monthly expenses) Income breakdown, Donut (spending), Transactions demo
Payment Multi-currency balances Line (Exchange rates) Transaction list, Currency converter demo

SaaS Dashboard Cheatsheet

The six rules. Memorize these.

Rule Spec Why
Typography 14px body, -0.2px letter-spacing Readable without feeling editorial
Sidebar width 240px, always Enough for labels, not enough to waste space
Table row height 48px minimum Scanability - eyes need vertical breathing room
Primary action Top right, never buried Users look there first; muscle memory from every SaaS app
Empty states Illustration + CTA "No data" is a dead end; empty states are onboarding
Status colors Green = done, amber = pending, red = action needed Three states, three colors, zero ambiguity

Checklist - Before Shipping a Dashboard

  • Base font is 14px, not 16px
  • Body text uses -0.2px letter-spacing
  • At most 3 font weights used (regular, medium, semibold)
  • All numbers use tabular-nums
  • Icons are 16px with 1.5px stroke
  • Stat cards have: icon + label + hero value + delta + context
  • Delta uses green/red only, with direction indicator
  • Card gap is 16px uniform
  • Card padding is 20-24px
  • Card radius is 8px
  • Charts use at most 5 colors
  • Table rows are 48-52px height
  • Sidebar active state has background fill, not just text color
  • Primary action is top right, never buried in the page
  • Empty states have illustration + CTA, not just "No data"
  • Top bar has search with keyboard shortcut hint
  • No animations on instant-load content
  • Dark mode backgrounds are near-black (#09090b), not gray
  • Dark mode cards use the 1px inner shadow (white 2%) + drop shadow (black 25%)

Timeline

  • 2026-04-12 | Created from analysis of 12 shadcnuikit.com admin dashboards (Classic, E-commerce, Sales, CRM, Project Management, File Manager, Crypto, Academy, Hospital Management, Website Analytics, Finance, Payment). 24 preview images (light + dark) archived at wiki/assets/dashboards/. Live screenshots captured via Chrome browser automation. Design cheatsheet principles (14px base, 16px icons, weight discipline) codified from Kevin's direction. Source: shadcnuikit.com, Kevin Liu
  • 2026-04-12 | Added dark mode card shadow technique (the 1px rule): inner white shadow at 2% + drop black shadow at 25%. Cross-referenced with Interface Micro-Polish. Source: @PixelJanitor, @AliGrids on X, 2026-04-11
  • 2026-04-13 | Added SaaS dashboard cheatsheet (6-rule quick reference), -0.2px letter-spacing spec, empty states pattern (illustration + CTA), explicit primary action placement rule (top right, never buried). Updated checklist with new items. Source: Kevin Liu
  • 2026-07-03 | Deep-reviewed the AliGrids/@_heyrico dashboard artifact and attached it as visual evidence for the existing density rules: 14px base text, 16px icons, thin strokes, restrained weights, quiet sidebars, and stat-card hierarchy. Source: X/@AliGrids, 2026-04-12
  • 2026-07-04 | Deep-reviewed Tanjim's CloseCRM dashboard artifact and attached it to the existing SaaS dashboard rules. The local image reinforces 240px-class sidebar rhythm, 48px scan rows, top-right primary action, compact stat cards, and empty/state/action placement as dashboard defaults. Source: X/@Tanjim38, 2026-04-12
  • 2026-07-04 | Reviewed shadcn's sidebar scale anecdote and codified sidebar as app-shell infrastructure: shared grouping, active states, collapse behavior, badges, focus, and product-area naming must survive reuse across many surfaces. Source: X/@shadcn, 2026-06-20