---
version: alpha
name: PostHog-design-analysis
description: |
A playful developer-tools system rendered on a warm cream canvas with hand-drawn hedgehog mascots dotted across every page like marginalia in a sketchbook. The chrome reads like a friendly engineering blog: olive-gray ink (#4d4f46) for body, deep olive-charcoal (#23251d) for headlines, IBM Plex Sans Variable typography in tight 1.43-line-height paragraphs, and a single saturated yellow-orange CTA pill (#f7a501) carrying every primary action. The system actively rejects the genre's typical somber dark-tech aesthetic in favor of a creamy, textbook-illustration sensibility — bordered cards stack on the cream canvas with 4–6px radii, doc sidebars use rounded outline-icon mini-illustrations, and the home page leans on cartoon characters (hedgehogs in lab coats, hedgehogs at terminals, hedgehogs in lounge chairs) as its signature decoration. Code samples and product analytics charts live inside white-on-cream cards with thin olive borders; the contrast between the playful illustration and the data-dense product imagery is the brand's signature voice.
colors:
primary: "#f7a501"
primary-pressed: "#dd9001"
primary-active: "#b17816"
on-primary: "#23251d"
ink: "#23251d"
body: "#4d4f46"
charcoal: "#33342d"
mute: "#6c6e63"
ash: "#9b9c92"
stone: "#b6b7af"
hairline: "#bfc1b7"
hairline-soft: "#dcdfd2"
on-dark: "#ffffff"
canvas: "#eeefe9"
surface-soft: "#e5e7e0"
surface-card: "#ffffff"
surface-doc: "#fcfcfa"
surface-dark: "#23251d"
link-blue: "#1d4ed8"
link-teal: "#1078a3"
accent-blue: "#2c84e0"
accent-blue-soft: "#dceaf6"
accent-red: "#cd4239"
accent-red-soft: "#f7d6d3"
accent-green: "#2c8c66"
accent-green-soft: "#d9eddf"
accent-purple: "#7c44a6"
accent-purple-soft: "#e7d8ee"
focus-ring: "rgba(59,130,246,0.5)"
typography:
display-xl:
fontFamily: IBM Plex Sans Variable
fontSize: 36px
fontWeight: 700
lineHeight: 1.5
letterSpacing: 0
display-lg:
fontFamily: IBM Plex Sans Variable
fontSize: 24px
fontWeight: 800
lineHeight: 1.33
letterSpacing: -0.6px
heading-lg:
fontFamily: IBM Plex Sans Variable
fontSize: 21px
fontWeight: 700
lineHeight: 1.4
letterSpacing: -0.5px
heading-md:
fontFamily: IBM Plex Sans Variable
fontSize: 20px
fontWeight: 700
lineHeight: 1.4
letterSpacing: 0
heading-sm:
fontFamily: IBM Plex Sans Variable
fontSize: 18px
fontWeight: 700
lineHeight: 1.5
letterSpacing: 0
textTransform: uppercase
heading-sm-mixed:
fontFamily: IBM Plex Sans Variable
fontSize: 18px
fontWeight: 600
lineHeight: 1.56
letterSpacing: 0
body-md:
fontFamily: IBM Plex Sans Variable
fontSize: 16px
fontWeight: 400
lineHeight: 1.5
letterSpacing: 0
body-strong:
fontFamily: IBM Plex Sans Variable
fontSize: 16px
fontWeight: 600
lineHeight: 1.5
letterSpacing: 0
body-sm:
fontFamily: IBM Plex Sans Variable
fontSize: 15px
fontWeight: 400
lineHeight: 1.71
letterSpacing: 0
body-sm-strong:
fontFamily: IBM Plex Sans Variable
fontSize: 15px
fontWeight: 600
lineHeight: 1.71
letterSpacing: 0
body-xs:
fontFamily: IBM Plex Sans Variable
fontSize: 14px
fontWeight: 500
lineHeight: 1.43
letterSpacing: 0
caption-md:
fontFamily: IBM Plex Sans Variable
fontSize: 14px
fontWeight: 700
lineHeight: 1.71
letterSpacing: 0
caption-sm:
fontFamily: IBM Plex Sans Variable
fontSize: 13px
fontWeight: 500
lineHeight: 1.5
letterSpacing: 0
caption-xs:
fontFamily: IBM Plex Sans Variable
fontSize: 12px
fontWeight: 600
lineHeight: 1.33
letterSpacing: 0
textTransform: uppercase
utility-xs:
fontFamily: IBM Plex Sans Variable
fontSize: 12px
fontWeight: 700
lineHeight: 1.33
letterSpacing: 0
textTransform: uppercase
link-md:
fontFamily: IBM Plex Sans Variable
fontSize: 16px
fontWeight: 400
lineHeight: 1.5
letterSpacing: 0
button-md:
fontFamily: IBM Plex Sans Variable
fontSize: 14px
fontWeight: 700
lineHeight: 1.5
letterSpacing: 0
button-sm:
fontFamily: IBM Plex Sans Variable
fontSize: 13px
fontWeight: 500
lineHeight: 1
letterSpacing: 0
code-sm:
fontFamily: ui-monospace
fontSize: 14px
fontWeight: 400
lineHeight: 1.43
letterSpacing: 0
code-xs:
fontFamily: Source Code Pro
fontSize: 14px
fontWeight: 500
lineHeight: 1.43
letterSpacing: 0
rounded:
none: 0px
xs: 2px
sm: 4px
md: 6px
lg: 8px
full: 9999px
spacing:
xxs: 2px
xs: 4px
sm: 8px
md: 12px
lg: 16px
xl: 24px
xxl: 32px
section: 80px
components:
button-primary:
backgroundColor: "{colors.primary}"
textColor: "{colors.on-primary}"
typography: "{typography.button-md}"
rounded: "{rounded.md}"
padding: 8px 16px
height: 40px
button-primary-pressed:
backgroundColor: "{colors.primary-pressed}"
textColor: "{colors.on-primary}"
typography: "{typography.button-md}"
rounded: "{rounded.md}"
button-secondary:
backgroundColor: "{colors.surface-soft}"
textColor: "{colors.ink}"
typography: "{typography.button-md}"
rounded: "{rounded.md}"
padding: 8px 16px
height: 40px
button-tertiary:
backgroundColor: "transparent"
textColor: "{colors.ink}"
typography: "{typography.button-md}"
rounded: "{rounded.md}"
padding: 8px 12px
button-disabled:
backgroundColor: "{colors.surface-soft}"
textColor: "{colors.ash}"
rounded: "{rounded.md}"
text-input:
backgroundColor: "{colors.surface-card}"
textColor: "{colors.ink}"
typography: "{typography.body-md}"
rounded: "{rounded.md}"
padding: 8px 12px
height: 36px
text-input-focused:
backgroundColor: "{colors.surface-card}"
textColor: "{colors.ink}"
rounded: "{rounded.md}"
search-input:
backgroundColor: "{colors.surface-card}"
textColor: "{colors.ink}"
typography: "{typography.body-md}"
rounded: "{rounded.md}"
padding: 8px 12px
height: 36px
product-card:
backgroundColor: "{colors.surface-card}"
textColor: "{colors.ink}"
typography: "{typography.body-md}"
rounded: "{rounded.md}"
padding: 24px
doc-card:
backgroundColor: "{colors.surface-doc}"
textColor: "{colors.ink}"
typography: "{typography.body-md}"
rounded: "{rounded.md}"
padding: 24px
feature-tile:
backgroundColor: "{colors.surface-card}"
textColor: "{colors.ink}"
typography: "{typography.heading-sm-mixed}"
rounded: "{rounded.md}"
padding: 20px
pricing-tier-card:
backgroundColor: "{colors.surface-card}"
textColor: "{colors.ink}"
typography: "{typography.body-md}"
rounded: "{rounded.md}"
padding: 32px
hedgehog-mascot-card:
backgroundColor: "{colors.surface-card}"
textColor: "{colors.ink}"
typography: "{typography.body-md}"
rounded: "{rounded.md}"
padding: 24px
product-tab:
backgroundColor: "transparent"
textColor: "{colors.body}"
typography: "{typography.body-strong}"
rounded: "{rounded.md}"
padding: 8px 12px
product-tab-active:
backgroundColor: "{colors.surface-card}"
textColor: "{colors.ink}"
typography: "{typography.body-strong}"
rounded: "{rounded.md}"
pill-tab:
backgroundColor: "transparent"
textColor: "{colors.body}"
typography: "{typography.button-sm}"
rounded: "{rounded.full}"
padding: 6px 14px
pill-tab-active:
backgroundColor: "{colors.ink}"
textColor: "{colors.on-dark}"
typography: "{typography.button-sm}"
rounded: "{rounded.full}"
badge-uppercase:
backgroundColor: "transparent"
textColor: "{colors.body}"
typography: "{typography.utility-xs}"
rounded: "{rounded.none}"
badge-promo:
backgroundColor: "{colors.accent-blue-soft}"
textColor: "{colors.link-blue}"
typography: "{typography.caption-xs}"
rounded: "{rounded.full}"
padding: 2px 8px
banner-tip-blue:
backgroundColor: "{colors.accent-blue-soft}"
textColor: "{colors.ink}"
typography: "{typography.body-md}"
rounded: "{rounded.md}"
padding: 16px 20px
banner-tip-green:
backgroundColor: "{colors.accent-green-soft}"
textColor: "{colors.ink}"
typography: "{typography.body-md}"
rounded: "{rounded.md}"
padding: 16px 20px
banner-tip-red:
backgroundColor: "{colors.accent-red-soft}"
textColor: "{colors.ink}"
typography: "{typography.body-md}"
rounded: "{rounded.md}"
padding: 16px 20px
banner-tip-purple:
backgroundColor: "{colors.accent-purple-soft}"
textColor: "{colors.ink}"
typography: "{typography.body-md}"
rounded: "{rounded.md}"
padding: 16px 20px
code-block:
backgroundColor: "{colors.surface-dark}"
textColor: "{colors.on-dark}"
typography: "{typography.code-sm}"
rounded: "{rounded.md}"
padding: 16px 20px
inline-code:
backgroundColor: "{colors.surface-soft}"
textColor: "{colors.ink}"
typography: "{typography.code-xs}"
rounded: "{rounded.xs}"
padding: 2px 6px
primary-nav:
backgroundColor: "{colors.canvas}"
textColor: "{colors.ink}"
typography: "{typography.body-strong}"
rounded: "{rounded.none}"
height: 56px
sub-nav-strip:
backgroundColor: "{colors.surface-soft}"
textColor: "{colors.body}"
typography: "{typography.body-xs}"
rounded: "{rounded.none}"
height: 40px
doc-sidebar:
backgroundColor: "{colors.canvas}"
textColor: "{colors.body}"
typography: "{typography.body-xs}"
rounded: "{rounded.none}"
width: 240px
footer-section:
backgroundColor: "{colors.canvas}"
textColor: "{colors.body}"
typography: "{typography.body-xs}"
rounded: "{rounded.none}"
padding: 32px 24px
link-inline:
textColor: "{colors.link-teal}"
typography: "{typography.link-md}"
---
Overview
Section 01PostHog's marketing system is built on the visual contradiction at the heart of the brand: a serious open-source product analytics platform rendered as if it were a friendly engineering sketchbook. The chrome runs on a warm cream canvas (`{colors.canvas}` — `#eeefe9`) — not white — and every page is dotted with hand-drawn hedgehog mascots in lab coats, lounge chairs, terminals, and reading glasses, scattered across the layout like marginalia in a textbook. Type sits in IBM Plex Sans Variable at olive-gray (`{colors.body}` — `#4d4f46`) for body and deep olive-charcoal (`{colors.ink}` — `#23251d`) for headlines, with weights stepped tightly between 400, 600, 700, and 800 to create hierarchy without color. The single saturated yellow-orange pill (`{colors.primary}` — `#f7a501`) is the brand's only loud chromatic moment; everything else is cream, olive, white card, and the occasional pastel callout band.
The system has a distinctive **two-mode body layout**: marketing pages (home, workflows, pricing) lean on alternating-pastel callout bands and feature tiles in white cards on cream, while documentation pages add a sticky 240px left sidebar with a rounded outline-icon section list. Code samples are full-width dark blocks on `{colors.surface-dark}` (the same olive-charcoal that carries body ink, used inverted) inside white doc cards, creating the system's most distinctive visual moment: a dark-on-dark code island floating inside a white card on a cream canvas, with a hedgehog mascot doodled in the margin.
Sections stack at `{spacing.section}` (80px) rhythm with cream canvas continuing edge-to-edge between them. The only color bands that interrupt the cream are pastel `{component.banner-tip-blue}` / `-green` / `-red` / `-purple` callout panels inside doc articles — soft tinted boxes that carry "💡 Tip", "✅ Success", "⚠️ Warning", "📘 Info" inline annotations. There are no decorative gradients, no atmospheric mesh backgrounds, and no full-bleed dark hero chapters; the cream canvas runs uninterrupted top to bottom and the hedgehogs are the entire visual identity.
**Key Characteristics:**
Colors
Section 02> **Source pages:** `/` (home), `/pricing` (pricing detail), `/docs/product-analytics` (docs article), `/workflows` (product feature page). The chrome palette is identical across all four pages — only doc-specific accents (callout-banner pastels, code-block dark surface) appear exclusively inside the docs experience.
Brand & Accent
Section 03Surface
Section 04Text
Section 05Semantic
Section 06Typography
Section 07Font Family
Section 08**IBM Plex Sans Variable** is the system's primary face — used across every text role on every page at weights 400 (regular), 500 (medium), 600 (semibold), 700 (bold), and 800 (extra-bold). Falls back through `IBM Plex Sans` → `-apple-system` → `system-ui` → broad cross-platform sans stack.
**ui-monospace** + **Source Code Pro** carry code samples and inline-code chips at 14px / 1.43 line-height. Source Code Pro is the explicit display monospace; ui-monospace handles inline `<code>` chips.
The brand-distinctive choice is the **mixed weight ladder** (400 / 500 / 600 / 700 / 800) — most chrome lives in the 400–700 band, with weight 800 reserved exclusively for the larger display headlines on home and pricing. This gives the system its "engineering blog" feel: hierarchy is built from weight contrast much more than from size.
Hierarchy
Section 09| Token | Size | Weight | Line Height | Letter Spacing | Use |
|---|---|---|---|---|---|
| `{typography.display-xl}` | 36px | 700 | 1.5 | 0 | Hero headline ("The new way to build products") |
| `{typography.display-lg}` | 24px | 800 | 1.33 | -0.6px | Section headline, pricing tier name |
| `{typography.heading-lg}` | 21px | 700 | 1.4 | -0.5px | Sub-section heading, doc-article H2 |
| `{typography.heading-md}` | 20px | 700 | 1.4 | 0 | Card group title, in-grid heading |
| `{typography.heading-sm}` | 18px | 700 | 1.5 | 0 (uppercase) | Section eyebrow ("UNDERSTAND PRODUCT USAGE") |
| `{typography.heading-sm-mixed}` | 18px | 600 | 1.56 | 0 | Card title in mixed-case (no uppercase transform) |
| `{typography.body-md}` | 16px | 400 | 1.5 | 0 | Body copy, default paragraph |
| `{typography.body-strong}` | 16px | 600 | 1.5 | 0 | Inline emphasis, primary nav link, in-card label |
| `{typography.body-sm}` | 15px | 400 | 1.71 | 0 | Doc article body, marketing card description |
| `{typography.body-sm-strong}` | 15px | 600 | 1.71 | 0 | Sub-section emphasis inside doc article |
| `{typography.body-xs}` | 14px | 500 | 1.43 | 0 | Doc sidebar item, metadata, in-list caption |
| `{typography.caption-md}` | 14px | 700 | 1.71 | 0 | Card eyebrow, link cluster header |
| `{typography.caption-sm}` | 13px | 500 | 1.5 | 0 | Compact metadata caption |
| `{typography.caption-xs}` | 12px | 600 | 1.33 | 0 (uppercase) | Inline badge label |
| `{typography.utility-xs}` | 12px | 700 | 1.33 | 0 (uppercase) | Section-eyebrow utility text, footer category header |
| `{typography.link-md}` | 16px | 400 | 1.5 | 0 | Inline body anchor link |
| `{typography.button-md}` | 14px | 700 | 1.5 | 0 | Standard primary/secondary button label |
| `{typography.button-sm}` | 13px | 500 | 1 | 0 | Pill chip / compact CTA |
| `{typography.code-sm}` | 14px | 400 | 1.43 | 0 | Code block content |
| `{typography.code-xs}` | 14px | 500 | 1.43 | 0 | Inline code chip |
Principles
Section 010The hierarchy is explicitly built from weight + size + occasional uppercase transform — there is no italic style, no decorative display variant, no proprietary face. The biggest display moments use weight 800 with -0.6px tracking, and the body settles at 400 with 1.5 line-height; everything else fills the band between. Section eyebrows (`{typography.heading-sm}` and `{typography.utility-xs}`) consistently render uppercase, which gives the doc layout its textbook-chapter feel.
Note on Font Substitutes
Section 011IBM Plex Sans Variable is open-source and Google-Fonts-hosted. There is no need for a substitute — load it directly. If a substitute is genuinely needed, **Inter** is the closest geometric match at all five weights; pair with Inter's letter-spacing -0.5 to -0.6px on display sizes to approximate Plex's display tracking. For monospace, **JetBrains Mono** is a near-perfect substitute for Source Code Pro at body sizes.
Layout
Section 012Spacing System
Section 013Grid & Container
Section 014Whitespace Philosophy
Section 015Whitespace is generous on marketing pages and tight on doc pages. The home and workflows pages stack feature tiles with `{spacing.lg}` (16px) gutters and 24px internal padding, while doc articles tighten internal spacing to `{spacing.md}` (12px) between paragraphs to maximize information density. The cream canvas runs continuously through every section — there are no decorative dividers, no shaded section bands; only the 1px hairline beneath section eyebrows and footer column rules separate content blocks.
Elevation & Depth
Section 016| Level | Treatment | Use |
|---|---|---|
| 0 — Flat | No border, no shadow | Default for canvas-on-canvas blocks, hero text, body sections |
| 1 — Hairline border | 1px solid `{colors.hairline}` | Marketing cards, pricing tier cards, doc sidebar items, footer column rules |
| 2 — Hairline soft | 1px solid `{colors.hairline-soft}` | In-card row divider between adjacent rows |
| 3 — Inverted dark code block | `{colors.surface-dark}` fill | Code samples inside doc cards — the system's only "elevated" surface uses color, not shadow |
The system has no drop-shadow elevation in marketing or product chrome. Cards sit flat on cream with thin olive borders. The single inverted moment is the dark code-block surface used inside doc article body cards.
Decorative Depth
Section 017Depth comes entirely from illustration and the pastel callout band system, not from CSS effects:
Shapes
Section 018Border Radius Scale
Section 019| Token | Value | Use |
|---|---|---|
| `{rounded.none}` | 0px | Sub-nav strip, footer, doc sidebar, primary nav — flat structural surfaces |
| `{rounded.xs}` | 2px | Inline `<code>` chips, micro-rule highlights |
| `{rounded.sm}` | 4px | Inline buttons, form inputs, micro chips |
| `{rounded.md}` | 6px | Marketing cards, pricing cards, doc cards, code blocks, every standard CTA |
| `{rounded.lg}` | 8px | Tab top corners (`6px 6px 0 0` on active tab) and rare large containers |
| `{rounded.full}` | 9999px | Pill chips and pill-style CTAs ("Get started — free" sticky CTA in nav) |
The radius vocabulary clusters around 4–6px for nearly everything; the only fully-rounded element is the pill-style sticky nav CTA and inline pill chips.
Photography Geometry
Section 020There is no photography. Visual elements are limited to:
Components
Section 021> **No hover states documented** per system policy. Each spec covers Default and Active/Pressed only.
Buttons
Section 022**`button-primary`** — the universal PostHog CTA
**`button-secondary`** — soft alternative on cream canvas
**`button-tertiary`** — ghost text button
**`button-disabled`**
Tabs & Chips
Section 023**`product-tab`** + **`product-tab-active`** — major product section tabs
**`pill-tab`** + **`pill-tab-active`** — compact filter pill
**`badge-uppercase`** — text-only utility label
**`badge-promo`** — small inline pill chip
Inputs & Forms
Section 024**`text-input`** + **`text-input-focused`**
**`search-input`** — utility search field (doc sidebar, "Ask PostHog AI")
Cards & Containers
Section 025**`product-card`** — marketing tile / feature card
**`doc-card`** — doc article body card
**`feature-tile`** — small marketing feature tile
**`pricing-tier-card`** — pricing plan card
**`hedgehog-mascot-card`** — feature card with margin-anchored hedgehog
Callout Banners
Section 026**`banner-tip-blue`** + **`banner-tip-green`** + **`banner-tip-red`** + **`banner-tip-purple`**
Code
Section 027**`code-block`** — dark code sample inside doc card
**`inline-code`** — small inline `<code>` chip
Navigation
Section 028**`primary-nav`**
**`sub-nav-strip`** — secondary nav bar (under primary)
**`doc-sidebar`** — sticky doc-page left sidebar
**Top Nav (Mobile)**
Footer
Section 029**`footer-section`**
Inline
Section 030**`link-inline`** — body-prose anchor link
Do's and Don'ts
Section 031Do
Section 032Don't
Section 033Responsive Behavior
Section 034Breakpoints
Section 035| Name | Width | Key Changes |
|---|---|---|
| ultrawide | 1920px+ | Content max-width holds at 1280px; outer gutters grow to ~80px |
| desktop-large | 1440px | Default — 4-up feature tile grid, 240px sticky doc sidebar visible |
| desktop | 1280px | Same layout with narrower outer gutters |
| desktop-small | 1024px | 4-up tiles collapse to 3-up; doc sidebar remains visible |
| tablet | 768px | 3-up tiles collapse to 2-up; doc sidebar collapses into a top accordion; primary nav becomes hamburger |
| mobile | 480px | Single-column everything; hero `{typography.display-xl}` scales 36px → ~28px |
| mobile-narrow | 320px | Section padding tightens to 32px |
Touch Targets
Section 036All interactive elements meet WCAG AA (≥ 40×40px). `{component.button-primary}` and `{component.button-secondary}` sit at 40px height with 16px padding. `{component.text-input}` sits at 36px (just under AAA but above AA at this size). `{component.pill-tab}` is ~32–36px height with 14px padding extending to ~44px tappable via inline padding. Doc-sidebar items use 14px text with ~32px line-height + 6px vertical padding for ~44px tap rows.
Collapsing Strategy
Section 037Image Behavior
Section 038The only "imagery" in the system is hand-drawn hedgehog illustrations rendered as inline SVG. They preserve their natural aspect at every breakpoint and scale via CSS `width: auto; max-width: 100%`. There is no responsive art-direction needed because there is no photography.
Iteration Guide
Section 0391. Focus on ONE component at a time. Pull its YAML entry and verify every property resolves.
2. Reference component names and tokens directly (`{colors.primary}`, `{component.button-primary-pressed}`, `{rounded.md}`) — do not paraphrase.
3. Run `npx @google/design.md lint DESIGN.md` after edits — `broken-ref`, `contrast-ratio`, and `orphaned-tokens` warnings flag issues automatically.
4. Add new variants as separate component entries (`-pressed`, `-disabled`, `-focused`) — do not bury them inside prose.
5. Default body to `{typography.body-md}` (16px / 400 / 1.5); reach for `{typography.body-strong}` for emphasis; reserve `{typography.display-lg}` (24px / 800) strictly for marketing display moments.
6. Keep `{colors.primary}` scarce per viewport — at most one yellow-orange pill per fold.
7. When introducing a new component, ask whether it can be expressed with the existing card + 6px-radius + cream-canvas vocabulary before adding new tokens. The system's strength is that it almost never needs new ones.