---
version: alpha
name: Raycast-design-analysis
属于: A dark-canvas developer-tools system that treats the marketing page like an extended product screenshot — pure-near-black background, command-palette mockups as the hero, Inter typography with the ss03 stylistic set turned on, and a single white CTA pill that doesn't break the inky atmosphere. The chrome reads like Raycast's own command-palette UI scaled up to a marketing page: monochrome dark surfaces with a faint surface ladder (#07080a → #0d0d0d → #101111), tight 6–10px radius on cards, hairline 1px borders in #242728, and rare splashes of saturated accent (Hacker News yellow, Slack red, Mac green, info blue) reserved for product-tile category illustrations. The signature visual moment is a red gradient hero wordmark — three diagonal red stripes laid across the very top of the home page like a launch-banner — paired with full-bleed product UI screenshots that show Raycast's actual command palette, store, and AI chat surfaces.
description: |
Raycast's marketing system reads like an extended product screenshot. The chrome IS the in-product chrome at marketing scale: pure-near-black canvas, hairline 1px borders, command-palette-style cards, Inter typography with the ss03 stylistic set enabled site-wide, white CTA pill, and a small set of saturated category accent colors (yellow / red / green / blue) reserved for extension and feature illustrations. Section rhythm is generous (~96px) but the page never breaks tonal continuity — the whole site sits in one continuous dark mode.
colors:
primary: "#ffffff"
primary-pressed: "#e8e8e8"
on-primary: "#000000"
ink: "#f4f4f6"
body: "#cdcdcd"
charcoal: "#d3d3d4"
mute: "#9c9c9d"
ash: "#6a6b6c"
stone: "#434345"
on-dark: "#ffffff"
on-dark-mute: "rgba(255,255,255,0.72)"
canvas: "#07080a"
surface: "#0d0d0d"
surface-elevated: "#101111"
surface-card: "#121212"
button-fg: "#18191a"
hairline: "#242728"
hairline-soft: "rgba(255,255,255,0.08)"
hairline-strong: "rgba(255,255,255,0.16)"
accent-blue: "#57c1ff"
accent-blue-soft: "rgba(87,193,255,0.15)"
accent-red: "#ff6161"
accent-red-soft: "rgba(255,97,97,0.15)"
accent-green: "#59d499"
accent-green-soft: "rgba(89,212,153,0.15)"
accent-yellow: "#ffc533"
accent-yellow-soft: "rgba(255,197,51,0.15)"
hero-stripe-start: "#ff5757"
hero-stripe-end: "#a1131a"
key-bg-start: "#121212"
key-bg-end: "#0d0d0d"
typography:
display-xl:
fontFamily: Inter
fontSize: 64px
fontWeight: 600
lineHeight: 1.1
letterSpacing: 0
fontFeature: '"calt", "kern", "liga", "ss03"'
display-lg:
fontFamily: Inter
fontSize: 56px
fontWeight: 500
lineHeight: 1.17
letterSpacing: 0.2px
fontFeature: '"calt", "kern", "liga", "ss03"'
heading-xl:
fontFamily: Inter
fontSize: 24px
fontWeight: 500
lineHeight: 1.6
letterSpacing: 0.2px
fontFeature: '"calt", "kern", "liga", "ss03"'
heading-lg:
fontFamily: Inter
fontSize: 22px
fontWeight: 500
lineHeight: 1.15
letterSpacing: 0
fontFeature: '"calt", "kern", "liga", "ss03"'
heading-md:
fontFamily: Inter
fontSize: 20px
fontWeight: 500
lineHeight: 1.4
letterSpacing: 0.2px
fontFeature: '"calt", "kern", "liga", "ss03"'
heading-sm:
fontFamily: Inter
fontSize: 18px
fontWeight: 500
lineHeight: 1.4
letterSpacing: 0.2px
fontFeature: '"calt", "kern", "liga", "ss03"'
body-lg:
fontFamily: Inter
fontSize: 18px
fontWeight: 400
lineHeight: 1.6
letterSpacing: 0
fontFeature: '"calt", "kern", "liga", "ss03"'
body-md:
fontFamily: Inter
fontSize: 16px
fontWeight: 400
lineHeight: 1.6
letterSpacing: 0
fontFeature: '"calt", "kern", "liga", "ss03"'
body-strong:
fontFamily: Inter
fontSize: 16px
fontWeight: 500
lineHeight: 1.4
letterSpacing: 0.2px
fontFeature: '"calt", "kern", "liga", "ss03"'
body-sm:
fontFamily: Inter
fontSize: 14px
fontWeight: 400
lineHeight: 1.6
letterSpacing: 0
fontFeature: '"calt", "kern", "liga", "ss03"'
body-sm-strong:
fontFamily: Inter
fontSize: 14px
fontWeight: 500
lineHeight: 1.6
letterSpacing: 0.2px
fontFeature: '"calt", "kern", "liga", "ss03"'
caption-md:
fontFamily: Inter
fontSize: 13px
fontWeight: 400
lineHeight: 1.4
letterSpacing: 0.1px
fontFeature: '"calt", "kern", "liga", "ss03"'
caption-sm:
fontFamily: Inter
fontSize: 12px
fontWeight: 400
lineHeight: 1.5
letterSpacing: 0.4px
fontFeature: '"calt", "kern", "liga", "ss03"'
link-md:
fontFamily: Inter
fontSize: 16px
fontWeight: 500
lineHeight: 1.4
letterSpacing: 0.3px
fontFeature: '"calt", "kern", "liga", "ss03"'
button-md:
fontFamily: Inter
fontSize: 14px
fontWeight: 500
lineHeight: 1.6
letterSpacing: 0.2px
fontFeature: '"calt", "kern", "liga", "ss03"'
rounded:
none: 0px
xs: 4px
sm: 6px
md: 8px
lg: 10px
xl: 16px
full: 9999px
spacing:
xxs: 2px
xs: 4px
sm: 8px
md: 12px
lg: 16px
xl: 24px
xxl: 32px
section: 96px
components:
button-primary:
backgroundColor: "{colors.primary}"
textColor: "{colors.on-primary}"
typography: "{typography.button-md}"
rounded: "{rounded.md}"
padding: 8px 16px
height: 36px
button-primary-pressed:
backgroundColor: "{colors.primary-pressed}"
textColor: "{colors.on-primary}"
typography: "{typography.button-md}"
rounded: "{rounded.md}"
button-secondary:
backgroundColor: "transparent"
textColor: "{colors.on-dark}"
typography: "{typography.button-md}"
rounded: "{rounded.md}"
padding: 8px 16px
height: 36px
button-tertiary:
backgroundColor: "{colors.surface-elevated}"
textColor: "{colors.on-dark}"
typography: "{typography.button-md}"
rounded: "{rounded.md}"
padding: 8px 16px
height: 36px
button-disabled:
backgroundColor: "{colors.surface-elevated}"
textColor: "{colors.ash}"
rounded: "{rounded.md}"
install-button:
backgroundColor: "transparent"
textColor: "{colors.on-dark}"
typography: "{typography.button-md}"
rounded: "{rounded.md}"
padding: 6px 14px
text-input:
backgroundColor: "{colors.surface-elevated}"
textColor: "{colors.on-dark}"
typography: "{typography.body-md}"
rounded: "{rounded.md}"
padding: 8px 12px
height: 36px
text-input-focused:
backgroundColor: "{colors.surface-elevated}"
textColor: "{colors.on-dark}"
rounded: "{rounded.md}"
store-search-bar:
backgroundColor: "{colors.surface-elevated}"
textColor: "{colors.on-dark}"
typography: "{typography.body-md}"
rounded: "{rounded.md}"
padding: 10px 16px
height: 44px
command-palette-row:
backgroundColor: "transparent"
textColor: "{colors.on-dark}"
typography: "{typography.body-md}"
rounded: "{rounded.sm}"
padding: 6px 10px
command-palette-row-active:
backgroundColor: "{colors.surface-card}"
textColor: "{colors.on-dark}"
typography: "{typography.body-md}"
rounded: "{rounded.sm}"
pill-tab:
backgroundColor: "transparent"
textColor: "{colors.body}"
typography: "{typography.body-sm}"
rounded: "{rounded.full}"
padding: 4px 10px
pill-tab-active:
backgroundColor: "{colors.surface-elevated}"
textColor: "{colors.on-dark}"
typography: "{typography.body-sm}"
rounded: "{rounded.full}"
badge-pro:
backgroundColor: "{colors.surface-elevated}"
textColor: "{colors.on-dark-mute}"
typography: "{typography.caption-sm}"
rounded: "{rounded.xs}"
padding: 2px 6px
badge-info-soft:
backgroundColor: "{colors.accent-blue-soft}"
textColor: "{colors.accent-blue}"
typography: "{typography.caption-sm}"
rounded: "{rounded.xs}"
padding: 2px 8px
keycap:
backgroundColor: "{colors.surface-card}"
textColor: "{colors.body}"
typography: "{typography.caption-md}"
rounded: "{rounded.xs}"
padding: 1px 6px
height: 20px
command-palette-card:
backgroundColor: "{colors.surface}"
textColor: "{colors.on-dark}"
typography: "{typography.body-md}"
rounded: "{rounded.lg}"
padding: 0px
feature-card-dark:
backgroundColor: "{colors.surface}"
textColor: "{colors.on-dark}"
typography: "{typography.body-md}"
rounded: "{rounded.lg}"
padding: 24px
feature-card-elevated:
backgroundColor: "{colors.surface-elevated}"
textColor: "{colors.on-dark}"
typography: "{typography.body-md}"
rounded: "{rounded.lg}"
padding: 24px
store-extension-card:
backgroundColor: "{colors.surface}"
textColor: "{colors.on-dark}"
typography: "{typography.body-md}"
rounded: "{rounded.md}"
padding: 16px
pricing-tier-card:
backgroundColor: "{colors.surface}"
textColor: "{colors.on-dark}"
typography: "{typography.body-md}"
rounded: "{rounded.lg}"
padding: 24px
pricing-tier-card-featured:
backgroundColor: "{colors.surface-elevated}"
textColor: "{colors.on-dark}"
typography: "{typography.body-md}"
rounded: "{rounded.lg}"
padding: 24px
hero-stripe-band:
backgroundColor: "{colors.canvas}"
textColor: "{colors.on-dark}"
typography: "{typography.display-xl}"
rounded: "{rounded.none}"
padding: 96px 48px
app-icon-tile:
backgroundColor: "{colors.surface-card}"
rounded: "{rounded.md}"
size: 48px
app-icon-tile-large:
backgroundColor: "{colors.surface-card}"
rounded: "{rounded.md}"
size: 64px
primary-nav:
backgroundColor: "{colors.canvas}"
textColor: "{colors.on-dark}"
typography: "{typography.body-sm-strong}"
rounded: "{rounded.none}"
height: 56px
footer-section:
backgroundColor: "{colors.canvas}"
textColor: "{colors.body}"
typography: "{typography.body-sm}"
rounded: "{rounded.none}"
padding: 64px 48px
link-inline:
textColor: "{colors.on-dark}"
typography: "{typography.link-md}"
---
Overview
Section 01Raycast's marketing site reads like an extended product screenshot. The chrome IS the in-product command palette at marketing scale: pure near-black canvas (`{colors.canvas}` — `#07080a`), hairline 1px borders (`{colors.hairline}` — `#242728`), command-palette-style cards with rounded corners between 6 and 16px, Inter typography with the **ss03 stylistic set enabled site-wide** (a single character — the alternate `g` — that gives Raycast's typography its signature subtle distinction), a single white CTA pill that anchors every primary action, and small splashes of saturated accent reserved for category illustrations.
The system has effectively one surface mode — dark — with a faint three-step surface ladder (`{colors.canvas}` → `{colors.surface}` → `{colors.surface-elevated}` → `{colors.surface-card}`) carrying cards, in-card panels, and key-cap glyph backgrounds. The signature decorative moment is a **red diagonal-stripe gradient band** across the very top of the home page hero, used as a launch-banner motif behind the headline (the only time saturated red appears on chrome). Beyond that single moment, color in the chrome is reserved for category accents inside extension and feature illustrations: Hacker News yellow, Slack red, Linear green, info blue.
The design philosophy is "the marketing page is the product." Section rhythm is generous (`{spacing.section}` 96px) but the page never breaks tonal continuity — the whole site sits in one continuous dark mode, full-bleed product UI screenshots show Raycast's actual command palette / store / AI chat surfaces, and the typography ligature settings (`ss03`) are inherited from the in-product app's text rendering.
**Key Characteristics:**
Colors
Section 02> **Source pages:** `/` (home), `/store` (extension marketplace), `/core-features/ai` (feature page), `/pricing` (plan tiers), `/thomas/hacker-news` (single extension detail). The chrome palette is identical across all five pages — the dark surface ladder, hairline borders, white CTA, and ss03-enabled typography are the same on every page.
Brand & Accent
Section 03Surface
Section 04Text
Section 05Semantic
Section 06Brand Gradient
Section 07Typography
Section 08Font Family
Section 09**Inter** is the system's primary face, loaded with the `Inter Fallback` system fallback variant. Critically, Raycast enables `font-feature-settings: "calt", "kern", "liga", "ss03"` site-wide — the **ss03 stylistic set** swaps in Inter's alternate `g` glyph (single-story open `g`), which is the brand's signature typographic detail. Standard ligatures (`liga`), kerning (`kern`), and contextual alternates (`calt`) are also active. The display tier additionally enables `ss02` and `ss08` and disables standard `liga` to render the hero "Raycast Pro" wordmark with its distinctive geometric construction.
There is no monospace face used outside of inline `<code>` chips in documentation; the marketing pages use Inter for everything.
Hierarchy
Section 010| Token | Size | Weight | Line Height | Letter Spacing | Use |
|---|---|---|---|---|---|
| `{typography.display-xl}` | 64px | 600 | 1.1 | 0 | Hero "Built for the perfect tools" / "The new way to..." headline (with `liga: 0`, `ss02`, `ss08`) |
| `{typography.display-lg}` | 56px | 500 | 1.17 | 0.2px | Section headline ("Explore", "Pricing", store hero "Store") |
| `{typography.heading-xl}` | 24px | 500 | 1.6 | 0.2px | Sub-section heading, pricing-tier name |
| `{typography.heading-lg}` | 22px | 500 | 1.15 | 0 | Mid-section feature heading |
| `{typography.heading-md}` | 20px | 500 | 1.4 | 0.2px | Card group title, in-card heading |
| `{typography.heading-sm}` | 18px | 500 | 1.4 | 0.2px | Small heading, extension card title |
| `{typography.body-lg}` | 18px | 400 | 1.6 | 0 | Pricing tier description, hero subtitle |
| `{typography.body-md}` | 16px | 400 | 1.6 | 0 | Default body, paragraph text |
| `{typography.body-strong}` | 16px | 500 | 1.4 | 0.2px | Inline emphasis, primary nav link |
| `{typography.body-sm}` | 14px | 400 | 1.6 | 0 | Card description, secondary copy |
| `{typography.body-sm-strong}` | 14px | 500 | 1.6 | 0.2px | In-card label, table-header text |
| `{typography.caption-md}` | 13px | 400 | 1.4 | 0.1px | Caption, metadata |
| `{typography.caption-sm}` | 12px | 400 | 1.5 | 0.4px | Smallest utility text, badge label |
| `{typography.link-md}` | 16px | 500 | 1.4 | 0.3px | Inline body anchor link |
| `{typography.button-md}` | 14px | 500 | 1.6 | 0.2px | Standard button label |
Principles
Section 011The hierarchy works on a 1.6-line-height ladder for body and a 1.1–1.4 ladder for display/heading. Letter-spacing is consistently positive (0.1–0.4px) — slightly opening the type — which gives Raycast's chrome an airy quality at body sizes despite the dark canvas. The `ss03` stylistic set is the brand's most distinctive typographic detail; without it, the body face renders identically to plain Inter and loses Raycast's signature rendering.
Note on Font Substitutes
Section 012Inter is open-source and Google-Fonts-hosted; load it directly. To preserve the brand's signature look, you must enable `font-feature-settings: "calt", "kern", "liga", "ss03"` on the body element. Without `ss03`, the typography is recognizably "Inter default" rather than "Raycast." On systems where Inter cannot be loaded, the documented fallback is `Inter Fallback` (a self-hosted variant) → `system-ui`. **JetBrains Mono** or **Geist Mono** are acceptable substitutes for inline code chips when needed, though Raycast's marketing chrome rarely uses code-styled text.
Layout
Section 013Spacing System
Section 014Grid & Container
Section 015Whitespace Philosophy
Section 016Whitespace is generous and the canvas is uninterrupted. Sections sit 96px apart with no decorative dividers between them — the dark canvas continues edge-to-edge from hero to footer. Inside a section, content is left-aligned in a tight column, with command-palette mockup imagery occupying the right 50–60% of the band on home-page feature rows. The signature decorative element — the red diagonal-stripe gradient band — only appears in the very first hero band; from the second section down, the page is monochrome dark.
Elevation & Depth
Section 017| Level | Treatment | Use |
|---|---|---|
| 0 — Flat | No border, no shadow | Default for canvas-on-canvas blocks, hero text, footer body |
| 1 — Hairline border | 1px solid `{colors.hairline}` (#242728) | Every card on `{colors.surface}`, store extension card, pricing tier card |
| 2 — Hairline strong | 1px solid `{colors.hairline-strong}` | Stronger inline divider, table-row separator on the comparison table |
| 3 — Surface ladder elevation | `{colors.canvas}` → `{colors.surface}` → `{colors.surface-elevated}` → `{colors.surface-card}` | Multi-step background-color ladder used to create elevation without shadows |
The system has no drop-shadow elevation at all. Depth is built entirely from the surface-color ladder: each notch lighter on the dark scale reads as one step closer to the viewer.
Decorative Depth
Section 018Depth comes from product imagery and a single stripe-gradient band:
Shapes
Section 019Border Radius Scale
Section 020| Token | Value | Use |
|---|---|---|
| `{rounded.none}` | 0px | Hero band, primary nav, footer, full-bleed structural surfaces |
| `{rounded.xs}` | 4px | Keycap glyphs, badge-pro chips, small inline tags |
| `{rounded.sm}` | 6px | Command-palette row, inline buttons, micro chips |
| `{rounded.md}` | 8px | Standard buttons, text inputs, store search bar, app-icon tiles, store extension card |
| `{rounded.lg}` | 10px | Feature card, command-palette mockup card, pricing tier card |
| `{rounded.xl}` | 16px | Large hero command-palette mockup container, oversized feature panel |
| `{rounded.full}` | 9999px | Pill-tab chips, avatar circles |
The radius vocabulary clusters tightly between 4 and 16px, with most chrome at 6–10px. The system never goes flat (0px) on cards and never above 16px except for fully-rounded pills.
Photography Geometry
Section 021There is no traditional photography. Visual elements are limited to:
Components
Section 022> **No hover states documented** per system policy. Each spec covers Default and Active/Pressed only.
Buttons
Section 023**`button-primary`** — the universal Raycast CTA
**`button-secondary`** — transparent text button
**`button-tertiary`** — soft surface button
**`button-disabled`**
**`install-button`** — the store-page install pill
Filter & Tab Chips
Section 024**`pill-tab`** + **`pill-tab-active`** — small filter chip strip
**`badge-pro`** — small Pro/Plan label
**`badge-info-soft`** — translucent info chip
Inputs & Forms
Section 025**`text-input`** + **`text-input-focused`**
**`store-search-bar`** — the store-page search field
Cards & Containers
Section 026**`command-palette-card`** — the home-page hero command-palette mockup
**`command-palette-row`** + **`command-palette-row-active`** — single row inside the command palette
**`feature-card-dark`** — standard product feature card
**`feature-card-elevated`** — slightly-elevated variant
**`store-extension-card`** — store-page extension card
**`pricing-tier-card`** — pricing plan card (default tier)
**`pricing-tier-card-featured`** — middle "Pro" featured tier
**`hero-stripe-band`** — home-page hero with red stripe gradient
Decorative
Section 027**`app-icon-tile`** — small 48px square app icon
**`app-icon-tile-large`** — 64px feature variant
**`keycap`** — keyboard shortcut glyph
Navigation
Section 028**`primary-nav`**
**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 1240px; outer gutters grow to ~80px |
| desktop-large | 1440px | Default — 3-up pricing grid, 2-up store extension grid |
| desktop | 1280px | Same with narrower outer gutters |
| desktop-small | 1024px | 3-up pricing collapses to 2+1; primary nav remains horizontal |
| tablet | 768px | Pricing → 1-up stacked; primary nav becomes hamburger drawer |
| mobile | 480px | Single-column everything; hero `{typography.display-xl}` scales 64px → ~36px |
| mobile-narrow | 320px | Section padding tightens to 48px |
Touch Targets
Section 036All interactive elements meet WCAG AA at 36px+. `{component.button-primary}` and `{component.button-tertiary}` sit at 36px height with 16px padding. `{component.text-input}` sits at 36px. `{component.store-search-bar}` sits at 44px (above AAA). `{component.pill-tab}` is ~24–28px height with 10px padding extending to 36–40px tappable via inline padding (above AA but below AAA — intentional, the chips are compact). `{component.install-button}` sits at ~32px height with 14px padding.
Collapsing Strategy
Section 037Image Behavior
Section 038The only "imagery" in the system is in-product Raycast UI screenshots and small app-icon assets:
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`, `-active`) — do not bury them inside prose.
5. Default body to `{typography.body-md}` (16px / 400 / 1.6); reach for `{typography.body-strong}` for emphasis; reserve `{typography.display-xl}` strictly for the hero band.
6. Keep `{colors.primary}` (white CTA pill) scarce per viewport — at most one solid white pill per fold.
7. When introducing a new component, ask whether it can be expressed with the existing surface-ladder + 8px-radius + ss03-Inter vocabulary before adding new tokens. The system's strength is that it almost never needs new ones.