Overview
Notion's design system is a clean, token-driven framework emphasising systematic spacing, restrained colour use, and sharp typographic hierarchy. It pairs a crisp sans-serif type system with a neutral white-and-grey palette, punctuated by a signature blue accent. The system scales gracefully from mobile to wide desktop through six explicit breakpoints and a comprehensive logical-property-based spacing scale.
Signature traits: systematic CSS custom property tokens, logical CSS properties (inline/block), layered @layer cascade architecture, responsive fluid typography with cascading breakpoint overrides, dark/palette theme switching via class-scoped token overrides, semantic colour role naming.
Colors
| Role | Token | Hex | Usage |
|------|-------|-----|-------|
| Background | --color-background-base | #ffffff | Page backgrounds |
| Surface Neutral | --color-background-surface-neutral | #f1f1f0 | Card/panel backgrounds |
| Surface Accent Muted | --color-background-surface-accent-muted | #e8f0fd | Highlighted panels, callouts |
| Text Primary (Strong) | --color-text-strong | #191919 | Headings, emphasis |
| Text Normal | --color-text-normal | rgba(55,53,47,0.8) | Body copy, labels |
| Text Secondary (Muted) | --color-text-muted | rgba(55,53,47,0.5) | Captions, placeholders |
| Border Base | --color-border-base | rgba(55,53,47,0.2) | Dividers, outlines |
| Accent | --color-accent | #2383e2 | Links, focus rings |
| Accent Strong | --color-accent-strong | #0b6fce | CTAs, primary buttons |
| Button Primary Background | --color-button-primary-background | #2d7ff9 | Primary CTA buttons |
| Button Primary Text | --color-button-primary-text | #ffffff | Text on primary buttons |
| Error | --color-text-error | #eb5757 | Error states |
| Success | --color-text-success | #0f7b6c | Success states |
| Warning | --color-text-warning | #d9730d | Warning states |
Typography
| Role | Family | Size | Weight | Line Height | Letter Spacing | Usage |
|------|--------|------|--------|-------------|----------------|-------|
| Display | sans | var(--font-size-900) | 700 (bold) | var(--font-line-height-900) | -0.03571rem | Hero headlines |
| Heading LG | sans | var(--font-size-800) | 700 (bold) | var(--font-line-height-800) | -0.03013rem | Page-level titles |
| Heading MD | sans | var(--font-size-700) | 700 (bold) | var(--font-line-height-700) | -0.02344rem | Section headings |
| Heading SM | sans | var(--font-size-600) | 700 (bold) | var(--font-line-height-600) | -0.01786rem | Subheadings |
| Subheading | sans | var(--font-size-400) | 700 (bold) | var(--font-line-height-400) | -0.01228rem | Card headings |
| Body | sans | var(--font-size-200) | 400 (regular) | var(--font-line-height-200) | var(--typography-sans-200-regular-letter-spacing) | Paragraph text |
| Body Semibold | sans | var(--font-size-200) | 600 (semibold) | var(--font-line-height-200) | var(--typography-sans-200-semibold-letter-spacing) | Emphasized body |
| Caption | sans | var(--font-size-100) | 400 (regular) | var(--font-line-height-100) | var(--typography-sans-100-regular-letter-spacing) | Labels, metadata |
| Meta | sans | var(--font-size-50) | 400 (regular) | var(--font-line-height-50) | var(--typography-sans-50-regular-letter-spacing) | Timestamps, tags |
| Mono | mono | var(--font-size-100) | 400 (regular) | var(--font-line-height-100) | -0.00781rem | Code, data display |
| Button Large | sans | var(--font-size-200) | 600 (semibold) | var(--font-line-height-200) | var(--typography-sans-200-semibold-letter-spacing) | Large CTAs |
| Button Medium | sans | var(--font-size-200) | 500 (medium) | var(--font-line-height-200) | var(--typography-sans-200-medium-letter-spacing) | Standard CTAs |
| Button Small | sans | var(--font-size-100) | 500 (medium) | var(--font-line-height-100) | var(--typography-sans-100-medium-letter-spacing) | Small CTAs |
Layout
| Token | Value | Context |
|-------|-------|---------|
| Spacing XS | var(--dimension-spacing-4) | Icon gaps, tight inline spacing |
| Spacing SM | var(--dimension-spacing-8) | Component internal padding |
| Spacing MD | var(--dimension-spacing-16) | Card padding, default section gap |
| Spacing LG | var(--dimension-spacing-32) | Layout margins, section padding |
| Spacing XL | var(--dimension-spacing-64) | Large section separators |
| Spacing 2XL | var(--dimension-spacing-128) | Hero vertical rhythm |
| Spacing 3XL | var(--dimension-spacing-160) | Maximum vertical breathing room |
| Page Inset SM | var(--spacing-page-inset-sm) → var(--dimension-spacing-32) | Narrow viewport page margins |
| Page Inset Default | var(--spacing-page-inset) → var(--dimension-spacing-16) | Mobile page margins |
| Page Inset LG | var(--spacing-page-inset-lg) → var(--dimension-spacing-48) | Desktop page margins |
| Page Inset XL | var(--spacing-page-inset-xl) → var(--dimension-spacing-64) | Wide desktop page margins |
| Max Content Width | var(--spacing-page-max-width) → var(--dimension-size-1252) | Content container max-width |
| Hero Max Width | var(--spacing-hero-center-max-width) → var(--dimension-size-960) | Hero text column max-width |
| Nav Gutter | var(--dimension-spacing-24) | Navigation horizontal padding (≥lg) |
Responsive strategy: Six breakpoints — xs (default/mobile-first), sm (≥600px), md (≥840px), lg (≥1080px), xl (≥1280px), xxl (≥1440px). Typography cascades through breakpoint-scoped custom properties using CSS custom property fallback chains. Navigation switches from hamburger to full desktop layout at 1200px. Grid and flex direction utilities are provided at every breakpoint.
Elevation & Depth
| Level | CSS Value | Usage |
|-------|-----------|-------|
| sm | var(--shadow-200) | Cards, tooltips, floating menus |
| md | 0 4px 4px -2px rgb(0 0 0 / 8%) | Navigation dropdowns |
| lg | var(--shadow-200) + overlay shield | Modals, popovers, overlays |
| Focus Ring | outline: 2px solid var(--color-interaction-focus-ring) offset 2px | Keyboard focus indicators |
| Input Focus | inset 0 0 0 1px rgba(35,131,226,.57), 0 0 0 2px rgba(35,131,226,.35) | Text input active state |
Shapes
| Token | Value | Applied To |
|-------|-------|-----------|
| none | 0px | Dev-platform theme buttons, sharp UI variant |
| sm | var(--border-radius-200) | Badges, default base radius, icon buttons, graphic containers |
| md | var(--border-radius-500) | Standard buttons, menu list items, nav items |
| lg | var(--border-radius-700) | Cards, block media, popovers, dropdowns |
| xl | var(--border-radius-900) | Navigation dropdown panels |
| full | 9999px → var(--border-radius-round) | Badges (pill style), menu buttons (round), avatar chips |
Components
Navigation: Sticky positioned with scroll-triggered shadow animation via animation-timeline. Three-column grid (logo / links / actions). Collapses to hamburger at <1200px. Supports campaign-aware colour overrides via hero-exit scroll animations and CSS custom property scoping. Dev Platform variant uses monospace font links with bracket decoration.
Buttons: Four variants — primary (filled blue), secondary (light blue tint), tertiary (outlined), ghost (transparent). All share --border-button-radius token. Sizes: small, medium, large. States: hover/focus/active covered with distinct background tokens. Transition uses --motion-global-fade-in/out-duration.
Cards: Defined by --color-card-background, --color-card-border, --color-card-accent (top accent strip), and --border-card-radius. Padding scales via --spacing-card-padding-* tokens across sm/block/inline variants.
Icon Buttons: Square aspect-ratio containers with pseudo-element ::after surface for hover/focus states. Surface size independent of icon size via --icon-button-surface-size. Active state compresses icon via scale(0.9).
Menu Lists: Grid-based layout with named template areas (icon, label, caption). Auto-configures columns based on child presence using :has(). Variants: primary (background fill on hover) and secondary (underline reveal on hover).
Popover: Uses CSS Anchor Positioning API with position-area and position-try-fallbacks. Slide-in animations vary by placement (top vs bottom). Falls back to fixed full-screen sheet on mobile <840px.
Forms/Inputs: Two sizes (medium: 7px/10px padding; large: 17px/15px padding). Inline start/end slot support via --before-width/--after-width custom properties. Focus via inset box-shadow.
Graphic/Icon Container: Responsive font-size-driven sizing with breakpoint cascade. Optional filled background using --color-accent-muted. Border-radius and frame-size also breakpoint-responsive.
Theme System: @layer front-tokens with sub-layers base, dark, palette, palette-dark. Palette variants: blue (default), black, brown, gray, green, orange, pink, purple, red. Campaign variants: agentsLaunch (dark navy), devPlatform (DOS-inspired monochrome). Serif palette overrides all typography tokens to use --font-family-serif.
Do's and Don'ts
| Do ✓ | Don't ✗ |
|------|---------|
| Use semantic token names (--color-text-strong, --color-button-primary-background) rather than raw hex values | Hard-code hex colours directly in component styles |
| Use logical CSS properties (padding-inline, margin-block, inline-size) for RTL compatibility | Use physical properties (padding-left, width) in layout-critical styles |
| Apply spacing exclusively from the --dimension-spacing-* scale (4, 8, 12, 16, 20, 24, 28, 32, 40, 48, 56, 64, 72, 80, 96, 100, 128, 160) | Introduce arbitrary spacing values outside the defined scale |
| Layer theme overrides using the established @layer front-tokens palette system | Override token values with inline styles or high-specificity selectors |
| Use text-wrap: balance on headings and text-wrap: pretty on body text | Allow long headings to wrap awkwardly without balance control |
| Apply border-radius via --border-*-radius component-specific tokens | Use raw pixel values for border-radius in components |
| Leverage --motion-global-fade-in/out-duration and timing function tokens for transitions | Define ad-hoc animation durations or easing values |
| Use the .dark_palette_theme class to invert surfaces and text for dark contexts | Manually invert colours for dark mode without the token layer |
Agent Prompt Guide
You are working within the Notion design system ("The AI workspace that works for you."). Key constraints:
- —Colours: background #ffffff (--color-background-base), surface #f1f1f0 (--color-background-surface-neutral), text primary via --color-text-strong, text secondary via --color-text-muted, accent/CTA via --color-button-primary-background (blue ~#2d7ff9), border via --color-border-base
- —Typography: var(--font-family-sans) for all UI text and headings (bold 700 for display/headings, regular 400 for body), var(--font-family-mono) for code/data; use --typography-global-* shorthand font tokens
- —Spacing: use only the spacing scale tokens --dimension-spacing-4/8/12/16/20/24/28/32/40/48/56/64/72/80/96/128/160
- —Radius: --border-radius-500 (md) for buttons/inputs, --border-radius-700 (lg) for cards/popovers, --border-radius-round for pills
- —Layout: max content width --dimension-size-1252, page inset --dimension-spacing-16 (mobile) to --dimension-spacing-64 (wide)
- —Use logical CSS properties (inline/block) for all spacing and sizing
- —Breakpoints: 600px (sm), 840px (md), 1080px (lg), 1280px (xl), 1440px (xxl)
- —Never use colours, fonts, spacing, or radius values outside the design system token set
- —Apply transitions using --motion-global-fade-in-duration / --motion-global-fade-out-duration tokens