Skip to content
Back to extractor

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 | 9999pxvar(--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