---
version: alpha
name: Substack
website: "https://substack.com"
description: >-
  A subscription-publishing surface anchored on a white canvas with near-black ink ("#363737") and a single warm orange voltage ("#ff6719") that carries every primary button, wordmark, and accent border. Display type runs Cahuenga serif at 24–32px in weight 500 — a literary serif sized like a magazine subhead rather than a marketing billboard — while UI runs system-ui across 13–15px for the post-stream feed of avatars, replies, and metadata. The geometry mixes "8px" cards with full pills ("9999px") for chips and buttons, and a "1px" hairline at "#eeeeee" carries every divider in place of shadows.

seo:
  title: "Substack Design System for React — Cahuenga serif, orange #ff6719"
  metaDescription: "Substack's homepage as a DESIGN.md file. White canvas, near-black ink #363737, orange voltage #ff6719, Cahuenga serif, system-ui UI. For React, Next.js, and AI tools."
  highlights:
    - "Single orange voltage — #ff6719 used as the only saturated brand color, carrying the wordmark, primary CTA fill, and orange chip surfaces with zero gradient extension"
    - "Cahuenga serif at 24–32px weight 500 — a literary serif treated at subhead scale rather than the 80px+ billboard most subscription platforms reach for"
    - "Near-black ink #363737 over pure white — not pure black, a warm dark gray that sits 8 points off black to soften the ink against long reading sessions"
    - "Pill-and-card binary — 9999px chips for tags and primary buttons sit alongside 8px and 12px cards, with no 16px or 20px middle radius"
    - "Hairline-only elevation — a 1px #eeeeee divider carries every section break in place of shadows, with zero gradient surfaces anywhere on the page"
  tags:
    - "News & Publishing"
  lastUpdated: "2026-05-13"
  author:
    name: "Dov Azencot"
    url: "https://x.com/dovazencot"
  opening: |
    Substack's homepage is a feed of posts dressed as a marketing page. The canvas is pure white, the ink is a warm near-black ("#363737"), and the entire identity hangs on a single warm orange ("#ff6719") that does the work of wordmark, primary button fill, accent border, and the kicker chip beneath the hero. There is no gradient mesh, no dark hero section, no abstract product illustration loop — the page below the fold is the platform itself, rendered as a vertical column of real posts with avatars, reply threads, and emoji reactions. The marketing surface and the product surface are the same surface.

    This DESIGN.md file packages the homepage system into a structured spec: 19 color tokens covering the orange voltage, the four-step gray ladder from `#363737` ink down to `#eeeeee` hairline, and the single sky-blue link color, 10 typography tokens spanning Cahuenga serif (20–32px) and system-ui (13–17px), a four-step radius scale where the pill (`9999px`), the 12px card, the 8px button, and the 4px detail each own a distinct surface class, an 8-step spacing scale built on a strict 4px-and-8px unit, and 18 component specifications covering the top nav, hero cluster, primary orange button, post card, comment thread row, and the publication-detail mini-cards. The format follows the Google Labs DESIGN.md specification.

    Feed the file to Claude, Cursor, or any agent that reads structured tokens and it reproduces Substack's exact voice — white reading-feed canvas, warm orange voltage held to one role, near-black ink at weight 500 for serif display, system-ui sans for every UI label. Where most subscription brands lean on a chromatic hero gradient and a 64px display headline, Substack commits the homepage to a vertical post-stream rendered at reading-body type sizes — that decision to show the product instead of describing it is the design. Reference the tokens directly in Tailwind config, paste the hex values into CSS variables, or use the spec as an audit checklist when reviewing whether a publishing surface looks like a marketing page or a feed.
  related:
    - href: "/design"
      title: "Browse all design systems"
      description: "The full directory of DESIGN.md files on shadcn.io, with live mockups for each."
    - href: "https://substack.com"
      title: "Substack — official site"
      description: "The subscription publishing platform itself — visit to see the post-stream homepage and orange voltage in motion."
    - href: "https://github.com/google-labs-code/design.md"
      title: "The DESIGN.md specification"
      description: "Google Labs' open spec for machine-readable design system files — the format this page is built on."
  questions:
    - id: "primary-color"
      title: "What is Substack's primary brand color?"
      answer: "Substack runs a single saturated voltage. The orange is `#ff6719` — an OKLCH lightness of 0.70 with chroma 0.20 at hue 42 — and it carries the wordmark, the primary CTA fill, accent chip borders, and the tertiary-accent button background. It appears 47 times on the homepage across text (18), border (18), and background (11). There is no secondary brand color, no gradient extension, and no fade. A second saturated value (`#0083d5` sky blue) handles inline link text and that is the only other chromatic moment in the system."
    - id: "typography"
      title: "What typography does Substack use, and what should I substitute?"
      answer: "Two families do the work. Cahuenga (a contemporary serif) carries display headlines at 24px / weight 500 with 30px line-height and the larger 32px / 39.68px tier for the hero. UI runs system-ui across 13px, 15px, and 17px in weights 400, 500, 600, and 700 — every nav link, button label, post-card title, body paragraph, and metadata line uses the system stack with no custom UI sans loaded. If Cahuenga is unavailable, Source Serif 4, Newsreader, Tiempos Text, or Spectral substitute cleanly at the published sizes — match the 500 weight rather than dropping to 400, since the serif is held at semibold to compensate for the modest 24–32px display range."
    - id: "shape-language"
      title: "Why does Substack mix pills with 8px cards?"
      answer: "The system uses four distinct radii — 9999px for fully rounded chips and the primary CTA, 12px for elevated post cards and the publication-detail mini-cards, 8px for buttons and form inputs, and 4px for the smallest detail surfaces like the orange notification badge. Each radius marks a different surface class: pills are interactive controls, 12px is a content container, 8px is a labeled control, and 4px is a microsurface. There is no 16px, no 20px, no 24px — the binary jump from 12px straight to 9999px keeps the post-stream feed visually anchored on cards while letting the CTA read as a chip rather than another box."
    - id: "elevation"
      title: "How does Substack handle elevation?"
      answer: "The system uses hairline-only elevation. A 1px `#eeeeee` divider — the third-most-frequent color on the page with 47 background occurrences — carries every section break, every post-card boundary, and every comment thread separator. There are no box shadows on the canvas, no atmospheric blurs, no surface ladders. Shadows appear only inside one published gradient (the green publication-detail block at the page floor), and even there the shadow is rendered as a flat dark fill rather than a soft blur. The post-stream feed reads as a single continuous surface with hairlines drawing the cells, which is the inverse of a SaaS dashboard where every card floats."
    - id: "use-in-project"
      title: "Can I use this DESIGN.md to build a subscription-publishing React app?"
      answer: "Yes. Feed the file to Claude, Cursor, or any agent that reads structured design tokens and it reproduces Substack's voice — white feed canvas, single orange voltage held to one role, Cahuenga serif at subhead scale, system-ui UI, hairline dividers between every post. The spec captures the full token vocabulary, the post-card and comment-thread component definitions, and the orange-on-white CTA chrome. The 18 component entries cover the top nav, hero cluster, primary button, post card, comment row, publication-detail mini-card, footer rail, and metadata roles. The reader-app surfaces (article reading view, paywall flow, podcast player, video embed) are out of scope — those live on different pages with their own type ladders."
    - id: "known-gaps"
      title: "What's missing from this DESIGN.md spec?"
      answer: "A handful of pieces are documented in the Known Gaps section. The article-reading surface uses a different serif tier (Spectral or `-apple-system-ui-serif` at 17px with 28px leading) that appears in the extraction but is not part of the homepage token set. The dashboard surface for writers, the paywall checkout flow, and the dark-mode reader inversion are not in scope. Motion timings for the hover states are not captured in the extracted CSS, and the publication-detail page templates that creators customize per Substack carry their own per-publication color overrides that bypass these tokens."

