Skip to main content

frontend-design-saas

S-tier SaaS dashboard and product UI reference. Use this skill when building application shells, data tables, settings panels, billing pages, dashboards, auth flows, admin tools, or any internal/customer-facing SaaS product UI. Inspired by Stripe, Linear, Vercel, Airbnb, Notion. Covers neutral-led design tokens, sidebar+content shells, dense data UIs, form-heavy configuration pages, command palettes, empty states, and the accessibility (WCAG AA+) bar these products clear.

Source facts

Repository
cloudflare/vibesdk
Last source activity
June 10, 2026 at 08:07
Detected SKILL.md language
English
Stars
5,400
Forks
1,271

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
frontend-design-saas
description
S-tier SaaS dashboard and product UI reference. Use this skill when building application shells, data tables, settings panels, billing pages, dashboards, auth flows, admin tools, or any internal/customer-facing SaaS product UI. Inspired by Stripe, Linear, Vercel, Airbnb, Notion. Covers neutral-led design tokens, sidebar+content shells, dense data UIs, form-heavy configuration pages, command palettes, empty states, and the accessibility (WCAG AA+) bar these products clear.
# SaaS Design System (Stripe / Linear / Vercel lineage) > **AI-Optimized Design Reference** for building S-tier SaaS dashboards, admin consoles, billing pages, settings UIs, data-dense application shells, and product surfaces. > > Tonal anchors: `stripe.com/dashboard`, `linear.app`, `vercel.com/dashboard`, `notion.so/teamspace`, `clerk.com`, `planetscale.com/console`. --- ## Quick Reference (TL;DR) ``` Brand Accent: #5E6AD2 (indigo) - replace with product brand Neutrals: #FFFFFF → #F8FAFC → #F1F5F9 → #E2E8F0 → #94A3B8 → #475569 → #0F172A Text: #0F172A (primary) / #475569 (muted) / #94A3B8 (subtle) Border: #E2E8F0 (default) / #CBD5E1 (strong) Font Sans: "Inter", "Geist", system-ui (NOT Arial, NOT Roboto) Font Mono: "JetBrains Mono", "Geist Mono", ui-monospace Base Spacing: 4px (scale: 4, 8, 12, 16, 20, 24, 32, 40, 48, 64) Border Radius: Buttons/inputs = 6-8px (NOT pill), Cards = 8-12px, Modals = 12-16px Shadow: Tight, low-spread, single-direction (NOT diffuse marketing shadows) Density: Compact-to-comfortable; row heights 36-44px, button heights 32-36px ``` The fastest way to get this wrong: use marketing-page aesthetics (huge type, generous whitespace, pill buttons, gradient hero shadows) in a product surface. SaaS UIs are **dense, neutral, fast, and quiet**. The brand color appears in <5% of the pixels and earns its weight by marking only what's interactive or active. --- ## 1. Brand Foundation ### Design Philosophy | Principle | Description | |-----------|-------------| | **Users First** | Workflows, keyboard navigation, and information density beat decoration. | | **Quiet by Default** | Neutrals dominate; the brand color is reserved for primary action, active state, and focus. | | **Speed & Density** | Snappy transitions (≤200ms), compact row heights, no entrance animations on every page load. | | **Opinionated Defaults** | Single canonical pattern per surface (one button hierarchy, one date picker, one empty state). | | **Meticulous Craft** | 1px borders aligned to pixel grid, focus rings 2px offset 2px, motion uses ease-out not linear. | | **Accessible (WCAG AA+)** | 4.5:1 text contrast, 3:1 UI element contrast, every interactive surface keyboard-reachable. | | **Predictable** | Same component looks/behaves identically on every page; no marketing-grade variants. | ### Visual Identity Rules - **Do not use pure black on pure white.** Use `#0F172A` on `#FFFFFF` (or `#0B1220` on `#0A0E1A` in dark mode). - **Brand color is the accent, never the dominant.** If the brand color fills more than ~5% of the viewport in steady state, something is wrong. - **Avoid pill buttons** (`border-radius: 9999px`) for SaaS actions. Pills read as marketing/consumer; SaaS uses `6-8px` radius for buttons and inputs. - **No glassmorphism, no blur, no gradient borders.** The aesthetic is precision, not richness. - **Shadows are tight and downward.** Not diffuse, not multi-direction. Reserved for floating layers (popovers, modals, dropdowns). - **One font.** Inter / Geist / IBM Plex Sans / native system stack. Avoid mixing display + body fonts; SaaS uses a single workhorse sans. - **Mono for IDs, code, tokens, money.** Tabular figures (`font-variant-numeric: tabular-nums`) for any column of numbers. ### Reference apps to mentally calibrate against | Surface to build | Look at | |---|---| | Application shell | Linear, Vercel, Stripe Dashboard | | Data table | Stripe `/payments`, Linear backlog, PlanetScale branches | | Settings page | Vercel project settings, Clerk dashboard, GitHub repo settings | | Billing / invoice | Stripe billing, Vercel usage | | Empty state | Linear, Notion, Vercel deployments | | Command palette | Linear ⌘K, Vercel ⌘K, Raycast | | Auth | Clerk hosted pages, Stripe Connect onboarding | | Onboarding checklist | Stripe Atlas, Vercel project import | --- ## 2. Color System ### 2.1 Neutral Scale (the backbone) SaaS UIs are 80–90% neutrals. The neutral scale carries the entire interface; brand is sprinkled on top. Use a slightly cool neutral (slate) by default — it reads more "product" than warm grays which feel marketing/lifestyle. | Token | Hex | Usage | |---|---|---| | `--neutral-0` | `#FFFFFF` | Page background (light mode), surface lifted onto canvas | | `--neutral-50` | `#F8FAFC` | Canvas background, alternating row stripe | | `--neutral-100` | `#F1F5F9` | Hover background, subtle fill, table header | | `--neutral-200` | `#E2E8F0` | **Default border**, divider | | `--neutral-300` | `#CBD5E1` | Strong border, input border on focus-within parent | | `--neutral-400` | `#94A3B8` | **Subtle text** (placeholders, disabled, captions) | | `--neutral-500` | `#64748B` | Tertiary text, icon default | | `--neutral-600` | `#475569` | **Muted text** (descriptions, secondary labels) | | `--neutral-700` | `#334155` | Strong icon, hover text | | `--neutral-800` | `#1E293B` | Heading in dense UIs, code text | | `--neutral-900` | `#0F172A` | **Primary text**, primary icons | | `--neutral-950` | `#020617` | Highest contrast (rare; only for critical labels) | ### 2.2 Brand Accent (single color, used sparingly) Pick **one** accent. Use a 6-step ramp so hover/active/focused/disabled all derive from the same hue. Defaults below use indigo (`#5E6AD2`, Linear's accent) — swap the hue for your brand but keep the structure. | Token | Hex | Usage | |---|---|---| | `--brand-50` | `#EEF0FB` | Selected row background, badge background, focus ring background | | `--brand-100` | `#DDE0F7` | Hover on brand surfaces | | `--brand-200` | `#B9C0EF` | Disabled brand button, decorative | | `--brand-500` | `#7B85DC` | Brand hover surface stroke | | `--brand-600` | `#5E6AD2` | **Primary brand** — default button bg, link text, focus ring, active nav item | | `--brand-700` | `#4A56C0` | Hover state for primary button | | `--brand-800` | `#3A45A8` | Active/pressed state | | `--brand-900` | `#2A3284` | High-contrast brand text on light background | ### 2.3 Semantic / Status Colors Used for state — never for decoration. Each has a `text`, `bg`, `border` triplet so badges and inline messages stay legible. | State | `text` | `bg` (filled) | `bg-subtle` (badge) | `border` | |---|---|---|---|---| | **Success** | `#15803D` | `#16A34A` | `#DCFCE7` | `#86EFAC` | | **Warning** | `#A16207` | `#CA8A04` | `#FEF9C3` | `#FDE68A` | | **Error / Destructive** | `#B91C1C` | `#DC2626` | `#FEE2E2` | `#FCA5A5` | | **Info** | `#1D4ED8` | `#2563EB` | `#DBEAFE` | `#93C5FD` | | **Neutral (default badge)** | `#334155` | `#64748B` | `#F1F5F9` | `#CBD5E1` | Rules: - Inline form errors: `text` color on `bg-subtle` background, `border` for the input. - Toasts: `bg-subtle` panel, `text` heading, `--neutral-700` body. - Status badges: `text` on `bg-subtle` + 1px `border`. Never use solid `bg` for badges (too loud). ### 2.4 Data Visualization Palette When you need >1 color for charts. Categorical — visually distinct, similar luminance. Avoid the brand color in this palette so brand reads as "interactive" elsewhere. ``` --chart-1: #2563EB (blue) --chart-2: #16A34A (green) --chart-3: #CA8A04 (amber) --chart-4: #DC2626 (red) --chart-5: #9333EA (violet) --chart-6: #0891B2 (cyan) --chart-7: #DB2777 (pink) --chart-8: #65A30D (lime) ``` ### 2.5 Dark Mode Mapping SaaS dark modes are **not just inverted**. They are slightly desaturated, slightly lifted, with carefully tuned elevation. Use `#0A0E1A` (or `#0B0F1C`) as the canvas — NEVER `#000000`. Pure black creates harsh contrast and exposes any banding in shadows. | Token | Light | Dark | |---|---|---| | `--bg-canvas` | `#F8FAFC` | `#0A0E1A` | | `--bg-surface` | `#FFFFFF` | `#111827` | | `--bg-elevated` | `#FFFFFF` | `#1F2937` | | `--bg-overlay` (popover/modal) | `#FFFFFF` | `#1F2937` | | `--text-primary` | `#0F172A` | `#F1F5F9` | | `--text-muted` | `#475569` | `#94A3B8` | | `--text-subtle` | `#94A3B8` | `#64748B` | | `--border-default` | `#E2E8F0` | `#1F2937` | | `--border-strong` | `#CBD5E1` | `#374151` | | `--brand-bg-subtle` | `#EEF0FB` | `rgba(94, 106, 210, 0.16)` | | `--brand-fg` | `#5E6AD2` | `#A5B4FC` | In dark mode the **brand color shifts lighter** (toward `--brand-500/400` instead of `--brand-600/700`) to maintain contrast against the dark canvas. --- ## 3. Typography ### 3.1 Font Stack ```css --font-sans: "Inter", "Geist", -apple-system, BlinkMacSystemFont, "Segoe UI", "SF Pro Text", system-ui, sans-serif; --font-mono: "JetBrains Mono", "Geist Mono", "SF Mono", "Menlo", "Consolas", ui-monospace, monospace; ``` Hard rules: - **Never use `Arial`, `Helvetica`, `Roboto`, or `Times`** in a SaaS UI. These read as default/unstyled. If you can't load a webfont, fall through to `system-ui` instead. - **Never mix two display fonts.** One sans + one mono is the entire stack. - **`font-feature-settings: "cv11", "ss01", "ss03"`** for Inter (or whatever stylistic sets your font has) — small caps and alternate forms make tables look intentional. - **`font-variant-numeric: tabular-nums`** on EVERY column that contains numbers (money, dates, IDs, counts). Non-tabular figures make rows shimmer. ### 3.2 Type Scale (SaaS-tuned — denser than marketing) | Token | Size | Line Height | Weight | Letter Spacing | Use | |---|---|---|---|---|---| | `text-2xs` | 11px / 0.6875rem | 1.36 (15px) | 500 | 0.04em | Microlabels (uppercase metadata, table column tags) | | `text-xs` | 12px / 0.75rem | 1.33 (16px) | 400/500 | 0 | Captions, badge text, table secondary | | `text-sm` | 13px / 0.8125rem | 1.38 (18px) | 400/500 | 0 | **Default UI text**: table rows, buttons, form labels | | `text-base` | 14px / 0.875rem | 1.43 (20px) | 400/500 | 0 | Body text, paragraph copy in panels | | `text-md` | 15px / 0.9375rem | 1.47 (22px) | 400/500 | 0 | Comfortable reading (descriptions, modals) | | `text-lg` | 16px / 1rem | 1.5 (24px) | 500/600 | -0.005em | Card headings, sidebar section labels | | `text-xl` | 18px / 1.125rem | 1.44 (26px) | 600 | -0.01em | Subsection headings | | `text-2xl` | 20px / 1.25rem | 1.4 (28px) | 600 | -0.015em | Page subheadings | | `text-3xl` | 24px / 1.5rem | 1.33 (32px) | 600 | -0.02em | Page title (h1 in dashboards) | | `text-4xl` | 30px / 1.875rem | 1.2 (36px) | 600/700 | -0.025em | Marketing-adjacent hero in settings | **Critical**: the default UI size in SaaS is **13px or 14px**, NOT 16px. Stripe is 14px. Linear is 13px. Vercel is 14px. 16px feels too big and creates pages that scroll forever. ### 3.3 Weights | Weight | Value | Use | |---|---|---| | Regular | 400 | Body, table cells, descriptions | | Medium | 500 | Default for buttons, labels, table headers, navigation, badge text | | Semibold | 600 | Headings, emphasized stats, active nav | | Bold | 700 | Rare — only marketing-adjacent surfaces or KPI numbers | **Never** use weight 800 or 900 in a SaaS UI. ### 3.4 Letter Spacing | Context | Value |
View on GitHub
This SKILL.md is very large, so SkillsMP previews the first section here. View on GitHub