Substack
Add this design system to use its color palette, typography, spacing & other tokens while creating your own designs.
Publishing platform. White with warm off-white, one assertive orange, a literary Cahuenga soft serif.
Palette
Typography
32px
24px
19px
15px
13px
15px
Spacing & Shape
| Token | Value | Preview |
|---|---|---|
| xs | 4px | |
| sm | 8px | |
| md | 12px | |
| lg | 16px | |
| xl | 24px | |
| 2xl | 32px | |
| 3xl | 48px |
Border Radius
| Token | Value | Preview |
|---|---|---|
| sm | 8px | |
| md | 12px | |
| full | 9999px |
design.md
tokens (raw)
name: substack-design
version: alpha
description: >
Substack's canvas is plain white (#fff) with a near-black charcoal ink (#363737, never
pure black) and a single, unmistakable brand voltage: Substack orange (#ff6719) — the
flag/bookmark logo, every "Start your Substack" / "Create" CTA, and the outlined
"Subscribe" affordance. The system is split by font role: long-form reading is set in the
literary serif Spectral, big display headers in the proprietary serif Cahuenga, while the
app chrome (nav, buttons, meta) uses the native system-ui sans — an editorial/product
hybrid that signals "a writing platform, not a SaaS dashboard." Geometry mixes 8px action
buttons, fully-pill (9999px) chips and secondary buttons, and 12px cards. Depth is almost
nonexistent: hairline borders at 10% black, no shadows. The personality is warm, bookish,
and quiet — orange is the only color, and it is rationed.
colors:
# Brand
primary: '#ff6719' # Substack orange — logo, primary CTAs, Subscribe accent
primary-darken: '#ff5600' # hover/active
on-primary: '#ffffff'
primary-soft: 'rgba(255,103,25,0.4)' # faint orange wash
# Surface (light)
surface: '#ffffff' # canvas, cards
surface-secondary: '#f0f0f0'# secondary cover bg / button fill (contrast-1)
# Text (charcoal ramp, never pure black)
on-surface: '#363737' # primary text (cover_print_primary)
on-surface-secondary: '#757575' # secondary text / muted meta
on-surface-tertiary: '#b6b6b6' # tertiary / timestamps in app
on-surface-muted: '#777777' # app meta (likes, counts)
# Neutral contrast ramp (borders, fills, dividers)
contrast-1: '#f0f0f0'
contrast-2: '#dddddd'
contrast-3: '#b7b7b7'
contrast-4: '#929292'
contrast-5: '#515151'
detail: '#e6e6e6' # theme detail / light dividers
# Hairlines
hairline: 'rgba(0,0,0,0.1)' # card borders
typography:
display:
fontFamily: '"Cahuenga", Spectral, Georgia, serif'
fontSize: 32px # large display headers
fontWeight: 500
lineHeight: 1.24
letterSpacing: 0
reading-lg:
fontFamily: '"Spectral", Georgia, "Times New Roman", serif'
fontSize: 24px # post titles / large reading
fontWeight: 500
lineHeight: 1.3
letterSpacing: 0
reading-body:
fontFamily: '"Spectral", Georgia, "Times New Roman", serif'
fontSize: 19px # long-form body copy
fontWeight: 400
lineHeight: 1.6
letterSpacing: 0
ui-label:
fontFamily: 'system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif'
fontSize: 15px # buttons, author names, app body
fontWeight: 600
lineHeight: 20px
letterSpacing: 0
ui-meta:
fontFamily: 'system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif'
fontSize: 13px # meta, small Subscribe, tab labels
fontWeight: 500
lineHeight: 1.4
letterSpacing: 0
ui-body:
fontFamily: 'system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif'
fontSize: 15px
fontWeight: 400
lineHeight: 1.5
letterSpacing: 0
rounded:
sm: 8px # action buttons ("Start your Substack", "Subscribe")
md: 12px # cards
full: 9999px # pills: Sign in, count chips, secondary buttons
spacing: # base unit 8px
xs: 4px
sm: 8px
md: 12px
lg: 16px
xl: 24px
2xl: 32px
3xl: 48px
components:
button-primary: # "Start your Substack" / "Create" / "Create account"
backgroundColor: '{colors.primary}'
textColor: '{colors.on-primary}'
typography: '{typography.ui-label}'
rounded: '{rounded.sm}'
padding: '0 16px'
height: '32px'
button-secondary: # "Sign in" (grey pill)
backgroundColor: '{colors.surface-secondary}'
textColor: '{colors.on-surface}'
typography: '{typography.ui-label}'
rounded: '{rounded.full}'
padding: '0 16px'
button-subscribe: # outlined orange "Subscribe"
backgroundColor: 'transparent'
textColor: '{colors.primary}'
borderColor: '{colors.primary}'
borderWidth: '1px'
typography: '{typography.ui-meta}'
rounded: '{rounded.sm}'
padding: '0 6px'
button-outline: # "Learn more" (subtle border)
backgroundColor: 'transparent'
textColor: '{colors.on-primary}'
borderColor: '{colors.contrast-3}'
borderWidth: '1px'
typography: '{typography.ui-label}'
rounded: '{rounded.sm}'
padding: '0 16px'
count-chip: # like/comment/restack counts
backgroundColor: 'transparent'
textColor: '{colors.on-surface-muted}'
typography: '{typography.ui-body}'
rounded: '{rounded.full}'
padding: '0 8px'
tab: # "For you ▾" feed selector
backgroundColor: 'transparent'
textColor: '{colors.on-surface-secondary}'
typography: '{typography.ui-meta}'
rounded: '{rounded.sm}'
padding: '0 6px'
card: # feed post card
backgroundColor: '{colors.surface}'
borderColor: '{colors.hairline}'
borderWidth: '1px'
rounded: '{rounded.md}'
textColor: '{colors.on-surface}'
padding: '12px'
nav-item: # left rail (Home, Subscriptions, Chat…)
backgroundColor: 'transparent'
textColor: '{colors.on-surface}'
typography: '{typography.ui-body}'
iconColor: '{colors.on-surface-secondary}'
search-input:
backgroundColor: '{colors.surface}'
borderColor: '{colors.detail}'
borderWidth: '1px'
rounded: '{rounded.md}'
typography: '{typography.ui-body}'
motion:
easing-standard: 'cubic-bezier(0.4, 0, 0.2, 1)'
duration-standard: 200ms
icons:
style: outline
stroke: 1.75px
sizes: { sm: 16px, md: 24px }
color: '{colors.on-surface-secondary}'Substack
substack-design · alpha
Overview
Substack runs a plain white canvas (#fff) with a warm charcoal ink (#363737,
deliberately not pure black) and exactly one brand color: Substack orange #ff6719 —
the flag/bookmark logo mark, every "Start your Substack" / "Create" CTA, and the outlined
"Subscribe" affordance scattered through the feed. The defining structural choice is the
dual-font split by role: long-form reading uses the literary serif Spectral, big
display headers use the proprietary serif Cahuenga, and all app chrome (left-rail nav,
buttons, author names, meta, timestamps) is set in native system-ui sans. That serif +
system-sans hybrid is the whole brand thesis — this is a place for writing and reading,
not a product dashboard. Geometry is mixed-but-friendly: 8px action buttons, fully-
pill (9999px) chips and secondary buttons, 12px cards, round avatars. Depth is nearly
absent — cards are outlined with a 10%-black hairline, no drop shadows anywhere. The
personality is warm, bookish, and quiet: orange is rationed to a few CTAs per screen and
everything else is charcoal-on-white.
Colors
Brand — primary #ff6719 (Substack orange) is the only chromatic color in the entire
system: the logo, primary buttons ("Start your Substack", "Create", "Create account"), the
outlined "Subscribe" buttons, and active accents. It deepens to primary-darken #ff5600
on hover. A faint primary-soft rgba(255,103,25,.4) wash backs occasional highlights.
Surface — canvas surface #fff; secondary covers and the grey "Sign in" button use
surface-secondary #f0f0f0.
Text — a charcoal ramp, never pure black: on-surface #363737 (primary),
on-surface-secondary #757575 (secondary/meta), on-surface-tertiary #b6b6b6 and the
app's on-surface-muted #777 for counts and timestamps.
Neutral contrast ramp — contrast-1 #f0f0f0 → contrast-5 #515151 (plus detail #e6e6e6) provide borders, button fills, dividers, and disabled states without introducing
any new hue.
Hairlines — card edges use hairline rgba(0,0,0,0.1); lighter dividers use detail #e6e6e6.
Typography
Three families, assigned by role:
- Cahuenga (proprietary serif) — large display headers; weight 500. Substitute: Spectral or a high-contrast serif.
- Spectral (Google serif) — long-form reading: post titles (24px/500) and body (19px/400, line-height ~1.6). This is the literary voice.
- system-ui sans — all UI chrome: buttons and author names (15px/600), meta and small "Subscribe"/tabs (13px/500), app body (15px/400).
| Token | Family | Size | Weight | Line-height | Usage |
|---|---|---|---|---|---|
| display | Cahuenga serif | 32px | 500 | 1.24 | Large display headers |
| reading-lg | Spectral serif | 24px | 500 | 1.3 | Post titles |
| reading-body | Spectral serif | 19px | 400 | 1.6 | Long-form body copy |
| ui-label | system-ui sans | 15px | 600 | 20px | Buttons, author names |
| ui-meta | system-ui sans | 13px | 500 | 1.4 | Meta, small Subscribe, tabs |
| ui-body | system-ui sans | 15px | 400 | 1.5 | App body, counts |
Layout
Base unit 8px; scale 4 / 8 / 12 / 16 / 24 / 32 / 48. The signed-in app is a fixed left rail (Home, Subscriptions, Chat, Activity, Explore, Profile + an orange "Create" button) beside a centered single-column feed of post cards. A "For you ▾" tab selector sits above the feed; a search field and a "Log in or sign up" panel anchor the top-right. Cards stack vertically with generous internal padding (12px) and round avatars. Whitespace is ample and reading-first; line lengths stay comfortable for long-form.
Elevation & Depth
Flat. Substack uses outlines, not shadows: cards carry a 1px rgba(0,0,0,.1) border
and 12px radius with no drop shadow. The login popover is the rare element with a soft
border + subtle elevation. There are no gradients, glows, or layered shadows — depth is
communicated purely by hairlines and whitespace.
Shapes
Mixed but intentional: 8px for action buttons ("Start your Substack", "Subscribe", "Learn more"), fully-pill (9999px) for the grey "Sign in" button and all count chips (likes, comments, restacks), and 12px for feed cards. Avatars are circular. The blend of soft-rect buttons and pill chips reads friendly and casual rather than corporate.
Components
- button-primary — orange
#ff6719fill, white text, 8px radius, 32px tall ("Start your Substack", "Create"). - button-secondary —
#f0f0f0grey fill, charcoal text, full pill ("Sign in"). - button-subscribe — transparent, orange text + 1px orange border, 8px radius, 13px ("Subscribe").
- count-chip — transparent pill, muted-grey text, 13–15px, for like/comment/restack counts.
- tab — "For you ▾" feed selector in muted system-sans.
- card — white fill, 1px hairline, 12px radius, 12px padding; the feed post unit.
- nav-item — left-rail entries with 24px outline icon + charcoal label.
- search-input — white fill,
#e6e6e6border, 12px radius.
Motion
Calm and minimal — ~200ms standard ease for hovers, button states, and popover
reveals. No bounce, no parallax, no entrance animations on the feed. Motion is purely
functional: orange CTAs darken to #ff5600 on hover, chips highlight on interaction.
Iconography
Outline icons (~1.75px stroke) on a 24px grid, rendered 16/24px, colored
on-surface-secondary #757575 and darkening to on-surface when active. The fixed brand
mark is the orange flag/bookmark logo — the single place full saturation always
appears. Avatars are circular photos; no colorized or filled icons elsewhere.
Do's and Don'ts
- Do keep the canvas white with a charcoal
#363737ink — never pure black. - Do reserve orange
#ff6719for the logo, primary CTAs, and Subscribe — ration it. - Do set reading content in Spectral serif and UI chrome in system-ui sans (the split is the brand).
- Do use 8px action buttons, pill count-chips, and 12px outlined cards.
- Do separate content with hairlines and whitespace, not shadows.
- Don't introduce a second accent color — the system is monochrome + orange.
- Don't set body reading copy in a sans-serif; the serif is the editorial signature.
- Don't add drop shadows or gradients to cards.
- Don't darken the canvas; the surface is light (a dark reading theme exists per-publication, but the platform chrome is white).
Known Gaps
- Substack exposes a compact theming
:rootset (--background_pop, contrast ramp, cover print colors) captured above, so the orange, charcoal ramp, and neutral contrasts are exact. Values were read from the logged-out app/feed view; the marketing homepage and per-publication themed surfaces (which recolor--background_pop) were not separately sampled. Cahuenga is proprietary — substitute Spectral or a contrast serif.