colors:
  canvas: "#ffffff"
  surface-card: "#ffffff"
  surface-muted: "#eeeeee"
  surface-tertiary: "#d7d7d7"
  ink-primary: "#363737"
  ink-secondary: "#777777"
  ink-muted: "#b6b6b6"
  ink-pure: "#000000"
  primary: "#ff6719"
  on-primary: "#ffffff"
  link-default: "#0083d5"
  hairline: "#eeeeee"
  border-strong: "#363737"
  border-muted: "#777777"
  surface-dark: "#232525"
  surface-marketing-green: "#2f6d5d"
  surface-marketing-lavender: "#c6c7fa"
  shadow-cast: "#000000"
  text-inverse: "#ffffff"

typography:
  display-lg:
    fontFamily: "Cahuenga, ui-serif, Georgia, Cambria, serif"
    fontSize: 32px
    fontWeight: 500
    lineHeight: "1.24"
    letterSpacing: "0"
  display-md:
    fontFamily: "Cahuenga, ui-serif, Georgia, Cambria, serif"
    fontSize: 24px
    fontWeight: 500
    lineHeight: "1.25"
    letterSpacing: "0"
  body-lg:
    fontFamily: "-apple-system-ui-serif, ui-serif, Spectral, Georgia, serif"
    fontSize: 17px
    fontWeight: 400
    lineHeight: "1.65"
    letterSpacing: "0"
  heading-sm:
    fontFamily: "system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial, sans-serif"
    fontSize: 17px
    fontWeight: 600
    lineHeight: "1.41"
    letterSpacing: "0"
  body-md:
    fontFamily: "system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial, sans-serif"
    fontSize: 15px
    fontWeight: 400
    lineHeight: "1.4"
    letterSpacing: "0"
  label-md:
    fontFamily: "system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial, sans-serif"
    fontSize: 15px
    fontWeight: 500
    lineHeight: "1.33"
    letterSpacing: "0"
  button-md:
    fontFamily: "system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial, sans-serif"
    fontSize: 15px
    fontWeight: 600
    lineHeight: "1.33"
    letterSpacing: "0"
  body-sm:
    fontFamily: "system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial, sans-serif"
    fontSize: 13px
    fontWeight: 400
    lineHeight: "1.4"
    letterSpacing: "0"
  label-sm:
    fontFamily: "system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial, sans-serif"
    fontSize: 13px
    fontWeight: 500
    lineHeight: "1.54"
    letterSpacing: "0"
  caption-strong:
    fontFamily: "system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial, sans-serif"
    fontSize: 13px
    fontWeight: 700
    lineHeight: "1.4"
    letterSpacing: "0"

rounded:
  none: "0px"
  xs: "4px"
  md: "8px"
  lg: "12px"
  full: "9999px"

spacing:
  xxs: "2px"
  xs: "4px"
  sm: "6px"
  md: "8px"
  base: "12px"
  lg: "16px"
  xl: "20px"
  "2xl": "24px"
  "3xl": "32px"

components:
  top-nav:
    backgroundColor: "{colors.canvas}"
    textColor: "{colors.ink-primary}"
    typography: "{typography.body-md}"
    height: "56px"
    padding: "0px 16px"
    border: "0"
  wordmark:
    backgroundColor: "transparent"
    textColor: "{colors.primary}"
    typography: "{typography.heading-sm}"
  nav-link:
    backgroundColor: "transparent"
    textColor: "{colors.ink-primary}"
    typography: "{typography.label-md}"
    padding: "8px 12px"
  button-primary:
    backgroundColor: "{colors.primary}"
    textColor: "{colors.on-primary}"
    typography: "{typography.button-md}"
    rounded: "{rounded.md}"
    padding: "0px 16px"
    height: "40px"
    border: "0"
  button-primary-pill:
    backgroundColor: "{colors.primary}"
    textColor: "{colors.on-primary}"
    typography: "{typography.button-md}"
    rounded: "{rounded.full}"
    padding: "8px 16px"
    height: "40px"
    border: "0"
  button-secondary:
    backgroundColor: "{colors.surface-muted}"
    textColor: "{colors.ink-primary}"
    typography: "{typography.button-md}"
    rounded: "{rounded.md}"
    padding: "0px 16px"
    height: "40px"
    border: "0"
  button-tertiary-accent:
    backgroundColor: "{colors.surface-muted}"
    textColor: "{colors.primary}"
    typography: "{typography.button-md}"
    rounded: "{rounded.md}"
    padding: "0px 12px"
    height: "32px"
    border: "0"
  hero-headline:
    backgroundColor: "transparent"
    textColor: "{colors.text-inverse}"
    typography: "{typography.display-lg}"
    padding: "0"
  section-headline:
    backgroundColor: "transparent"
    textColor: "{colors.ink-primary}"
    typography: "{typography.display-md}"
    padding: "0"
  body-paragraph:
    backgroundColor: "transparent"
    textColor: "{colors.ink-primary}"
    typography: "{typography.body-md}"
  post-card:
    backgroundColor: "{colors.surface-card}"
    textColor: "{colors.ink-primary}"
    typography: "{typography.body-md}"
    rounded: "{rounded.lg}"
    padding: "16px"
    border: "1px solid #eeeeee"
  post-card-title:
    backgroundColor: "transparent"
    textColor: "{colors.ink-primary}"
    typography: "{typography.heading-sm}"
  comment-row:
    backgroundColor: "transparent"
    textColor: "{colors.ink-primary}"
    typography: "{typography.body-md}"
    padding: "8px 0px"
    border: "0"
  byline:
    backgroundColor: "transparent"
    textColor: "{colors.ink-secondary}"
    typography: "{typography.body-sm}"
  link-inline:
    backgroundColor: "transparent"
    textColor: "{colors.link-default}"
    typography: "{typography.body-md}"
  hairline-divider:
    backgroundColor: "{colors.hairline}"
    height: "1px"
    border: "0"
  notification-badge:
    backgroundColor: "{colors.primary}"
    textColor: "{colors.on-primary}"
    typography: "{typography.caption-strong}"
    rounded: "{rounded.xs}"
    padding: "2px 6px"
  chip-tag:
    backgroundColor: "{colors.surface-muted}"
    textColor: "{colors.ink-primary}"
    typography: "{typography.label-sm}"
    rounded: "{rounded.full}"
    padding: "4px 12px"
  input-text:
    backgroundColor: "{colors.canvas}"
    textColor: "{colors.ink-primary}"
    typography: "{typography.body-md}"
    rounded: "{rounded.md}"
    padding: "8px 12px"
    height: "40px"
    border: "1px solid #eeeeee"
---

## Overview

Substack's homepage is a post-stream rendered as marketing. The canvas is pure white (`{colors.canvas}` — `#ffffff`) with **Substack Ink** (`{colors.ink-primary}` — `#363737`) as the default text — a warm near-black that sits eight points off pure black, just enough to soften the ink against long reading sessions. The only saturated voltage is **Substack Orange** (`{colors.primary}` — `#ff6719`), which carries the wordmark, the primary button fill, accent chip borders, and a single tertiary chip background. There is no secondary brand color, no gradient mesh, no abstract hero illustration. Below the fold the page is the product itself: a vertical column of real posts with avatars, reply threads, and emoji reactions.

**Product-as-marketing**: where most subscription brands open with a 64px display headline over a gradient hero, Substack drops a single 32px Cahuenga serif sentence into a card and then renders the actual feed — author avatars, post titles, reply counts, "Liked by Casey Newton" rows — directly beneath. The marketing page and the running app share a typeface, a card geometry, and the same orange chip. A visitor scrolling the homepage is reading the same chrome they would see logged in, which is a deliberate decision to flatten the funnel between "consider Substack" and "use Substack."

**Single-orange voltage as commitment**: the orange (`#ff6719`) appears 47 times across the homepage — 18 text occurrences, 18 borders, 11 background fills. It owns the wordmark, the primary CTA, the orange chip, and the notification badge. It never appears as a gradient, never fades into a secondary hue, never extends to a hover state in a darker variant. The only other saturated color in the system is `#0083d5` sky blue, scoped exclusively to inline link text. Every other surface — every card border, every nav link, every byline — sits in the four-step gray ladder from `#363737` ink down through `#777777` muted, `#b6b6b6` tertiary, and `#eeeeee` hairline.

**Key Characteristics:**
- **White canvas** (`{colors.canvas}` — `#ffffff`): the default surface across the entire homepage and every post card. The page is a single continuous white field divided by hairlines.
- **Substack Ink** (`{colors.ink-primary}` — `#363737`): the warm near-black for body type, post titles, and the wordmark's structural ink. Frequency 1698, the most-used color on the page.
- **Single-orange voltage**: `#ff6719` for the wordmark, primary CTA fill, accent chip, and notification badge. Reserved for the moments that need to read as Substack rather than as web UI.
- **Cahuenga serif at 24–32px / weight 500**: literary serif treated at subhead scale rather than billboard scale. The hero sits at 32px with 39.68px line-height; section headlines run at 24px with 30px line-height.
- **System-ui sans across 13–17px**: every nav link, button label, post-card title, byline, and body paragraph uses the platform stack with no custom UI sans loaded. Weight ladder 400 / 500 / 600 / 700.
- **Hairline-only elevation**: a 1px `#eeeeee` divider carries every section break and post-card boundary. Zero box shadows on the white canvas.
- **Pill-and-card binary**: 12px radius for post cards and detail mini-cards, 9999px for chips and pills, 8px for buttons and inputs, 4px for the notification badge — and nothing in the 16–20px middle.
- **Comment-row chrome inline**: reply threads render with avatar, name in `#363737`, body in `#363737`, timestamp in `#777777`, all at 13–15px system-ui. The marketing surface uses the exact same row geometry as the product.

## Colors

### Surface
- **Pure White** (`{colors.canvas}` — `#ffffff`) — frequency 102 (29 bg, 30 text, 27 border, 13 shadow). The canvas across the entire homepage, every post card, and every input. Pure white rather than a warmed off-white — Substack does not borrow the cream-newsprint move from Medium; the surface stays at OLED white.
- **Surface Muted** (`{colors.surface-muted}` — `#eeeeee`) — frequency 47 (47 bg). The second-most-frequent surface, used as the fill for secondary buttons, accent chip backgrounds, and the post-card hover surface. The lightest gray in the system that still reads as a distinct fill against the white canvas.
- **Surface Tertiary** (`{colors.surface-tertiary}` — `#d7d7d7`) — frequency 0 (a declared token, scoped to elevated card hover states and material translucency variables). Appears in the CSS but rarely renders on the marketing homepage.

### Ink
- **Substack Ink** (`{colors.ink-primary}` — `#363737`) — frequency 1698 (863 text, 835 border). The most-used color on the page by a factor of three. Carries the wordmark, every post-card title, every body paragraph, every nav link, and every 1px ink border. Not pure black — a warm near-black sitting at OKLCH lightness `0.34` with a faint cool chroma of `0.001` at hue `197`, which prevents the ink from looking like a screen-pixel black against the white canvas.
- **Ink Secondary** (`{colors.ink-secondary}` — `#777777`) — frequency 544 (272 text, 272 border). The metadata gray for bylines, timestamps, reply counts, and tertiary-button outlines. Sits at OKLCH lightness `0.57`. Used as a workhorse text color for everything that should read as supporting rather than primary.
- **Ink Muted** (`{colors.ink-muted}` — `#b6b6b6`) — frequency 3 (3 border). Reserved for disabled-button labels and tertiary background fills. Rare on the homepage — appears only inside disabled-state CSS variables.
- **Ink Pure** (`{colors.ink-pure}` — `#000000`) — frequency 49 (1 text, 3 bg, 12 border, 33 shadow). Used almost exclusively as a shadow color and as the dark-mode utility ink. Not the default text color — Substack reserves `#363737` for type and pushes pure black into shadows and modal overlays.

### Brand
- **Substack Orange** (`{colors.primary}` — `#ff6719`) — frequency 47 (18 text, 11 bg, 18 border). The single saturated brand voltage. CSS variables include `--color-accent`, `--color-button-primary-bg`, `--color-bg-accent`, and `--color-nav-logo`. Reserved for the wordmark glyph, the primary CTA fill, accent chip borders, and the orange notification badge. Never extended into a hover gradient — hover darkens via `--color-accent-bg-orange-hover`, a single-step darker variant rather than a hue blend.
- **Link Sky** (`{colors.link-default}` — `#0083d5`) — frequency 10 (5 text, 5 border). The only other saturated color in the system, scoped to inline link text and the highlight semantic. Not a brand color — a utility color borrowed from the broader semantic palette for inline links.

### Structural
- **Hairline** (`{colors.hairline}` — `#eeeeee`): the 1px divider color between every section, every post card, and every comment row. Doubles as the secondary-surface fill.
- **Surface Dark** (`{colors.surface-dark}` — `#232525`): the dark canvas for the publication-detail card at the page floor and the dark-mode utility variables. Appears once on the homepage as a featured card background.
- **Surface Marketing Green** (`{colors.surface-marketing-green}` — `#2f6d5d`): the saturated green fill on the "Start a publication on Substack" promotional card near the page footer. Used as a single editorial color block, not as a recurring brand token.
- **Surface Marketing Lavender** (`{colors.surface-marketing-lavender}` — `#c6c7fa`): a pale lavender utility surface defined as `--color-marketing-lavender`, used on rare promotional tiles.
- **Shadow Cast** (`{colors.shadow-cast}` — `#000000`): used at low alpha for the rare card-shadow moment near the page floor.

### Gradient System
Substack uses **zero gradient backgrounds on the homepage canvas**. Every primary surface is a flat single-hex fill. A handful of low-frequency gradient values (a brown, a blue, a tan) appear deep in the CSS, but they live inside cover-image overlay utilities for publication header backgrounds and never surface on the marketing page itself. The orange voltage does not glow, the wordmark does not have a gradient glyph, and the hero card does not fade into the canvas.

## Typography

### Font Family
Two families do the work. **Cahuenga** (a contemporary serif) is the display voice — used at 24px and 32px in weight 500 for the hero card headline and section subheads. **System-ui** is the UI workhorse — used across 13px, 15px, and 17px at weights 400, 500, 600, and 700 for every nav link, button label, post-card title, byline, body paragraph, and metadata row. A third family appears rarely: `-apple-system-ui-serif` (falling back to Spectral / Georgia) renders post-card body excerpts at 17px / 28px line-height — a reading-serif treatment for previewing newsletter content inside the feed. There is no italic on the homepage, no monospace, and no third UI sans.

### Hierarchy

| Token | Size | Weight | Line Height | Use |
|---|---|---|---|---|
| `{typography.display-lg}` | 32px | 500 | 1.24 | Hero card headline ("Make money doing the work you believe in") |
| `{typography.display-md}` | 24px | 500 | 1.25 | Section subheads ("See work, in your work") |
| `{typography.body-lg}` | 17px | 400 | 1.65 | Post-card body excerpts (Spectral serif fallback) |
| `{typography.heading-sm}` | 17px | 600 | 1.41 | Post-card titles and section-row headings |
| `{typography.body-md}` | 15px | 400 | 1.40 | Body paragraphs, post-card body, nav links |
| `{typography.label-md}` | 15px | 500 | 1.33 | Nav link labels and metadata strong text |
| `{typography.button-md}` | 15px | 600 | 1.33 | Primary and secondary button labels |
| `{typography.body-sm}` | 13px | 400 | 1.40 | Bylines, timestamps, reply counts, footer items |
| `{typography.label-sm}` | 13px | 500 | 1.54 | Chip-tag labels and emphasized metadata |
| `{typography.caption-strong}` | 13px | 700 | 1.40 | Notification-badge counts and emphasized inline strong |

### Principles

**Serif-at-subhead scale**: Cahuenga caps out at 32px on the homepage. Where most subscription platforms reach for an 80px serif hero — substack runs the editorial serif at 24–32px and trusts the post-stream beneath it to do the persuasion. The serif is sized like a magazine subhead, not a billboard.

**System-ui as the brand stack**: every UI label, button, and post-card title uses the platform stack rather than a custom UI sans. No Söhne, no Inter, no Hanken — Substack treats system-ui as the load-bearing UI family. The decision is visible everywhere: nav at 15px system-ui, post titles at 17px system-ui, bylines at 13px system-ui.

**Weight 500 holds the serif**: where the sans ladder runs 400 / 500 / 600 / 700, the Cahuenga serif sits exclusively at weight 500. Not 400 (too thin against the white canvas at 24px), not 600 (too aggressive for a literary voice). A single weight inside a single family for the entire display ladder.

### Note on Font Substitutes
Cahuenga is a licensed contemporary serif. If unavailable, **Source Serif 4**, **Newsreader**, **Tiempos Text**, or **Spectral** substitute cleanly at the published sizes — hold the 500 weight rather than dropping to 400, and the 24–32px size range needs no metric adjustment for any of those substitutes. For the system-ui stack, no substitute is needed — system-ui already resolves to the platform's native UI sans (San Francisco on macOS, Segoe UI on Windows, Roboto on Android), which is the intended behavior.

## Layout

### Spacing System
- **Base unit:** 4px with a strict 8px primary step.
- **Tokens:** `{spacing.xxs}` 2px · `{spacing.xs}` 4px · `{spacing.sm}` 6px · `{spacing.md}` 8px · `{spacing.base}` 12px · `{spacing.lg}` 16px · `{spacing.xl}` 20px · `{spacing.2xl}` 24px · `{spacing.3xl}` 32px.
- **Top-nav padding:** 0 vertical, 16px horizontal — the nav itself is 56px tall.
- **Button padding:** 0px vertical, 16px horizontal at 40px button height (gives `~10px` visual breathing room above and below the 20px-tall label).
- **Card padding:** 16px on post cards, 24px on featured publication-detail blocks.
- **Inline gap:** 8px is the dominant gap in the extracted spacing (239 occurrences), used between every avatar and label, between every metadata item, and between every button and the next.

### Grid & Container
- **Max content width:** ~1280px with the post-stream column constrained to roughly 720px center-column width.
- **Column patterns:** a two-column hero (text card left, sample post stream right) on desktop, collapsing to a single stacked column on mobile.
- **Outer padding:** 16px on mobile, scaling to 24px on tablet and 32px on desktop.

### Whitespace Philosophy
The page reads as a vertical scroll of post-card cells separated by 16px gaps, with the cells themselves carrying 16px internal padding. The post-stream is dense — closer to a newsfeed than a magazine layout — but the 1px `#eeeeee` hairline between cells and the generous 24px section gaps prevent the density from crowding. Substack uses spacing the way a feed app does, not the way a magazine does.

### Border Radius Scale
- **`{rounded.none}` 0px:** hairline dividers and full-bleed image fills.
- **`{rounded.xs}` 4px:** the notification badge and other microsurfaces.
- **`{rounded.md}` 8px:** buttons, form inputs, and most labeled controls. 72 occurrences in the extracted radii.
- **`{rounded.lg}` 12px:** post cards and publication-detail mini-cards. 50 occurrences.
- **`{rounded.full}` 9999px:** chips, avatars, and pill-form CTAs. 140 occurrences — the most-frequent radius on the page, driven by every circular avatar in the post-stream.

The jump from 12px straight to 9999px without a 16px or 20px middle is the system's shape signature. Cards are 12px and chips are pills — there is no halfway softer card.

## Elevation

Substack's depth philosophy is **hairline-on-white**. There are zero box shadows on the canvas, zero atmospheric blurs, and zero surface ladders between the white canvas and the post cards.

| Level | Treatment | Use |
|---|---|---|
| 0 | No border, no shadow | Default white canvas |
| 1 | 1px `#eeeeee` border | Post cards, input fields, every section divider |
| 2 | `#eeeeee` filled surface on white canvas | Secondary buttons, accent chips |
| 3 | `#ff6719` saturated fill on white canvas | Primary CTA — depth via voltage, not shadow |
| 4 | `#232525` dark surface fill | The single dark-canvas publication-detail card near the page floor |

When something needs to stand out it does not get a shadow — it gets either the orange fill or the dark surface fill. The single shadow color in the system (`#000000` at low alpha) appears 33 times in extracted shadows but resolves to barely-visible 1px-2px casts on the featured cards near the page floor, not on the post-stream feed itself.

## Shapes

The system uses **four distinct radii** mapped to four surface classes. Pills (`9999px`) are for chips, avatars, and the pill-form primary CTA. Cards (`12px`) are for post cards and publication-detail mini-cards. Buttons and inputs (`8px`) own the labeled-control class. The 4px microsurface is reserved for the notification badge and similar tiny corner treatments. The discipline is strict — no `16px` rounded card, no `20px` button, no `24px` feature tile.

The pill-and-card binary keeps the post-stream visually grounded on rectangular cells while letting the CTA and the chip read as interactive controls. The orange chip near the top of the hero card is `9999px`; the post card beneath it is `12px`. That contrast — pill chip riding on a rounded card — is the visual rhythm of the entire page.

## Components

### Navigation

**`top-nav`** — White canvas bar at `56px` height with the orange Substack wordmark left-aligned and a `system-ui` 15px nav rail to the right. Padding: 0 vertical, 16px horizontal. No bottom border — the post-stream feed beneath the nav handles its own hairlines.

**`wordmark`** — The Substack logo rendered in orange (`#ff6719`) — the only place the orange ink appears as a typographic glyph rather than as a fill. Set in `{typography.heading-sm}` at 17px / weight 600.

**`nav-link`** — System-ui 15px weight 500 in Substack Ink (`#363737`). Padding 8px vertical, 12px horizontal. No underline at rest, no chromatic hover.

### Buttons

**`button-primary`** — Substack Orange (`#ff6719`) fill, white text, system-ui 15px weight 600, `{rounded.md}` 8px radius, `0px 16px` padding, `40px` total height. The default primary CTA across the homepage — usually "Start your Substack" or "Subscribe."

**`button-primary-pill`** — Same orange fill and label, with `{rounded.full}` 9999px radius applied instead of 8px. Used inside post-card chrome where the button should read as a chip rather than a labeled control.

**`button-secondary`** — Surface Muted (`#eeeeee`) fill, Substack Ink text, same 15px / weight 600 label and 8px radius. The default ghost button for secondary actions in the post-stream.

**`button-tertiary-accent`** — Surface Muted (`#eeeeee`) fill with Substack Orange text. The orange-on-gray chip used for tertiary CTAs like "Get it" on a recommended-publication card. 32px tall, `0px 12px` padding.

### Editorial Display

**`hero-headline`** — Cahuenga serif 32px weight 500 in white over a colored hero-card surface. Sized for one phrase: "Make money doing the work you believe in." Sits at the top of the page inside a dark or saturated card rather than over the white canvas — the hero is contained inside the card geometry.

**`section-headline`** — Cahuenga serif 24px weight 500 in Substack Ink. Used for section subheads like "See work, in your work" and "Start a publication on Substack." The recurring editorial voice between feed sections.

### Post Stream

**`post-card`** — White surface with a 1px `#eeeeee` hairline border, `{rounded.lg}` 12px radius, 16px internal padding. Carries an author avatar, post title, body excerpt, and a metadata row of likes / comments. The fundamental unit of the homepage.

**`post-card-title`** — System-ui 17px weight 600 in Substack Ink. The post-title voice — set heavier than body copy at the same size to register as a hierarchical step without leaving the system-ui family.

**`comment-row`** — Transparent background with 8px vertical padding. Holds a 13px byline in `#777777`, a 15px body in `#363737`, and a metadata row of timestamps and reply counts. The comment chrome inside post cards uses the exact same row geometry that appears on the logged-in product surface.

**`byline`** — System-ui 13px weight 400 in Ink Secondary (`#777777`). Author names, timestamps, and "Liked by X" rows.

### Inline

**`body-paragraph`** — System-ui 15px weight 400 with `1.40` line-height in Substack Ink. The default body voice across the marketing page and inside post-card body copy.

**`link-inline`** — Inherits the body-paragraph type with the color set to Link Sky (`#0083d5`). The only saturated color other than orange that appears in text, scoped exclusively to inline links.

**`hairline-divider`** — A 1px `#eeeeee` horizontal rule. Sits between every section and inside every comment-thread separator. The entire structural-elevation system in one token.

**`notification-badge`** — Substack Orange fill, white text, system-ui 13px weight 700, `{rounded.xs}` 4px radius, `2px 6px` padding. Sits on top of nav icons to indicate unread counts — the only place the 4px radius appears.

### Chips & Inputs

**`chip-tag`** — Surface Muted (`#eeeeee`) fill, Substack Ink text, system-ui 13px weight 500, `{rounded.full}` 9999px radius, `4px 12px` padding. Used for category tags, publication-genre chips, and the orange-accent chip beneath the hero.

**`input-text`** — White fill with a 1px `#eeeeee` hairline border, `{rounded.md}` 8px radius, system-ui 15px weight 400 type at 40px height. The default form-field chrome for newsletter signup inputs and reply boxes.

## Do's and Don'ts

### Do
- **Use `#ff6719` only for the wordmark, primary CTA, accent chip, and notification badge.** The voltage appears 47 times across the homepage and never as a gradient or a hover fade. Extending it to a section background would dilute its role.
- **Hold Cahuenga serif at weight 500 across the 24–32px range.** The literary serif voice depends on the medium weight — dropping to 400 makes it too thin against white, jumping to 600 makes it shout.
- **Pair Cahuenga for display, system-ui for everything else.** The two-family discipline includes the deliberate decision to skip a custom UI sans. Adding Inter or Söhne breaks the platform-native UI voice.
- **Use 12px for post cards and 9999px for chips.** The binary card-and-pill geometry is the system's shape signature.
- **Draw section boundaries with a 1px `#eeeeee` hairline.** That single hairline does the entire elevation job — the white canvas stays perfectly flat.

### Don't
- **Don't use `#777777` (Ink Secondary) for primary headlines or button labels.** It is a metadata-only ink (frequency 544, used entirely on bylines, timestamps, and tertiary borders). Headlines and buttons take `#363737`.
- **Don't introduce a `16px` or `20px` border-radius on any surface.** The radius scale is `4 / 8 / 12 / 9999` — a `16px` rounded post card breaks the card-and-pill rhythm and reads as a SaaS dashboard tile.
- **Don't add box-shadows to the post-stream feed.** Substack's depth comes from the 1px hairline border, not from atmospheric blur. A `0 2px 4px rgba(0,0,0,0.05)` would import a card-floating feel that the feed is engineered to avoid.
- **Don't replace the system-ui stack with Inter, Söhne, or a custom UI sans.** The decision to use the platform-native UI family is deliberate — a custom sans turns the marketing page into a SaaS landing and breaks the feed's native-app feel.
- **Don't use `#0083d5` (Link Sky) anywhere other than inline link text.** It is scoped to `<a>` tags and the highlight semantic only. Applied to a button or chip it reads as a Material-style action color, which the system is not.
- **Don't lift the Cahuenga serif above 32px on the marketing page.** The serif is sized as a subhead, not as a billboard — pushing it to 56px or 80px collapses the post-stream-feels-like-the-product voice into a conventional marketing layout.
- **Don't fill the right column with a static product screenshot.** The right column carries an actual sample post-stream — real avatars, real comment rows, real reactions. Replacing it with a UI mockup turns the homepage from a feed into a landing page.

## Known Gaps

- **Article-reading surface:** the long-form post reading view past the homepage uses a different type ladder (Spectral or `-apple-system-ui-serif` body at 17px with 28px line-height) that appears in the extraction but is not the marketing-page voice captured here.
- **Writer dashboard:** the authenticated authoring surface (post composer, analytics, subscriber management) has its own component vocabulary not in scope.
- **Paywall checkout flow:** the Stripe-backed subscription flow uses its own form chrome and is not extracted.
- **Per-publication overrides:** each Substack publication can override the orange voltage with a custom hex applied to wordmark, CTA, and accent chip. The extraction captures the platform defaults; individual publications drift from these tokens.
- **Dark-mode reader inversion:** the reader-facing dark mode swaps the white canvas for a near-black surface (`#232525` appears in the dark-mode CSS variables), but full dark-mode tokens are not part of the homepage spec.
- **Motion and transition timings:** hover states on the primary CTA and nav links are described as color shifts but specific transition durations and easings are not captured in the extracted CSS.
- **Podcast player and video embed components:** Substack's audio and video chrome lives inside post-detail surfaces, not on the marketing homepage, and is not tokenized here.
