From 4990fd5168f77e939d1665b28117109771a0e79b Mon Sep 17 00:00:00 2001 From: necatiozmen Date: Sat, 2 May 2026 20:37:58 +0300 Subject: [PATCH] update DESIGN.md v2 --- README.md | 2 +- design-md/nike/DESIGN.md | 820 +++++++++++++++++----------- design-md/nvidia/DESIGN.md | 819 +++++++++++++++++++--------- design-md/ollama/DESIGN.md | 696 ++++++++++++++++-------- design-md/opencode.ai/DESIGN.md | 686 ++++++++++++++++-------- design-md/pinterest/DESIGN.md | 721 ++++++++++++++++++------- design-md/playstation/DESIGN.md | 909 +++++++++++++++++++++----------- design-md/posthog/DESIGN.md | 840 ++++++++++++++++++++++------- design-md/raycast/DESIGN.md | 829 +++++++++++++++++++++-------- design-md/renault/DESIGN.md | 778 ++++++++++++++++++--------- design-md/replicate/DESIGN.md | 763 ++++++++++++++++++++------- design-md/resend/DESIGN.md | 768 ++++++++++++++++++--------- design-md/revolut/DESIGN.md | 723 ++++++++++++++++++++----- 13 files changed, 6645 insertions(+), 2709 deletions(-) diff --git a/README.md b/README.md index fd31072..8efa397 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,7 @@ You can [request a DESIGN.md](https://getdesign.md/request) for specific website ## Sponsors ❤️ -[Become a Sponsor](https://github.com/sponsors/VoltAgent/sponsorships?tier_id=605140) [1M+ view] — your logo here and get listed on [getdesign.md](https://getdesign.md/) +Become a Sponsor [1M+ view] — your logo here and get listed on [getdesign.md](https://getdesign.md/) ## Collection diff --git a/design-md/nike/DESIGN.md b/design-md/nike/DESIGN.md index 065a1f7..744a5f0 100644 --- a/design-md/nike/DESIGN.md +++ b/design-md/nike/DESIGN.md @@ -1,363 +1,575 @@ -# Design System Inspired by Nike +--- +version: alpha +name: Nike +description: | + A photography-first commerce system built on extreme typographic contrast — towering uppercase Futura display lockups burned into editorial campaign imagery, sitting above a dense, neutral, near-monochrome retail chrome of pill-shaped black CTAs, gray search and tag pills, and tight 8px-grid product cards. The brand's voice is athletic, kinetic, and absolute: pure black, pure white, a single soft surface gray, and a deliberately small set of semantic accents (sale red, success green, restrained category tints) — every chromatic moment is reserved for editorial photography or pricing signal, never decorative chrome. -## 1. Visual Theme & Atmosphere +colors: + primary: "#111111" + on-primary: "#ffffff" + canvas: "#ffffff" + soft-cloud: "#f5f5f5" + ink: "#111111" + charcoal: "#39393b" + ash: "#4b4b4d" + mute: "#707072" + stone: "#9e9ea0" + hairline: "#cacacb" + hairline-soft: "#e5e5e5" + sale: "#d30005" + sale-deep: "#780700" + success: "#007d48" + success-bright: "#1eaa52" + info: "#1151ff" + info-deep: "#0034e3" + accent-pink: "#ed1aa0" + accent-pink-soft: "#ffb0dd" + accent-purple-soft: "#beaffd" + accent-purple-pale: "#d6d1ff" + accent-teal: "#0a7281" + accent-pink-deep: "#4c012d" -Nike.com is a kinetic retail cathedral — a site that channels the explosive energy of sport into a digital shopping experience. The design operates on a principle of radical simplicity: strip everything back to black, white, and grey so that athletic photography and product color can dominate without competition. The result feels less like a website and more like a sports editorial laid out with the precision of a luxury magazine. Every pixel of real estate is either selling product or driving toward product. +typography: + display-campaign: + fontFamily: Nike Futura ND + fontSize: 96px + fontWeight: 500 + lineHeight: 0.9 + letterSpacing: 0 + textTransform: uppercase + heading-xl: + fontFamily: Helvetica Now Display Medium + fontSize: 32px + fontWeight: 500 + lineHeight: 1.2 + letterSpacing: 0 + heading-lg: + fontFamily: Helvetica Now Display Medium + fontSize: 24px + fontWeight: 500 + lineHeight: 1.2 + letterSpacing: 0 + heading-md: + fontFamily: Helvetica Now Display Medium + fontSize: 16px + fontWeight: 500 + lineHeight: 1.75 + letterSpacing: 0 + body-md: + fontFamily: Helvetica Now Text + fontSize: 16px + fontWeight: 400 + lineHeight: 1.5 + letterSpacing: 0 + body-strong: + fontFamily: Helvetica Now Text Medium + fontSize: 16px + fontWeight: 500 + lineHeight: 1.5 + letterSpacing: 0 + button-lg: + fontFamily: Helvetica Now Display Medium + fontSize: 24px + fontWeight: 500 + lineHeight: 1.2 + letterSpacing: 0 + button-md: + fontFamily: Helvetica Now Text Medium + fontSize: 16px + fontWeight: 500 + lineHeight: 1.5 + letterSpacing: 0 + button-sm: + fontFamily: Helvetica Now Text Medium + fontSize: 14px + fontWeight: 500 + lineHeight: 1.5 + letterSpacing: 0 + link-md: + fontFamily: Helvetica Now Text + fontSize: 16px + fontWeight: 500 + lineHeight: 1.75 + letterSpacing: 0 + textDecoration: underline + caption-md: + fontFamily: Helvetica Now Text Medium + fontSize: 14px + fontWeight: 500 + lineHeight: 1.5 + letterSpacing: 0 + caption-sm: + fontFamily: Helvetica Now Text Medium + fontSize: 12px + fontWeight: 500 + lineHeight: 1.5 + letterSpacing: 0 + utility-xs: + fontFamily: Helvetica Neue + fontSize: 9px + fontWeight: 500 + lineHeight: 1.75 + letterSpacing: 0 -The "Podium CDS" (Nike's internal Core Design System) establishes an aggressively monochromatic foundation. The UI disappears into black (`#111111`) text and white surfaces, allowing hero photography — sweating athletes, mid-air shoes, stadium energy — to carry the emotional weight. When color does appear in the UI, it's almost exclusively functional: red for errors, blue for links, green for success. The product itself is the color story. This restraint creates a visual paradox: the most colorful pages on the internet feel the most minimal, because all vibrancy comes from merchandise rather than interface. +rounded: + none: 0px + sm: 18px + md: 24px + lg: 30px + full: 9999px -The typography system is the other half of Nike's visual identity. Massive uppercase headlines in Nike Futura ND — a custom condensed Futura variant with impossibly tight line-height (0.90) — punch through hero imagery like a typographic shockwave. Below the headlines, the workhorse Helvetica Now family handles everything from navigation to product descriptions with Swiss-precision clarity. This split between expressive display type and functional body type mirrors Nike's brand duality: inspiration meets execution. +spacing: + xxs: 2px + xs: 4px + sm: 8px + md: 12px + lg: 18px + xl: 24px + xxl: 30px + section: 48px + +components: + button-primary: + backgroundColor: "{colors.ink}" + textColor: "{colors.on-primary}" + typography: "{typography.button-md}" + rounded: "{rounded.full}" + padding: 16px 32px + height: 48px + button-primary-active: + backgroundColor: "{colors.ink}" + textColor: "{colors.on-primary}" + typography: "{typography.button-md}" + rounded: "{rounded.full}" + button-secondary: + backgroundColor: "{colors.soft-cloud}" + textColor: "{colors.ink}" + typography: "{typography.button-md}" + rounded: "{rounded.full}" + padding: 16px 32px + height: 48px + button-outline-on-image: + backgroundColor: "{colors.canvas}" + textColor: "{colors.ink}" + typography: "{typography.button-md}" + rounded: "{rounded.full}" + padding: 12px 24px + button-icon-circular: + backgroundColor: "{colors.soft-cloud}" + textColor: "{colors.ink}" + rounded: "{rounded.full}" + size: 40px + search-pill: + backgroundColor: "{colors.soft-cloud}" + textColor: "{colors.ink}" + typography: "{typography.body-md}" + rounded: "{rounded.md}" + padding: 8px 16px + height: 40px + search-pill-focused: + backgroundColor: "{colors.canvas}" + textColor: "{colors.ink}" + rounded: "{rounded.md}" + filter-chip: + backgroundColor: "{colors.canvas}" + textColor: "{colors.ink}" + typography: "{typography.button-md}" + rounded: "{rounded.full}" + padding: 8px 16px + filter-chip-active: + backgroundColor: "{colors.ink}" + textColor: "{colors.on-primary}" + typography: "{typography.button-md}" + rounded: "{rounded.full}" + badge-promo: + backgroundColor: "{colors.canvas}" + textColor: "{colors.ink}" + typography: "{typography.caption-sm}" + rounded: "{rounded.full}" + padding: 4px 12px + badge-sale-text: + textColor: "{colors.sale}" + typography: "{typography.caption-md}" + product-card: + backgroundColor: "{colors.canvas}" + textColor: "{colors.ink}" + typography: "{typography.body-strong}" + rounded: "{rounded.none}" + padding: 0px + product-card-image: + backgroundColor: "{colors.soft-cloud}" + rounded: "{rounded.none}" + swatch-dot: + backgroundColor: "{colors.ink}" + rounded: "{rounded.full}" + size: 12px + swatch-dot-active: + backgroundColor: "{colors.ink}" + rounded: "{rounded.full}" + size: 12px + campaign-tile: + backgroundColor: "{colors.ink}" + textColor: "{colors.on-primary}" + typography: "{typography.display-campaign}" + rounded: "{rounded.none}" + category-icon-card: + backgroundColor: "{colors.canvas}" + textColor: "{colors.ink}" + typography: "{typography.caption-md}" + rounded: "{rounded.none}" + member-benefit-card: + backgroundColor: "{colors.ink}" + textColor: "{colors.on-primary}" + typography: "{typography.heading-lg}" + rounded: "{rounded.none}" + faq-row: + backgroundColor: "{colors.canvas}" + textColor: "{colors.ink}" + typography: "{typography.heading-md}" + rounded: "{rounded.none}" + padding: 24px 0px + pdp-disclosure-row: + backgroundColor: "{colors.canvas}" + textColor: "{colors.ink}" + typography: "{typography.body-strong}" + rounded: "{rounded.none}" + padding: 24px 0px + utility-bar: + backgroundColor: "{colors.soft-cloud}" + textColor: "{colors.ink}" + typography: "{typography.caption-sm}" + rounded: "{rounded.none}" + height: 36px + primary-nav: + backgroundColor: "{colors.canvas}" + textColor: "{colors.ink}" + typography: "{typography.body-strong}" + rounded: "{rounded.none}" + height: 56px + filter-sidebar: + backgroundColor: "{colors.canvas}" + textColor: "{colors.ink}" + typography: "{typography.body-strong}" + rounded: "{rounded.none}" + footer: + backgroundColor: "{colors.canvas}" + textColor: "{colors.mute}" + typography: "{typography.caption-md}" + rounded: "{rounded.none}" +--- + +## Overview + +Nike's commerce system is built on a single, almost violently simple idea: photography speaks, the chrome doesn't. Every page reads as an athletic editorial — towering uppercase Futura display lockups (`{typography.display-campaign}`) burned into full-bleed campaign imagery, with everything else (nav, filters, buttons, cards, footer) reduced to neutral typography and pill geometry on `{colors.canvas}` and `{colors.soft-cloud}`. There is no decorative gradient, no soft shadow nostalgia, no accent color used for "tone" — the system saves all chromatic energy for product photography and the small handful of moments that actually need to signal (sale price `{colors.sale}`, success `{colors.success}`, swatch dots). + +The result is a layout that feels physical — campaign hero, product grid, sport tile, footer — stacked like a printed catalog rather than animated like a typical SaaS landing page. Density is high but never crowded, because the system relies on three relentless devices: square or near-square 1:1 product imagery on `{colors.soft-cloud}`, pill-shaped black CTAs (`{rounded.full}`) anchoring every actionable surface, and a tight 8px-base spacing scale that keeps cards and filters mathematically aligned across PLP, PDP, and editorial pages. + +Across `/men`, the trail-running listing, the Zegama PDP, `/membership`, and Jordan Golf, the same chrome appears in identical proportions — only the photography and copy change. That is the system's signature: maximum editorial expression in the imagery, maximum mechanical restraint everywhere else. **Key Characteristics:** -- Monochromatic UI (black/white/grey) that lets product photography be the only color source -- Massive uppercase display typography (96px, line-height 0.90) that punches through hero images -- Full-bleed photography with no border radius — imagery fills every available edge -- Pill-shaped buttons (30px radius) as the primary interactive element -- 8px spacing grid with athletic discipline — every measurement snaps to the system -- Category-driven shopping architecture with large navigational image cards -- Shadow-free, border-minimal elevation model — surface differentiation through grey shifts only +- Editorial campaign hero with `{typography.display-campaign}` (Nike Futura ND, 96px, line-height 0.9, uppercase) burned directly into full-bleed photography +- Pure black/white/single-gray UI palette: `{colors.ink}`, `{colors.canvas}`, and `{colors.soft-cloud}` carry ~95% of the chrome surface area +- Pill geometry everywhere: every CTA, search field, filter chip, and badge uses `{rounded.full}` (30px) or `{rounded.md}` (24px) — there are no sharp-cornered buttons in the system +- Product cards have zero radius, zero shadow, sit directly on `{colors.soft-cloud}` swatch backgrounds — the photograph is the card +- Two-tone CTA hierarchy: `{component.button-primary}` (black on anything light) versus `{component.button-secondary}` (`{colors.soft-cloud}` on anything bright) — never both at once on the same surface +- 8px spacing system with section rhythm at `{spacing.section}` (48px) creating consistent vertical breathing across PLP, PDP, and editorial pages +- Sale signaling is the only place a non-neutral color appears in retail chrome: `{colors.sale}` price + strike-through original price, no badge background -## 2. Color Palette & Roles +## Colors -### Primary +> **Source pages:** `/men` (primary), `/w/mens-acg-trail-running-shoes-…`, `/t/acg-zegama-…`, `/membership`, `/w/jordan-golf-…`. The chrome palette is identical across all five — only photography varies. -- **Nike Black** (`#111111`): The foundation — primary text, button backgrounds, nav text, hero overlays. Deliberately not pure black (#000000), creating a fractionally softer reading experience -- **Nike White** (`#FFFFFF`): Primary page canvas, button text on dark, card surfaces, nav bar background +### Brand & Accent +- **Nike Black** (`{colors.ink}` — `#111111`): The brand's only "color." It is the primary CTA, the swatch dot, the active filter chip, the campaign overlay, the headline color, and the body text. When Nike wants to assert anything, it goes black. +- **Pure White** (`{colors.on-primary}`, `{colors.canvas}` — `#ffffff`): Equal partner to black. Carries every page background, the on-image CTA, and the inverse text on `{colors.ink}` surfaces. -### Surface & Background +### Surface +- **Soft Cloud** (`{colors.soft-cloud}` — `#f5f5f5`): The most-used non-white surface in the entire system. Product card image backgrounds, search pill, secondary CTA, utility bar, sport-category swatch tiles. It is the "color" of every product photograph's stage. +- **Hairline** (`{colors.hairline}` — `#cacacb`): 1px dividers between filter rows, footer columns, and PDP disclosure rows. +- **Hairline Soft** (`{colors.hairline-soft}` — `#e5e5e5`): Inset 1px shadow under sticky bars and tab strips, the only "shadow" the system uses. -- **Snow** (`#FAFAFA`): Lightest surface, near-white subtle differentiation (--podium-cds-color-grey-50) -- **Light Gray** (`#F5F5F5`): Secondary background, search input fill, image placeholder, loading skeleton (--podium-cds-color-grey-100) -- **Hover Gray** (`#E5E5E5`): Hover state background, disabled button fill (--podium-cds-color-grey-200) -- **Dark Surface** (`#28282A`): Primary background on dark/inverted sections (--podium-cds-color-grey-800) -- **Deep Charcoal** (`#1F1F21`): Inverse primary background, darkest non-black surface (--podium-cds-color-grey-900) -- **Dark Hover** (`#39393B`): Hover state on dark backgrounds (--podium-cds-color-grey-700) +### Text +- **Ink** (`{colors.ink}` — `#111111`): Primary text on light surfaces — headlines, product names, prices, nav. +- **Charcoal** (`{colors.charcoal}` — `#39393b`): Slightly softer body where ink is too heavy. +- **Ash** (`{colors.ash}` — `#4b4b4d`): Disabled secondary border on dark surfaces and very low-emphasis utility text. +- **Mute** (`{colors.mute}` — `#707072`): Product category subtitles ("Men's Trail Running Shoes"), footer link text, secondary metadata. +- **Stone** (`{colors.stone}` — `#9e9ea0`): Inverse secondary text on dark surfaces and lowest-emphasis utility text. -### Neutrals & Text +### Semantic +- **Sale** (`{colors.sale}` — `#d30005`): Discounted price color and "% off" copy — the only red in the entire retail chrome. +- **Sale Deep** (`{colors.sale-deep}` — `#780700`): Sale price hover/pressed and dark-mode sale anchor. +- **Success** (`{colors.success}` — `#007d48`): Confirmation messages, in-stock indicators, eligibility ticks. +- **Success Bright** (`{colors.success-bright}` — `#1eaa52`): Inverse success on dark surfaces. +- **Info** (`{colors.info}` — `#1151ff`): Informational link/badge accent in member-experience callouts. +- **Info Deep** (`{colors.info-deep}` — `#0034e3`): Pressed state for info accent. -- **Primary Text** (`#111111`): Main body text, headings, nav links (--podium-cds-color-text-primary) -- **Secondary Text** (`#707072`): Descriptive copy, metadata, timestamps, price labels (--podium-cds-color-text-secondary) -- **Disabled Text** (`#9E9EA0`): Inactive elements, unavailable options (--podium-cds-color-text-disabled) -- **Disabled Inverse** (`#4B4B4D`): Disabled text on dark backgrounds (--podium-cds-color-text-disabled-inverse) -- **Border Primary** (`#707072`): Standard border color, matching secondary text -- **Border Secondary** (`#CACACB`): Subtle borders, input borders, divider lines (--podium-cds-color-grey-300) -- **Border Disabled** (`#CACACB`): Inactive border state -- **Border Active** (`#111111`): Active/focused border, matching primary text +### Category Accents (sport / collection chips) +These appear sparingly — almost exclusively as small chip backgrounds, swatch dots, or category illustrations in editorial tiles. They are never used as text or primary CTA color. +- **Accent Pink** (`{colors.accent-pink}` — `#ed1aa0`): SKIMS / women's collection moments. +- **Accent Pink Soft** (`{colors.accent-pink-soft}` — `#ffb0dd`): Soft tinting on member-experience tiles. +- **Accent Purple Soft** (`{colors.accent-purple-soft}` — `#beaffd`): Editorial swatch dot, soft category chip. +- **Accent Purple Pale** (`{colors.accent-purple-pale}` — `#d6d1ff`): Lightest soft-tile fill. +- **Accent Teal** (`{colors.accent-teal}` — `#0a7281`): Trail / outdoor / ACG editorial accent in lockups. +- **Accent Pink Deep** (`{colors.accent-pink-deep}` — `#4c012d`): Deepest editorial overlay tint, used as wash on heritage / Jordan tiles. -### Semantic & Accent - -- **Nike Red** (`#D30005`): Critical errors, sale badges, urgent notifications (--podium-cds-color-red-600) -- **Bright Red** (`#EE0005`): Red-500, slightly lighter red for emphasis -- **Nike Orange Badge** (`#D33918`): Badge text, promotional callouts (--podium-cds-color-text-badge) -- **Orange Flash** (`#FF5000`): Expressive orange accent (--podium-cds-color-orange-400) -- **Success Green** (`#007D48`): Confirmation, availability, positive states (--podium-cds-color-green-600) -- **Success Inverse** (`#1EAA52`): Success on dark backgrounds (--podium-cds-color-green-500) -- **Link Blue** (`#1151FF`): Text links, informational highlights (--podium-cds-color-blue-500) -- **Info Inverse** (`#1190FF`): Links on dark backgrounds (--podium-cds-color-blue-400) -- **Warning Yellow** (`#FEDF35`): Warning backgrounds, attention banners (--podium-cds-color-yellow-200) -- **Focus Ring** (`rgba(39, 93, 197, 1)`): Keyboard focus indicator ring - -### Extended Color Spectrum (Podium CDS) - -Each color ramp runs 50–900 for expressive use in campaigns and product pages: - -- **Red**: `#FFE5E5` → `#EE0005` → `#530300` -- **Orange**: `#FFE2D6` → `#FF5000` → `#3E1009` -- **Yellow**: `#FEF087` → `#FCA600` → `#99470A` -- **Green**: `#DFFFB9` → `#1EAA52` → `#003C2A` -- **Teal**: `#D4FFFB` → `#008E98` → `#043441` -- **Blue**: `#D6EEFF` → `#1151FF` → `#020664` -- **Purple**: `#E4E1FC` → `#6E0FF6` → `#1C0060` -- **Pink**: `#FFE1F3` → `#ED1AA0` → `#4C012D` - -### Gradient System - -Nike avoids UI gradients. When gradients appear, they are photographic — applied to product hero backgrounds (e.g., a red shoe on a red-to-deeper-red gradient). The design system itself is flat-color only. - -## 3. Typography Rules +## Typography ### Font Family +- **Nike Futura ND** (display campaign only) — proprietary geometric sans for the towering uppercase headlines burned into campaign hero photography. Falls back to Helvetica Now Text Medium → Helvetica → Arial. +- **Helvetica Now Display Medium** (headings 16–32px) — modern Helvetica cut tuned for display sizes; carries every section title, PDP product name, and dialog headline. +- **Helvetica Now Text Medium** (UI 12–16px) — buttons, captions, swatch labels, badge text. The system's UI workhorse. +- **Helvetica Now Text** (body and links) — long-form body and underlined inline links. +- **Neue Frutiger Arabic** — RTL pairing for Arabic locales at `{typography.heading-lg}` and caption sizes. +- **Helvetica Neue 9px** — legal-fine-print utility row only (`{typography.utility-xs}`). -**Display:** Nike Futura ND (custom condensed Futura variant exclusive to Nike) -- Fallbacks: Helvetica Now Text Medium, Helvetica, Arial -- Used exclusively for large uppercase display headlines -- Characteristically tight line-height (0.90) and uppercase transform - -**Heading:** Helvetica Now Display Medium -- Fallbacks: Helvetica, Arial -- Used for section headings and product titles at 24–32px - -**Body Medium:** Helvetica Now Text Medium (weight 500) -- Fallbacks: Helvetica, Arial -- Used for links, buttons, captions, emphasized body text - -**Body:** Helvetica Now Text (weight 400) -- Fallbacks: Helvetica, Arial -- Used for standard body copy, descriptions, metadata - -**Arabic:** Neue Frutiger Arabic — locale-specific alternative +When substituting on systems without proprietary Nike fonts: pair **Inter** (Display 700 for body chrome, Display 500 for buttons) with **Bebas Neue** or **Anton** at 96px/0.9 line-height for the campaign headline tier. Tighten letter-spacing slightly (-0.5%) on the substitute to approximate Futura ND's optical weight. ### Hierarchy -| Role | Size | Weight | Line Height | Letter Spacing | Notes | -|------|------|--------|-------------|----------------|-------| -| Display | 96px | 500 | 0.90 | — | Nike Futura ND, uppercase, hero headlines | -| Heading 1 | 32px | 500 | 1.20 | — | Helvetica Now Display Medium, section titles | -| Heading 2 | 24px | 500 | 1.20 | — | Helvetica Now Display Medium, subsections | -| Heading 3 | 16px | 500 | 1.50 | — | Helvetica Now Text Medium, card titles | -| Body | 16px | 400 | 1.75 | — | Helvetica Now Text, product descriptions | -| Body Medium | 16px | 500 | 1.75 | — | Helvetica Now Text Medium, emphasized text | -| Link | 16px | 500 | 1.75 | — | Helvetica Now Text Medium, navigation links | -| Link Small | 14px | 500 | 1.86 | — | Helvetica Now Text Medium, footer/utility links | -| Button | 16px | 500 | 1.50 | — | Helvetica Now Text Medium, CTA text | -| Button Small | 14px | 500 | 1.50 | — | Helvetica Now Text Medium, secondary buttons | -| Caption | 14px | 500 | 1.50 | — | Helvetica Now Text Medium, price labels | -| Small | 12px | 500 | 1.50 | — | Helvetica Now Text Medium, timestamps | -| Tiny | 12px | 400 | 1.50 | — | Helvetica Now Text, legal text | +| Token | Size | Weight | Line Height | Letter Spacing | Use | +|---|---|---|---|---|---| +| `{typography.display-campaign}` | 96px | 500 | 0.9 | 0 | Editorial campaign headline burned into hero photography (uppercase) | +| `{typography.heading-xl}` | 32px | 500 | 1.2 | 0 | Section headers — "FEATURED FOOTWEAR", "LATEST IN CLOTHING", PDP product title block | +| `{typography.heading-lg}` | 24px | 500 | 1.2 | 0 | Subsection / member-benefit card title, large CTA label, PDP price | +| `{typography.heading-md}` | 16px | 500 | 1.75 | 0 | Card title, FAQ row label, filter group header | +| `{typography.body-md}` | 16px | 400 | 1.5 | 0 | Body copy, search-pill placeholder, product description | +| `{typography.body-strong}` | 16px | 500 | 1.5 | 0 | Product card name, filter row label, primary nav link | +| `{typography.button-lg}` | 24px | 500 | 1.2 | 0 | Pressed-letter campaign CTA inside hero blocks | +| `{typography.button-md}` | 16px | 500 | 1.5 | 0 | Standard pill CTAs across the system | +| `{typography.button-sm}` | 14px | 500 | 1.5 | 0 | Compact pill CTA, badge label, geo-selector button | +| `{typography.link-md}` | 16px | 500 | 1.75 | 0 | Underlined inline link, "View Product Details" | +| `{typography.caption-md}` | 14px | 500 | 1.5 | 0 | Product subtitle ("Men's Trail Running Shoes"), filter count, footer link | +| `{typography.caption-sm}` | 12px | 500 | 1.5 | 0 | Filter chip label, badge text, color count | +| `{typography.utility-xs}` | 9px | 500 | 1.75 | 0 | Legal copyright / fine-print row at the very bottom | ### Principles +The system runs on extreme typographic contrast: a single 96px uppercase display tier reserved for editorial campaign moments, and a quiet 12–16px Helvetica Now Text/Medium tier carrying everything else. There is almost no middle ground — the jump from `{typography.heading-xl}` (32px) directly to `{typography.body-strong}` (16px) is intentional and creates the "billboard above, catalog below" effect across every page. Letter-spacing is left at 0 (Futura ND and Helvetica Now are both cut for tight optical fit at scale). -Nike's typography is a study in tension. The display layer — Nike Futura ND at 96px with a devastating 0.90 line-height — is engineered to feel like a stadium scoreboard: massive, condensed, uppercase, impossible to ignore. It transforms headlines into battle cries. Below the display layer, Helvetica Now provides a clinical counterpoint: Swiss-precision legibility with generous 1.75 line-height for comfortable product browsing. Weight 500 (Medium) dominates throughout the body text, giving Nike's prose a slight assertiveness without the heaviness of bold — every sentence reads like a confident recommendation, not a shout. +### Note on Font Substitutes +The closest open-source path to Nike's display tier is **Bebas Neue** (free, geometric condensed) at 96px / 0.9 / uppercase / 500. For UI text, **Inter** is the safest substitute — match weights 400/500 and the system reads almost identically at button and caption sizes. -## 4. Component Stylings - -### Buttons - -**Primary** -- Background: Nike Black (`#111111`) -- Text: White (`#FFFFFF`), 16px/500, Helvetica Now Text Medium -- Border: none -- Border radius: fully rounded pill (30px) -- Padding: ~12px 24px -- Hover: background shifts to Grey-500 (`#707072`), text hover color -- Active: scale(0) ripple effect with opacity 0.5 -- Focus: 2px box-shadow ring in `rgba(39, 93, 197, 1)` -- Transition: background 200ms ease - -**Primary on Dark** -- Background: White (`#FFFFFF`) -- Text: Black (`#111111`) -- Hover: background shifts to Grey-300 (`#CACACB`) - -**Secondary (Outlined)** -- Background: transparent -- Text: Nike Black (`#111111`) -- Border: 1.5px solid `#CACACB` (grey-300) -- Border radius: 30px -- Hover: border darkens to `#707072`, background to grey-200 - -**Disabled** -- Background: Grey-200 (`#E5E5E5`) -- Text: Grey-400 (`#9E9EA0`) -- Cursor: not-allowed - -**Icon Button** -- Background: Grey-100 (`#F5F5F5`) -- Shape: 30px radius (or 50% for circular) -- Padding: 6px -- Hover: Grey-500 background - -### Cards & Containers - -- Background: White (`#FFFFFF`) — no visible card boundary in most cases -- Border radius: 0px for product image cards (edge-to-edge imagery), 20px for interactive containers -- Shadow: none — Nike uses no card shadows whatsoever -- Hover: no lift effect on product cards; underline on text links within cards -- Product cards: image on top (no radius), text metadata below with 12px gap -- Category cards: full-bleed photography with text overlay on dark gradient -- Transition: opacity 200ms ease for image swap on hover - -### Inputs & Forms - -- Background: Grey-100 (`#F5F5F5`) -- Border: 1px solid `#CACACB` when visible, or borderless on search -- Border radius: 24px (search inputs), 8px (form inputs) -- Font: Helvetica Now Text, 16px -- Focus: border shifts to `#111111` (border-active), 2px focus ring in `rgba(39, 93, 197, 1)` -- Error: border `#D30005` (critical) -- Placeholder: Grey-500 (`#707072`) -- Transition: border-color 200ms ease - -### Navigation - -- Background: White (`#FFFFFF`), sticky -- Height: ~60px desktop -- Left: Nike Swoosh logo (24x24px SVG) -- Center: Category links (New & Featured, Men, Women, Kids, Sale) in 16px/500 Helvetica Now Text Medium -- Right: Search (24px radius input), Favorites, Cart icons -- Hover: text color shifts to Grey-500 (`#707072`) -- Mobile: hamburger menu, full-screen overlay -- Top banner: promotional message bar with dark background (#111111) and white text - -### Image Treatment - -- Hero images: full-bleed, no border radius, edge-to-edge -- Product grid: square (1:1) or 4:3 aspect ratio, no border radius -- Category cards: 16:9 or 4:3, full-bleed with text overlay -- Image placeholder: Grey-100 (`#F5F5F5`) solid background -- Lazy loading: native loading="lazy", skeleton uses #F5F5F5 bg -- Product hover: secondary image swap (front → side view) - -### Promotional Banners - -- Full-width dark (`#111111`) background with white text -- Tight padding (8-12px vertical) -- Centered text, 12px/500 Helvetica Now Text Medium -- Used for shipping promotions, member benefits, sale announcements - -## 5. Layout Principles +## Layout ### Spacing System - -Base unit: 4px (primary grid is 8px multiples) - -| Token | Value | Use | -|-------|-------|-----| -| space-1 | 4px | Tight icon gaps, inline spacing | -| space-2 | 8px | Base unit, button icon gaps | -| space-3 | 12px | Card internal padding, tight margins | -| space-4 | 16px | Standard padding, nav spacing | -| space-5 | 20px | Product card gaps | -| space-6 | 24px | Section internal padding, grid gaps | -| space-7 | 32px | Section breaks | -| space-8 | 48px | Major section padding | -| space-9 | 64px | Hero section padding | -| space-10 | 80px | Large section spacing | +- **Base unit:** 8px +- **Tokens (front matter):** `{spacing.xxs}` (2px) · `{spacing.xs}` (4px) · `{spacing.sm}` (8px) · `{spacing.md}` (12px) · `{spacing.lg}` (18px) · `{spacing.xl}` (24px) · `{spacing.xxl}` (30px) · `{spacing.section}` (48px+) +- **Universal rhythm:** every page in the set uses `{spacing.section}` (48px) as the vertical gap between major content blocks (campaign hero → trending row → featured row → shop-by-sport → latest-in-clothing → footer). PLP card grids use `{spacing.sm}` (8px) gutters. PDP disclosure rows are stacked at `{spacing.xl}` (24px) vertical padding. +- **Card internal padding:** product cards use 0px internal padding — image is full-bleed; metadata rows sit directly below with `{spacing.sm}` (8px) gap between name, subtitle, and price. ### Grid & Container - -- Max container width: 1920px -- Standard content width: ~1440px with horizontal padding -- Product grid: 3-column on desktop, 2-column on tablet, 1-column on mobile -- Category grid: 3-column with full-bleed images -- Grid gap: 4-12px between product cards (intentionally tight) -- Horizontal padding: 48px desktop, 24px tablet, 16px mobile +- **Max width:** ~1440px content area with edge gutters that grow to ~80px at 1920px (the system lets very wide viewports breathe rather than stretch). +- **Column patterns:** PLP listing uses 3-up at desktop, collapsing to 2-up at 1023px and 1-up at 599px. The men's home `/men` mixes a 2-up campaign hero row, a 3- or 4-up "Trending Now" row, a horizontal-scroll "Shop by Sport" rail, and a 4-up "Latest in Clothing" thumbnail grid. +- **Filter sidebar:** ~220px fixed-width left rail on PLP at desktop, collapsing into a `Hide Filters` toggle button at narrow widths. ### Whitespace Philosophy +Whitespace is a tool for separation, not for breath. Sections butt directly against each other vertically with `{spacing.section}` rhythm, and product photos tile edge-to-edge inside their grid — there is no padding wrapped around the product image itself. The "air" comes from the `{colors.soft-cloud}` background of the photograph, not from layout margin. Headlines do not have decorative whitespace above them; they sit immediately under the section divider line. -Nike's whitespace strategy is deliberately aggressive — not in the luxurious, breathing way of a fashion brand, but in a compressed, high-density way that fills every pixel with either content or intentional absence. Product grids use minimal gaps (4-12px) to create a sense of abundance and choice. Section breaks are generous (48-80px) to separate shopping contexts. The overall effect is a store that feels packed with product while remaining navigable — like a well-organized athletic superstore. +## Elevation & Depth + +| Level | Treatment | Use | +|---|---|---| +| 0 — Flat | No shadow, no border | Default for cards, buttons, sections — the dominant treatment | +| 1 — Hairline divider | 1px solid `{colors.hairline}` | Filter row separators, footer column borders, PDP disclosure-row separators | +| 2 — Inset bottom-line | `box-shadow: inset 0 -1px 0 {colors.hairline-soft}` | Sticky utility/sub-nav bar bottom edge, tab strip underline | + +The system has no drop-shadow elevation in its retail chrome at all. Cards do not lift on the page. The only depth cue is the 1px inset hairline on sticky strips and the contrast between full-bleed photography and `{colors.soft-cloud}` product backdrops. + +### Decorative Depth +Depth in Nike's system comes entirely from photography, not from CSS effects: +- **Editorial campaign tiles** create depth via cinematic perspective — a runner on a trail, a model in a courtyard — with the Futura display headline overlaid in white or `{colors.ink}` directly on the image. +- **Product card photography** is shot on flat `{colors.soft-cloud}` to remove any background depth, so the product itself is the only thing with form on the page. +- **Sport-category tiles** on the home page are full-bleed cinematic photography with a small `{component.button-outline-on-image}` pill anchored at the bottom-left, giving a moment of crisp white pill against atmospheric image. + +## Shapes ### Border Radius Scale -| Value | Context | -|-------|---------| -| 0px | Product images, hero photography (sharp edges) | -| 8px | Form inputs (non-search) | -| 18px | Small interactive elements | -| 20px | Containers, cards with UI content | -| 24px | Search inputs, medium pills | -| 30px | Buttons, tags, filters (full pill) | -| 50% | Circular icon buttons, avatar placeholders | +| Token | Value | Use | +|---|---|---| +| `{rounded.none}` | 0px | Cards, campaign tiles, product imagery, navigation, footer — every container in the system | +| `{rounded.sm}` | 18px | Avatar / icon container in member-benefit lockups | +| `{rounded.md}` | 24px | Search pill, search submit, filter input | +| `{rounded.lg}` | 30px | Every CTA pill — primary, secondary, on-image, filter chip, geo-selector, "Notify Me" | +| `{rounded.full}` | 9999px | Color swatch dots and circular icon buttons (back, share, favorite, carousel paddle) | -## 6. Depth & Elevation +### Photography Geometry +- **Product cards:** consistent 1:1 square or near-square (~4:5 portrait on tall product crops), full-bleed within the card with no padding, sitting on `{colors.soft-cloud}` backdrop. +- **Editorial campaign hero:** ~16:9 or wider cinematic crop, full-bleed across the content max-width, with the Futura display headline burned into the lower-left or upper-left third. +- **Sport-category rail:** 4:5 portrait full-bleed thumbnails with a small CTA pill anchored bottom-left. +- **PDP main image:** square primary image with vertical thumbnail rail to its left (~5–7 thumbnails stacked at small size), enabling rapid color/angle browsing without leaving the page. +- **Avatar / category icon cards:** centered illustrated icon at ~80–96px on `{colors.canvas}` with `{typography.caption-md}` label below. -| Level | Treatment | Use | -|-------|-----------|-----| -| Flat | No shadow, no border | Default state for everything | -| Divider | `0px -1px 0px 0px #E5E5E5 inset` | Subtle inset line between sections | -| Focus | `0 0 0 2px rgba(39, 93, 197, 1)` | Keyboard focus ring | -| Overlay | Dark scrim over photography | Text-on-image legibility | +## Components -Nike's elevation philosophy is radically flat. There are no card shadows, no hover lifts, no floating elements. Depth is communicated exclusively through color — dark sections recede, light sections advance, grey shifts indicate state changes. This flatness reinforces the athletic, no-nonsense brand personality: no visual frills, just direct communication. The only "shadow" in the entire system is a 1px inset divider line and the accessibility-required focus ring. +> **No hover states documented** per system policy. Each spec covers Default and Active/Pressed only; variants live as separate `components:` entries in the front matter. -### Decorative Depth +### Buttons -- **Hero photography overlays**: Dark gradient scrims over full-bleed photography for text readability -- **Product background gradients**: Colored backgrounds behind hero product shots (e.g., red shoe on red gradient) -- **Banner bars**: Solid dark (#111111) promotional strips at page top +**`button-primary`** — the universal Nike CTA +- Background `{colors.ink}`, text `{colors.on-primary}`, type `{typography.button-md}`, padding `16px 32px`, height `{spacing.section}` (48px), rounded `{rounded.lg}` (30px pill). +- Used on every primary action in the system: "Sign Up", "Notify Me", "Buy", "Türkiye" geo-confirm, "Shop" overlay on sport tiles, "Continue". +- Pressed state lives in `button-primary-active` — the bg stays `{colors.ink}` while the surface shrinks to `scale(0.5)` with `opacity: 0.5` (Nike's signature "tap collapse" feedback that's extracted across all five pages). -## 7. Do's and Don'ts +**`button-secondary`** — soft alternative on light surfaces +- Background `{colors.soft-cloud}`, text `{colors.ink}`, type `{typography.button-md}`, padding `16px 32px`, rounded `{rounded.lg}`. +- Used as the lower-emphasis alternate when a primary CTA already exists, e.g., "United States" geo-decline next to the black "Türkiye" confirm; "Cancel" or "Discover More" on light cards. + +**`button-outline-on-image`** — overlay CTA on photography +- Background `{colors.canvas}`, text `{colors.ink}`, type `{typography.button-md}`, padding `12px 24px`, rounded `{rounded.lg}`. +- The crisp white pill that anchors the bottom-left of every full-bleed sport-category and editorial campaign tile. + +**`button-icon-circular`** — chrome icon controls +- Background `{colors.soft-cloud}` or transparent, icon `{colors.ink}`, rounded `{rounded.full}`, size 40px. +- Used for back-arrow, carousel paddle (left/right), wishlist heart, share, and "Hide Filters" toggle. + +**`filter-chip`** + **`filter-chip-active`** +- Default: background `{colors.canvas}`, text `{colors.ink}`, 1px hairline `{colors.hairline}`, type `{typography.button-md}`, rounded `{rounded.lg}`, padding `8px 16px`. +- Active: background `{colors.ink}`, text `{colors.on-primary}` — the chip flips fully inverted when selected. No middle state. + +### Inputs & Forms + +**`search-pill`** + **`search-pill-focused`** +- Default: background `{colors.soft-cloud}`, text `{colors.ink}`, type `{typography.body-md}`, rounded `{rounded.md}` (24px), padding `8px 16px`, height `40px`. Anchored to the right of the primary nav with a small magnifier icon. +- Focused: background `{colors.canvas}`, 2px solid border `{colors.ink}`, with a 12px outer halo of `{colors.soft-cloud}` (the system's only "focus ring" effect). The pill shape stays `{rounded.md}` so the halo reads as a soft glove, not a hard outline. + +### Cards & Containers + +**`product-card`** +- Container: background `{colors.canvas}`, rounded `{rounded.none}`, padding 0, no shadow. +- Image area: `{component.product-card-image}` — full-bleed product photo on `{colors.soft-cloud}` square. +- Below image (in this order with `{spacing.sm}` between): swatch dot row (3–6 dots at 12px circular), promo badge if applicable (`{component.badge-promo}` "Just In", "Coming Soon", "Recycled Materials"), product name `{typography.body-strong}` `{colors.ink}`, category subtitle `{typography.caption-md}` `{colors.mute}`, price row. +- Price row: regular price `{typography.body-strong}` `{colors.ink}`. If on sale: discounted price `{colors.sale}` followed by strike-through original `{colors.mute}` followed by "% off" in `{colors.sale}`. + +**`campaign-tile`** — the brand's signature editorial unit +- Full-bleed photography with `{typography.display-campaign}` headline burned in (uppercase, 96px, line-height 0.9). +- Headline color is whichever of `{colors.canvas}` or `{colors.ink}` reads against the underlying image — not parameterized; chosen per-asset. +- A single `{component.button-outline-on-image}` pill anchored bottom-left of the tile carries the call-to-action. + +**`category-icon-card`** +- Container: background `{colors.canvas}`, rounded `{rounded.none}`. +- Centered category illustration (~80px) + label `{typography.caption-md}` `{colors.ink}` directly below. Used in the "Latest in Clothing" 4–8-up icon strip on `/men`. + +**`member-benefit-card`** +- Full-bleed photographic card on a dark image background; copy slot at the bottom-left with `{typography.heading-lg}` headline `{colors.on-primary}` and a `{component.button-outline-on-image}` "Explore" pill below. +- Used in the `/membership` "Member Benefits" 3-up grid. + +**`swatch-dot`** + **`swatch-dot-active`** +- 12px circle, rounded `{rounded.full}`, no border in default state. Renders the colorway options on every product card and PDP color picker. +- Default: filled with the colorway's actual product color (extracted at runtime from the product image), 1px subtle outer ring in `{colors.hairline}` for white/light colorways so they remain visible on `{colors.canvas}`. +- Active: identical fill with a 2px `{colors.ink}` outer ring and 2px white interior gap, creating Nike's signature concentric-ring "selected" state. No size change between default and active. + +**`badge-promo`** +- Background `{colors.canvas}` with 1px hairline `{colors.hairline}`, text `{colors.ink}`, type `{typography.caption-sm}`, rounded `{rounded.lg}`, padding `4px 12px`. +- Sits on top of product imagery (top-left of card) with copy like "Just In", "Coming Soon", "Recycled Materials", "Member Exclusive". + +**`badge-sale-text`** +- Inline price-row text in `{colors.sale}` with no background — the only "badge" in the system that has no container. + +### Navigation + +**`utility-bar`** — top utility strip +- Background `{colors.soft-cloud}`, text `{colors.ink}`, type `{typography.caption-sm}`, height ~36px, rounded `{rounded.none}`. +- Right-aligned cluster: "Find a Store · Help · Join Us · Sign In". Always present; never collapses. + +**`primary-nav`** — main navigation +- Background `{colors.canvas}`, text `{colors.ink}`, type `{typography.body-strong}` for nav links, height 56–64px, rounded `{rounded.none}`. +- Layout: Nike swoosh logo at left (32×32), centered nav row ("New & Featured · Men · Women · Kids · Jordan · Nike SKIMS · Sport"), right cluster (search pill, wishlist heart icon, bag icon). +- The active section gets a 2px-bottom underline in `{colors.ink}` — no background fill. + +**Sub-nav strip** (PLP) — appears under primary nav with breadcrumb + sort + hide-filters controls. +- Same `{colors.canvas}` background with a 1px inset hairline-soft bottom edge. +- Left: breadcrumb in `{typography.caption-md}` `{colors.mute}` separated by " / ". +- Right: "Hide Filters" toggle + "Sort By: …" dropdown — both in `{typography.button-md}` with chevron icons. + +**Top Nav (Mobile)** +- Hamburger menu icon (left), Nike swoosh (center), search + bag icons (right). +- Search pill collapses into an icon-only button at narrow widths; tapping expands a full-width overlay search pill with `{rounded.md}`. +- Primary nav collapses into a full-height drawer that slides in from the left, listing nav rows top-down with `{spacing.xl}` vertical padding. + +### Signature Components + +**`pdp-disclosure-row`** — PDP information accordion rows +- Stacked rows for "View Product Details", "Shipping & Returns", "Reviews (n)" with `{spacing.xl}` vertical padding and a 1px `{colors.hairline}` divider below each. +- Label `{typography.body-strong}` `{colors.ink}` left-aligned; chevron `{colors.ink}` right-aligned. + +**`faq-row`** — `/membership` FAQ accordion +- Identical pattern to `pdp-disclosure-row` but with `{typography.heading-md}` label weight; 1px `{colors.hairline}` divider below each. + +**`filter-sidebar`** — PLP left rail +- Container `{colors.canvas}`, rounded `{rounded.none}`. +- Section headers `{typography.body-strong}` `{colors.ink}` with `{spacing.lg}` (18px) vertical gap between groups. +- Active filters get a 1px ink underline; counts in parentheses use `{colors.mute}`. + +**`footer`** +- Background `{colors.canvas}` with a single 1px `{colors.hairline}` top divider. +- Four columns: Resources / Help / Company / Promotions & Discounts, each with column header `{typography.body-strong}` `{colors.ink}` and link list `{typography.caption-md}` `{colors.mute}`. +- Below the columns: a horizontal rule, then a fine-print row with `{typography.utility-xs}` `{colors.mute}` (copyright, locale switcher, terms, privacy, supply-chain act). + +## Do's and Don'ts ### Do - -- Use Nike Black (#111111) for all primary text — never pure #000000 -- Keep buttons pill-shaped (30px radius) and limited to primary/secondary variants -- Use full-bleed, edge-to-edge photography for hero sections — no border radius on images -- Let product photography provide all color vibrancy; keep UI monochromatic -- Use uppercase Nike Futura ND ONLY for display headlines (96px+) -- Maintain tight product grid gaps (4-12px) for a dense, abundant feel -- Use Grey-100 (#F5F5F5) for all input and placeholder backgrounds -- Reserve color exclusively for semantic meaning (red=error, green=success, blue=link) -- Use weight 500 (Medium) for all interactive text elements +- Reserve `{typography.display-campaign}` exclusively for editorial campaign hero lockups — never use 96px Futura for section headers or product titles. +- Use `{component.button-primary}` (`{colors.ink}` pill) as the single primary action per viewport. Pair it at most with `{component.button-secondary}` (`{colors.soft-cloud}` pill) for a soft alternative. +- Stage every product photograph on `{colors.soft-cloud}` — the gray is the system's "studio." +- Keep all CTAs pill-shaped at `{rounded.lg}` (30px). Never introduce a square or `{rounded.sm}` button. +- Use `{colors.sale}` only on price rows — never on backgrounds, badges, or chrome. +- Stack content sections at `{spacing.section}` (48px) rhythm with no decorative dividers between them; the photography's bleed-edge is the divider. +- Anchor on-image CTAs with `{component.button-outline-on-image}` (white pill) at bottom-left — the system's universal "shop this image" position. ### Don't +- Don't introduce drop shadows or card elevation. Cards sit flat on the page; the only depth cue is the 1px inset hairline on sticky bars. +- Don't use any of the category accent colors (`{colors.accent-pink}`, `{colors.accent-purple-soft}`, `{colors.accent-teal}`) for primary chrome — they belong to swatch dots, soft tile fills, and editorial moments only. +- Don't replace `{colors.ink}` with a near-black gray like `{colors.charcoal}` for a CTA — Nike's primary pill is true `#111111`. +- Don't pad inside product cards. The image is full-bleed; metadata sits directly below with `{spacing.sm}` (8px) between rows. +- Don't put two campaign-tile lockups in the same row at the same scale — Nike alternates a single full-bleed editorial tile with a 2-up or 4-up product/category grid. +- Don't underline anything other than `{typography.link-md}` inline links and the active primary-nav indicator. Buttons, headings, and prices stay un-underlined. +- Don't introduce a third button shape. Pill or icon-circular — that's the entire button shape vocabulary. -- Don't add shadows to cards — Nike's elevation model is entirely flat -- Don't use border radius on product imagery — only UI elements get rounded corners -- Don't introduce brand colors beyond the grey scale for UI elements -- Don't use Nike Futura ND below 24px — it's exclusively a display face -- Don't add hover lift effects — Nike cards don't animate on hover -- Don't use regular weight (400) for buttons or links — always use 500 -- Don't place colored backgrounds behind UI elements — color is reserved for product contexts -- Don't use more than two levels of text hierarchy per card (title + body) -- Don't add decorative dividers — the 1px inset is the only divider pattern -- Don't soften the contrast — Nike's design deliberately pushes black-on-white to maximum - -## 8. Responsive Behavior +## Responsive Behavior ### Breakpoints | Name | Width | Key Changes | -|------|-------|-------------| -| Mobile | <640px | Single column, hamburger nav, display text scales down, tight 16px padding | -| Small Tablet | 640-768px | 2-column product grid begins, nav still collapsed | -| Tablet | 768-960px | 2-column grids, category cards scale, horizontal padding 24px | -| Small Desktop | 960-1024px | Nav expands to full horizontal, 3-column product grid | -| Desktop | 1024-1440px | Full layout, expanded nav, 3-column grids, 48px padding | -| Large Desktop | >1440px | Max-width container centered, increased margins, hero images full-bleed | +|---|---|---| +| ultrawide | 1920px+ | Content max-width holds at ~1440px; outer gutters grow to ~80px on each side | +| desktop-large | 1440px | Default desktop layout — 3-up product grid, 4-up clothing strip, full primary nav | +| desktop | 1200px | Same as large with slightly narrower outer gutters | +| desktop-small | 1024px | Filter sidebar starts compressing; sport rail shows ~3 visible tiles | +| tablet | 1023–961px | 3-up PLP collapses to 2-up; "Hide Filters" becomes a default toggle | +| tablet-narrow | 960–640px | Primary nav center cluster collapses to a hamburger drawer; search pill becomes icon-only | +| mobile-landscape | 639–600px | 2-up PLP collapses to 1-up; product cards become full-width with image and metadata stacking | +| mobile | 599–320px | Single-column everything; campaign tiles render at full screen width with shorter Futura sizes (~64px) | ### Touch Targets - -- Minimum touch target: 44x44px (WCAG AAA) -- Mobile nav icons: 48x48px touch area -- Product cards: full surface is tappable -- Filter pills: minimum 36px height with 12px padding +All interactive elements meet WCAG AAA (44×44px minimum). Pills (`{component.button-primary}`, `{component.button-secondary}`) sit at 48px height with 32px horizontal padding. Icon-circular buttons (`{component.button-icon-circular}`) sit at 40px — Nike's PDP carousel paddle and wishlist heart sit just under AAA but above AA at 40×40, with hit-target padding extending the tappable area to 48px+. Filter-chip pills are 40px height with 16px padding. ### Collapsing Strategy - -- **Navigation**: Full category links → hamburger menu below 960px; search, favorites, cart icons remain visible -- **Product grids**: 3-col → 2-col at 960px → 1-col at 640px -- **Hero sections**: Display text scales from 96px → 64px → 48px; hero images remain full-bleed at all sizes -- **Category cards**: 3-col → 2-col → 1-col with maintained full-bleed imagery -- **Section padding**: 80px → 48px → 32px → 24px as viewport narrows -- **Promotional banner**: text wraps or truncates, maintains dark background +- **Primary nav:** desktop center cluster → mobile drawer triggered by hamburger at left of the swoosh. +- **PLP grid:** 3-up → 2-up → 1-up at 1023, 599, and below; gutters drop from `{spacing.sm}` to `{spacing.xs}` on mobile. +- **Filter sidebar:** 220px fixed → "Hide Filters" toggle → off-canvas full-screen filter drawer at mobile. +- **Sport rail:** desktop horizontal scroll with ~5 visible → mobile horizontal scroll with ~1.5 visible (peek-next-card pattern). +- **Section spacing:** `{spacing.section}` 48px desktop → 32px tablet → 24px mobile to keep editorial rhythm tight on small screens. +- **Editorial campaign headline:** desktop 96px → tablet 64px → mobile 48px, line-height stays at 0.9 across all sizes. ### Image Behavior +- Product imagery is responsive at the same 1:1 ratio across all breakpoints — the image scales, the ratio doesn't. +- Editorial campaign tiles use art-direction crops: a 16:9 wide hero on desktop swaps to a 4:5 portrait on mobile so the figure stays centered and the headline still has burn-in space. +- All non-critical product imagery is lazy-loaded as the user scrolls into the next grid row. -- Responsive images via Nike CDN (`c.static-nike.com`) with width parameters -- Product images: srcset with multiple resolutions (w_320, w_640, w_960, w_1920) -- Hero images: full-bleed at all breakpoints, aspect ratio shifts (16:9 desktop → 4:3 mobile) -- Lazy loading: native loading="lazy", grey-100 placeholder during load -- Art direction: hero crops change between desktop and mobile compositions +## Iteration Guide -## 9. Agent Prompt Guide +1. Focus on ONE component at a time. Pull its YAML entry from the front matter and verify every property resolves. +2. Reference component names and tokens directly (`{colors.ink}`, `{component.button-primary-active}`, `{rounded.lg}`) — do not paraphrase color names or radii in prose. +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 (`-active`, `-disabled`, `-focused`) — do not bury them inside prose. Nike's pressed state (`scale(0.5) opacity 0.5`) is intentional and must be its own entry, not a hover stand-in. +5. Default body to `{typography.body-md}`; reach for `{typography.body-strong}` for product names and primary nav links; reserve `{typography.display-campaign}` strictly for hero campaign lockups. +6. Keep `{colors.ink}` scarce per viewport — if more than one solid-black pill or block appears in the same fold, neutralize one to `{component.button-secondary}` or `{component.button-outline-on-image}`. +7. When introducing a new component, ask whether it can be expressed with the existing pill + flat-card + photography-on-`{colors.soft-cloud}` vocabulary before adding new tokens. The system's strength is that it almost never needs new ones. -### Quick Color Reference +## Known Gaps -- Primary CTA: Nike Black (`#111111`) -- Background: White (`#FFFFFF`) -- Secondary surface: Light Gray (`#F5F5F5`) -- Heading text: Nike Black (`#111111`) -- Body text / hover: Secondary Text (`#707072`) -- Border: Border Secondary (`#CACACB`) -- Error: Nike Red (`#D30005`) -- Link: Link Blue (`#1151FF`) - -### Example Component Prompts - -- "Create a product hero section with full-bleed edge-to-edge photography, no border radius, a dark gradient overlay for text, and a massive uppercase 96px/500 headline in Nike Futura style with 0.90 line-height and a Nike Black (#111111) pill button (30px radius)" -- "Design a 3-column product card grid with square images (no border radius), 4px gap between cards, product name in 16px/500 Nike Black (#111111), price in 14px/500, and secondary text in Grey-500 (#707072)" -- "Build a sticky white navigation bar with a left-aligned logo, centered category links in 16px/500 (#111111) with hover color #707072, and right-aligned search (24px radius, #F5F5F5 background), favorites, and cart icons" -- "Create a promotional banner strip with #111111 background, white 12px/500 centered text, and 8px vertical padding — full width, no border radius" -- "Design a secondary outlined button with transparent background, 1.5px #CACACB border, 30px pill radius, 16px/500 #111111 text, hover border darkening to #707072" - -### Iteration Guide - -When refining existing screens generated with this design system: -1. Focus on ONE component at a time -2. Reference specific color names and hex codes from this document -3. Remember: product photography is the color — UI stays monochromatic -4. Use the grey scale for state changes: #F5F5F5 → #E5E5E5 → #CACACB → #707072 -5. If something feels too colorful in the UI, it probably is — Nike keeps UI greyscale -6. Display type (Nike Futura) should ALWAYS be uppercase and never below 24px -7. Body type (Helvetica Now) should almost always be weight 500 for interactive elements +- **Mobile screenshots not captured** — responsive behavior described above synthesizes Nike's known mobile pattern (hamburger drawer, 1-up grid, headline downscale) from desktop evidence and the breakpoint list extracted from tokens. +- **Hover states not documented** by system policy — Nike's CSS uses `--pds-color-element-hover` and `--pds-color-text-hover` tokens but these are not included here. +- **Dialog / modal styling** beyond the geo-selector and the country-confirmation pill pair could not be confirmed from the captured surfaces; bag, wishlist, and login overlays are not documented. +- **Form field styling** for checkout, sign-up, and address forms is not present in the captured surfaces — only the search pill is documented. +- **Bag and wishlist** icon-state variants (filled count badges) not visible in the captured pages. diff --git a/design-md/nvidia/DESIGN.md b/design-md/nvidia/DESIGN.md index 4dfcaac..e8ff2b5 100644 --- a/design-md/nvidia/DESIGN.md +++ b/design-md/nvidia/DESIGN.md @@ -1,293 +1,640 @@ -# Design System Inspired by NVIDIA +--- +version: alpha +name: NVIDIA +description: | + An engineering-grade marketing system organized around two surface modes — a deep black canvas for hero and footer chapters and a flat paper-white canvas for body content — connected by a single, almost violently saturated NVIDIA Green accent that carries every CTA, every active tab, and the small decorative corner squares that mark out cards. The system is unapologetically angular: 2px radius across every surface, tight bold sans-serif typography in NVIDIA's proprietary EMEA cut, and a hairline gray rule that separates dense multi-column technical content. There is no decorative gradient, no atmospheric mesh, no soft drop shadow — just black, white, gray, and green stacked into a structured editorial grid that scales from product cards to massive industry landing pages without bending its rules. -## 1. Visual Theme & Atmosphere +colors: + primary: "#76b900" + on-primary: "#000000" + primary-dark: "#5a8d00" + ink: "#000000" + canvas: "#ffffff" + surface-dark: "#000000" + surface-soft: "#f7f7f7" + surface-elevated: "#1a1a1a" + hairline: "#cccccc" + hairline-strong: "#5e5e5e" + body: "#1a1a1a" + mute: "#757575" + stone: "#898989" + ash: "#a7a7a7" + on-dark: "#ffffff" + on-dark-mute: "rgba(255,255,255,0.7)" + link-blue: "#0046a4" + blue-700: "#0046a4" + error: "#e52020" + error-deep: "#650b0b" + warning: "#df6500" + warning-bright: "#ef9100" + success-deep: "#3f8500" + accent-yellow-pale: "#feeeb2" + accent-purple: "#952fc6" + accent-purple-deep: "#4d1368" + accent-purple-pale: "#f9d4ff" + accent-green-pale: "#bff230" -NVIDIA's website is a high-contrast, technology-forward experience that communicates raw computational power through design restraint. The page is built on a stark black (`#000000`) and white (`#ffffff`) foundation, punctuated by NVIDIA's signature green (`#76b900`) -- a color so specific it functions as a brand fingerprint. This is not the lush green of nature; it's the electric, lime-shifted green of GPU-rendered light, a color that sits between chartreuse and kelly green and immediately signals "NVIDIA" to anyone in technology. +typography: + display-xl: + fontFamily: NVIDIA-EMEA + fontSize: 48px + fontWeight: 700 + lineHeight: 1.25 + letterSpacing: 0 + display-lg: + fontFamily: NVIDIA-EMEA + fontSize: 36px + fontWeight: 700 + lineHeight: 1.25 + letterSpacing: 0 + heading-xl: + fontFamily: NVIDIA-EMEA + fontSize: 24px + fontWeight: 700 + lineHeight: 1.25 + letterSpacing: 0 + heading-lg: + fontFamily: NVIDIA-EMEA + fontSize: 22px + fontWeight: 400 + lineHeight: 1.75 + letterSpacing: 0 + heading-md: + fontFamily: NVIDIA-EMEA + fontSize: 20px + fontWeight: 700 + lineHeight: 1.25 + letterSpacing: 0 + heading-sm: + fontFamily: NVIDIA-EMEA + fontSize: 18px + fontWeight: 700 + lineHeight: 1.4 + letterSpacing: 0 + card-title: + fontFamily: NVIDIA-EMEA + fontSize: 17px + fontWeight: 700 + lineHeight: 1.47 + letterSpacing: 0 + body-md: + fontFamily: NVIDIA-EMEA + fontSize: 16px + fontWeight: 400 + lineHeight: 1.5 + letterSpacing: 0 + body-strong: + fontFamily: NVIDIA-EMEA + fontSize: 16px + fontWeight: 700 + lineHeight: 1.5 + letterSpacing: 0 + body-sm: + fontFamily: NVIDIA-EMEA + fontSize: 15px + fontWeight: 400 + lineHeight: 1.67 + letterSpacing: 0 + button-lg: + fontFamily: NVIDIA-EMEA + fontSize: 18px + fontWeight: 700 + lineHeight: 1.25 + letterSpacing: 0 + button-md: + fontFamily: NVIDIA-EMEA + fontSize: 16px + fontWeight: 700 + lineHeight: 1.25 + letterSpacing: 0 + button-sm: + fontFamily: NVIDIA-EMEA + fontSize: 14.4px + fontWeight: 700 + lineHeight: 1 + letterSpacing: 0.144px + link-md: + fontFamily: NVIDIA-EMEA + fontSize: 15px + fontWeight: 400 + lineHeight: 1.5 + letterSpacing: 0 + caption-md: + fontFamily: NVIDIA-EMEA + fontSize: 14px + fontWeight: 700 + lineHeight: 1.43 + letterSpacing: 0 + textTransform: uppercase + caption-sm: + fontFamily: NVIDIA-EMEA + fontSize: 12px + fontWeight: 400 + lineHeight: 1.25 + letterSpacing: 0 + caption-xs: + fontFamily: NVIDIA-EMEA + fontSize: 11px + fontWeight: 700 + lineHeight: 1 + letterSpacing: 0 + utility-xs: + fontFamily: NVIDIA-EMEA + fontSize: 10px + fontWeight: 700 + lineHeight: 1.5 + letterSpacing: 0 + textTransform: uppercase -The custom NVIDIA-EMEA font family (with Arial and Helvetica fallbacks) creates a clean, industrial typographic voice. Headings at 36px bold with tight 1.25 line-height create dense, authoritative blocks of text. The font lacks the geometric playfulness of Silicon Valley sans-serifs -- it's European, pragmatic, and engineering-focused. Body text runs at 15-16px, comfortable for reading but not generous, maintaining the sense that screen real estate is optimized like GPU memory. +rounded: + none: 0px + xs: 1px + sm: 2px + full: 9999px -What distinguishes NVIDIA's design from other dark-background tech sites is the disciplined use of the green accent. The `#76b900` appears in borders (`2px solid #76b900`), link underlines (`underline 2px rgb(118, 185, 0)`), and CTAs -- but never as backgrounds or large surface areas on the main content. The green is a signal, not a surface. Combined with a deep shadow system (`rgba(0, 0, 0, 0.3) 0px 0px 5px`) and minimal border radius (1-2px), the overall effect is of precision engineering hardware rendered in pixels. +spacing: + xxs: 2px + xs: 4px + sm: 8px + md: 12px + lg: 16px + xl: 24px + xxl: 32px + section: 64px + +components: + button-primary: + backgroundColor: "{colors.primary}" + textColor: "{colors.on-primary}" + typography: "{typography.button-md}" + rounded: "{rounded.sm}" + padding: 11px 24px + height: 44px + button-primary-active: + backgroundColor: "{colors.primary-dark}" + textColor: "{colors.on-primary}" + typography: "{typography.button-md}" + rounded: "{rounded.sm}" + button-outline: + backgroundColor: "transparent" + textColor: "{colors.ink}" + typography: "{typography.button-md}" + rounded: "{rounded.sm}" + padding: 11px 13px + button-outline-on-dark: + backgroundColor: "transparent" + textColor: "{colors.on-dark}" + typography: "{typography.button-md}" + rounded: "{rounded.sm}" + button-ghost-link: + textColor: "{colors.primary}" + typography: "{typography.button-md}" + rounded: "{rounded.none}" + button-disabled: + backgroundColor: "{colors.surface-soft}" + textColor: "{colors.ash}" + rounded: "{rounded.sm}" + pill-tab: + backgroundColor: "transparent" + textColor: "{colors.ink}" + typography: "{typography.button-sm}" + rounded: "{rounded.sm}" + padding: 10px 18px + pill-tab-active: + backgroundColor: "{colors.ink}" + textColor: "{colors.on-dark}" + typography: "{typography.button-sm}" + rounded: "{rounded.sm}" + text-input: + backgroundColor: "{colors.canvas}" + textColor: "{colors.ink}" + typography: "{typography.body-md}" + rounded: "{rounded.sm}" + padding: 12px 16px + height: 44px + text-input-focused: + backgroundColor: "{colors.canvas}" + textColor: "{colors.ink}" + rounded: "{rounded.sm}" + search-input: + backgroundColor: "{colors.canvas}" + textColor: "{colors.ink}" + typography: "{typography.body-md}" + rounded: "{rounded.sm}" + padding: 10px 16px + height: 40px + product-card: + backgroundColor: "{colors.canvas}" + textColor: "{colors.ink}" + typography: "{typography.card-title}" + rounded: "{rounded.sm}" + padding: 24px + feature-card: + backgroundColor: "{colors.canvas}" + textColor: "{colors.ink}" + typography: "{typography.body-md}" + rounded: "{rounded.sm}" + padding: 32px + resource-card: + backgroundColor: "{colors.canvas}" + textColor: "{colors.ink}" + typography: "{typography.card-title}" + rounded: "{rounded.sm}" + padding: 24px + hero-card-dark: + backgroundColor: "{colors.surface-dark}" + textColor: "{colors.on-dark}" + typography: "{typography.display-xl}" + rounded: "{rounded.none}" + padding: 80px 48px + cta-strip-dark: + backgroundColor: "{colors.surface-dark}" + textColor: "{colors.on-dark}" + typography: "{typography.heading-xl}" + rounded: "{rounded.none}" + padding: 64px 48px + callout-stat: + backgroundColor: "{colors.canvas}" + textColor: "{colors.ink}" + typography: "{typography.display-lg}" + rounded: "{rounded.sm}" + padding: 32px + corner-square: + backgroundColor: "{colors.primary}" + rounded: "{rounded.none}" + size: 12px + utility-bar: + backgroundColor: "{colors.surface-dark}" + textColor: "{colors.on-dark}" + typography: "{typography.caption-sm}" + rounded: "{rounded.none}" + height: 32px + primary-nav: + backgroundColor: "{colors.surface-dark}" + textColor: "{colors.on-dark}" + typography: "{typography.body-strong}" + rounded: "{rounded.none}" + height: 64px + breadcrumb-bar: + backgroundColor: "{colors.surface-soft}" + textColor: "{colors.body}" + typography: "{typography.caption-md}" + rounded: "{rounded.none}" + height: 48px + sub-nav-strip: + backgroundColor: "{colors.surface-soft}" + textColor: "{colors.ink}" + typography: "{typography.button-md}" + rounded: "{rounded.none}" + height: 56px + footer-section: + backgroundColor: "{colors.surface-dark}" + textColor: "{colors.on-dark-mute}" + typography: "{typography.body-sm}" + rounded: "{rounded.none}" + padding: 64px 48px + link-inline: + textColor: "{colors.link-blue}" + typography: "{typography.link-md}" + badge-tag: + backgroundColor: "{colors.surface-soft}" + textColor: "{colors.body}" + typography: "{typography.caption-md}" + rounded: "{rounded.sm}" + padding: 4px 10px +--- + +## Overview + +NVIDIA's marketing system is built like a piece of engineering documentation that learned graphic design — every page is a structured cascade of dense, factual information arranged on a paper-white grid, framed top and bottom by deep black hero/footer chapters. There is exactly one accent color in the entire system, and it is doing all the work: NVIDIA Green (`{colors.primary}` — `#76b900`), used for every primary CTA, every active tab, every link affordance on dark surfaces, and the small decorative corner squares that mark out card containers. Nothing else competes for attention. + +The system's character comes from extreme typographic restraint and an almost punishingly angular geometry. Every container, button, and image uses `{rounded.sm}` (2px) — a token that's barely-there but never zero, giving the system the precise, technical feel of CAD output rather than warm consumer software. Cards sit on plain `{colors.canvas}` with a hairline `{colors.hairline}` border (no shadow, no elevation), separated by tight 8px-base spacing rhythm. Long-form pages stack 6–10 of these cards into multi-column technical grids without ever introducing decorative breaks. + +The black-canvas hero and footer chapters are the system's "headline moments" — a single full-bleed photographic or 3D-rendered image with `{typography.display-xl}` headline copy laid in white, a single green CTA button, and a small green corner square as the only ornamentation. Everything else is subordinate. **Key Characteristics:** -- NVIDIA Green (`#76b900`) as pure accent -- borders, underlines, and interactive highlights only -- Black (`#000000`) dominant background with white (`#ffffff`) text on dark sections -- NVIDIA-EMEA custom font with Arial/Helvetica fallback -- industrial, European, clean -- Tight line-heights (1.25 for headings) creating dense, authoritative text blocks -- Minimal border radius (1-2px) -- sharp, engineered corners throughout -- Green-bordered buttons (`2px solid #76b900`) as primary interactive pattern -- Font Awesome 6 Pro/Sharp icon system at weight 900 for sharp iconography -- Multi-framework architecture (PrimeReact, Fluent UI, Element Plus) enabling rich interactive components +- Single-accent system: `{colors.primary}` carries every CTA, active state, and decorative motif. The rest is monochrome black/white/gray. +- Two-mode surface architecture: `{colors.surface-dark}` for hero/footer chapters; `{colors.canvas}` for body — alternating in a predictable rhythm down the page +- Hyper-angular geometry: `{rounded.sm}` (2px) on every interactive element. There are no pill buttons, no rounded cards, no soft chrome. +- NVIDIA-EMEA proprietary sans-serif at weights 400 and 700, scaled across a 12-tier hierarchy from `{typography.utility-xs}` (10px) up to `{typography.display-xl}` (48px) +- Card library leans on hairline `{colors.hairline}` borders and `{colors.surface-soft}` backgrounds rather than shadows for separation +- Signature decorative element: the small `{component.corner-square}` (~12px green square) anchored to one corner of resource and feature cards +- Dense multi-column footer with 4–6 link columns on `{colors.surface-dark}` — every page closes with the same structured global navigation -## 2. Color Palette & Roles +## Colors -### Primary Brand -- **NVIDIA Green** (`#76b900`): The signature -- borders, link underlines, CTA outlines, active indicators. Never used as large surface fills. -- **True Black** (`#000000`): Primary page background, text on light surfaces, dominant tone. -- **Pure White** (`#ffffff`): Text on dark backgrounds, light section backgrounds, card surfaces. +> **Source pages:** `/tr-tr/` (primary homepage), `/en-eu/industries/healthcare-life-sciences/`, `/en-eu/solutions/ai/`, `/en-eu/ai/foundry/`. The chrome palette is identical across all four — only photography and copy vary. -### Extended Brand Palette -- **NVIDIA Green Light** (`#bff230`): Bright lime accent for highlights and hover states. -- **Orange 400** (`#df6500`): Warm accent for alerts, featured badges, or energy-related contexts. -- **Yellow 300** (`#ef9100`): Secondary warm accent, product category highlights. -- **Yellow 050** (`#feeeb2`): Light warm surface for callout backgrounds. +### Brand & Accent +- **NVIDIA Green** (`{colors.primary}` — `#76b900`): the brand. Every primary CTA, every active state, every link affordance on dark surfaces, every corner square, and the brand wordmark itself. +- **NVIDIA Green Dark** (`{colors.primary-dark}` — `#5a8d00`): pressed state for the primary button — a single notch deeper than the brand green. +- **Accent Green Pale** (`{colors.accent-green-pale}` — `#bff230`): rare highlight tint used in editorial callouts and decorative micro-blocks; never on chrome. -### Status & Semantic -- **Red 500** (`#e52020`): Error states, destructive actions, critical alerts. -- **Red 800** (`#650b0b`): Deep red for severe warning backgrounds. -- **Green 500** (`#3f8500`): Success states, positive indicators (darker than brand green). -- **Blue 700** (`#0046a4`): Informational accents, link hover alternative. +### Surface +- **Page Canvas** (`{colors.canvas}` — `#ffffff`): the body of every page. Cards sit directly on it with hairline rules. +- **Soft Surface** (`{colors.surface-soft}` — `#f7f7f7`): breadcrumb strip, sub-nav, side-by-side comparison panels, alternating row backgrounds. +- **Black Canvas** (`{colors.surface-dark}` — `#000000`): hero chapter, dark CTA strips, footer, primary nav. The system's "frame" color. +- **Surface Elevated** (`{colors.surface-elevated}` — `#1a1a1a`): nested dark panels inside the footer (column dividers, fine-print bar). +- **Hairline** (`{colors.hairline}` — `#cccccc`): 1px card border, table rule, divider between footer link sections. +- **Hairline Strong** (`{colors.hairline-strong}` — `#5e5e5e`): 1px divider on dark surfaces (footer column rules, dark-mode card edges). -### Decorative -- **Purple 800** (`#4d1368`): Deep purple for gradient ends, premium/AI contexts. -- **Purple 100** (`#f9d4ff`): Light purple surface tint. -- **Fuchsia 700** (`#8c1c55`): Rich accent for special promotions or featured content. +### Text +- **Ink** (`{colors.ink}` — `#000000`): headlines and body text on `{colors.canvas}`. +- **Body** (`{colors.body}` — `#1a1a1a`): long-form paragraph text where pure black is too heavy. +- **Mute** (`{colors.mute}` — `#757575`): metadata, breadcrumb separators, footer copyright. +- **Stone** (`{colors.stone}` — `#898989`): least-emphasis text and disabled state. +- **Ash** (`{colors.ash}` — `#a7a7a7`): disabled icon color and faint utility text. +- **On Dark** (`{colors.on-dark}` — `#ffffff`): primary text on `{colors.surface-dark}`. +- **On Dark Mute** (`{colors.on-dark-mute}` — `rgba(255,255,255,0.7)`): secondary footer link text and dark-canvas body copy. -### Neutral Scale -- **Gray 300** (`#a7a7a7`): Muted text, disabled labels. -- **Gray 400** (`#898989`): Secondary text, metadata. -- **Gray 500** (`#757575`): Tertiary text, placeholders, footers. -- **Gray Border** (`#5e5e5e`): Subtle borders, divider lines. -- **Near Black** (`#1a1a1a`): Dark surfaces, card backgrounds on black pages. +### Semantic +- **Error** (`{colors.error}` — `#e52020`): validation messages, destructive confirmation. +- **Error Deep** (`{colors.error-deep}` — `#650b0b`): pressed state for error buttons; hover-pressed validation icons. +- **Warning** (`{colors.warning}` — `#df6500`): caution callouts, deprecated documentation banners. +- **Warning Bright** (`{colors.warning-bright}` — `#ef9100`): inverse warning on dark canvas. +- **Success Deep** (`{colors.success-deep}` — `#3f8500`): positive confirmation where NVIDIA Green's saturation would clash. +- **Link Blue** (`{colors.link-blue}` — `#0046a4`): inline anchor link color on light canvas — the only blue in the system, reserved for prose-embedded hyperlinks. -### Interactive States -- **Link Default (dark bg)** (`#ffffff`): White links on dark backgrounds. -- **Link Default (light bg)** (`#000000`): Black links with green underline on light backgrounds. -- **Link Hover** (`#3860be`): Blue shift on hover across all link variants. -- **Button Hover** (`#1eaedb`): Teal highlight for button hover states. -- **Button Active** (`#007fff`): Bright blue for active/pressed button states. -- **Focus Ring** (`#000000 solid 2px`): Black outline for keyboard focus. +### Editorial Accents (used sparingly inside long-form content) +- **Accent Purple** (`{colors.accent-purple}` — `#952fc6`): research / scientific computing editorial accent. +- **Accent Purple Deep** (`{colors.accent-purple-deep}` — `#4d1368`): paired dark for purple lockups. +- **Accent Purple Pale** (`{colors.accent-purple-pale}` — `#f9d4ff`): wash background for editorial callouts. +- **Accent Yellow Pale** (`{colors.accent-yellow-pale}` — `#feeeb2`): documentation tip / soft callout fill. -### Shadows & Depth -- **Card Shadow** (`rgba(0, 0, 0, 0.3) 0px 0px 5px 0px`): Subtle ambient shadow for elevated cards. - -## 3. Typography Rules +## Typography ### Font Family -- **Primary**: `NVIDIA-EMEA`, with fallbacks: `Arial, Helvetica, sans-serif` -- **Icon Font**: `Font Awesome 6 Pro` (weight 900 for solid icons, 700 for regular) -- **Icon Sharp**: `Font Awesome 6 Sharp` (weight 300 for light icons, 400 for regular) +- **NVIDIA-EMEA** is the proprietary brand sans-serif used across every text role on the site. It carries weights 400 (regular) and 700 (bold) and falls back to Arial → Helvetica. +- **Font Awesome 6 Pro** and **Font Awesome 6 Sharp** are used exclusively for iconography (chevrons, social glyphs, breadcrumb separators, search/menu icons) at sizes 14–22px. + +NVIDIA's type system is unusually flat: most chrome and body roles render at the same line-height (1.25–1.5) with the only meaningful variation coming from weight (400 vs 700) and size. The system relies on weight contrast — not size jumps and not color tinting — to establish hierarchy, which gives marketing copy and technical documentation an editorial newspaper feel. ### Hierarchy -| Role | Font | Size | Weight | Line Height | Letter Spacing | Notes | -|------|------|------|--------|-------------|----------------|-------| -| Display Hero | NVIDIA-EMEA | 36px (2.25rem) | 700 | 1.25 (tight) | normal | Maximum impact headlines | -| Section Heading | NVIDIA-EMEA | 24px (1.50rem) | 700 | 1.25 (tight) | normal | Section titles, card headings | -| Sub-heading | NVIDIA-EMEA | 22px (1.38rem) | 400 | 1.75 (relaxed) | normal | Feature descriptions, subtitles | -| Card Title | NVIDIA-EMEA | 20px (1.25rem) | 700 | 1.25 (tight) | normal | Card and module headings | -| Body Large | NVIDIA-EMEA | 18px (1.13rem) | 700 | 1.67 (relaxed) | normal | Emphasized body, lead paragraphs | -| Body | NVIDIA-EMEA | 16px (1.00rem) | 400 | 1.50 | normal | Standard reading text | -| Body Bold | NVIDIA-EMEA | 16px (1.00rem) | 700 | 1.50 | normal | Strong labels, nav items | -| Body Small | NVIDIA-EMEA | 15px (0.94rem) | 400 | 1.67 (relaxed) | normal | Secondary content, descriptions | -| Body Small Bold | NVIDIA-EMEA | 15px (0.94rem) | 700 | 1.50 | normal | Emphasized secondary content | -| Button Large | NVIDIA-EMEA | 18px (1.13rem) | 700 | 1.25 (tight) | normal | Primary CTA buttons | -| Button | NVIDIA-EMEA | 16px (1.00rem) | 700 | 1.25 (tight) | normal | Standard buttons | -| Button Compact | NVIDIA-EMEA | 14.4px (0.90rem) | 700 | 1.00 (tight) | 0.144px | Small/compact buttons | -| Link | NVIDIA-EMEA | 14px (0.88rem) | 700 | 1.43 | normal | Navigation links | -| Link Uppercase | NVIDIA-EMEA | 14px (0.88rem) | 700 | 1.43 | normal | `text-transform: uppercase`, nav labels | -| Caption | NVIDIA-EMEA | 14px (0.88rem) | 600 | 1.50 | normal | Metadata, timestamps | -| Caption Small | NVIDIA-EMEA | 12px (0.75rem) | 400 | 1.25 (tight) | normal | Fine print, legal | -| Micro Label | NVIDIA-EMEA | 10px (0.63rem) | 700 | 1.50 | normal | `text-transform: uppercase`, tiny badges | -| Micro | NVIDIA-EMEA | 11px (0.69rem) | 700 | 1.00 (tight) | normal | Smallest UI text | +| Token | Size | Weight | Line Height | Letter Spacing | Use | +|---|---|---|---|---|---| +| `{typography.display-xl}` | 48px | 700 | 1.25 | 0 | Hero headline on `{component.hero-card-dark}` | +| `{typography.display-lg}` | 36px | 700 | 1.25 | 0 | Section headline ("Explore Our AI Solutions"), large stat callouts | +| `{typography.heading-xl}` | 24px | 700 | 1.25 | 0 | Sub-section title, dark CTA-strip headline | +| `{typography.heading-lg}` | 22px | 400 | 1.75 | 0 | Long-form intro paragraph that doubles as a heading | +| `{typography.heading-md}` | 20px | 700 | 1.25 | 0 | Card group title, sub-nav anchor heading | +| `{typography.heading-sm}` | 18px | 700 | 1.4 | 0 | Side-rail filter group, small section label | +| `{typography.card-title}` | 17px | 700 | 1.47 | 0 | Resource card title, product card title | +| `{typography.body-md}` | 16px | 400 | 1.5 | 0 | Body copy, default paragraph | +| `{typography.body-strong}` | 16px | 700 | 1.5 | 0 | Inline emphasis, primary nav link, label | +| `{typography.body-sm}` | 15px | 400 | 1.67 | 0 | Card description, secondary copy | +| `{typography.button-lg}` | 18px | 700 | 1.25 | 0 | Hero primary CTA | +| `{typography.button-md}` | 16px | 700 | 1.25 | 0 | Standard primary/secondary buttons | +| `{typography.button-sm}` | 14.4px | 700 | 1 | 0.144px | Compact pill tab, in-card secondary CTA | +| `{typography.link-md}` | 15px | 400 | 1.5 | 0 | Inline anchor link in body prose | +| `{typography.caption-md}` | 14px | 700 | 1.43 | 0 | Eyebrow over section heading, breadcrumb (uppercase) | +| `{typography.caption-sm}` | 12px | 400 | 1.25 | 0 | Footnote copy, metadata, table caption | +| `{typography.caption-xs}` | 11px | 700 | 1 | 0 | Pill chip label, utility-bar text | +| `{typography.utility-xs}` | 10px | 700 | 1.5 | 0 | Legal fine-print bar at the very bottom (uppercase) | ### Principles -- **Bold as the default voice**: NVIDIA leans heavily on weight 700 for headings, buttons, links, and labels. The 400 weight is reserved for body text and descriptions -- everything else is bold, projecting confidence and authority. -- **Tight headings, relaxed body**: Heading line-height is consistently 1.25 (tight), while body text relaxes to 1.50-1.67. This contrast creates visual density at the top of content blocks and comfortable readability in paragraphs. -- **Uppercase for navigation**: Link labels use `text-transform: uppercase` with weight 700, creating a navigation voice that reads like hardware specification labels. -- **No decorative tracking**: Letter-spacing is normal throughout, except for compact buttons (0.144px). The font itself carries the industrial character without manipulation. +The typography is brand-locked: NVIDIA-EMEA is used at every level, no serif, no display variant, no monospace, no italic. Hierarchy is built almost entirely from size and weight — color is reserved for emphasis (`{colors.primary}` on links over dark, `{colors.link-blue}` on light) and never used to separate type tiers. -## 4. Component Stylings +### Note on Font Substitutes +NVIDIA-EMEA is proprietary. The closest open-source pairing is **Inter** (weights 400/700) — its x-height and stroke contrast match NVIDIA-EMEA's optical metrics within ~2% at body sizes. **Arial** is the official documented fallback and is acceptable for any system where Inter is unavailable. Avoid Helvetica Now or Helvetica Neue substitutes; their slightly tighter cap heights drift away from the brand's geometry. + +## Layout + +### Spacing System +- **Base unit:** 8px +- **Tokens (front matter):** `{spacing.xxs}` (2px) · `{spacing.xs}` (4px) · `{spacing.sm}` (8px) · `{spacing.md}` (12px) · `{spacing.lg}` (16px) · `{spacing.xl}` (24px) · `{spacing.xxl}` (32px) · `{spacing.section}` (64px) +- **Universal section rhythm:** every page in the set uses `{spacing.section}` (64px) as the vertical gap between major content blocks. Card grids use `{spacing.xl}` (24px) gutters; in-card padding sits at `{spacing.xl}` to `{spacing.xxl}` depending on density. +- **Hero chapter padding:** 80px vertical / 48px horizontal — the largest spacing in the system, reserved for `{component.hero-card-dark}`. + +### Grid & Container +- **Max width:** ~1280px content area at desktop, with 24px gutters that grow to ~48px at ultrawide. +- **Column patterns:** + - Card grids: 4-up at desktop, 3-up at 1024px, 2-up at 768px, 1-up at 480px. + - Long-form text: 2-column 60/40 split (body + sidebar) at desktop, single-column at < 960px. + - Footer: 6-up link columns at desktop, collapsing to 2-up on tablet, full accordion on mobile. +- **Card aspect:** product cards lean to 1:1 or 4:3 with 16:9 imagery on top + 1–2 lines of metadata below. Resource cards are 3:2 imagery with a longer description block. + +### Whitespace Philosophy +Whitespace is structural, not atmospheric. Sections butt against each other with `{spacing.section}` rhythm — there are no decorative dividers, no empty "breathing room" bands, no gradient transitions between sections. The sense of air comes from `{colors.canvas}` body sections sandwiched between `{colors.surface-dark}` chapter blocks, not from generous padding inside any one component. + +## Elevation & Depth + +| Level | Treatment | Use | +|---|---|---| +| 0 — Flat | No border, no shadow | Canvas-on-canvas blocks, hero chapter content, footer column body | +| 1 — Hairline border | 1px solid `{colors.hairline}` | All cards on `{colors.canvas}`, table cells, comparison panels | +| 2 — Hairline strong | 1px solid `{colors.hairline-strong}` | Dividers on `{colors.surface-dark}` (footer column rules, dark-card edges) | +| 3 — Soft shadow | `0 0 5px 0 rgba(0,0,0,0.3)` | Sticky nav bottom edge when scrolled, sticky CTA bar — used very sparingly | + +NVIDIA's system has effectively no drop-shadow elevation in card or content surfaces. The only "shadow" in the extracted tokens is a subtle 5px ambient on sticky chrome bars. Cards do not lift; cards are flat rectangles with hairline borders. + +### Decorative Depth +Depth in NVIDIA's system comes from photography and 3D-rendered hero imagery rather than from CSS effects: +- **Hero imagery:** full-bleed photographic or rendered scenes (data-center hardware, neural-net visualizations, life-sciences microscopy) sit behind hero copy with a dark gradient overlay for legibility. +- **Decorative corner squares:** the small `{component.corner-square}` (~12px solid `{colors.primary}` square) anchored to the top-left or bottom-right corner of resource and feature cards — the system's only consistent ornamental device. +- **Editorial 3D accents:** isometric or wireframe 3D renderings appear as illustration-style fills inside long-form articles, never as chrome. + +## Shapes + +### Border Radius Scale + +| Token | Value | Use | +|---|---|---| +| `{rounded.none}` | 0px | Hero chapter, footer, dark CTA strips, primary nav | +| `{rounded.xs}` | 1px | Decorative micro-rules and inset accent strips | +| `{rounded.sm}` | 2px | Every interactive element — buttons, cards, inputs, pill tabs, badges | +| `{rounded.full}` | 9999px / 50% | Avatar circles, social-icon dots, brand wordmark icon | + +The system is aggressively angular. Outside of avatar/icon circles, no element exceeds 2px radius. The 2px is enough to soften the optical aliasing on a sharp edge but small enough that the system reads as engineering-grade rather than consumer-friendly. + +### Photography Geometry +- **Hero imagery:** full-bleed 16:9 (desktop) cropping to 4:5 portrait on mobile. +- **Card imagery:** 16:9 thumbnail at the top of resource cards; 1:1 square for product/SKU cards; 3:2 for editorial article cards. +- **Decorative corner squares:** 12×12px on standard cards, scaled to 16×16 on hero callouts. +- **Avatar/social icons:** 32–40px circles with 1px hairline. + +## Components + +> **No hover states documented** per system policy. Each spec covers Default and Active/Pressed only; variants live as separate `components:` entries in the front matter. ### Buttons -**Primary (Green Border)** -- Background: `transparent` -- Text: `#000000` -- Padding: 11px 13px -- Border: `2px solid #76b900` -- Radius: 2px -- Font: 16px weight 700 -- Hover: background `#1eaedb`, text `#ffffff` -- Active: background `#007fff`, text `#ffffff`, border `1px solid #003eff`, scale(1) -- Focus: background `#1eaedb`, text `#ffffff`, outline `#000000 solid 2px`, opacity 0.9 -- Use: Primary CTA ("Learn More", "Explore Solutions") +**`button-primary`** — the universal NVIDIA CTA +- Background `{colors.primary}`, text `{colors.on-primary}`, type `{typography.button-md}`, padding `11px 24px`, height `44px`, rounded `{rounded.sm}`. +- The single most-repeated component in the system: hero CTA, dark CTA strip, "Learn More" on every card group, "Sign Up" / "Get Started" on every long-form page bottom. +- Pressed state lives in `button-primary-active` — background drops to `{colors.primary-dark}` (`#5a8d00`) with the same text color. -**Secondary (Green Border Thin)** -- Background: transparent -- Border: `1px solid #76b900` -- Radius: 2px -- Use: Secondary actions, alternative CTAs +**`button-outline`** — secondary on light canvas +- Background transparent, text `{colors.ink}`, 2px solid `{colors.primary}` border, type `{typography.button-md}`, padding `11px 13px`, rounded `{rounded.sm}`. +- The system's most distinctive secondary CTA: a clear pane bordered in NVIDIA Green. Used for "Read the Documentation", "Watch the Video", "Compare Products" — second-tier actions that still earn the brand color. -**Compact / Inline** -- Font: 14.4px weight 700 -- Letter-spacing: 0.144px -- Line-height: 1.00 -- Use: Inline CTAs, compact navigation +**`button-outline-on-dark`** — outline on `{colors.surface-dark}` +- Background transparent, text `{colors.on-dark}`, 1px solid `{colors.on-dark}`, type `{typography.button-md}`, rounded `{rounded.sm}`. +- White-on-black variant used in dark hero/footer CTA strips paired with a primary green button. -### Cards & Containers -- Background: `#ffffff` (light) or `#1a1a1a` (dark sections) -- Border: none (clean edges) or `1px solid #5e5e5e` -- Radius: 2px -- Shadow: `rgba(0, 0, 0, 0.3) 0px 0px 5px 0px` for elevated cards -- Hover: shadow intensification -- Padding: 16-24px internal +**`button-ghost-link`** — inline arrow link +- Text `{colors.primary}` with a small right-arrow icon, type `{typography.button-md}`, no background, no border, rounded `{rounded.none}`. +- "Learn More →" affordance sitting at the bottom of resource cards and long-form section blocks. The arrow is uppercase and bold per `{typography.caption-md}`-equivalent treatment. -### Links -- **On Dark Background**: `#ffffff`, no underline, hover shifts to `#3860be` -- **On Light Background**: `#000000` or `#1a1a1a`, underline `2px solid #76b900`, hover shifts to `#3860be`, underline removed -- **Green Links**: `#76b900`, hover shifts to `#3860be` -- **Muted Links**: `#666666`, hover shifts to `#3860be` +**`button-disabled`** +- Background `{colors.surface-soft}`, text `{colors.ash}`, rounded `{rounded.sm}` — flat gray. + +### Tabs & Chips + +**`pill-tab`** + **`pill-tab-active`** +- Default: transparent background, text `{colors.ink}`, type `{typography.button-sm}`, padding `10px 18px`, rounded `{rounded.sm}`. +- Active: background `{colors.ink}`, text `{colors.on-dark}` — the tab flips inverted on selection. Used in the "Latest in AI Resources" filter strip and similar segmented controls. + +**`badge-tag`** +- Background `{colors.surface-soft}`, text `{colors.body}`, type `{typography.caption-md}`, padding `4px 10px`, rounded `{rounded.sm}` (uppercase). +- Document type / category labels at the top of resource cards ("WHITE PAPER", "WEBINAR", "BLOG"). + +### Inputs & Forms + +**`text-input`** + **`text-input-focused`** +- Default: background `{colors.canvas}`, text `{colors.ink}`, 1px solid `{colors.hairline}`, type `{typography.body-md}`, padding `12px 16px`, height `44px`, rounded `{rounded.sm}`. +- Focused: same surface, border becomes 2px solid `{colors.primary}` — the green border is the only focus signal in the system. + +**`search-input`** +- Used in the global search overlay — same treatment as `text-input` but at 40px height with a magnifier glyph at left. + +### Cards + +**`product-card`** +- Container: background `{colors.canvas}`, 1px solid `{colors.hairline}`, padding `{spacing.xl}` (24px), rounded `{rounded.sm}`. +- Layout: 16:9 product image at top, `{typography.card-title}` title, `{typography.body-sm}` description, `{component.button-ghost-link}` "Learn More →" affordance at bottom. +- The `{component.corner-square}` sits at the top-left corner. + +**`feature-card`** +- Container: background `{colors.canvas}`, 1px solid `{colors.hairline}`, padding `{spacing.xxl}` (32px), rounded `{rounded.sm}`. +- Layout: icon (Font Awesome at 22–24px) at top in `{colors.primary}` followed by `{typography.heading-md}` title and `{typography.body-md}` body. +- Used in 3-up or 4-up grids that explain product capabilities ("Agentic AI", "Data Science", "Inference", "Conversational AI"). + +**`resource-card`** +- Container: background `{colors.canvas}`, 1px solid `{colors.hairline}`, padding `{spacing.xl}`, rounded `{rounded.sm}`. +- Header strip: `{component.badge-tag}` document-type label. +- Body: 3:2 thumbnail, `{typography.card-title}` title, `{typography.body-sm}` description. +- Footer: ghost-link "Read More →" with right-pointing chevron in `{colors.primary}`. + +**`callout-stat`** +- Background `{colors.canvas}` with 1px hairline `{colors.hairline}`, padding `{spacing.xxl}`, rounded `{rounded.sm}`. +- Massive `{typography.display-lg}` (36px) numeric in `{colors.primary}` followed by `{typography.body-md}` caption underneath ("4× faster training", "60% lower cost", etc.). Used inside long-form industry pages. + +### Hero & CTA Strips + +**`hero-card-dark`** +- Background `{colors.surface-dark}` with full-bleed 16:9 photographic/3D image and dark gradient overlay; copy slot at left. +- `{typography.display-xl}` headline `{colors.on-dark}`, `{typography.heading-lg}` subhead, single `{component.button-primary}` CTA (sometimes paired with `{component.button-outline-on-dark}`). +- Anchors the top of every primary landing page. + +**`cta-strip-dark`** +- Same surface as hero but compressed to a 1-row band with `{typography.heading-xl}` headline + single CTA. +- Sits between content sections as a "Ready to get started?" bridge. + +### Decorative + +**`corner-square`** +- 12×12px solid `{colors.primary}` square anchored to a card corner. The brand's signature ornamental motif. +- Used on resource cards, feature cards, and editorial callouts. Position varies (top-left, bottom-right) but the size and color are constant. ### Navigation -- Dark black background (`#000000`) -- Logo left-aligned, prominent NVIDIA wordmark -- Links: NVIDIA-EMEA 14px weight 700 uppercase, `#ffffff` -- Hover: color shift, no underline change -- Mega-menu dropdowns for product categories -- Sticky on scroll with backdrop -### Image Treatment -- Product/GPU renders as hero images, often full-width -- Screenshot images with subtle shadow for depth -- Green gradient overlays on dark hero sections -- Circular avatar containers with 50% radius +**`utility-bar`** +- Background `{colors.surface-dark}`, text `{colors.on-dark}`, height 32px, type `{typography.caption-sm}`, rounded `{rounded.none}`. +- Right-aligned cluster: locale selector / "Login" / "Account". Always present at the very top of the page. -### Distinctive Components +**`primary-nav`** +- Background `{colors.surface-dark}`, text `{colors.on-dark}`, height 64px, type `{typography.body-strong}`, rounded `{rounded.none}`. +- Layout: NVIDIA wordmark at left, centered nav row ("Products / Solutions / Industries / Resources / Support / Company"), right cluster (search-glyph + "Login" button + green CTA "Get Started"). -**Product Cards** -- Clean white or dark card with minimal radius (2px) -- Green accent border or underline on title -- Bold heading + lighter description pattern -- CTA with green border at bottom +**`breadcrumb-bar`** +- Background `{colors.surface-soft}`, text `{colors.body}`, height 48px, type `{typography.caption-md}` (uppercase). +- Sits directly under the primary nav on every interior page; chevron separators in `{colors.mute}`. -**Tech Spec Tables** -- Industrial grid layouts -- Alternating row backgrounds (subtle gray shift) -- Bold labels, regular values -- Green highlights for key metrics +**`sub-nav-strip`** +- Background `{colors.surface-soft}`, text `{colors.ink}`, height 56px, type `{typography.button-md}`, rounded `{rounded.none}`. +- Section-specific nav anchored above content (e.g., "Healthcare → Drug Discovery / Medical Imaging / Genomics / Patient Care"). -**Cookie/Consent Banner** -- Fixed bottom positioning -- Rounded buttons (2px radius) -- Gray border treatments +**Top Nav (Mobile)** +- Hamburger menu icon (left), NVIDIA wordmark (center), search + locale icons (right). Primary nav collapses into a full-screen drawer that slides in from the right. -## 5. Layout Principles +### Footer -### Spacing System -- Base unit: 8px -- Scale: 1px, 2px, 3px, 4px, 5px, 6px, 7px, 8px, 9px, 10px, 11px, 12px, 13px, 15px -- Primary padding values: 8px, 11px, 13px, 16px, 24px, 32px -- Section spacing: 48-80px vertical padding +**`footer-section`** +- Background `{colors.surface-dark}`, text `{colors.on-dark-mute}`, padding `{spacing.section}` (64px) vertical / 48px horizontal, rounded `{rounded.none}`. +- Layout: 6-column link grid (Products / Software / Resources / Company Info / Solutions / Support) with column headers in `{typography.body-strong}` `{colors.on-dark}` and link lists in `{typography.body-sm}` `{colors.on-dark-mute}`. +- Below the columns: social-icon strip + locale selector + legal/privacy fine-print row in `{typography.utility-xs}` (uppercase) `{colors.mute}`. -### Grid & Container -- Max content width: approximately 1200px (contained) -- Full-width hero sections with contained text -- Feature sections: 2-3 column grids for product cards -- Single-column for article/blog content -- Sidebar layouts for documentation +### Inline -### Whitespace Philosophy -- **Purposeful density**: NVIDIA uses tighter spacing than typical SaaS sites, reflecting the density of technical content. White space exists to separate concepts, not to create luxury emptiness. -- **Section rhythm**: Dark sections alternate with white sections, using background color (not just spacing) to separate content blocks. -- **Card density**: Product cards sit close together with 16-20px gaps, creating a catalog feel rather than a gallery feel. +**`link-inline`** +- Body-prose anchor link: `{colors.link-blue}` text with underline. The ONLY blue in the system — appears nowhere except inline links inside `{typography.body-md}` paragraphs. -### Border Radius Scale -- Micro (1px): Inline spans, tiny elements -- Standard (2px): Buttons, cards, containers, inputs -- the default for nearly everything -- Circle (50%): Avatar images, circular tab indicators +## Do's and Don'ts -## 6. Depth & Elevation +### Do +- Reserve `{colors.primary}` for primary CTAs, active states, decorative corner squares, and the NVIDIA wordmark itself. Treat it as a precious resource. +- Stack hero/footer chapters in `{colors.surface-dark}` and body sections in `{colors.canvas}` — alternate them in a predictable rhythm down the page. +- Anchor a `{component.corner-square}` to one corner of every reusable card. It is the system's identity tag. +- Use `{rounded.sm}` (2px) on every interactive element. Never go to 0, never go past 4. +- Build hierarchy from font weight (400 vs 700) and size, not from color tinting. Body text stays `{colors.ink}` or `{colors.body}` regardless of context. +- Stack content sections at `{spacing.section}` (64px) rhythm with no decorative dividers between them. +- Pair `{component.button-primary}` (green fill) with `{component.button-outline}` (green border) for primary + secondary action pairs. -| Level | Treatment | Use | -|-------|-----------|-----| -| Flat (Level 0) | No shadow | Page backgrounds, inline text | -| Subtle (Level 1) | `rgba(0,0,0,0.3) 0px 0px 5px 0px` | Standard cards, modals | -| Border (Level 1b) | `1px solid #5e5e5e` | Content dividers, section borders | -| Green accent (Level 2) | `2px solid #76b900` | Active elements, CTAs, selected items | -| Focus (Accessibility) | `2px solid #000000` outline | Keyboard focus ring | +### Don't +- Don't introduce drop shadows on cards or content surfaces. The only allowed shadow is the 5px ambient on sticky chrome. +- Don't substitute `{colors.success-deep}`, `{colors.accent-green-pale}`, or any other green for `{colors.primary}` in CTAs. The brand green is precise. +- Don't use `{colors.link-blue}` outside of inline body-prose links. It is not a button color, not a chrome color. +- Don't soften the geometry. No pill buttons, no rounded cards, no `{rounded.lg}` or higher anywhere except avatars and social icons. +- Don't pad the hero `{component.hero-card-dark}` symmetrically. Copy hugs the left third; imagery fills the right. +- Don't add a second accent color for variety. The system is intentionally one-color. +- Don't put `{component.button-primary}` on a `{colors.canvas}` background where green-on-white would clash with photo content — use `{component.button-outline}` instead and reserve fill for dark surfaces. -**Shadow Philosophy**: NVIDIA's depth system is minimal and utilitarian. There is essentially one shadow value -- a 5px ambient blur at 30% opacity -- used sparingly for cards and modals. The primary depth signal is not shadow but _color contrast_: black backgrounds next to white sections, green borders on black surfaces. This creates hardware-like visual layering where depth comes from material difference, not simulated light. - -### Decorative Depth -- Green gradient washes behind hero content -- Dark-to-darker gradients (black to near-black) for section transitions -- No glassmorphism or blur effects -- clarity over atmosphere - -## 7. Responsive Behavior +## Responsive Behavior ### Breakpoints + | Name | Width | Key Changes | -|------|-------|-------------| -| Mobile Small | <375px | Compact single column, reduced padding | -| Mobile | 375-425px | Standard mobile layout | -| Mobile Large | 425-600px | Wider mobile, some 2-col hints | -| Tablet Small | 600-768px | 2-column grids begin | -| Tablet | 768-1024px | Full card grids, expanded nav | -| Desktop | 1024-1350px | Standard desktop layout | -| Large Desktop | >1350px | Maximum content width, generous margins | +|---|---|---| +| ultrawide | 1920px+ | Content max-width holds at 1280px; outer gutters grow to ~80px | +| desktop-large | 1440px | Default desktop layout — 4-up card grid, 6-col footer | +| desktop | 1280px | Same as large with slightly narrower outer gutters | +| desktop-small | 1024px | 4-up cards collapse to 3-up; sub-nav remains horizontal | +| tablet | 768px | 3-up cards collapse to 2-up; primary nav becomes hamburger drawer | +| mobile | 480px | Single-column everything; footer columns collapse to accordion | +| mobile-narrow | 320px | Hero `{typography.display-xl}` scales from 48px → 32px | ### Touch Targets -- Buttons use 11px 13px padding for comfortable tap targets -- Navigation links at 14px uppercase with adequate spacing -- Green-bordered buttons provide high-contrast touch targets on dark backgrounds -- Mobile: hamburger menu collapse with full-screen overlay +All interactive elements meet WCAG AA (≥ 44×44px). `{component.button-primary}` sits at 44px height with 24px horizontal padding. `{component.text-input}` sits at 44px. `{component.pill-tab}` sits at ~40px height with extended hit-target padding to 44px. `{component.button-outline}` matches the 44px standard. Footer links are 18–20px line-height with 8–12px vertical padding to keep tap targets at ~36–44px depending on link length. ### Collapsing Strategy -- Hero: 36px heading scales down proportionally -- Navigation: full horizontal nav collapses to hamburger menu at ~1024px -- Product cards: 3-column to 2-column to single column stacked -- Footer: multi-column grid collapses to single stacked column -- Section spacing: 64-80px reduces to 32-48px on mobile -- Images: maintain aspect ratio, scale to container width +- **Primary nav:** desktop center cluster → tablet hamburger drawer at 768px. +- **Card grid:** 4-up → 3-up → 2-up → 1-up at 1024, 768, and 480px; gutters drop from 24px to 16px on mobile. +- **Footer:** 6-up link columns → 2-up at tablet → full accordion at mobile (each column header becomes a tap-to-expand row). +- **Hero copy:** desktop `{typography.display-xl}` (48px) → tablet 36px → mobile 32px; line-height holds at 1.25. +- **Sub-nav strip:** desktop horizontal anchor row → tablet horizontal scroll → mobile collapses into a select dropdown. +- **Section padding:** `{spacing.section}` (64px) desktop → 48px tablet → 32px mobile. +- **Long-form text:** desktop 60/40 body+sidebar → tablet/mobile single-column with sidebar pushed to the bottom. ### Image Behavior -- GPU/product renders maintain high resolution at all sizes -- Hero images scale proportionally with viewport -- Card images use consistent aspect ratios -- Full-bleed dark sections maintain edge-to-edge treatment +- Hero imagery uses art-direction crops: 16:9 wide hero on desktop swaps to 4:5 portrait on mobile so the subject stays centered and headline text still has overlay space. +- Card imagery is a fixed aspect (16:9 for resource, 1:1 for product) that scales rather than re-crops between breakpoints. +- All non-critical imagery is lazy-loaded as the user scrolls into the next grid row. -## 8. Responsive Behavior (Extended) +## Iteration Guide -### Typography Scaling -- Display 36px scales to ~24px on mobile -- Section headings 24px scale to ~20px on mobile -- Body text maintains 15-16px across all breakpoints -- Button text maintains 16px for consistent tap targets +1. Focus on ONE component at a time. Pull its YAML entry from the front matter and verify every property resolves. +2. Reference component names and tokens directly (`{colors.primary}`, `{component.button-primary-active}`, `{rounded.sm}`) — 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 (`-active`, `-disabled`, `-focused`) — do not bury them inside prose. +5. Default body to `{typography.body-md}`; reach for `{typography.body-strong}` for emphasis; reserve `{typography.display-xl}` strictly for hero chapter headlines. +6. Keep `{colors.primary}` scarce per viewport — if more than one solid-green CTA appears in the same fold, neutralize one to `{component.button-outline}`. +7. When introducing a new component, ask whether it can be expressed with the existing card + 2px-radius + corner-square + green-CTA vocabulary before adding new tokens. The system's strength is that it almost never needs new ones. -### Dark/Light Section Strategy -- Dark sections (black bg, white text) alternate with light sections (white bg, black text) -- The green accent remains consistent across both surface types -- On dark: links are white, underlines are green -- On light: links are black, underlines are green -- This alternation creates natural scroll rhythm and content grouping +## Known Gaps -## 9. Agent Prompt Guide - -### Quick Color Reference -- Primary accent: NVIDIA Green (`#76b900`) -- Background dark: True Black (`#000000`) -- Background light: Pure White (`#ffffff`) -- Heading text (dark bg): White (`#ffffff`) -- Heading text (light bg): Black (`#000000`) -- Body text (light bg): Black (`#000000`) or Near Black (`#1a1a1a`) -- Body text (dark bg): White (`#ffffff`) or Gray 300 (`#a7a7a7`) -- Link hover: Blue (`#3860be`) -- Border accent: `2px solid #76b900` -- Button hover: Teal (`#1eaedb`) - -### Example Component Prompts -- "Create a hero section on black background. Headline at 36px NVIDIA-EMEA weight 700, line-height 1.25, color #ffffff. Subtitle at 18px weight 400, line-height 1.67, color #a7a7a7. CTA button with transparent background, 2px solid #76b900 border, 2px radius, 11px 13px padding, text #ffffff. Hover: background #1eaedb, text white." -- "Design a product card: white background, 2px border-radius, box-shadow rgba(0,0,0,0.3) 0px 0px 5px. Title at 20px NVIDIA-EMEA weight 700, line-height 1.25, color #000000. Body at 15px weight 400, line-height 1.67, color #757575. Green underline accent on title: border-bottom 2px solid #76b900." -- "Build a navigation bar: #000000 background, sticky top. NVIDIA logo left-aligned. Links at 14px NVIDIA-EMEA weight 700 uppercase, color #ffffff. Hover: color #3860be. Green-bordered CTA button right-aligned." -- "Create a dark feature section: #000000 background. Section label at 14px weight 700 uppercase, color #76b900. Heading at 24px weight 700, color #ffffff. Description at 16px weight 400, color #a7a7a7. Three product cards in a row with 20px gap." -- "Design a footer: #000000 background. Multi-column layout with link groups. Links at 14px weight 400, color #a7a7a7. Hover: color #76b900. Bottom bar with legal text at 12px, color #757575." - -### Iteration Guide -1. Always use `#76b900` as accent, never as a background fill -- it's a signal color for borders, underlines, and highlights -2. Buttons are transparent with green borders by default -- filled backgrounds appear only on hover/active states -3. Weight 700 is the dominant voice for all interactive and heading elements; 400 is only for body paragraphs -4. Border radius is 2px for everything -- this sharp, minimal rounding is core to the industrial aesthetic -5. Dark sections use white text; light sections use black text -- green accent works identically on both -6. Link hover is always `#3860be` (blue) regardless of the link's default color -7. Line-height 1.25 for headings, 1.50-1.67 for body text -- maintain this contrast for visual hierarchy -8. Navigation uses uppercase 14px bold -- this hardware-label typography is part of the brand voice +- **Mobile screenshots not captured** — responsive behavior synthesizes NVIDIA's known mobile pattern (hamburger drawer, accordion footer, 1-up card grid, hero downscale) from desktop evidence and the documented breakpoint stack. +- **Hover states not documented** by system policy. +- **Dialog / modal styling** beyond the locale-selector overlay not visible in the captured surfaces. +- **Form field styling** for full sign-up / contact forms is not present in the captured surfaces — only inline search and basic text inputs are documented. +- **Login / authenticated chrome** not in the captured pages. diff --git a/design-md/ollama/DESIGN.md b/design-md/ollama/DESIGN.md index 4284b16..38da8e1 100644 --- a/design-md/ollama/DESIGN.md +++ b/design-md/ollama/DESIGN.md @@ -1,267 +1,539 @@ -# Design System Inspired by Ollama +--- +version: alpha +name: Ollama +description: | + An almost defiantly minimal documentation-first system that treats the home page like a Markdown README — paper-white canvas, 36px center-aligned heading, a single black pill CTA, an inline terminal install snippet, and a hand-drawn llama mascot as the only ornamental element. No gradient, no hero photography, no marketing pyrotechnics. The chrome is a tiny utility palette of pure black, pure white, and three neutral grays; every interactive element is fully rounded into a pill (`{rounded.full}`); typography is SF Pro Rounded for headings paired with system sans for body and ui-monospace for code. Pricing tiers, FAQs, and "your data stays yours" guarantees all sit on the same flat canvas inside thin-border cards — the system is the documentation, and the documentation is the system. -## 1. Visual Theme & Atmosphere +colors: + primary: "#000000" + on-primary: "#ffffff" + ink: "#000000" + ink-deep: "#090909" + charcoal: "#525252" + body: "#737373" + mute: "#a3a3a3" + canvas: "#ffffff" + surface-soft: "#fafafa" + surface-card: "#ffffff" + hairline: "#e5e5e5" + hairline-strong: "#d4d4d4" + on-dark: "#ffffff" + on-dark-mute: "rgba(255,255,255,0.7)" + surface-dark: "#171717" + focus-ring: "rgba(59,130,246,0.5)" + link: "#000000" + link-mute: "#737373" + terminal-red: "#ff5f56" + terminal-yellow: "#ffbd2e" + terminal-green: "#27c93f" -Ollama's interface is radical minimalism taken to its logical conclusion — a pure-white void where content floats without decoration, shadow, or color. The design philosophy mirrors the product itself: strip away everything unnecessary until only the essential tool remains. This is the digital equivalent of a Dieter Rams object — every pixel earns its place, and the absence of design IS the design. +typography: + display-xl: + fontFamily: SF Pro Rounded + fontSize: 36px + fontWeight: 500 + lineHeight: 1.11 + letterSpacing: 0 + display-lg: + fontFamily: SF Pro Rounded + fontSize: 30px + fontWeight: 500 + lineHeight: 1.2 + letterSpacing: 0 + heading-lg: + fontFamily: SF Pro Rounded + fontSize: 24px + fontWeight: 600 + lineHeight: 1.33 + letterSpacing: 0 + heading-md: + fontFamily: ui-sans-serif + fontSize: 20px + fontWeight: 500 + lineHeight: 1.4 + letterSpacing: 0 + heading-sm: + fontFamily: ui-sans-serif + fontSize: 18px + fontWeight: 500 + lineHeight: 1.56 + letterSpacing: 0 + body-md: + fontFamily: ui-sans-serif + fontSize: 16px + fontWeight: 400 + lineHeight: 1.5 + letterSpacing: 0 + body-strong: + fontFamily: ui-sans-serif + fontSize: 16px + fontWeight: 500 + lineHeight: 1.5 + letterSpacing: 0 + body-sm: + fontFamily: ui-sans-serif + fontSize: 14px + fontWeight: 400 + lineHeight: 1.43 + letterSpacing: 0 + body-sm-strong: + fontFamily: ui-sans-serif + fontSize: 14px + fontWeight: 500 + lineHeight: 1.43 + letterSpacing: 0 + caption-sm: + fontFamily: ui-sans-serif + fontSize: 12px + fontWeight: 400 + lineHeight: 1.33 + letterSpacing: 0 + code-md: + fontFamily: ui-monospace + fontSize: 16px + fontWeight: 400 + lineHeight: 1.5 + letterSpacing: 0 + code-sm: + fontFamily: ui-monospace + fontSize: 14px + fontWeight: 400 + lineHeight: 1.43 + letterSpacing: 0 + button-md: + fontFamily: ui-sans-serif + fontSize: 14px + fontWeight: 500 + lineHeight: 1 + letterSpacing: 0 -The entire page exists in pure grayscale. There is zero chromatic color in the interface — no brand blue, no accent green, no semantic red. The only colors that exist are shades between pure black (`#000000`) and pure white (`#ffffff`), creating a monochrome environment that lets the user's mental model of "open models" remain uncolored by brand opinion. The Ollama llama mascot, rendered in simple black line art, is the only illustration — and even it's monochrome. +rounded: + none: 0px + sm: 6px + md: 8px + lg: 12px + full: 9999px -What makes Ollama distinctive is the combination of SF Pro Rounded (Apple's rounded system font) with an exclusively pill-shaped geometry (9999px radius on everything interactive). The rounded letterforms + rounded buttons + rounded containers create a cohesive "softness language" that makes a developer CLI tool feel approachable and friendly rather than intimidating. This is minimalism with warmth — not cold Swiss-style grid minimalism, but the kind where the edges are literally softened. +spacing: + xxs: 2px + xs: 4px + sm: 8px + md: 12px + lg: 16px + xl: 24px + xxl: 32px + section: 88px + +components: + button-primary: + backgroundColor: "{colors.primary}" + textColor: "{colors.on-primary}" + typography: "{typography.button-md}" + rounded: "{rounded.full}" + padding: 8px 20px + height: 36px + button-primary-active: + backgroundColor: "{colors.ink-deep}" + textColor: "{colors.on-primary}" + typography: "{typography.button-md}" + rounded: "{rounded.full}" + button-secondary: + backgroundColor: "{colors.canvas}" + textColor: "{colors.ink}" + typography: "{typography.button-md}" + rounded: "{rounded.full}" + padding: 8px 20px + height: 36px + button-pill-on-dark: + backgroundColor: "{colors.canvas}" + textColor: "{colors.ink}" + typography: "{typography.button-md}" + rounded: "{rounded.full}" + padding: 8px 20px + button-disabled: + backgroundColor: "{colors.surface-soft}" + textColor: "{colors.mute}" + rounded: "{rounded.full}" + search-pill: + backgroundColor: "{colors.surface-soft}" + textColor: "{colors.ink}" + typography: "{typography.body-sm}" + rounded: "{rounded.full}" + padding: 8px 16px + height: 36px + search-pill-focused: + backgroundColor: "{colors.canvas}" + textColor: "{colors.ink}" + rounded: "{rounded.full}" + text-input: + backgroundColor: "{colors.canvas}" + textColor: "{colors.ink}" + typography: "{typography.body-md}" + rounded: "{rounded.full}" + padding: 8px 16px + height: 40px + text-input-focused: + backgroundColor: "{colors.canvas}" + textColor: "{colors.ink}" + rounded: "{rounded.full}" + install-snippet: + backgroundColor: "{colors.surface-soft}" + textColor: "{colors.ink}" + typography: "{typography.code-md}" + rounded: "{rounded.full}" + padding: 12px 20px + height: 48px + command-tag: + backgroundColor: "{colors.surface-soft}" + textColor: "{colors.ink}" + typography: "{typography.code-sm}" + rounded: "{rounded.full}" + padding: 6px 12px + terminal-card: + backgroundColor: "{colors.canvas}" + textColor: "{colors.ink}" + typography: "{typography.code-sm}" + rounded: "{rounded.lg}" + padding: 16px + terminal-traffic-lights: + rounded: "{rounded.full}" + size: 12px + pricing-card: + backgroundColor: "{colors.canvas}" + textColor: "{colors.ink}" + typography: "{typography.body-md}" + rounded: "{rounded.lg}" + padding: 32px + pricing-card-dark: + backgroundColor: "{colors.surface-dark}" + textColor: "{colors.on-dark}" + typography: "{typography.body-md}" + rounded: "{rounded.lg}" + padding: 32px + feature-bullet: + textColor: "{colors.charcoal}" + typography: "{typography.body-sm}" + faq-row: + backgroundColor: "{colors.canvas}" + textColor: "{colors.ink}" + typography: "{typography.body-md}" + rounded: "{rounded.none}" + padding: 16px 0px + link-inline: + textColor: "{colors.ink}" + typography: "{typography.body-md}" + link-mute: + textColor: "{colors.body}" + typography: "{typography.body-sm}" + primary-nav: + backgroundColor: "{colors.canvas}" + textColor: "{colors.ink}" + typography: "{typography.body-sm-strong}" + rounded: "{rounded.none}" + height: 56px + footer-section: + backgroundColor: "{colors.canvas}" + textColor: "{colors.body}" + typography: "{typography.caption-sm}" + rounded: "{rounded.none}" + padding: 32px 24px + cta-strip-dark: + backgroundColor: "{colors.surface-dark}" + textColor: "{colors.on-dark}" + typography: "{typography.heading-lg}" + rounded: "{rounded.lg}" + padding: 24px 32px +--- + +## Overview + +Ollama's site is the most aggressively under-designed marketing surface in the AI tooling space, and that is the entire point. The home page reads like a Markdown README rendered with care: a 36px center-aligned heading sits above an inline `curl` install snippet inside a soft-gray pill, a single black "Download" CTA, and a hand-drawn llama mascot as the only ornament. Everything else — automate-your-work block, "Start local. Scale cloud." pricing pair, "Your data stays yours" guarantee strip, FAQ wall on `/pricing` — sits on the same paper-white canvas (`{colors.canvas}`) with quiet `{colors.body}` neutrals carrying the prose. The system is the documentation, and the documentation is the system. + +The design philosophy is geometric: every interactive element collapses to `{rounded.full}` (9999px) — buttons, search pills, install-snippet pills, text inputs, and the terminal-traffic-light dots. There are no decorative drop shadows, no gradients, no hero illustrations beyond the llama. Cards (the rare ones, on `/pricing`) use a soft `{rounded.lg}` (12px) and a 1px hairline. The single inverted moment in the entire system is the dark "Max" pricing tier — `{colors.surface-dark}` with white text — which acts as the only attention-grabbing surface in an otherwise studiously flat layout. + +Typography pairs SF Pro Rounded (display headings, weight 500–600) with the operating system's default sans (`ui-sans-serif`) for body and `ui-monospace` for code. The roundness of the heading face is the only "personality" the chrome carries — it gently echoes the `{rounded.full}` button geometry without being decorative about it. **Key Characteristics:** -- Pure white canvas with zero chromatic color — completely grayscale -- SF Pro Rounded headlines creating a distinctively Apple-like softness -- Binary border-radius system: 12px (containers) or 9999px (everything interactive) -- Zero shadows — depth comes exclusively from background color shifts and borders -- Pill-shaped geometry on all interactive elements (buttons, tabs, inputs, tags) -- The Ollama llama as the sole illustration — black line art, no color -- Extreme content restraint — the homepage is short, focused, and uncluttered +- Paper-white `{colors.canvas}` end-to-end with no surface alternation — the whole page is one continuous sheet +- Center-aligned hero with `{typography.display-xl}` SF Pro Rounded headline, no eyebrow, no subhead beyond a small "Power OpenClaw with Ollama" line under the llama +- Pill geometry everywhere: every button and pill input is `{rounded.full}`; cards use `{rounded.lg}`; nothing is sharp-cornered except section dividers +- Single-color CTA system: pure black `{colors.primary}` pills carry every action; "Get Pro" / "Get Max" inside pricing cards are the only variations +- Inline `curl` install snippet rendered as a pill with `{typography.code-md}` — the most signature element, sitting directly under the hero headline +- Terminal-mockup card with macOS traffic-light dots and inline `ollama launch openclaw` example — the home page's only "product preview" +- Inverted dark `{component.pricing-card-dark}` for the highest-tier "Max" plan, breaking the flat-white rhythm exactly once per page -## 2. Color Palette & Roles +## Colors -### Primary -- **Pure Black** (`#000000`): Primary headlines, primary links, and the darkest text. The only "color" that demands attention. -- **Near Black** (`#262626`): Button text on light surfaces, secondary headline weight. -- **Darkest Surface** (`#090909`): The darkest possible surface — barely distinguishable from pure black, used for footer or dark containers. +> **Source pages:** `/` (home) and `/pricing`. The chrome palette is identical across both — only content changes. -### Surface & Background -- **Pure White** (`#ffffff`): The primary page background — not off-white, not cream, pure white. Button surfaces for secondary actions. -- **Snow** (`#fafafa`): The subtlest possible surface distinction from white — used for section backgrounds and barely-elevated containers. -- **Light Gray** (`#e5e5e5`): Button backgrounds, borders, and the primary containment color. The workhorse neutral. +### Brand & Accent +- **Pure Black** (`{colors.primary}` — `#000000`): the brand. Every primary CTA, every black pill, every link in the nav, and every solid icon. There is no other "brand color." +- **Ink Deep** (`{colors.ink-deep}` — `#090909`): pressed-state black for the primary pill — a single notch below pure. -### Neutrals & Text -- **Stone** (`#737373`): Secondary body text, footer links, and de-emphasized content. The primary "muted" tone. -- **Mid Gray** (`#525252`): Emphasized secondary text, slightly darker than Stone. -- **Silver** (`#a3a3a3`): Tertiary text, placeholders, and deeply de-emphasized metadata. -- **Button Text Dark** (`#404040`): Specific to white-surface button text. +### Surface +- **Canvas** (`{colors.canvas}` — `#ffffff`): the page itself. Nearly every surface in the system. +- **Soft Surface** (`{colors.surface-soft}` — `#fafafa`): install-snippet pill background, search pill, secondary chip backgrounds, alternating row fill where one is needed. +- **Surface Dark** (`{colors.surface-dark}` — `#171717`): the dark "Max" pricing card and dark CTA strips. The single inverted surface in the system. +- **Hairline** (`{colors.hairline}` — `#e5e5e5`): 1px card border, divider line above footer, divider between FAQ rows. +- **Hairline Strong** (`{colors.hairline-strong}` — `#d4d4d4`): rare slightly stronger divider where extra separation is needed (e.g., between unrelated FAQ groups). -### Semantic & Accent -- **Ring Blue** (`#3b82f6` at 50%): The ONLY non-gray color in the entire system — Tailwind's default focus ring, used exclusively for keyboard accessibility. Never visible in normal interaction flow. -- **Border Light** (`#d4d4d4`): A slightly darker gray for white-surface button borders. +### Text +- **Ink** (`{colors.ink}` — `#000000`): all headlines, primary nav links, button text on light surfaces, prices on pricing cards. +- **Charcoal** (`{colors.charcoal}` — `#525252`): list-item text and disabled-state secondary copy. +- **Body** (`{colors.body}` — `#737373`): default body color for paragraph copy, FAQ answers, footer link text — the system's most-used text color after pure black. +- **Mute** (`{colors.mute}` — `#a3a3a3`): caption text, command-line "comment" gray inside terminal mockups, lowest-emphasis utility text. +- **On Dark** (`{colors.on-dark}` — `#ffffff`): primary text on `{colors.surface-dark}`. +- **On Dark Mute** (`{colors.on-dark-mute}` — `rgba(255,255,255,0.7)`): secondary copy inside the dark "Max" pricing card. -### Gradient System -- **None.** Ollama uses absolutely no gradients. Visual separation comes from flat color blocks and single-pixel borders. This is a deliberate, almost philosophical design choice. +### Semantic +The system has effectively no error/success/warning palette in its public marketing surfaces — there are no validation states, no destructive flows, no banners. The only "semantic" colors are the macOS terminal traffic lights inside the terminal mockup: -## 3. Typography Rules +- **Terminal Red** (`{colors.terminal-red}` — `#ff5f56`): close-window dot. +- **Terminal Yellow** (`{colors.terminal-yellow}` — `#ffbd2e`): minimize dot. +- **Terminal Green** (`{colors.terminal-green}` — `#27c93f`): zoom dot. + +These appear only inside `{component.terminal-card}` and have no other use. + +### Focus +- **Focus Ring** (`{colors.focus-ring}` — `rgba(59,130,246,0.5)`): translucent blue browser-default focus ring around interactive elements. The only blue in the system. + +## Typography ### Font Family -- **Display**: `SF Pro Rounded`, with fallbacks: `system-ui, -apple-system, system-ui` -- **Body / UI**: `ui-sans-serif`, with fallbacks: `system-ui, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol, Noto Color Emoji` -- **Monospace**: `ui-monospace`, with fallbacks: `SFMono-Regular, Menlo, Monaco, Consolas, Liberation Mono, Courier New` +- **SF Pro Rounded** (display headings) — Apple's rounded geometric sans, used at weights 500 and 600 for headlines from `{typography.display-xl}` (36px) down to `{typography.heading-lg}` (24px). Falls back to `system-ui` → `-apple-system`. +- **ui-sans-serif** (body, links, buttons, captions) — the operating system's default sans-serif. Carries every non-display text role at 12–20px. Falls back through `system-ui` and platform emoji families. +- **ui-monospace** (code, install snippet, command tags) — the OS default monospace. Used inside the terminal mockup, the inline `curl` install pill, and any inline `` formatting. Falls back to SFMono-Regular → Menlo → Monaco → Consolas. -*Note: SF Pro Rounded is Apple's system font — it renders with rounded terminals on macOS/iOS and falls back to the system sans-serif on other platforms.* +The pairing of SF Pro Rounded display + system sans body + system mono code is intentionally "stock Apple" — the design decision is to not have a typography decision. Branded display faces would compete with the system's documentation feel. ### Hierarchy -| Role | Font | Size | Weight | Line Height | Letter Spacing | Notes | -|------|------|------|--------|-------------|----------------|-------| -| Display / Hero | SF Pro Rounded | 48px (3rem) | 500 | 1.00 (tight) | normal | Maximum impact, rounded letterforms | -| Section Heading | SF Pro Rounded | 36px (2.25rem) | 500 | 1.11 (tight) | normal | Feature section titles | -| Sub-heading | SF Pro Rounded / ui-sans-serif | 30px (1.88rem) | 400–500 | 1.20 (tight) | normal | Card headings, feature names | -| Card Title | ui-sans-serif | 24px (1.5rem) | 400 | 1.33 | normal | Medium emphasis headings | -| Body Large | ui-sans-serif | 18px (1.13rem) | 400–500 | 1.56 | normal | Hero descriptions, button text | -| Body / Link | ui-sans-serif | 16px (1rem) | 400–500 | 1.50 | normal | Standard body text, navigation | -| Caption | ui-sans-serif | 14px (0.88rem) | 400 | 1.43 | normal | Metadata, descriptions | -| Small | ui-sans-serif | 12px (0.75rem) | 400 | 1.33 | normal | Smallest sans-serif text | -| Code Body | ui-monospace | 16px (1rem) | 400 | 1.50 | normal | Inline code, commands | -| Code Caption | ui-monospace | 14px (0.88rem) | 400 | 1.43 | normal | Code snippets, secondary | -| Code Small | ui-monospace | 12px (0.75rem) | 400–700 | 1.63 | normal | Tags, labels | +| Token | Size | Weight | Line Height | Letter Spacing | Use | +|---|---|---|---|---|---| +| `{typography.display-xl}` | 36px | 500 | 1.11 | 0 | Hero headline ("The easiest way to build with open models") | +| `{typography.display-lg}` | 30px | 500 | 1.2 | 0 | Major section headlines ("Pricing", "Frequently asked questions") | +| `{typography.heading-lg}` | 24px | 600 | 1.33 | 0 | Section subheading inside body ("Automate your work", "Start local. Scale cloud.") | +| `{typography.heading-md}` | 20px | 500 | 1.4 | 0 | Pricing tier name ("Free", "Pro", "Max"), card title | +| `{typography.heading-sm}` | 18px | 500 | 1.56 | 0 | FAQ question label, in-card subtitle | +| `{typography.body-md}` | 16px | 400 | 1.5 | 0 | Default body, FAQ answers, paragraph copy | +| `{typography.body-strong}` | 16px | 500 | 1.5 | 0 | Inline emphasis, primary-nav link | +| `{typography.body-sm}` | 14px | 400 | 1.43 | 0 | Feature bullet ("Access larger models on data-center-grade hardware"), footer link | +| `{typography.body-sm-strong}` | 14px | 500 | 1.43 | 0 | Button label, pricing-card eyebrow ("Solve harder tasks, faster") | +| `{typography.caption-sm}` | 12px | 400 | 1.33 | 0 | Footer copyright row, smallest meta text | +| `{typography.code-md}` | 16px | 400 | 1.5 | 0 | Install-snippet `curl` line, in-terminal command | +| `{typography.code-sm}` | 14px | 400 | 1.43 | 0 | Terminal output line, inline `` chips | +| `{typography.button-md}` | 14px | 500 | 1 | 0 | Every button label across the system | ### Principles -- **Rounded display, standard body**: SF Pro Rounded carries display headlines with its distinctive rounded terminals, while the standard system sans handles all body text. The rounded font IS the brand expression. -- **Weight restraint**: Only two weights matter — 400 (regular) for body and 500 (medium) for headings. No bold, no light, no black weight. This extreme restraint reinforces the minimal philosophy. -- **Tight display, comfortable body**: Headlines compress to 1.0 line-height, while body text relaxes to 1.43–1.56. The contrast creates clear hierarchy without needing weight contrast. -- **Monospace for developer identity**: Code blocks and terminal commands appear throughout as primary content, using the system monospace stack. +The typography is built for legibility at small sizes on a flat-white canvas. SF Pro Rounded's softened terminals on the heading face do almost all of the brand expression; everything below 20px collapses into the operating system's default sans, which renders identically to the way docs.ollama.com and the Ollama CLI's own help text would appear in a terminal. There is almost no letter-spacing variation, no display-only weights, no italic, and the heading-to-body ratio compresses tightly (36 → 30 → 24 → 20 → 16) so the page reads as a single readable column rather than a marketing pyramid. -## 4. Component Stylings +### Note on Font Substitutes +SF Pro Rounded is Apple-licensed and ships only on macOS/iOS. On other systems it falls back to `system-ui` (Segoe UI / Roboto / DejaVu Sans depending on platform) — Ollama explicitly accepts that the heading face will look slightly different on Windows/Linux. The closest open-source substitute is **Nunito** (rounded geometric sans, weights 500/600). For the body face, **Inter** is a near-perfect match for `system-ui` rendered metrics. For code, **JetBrains Mono** or **Fira Code** are the canonical open-source substitutes for `ui-monospace`. + +## Layout + +### Spacing System +- **Base unit:** 8px (with finer 2/4/6px steps available for tight inline gaps) +- **Tokens (front matter):** `{spacing.xxs}` (2px) · `{spacing.xs}` (4px) · `{spacing.sm}` (8px) · `{spacing.md}` (12px) · `{spacing.lg}` (16px) · `{spacing.xl}` (24px) · `{spacing.xxl}` (32px) · `{spacing.section}` (88px) +- **Universal section rhythm:** every page uses `{spacing.section}` (88px) as the vertical gap between major content blocks (hero → automate → start local/scale cloud → your data stays yours → get-started footer call). This is the single largest spacing token in the system and it is used liberally. +- **Card internal padding:** pricing cards sit at `{spacing.xxl}` (32px) all around; FAQ rows use `{spacing.lg}` (16px) vertical with no horizontal padding. + +### Grid & Container +- **Max width:** ~720px content column on the home page (the whole page is laid out as a single narrow reading column with optional 2-column splits inside specific sections). +- **Pricing grid:** 3-up cards at desktop with a max content width of ~960px; collapses to 1-up below 768px. +- **Automate-your-work split:** desktop 50/50 left-text/right-terminal-mockup; mobile stacks vertical with the terminal below the text. +- **FAQ:** single-column stacked rows, full-width within the 720px content column. +- **Footer:** single-row of small body-sm links, center-aligned at desktop, wrapping to two rows on narrow screens. + +### Whitespace Philosophy +Whitespace is the entire layout. Sections are separated by 88px of plain white air, never by decorative dividers, never by colored bands. Inside a section, content sits in a tight reading column with no decorative columns, callout boxes, or lifted cards. The site treats the page as a long-form Markdown document, and the air between sections is the equivalent of a blank line in Markdown source. + +## Elevation & Depth + +| Level | Treatment | Use | +|---|---|---| +| 0 — Flat | No border, no shadow | Hero, automate-your-work, your-data-stays-yours, footer — the dominant treatment across the page | +| 1 — Hairline border | 1px solid `{colors.hairline}` | Pricing cards, FAQ row dividers, terminal mockup card | +| 2 — Inverted dark | `{colors.surface-dark}` fill | Dark "Max" pricing card and dark CTA strip — the system's only "elevated" surfaces use color, not shadow | + +The system has no drop-shadow elevation at all. Nothing lifts, nothing floats, nothing layers. The only depth cue beyond hairline borders is the single dark surface used on the highest-tier pricing card to draw attention to it. + +### Decorative Depth +The site has effectively zero decorative depth in the traditional sense. The "depth" comes entirely from two recurring devices: +- **The hand-drawn llama mascot** — appearing once at the top of the hero, once at the top of each pricing card, and once next to the lock icon in the "Your data stays yours" section. It is the only illustration in the system. +- **A single line-drawn lock icon** — used in the data-privacy section. Stroke-only, no fill, drawn in `{colors.ink}`. + +## Shapes + +### Border Radius Scale + +| Token | Value | Use | +|---|---|---| +| `{rounded.none}` | 0px | Nav, footer, FAQ row dividers — flat structural lines | +| `{rounded.sm}` | 6px | Inline code chips, command tags | +| `{rounded.md}` | 8px | Rare medium-radius surfaces (e.g., dropdown panels) | +| `{rounded.lg}` | 12px | Pricing cards, terminal mockup card | +| `{rounded.full}` | 9999px | Every button, every pill input, install-snippet pill, search pill, traffic-light dots | + +The dominant shape vocabulary is just two values: pills (`{rounded.full}`) for everything interactive and 12px (`{rounded.lg}`) for the few cards in the system. There are no medium-radius "soft cards" — surfaces are either pills or rectangles with corners large enough to read as deliberately soft. + +### Photography Geometry +There is no photography. The only image-like elements are: +- **The llama mascot** — a hand-drawn line illustration, ~80–120px on the hero, ~32–48px when it appears as a pricing-card eyebrow icon. +- **The lock icon** — single stroke line drawing in the privacy section. +- **macOS traffic-light dots** — three filled circles at 12px (`{rounded.full}`) inside the terminal mockup card. + +## Components + +> **No hover states documented** per system policy. Each spec covers Default and Active/Pressed only. ### Buttons -**Gray Pill (Primary)** -- Background: Light Gray (`#e5e5e5`) -- Text: Near Black (`#262626`) -- Padding: 10px 24px -- Border: thin solid Light Gray (`1px solid #e5e5e5`) -- Radius: pill-shaped (9999px) -- The primary action button — understated, grayscale, always pill-shaped +**`button-primary`** — the universal Ollama CTA +- Background `{colors.primary}`, text `{colors.on-primary}`, type `{typography.button-md}`, padding `8px 20px`, height `36px`, rounded `{rounded.full}`. +- Used for "Download" (top nav), "Sign in" (top nav, paired with Download), "Create account", "Get Pro", "Get Max" — every primary action in the system. +- Pressed state lives in `button-primary-active` — background drops to `{colors.ink-deep}`. -**White Pill (Secondary)** -- Background: Pure White (`#ffffff`) -- Text: Button Text Dark (`#404040`) -- Padding: 10px 24px -- Border: thin solid Border Light (`1px solid #d4d4d4`) -- Radius: pill-shaped (9999px) -- Secondary action — visually lighter than Gray Pill +**`button-secondary`** — outline alternative on light canvas +- Background `{colors.canvas}`, text `{colors.ink}`, 1px solid `{colors.hairline-strong}`, type `{typography.button-md}`, padding `8px 20px`, height `36px`, rounded `{rounded.full}`. +- Used as a secondary affordance — e.g., the "Sign in" pill in the top nav when paired with the black "Download" pill, "See more apps →" arrow link in compact form. -**Black Pill (CTA)** -- Background: Pure Black (`#000000`) -- Text: Pure White (`#ffffff`) -- Radius: pill-shaped (9999px) -- Inferred from "Create account" and "Explore" buttons -- Maximum emphasis — black on white +**`button-pill-on-dark`** — white pill on dark surface +- Background `{colors.canvas}`, text `{colors.ink}`, type `{typography.button-md}`, rounded `{rounded.full}`. +- Sits inside the dark "Max" pricing card as the "Get Max" CTA — inverts the standard primary so the dark card itself becomes the visual anchor and the white pill reads as the CTA. -### Cards & Containers -- Background: Pure White or Snow (`#fafafa`) -- Border: thin solid Light Gray (`1px solid #e5e5e5`) when needed -- Radius: comfortably rounded (12px) — the ONLY non-pill radius in the system -- Shadow: **none** — zero shadows on any element -- Hover: likely subtle background shift or border darkening +**`button-disabled`** +- Background `{colors.surface-soft}`, text `{colors.mute}`, rounded `{rounded.full}` — flat soft gray. ### Inputs & Forms -- Background: Pure White -- Border: `1px solid #e5e5e5` -- Radius: pill-shaped (9999px) — search inputs and form fields are pill-shaped -- Focus: Ring Blue (`#3b82f6` at 50%) ring -- Placeholder: Silver (`#a3a3a3`) + +**`search-pill`** + **`search-pill-focused`** +- Default: background `{colors.surface-soft}`, text `{colors.ink}`, type `{typography.body-sm}`, padding `8px 16px`, height `36px`, rounded `{rounded.full}`. Anchored in the center of the primary nav with a small magnifier icon prefix and "Search models" placeholder. +- Focused: background flips to `{colors.canvas}` and the browser-default `{colors.focus-ring}` translucent blue ring appears. + +**`text-input`** + **`text-input-focused`** +- Default: background `{colors.canvas}`, 1px solid `{colors.hairline}`, type `{typography.body-md}`, padding `8px 16px`, height `40px`, rounded `{rounded.full}`. +- Focused: 1px ink border + browser-default focus ring. + +**`install-snippet`** — the signature install pill +- Background `{colors.surface-soft}`, text `{colors.ink}` rendered in `{typography.code-md}`, padding `12px 20px`, height `48px`, rounded `{rounded.full}`. +- Contains the literal `curl -fsSL https://ollama.com/install.sh | sh` install command with a small copy-icon at the right edge. Sits directly below the hero headline as the page's most prominent "CTA." + +**`command-tag`** — small inline command chip +- Background `{colors.surface-soft}`, text `{colors.ink}` in `{typography.code-sm}`, padding `6px 12px`, rounded `{rounded.full}`. +- Used inside the "Automate your work" section for the `ollama launch openclaw` example chip and similar inline-command demos. + +### Cards & Containers + +**`terminal-card`** — the home page's only "product preview" +- Container: background `{colors.canvas}`, 1px solid `{colors.hairline}`, padding `{spacing.lg}` (16px), rounded `{rounded.lg}`. +- Header: three `{component.terminal-traffic-lights}` dots (red/yellow/green at 12px) anchored to the top-left of the card. +- Body: terminal output rendered in `{typography.code-sm}` with comments in `{colors.mute}` and active commands in `{colors.ink}`. + +**`terminal-traffic-lights`** +- Three 12px filled circles at `{rounded.full}`: `{colors.terminal-red}`, `{colors.terminal-yellow}`, `{colors.terminal-green}`. Sits as a row of three with `{spacing.xs}` gaps between dots inside the terminal card header. + +**`pricing-card`** — Free / Pro tiers +- Container: background `{colors.canvas}`, 1px solid `{colors.hairline}`, padding `{spacing.xxl}` (32px), rounded `{rounded.lg}`. +- Layout: small llama mascot icon (~32px) at top, tier name in `{typography.heading-md}`, one-line tier description, large price in `{typography.display-lg}` (`$0` / `$20`), single `{component.button-primary}` CTA, divider, `{typography.body-sm-strong}` "Everything in Free, plus:" header, list of `{component.feature-bullet}` rows. + +**`pricing-card-dark`** — Max tier (inverted) +- Identical layout to `pricing-card` but with `{colors.surface-dark}` background, `{colors.on-dark}` text, `{colors.on-dark-mute}` secondary text, and `{component.button-pill-on-dark}` CTA. The inversion is the system's single "look here" cue. + +**`feature-bullet`** — pricing card list item +- Inline `✓` checkmark at `{colors.ink}` followed by `{typography.body-sm}` text in `{colors.charcoal}`. No background, no border, just stacked rows with `{spacing.sm}` between them. + +**`faq-row`** — `/pricing` FAQ entry +- Container: background `{colors.canvas}`, padding `16px 0`, 1px bottom border `{colors.hairline}`. +- Question: `{typography.heading-sm}` (18px / 500) in `{colors.ink}`. +- Answer: `{typography.body-md}` (16px / 400) in `{colors.body}`, sitting directly below the question with `{spacing.xs}` gap. Always expanded — no accordion collapse. + +**`cta-strip-dark`** — rare dark CTA band +- Background `{colors.surface-dark}`, text `{colors.on-dark}` in `{typography.heading-lg}`, padding `24px 32px`, rounded `{rounded.lg}`. Used sparingly between sections. + +### Inline + +**`link-inline`** — body-prose anchor link +- `{colors.ink}` text with underline. Default decoration is `text-decoration: underline`. + +**`link-mute`** — secondary anchor in long-form prose +- `{colors.body}` text with underline appearing on default — used in FAQ answers ("see [hello@ollama.com](mailto:)") and footer. ### Navigation -- Clean horizontal nav with minimal elements -- Logo: Ollama llama icon + wordmark in black -- Links: "Models", "Docs", "Pricing" in black at 16px, weight 400 -- Search bar: pill-shaped with placeholder text -- Right side: "Sign in" link + "Download" black pill CTA -- No borders, no background — transparent nav on white page -### Image Treatment -- The Ollama llama mascot is the only illustration — black line art on white -- Code screenshots/terminal outputs shown in bordered containers (12px radius) -- Integration logos displayed as simple icons in a grid -- No photographs, no gradients, no decorative imagery +**`primary-nav`** +- Background `{colors.canvas}`, text `{colors.ink}`, height 56px, type `{typography.body-sm-strong}`, rounded `{rounded.none}`. +- Layout (desktop): llama icon (left) followed by "Models · Docs · Pricing" text links, centered `{component.search-pill}`, and a right cluster of "Sign in" + black `{component.button-primary}` "Download". -### Distinctive Components +**Top Nav (Mobile)** +- Llama icon at left, hamburger drawer trigger at right. Search pill expands to full-width when triggered. The drawer lists "Models · Docs · Pricing · Sign in · Download" stacked vertically with `{spacing.lg}` row gaps. -**Tab Pills** -- Pill-shaped tab selectors (e.g., "Coding" | "OpenClaw") -- Active: Light Gray bg; Inactive: transparent -- All pill-shaped (9999px) +### Footer -**Model Tags** -- Small pill-shaped tags (e.g., "ollama", "launch", "claude") -- Light Gray background, dark text -- The primary way to browse models +**`footer-section`** +- Background `{colors.canvas}`, 1px top border `{colors.hairline}`, padding `32px 24px`, type `{typography.caption-sm}` `{colors.body}`. +- Single horizontal row of small links: "Download · Blog · Docs · GitHub · Discord · X · Contact · Privacy · Terms" + a "© 2026 Ollama" copyright at the right edge. Wraps to two rows on narrow screens. -**Terminal Command Block** -- Monospace code showing `ollama run` commands -- Minimal styling — just a bordered 12px-radius container -- Copy button integrated - -**Integration Grid** -- Grid of integration logos (Codex, Claude Code, OpenCode, LangChain, etc.) -- Each in a bordered pill or card with icon + name -- Tabbed by category (Coding, Documents & RAG, Automation, Chat) - -## 5. Layout Principles - -### Spacing System -- Base unit: 8px -- Scale: 4px, 6px, 8px, 9px, 10px, 12px, 14px, 16px, 20px, 24px, 32px, 40px, 48px, 88px, 112px -- Button padding: 10px 24px (consistent across all buttons) -- Card internal padding: approximately 24–32px -- Section vertical spacing: very generous (88px–112px) - -### Grid & Container -- Max container width: approximately 1024–1280px, centered -- Hero: centered single-column with llama illustration -- Feature sections: 2-column layout (text left, code right) -- Integration grid: responsive multi-column -- Footer: clean single-row - -### Whitespace Philosophy -- **Emptiness as luxury**: The page is remarkably short and sparse — no feature section overstays its welcome. Each concept gets minimal but sufficient space. -- **Content density is low by design**: Where other AI companies pack feature after feature, Ollama presents three ideas (run models, use with apps, integrations) and stops. -- **The white space IS the brand**: Pure white space with zero decoration communicates "this tool gets out of your way." - -### Border Radius Scale -- Comfortably rounded (12px): The sole container radius — code blocks, cards, panels -- Pill-shaped (9999px): Everything interactive — buttons, tabs, inputs, tags, badges - -*This binary system is extreme and distinctive. There is no 4px, no 8px, no gradient of roundness. Elements are either containers (12px) or interactive (pill).* - -## 6. Depth & Elevation - -| Level | Treatment | Use | -|-------|-----------|-----| -| Flat (Level 0) | No shadow, no border | Page background, most content | -| Bordered (Level 1) | `1px solid #e5e5e5` | Cards, code blocks, buttons | - -**Shadow Philosophy**: Ollama uses **zero shadows**. This is not an oversight — it's a deliberate design decision. Every other major AI product site uses at least subtle shadows. Ollama's flat, shadowless approach creates a paper-like experience where elements are distinguished purely by background color and single-pixel borders. Depth is communicated through **content hierarchy and typography weight**, not visual layering. - -## 7. Do's and Don'ts +## Do's and Don'ts ### Do -- Use pure white (`#ffffff`) as the page background — never off-white or cream -- Use pill-shaped (9999px) radius on all interactive elements — buttons, tabs, inputs, tags -- Use 12px radius on all non-interactive containers — code blocks, cards, panels -- Keep the palette strictly grayscale — no chromatic colors except the blue focus ring -- Use SF Pro Rounded at weight 500 for display headings — the rounded terminals are the brand expression -- Maintain zero shadows — depth comes from borders and background shifts only -- Keep content density low — each section should present one clear idea -- Use monospace for terminal commands and code — it's primary content, not decoration -- Keep all buttons at 10px 24px padding with pill shape — consistency is absolute +- Treat the page like a Markdown document: single reading column, plenty of `{spacing.section}` air between sections, no decorative dividers. +- Use `{component.button-primary}` (black pill) for every primary action. There is no green, no blue, no brand-tinted CTA. +- Default to `{rounded.full}` for any interactive element. Cards get `{rounded.lg}` (12px) and that is the only exception. +- Use `{typography.display-xl}` SF Pro Rounded for the hero headline and `{typography.body-md}` system sans for everything else. Avoid intermediate display sizes. +- Reserve `{component.pricing-card-dark}` (the inverted dark surface) for exactly one "look here" moment per page — never use it twice. +- Render install commands and CLI examples inside `{component.install-snippet}` or `{component.terminal-card}` with `{typography.code-md}` / `{typography.code-sm}`. Code is a first-class component. +- Keep the llama mascot the only illustration in the system. It is the brand. ### Don't -- Don't introduce any chromatic color — no brand blue, no accent green, no warm tones -- Don't use border-radius between 12px and 9999px — the system is binary -- Don't add shadows to any element — the flat aesthetic is intentional -- Don't use font weights above 500 — no bold, no black weight -- Don't add decorative illustrations beyond the llama mascot -- Don't use gradients anywhere — flat blocks and borders only -- Don't overcomplicate the layout — two columns maximum, no complex grids -- Don't use borders heavier than 1px — containment is always the lightest possible touch -- Don't add hover animations or transitions — interactions should feel instant and direct +- Don't introduce gradients, drop shadows, or atmospheric backgrounds. The canvas is pure `{colors.canvas}`. +- Don't add brand colors. The system is `{colors.primary}` (black) on `{colors.canvas}` (white) with `{colors.body}` (gray) text. That is it. +- Don't soften pills or sharpen cards — pills stay `{rounded.full}`, cards stay `{rounded.lg}`. Don't introduce `{rounded.md}` for buttons or `{rounded.full}` for cards. +- Don't lift cards with shadows. Use a 1px `{colors.hairline}` border or invert to `{colors.surface-dark}` — those are the only two card treatments. +- Don't replace `ui-sans-serif` with a branded display body face. The system relies on `system-ui` rendering to feel native. +- Don't fill long-form pages with marketing chrome. FAQ answers stay in `{colors.body}` body-md prose with no decorative containers. -## 8. Responsive Behavior +## Responsive Behavior ### Breakpoints + | Name | Width | Key Changes | -|------|-------|-------------| -| Mobile | <640px | Single column, stacked everything, hamburger nav | -| Small Tablet | 640–768px | Minor adjustments to spacing | -| Tablet | 768–850px | 2-column layouts begin | -| Desktop | 850–1024px | Standard layout, expanded features | -| Large Desktop | 1024–1280px | Maximum content width | +|---|---|---| +| desktop-large | 1280px+ | Default desktop — 720px content column, 3-up pricing grid | +| desktop | 1024px | Same layout; nav remains horizontal | +| tablet | 850px | Pricing collapses from 3-up to 2-up + 1; nav search pill compresses | +| tablet-narrow | 768px | Pricing collapses to 1-up stacked; primary nav becomes hamburger | +| mobile | 640px | Hero headline drops from `{typography.display-xl}` (36px) to ~28px; install-snippet wraps; section padding tightens | ### Touch Targets -- All buttons are pill-shaped with generous padding (10px 24px) -- Navigation links at comfortable 16px size -- Minimum touch area easily exceeds 44x44px +All interactive elements meet WCAG AA at the 36–40px height range. `{component.button-primary}` and `{component.button-secondary}` sit at 36px height with 20px horizontal padding, giving an effective tappable area of ~36×80px which exceeds the 44×44px AAA threshold via the inline padding. `{component.text-input}` sits at 40px. `{component.search-pill}` sits at 36px height with 16px padding. Footer links use `{typography.caption-sm}` (12px) but receive ~12px line-height + ~8px vertical padding for a tappable row of ~32–36px. ### Collapsing Strategy -- **Navigation**: Collapses to hamburger menu on mobile -- **Feature sections**: 2-column → stacked single column -- **Hero text**: 48px → 36px → 30px progressive scaling -- **Integration grid**: Multi-column → 2-column → single column -- **Code blocks**: Horizontal scroll maintained +- **Primary nav:** desktop horizontal → tablet-narrow hamburger drawer at 768px. The black "Download" CTA stays visible at all widths; it never collapses into the menu. +- **Search pill:** desktop fixed width ~360px → tablet compressed to ~240px → mobile collapses to icon-only with a full-width overlay on tap. +- **Pricing grid:** 3-up → 2+1 → 1-up stacked at 850, 768, and below. The dark "Max" card stays in its inverted treatment at every breakpoint. +- **Automate-your-work split:** desktop 50/50 → tablet stacks vertical with text above terminal mockup. +- **Hero headline:** `{typography.display-xl}` (36px) at desktop, scaling to ~28px at mobile with line-height holding at ~1.15. +- **Section spacing:** `{spacing.section}` (88px) desktop → 64px tablet → 48px mobile. +- **Install-snippet pill:** wraps `curl` text to a second line on narrow screens rather than truncating; the copy-icon stays anchored to the right edge. ### Image Behavior -- Llama mascot scales proportionally -- Code blocks maintain monospace formatting -- Integration icons reflow to fewer columns -- No art direction changes +The only image asset is the llama mascot (raster PNG at multiple resolutions: 16/32/48/64/180/192/512px). It is rendered at fixed pixel sizes on the hero and pricing cards rather than scaling responsively — the brand asset is treated like a logo, not a hero image. -## 9. Agent Prompt Guide +## Iteration Guide -### Quick Color Reference -- Primary Text: "Pure Black (#000000)" -- Page Background: "Pure White (#ffffff)" -- Secondary Text: "Stone (#737373)" -- Button Background: "Light Gray (#e5e5e5)" -- Borders: "Light Gray (#e5e5e5)" -- Muted Text: "Silver (#a3a3a3)" -- Dark Text: "Near Black (#262626)" -- Subtle Surface: "Snow (#fafafa)" +1. Focus on ONE component at a time. Pull its YAML entry from the front matter and verify every property resolves. +2. Reference component names and tokens directly (`{colors.primary}`, `{component.button-primary-active}`, `{rounded.full}`) — 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 (`-active`, `-disabled`, `-focused`) — do not bury them inside prose. +5. Default body to `{typography.body-md}`; reach for `{typography.body-sm}` for footer/utility text; reserve `{typography.display-xl}` strictly for the page-top headline. +6. Keep `{colors.primary}` scarce per viewport — there should be at most one black pill per fold (counting nav, hero CTA, and pricing-card CTA together). The design's restraint is the design. +7. When introducing a new component, ask whether it can be expressed with the existing pill + flat-card + terminal-mockup vocabulary before adding new tokens. The system's strength is that it almost never needs new ones. -### Example Component Prompts -- "Create a hero section on pure white (#ffffff) with an illustration centered above a headline at 48px SF Pro Rounded weight 500, line-height 1.0. Use Pure Black (#000000) text. Below, add a black pill-shaped CTA button (9999px radius, 10px 24px padding) and a gray pill button." -- "Design a code block with a 12px border-radius, 1px solid Light Gray (#e5e5e5) border on white background. Use ui-monospace at 16px for the terminal command. No shadow." -- "Build a tab bar with pill-shaped tabs (9999px radius). Active tab: Light Gray (#e5e5e5) background, Near Black (#262626) text. Inactive: transparent background, Stone (#737373) text." -- "Create an integration card grid. Each card is a bordered pill (9999px radius) or a 12px-radius card with 1px solid #e5e5e5 border. Icon + name inside. Grid of 4 columns on desktop." -- "Design a navigation bar: transparent background, no border. Ollama logo on the left, 3 text links (Pure Black, 16px, weight 400), pill search input in the center, 'Sign in' text link and black pill 'Download' button on the right." +## Known Gaps -### Iteration Guide -1. Focus on ONE component at a time -2. Keep all values grayscale — "Stone (#737373)" not "use a light color" -3. Always specify pill (9999px) or container (12px) radius — nothing in between -4. Shadows are always zero — never add them -5. Weight is always 400 or 500 — never bold -6. If something feels too decorated, remove it — less is always more for Ollama +- **Mobile screenshots not captured** — responsive behavior synthesizes Ollama's known mobile pattern (hamburger drawer, 1-up pricing stack, install-snippet wrap) from desktop evidence and the extracted breakpoint stack. +- **Hover states not documented** by system policy. +- **Form field styling** beyond search and install-snippet is not present in the captured surfaces — there is no visible long-form form on the home or pricing pages. +- **Authenticated chrome** (account dropdown, billing settings, model dashboard) not in the captured pages. +- **Models / Docs pages** not in the captured set — those surfaces likely add a sidebar and a docs typography tier that this document does not describe. diff --git a/design-md/opencode.ai/DESIGN.md b/design-md/opencode.ai/DESIGN.md index d8c9709..05f46a9 100644 --- a/design-md/opencode.ai/DESIGN.md +++ b/design-md/opencode.ai/DESIGN.md @@ -1,281 +1,521 @@ -# Design System Inspired by OpenCode +--- +version: alpha +name: OpenCode +description: | + A terminal-native marketing system rendered entirely in Berkeley Mono — every word on the page, from the hero headline down to the footer fine print, is monospaced. The page itself reads like a manpage or a static-site README: warm cream canvas (`#fdfcfc`), nearly-black ink (`#201d1d`), 4px-radius rectangles for the few interactive elements, and bracketed `[+]`/`[-]` ASCII markers used as bullets. The brand's only "visual moment" is a single dark hero card that mocks up the OpenCode TUI itself — black background, monospaced terminal output, ASCII pipe characters, and a wordmark rendered as block-pixel ASCII. Every section sits as a hairline-bordered text block on the cream canvas with no shadows, no gradients, no decorative imagery, and no non-monospaced character anywhere in the system. -## 1. Visual Theme & Atmosphere +colors: + primary: "#201d1d" + on-primary: "#fdfcfc" + ink: "#201d1d" + ink-deep: "#0f0000" + charcoal: "#302c2c" + body: "#424245" + mute: "#646262" + stone: "#6e6e73" + ash: "#9a9898" + canvas: "#fdfcfc" + surface-soft: "#f8f7f7" + surface-card: "#f1eeee" + surface-dark: "#201d1d" + surface-dark-elevated: "#302c2c" + hairline: "rgba(15,0,0,0.12)" + hairline-strong: "#646262" + on-dark: "#fdfcfc" + on-dark-mute: "#9a9898" + accent: "#007aff" + accent-hover: "#0056b3" + accent-active: "#004085" + warning: "#ff9f0a" + warning-hover: "#cc7f08" + warning-active: "#995f06" + danger: "#ff3b30" + danger-hover: "#d70015" + danger-active: "#a50011" + success: "#30d158" -OpenCode's website embodies a terminal-native, monospace-first aesthetic that reflects its identity as an open source AI coding agent. The entire visual system is built on a stark dark-on-light contrast using a near-black background (`#201d1d`) with warm off-white text (`#fdfcfc`). This isn't a generic dark theme -- it's a warm, slightly reddish-brown dark that feels like a sophisticated terminal emulator rather than a cold IDE. The warm undertone in both the darks and lights (notice the subtle red channel in `#201d1d` -- rgb(32, 29, 29)) creates a cohesive, lived-in quality. +typography: + display-xl: + fontFamily: Berkeley Mono + fontSize: 38px + fontWeight: 700 + lineHeight: 1.5 + letterSpacing: 0 + heading-md: + fontFamily: Berkeley Mono + fontSize: 16px + fontWeight: 700 + lineHeight: 1.5 + letterSpacing: 0 + body-md: + fontFamily: Berkeley Mono + fontSize: 16px + fontWeight: 400 + lineHeight: 1.5 + letterSpacing: 0 + body-strong: + fontFamily: Berkeley Mono + fontSize: 16px + fontWeight: 500 + lineHeight: 1.5 + letterSpacing: 0 + body-tight: + fontFamily: Berkeley Mono + fontSize: 16px + fontWeight: 500 + lineHeight: 1 + letterSpacing: 0 + link-md: + fontFamily: Berkeley Mono + fontSize: 16px + fontWeight: 400 + lineHeight: 1.5 + letterSpacing: 0 + button-md: + fontFamily: Berkeley Mono + fontSize: 16px + fontWeight: 500 + lineHeight: 2 + letterSpacing: 0 + caption-md: + fontFamily: Berkeley Mono + fontSize: 14px + fontWeight: 400 + lineHeight: 2 + letterSpacing: 0 -Berkeley Mono is the sole typeface, establishing an unapologetic monospace identity. Every element -- headings, body text, buttons, navigation -- shares this single font family, creating a unified "everything is code" philosophy. The heading at 38px bold with 1.50 line-height is generous and readable, while body text at 16px with weight 500 provides a slightly heavier-than-normal reading weight that enhances legibility on screen. The monospace grid naturally enforces alignment and rhythm across the layout. +rounded: + none: 0px + sm: 4px + full: 9999px -The color system is deliberately minimal. The primary palette consists of just three functional tones: the warm near-black (`#201d1d`), a medium warm gray (`#9a9898`), and a bright off-white (`#fdfcfc`). Semantic colors borrow from the Apple HIG palette -- blue accent (`#007aff`), red danger (`#ff3b30`), green success (`#30d158`), orange warning (`#ff9f0a`) -- giving the interface familiar, trustworthy signal colors without adding brand complexity. Borders use a subtle warm transparency (`rgba(15, 0, 0, 0.12)`) that ties into the warm undertone of the entire system. +spacing: + xxs: 1px + 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.sm}" + padding: 4px 20px + height: 36px + button-primary-active: + backgroundColor: "{colors.ink-deep}" + textColor: "{colors.on-primary}" + typography: "{typography.button-md}" + rounded: "{rounded.sm}" + button-secondary: + backgroundColor: "{colors.canvas}" + textColor: "{colors.ink}" + typography: "{typography.button-md}" + rounded: "{rounded.sm}" + padding: 4px 20px + button-tab: + backgroundColor: "transparent" + textColor: "{colors.mute}" + typography: "{typography.button-md}" + rounded: "{rounded.none}" + padding: 8px 16px + button-tab-active: + backgroundColor: "transparent" + textColor: "{colors.ink}" + typography: "{typography.button-md}" + rounded: "{rounded.none}" + button-disabled: + backgroundColor: "{colors.surface-card}" + textColor: "{colors.ash}" + rounded: "{rounded.sm}" + badge-news: + backgroundColor: "{colors.surface-dark}" + textColor: "{colors.on-dark}" + typography: "{typography.caption-md}" + rounded: "{rounded.sm}" + padding: 2px 8px + text-input: + backgroundColor: "{colors.surface-soft}" + textColor: "{colors.ink}" + typography: "{typography.body-md}" + rounded: "{rounded.sm}" + padding: 8px 12px + height: 40px + text-input-focused: + backgroundColor: "{colors.canvas}" + textColor: "{colors.ink}" + rounded: "{rounded.sm}" + textarea: + backgroundColor: "{colors.surface-soft}" + textColor: "{colors.ink}" + typography: "{typography.body-md}" + rounded: "{rounded.sm}" + padding: 12px + install-snippet: + backgroundColor: "{colors.surface-card}" + textColor: "{colors.ink}" + typography: "{typography.body-md}" + rounded: "{rounded.sm}" + padding: 12px 16px + hero-tui-mockup: + backgroundColor: "{colors.surface-dark}" + textColor: "{colors.on-dark}" + typography: "{typography.body-md}" + rounded: "{rounded.none}" + padding: 64px 32px + tui-prompt-row: + backgroundColor: "{colors.surface-dark-elevated}" + textColor: "{colors.on-dark}" + typography: "{typography.body-md}" + rounded: "{rounded.sm}" + padding: 8px 12px + list-row: + backgroundColor: "{colors.canvas}" + textColor: "{colors.body}" + typography: "{typography.body-md}" + rounded: "{rounded.none}" + padding: 8px 0px + faq-row: + backgroundColor: "{colors.canvas}" + textColor: "{colors.ink}" + typography: "{typography.body-md}" + rounded: "{rounded.none}" + padding: 12px 0px + testimonial-row: + backgroundColor: "{colors.surface-soft}" + textColor: "{colors.body}" + typography: "{typography.body-md}" + rounded: "{rounded.sm}" + padding: 16px 20px + chart-tile: + backgroundColor: "{colors.canvas}" + textColor: "{colors.body}" + typography: "{typography.caption-md}" + rounded: "{rounded.none}" + padding: 16px + primary-nav: + backgroundColor: "{colors.canvas}" + textColor: "{colors.ink}" + typography: "{typography.body-strong}" + rounded: "{rounded.none}" + height: 56px + footer-section: + backgroundColor: "{colors.canvas}" + textColor: "{colors.body}" + typography: "{typography.caption-md}" + rounded: "{rounded.none}" + padding: 32px 0px + link-inline: + textColor: "{colors.ink}" + typography: "{typography.link-md}" + badge-section-label: + backgroundColor: "transparent" + textColor: "{colors.ink}" + typography: "{typography.heading-md}" + rounded: "{rounded.none}" +--- + +## Overview + +OpenCode's marketing site is rendered entirely in Berkeley Mono — every word on the page, from the 38px hero headline down to the 14px footer fine print, sits in the same monospaced face. The visual identity comes from that single typographic decision: the page reads like a manpage or a static-site README, complete with bracketed `[+]` / `[-]` / `[x]` ASCII markers used in place of icons or bullets, and a wordmark rendered as block-pixel ASCII art at the top of the nav. There is no sans-serif anywhere, no display face, no italics, no decorative ornament — the system is one font and one weight away from being a 1990s `whatis` page rendered at modern resolutions. + +The chrome is austere: warm cream canvas (`{colors.canvas}` — `#fdfcfc` with a faint blush), nearly-black ink (`{colors.ink}` — `#201d1d`), and a 4-tier neutral gray ladder for body, metadata, and disabled text. Cards don't exist as raised surfaces — sections are just hairline-bordered text blocks (`{colors.hairline}` 1px) sitting directly on the canvas with `{spacing.section}` (96px) air between them. The single "visual" moment in the entire system is a full-bleed dark hero card (`{colors.surface-dark}` — true near-black) that mocks up the OpenCode TUI itself: a terminal frame with `tab` / `ctrl-p` keybinding hints, a "Build" command line, and the OpenCode wordmark rendered as a pixel-block ASCII title. + +The semantic palette is unusual for a brand-marketing site: it ships the full Apple Human Interface Guidelines accent ramp — `{colors.accent}` (Apple Blue `#007aff`), `{colors.danger}` (`#ff3b30`), `{colors.warning}` (`#ff9f0a`), `{colors.success}` (`#30d158`) plus their hover/active deepenings — even though the marketing surfaces themselves only use these colors in the dark hero TUI mockup as syntax-highlight stand-ins. The wider palette belongs to the in-product TUI; the marketing pages mostly stay in monochrome. **Key Characteristics:** -- Berkeley Mono as the sole typeface -- monospace everywhere, no sans-serif or serif voices -- Warm near-black primary (`#201d1d`) with reddish-brown undertone, not pure black -- Off-white text (`#fdfcfc`) with warm tint, not pure white -- Minimal 4px border radius throughout -- sharp, utilitarian corners -- 8px base spacing system scaling up to 96px -- Apple HIG-inspired semantic colors (blue, red, green, orange) -- Transparent warm borders using `rgba(15, 0, 0, 0.12)` -- Email input with generous 20px padding and 6px radius -- the most generous component radius -- Single button variant: dark background, light text, tight vertical padding (4px 20px) -- Underlined links as default link style, reinforcing the text-centric identity +- 100% Berkeley Mono typography across every text role — no sans-serif fallback anywhere in the chrome +- Warm cream `{colors.canvas}` (#fdfcfc) as the only body background — no surface alternation across sections +- Single dark surface (`{colors.surface-dark}` — #201d1d) reserved exclusively for the hero TUI mockup +- 4px radius (`{rounded.sm}`) on every interactive element; sections themselves are sharp rectangles bordered in 1px hairline +- ASCII bracket markers (`[+]`, `[-]`, `[x]`) used as bullet glyphs in feature lists and FAQ rows +- Block-pixel ASCII wordmark in the primary nav and inside the hero TUI — the brand identity is its own ASCII art +- 96px `{spacing.section}` rhythm between every section, with no decorative dividers; only thin 1px `{colors.hairline}` rules separate content blocks -## 2. Color Palette & Roles +## Colors -### Primary -- **OpenCode Dark** (`#201d1d`): Primary background, button fills, link text. A warm near-black with subtle reddish-brown warmth -- rgb(32, 29, 29). -- **OpenCode Light** (`#fdfcfc`): Primary text on dark surfaces, button text. A barely-warm off-white that avoids clinical pure white. -- **Mid Gray** (`#9a9898`): Secondary text, muted links. A neutral warm gray that bridges dark and light. +> **Source pages:** `/` (home), `/zen`, `/enterprise`. The chrome palette is identical across all three. -### Secondary -- **Dark Surface** (`#302c2c`): Slightly lighter than primary dark, used for elevated surfaces and subtle differentiation. -- **Border Gray** (`#646262`): Stronger borders, outline rings on interactive elements. -- **Light Surface** (`#f1eeee`): Light mode surface, subtle background variation. +### Brand & Accent +- **Ink** (`{colors.primary}` / `{colors.ink}` — `#201d1d`): the brand's only "color." Headlines, body text, primary CTA fill, nav links, and every solid icon. Treats nearly-black as the brand color rather than pure black to keep type readable on the warm cream canvas. +- **Ink Deep** (`{colors.ink-deep}` — `#0f0000`): pressed-state for the primary CTA. Carries a faint red undertone matching the canvas's warm cast. +- **Cream** (`{colors.canvas}` — `#fdfcfc`): the brand's signature warm white. Used for every page body, every card surface, the on-primary text color, and the ASCII wordmark fill on dark. -### Accent -- **Accent Blue** (`#007aff`): Primary accent, links, interactive highlights. Apple system blue. -- **Accent Blue Hover** (`#0056b3`): Darker blue for hover states. -- **Accent Blue Active** (`#004085`): Deepest blue for pressed/active states. +### Surface +- **Canvas Cream** (`{colors.canvas}` — `#fdfcfc`): every page body, every card. +- **Soft Surface** (`{colors.surface-soft}` — `#f8f7f7`): text-input default background, testimonial row fill, alternating row tint. +- **Surface Card** (`{colors.surface-card}` — `#f1eeee`): install-snippet pill, disabled button fill, slightly-elevated section row. +- **Surface Dark** (`{colors.surface-dark}` — `#201d1d`): the hero TUI mockup background and the dark CTA pill on the home page. Identical to `{colors.ink}` — the brand uses one near-black for both text and dark surfaces. +- **Surface Dark Elevated** (`{colors.surface-dark-elevated}` — `#302c2c`): the prompt-row inside the hero TUI mockup, one notch lighter than the dark surface itself. +- **Hairline** (`{colors.hairline}` — `rgba(15,0,0,0.12)`): 1px section divider. The translucent warm tint matches the cream canvas's undertone. +- **Hairline Strong** (`{colors.hairline-strong}` — `#646262`): tab strip's bottom rule and stronger inline divider. + +### Text +- **Ink** (`{colors.ink}` — `#201d1d`): headlines, body text, primary nav links, button text on light surfaces. +- **Charcoal** (`{colors.charcoal}` — `#302c2c`): subtly softer body where pure ink is too heavy. +- **Body** (`{colors.body}` — `#424245`): default paragraph text and FAQ answers. +- **Mute** (`{colors.mute}` — `#646262`): tab labels (default state), metadata, footer link text, in-list secondary annotations. +- **Stone** (`{colors.stone}` — `#6e6e73`): least-emphasis utility text, breadcrumb separators. +- **Ash** (`{colors.ash}` — `#9a9898`): disabled text and secondary annotation in dark TUI mockup, also TUI mockup secondary color. ### Semantic -- **Danger Red** (`#ff3b30`): Error states, destructive actions. Apple system red. -- **Danger Hover** (`#d70015`): Darker red for hover on danger elements. -- **Danger Active** (`#a50011`): Deepest red for pressed danger states. -- **Success Green** (`#30d158`): Success states, positive feedback. Apple system green. -- **Warning Orange** (`#ff9f0a`): Warning states, caution signals. Apple system orange. -- **Warning Hover** (`#cc7f08`): Darker orange for hover on warning elements. -- **Warning Active** (`#995f06`): Deepest orange for pressed warning states. +The full Apple Human Interface Guidelines semantic ramp ships with the system. On marketing pages these colors appear primarily inside the hero TUI mockup as syntax-highlight stand-ins; in the in-product TUI they carry their conventional meaning. -### Text Scale -- **Text Muted** (`#6e6e73`): Muted labels, disabled text, placeholder content. -- **Text Secondary** (`#424245`): Secondary text on light backgrounds, captions. +- **Accent** (`{colors.accent}` — `#007aff`): primary informational signal, in-product link color, TUI command highlight. +- **Accent Hover** (`{colors.accent-hover}` — `#0056b3`): pressed informational link. +- **Accent Active** (`{colors.accent-active}` — `#004085`): deeply-pressed informational state. +- **Danger** (`{colors.danger}` — `#ff3b30`): destructive confirmation, error state. +- **Danger Hover** (`{colors.danger-hover}` — `#d70015`): pressed destructive. +- **Danger Active** (`{colors.danger-active}` — `#a50011`): deeply-pressed destructive. +- **Warning** (`{colors.warning}` — `#ff9f0a`): caution callouts. +- **Warning Hover** (`{colors.warning-hover}` — `#cc7f08`): pressed caution. +- **Warning Active** (`{colors.warning-active}` — `#995f06`): deeply-pressed caution. +- **Success** (`{colors.success}` — `#30d158`): positive confirmation, in-TUI success indicator. -### Border -- **Border Warm** (`rgba(15, 0, 0, 0.12)`): Primary border color, warm transparent black with red tint. -- **Border Tab** (`#9a9898`): Tab underline border, 2px solid bottom. -- **Border Outline** (`#646262`): 1px solid outline border for containers. - -## 3. Typography Rules +## Typography ### Font Family -- **Universal**: `Berkeley Mono`, with fallbacks: `IBM Plex Mono, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, Liberation Mono, Courier New, monospace` +**Berkeley Mono** is the proprietary monospaced face used across every text role in the system. It carries weights 400 (regular), 500 (medium), and 700 (bold) and falls back through a long monospace stack — IBM Plex Mono → ui-monospace → SFMono-Regular → Menlo → Monaco → Consolas → Liberation Mono → Courier New. + +The single-font decision is the brand. There is no display face, no body sans, no italic alternative, and no fallback to a proportional font anywhere — even the legal copyright row uses Berkeley Mono at 14px. This is the most aggressive typographic restraint of any site in the marketing-tools category: OpenCode's identity is "the marketing page is a man page." ### Hierarchy -| Role | Size | Weight | Line Height | Notes | -|------|------|--------|-------------|-------| -| Heading 1 | 38px (2.38rem) | 700 | 1.50 | Hero headlines, page titles | -| Heading 2 | 16px (1.00rem) | 700 | 1.50 | Section titles, bold emphasis | -| Body | 16px (1.00rem) | 400 | 1.50 | Standard body text, paragraphs | -| Body Medium | 16px (1.00rem) | 500 | 1.50 | Links, button text, nav items | -| Body Tight | 16px (1.00rem) | 500 | 1.00 (tight) | Compact labels, tab items | -| Caption | 14px (0.88rem) | 400 | 2.00 (relaxed) | Footnotes, metadata, small labels | +| Token | Size | Weight | Line Height | Letter Spacing | Use | +|---|---|---|---|---|---| +| `{typography.display-xl}` | 38px | 700 | 1.5 | 0 | Hero headline ("The open source AI coding agent") | +| `{typography.heading-md}` | 16px | 700 | 1.5 | 0 | Section label ("What is OpenCode?", "FAQ", "Built for privacy first") | +| `{typography.body-md}` | 16px | 400 | 1.5 | 0 | Body copy, paragraph text, list-row text, install-snippet code | +| `{typography.body-strong}` | 16px | 500 | 1.5 | 0 | Inline emphasis, primary nav link, tab-label active | +| `{typography.body-tight}` | 16px | 500 | 1 | 0 | Compact label rendered without breathing room | +| `{typography.link-md}` | 16px | 400 | 1.5 | 0 | Inline anchor link in body prose | +| `{typography.button-md}` | 16px | 500 | 2 | 0 | Every button label across the system | +| `{typography.caption-md}` | 14px | 400 | 2 | 0 | Footer link text, badge label, copyright row, chart caption | ### Principles -- **One font, one voice**: Berkeley Mono is used exclusively. There is no typographic variation between display, body, and code -- everything speaks in the same monospace register. Hierarchy is achieved through size and weight alone. -- **Weight as hierarchy**: 700 for headings, 500 for interactive/medium emphasis, 400 for body text. Three weight levels create the entire hierarchy. -- **Generous line-height**: 1.50 as the standard line-height gives text room to breathe within the monospace grid. The relaxed 2.00 line-height on captions creates clear visual separation. -- **Tight for interaction**: Interactive elements (tabs, compact labels) use 1.00 line-height for dense, clickable targets. +The hierarchy is built almost entirely from size and weight contrast on a single face. The display headline (38px / 700) and the heading-md label (16px / 700) share a weight; the difference is just size. Body and link share size, weight, and line-height — only context distinguishes them. Buttons get a deliberately tall line-height (2.0) so labels feel calmly spaced inside the 4px-radius rectangle. -## 4. Component Stylings +### Note on Font Substitutes +Berkeley Mono is a paid commercial font. Open-source substitutes that approximate its metrics within ~3% at body sizes: +- **JetBrains Mono** — closest match for stroke contrast and x-height; pair at weights 400 / 500 / 700. +- **IBM Plex Mono** — official secondary fallback in the documented font stack; slightly more open counters but matches line-height behavior. +- **Geist Mono** — modern alternative with similar geometric construction. + +When substituting, line-height behavior is preserved by keeping `lineHeight: 1.5` for body and `lineHeight: 2` for buttons — adjusting weight is rarely needed. + +## Layout + +### Spacing System +- **Base unit:** 8px (with finer 1/2/4px steps available for tight inline gaps). +- **Tokens (front matter):** `{spacing.xxs}` (1px) · `{spacing.xs}` (4px) · `{spacing.sm}` (8px) · `{spacing.md}` (12px) · `{spacing.lg}` (16px) · `{spacing.xl}` (24px) · `{spacing.xxl}` (32px) · `{spacing.section}` (96px). +- **Universal section rhythm:** every page in the set uses `{spacing.section}` (96px) as the vertical gap between major content blocks. This is the largest spacing token in the system and is the dominant layout cue across the home, `/zen`, and `/enterprise` pages. +- **Section internal padding:** content rows inside a section sit at `{spacing.lg}` (16px) vertical with no horizontal padding — text starts flush at the section's left edge. + +### Grid & Container +- **Max width:** ~960px content column for body sections; the dark hero TUI mockup is full-bleed within an outer ~1100px content frame. +- **Two-column split:** `/enterprise` pairs a left text block (~360px wide) with a right-aligned form column (~480px wide). The home page is single-column reading. +- **Footer:** 5-up horizontal link row (GitHub / Docs / Changelog / Discord / X) at desktop, collapsing to 2-up at tablet and 1-up at mobile. + +### Whitespace Philosophy +Whitespace is structural and generous. Sections sit 96px apart with no decorative dividers between them — the `{colors.hairline}` 1px rule is the only signal of separation. Inside a section, content is left-flush against the column edge with no internal indentation; bullets use ASCII bracket prefixes (`[+]` / `[-]`) instead of indent-based layout. The result is a page that feels like a printed code listing rather than a styled marketing layout. + +## Elevation & Depth + +| Level | Treatment | Use | +|---|---|---| +| 0 — Flat | No border, no shadow | Default for body sections, list rows, hero text block, footer | +| 1 — Hairline rule | 1px solid `{colors.hairline}` (translucent warm tint) | Section dividers, between major content blocks | +| 2 — Hairline strong | 1px solid `{colors.hairline-strong}` | Tab strip bottom rule, in-list emphasized divider | +| 3 — Inverted dark | `{colors.surface-dark}` fill | Hero TUI mockup, dark CTA pill — the system's only "elevated" surface uses color, not shadow | + +There are no drop shadows in the system. Nothing lifts, nothing floats. The only way an element registers as "above" another is the dark surface used in the hero mockup. + +### Decorative Depth +Depth comes from typography density and the single dark TUI mockup, not from CSS effects: +- **ASCII block-pixel wordmark** — the OpenCode brand name rendered as a 5-row block of monospaced character cells, used in the primary nav and as the centerpiece of the hero TUI mockup. +- **Hero TUI mockup** — full-bleed `{colors.surface-dark}` rectangle containing a faux terminal interface: ASCII wordmark, a `tui-prompt-row` showing a Build command line, and `tab switch agent` / `ctrl-p commands` keybinding hints in `{colors.ash}` at the bottom edge. +- **Chart tiles** — three thin-line ASCII charts inside the home page's "open source AI coding agent" stat block, with abstract dotted/sparse-line plots in `{colors.body}` against the cream canvas. Captions sit beneath in `{typography.caption-md}` (`Fig 1. 150K GitHub Stars`, `Fig 2. 850 Contributors`, `Fig 3. 6.5M Monthly Devs`). + +## Shapes + +### Border Radius Scale + +| Token | Value | Use | +|---|---|---| +| `{rounded.none}` | 0px | Sections, hero TUI mockup, primary nav, footer, list rows — every container that isn't a button | +| `{rounded.sm}` | 4px | Every interactive element — primary CTA, secondary CTA, text inputs, install snippet, badges, prompt rows | +| `{rounded.full}` | 9999px | Avatar circles in testimonials | + +The radius vocabulary is two values: 4px for interactive elements and 0px for everything else. Avatar circles in testimonial rows are the only fully-rounded element in the system. + +### Photography Geometry +There is no photography. Visual elements are limited to: +- **ASCII block-pixel wordmark** in the nav and hero TUI mockup. +- **Inline ASCII charts** inside the stat-block section — abstract sparse-line and dotted plots without specific data points. +- **Avatar dots** (~32px) inside testimonial rows on `/zen` — flat colored circles in `{rounded.full}`. +- **In-product icons** (kbd, A+, ⊕, ↻, K, Z) rendered as small monospaced character glyphs, not bitmaps or SVG. + +## Components + +> **No hover states documented** per system policy. Each spec covers Default and Active/Pressed only. ### Buttons -**Primary (Dark Fill)** -- Background: `#201d1d` (OpenCode Dark) -- Text: `#fdfcfc` (OpenCode Light) -- Padding: 4px 20px -- Radius: 4px -- Font: 16px Berkeley Mono, weight 500, line-height 2.00 (relaxed) -- Outline: `rgb(253, 252, 252) none 0px` -- Use: Primary CTAs, main actions +**`button-primary`** — the universal OpenCode CTA +- Background `{colors.primary}`, text `{colors.on-primary}`, type `{typography.button-md}`, padding `4px 20px`, height ~36px, rounded `{rounded.sm}` (4px). +- Used for "Download" (top nav), "Get started with Zen", "Send" (enterprise contact form), "Subscribe" (newsletter footer), "Read docs →". +- Pressed state lives in `button-primary-active` — background drops to `{colors.ink-deep}`. -### Inputs +**`button-secondary`** — outlined alternative +- Background `{colors.canvas}`, text `{colors.ink}`, 1px solid `{colors.hairline-strong}` border, type `{typography.button-md}`, padding `4px 20px`, rounded `{rounded.sm}`. +- Lower-emphasis CTA — appears beside the primary fill where two actions are paired. -**Email Input** -- Background: `#f8f7f7` (light neutral) -- Text: `#201d1d` -- Border: `1px solid rgba(15, 0, 0, 0.12)` -- Padding: 20px -- Radius: 6px -- Font: Berkeley Mono, standard size -- Use: Form fields, email capture +**`button-tab`** + **`button-tab-active`** — install-tab strip +- Default: transparent background, text `{colors.mute}`, type `{typography.button-md}`, padding `8px 16px`, rounded `{rounded.none}`. +- Active: same surface, text `{colors.ink}`, with a 2px `{colors.ash}` bottom underline indicating selection. +- Used in the install-method tab strip on the home page (`curl` / `npm` / `bun` / `brew` / `yay`). -### Links +**`button-disabled`** +- Background `{colors.surface-card}`, text `{colors.ash}`, rounded `{rounded.sm}`. -**Default Link** -- Color: `#201d1d` -- Decoration: underline 1px -- Font-weight: 500 -- Use: Primary text links in body content +### Badges & Chips -**Light Link** -- Color: `#fdfcfc` -- Decoration: none -- Use: Links on dark backgrounds, navigation +**`badge-news`** — small dark chip in the news/announcement strip +- Background `{colors.surface-dark}`, text `{colors.on-dark}`, type `{typography.caption-md}`, padding `2px 8px`, rounded `{rounded.sm}`. +- Sits inline with body copy as a "News" / "Beta" / "Live now" tag on the home page above the hero headline. -**Muted Link** -- Color: `#9a9898` -- Decoration: none -- Use: Footer links, secondary navigation +**`badge-section-label`** — bracketed section header +- Background transparent, text `{colors.ink}`, type `{typography.heading-md}`, rounded `{rounded.none}`. +- Renders as a bare `**Heading**` line above a 1px `{colors.hairline}` rule with no chip background — but the way the text reads ("[+]", "[x]", `What is OpenCode?`) makes it function as a label component. -### Tabs +### Inputs & Forms -**Tab Navigation** -- Border-bottom: `2px solid #9a9898` (active tab indicator) -- Font: 16px, weight 500, line-height 1.00 -- Use: Section switching, content filtering +**`text-input`** + **`text-input-focused`** +- Default: background `{colors.surface-soft}`, text `{colors.ink}`, 1px solid `{colors.hairline}`, type `{typography.body-md}`, padding `8px 12px`, height ~40px, rounded `{rounded.sm}`. +- Focused: background flips to `{colors.canvas}`, border becomes 1px solid `{colors.ink}` (the canvas's flat focus signal — no halo, no glow). +- Used for every contact-form field on `/enterprise` (Full name, Role, Company, Company email, Phone number) and the newsletter email field at the home page footer. + +**`textarea`** +- Background `{colors.surface-soft}`, text `{colors.ink}`, 1px solid `{colors.hairline}`, type `{typography.body-md}`, padding `12px`, rounded `{rounded.sm}`. +- "What problem are you trying to solve?" multi-line textarea on `/enterprise`. + +**`install-snippet`** — the home page's signature install code block +- Background `{colors.surface-card}` (`#f1eeee`), text `{colors.ink}` rendered in `{typography.body-md}` (already monospaced — Berkeley Mono), padding `12px 16px`, rounded `{rounded.sm}`. +- Contains the literal `curl -fsSL https://opencode.ai/install | bash` command with a small copy-icon at the right edge. Sits below the install-method tab strip. + +### Cards & Containers + +**`hero-tui-mockup`** — the home page's signature TUI preview +- Container: full-bleed `{colors.surface-dark}` (~near-black), padding `64px 32px`, rounded `{rounded.none}`. +- Contents (top → bottom): ASCII block-pixel "OPENCODE" wordmark centered in `{colors.on-dark}`; a `{component.tui-prompt-row}` showing a "Build" command line with model selector text; an `tab switch agent ctrl-p commands` keybinding hint row at the bottom in `{colors.ash}`. + +**`tui-prompt-row`** — the inset command line inside the TUI mockup +- Background `{colors.surface-dark-elevated}` (`#302c2c`), text `{colors.on-dark}` in `{typography.body-md}`, padding `8px 12px`, rounded `{rounded.sm}`. +- Renders an inline command (`Build Claude Opus 4.5 OpenCode Zen`) with a leading vertical pipe and the model name styled as a bracketed token. + +**`list-row`** — feature/benefit row with ASCII bracket bullet +- Background `{colors.canvas}`, text `{colors.body}` in `{typography.body-md}`, padding `8px 0`. +- Each row begins with a `[+]` / `[-]` / `[x]` ASCII marker followed by a bold label and a regular description: e.g., `[+] LSP enabled Automatically loads the right LSPs for the IDE`. The bracket marker is part of the text content, not a separate icon. + +**`faq-row`** — FAQ entry with bracket toggle +- Background `{colors.canvas}`, text `{colors.ink}` in `{typography.body-md}`, padding `12px 0`, with a 1px `{colors.hairline}` bottom rule. +- Each row leads with `+` / `−` ASCII markers indicating expand/collapse state. Always rendered as plain text rows — no chevron icons, no animated accordion chrome. + +**`testimonial-row`** — `/zen` peer-quote row +- Background `{colors.surface-soft}`, text `{colors.body}` in `{typography.body-md}`, padding `16px 20px`, rounded `{rounded.sm}`. +- Layout: a 32px avatar circle (`{rounded.full}`) at left, name + role + company in `{typography.body-strong}` on the first line, quote in `{typography.body-md}` `{colors.body}` on the second line. + +**`chart-tile`** — the stat-block sparse-line chart +- Background `{colors.canvas}`, text `{colors.body}` in `{typography.caption-md}`, rounded `{rounded.none}`, padding `16px`. +- Contains an inline SVG/CSS-drawn ASCII-style sparse-line plot (dotted, abstract — never specific data points) with a `Fig N. ` caption beneath in `{colors.mute}`. ### Navigation -- Clean horizontal layout with Berkeley Mono throughout -- Brand logotype left-aligned in monospace -- Links at 16px weight 500 with underline decoration -- Dark background matching page background -- No backdrop blur or transparency -- solid surfaces only -### Image Treatment -- Terminal/code screenshots as hero imagery -- Dark terminal aesthetic with monospace type -- Minimal borders, content speaks for itself +**`primary-nav`** +- Background `{colors.canvas}`, text `{colors.ink}` in `{typography.body-strong}`, height ~56px, rounded `{rounded.none}`, with a 1px `{colors.hairline}` bottom rule. +- Layout (desktop): block-pixel ASCII OpenCode wordmark at left (~120×24px), nav links cluster center-right ("GitHub [150K] · Docs · Zen · Go · Enterprise"), `{component.button-primary}` "Download" CTA at the far right with a small download glyph. -### Distinctive Components +**Top Nav (Mobile)** +- ASCII wordmark stays at left, nav links collapse into a hamburger drawer at the right. The Download CTA remains visible at every breakpoint. -**Terminal Hero** -- Full-width dark terminal window as hero element -- ASCII art / stylized logo within terminal frame -- Monospace command examples with syntax highlighting -- Reinforces the CLI-first identity of the product +### Footer -**Feature List** -- Bulleted feature items with Berkeley Mono text -- Weight 500 for feature names, 400 for descriptions -- Tight vertical spacing between items -- No cards or borders -- pure text layout +**`footer-section`** +- Background `{colors.canvas}`, text `{colors.body}` in `{typography.caption-md}`, padding `32px 0`, with a 1px `{colors.hairline}` top rule. +- Top row: 5-column horizontal link grid (GitHub [150K] · Docs · Changelog · Discord · X), each rendered as a centered cell separated by 1px `{colors.hairline}` vertical rules. +- Bottom row: `©2026 Anomaly` copyright at left, `Brand · Privacy · Terms · English ▼` utility cluster at right, all in `{typography.caption-md}` `{colors.mute}`. -**Email Capture** -- Light background input (`#f8f7f7`) contrasting dark page -- Generous 20px padding for comfortable typing -- 6px radius -- the roundest element in the system -- Newsletter/waitlist pattern +### Inline -## 5. Layout Principles +**`link-inline`** — body-prose anchor link +- `{colors.ink}` text with underline. The brand's only link affordance — even links inside body paragraphs use ink color rather than `{colors.accent}` blue. Apple Blue is reserved for the in-product TUI. -### Spacing System -- Base unit: 8px -- Fine scale: 1px, 2px, 4px (sub-8px for borders and micro-adjustments) -- Standard scale: 8px, 12px, 16px, 20px, 24px -- Extended scale: 32px, 40px, 48px, 64px, 80px, 96px -- The system follows a clean 4/8px grid with consistent doubling +## Do's and Don'ts -### Grid & Container -- Max content width: approximately 800-900px (narrow, reading-optimized) -- Single-column layout as the primary pattern -- Centered content with generous horizontal margins -- Hero section: full-width dark terminal element -- Feature sections: single-column text blocks -- Footer: multi-column link grid +### Do +- Render every text role in Berkeley Mono. The single-font decision is the entire identity. +- Keep `{colors.canvas}` (`#fdfcfc`) as the only body background. Don't introduce gray section bands. +- Use ASCII bracket markers (`[+]`, `[-]`, `[x]`, `+`, `−`) as bullets, toggles, and section glyphs. They are the brand's only iconography. +- Anchor the dark `{component.hero-tui-mockup}` exactly once per landing page as the hero centerpiece. Never use the dark surface for body content. +- Reserve `{colors.accent}` (Apple Blue) and the rest of the semantic ramp for in-TUI states; marketing chrome stays monochrome. +- Use `{rounded.sm}` (4px) on every interactive element and `{rounded.none}` (0px) on every container. +- Stack content sections at `{spacing.section}` (96px) rhythm with only 1px `{colors.hairline}` rules between them. -### Whitespace Philosophy -- **Monospace rhythm**: The fixed-width nature of Berkeley Mono creates a natural vertical grid. Line-heights of 1.50 and 2.00 maintain consistent rhythm. -- **Narrow and focused**: Content is constrained to a narrow column, creating generous side margins that focus attention on the text. -- **Sections through spacing**: No decorative dividers. Sections are separated by generous vertical spacing (48-96px) rather than borders or background changes. +### Don't +- Don't introduce a sans-serif body font, a display face, or an italic style. Berkeley Mono carries everything. +- Don't add drop shadows, gradients, or atmospheric backgrounds. The system is flat-on-cream. +- Don't replace the ASCII bracket markers with SVG icons. The brackets are the icons. +- Don't use the semantic accent ramp (`{colors.accent}`, `{colors.warning}`, `{colors.danger}`, `{colors.success}`) on marketing CTAs. They belong to the in-product TUI. +- Don't pad cards with 24px+ internal padding. List rows sit at 8px vertical; FAQ rows at 12px. +- Don't render the OpenCode wordmark as a vector logo. It is always block-pixel ASCII. +- Don't fill the hero TUI mockup with photography or illustration. It is text-only and always shows a faux terminal command line. -### Border Radius Scale -- Micro (4px): Default for all elements -- buttons, containers, badges -- Input (6px): Form inputs get slightly more roundness -- The entire system uses just two radius values, reinforcing the utilitarian aesthetic - -## 6. Depth & Elevation - -| Level | Treatment | Use | -|-------|-----------|-----| -| Flat (Level 0) | No shadow, no border | Default state for most elements | -| Border Subtle (Level 1) | `1px solid rgba(15, 0, 0, 0.12)` | Section dividers, input borders, horizontal rules | -| Border Tab (Level 2) | `2px solid #9a9898` bottom only | Active tab indicator | -| Border Outline (Level 3) | `1px solid #646262` | Container outlines, elevated elements | - -**Shadow Philosophy**: OpenCode's depth system is intentionally flat. There are no box-shadows in the extracted tokens -- zero shadow values were detected. Depth is communicated exclusively through border treatments and background color shifts. This flatness is consistent with the terminal aesthetic: terminals don't have shadows, and neither does OpenCode. The three border levels (transparent warm, tab indicator, solid outline) create sufficient visual hierarchy without any elevation illusion. - -### Decorative Depth -- Background color shifts between `#201d1d` and `#302c2c` create subtle surface differentiation -- Transparent borders at 12% opacity provide barely-visible structure -- The warm reddish tint in border colors (`rgba(15, 0, 0, 0.12)`) ties borders to the overall warm dark palette -- No gradients, no blurs, no ambient effects -- pure flat terminal aesthetic - -## 7. Interaction & Motion - -### Hover States -- Links: color shift from default to accent blue (`#007aff`) or underline style change -- Buttons: subtle background lightening or border emphasis -- Accent blue provides a three-stage hover sequence: `#007aff` → `#0056b3` → `#004085` (default → hover → active) -- Danger red: `#ff3b30` → `#d70015` → `#a50011` -- Warning orange: `#ff9f0a` → `#cc7f08` → `#995f06` - -### Focus States -- Border-based focus: increased border opacity or solid border color -- No shadow-based focus rings -- consistent with the flat, no-shadow aesthetic -- Keyboard focus likely uses outline or border color shift to accent blue - -### Transitions -- Minimal transitions expected -- terminal-inspired interfaces favor instant state changes -- Color transitions: 100-150ms for subtle state feedback -- No scale, rotate, or complex transform animations - -## 8. Responsive Behavior +## Responsive Behavior ### Breakpoints + | Name | Width | Key Changes | -|------|-------|-------------| -| Mobile | <640px | Single column, reduced padding, heading scales down | -| Tablet | 640-1024px | Content width expands, slight padding increase | -| Desktop | >1024px | Full content width (~800-900px centered), maximum whitespace | +|---|---|---| +| desktop-large | 1280px+ | Default — 960px content column, 5-up footer link grid | +| desktop | 1024px | Same layout; nav remains horizontal | +| tablet | 850px | Footer collapses to 2-up grid; `/enterprise` two-column form stacks | +| tablet-narrow | 768px | Primary nav becomes hamburger drawer; Download CTA stays visible | +| mobile | 640px | Single-column everything; hero display drops 38px → ~28px; section padding tightens | ### Touch Targets -- Buttons with 4px 20px padding provide adequate horizontal touch area -- Input fields with 20px padding ensure comfortable mobile typing -- Tab items at 16px with tight line-height may need mobile adaptation +All interactive elements meet WCAG AA at the ~36–40px height range. `{component.button-primary}` sits at ~36px with 20px horizontal padding. `{component.text-input}` and `{component.textarea}` sit at ~40px. `{component.button-tab}` rows in the install-method strip sit at ~32–36px depending on label length but extend to a full 44px tappable cell via inline padding. Footer links use `{typography.caption-md}` (14px) but receive ~28px line-height (caption-md is 2.0) plus 8px vertical padding for a comfortable ~44px tappable row. ### Collapsing Strategy -- Hero heading: 38px → 28px → 24px on smaller screens -- Navigation: horizontal links → hamburger/drawer on mobile -- Feature lists: maintain single-column, reduce horizontal padding -- Terminal hero: maintain full-width, reduce internal padding -- Footer columns: multi-column → stacked single column -- Section spacing: 96px → 64px → 48px on mobile +- **Primary nav:** desktop horizontal cluster → tablet-narrow hamburger drawer at 768px. The dark "Download" CTA stays visible at all widths. +- **Hero TUI mockup:** maintains its full-bleed dark surface at every breakpoint; the ASCII wordmark scales proportionally and the keybinding-hint row may wrap to two lines on narrow screens. +- **Install snippet + tab strip:** desktop fixed-width pill → mobile full-width pill with horizontal scroll on the tab strip if labels overflow. +- **Footer:** 5-up horizontal link grid → 2-up at tablet → 1-up at mobile (each link becomes a full-width row). +- **`/enterprise` two-column layout:** desktop 50/50 → tablet stacks to single-column with the form below the text block. +- **Section padding:** `{spacing.section}` (96px) desktop → 64px tablet → 48px mobile. +- **Hero headline:** `{typography.display-xl}` (38px) at desktop, scaling to ~28px at mobile, line-height holding at 1.5. ### Image Behavior -- Terminal screenshots maintain aspect ratio and border treatment -- Full-width elements scale proportionally -- Monospace type maintains readability at all sizes due to fixed-width nature +There are no raster images in the system aside from the favicon and OG share image. Every visual element — wordmarks, charts, icons — is rendered as type or inline SVG and scales without aspect-ratio considerations. -## 9. Agent Prompt Guide +## Iteration Guide -### Quick Color Reference -- Page background: `#201d1d` (warm near-black) -- Primary text: `#fdfcfc` (warm off-white) -- Secondary text: `#9a9898` (warm gray) -- Muted text: `#6e6e73` -- Accent: `#007aff` (blue) -- Danger: `#ff3b30` (red) -- Success: `#30d158` (green) -- Warning: `#ff9f0a` (orange) -- Button bg: `#201d1d`, button text: `#fdfcfc` -- Border: `rgba(15, 0, 0, 0.12)` (warm transparent) -- Input bg: `#f8f7f7`, input border: `rgba(15, 0, 0, 0.12)` +1. Focus on ONE component at a time. Pull its YAML entry and verify every property resolves. +2. Reference component names and tokens directly (`{colors.ink}`, `{component.hero-tui-mockup}`, `{rounded.sm}`) — 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 (`-active`, `-disabled`) — do not bury them inside prose. +5. Default body to `{typography.body-md}`; reach for `{typography.body-strong}` for emphasis; reserve `{typography.display-xl}` strictly for the page-top hero headline. +6. Keep `{colors.surface-dark}` scarce — at most one full-bleed dark mockup per page. The dark surface is a narrative device, not a chrome treatment. +7. When introducing a new component, ask whether it can be expressed with the existing ASCII-bracket + 4px-radius + Berkeley-Mono vocabulary before adding new tokens. The system's strength is that it almost never needs new ones. -### Example Component Prompts -- "Create a hero section on `#201d1d` warm dark background. Headline at 38px Berkeley Mono weight 700, line-height 1.50, color `#fdfcfc`. Subtitle at 16px weight 400, color `#9a9898`. Primary CTA button (`#201d1d` bg with `1px solid #646262` border, 4px radius, 4px 20px padding, `#fdfcfc` text at weight 500)." -- "Design a feature list: single-column on `#201d1d` background. Feature name at 16px Berkeley Mono weight 700, color `#fdfcfc`. Description at 16px weight 400, color `#9a9898`. No cards, no borders -- pure text with 16px vertical gap between items." -- "Build an email capture form: `#f8f7f7` background input, `1px solid rgba(15, 0, 0, 0.12)` border, 6px radius, 20px padding. Adjacent dark button (`#201d1d` bg, `#fdfcfc` text, 4px radius, 4px 20px padding). Berkeley Mono throughout." -- "Create navigation: sticky `#201d1d` background. 16px Berkeley Mono weight 500 for links, `#fdfcfc` text. Brand name left-aligned in monospace. Links with underline decoration. No blur, no transparency -- solid dark surface." -- "Design a footer: `#201d1d` background, multi-column link grid. Links at 16px Berkeley Mono weight 400, color `#9a9898`. Section headers at weight 700. Border-top `1px solid rgba(15, 0, 0, 0.12)` separator." +## Known Gaps -### Iteration Guide -1. Berkeley Mono is the only font -- never introduce a second typeface. Size and weight create all hierarchy. -2. Keep surfaces flat: no shadows, no gradients, no blur effects. Use borders and background shifts only. -3. The warm undertone matters: use `#201d1d` not `#000000`, use `#fdfcfc` not `#ffffff`. The reddish warmth is subtle but essential. -4. Border radius is 4px everywhere except inputs (6px). Never use rounded pills or large radii. -5. Semantic colors follow Apple HIG: `#007aff` blue, `#ff3b30` red, `#30d158` green, `#ff9f0a` orange. Each has hover and active darkened variants. -6. Three-stage interaction: default → hover (darkened) → active (deeply darkened) for all semantic colors. -7. Borders use `rgba(15, 0, 0, 0.12)` -- a warm transparent dark, not neutral gray. This ties borders to the warm palette. -8. Spacing follows an 8px grid: 8, 16, 24, 32, 40, 48, 64, 80, 96px. Use 4px for fine adjustments only. +- **Mobile screenshots not captured** — responsive behavior synthesizes OpenCode's mobile pattern (hamburger drawer, single-column, footer accordion) from desktop evidence and the breakpoint stack. +- **Hover states not documented** by system policy. +- **In-product TUI screenshots** beyond the marketing hero mockup are not in the captured set; the actual `opencode` terminal interface (full keybindings, panels, status bar) is not documented here. +- **`/go` page** not extracted — the marketing page for the Go SDK likely shares the same chrome but introduces code-sample blocks not documented above. +- **Form validation state styling** (success / error inline messages) not present in the captured surfaces. diff --git a/design-md/pinterest/DESIGN.md b/design-md/pinterest/DESIGN.md index 2ff4d46..6da3ce7 100644 --- a/design-md/pinterest/DESIGN.md +++ b/design-md/pinterest/DESIGN.md @@ -1,230 +1,597 @@ -# Design System Inspired by Pinterest +--- +version: alpha +name: Pinterest +description: | + A photography-first discovery system organized around the Pinterest Red CTA, the masonry pin grid, and a soft warm-cream chrome that gets out of the imagery's way. The home page is a content-discovery tool wearing the chrome of a magazine publisher: 70px display headlines, friendly Pin Sans typography, fully-rounded pill buttons (16px) on a cream-tinted neutral palette, and a sticky red "Sign up" CTA that anchors every viewport. Pin imagery is the system's load-bearing visual element — square, portrait, and landscape pins tile in a column-based masonry grid where each tile is a fully-rounded 16px-radius card, separated by tight 8px gutters. The chrome is otherwise quiet: warm grays, true whites, and a single saturated red — no decorative gradients, no atmospheric backgrounds, no shadows beyond a soft modal scrim. -## 1. Visual Theme & Atmosphere +colors: + primary: "#e60023" + on-primary: "#ffffff" + primary-pressed: "#cc001f" + ink: "#000000" + ink-soft: "#211922" + body: "#33332e" + charcoal: "#262622" + mute: "#62625b" + ash: "#91918c" + stone: "#c8c8c1" + hairline: "#dadad3" + hairline-soft: "#e5e5e0" + on-secondary: "#000000" + secondary-bg: "#e5e5e0" + secondary-pressed: "#c8c8c1" + canvas: "#ffffff" + surface-soft: "#fbfbf9" + surface-card: "#f6f6f3" + surface-elevated: "#ffffff" + on-dark: "#ffffff" + on-dark-mute: "rgba(255,255,255,0.7)" + surface-dark: "#262622" + focus-outer: "#435ee5" + focus-inner: "#ffffff" + accent-pressed-blue: "#617bff" + accent-purple: "#7e238b" + accent-purple-deep: "#6845ab" + success-deep: "#103c25" + success-pale: "#c7f0da" + error: "#9e0a0a" + error-deep: "#cc001f" -Pinterest's website is a warm, inspiration-driven canvas that treats visual discovery like a lifestyle magazine. The design operates on a soft, slightly warm white background with Pinterest Red (`#e60023`) as the singular, bold brand accent. Unlike the cool blues of most tech platforms, Pinterest's neutral scale has a distinctly warm undertone — grays lean toward olive/sand (`#91918c`, `#62625b`, `#e5e5e0`) rather than cool steel, creating a cozy, craft-like atmosphere that invites browsing. +typography: + display-xl: + fontFamily: Pin Sans + fontSize: 70px + fontWeight: 600 + lineHeight: 1.1 + letterSpacing: -1.2px + display-lg: + fontFamily: Pin Sans + fontSize: 44px + fontWeight: 700 + lineHeight: 1.15 + letterSpacing: -0.8px + heading-xl: + fontFamily: Pin Sans + fontSize: 28px + fontWeight: 700 + lineHeight: 1.2 + letterSpacing: -1.2px + heading-lg: + fontFamily: Pin Sans + fontSize: 22px + fontWeight: 600 + lineHeight: 1.25 + letterSpacing: 0 + heading-md: + fontFamily: Pin Sans + fontSize: 18px + fontWeight: 600 + lineHeight: 1.3 + letterSpacing: 0 + body-md: + fontFamily: Pin Sans + fontSize: 16px + fontWeight: 400 + lineHeight: 1.4 + letterSpacing: 0 + body-strong: + fontFamily: Pin Sans + fontSize: 16px + fontWeight: 600 + lineHeight: 1.4 + letterSpacing: 0 + body-sm: + fontFamily: Pin Sans + fontSize: 14px + fontWeight: 400 + lineHeight: 1.4 + letterSpacing: 0 + body-sm-strong: + fontFamily: Pin Sans + fontSize: 14px + fontWeight: 700 + lineHeight: 1.4 + letterSpacing: 0 + caption-md: + fontFamily: Pin Sans + fontSize: 12px + fontWeight: 500 + lineHeight: 1.5 + letterSpacing: 0 + caption-sm: + fontFamily: Pin Sans + fontSize: 12px + fontWeight: 400 + lineHeight: 1.4 + letterSpacing: 0 + link-md: + fontFamily: Pin Sans + fontSize: 16px + fontWeight: 600 + lineHeight: 1.4 + letterSpacing: 0 + button-md: + fontFamily: Pin Sans + fontSize: 14px + fontWeight: 700 + lineHeight: 1 + letterSpacing: 0 + button-sm: + fontFamily: Pin Sans + fontSize: 12px + fontWeight: 700 + lineHeight: 1 + letterSpacing: 0 -The typography uses Pin Sans — a custom proprietary font with a broad fallback stack including Japanese fonts, reflecting Pinterest's global reach. At display scale (70px, weight 600), Pin Sans creates large, inviting headlines. At smaller sizes, the system is compact: buttons at 12px, captions at 12–14px. The CSS variable naming system (`--comp-*`, `--sema-*`, `--base-*`) reveals a sophisticated three-tier design token architecture: component-level, semantic-level, and base-level tokens. +rounded: + none: 0px + sm: 8px + md: 16px + lg: 32px + full: 9999px -What distinguishes Pinterest is its generous border-radius system (12px–40px, plus 50% for circles) and warm-tinted button backgrounds. The secondary button (`#e5e5e0`) has a distinctly warm, sand-like tone rather than cold gray. The primary red button uses 16px radius — rounded but not pill-shaped. Combined with warm badge backgrounds (`hsla(60,20%,98%,.5)` — a subtle yellow-warm wash) and photography-dominant layouts, the result is a design that feels handcrafted and personal, not corporate and sterile. +spacing: + xxs: 4px + xs: 6px + sm: 8px + md: 12px + lg: 16px + xl: 24px + xxl: 32px + section: 64px + +components: + button-primary: + backgroundColor: "{colors.primary}" + textColor: "{colors.on-primary}" + typography: "{typography.button-md}" + rounded: "{rounded.md}" + padding: 6px 14px + height: 40px + button-primary-pressed: + backgroundColor: "{colors.primary-pressed}" + textColor: "{colors.on-primary}" + typography: "{typography.button-md}" + rounded: "{rounded.md}" + button-secondary: + backgroundColor: "{colors.secondary-bg}" + textColor: "{colors.on-secondary}" + typography: "{typography.button-md}" + rounded: "{rounded.md}" + padding: 6px 14px + height: 40px + button-secondary-pressed: + backgroundColor: "{colors.secondary-pressed}" + textColor: "{colors.on-secondary}" + typography: "{typography.button-md}" + rounded: "{rounded.md}" + button-tertiary: + backgroundColor: "transparent" + textColor: "{colors.ink}" + typography: "{typography.button-md}" + rounded: "{rounded.md}" + button-icon-circular: + backgroundColor: "{colors.surface-card}" + textColor: "{colors.ink}" + rounded: "{rounded.full}" + size: 40px + button-pill-on-image: + backgroundColor: "{colors.canvas}" + textColor: "{colors.ink}" + typography: "{typography.button-md}" + rounded: "{rounded.full}" + padding: 8px 14px + button-disabled: + backgroundColor: "{colors.surface-card}" + textColor: "{colors.ash}" + rounded: "{rounded.md}" + search-bar: + backgroundColor: "{colors.surface-card}" + textColor: "{colors.ink}" + typography: "{typography.body-md}" + rounded: "{rounded.full}" + padding: 11px 15px + height: 48px + search-bar-focused: + backgroundColor: "{colors.canvas}" + textColor: "{colors.ink}" + rounded: "{rounded.full}" + text-input: + backgroundColor: "{colors.canvas}" + textColor: "{colors.ink}" + typography: "{typography.body-md}" + rounded: "{rounded.md}" + padding: 11px 15px + height: 44px + text-input-focused: + backgroundColor: "{colors.canvas}" + textColor: "{colors.ink}" + rounded: "{rounded.md}" + pin-card: + backgroundColor: "{colors.surface-card}" + textColor: "{colors.ink}" + rounded: "{rounded.md}" + padding: 0px + pin-card-large: + backgroundColor: "{colors.surface-card}" + textColor: "{colors.ink}" + rounded: "{rounded.lg}" + padding: 0px + pin-overlay-pill: + backgroundColor: "{colors.canvas}" + textColor: "{colors.ink}" + typography: "{typography.button-sm}" + rounded: "{rounded.full}" + padding: 6px 12px + filter-chip: + backgroundColor: "{colors.surface-card}" + textColor: "{colors.ink}" + typography: "{typography.button-md}" + rounded: "{rounded.full}" + padding: 8px 16px + filter-chip-active: + backgroundColor: "{colors.ink}" + textColor: "{colors.on-dark}" + typography: "{typography.button-md}" + rounded: "{rounded.full}" + category-tile: + backgroundColor: "{colors.surface-card}" + textColor: "{colors.ink}" + typography: "{typography.body-strong}" + rounded: "{rounded.md}" + padding: 16px + feature-card: + backgroundColor: "{colors.canvas}" + textColor: "{colors.ink}" + typography: "{typography.heading-xl}" + rounded: "{rounded.md}" + padding: 32px + feature-card-soft: + backgroundColor: "{colors.surface-card}" + textColor: "{colors.ink}" + typography: "{typography.heading-xl}" + rounded: "{rounded.md}" + padding: 32px + modal-card: + backgroundColor: "{colors.canvas}" + textColor: "{colors.ink}" + typography: "{typography.body-md}" + rounded: "{rounded.lg}" + padding: 32px + hero-cta-strip: + backgroundColor: "{colors.surface-dark}" + textColor: "{colors.on-dark}" + typography: "{typography.heading-xl}" + rounded: "{rounded.none}" + padding: 48px 32px + primary-nav: + backgroundColor: "{colors.canvas}" + textColor: "{colors.ink}" + typography: "{typography.body-strong}" + rounded: "{rounded.none}" + height: 64px + footer-section: + backgroundColor: "{colors.canvas}" + textColor: "{colors.mute}" + typography: "{typography.body-sm}" + rounded: "{rounded.none}" + padding: 32px 24px + link-inline: + textColor: "{colors.ink-soft}" + typography: "{typography.link-md}" +--- + +## Overview + +Pinterest's marketing system is built around a single instructional principle: get out of the photograph's way. The chrome is a quiet warm-cream neutral palette (`{colors.surface-soft}`, `{colors.surface-card}`, `{colors.canvas}`) carrying typography in Pinterest's proprietary Pin Sans face, with Pinterest Red (`{colors.primary}` — `#e60023`) reserved exclusively for the "Sign up" CTA, the active-tab indicator, and the sticky top-nav anchor. Every other surface is allowed to fade behind the imagery — pin tiles, category tiles, content thumbnails, profile shots — that constitutes the actual product. + +The design system has two distinct surface modes that alternate down the home page: the **hero/CTA chrome** (cream surfaces, large 70px Pin Sans display headlines, alternating left/right photo-illustrated feature cards) and the **content masonry** (a column-based grid of 16px-radius pin cards on `{colors.surface-card}` with no internal padding — the pin is the card). The search results page is almost pure masonry: a tight column grid of pin imagery in mixed aspect ratios, with a small filter-chip strip at the top and the sticky red Sign-up CTA in the upper-right corner. The `create.pinterest.com` business surface inverts the grid back to a more traditional editorial layout but keeps every other rule of the system: Pin Sans, cream chrome, red CTA, 16px-radius pills. + +The system's signature gesture is **shape geometry**: 16px radius (`{rounded.md}`) for nearly every surface — buttons, inputs, pin cards, feature cards — and 32px radius (`{rounded.lg}`) reserved for pin-card-large and modal cards. There are exactly three radius values in active use: 16px, 32px, and pill (9999px). The system never goes flat (sharp corners) and never goes radius-medium — those two values are the entire shape vocabulary. **Key Characteristics:** -- Warm white canvas with olive/sand-toned neutrals — cozy, not clinical -- Pinterest Red (`#e60023`) as singular bold accent — never subtle, always confident -- Pin Sans custom font with global fallback stack (including CJK) -- Three-tier token architecture: `--comp-*` / `--sema-*` / `--base-*` -- Warm secondary surfaces: sand gray (`#e5e5e0`), warm badge (`hsla(60,20%,98%,.5)`) -- Generous border-radius: 16px standard, up to 40px for large containers -- Photography-first content — pins/images are the primary visual element -- Dark near-purple text (`#211922`) — warm, with a hint of plum +- Single-accent CTA: Pinterest Red (`{colors.primary}`) carries every primary action; everything else is monochrome +- Pin Sans proprietary typography across every text role from `{typography.display-xl}` (70px) down to `{typography.caption-sm}` (12px) — no serif, no monospace anywhere +- Two-radius shape system: `{rounded.md}` (16px) for most components, `{rounded.lg}` (32px) for large cards and modals, `{rounded.full}` for circular elements +- Masonry pin grid as the load-bearing visual element — column-based layout where each pin's natural aspect ratio is preserved +- Warm-cream neutral chrome (`{colors.surface-card}` — #f6f6f3) that softly recedes behind imagery without competing +- Sticky top nav with the always-red Sign-up CTA anchored in the upper-right at every breakpoint +- Modal overlay (login/signup) using a soft scrim over the page content rather than a navigation jump -## 2. Color Palette & Roles +## Colors -### Primary Brand -- **Pinterest Red** (`#e60023`): Primary CTA, brand accent — bold, confident red -- **Green 700** (`#103c25`): `--base-color-green-700`, success/nature accent -- **Green 700 Hover** (`#0b2819`): `--base-color-hover-green-700`, pressed green +> **Source pages:** `/` (home), `/search/pins/?q=bold lip` (search results), `create.pinterest.com/` (creator marketing), `create.pinterest.com/product-features/how-to-create-boards/` (creator article). The chrome palette is identical across all four pages. + +### Brand & Accent +- **Pinterest Red** (`{colors.primary}` — `#e60023`): the brand's only highly-saturated color. Sign-up CTAs, sticky top-nav anchor, active state in tab strips, and the brand wordmark. +- **Pinterest Red Pressed** (`{colors.primary-pressed}` — `#cc001f`): pressed state for the primary button — a single notch deeper than brand red. + +### Surface +- **Canvas** (`{colors.canvas}` — `#ffffff`): true white. The base surface for the primary nav, modals, feature cards, and content body. +- **Soft Surface** (`{colors.surface-soft}` — `#fbfbf9`): faintly cream-tinted off-white used for the page body wash on the home page hero. +- **Surface Card** (`{colors.surface-card}` — `#f6f6f3`): warm-cream card and pin-tile background. Carries category tiles, search-bar default fill, button-secondary default, and pin-card backgrounds. +- **Secondary BG** (`{colors.secondary-bg}` — `#e5e5e0`): the gray-cream used for `{component.button-secondary}` ("I already have an account") fill — a notch deeper than `{colors.surface-card}`. +- **Secondary Pressed** (`{colors.secondary-pressed}` — `#c8c8c1`): pressed state for the secondary button. +- **Surface Dark** (`{colors.surface-dark}` — `#262622`): warm near-black used in the rare dark CTA strip on `create.pinterest.com`. +- **Hairline** (`{colors.hairline}` — `#dadad3`): 1px row dividers, footer column rules. +- **Hairline Soft** (`{colors.hairline-soft}` — `#e5e5e0`): lighter inline divider; doubles as the secondary-button background. ### Text -- **Plum Black** (`#211922`): Primary text — warm near-black with plum undertone -- **Black** (`#000000`): Secondary text, button text -- **Olive Gray** (`#62625b`): Secondary descriptions, muted text -- **Warm Silver** (`#91918c`): `--comp-button-color-text-transparent-disabled`, disabled text, input borders -- **White** (`#ffffff`): Text on dark/colored surfaces - -### Interactive -- **Focus Blue** (`#435ee5`): `--comp-button-color-border-focus-outer-transparent`, focus rings -- **Performance Purple** (`#6845ab`): `--sema-color-hover-icon-performance-plus`, performance features -- **Recommendation Purple** (`#7e238b`): `--sema-color-hover-text-recommendation`, AI recommendation -- **Link Blue** (`#2b48d4`): Link text color -- **Facebook Blue** (`#0866ff`): `--facebook-background-color`, social login -- **Pressed Blue** (`#617bff`): `--base-color-pressed-blue-200`, pressed state - -### Surface & Border -- **Sand Gray** (`#e5e5e0`): Secondary button background — warm, craft-like -- **Warm Light** (`#e0e0d9`): Circular button backgrounds, badges -- **Warm Wash** (`hsla(60, 20%, 98%, 0.5)`): `--comp-badge-color-background-wash-light`, subtle warm badge bg -- **Fog** (`#f6f6f3`): Light surface (at 50% opacity) -- **Border Disabled** (`#c8c8c1`): `--sema-color-border-disabled`, disabled borders -- **Hover Gray** (`#bcbcb3`): `--base-color-hover-grayscale-150`, hover border -- **Dark Surface** (`#33332e`): Dark section backgrounds +- **Ink** (`{colors.ink}` — `#000000`): primary headlines, button text, primary nav links. +- **Ink Soft** (`{colors.ink-soft}` — `#211922`): inline-link color in body prose. The brand's only "color" beyond Pinterest Red used in chrome — a near-black with a faint warm cast. +- **Body** (`{colors.body}` — `#33332e`): default paragraph text on `{colors.canvas}`. +- **Charcoal** (`{colors.charcoal}` — `#262622`): subtly softer body where pure ink is too heavy. +- **Mute** (`{colors.mute}` — `#62625b`): metadata text, footer links, secondary captions. +- **Ash** (`{colors.ash}` — `#91918c`): disabled button text, placeholder text in inputs. +- **Stone** (`{colors.stone}` — `#c8c8c1`): least-emphasis utility text, disabled-state borders. +- **On Dark** (`{colors.on-dark}` — `#ffffff`): primary text on `{colors.surface-dark}`. ### Semantic -- **Error Red** (`#9e0a0a`): Checkbox/form error states +- **Error** (`{colors.error}` — `#9e0a0a`): validation messages, destructive confirmation copy. +- **Error Deep** (`{colors.error-deep}` — `#cc001f`): deepened error background where the regular error tone needs more contrast. Note: this matches the primary-pressed value but in error context represents semantic destructiveness. +- **Success Deep** (`{colors.success-deep}` — `#103c25`): in-product success messaging. +- **Success Pale** (`{colors.success-pale}` — `#c7f0da`): pale success-pill background. +- **Focus Outer** (`{colors.focus-outer}` — `#435ee5`): the system's focus-ring blue — appears as a 2px outer outline around focused inputs and buttons. +- **Focus Inner** (`{colors.focus-inner}` — `#ffffff`): white inner gap inside the focus-ring stack. -## 3. Typography Rules +### Editorial Accents (used sparingly inside content imagery and category badges) +- **Accent Pressed Blue** (`{colors.accent-pressed-blue}` — `#617bff`): pressed state for blue informational badges and editorial pin chips. +- **Accent Purple** (`{colors.accent-purple}` — `#7e238b`): editorial recommendation badge, in-product "Pinterest Predicts" callout. +- **Accent Purple Deep** (`{colors.accent-purple-deep}` — `#6845ab`): paired dark for purple lockups and "Performance+" iconography. + +## Typography ### Font Family -- **Primary**: `Pin Sans`, fallbacks: `-apple-system, system-ui, Segoe UI, Roboto, Oxygen-Sans, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol, Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, Helvetica, ヒラギノ角ゴ Pro W3, メイリオ, Meiryo, MS Pゴシック, Arial` +**Pin Sans** is Pinterest's proprietary geometric sans-serif used across every text role on every page. It carries weights 400 (regular), 500 (medium), 600 (semibold), and 700 (bold), and falls back through a long stack — `-apple-system` → `system-ui` → `Segoe UI` → `Roboto` → `Helvetica Neue` → `Arial` plus emoji fallbacks. The face's distinctive trait is its tight letter-spacing at display sizes (-1.2px on `{typography.display-xl}` and `{typography.heading-xl}`), which gives 70px headlines a confident, friendly density rather than the airy spread of more conventional display geometric sans faces. ### Hierarchy -| Role | Font | Size | Weight | Line Height | Letter Spacing | Notes | -|------|------|------|--------|-------------|----------------|-------| -| Display Hero | Pin Sans | 70px (4.38rem) | 600 | normal | normal | Maximum impact | -| Section Heading | Pin Sans | 28px (1.75rem) | 700 | normal | -1.2px | Negative tracking | -| Body | Pin Sans | 16px (1.00rem) | 400 | 1.40 | normal | Standard reading | -| Caption Bold | Pin Sans | 14px (0.88rem) | 700 | normal | normal | Strong metadata | -| Caption | Pin Sans | 12px (0.75rem) | 400–500 | 1.50 | normal | Small text, tags | -| Button | Pin Sans | 12px (0.75rem) | 400 | normal | normal | Button labels | +| Token | Size | Weight | Line Height | Letter Spacing | Use | +|---|---|---|---|---|---| +| `{typography.display-xl}` | 70px | 600 | 1.1 | -1.2px | Marketing hero headline ("Create the life you love on Pinterest") | +| `{typography.display-lg}` | 44px | 700 | 1.15 | -0.8px | "Where your content can thrive" creator hero | +| `{typography.heading-xl}` | 28px | 700 | 1.2 | -1.2px | Section heading ("Bring your favorite ideas to life", "Pinterest for your brand") | +| `{typography.heading-lg}` | 22px | 600 | 1.25 | 0 | Sub-section heading, modal title ("Welcome to Pinterest") | +| `{typography.heading-md}` | 18px | 600 | 1.3 | 0 | Card title, in-grid pin label | +| `{typography.body-md}` | 16px | 400 | 1.4 | 0 | Body copy, modal body, default paragraph | +| `{typography.body-strong}` | 16px | 600 | 1.4 | 0 | Inline emphasis, primary nav link, form label | +| `{typography.body-sm}` | 14px | 400 | 1.4 | 0 | Footer copy, in-grid pin metadata, helper text | +| `{typography.body-sm-strong}` | 14px | 700 | 1.4 | 0 | Search-result count label, table-header text | +| `{typography.caption-md}` | 12px | 500 | 1.5 | 0 | Caption text, link metadata | +| `{typography.caption-sm}` | 12px | 400 | 1.4 | 0 | Smallest utility text, copyright | +| `{typography.link-md}` | 16px | 600 | 1.4 | 0 | Inline anchor link in body prose | +| `{typography.button-md}` | 14px | 700 | 1 | 0 | Standard primary/secondary button label | +| `{typography.button-sm}` | 12px | 700 | 1 | 0 | Compact pill chip, in-card button | ### Principles -- **Compact type scale**: The range is 12px–70px with a dramatic jump — most functional text is 12–16px, creating a dense, app-like information hierarchy. -- **Warm weight distribution**: 600–700 for headings, 400–500 for body. No ultra-light weights — the type always feels substantial. -- **Negative tracking on headings**: -1.2px on 28px headings creates cozy, intimate section titles. -- **Single font family**: Pin Sans handles everything — no secondary display or monospace font detected. +The system has an unusually steep size jump between display and body — `{typography.display-xl}` (70px) drops directly to `{typography.body-md}` (16px) on the home hero with no intermediate tier between. The negative tracking on the largest tiers (-1.2px / -0.8px) creates a tighter, more confident headline than a default geometric sans would deliver, and the body copy sits at a generous 1.4 line-height to keep multi-line descriptions breathing. -## 4. Component Stylings +### Note on Font Substitutes +Pin Sans is proprietary. The closest open-source substitute is **Inter** (weights 400 / 500 / 600 / 700) — its geometry, x-height, and metric balance match Pin Sans within ~3% at body sizes. **Manrope** is a strong secondary substitute for the display tier where slightly tighter letterspacing helps the 70px headline feel weighted. Apply -1.2px tracking on the substitute at display sizes regardless of which substitute is chosen. + +## Layout + +### Spacing System +- **Base unit:** 8px (with finer 4/6/7px steps available for tight inline gaps in pill buttons and chips). +- **Tokens (front matter):** `{spacing.xxs}` (4px) · `{spacing.xs}` (6px) · `{spacing.sm}` (8px) · `{spacing.md}` (12px) · `{spacing.lg}` (16px) · `{spacing.xl}` (24px) · `{spacing.xxl}` (32px) · `{spacing.section}` (64px). +- **Universal section rhythm:** every page in the set uses `{spacing.section}` (64px) as the vertical gap between major content blocks. Pin grids use `{spacing.sm}` (8px) gutters between tiles — the tightest grid gutter in the system, designed so imagery effectively touches across columns. +- **Modal padding:** `{component.modal-card}` uses 32px internal padding (`{spacing.xxl}`) on all sides. + +### Grid & Container +- **Max width:** ~1280px content area at desktop with 24px gutters (~48px at ultrawide). +- **Pin masonry grid:** auto-fitting column-based layout — 5–6 columns at ultrawide, 4 columns at desktop, 3 at tablet, 2 at mobile-landscape, 1 at mobile. Each tile preserves its natural aspect ratio (square / 2:3 / 3:4 / 4:5 portrait — never landscape because pins are vertically-oriented). Gutters are `{spacing.sm}` (8px) horizontal and vertical. +- **Home hero feature row:** asymmetric 2-column split where text and imagery alternate left/right down the page (text-left + image-right, then image-left + text-right, etc.). +- **Footer:** 4-column link grid at desktop, collapsing to 2-up at tablet, 1-up at mobile. + +### Whitespace Philosophy +Whitespace is generous on the marketing surfaces and tight on the discovery surfaces. The home page sits sections 64px apart with photo-illustrated feature cards using 32px internal padding, while the search results page collapses to an 8px-gutter masonry grid that tiles imagery edge-to-edge. The system reads as two tools sharing the same chrome: a magazine (hero / feature / CTA / footer) and a search engine (top nav / filter row / pin grid / load more). + +## Elevation & Depth + +| Level | Treatment | Use | +|---|---|---| +| 0 — Flat | No border, no shadow | Default for pin cards, feature cards, footer — the dominant treatment | +| 1 — Hairline border | 1px solid `{colors.hairline}` | Inputs, footer column dividers, in-list rows | +| 2 — Modal scrim + soft shadow | Modal sits on a dark scrim over the page content with a soft 16px ambient shadow | Login / signup modal, image preview modal | +| 3 — Pin hover lift | (intentionally undocumented per system policy) | n/a | + +Pinterest's system has effectively no shadow elevation in its content surfaces. Pin cards sit flat on the canvas; the only "elevation" appears on the modal layer where a 16px ambient shadow paired with a 50%-opacity scrim lifts the modal above the page content. + +### Decorative Depth +Depth comes entirely from the imagery itself, not from CSS effects: +- **Pin photography** carries cinematic depth through composition (food photography, fashion close-ups, interior shots) — the design lets each tile's image speak rather than adding chrome to it. +- **Category tile thumbnails** in the home page's feature rows use Pinterest's own pin imagery as composition assets, often with a small `{component.pin-overlay-pill}` ("Cherry red", "Preppy look", "Earthy space inspo") overlaid in the corner of the image. +- **Modal scrim** — a 50%-opacity dark overlay over the entire page content when the login modal opens, with a 16px ambient shadow underneath the modal card lifting it to the visual top. + +## Shapes + +### Border Radius Scale + +| Token | Value | Use | +|---|---|---| +| `{rounded.none}` | 0px | Footer, primary nav, page sections — all flat structural surfaces | +| `{rounded.sm}` | 8px | Rare medium-radius surface (e.g., editorial tooltip) | +| `{rounded.md}` | 16px | Buttons, inputs, pin cards, feature cards, category tiles — the dominant component radius | +| `{rounded.lg}` | 32px | Large pin cards, modal cards — used sparingly for "big" content surfaces | +| `{rounded.full}` | 9999px | Search bar, filter chips, pin overlay pills, icon-circular buttons, avatars | + +The radius vocabulary is essentially three values: 16px for most things, 32px for big cards and modals, and pill for circular elements. There are no sharp-cornered buttons or sharp-cornered pin cards. + +### Photography Geometry +- **Pin imagery:** mixed aspect ratios — square (1:1), portrait (3:4, 2:3, 4:5), and rare landscape — preserved at their natural ratio inside `{rounded.md}` (16px) corners on small tiles and `{rounded.lg}` (32px) on large feature pins. +- **Category tile thumbnails:** square (1:1) with `{rounded.md}` corners. +- **Avatar circles:** 32–48px at `{rounded.full}` for in-pin attribution and profile chips. +- **Feature card imagery:** typically 4:5 portrait on home-page category cards, with the photo occupying ~60% of the card and the headline + CTA stacked beneath. + +## Components + +> **No hover states documented** per system policy. Each spec covers Default and Active/Pressed only. ### Buttons -**Primary Red** -- Background: `#e60023` (Pinterest Red) -- Text: `#000000` (black — unusual choice for contrast on red) -- Padding: 6px 14px -- Radius: 16px (generously rounded, not pill) -- Border: `2px solid rgba(255, 255, 255, 0)` (transparent) -- Focus: semantic border + outline via CSS variables +**`button-primary`** — the universal Pinterest CTA +- Background `{colors.primary}` (Pinterest Red), text `{colors.on-primary}`, type `{typography.button-md}`, padding `6px 14px`, height ~40px, rounded `{rounded.md}` (16px). +- Used for "Sign up", "Join Pinterest for free", "Get started" — every primary action across every surface in the system. +- Pressed state lives in `button-primary-pressed` — background drops to `{colors.primary-pressed}` (`#cc001f`). -**Secondary Sand** -- Background: `#e5e5e0` (warm sand gray) -- Text: `#000000` -- Padding: 6px 14px -- Radius: 16px -- Focus: same semantic border system +**`button-secondary`** — gray-cream alternative +- Background `{colors.secondary-bg}` (`#e5e5e0`), text `{colors.on-secondary}`, type `{typography.button-md}`, padding `6px 14px`, height ~40px, rounded `{rounded.md}`. +- "I already have an account", "Continue", "Cancel" — second-tier actions paired with the red primary. +- Pressed state lives in `button-secondary-pressed` — background drops to `{colors.secondary-pressed}`. -**Circular Action** -- Background: `#e0e0d9` (warm light) -- Text: `#211922` (plum black) -- Radius: 50% (circle) -- Use: Pin actions, navigation controls +**`button-tertiary`** — ghost link +- Background transparent, text `{colors.ink}`, type `{typography.button-md}`, rounded `{rounded.md}`. +- Used for low-emphasis actions inside dialogs ("Read the docs", "Learn more →" with a small chevron). -**Ghost / Transparent** -- Background: transparent -- Text: `#000000` -- No border -- Use: Tertiary actions +**`button-icon-circular`** — circular icon button +- Background `{colors.surface-card}`, icon `{colors.ink}`, rounded `{rounded.full}`, size 40px. +- Carousel paddles, modal close button, and small floating action buttons in pin imagery. + +**`button-pill-on-image`** — small overlay pill on photography +- Background `{colors.canvas}`, text `{colors.ink}`, type `{typography.button-md}`, rounded `{rounded.full}`, padding `8px 14px`. +- The signature "Cherry red" / "Preppy look" / "Earthy space inspo" overlay pill that anchors the corner of category-tile pin imagery. + +**`button-disabled`** +- Background `{colors.surface-card}`, text `{colors.ash}` — flat soft-cream. + +### Filter & Tab Chips + +**`filter-chip`** + **`filter-chip-active`** +- Default: background `{colors.surface-card}`, text `{colors.ink}`, type `{typography.button-md}`, rounded `{rounded.full}`, padding `8px 16px`. +- Active: background `{colors.ink}`, text `{colors.on-dark}` — the chip flips fully inverted on selection. +- Used across the search results page filter strip ("Beauty makeup", "Lipstick", "Editorial makeup"...). + +### Inputs & Forms + +**`text-input`** + **`text-input-focused`** +- Default: background `{colors.canvas}`, text `{colors.ink}`, 1px solid `{colors.ash}`, type `{typography.body-md}`, padding `11px 15px`, height ~44px, rounded `{rounded.md}`. +- Focused: 2px `{colors.ink}` inner border + 4px `{colors.focus-outer}` outer outline — the signature double-ring focus signal. +- Used across the login/signup modal for email, password, birthdate, country fields. + +**`search-bar`** + **`search-bar-focused`** +- Default: background `{colors.surface-card}`, text `{colors.ink}`, type `{typography.body-md}`, padding `11px 15px`, height ~48px, rounded `{rounded.full}`. +- Focused: same dimensions, background flips to `{colors.canvas}` with a 1px `{colors.ash}` border. +- Anchored in the center of the primary nav with a magnifier glyph at the left edge and "Search for ideas, fashion..." placeholder. ### Cards & Containers -- Photography-first pin cards with generous radius (12px–20px) -- No traditional box-shadow on most cards -- White or warm fog backgrounds -- 8px white thick border on some image containers -### Inputs -- Email input: white background, `1px solid #91918c` border, 16px radius, 11px 15px padding -- Focus: semantic border + outline system via CSS variables +**`pin-card`** — the standard masonry pin tile +- Container: background `{colors.surface-card}`, rounded `{rounded.md}` (16px), padding 0. +- Layout: full-bleed image at the card's natural aspect ratio with no internal padding. Optional `{component.pin-overlay-pill}` anchored to one corner of the image, optional 32px circular avatar with profile name in `{typography.body-sm-strong}` overlaid at the bottom-left. + +**`pin-card-large`** — the home-page feature pin +- Identical to `pin-card` but rounded `{rounded.lg}` (32px) — used for the large editorial pins that anchor home-page feature rows. + +**`pin-overlay-pill`** — anchored chip on pin imagery +- Background `{colors.canvas}`, text `{colors.ink}`, type `{typography.button-sm}`, rounded `{rounded.full}`, padding `6px 12px`. +- Floats over a pin's bottom-left or top-left corner with the search-term label that surfaces if the pin matches a search ("Cherry red", "Preppy look", "Earthy space inspo"). + +**`category-tile`** +- Background `{colors.surface-card}`, rounded `{rounded.md}`, padding 16px. +- 3- or 4-up grid of small category thumbnails inside the home-page "Bring your favorite ideas to life" section. Each tile contains a category icon or composition photograph + a short label in `{typography.body-strong}`. + +**`feature-card`** + **`feature-card-soft`** +- Standard: background `{colors.canvas}`, rounded `{rounded.md}`, padding 32px. Pairs a 4:5 portrait pin image (left or right) with a `{typography.heading-xl}` headline + body copy + `{component.button-primary}` red CTA. +- Soft: background `{colors.surface-card}` for the alternating-row variant where the cream surface is needed to break up content. + +**`modal-card`** — login/signup overlay +- Background `{colors.canvas}`, rounded `{rounded.lg}` (32px), padding 32px. +- Layout: title in `{typography.heading-lg}` ("Welcome to Pinterest"), subtitle in `{typography.body-md}`, stacked `{component.text-input}` fields (Email, Password, Birthdate, Country), primary `{component.button-primary}` "Continue", small "Already a member? Log in" link below. +- Floats over a 50%-opacity scrim covering the entire page content with a 16px ambient shadow. + +**`hero-cta-strip`** — dark CTA strip on `create.pinterest.com` +- Background `{colors.surface-dark}`, text `{colors.on-dark}`, type `{typography.heading-xl}`, padding `48px 32px`, rounded `{rounded.none}`. +- Sits at the top of the creator marketing page with a single `{component.button-primary}` red CTA on the right. ### Navigation -- Clean header on white or warm background -- Pinterest logo + search bar centered -- Pin Sans 16px for nav links -- Pinterest Red accents for active states -### Image Treatment -- Pin-style masonry grid (signature Pinterest layout) -- Rounded corners: 12px–20px on images -- Photography as primary content — every pin is an image -- Thick white borders (8px) on featured image containers +**`primary-nav`** +- Background `{colors.canvas}`, text `{colors.ink}`, height ~64px, type `{typography.body-strong}`, rounded `{rounded.none}`, with a 1px `{colors.hairline}` bottom rule on inner pages (no rule on the home hero). +- Layout (desktop home): Pinterest red wordmark at left + "Explore" link, centered `{component.search-bar}`, right cluster ("About / Businesses / Create / Log in" + the always-red `{component.button-primary}` "Sign up" CTA). +- Layout (search results): Pinterest red P-logo at left, centered search bar with the active query, right cluster ("Log in" + red Sign-up button). -## 5. Layout Principles +**Top Nav (Mobile)** +- Hamburger menu icon at left, P-logo at center, search-glyph + Sign-up CTA at right. Search bar collapses into the magnifier icon and expands to full-width when tapped. -### Spacing System -- Base unit: 8px -- Scale: 4px, 6px, 7px, 8px, 10px, 11px, 12px, 16px, 18px, 20px, 22px, 24px, 32px, 80px, 100px -- Large jumps: 32px → 80px → 100px for section spacing +### Footer -### Grid & Container -- Masonry grid for pin content (signature layout) -- Centered content sections with generous max-width -- Full-width dark footer -- Search bar as primary navigation element +**`footer-section`** +- Background `{colors.canvas}`, text `{colors.mute}` in `{typography.body-sm}`, padding `32px 24px`, rounded `{rounded.none}`, with a 1px `{colors.hairline}` top rule. +- Layout: 4-column link grid (Get the app — iOS / Android · Quick Links — Explore / Shop / Users / Collections / Shopping · Pinterest for · About — Privacy / Terms / Help Center) with column headers in `{typography.body-sm-strong}` and link lists in `{typography.body-sm}` `{colors.mute}`. +- Bottom row: Pinterest red wordmark + "© 2026 Pinterest" in `{typography.caption-sm}` `{colors.mute}`. -### Whitespace Philosophy -- **Inspiration density**: The masonry grid packs pins tightly — the content density IS the value proposition. Whitespace exists between sections, not within the grid. -- **Breathing above, density below**: Hero/feature sections get generous padding; the pin grid is compact and immersive. +### Inline -### Border Radius Scale -- Standard (12px): Small cards, links -- Button (16px): Buttons, inputs, medium cards -- Comfortable (20px): Feature cards -- Large (28px): Large containers -- Section (32px): Tab elements, large panels -- Hero (40px): Hero containers, large feature blocks -- Circle (50%): Action buttons, tab indicators +**`link-inline`** — body-prose anchor link +- `{colors.ink-soft}` text with no underline by default. Pinterest's only "color" beyond brand red on chrome — a near-black warm tint used inline to differentiate links from body without color contrast. -## 6. Depth & Elevation - -| Level | Treatment | Use | -|-------|-----------|-----| -| Flat (Level 0) | No shadow | Default — pins rely on content, not shadow | -| Subtle (Level 1) | Minimal shadow (from tokens) | Elevated overlays, dropdowns | -| Focus (Accessibility) | `--sema-color-border-focus-outer-default` ring | Focus states | - -**Shadow Philosophy**: Pinterest uses minimal shadows. The masonry grid relies on content (photography) to create visual interest rather than elevation effects. Depth comes from the warmth of surface colors and the generous rounding of containers. - -## 7. Do's and Don'ts +## Do's and Don'ts ### Do -- Use warm neutrals (`#e5e5e0`, `#e0e0d9`, `#91918c`) — the warm olive/sand tone is the identity -- Apply Pinterest Red (`#e60023`) only for primary CTAs — it's bold and singular -- Use Pin Sans exclusively — one font for everything -- Apply generous border-radius: 16px for buttons/inputs, 20px+ for cards -- Keep the masonry grid dense — content density is the value -- Use warm badge backgrounds (`hsla(60,20%,98%,.5)`) for subtle warm washes -- Use `#211922` (plum black) for primary text — it's warmer than pure black +- Reserve `{colors.primary}` (Pinterest Red) for primary CTAs, the active-tab indicator, and the brand wordmark only. It is never decorative. +- Use `{rounded.md}` (16px) on every interactive element and standard card; reserve `{rounded.lg}` (32px) for large pin cards and modals; reserve `{rounded.full}` for circular elements (search bar, chips, avatars). +- Stage every pin image inside a `{component.pin-card}` with no internal padding — the photograph IS the card. +- Stack content sections at `{spacing.section}` (64px) rhythm; tighten pin grids to `{spacing.sm}` (8px) gutters so imagery effectively touches. +- Use `{component.pin-overlay-pill}` to anchor a search-term tag in the corner of a category-tile pin photograph — the system's signature decorative gesture. +- Build hierarchy from font weight (400 → 600 → 700) and size, not from color tinting. Body stays `{colors.body}` regardless of section context. +- Apply -1.2px letter-spacing on `{typography.display-xl}` and `{typography.heading-xl}`. The negative tracking is part of the brand voice. ### Don't -- Don't use cool gray neutrals — always warm/olive-toned -- Don't use pure black (`#000000`) as primary text — use plum black (`#211922`) -- Don't use pill-shaped buttons — 16px radius is rounded but not pill -- Don't add heavy shadows — Pinterest is flat by design, depth from content -- Don't use small border-radius (<12px) on cards — the generous rounding is core -- Don't introduce additional brand colors — red + warm neutrals is the complete palette -- Don't use thin font weights — Pin Sans at 400 minimum +- Don't use sharp-cornered buttons or cards. There are no `{rounded.none}` interactive elements in the system. +- Don't introduce drop shadows on cards. The only shadow in the system is the 16px ambient under `{component.modal-card}`. +- Don't pad `{component.pin-card}` internally. The image is full-bleed; metadata sits over the image as an overlay pill, not below it. +- Don't replace `{colors.primary}` with another red. The brand red is precise — `#e60023`. +- Don't use `{colors.ink-soft}` (the body-prose link tint) outside of inline body anchor links. It is not a chrome color. +- Don't introduce a third radius value between 16px and 32px. The system jumps directly from md to lg with nothing in between. -## 8. Responsive Behavior +## Responsive Behavior ### Breakpoints + | Name | Width | Key Changes | -|------|-------|-------------| -| Mobile | <576px | Single column, compact layout | -| Mobile Large | 576–768px | 2-column pin grid | -| Tablet | 768–890px | Expanded grid | -| Desktop Small | 890–1312px | Standard masonry grid | -| Desktop | 1312–1440px | Full layout | -| Large Desktop | 1440–1680px | Expanded grid columns | -| Ultra-wide | >1680px | Maximum grid density | +|---|---|---| +| ultrawide | 1920px+ | Pin grid expands to 5–6 columns; content max-width holds at ~1280px | +| desktop-large | 1440px | Default — 4-column pin grid, full primary nav | +| desktop | 1280px | Same layout with narrower outer gutters | +| desktop-small | 1024px | Pin grid collapses to 3 columns; sub-nav remains horizontal | +| tablet | 768px | Pin grid collapses to 2 columns; primary nav becomes hamburger drawer; search bar becomes icon-only | +| mobile | 480px | Single-column pin grid; hero `{typography.display-xl}` scales 70px → ~44px | +| mobile-narrow | 320px | Hero further scales to ~36px; section padding tightens to 32px | + +### Touch Targets +All interactive elements meet WCAG AA (≥ 44×44px). `{component.button-primary}` and `{component.button-secondary}` sit at ~40px height with 14px horizontal padding (effective ~40×80px tappable). `{component.search-bar}` sits at 48px. `{component.text-input}` sits at 44px. `{component.filter-chip}` is ~36–40px height with 16px padding — extends to 44px tappable via inline padding. `{component.button-icon-circular}` is exactly 40×40 with extended hit-target padding to 48×48 inside the parent. ### Collapsing Strategy -- Pin grid: 5+ columns → 3 → 2 → 1 -- Navigation: search bar + icons → simplified mobile nav -- Feature sections: side-by-side → stacked -- Hero: 70px → scales down proportionally -- Footer: dark multi-column → stacked +- **Primary nav:** desktop horizontal cluster → tablet hamburger drawer at 768px. The red Sign-up CTA stays visible at every breakpoint. +- **Search bar:** desktop centered (~480px wide) → tablet compressed (~320px) → mobile collapses to a magnifier icon that expands to a full-width overlay on tap. +- **Pin masonry grid:** 5/6-up → 4-up → 3-up → 2-up → 1-up at 1920, 1024, 768, and 480px. Gutters drop from 8px to 6px on mobile. +- **Home feature row:** desktop alternating left/right 2-column → tablet vertical stack with text above image → mobile single-column with full-bleed image. +- **Modal:** desktop centered ~480px-wide card → mobile full-width sheet with rounded `{rounded.lg}` top-only and bottom-anchored CTA. +- **Section padding:** `{spacing.section}` (64px) desktop → 48px tablet → 32px mobile. +- **Hero headline:** `{typography.display-xl}` (70px) at desktop, scaling 56px / 44px / 36px down the breakpoint stack. +- **Footer:** 4-up link columns → 2-up at tablet → full accordion at mobile (each header becomes a tap-to-expand row). -## 9. Agent Prompt Guide +### Image Behavior +- Pin imagery preserves natural aspect ratio at every breakpoint; the column count changes, not the aspect. +- Category tile thumbnails maintain 1:1 across all sizes. +- Hero feature imagery uses art-direction crops on mobile (4:5 portrait → square) so the subject stays centered when the layout collapses to single-column. +- All non-critical imagery is lazy-loaded as the user scrolls into the next grid row. -### Quick Color Reference -- Brand: Pinterest Red (`#e60023`) -- Background: White (`#ffffff`) -- Text: Plum Black (`#211922`) -- Secondary text: Olive Gray (`#62625b`) -- Button surface: Sand Gray (`#e5e5e0`) -- Border: Warm Silver (`#91918c`) -- Focus: Focus Blue (`#435ee5`) +## Iteration Guide -### Example Component Prompts -- "Create a hero: white background. Headline at 70px Pin Sans weight 600, plum black (#211922). Red CTA button (#e60023, 16px radius, 6px 14px padding). Secondary sand button (#e5e5e0, 16px radius)." -- "Design a pin card: white background, 16px radius, no shadow. Photography fills top, 16px Pin Sans weight 400 description below in #62625b." -- "Build a circular action button: #e0e0d9 background, 50% radius, #211922 icon." -- "Create an input field: white background, 1px solid #91918c, 16px radius, 11px 15px padding. Focus: blue outline via semantic tokens." -- "Design the dark footer: #33332e background. Pinterest script logo in white. 12px Pin Sans links in #91918c." +1. 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}`; reach for `{typography.body-strong}` for emphasis; reserve `{typography.display-xl}` strictly for top-of-page hero headlines. +6. Keep `{colors.primary}` scarce — at most one Pinterest-red CTA per fold (counting nav, hero, and feature-card CTAs together). +7. When introducing a new component, ask whether it can be expressed with the existing pin-card + 16px-radius + cream-surface vocabulary before adding new tokens. The system's strength is that it almost never needs new ones. -### Iteration Guide -1. Warm neutrals everywhere — olive/sand grays, never cool steel -2. Pinterest Red for CTAs only — bold and singular -3. 16px radius on buttons/inputs, 20px+ on cards — generous but not pill -4. Pin Sans is the only font — compact at 12px for UI, 70px for display -5. Photography carries the design — the UI stays warm and minimal -6. Plum black (#211922) for text — warmer than pure black +## Known Gaps + +- **Mobile screenshots not captured** — responsive behavior synthesizes Pinterest's known mobile pattern (hamburger drawer, single-column grid, hero downscale) from desktop evidence and the documented breakpoint stack. +- **Hover states not documented** by system policy. +- **Pin-detail close-up (single pin overlay)** is not in the captured set — the in-product Pin detail view (with comments, related pins, save board picker) likely introduces components not documented here. +- **Authenticated chrome** (logged-in home feed, board pages, profile pages) not in the captured pages — the captured surfaces are the logged-out marketing and search experience. +- **Pinterest mobile app screens** not in the system documented here — this is the web-only chrome. +- **Form validation states** (success / error inline messages) not documented; only the focused-state field is captured. diff --git a/design-md/playstation/DESIGN.md b/design-md/playstation/DESIGN.md index 13759b8..16abcbd 100644 --- a/design-md/playstation/DESIGN.md +++ b/design-md/playstation/DESIGN.md @@ -1,364 +1,661 @@ -# Design System Inspired by PlayStation +--- +version: alpha +name: PlayStation +description: | + A three-surface marketing system organized around alternating black, white, and PlayStation Blue chapters that scroll past the viewer like a console launch trailer. Each section has a single editorial purpose — hero photography, console product render, PS Plus tier callout, news strip — and each owns one of three full-bleed canvas modes. The chrome is unusually quiet for a gaming brand: bright PlayStation Blue (`#0070d1`) carries every primary CTA as a fully-rounded pill, the proprietary SST face renders display copy at a signature weight 300 (light) for an airy, premium feel, and a crisp 8px-radius secondary card system carries product info on either canvas mode. The system never decorates — no gradient backgrounds on chrome, no atmospheric mesh, no drop shadows beyond a faint section-divide. Imagery does all the heavy lifting: console glamour shots, game key art, and PS Plus tier illustrations occupy 60-90% of every section, with copy compressed into a small editorial slot. -## 1. Visual Theme & Atmosphere +colors: + primary: "#0070d1" + primary-pressed: "#0064b7" + primary-active: "#004d8d" + on-primary: "#ffffff" + link-light: "#0064b7" + link-dark: "#53b1ff" + commerce: "#d53b00" + commerce-pressed: "#aa2f00" + commerce-link-base: "#d63d00" + on-commerce: "#ffffff" + ink: "#000000" + ink-deep: "#121314" + ink-elevated: "#181818" + charcoal: "#1f2024" + body-light: "rgba(0,0,0,0.6)" + mute-light: "#6b6b6b" + ash-light: "#cccccc" + body-dark: "rgba(255,255,255,0.7)" + mute-dark: "rgba(229,229,229,0.55)" + ash-dark: "rgba(229,229,229,0.2)" + canvas-light: "#ffffff" + surface-soft: "#f3f3f3" + surface-card: "#f5f7fa" + surface-filter: "rgba(245,247,250,0.3)" + canvas-dark: "#000000" + surface-dark-elevated: "#121314" + surface-dark-card: "#181818" + hairline-light: "#f3f3f3" + hairline-dark: "rgba(229,229,229,0.2)" + on-dark: "#ffffff" + on-dark-mute: "#cccccc" + warning: "#c81b3a" + ps-plus-gold-start: "#ffce21" + ps-plus-gold-mid: "#f5a623" + ps-plus-gold-end: "#ee8e00" + marathon-yellow: "#deff20" -PlayStation.com carries itself like the marketing wing of a premium consumer-electronics brand that happens to sell entertainment. The page is organized as a **vertical channel of alternating surfaces**: a near-black masthead and hero, a sequence of paper-white editorial panels in the middle, and a deep cobalt-blue footer that anchors the entire experience. Between those surface modes the site leans hard on photography and 3D product renders — the PS5 console, game cover art, DualSense controllers — letting the hardware do the emotional work while the chrome stays restrained. +typography: + display-xl: + fontFamily: PlayStation SST + fontSize: 54px + fontWeight: 300 + lineHeight: 1.25 + letterSpacing: -0.1px + display-lg: + fontFamily: PlayStation SST + fontSize: 44px + fontWeight: 300 + lineHeight: 1.25 + letterSpacing: 0.1px + display-md: + fontFamily: PlayStation SST + fontSize: 35px + fontWeight: 300 + lineHeight: 1.25 + letterSpacing: 0 + heading-xl: + fontFamily: PlayStation SST + fontSize: 28px + fontWeight: 300 + lineHeight: 1.25 + letterSpacing: 0.1px + heading-lg: + fontFamily: PlayStation SST + fontSize: 22px + fontWeight: 300 + lineHeight: 1.25 + letterSpacing: 0.1px + heading-md: + fontFamily: PlayStation SST + fontSize: 18px + fontWeight: 600 + lineHeight: 1 + letterSpacing: 0 + body-md: + fontFamily: PlayStation SST + fontSize: 18px + fontWeight: 400 + lineHeight: 1.5 + letterSpacing: 0.1px + body-strong: + fontFamily: PlayStation SST + fontSize: 18px + fontWeight: 500 + lineHeight: 1.25 + letterSpacing: 0.4px + body-sm: + fontFamily: PlayStation SST + fontSize: 16px + fontWeight: 400 + lineHeight: 1.5 + letterSpacing: 0 + caption-md: + fontFamily: PlayStation SST + fontSize: 14px + fontWeight: 400 + lineHeight: 1.5 + letterSpacing: 0 + caption-sm: + fontFamily: PlayStation SST + fontSize: 12px + fontWeight: 500 + lineHeight: 1.5 + letterSpacing: 0 + link-md: + fontFamily: PlayStation SST + fontSize: 18px + fontWeight: 400 + lineHeight: 1.5 + letterSpacing: 0 + button-lg: + fontFamily: PlayStation SST + fontSize: 18px + fontWeight: 700 + lineHeight: 1.25 + letterSpacing: 0.45px + button-md: + fontFamily: PlayStation SST + fontSize: 14px + fontWeight: 700 + lineHeight: 1.25 + letterSpacing: 0.324px -The signature typographic move is **SST Light (weight 300) at large sizes**. Sony's custom SST family is used from 22px up to 54px in weight 300, giving display headlines a whispered, elegant quality that feels closer to a luxury watch ad than a game store. That "quiet authority" is the exact opposite of The Verge's Manuka shout or Wired's newsstand density — PlayStation wants the type to recede and the product to lead. Body and UI lean on weights 500–700, but the *display* voice is consistently thin and calm. +rounded: + none: 0px + sm: 4px + md: 8px + lg: 16px + full: 9999px -The one place restraint breaks is **interaction**. Every primary button has the same hover move: fill swaps to an electric cyan `#1eaedb`, a 2px white border appears, a 2px PlayStation-blue outer ring blooms behind it, and the entire button **scales up 1.2×**. That combination of color pop, border, ring, and lift-scale is a signature move unique to Sony among major brands — a miniature "power-on" animation that the site repeats hundreds of times across a single page. +spacing: + xxs: 4px + xs: 8px + sm: 12px + md: 16px + lg: 24px + xl: 32px + xxl: 48px + section: 96px + +components: + button-primary: + backgroundColor: "{colors.primary}" + textColor: "{colors.on-primary}" + typography: "{typography.button-lg}" + rounded: "{rounded.full}" + padding: 12px 28px + height: 48px + button-primary-pressed: + backgroundColor: "{colors.primary-pressed}" + textColor: "{colors.on-primary}" + typography: "{typography.button-lg}" + rounded: "{rounded.full}" + button-commerce: + backgroundColor: "{colors.commerce}" + textColor: "{colors.on-commerce}" + typography: "{typography.button-lg}" + rounded: "{rounded.full}" + padding: 12px 28px + height: 48px + button-commerce-pressed: + backgroundColor: "{colors.commerce-pressed}" + textColor: "{colors.on-commerce}" + typography: "{typography.button-lg}" + rounded: "{rounded.full}" + button-secondary-light: + backgroundColor: "transparent" + textColor: "{colors.ink}" + typography: "{typography.button-lg}" + rounded: "{rounded.full}" + padding: 12px 28px + height: 48px + button-secondary-dark: + backgroundColor: "transparent" + textColor: "{colors.on-dark}" + typography: "{typography.button-lg}" + rounded: "{rounded.full}" + padding: 12px 28px + height: 48px + button-disabled: + backgroundColor: "{colors.surface-soft}" + textColor: "{colors.ash-light}" + rounded: "{rounded.full}" + text-input: + backgroundColor: "{colors.canvas-light}" + textColor: "{colors.ink}" + typography: "{typography.body-md}" + rounded: "{rounded.sm}" + padding: 12px 16px + height: 48px + text-input-focused: + backgroundColor: "{colors.canvas-light}" + textColor: "{colors.ink}" + rounded: "{rounded.sm}" + filter-pill: + backgroundColor: "{colors.surface-filter}" + textColor: "{colors.ink}" + typography: "{typography.button-md}" + rounded: "{rounded.full}" + padding: 8px 16px + filter-pill-active: + backgroundColor: "{colors.canvas-light}" + textColor: "{colors.ink}" + typography: "{typography.button-md}" + rounded: "{rounded.full}" + product-card: + backgroundColor: "{colors.surface-card}" + textColor: "{colors.ink}" + typography: "{typography.body-md}" + rounded: "{rounded.md}" + padding: 24px + product-card-dark: + backgroundColor: "{colors.surface-dark-card}" + textColor: "{colors.on-dark}" + typography: "{typography.body-md}" + rounded: "{rounded.md}" + padding: 24px + game-tile: + backgroundColor: "{colors.surface-dark-elevated}" + textColor: "{colors.on-dark}" + typography: "{typography.body-sm}" + rounded: "{rounded.md}" + padding: 0px + feature-card: + backgroundColor: "{colors.canvas-light}" + textColor: "{colors.ink}" + typography: "{typography.body-md}" + rounded: "{rounded.md}" + padding: 32px + hero-band-blue: + backgroundColor: "{colors.primary}" + textColor: "{colors.on-primary}" + typography: "{typography.display-md}" + rounded: "{rounded.none}" + padding: 96px 48px + hero-band-dark: + backgroundColor: "{colors.canvas-dark}" + textColor: "{colors.on-dark}" + typography: "{typography.display-xl}" + rounded: "{rounded.none}" + padding: 96px 48px + hero-band-light: + backgroundColor: "{colors.canvas-light}" + textColor: "{colors.ink}" + typography: "{typography.display-xl}" + rounded: "{rounded.none}" + padding: 96px 48px + ps-plus-banner: + backgroundColor: "{colors.surface-dark-elevated}" + textColor: "{colors.on-dark}" + typography: "{typography.heading-xl}" + rounded: "{rounded.md}" + padding: 48px 32px + carousel-paddle: + backgroundColor: "rgba(255,255,255,0.16)" + textColor: "{colors.on-dark}" + rounded: "{rounded.full}" + size: 48px + pagination-dot: + backgroundColor: "{colors.ash-dark}" + rounded: "{rounded.full}" + size: 8px + pagination-dot-active: + backgroundColor: "{colors.on-dark}" + rounded: "{rounded.full}" + size: 8px + badge-info: + backgroundColor: "{colors.primary}" + textColor: "{colors.on-primary}" + typography: "{typography.caption-sm}" + rounded: "{rounded.full}" + padding: 4px 10px + primary-nav: + backgroundColor: "{colors.canvas-dark}" + textColor: "{colors.on-dark}" + typography: "{typography.body-strong}" + rounded: "{rounded.none}" + height: 48px + sub-nav: + backgroundColor: "{colors.canvas-dark}" + textColor: "{colors.on-dark}" + typography: "{typography.caption-md}" + rounded: "{rounded.none}" + height: 40px + footer-section: + backgroundColor: "{colors.primary}" + textColor: "{colors.on-primary}" + typography: "{typography.caption-md}" + rounded: "{rounded.none}" + padding: 48px 32px + support-search-bar: + backgroundColor: "{colors.canvas-light}" + textColor: "{colors.ink}" + typography: "{typography.body-md}" + rounded: "{rounded.full}" + padding: 12px 24px + height: 56px + support-row: + backgroundColor: "{colors.canvas-light}" + textColor: "{colors.ink}" + typography: "{typography.body-md}" + rounded: "{rounded.none}" + padding: 16px 0px + link-inline: + textColor: "{colors.link-light}" + typography: "{typography.link-md}" +--- + +## Overview + +PlayStation's marketing system reads like a console launch trailer scrolling past the viewer in chapters. Each section is a full-bleed band — pure black `{colors.canvas-dark}`, true white `{colors.canvas-light}`, or PlayStation Blue `{colors.primary}` — and each chapter owns one editorial moment: hero console photography, a games-coming-soon strip, the PlayStation Plus tier banner, the "30 Years of PlayStation" anniversary band, the news strip from the PlayStation Blog. There is no decorative chrome between chapters; the section background change IS the divider. Sections stack at `{spacing.section}` (96px) rhythm with the next band's color taking over the page edge-to-edge. + +The system has two distinct surface modes that alternate down the page: a **dark canvas mode** for editorial product moments (hero, "ON PLAYSTATION" band, marathon game pages) and a **light canvas mode** for utility surfaces (PS5 games listing, support pages, news index). Both modes use the same chrome vocabulary — fully-rounded `{rounded.full}` pill buttons, 8px-radius `{rounded.md}` cards, the proprietary PlayStation SST face — only the surface and on-surface colors change. The third surface mode is the **PlayStation Blue band** (`{colors.primary}` — `#0070d1`) reserved for the highest-priority moments: the Marathon launch CTA strip, the footer, and any "Action Required" banner. + +The typography is the system's most distinctive choice. PlayStation SST renders display headlines at **weight 300** (light) — unusual for a gaming brand that could easily reach for bold geometric display faces. The light weight gives the chrome an airy, almost editorial quality that lets the imagery speak; copy is information rather than decoration. Heading sizes drop in tight increments (54 → 44 → 35 → 28 → 22 → 18) and body settles at 18px with 1.5 line-height for comfortable long-form reading on support and games pages. **Key Characteristics:** -- Three-surface channel layout: near-black hero, paper-white content, cobalt-blue footer — alternating, never blending -- SST weight 300 at 22–54px for display — "quiet authority" headlines that let product photography lead -- PlayStation Blue `#0070cc` as the brand anchor; cyan `#1eaedb` reserved exclusively for hover/focus states -- Every interactive element scales 1.2× on hover — a signature "power-on" lift unique to PlayStation -- Pill buttons at full 999px radius; card art in rounded 12–24px rectangles -- Commerce-orange `#d53b00` used exclusively for PlayStation Store / buy-state CTAs -- Wide breakpoint coverage up to 2120px — the site scales all the way to 4K-TV browsing contexts +- Three-canvas chapter system: `{colors.canvas-dark}` (black), `{colors.canvas-light}` (white), `{colors.primary}` (PlayStation Blue) alternating down the page +- PlayStation Blue (`{colors.primary}` — `#0070d1`) is the universal primary CTA — fully-rounded pill at `{rounded.full}` (9999px) +- Commerce orange (`{colors.commerce}` — `#d53b00`) is the secondary CTA reserved for "Buy now" / "Pre-order" / store actions +- PlayStation SST display tier renders at **weight 300** with -0.1px to +0.4px tracking — the brand's signature airy editorial voice +- 8px-radius (`{rounded.md}`) for product cards and feature panels; 4px-radius (`{rounded.sm}`) for inputs; pills (`{rounded.full}`) for every CTA +- Game tiles, console renders, and PS Plus tier illustrations occupy 60-90% of each section — imagery does the storytelling +- Color-block page rhythm (one observed band sequence): dark hero → light console showcase → dark "Great PS4 & PS5 games" rail → light "Discover PlayStation Plus" tier band → light "30 years of PlayStation" callout → dark "ON PLAYSTATION" band → light news strip → blue footer -## 2. Color Palette & Roles +## Colors -### Primary (Brand Anchor) -- **PlayStation Blue** (`#0070cc`): The brand's anchor color. Used on the primary footer, inline links, primary button fills on dark surfaces, and every "official" marker. Treat this as immovable — it is the color the brand is most associated with in consumer memory. -- **Console Black** (`#000000`): Pure black for the masthead, hero backdrops, and product presentation zones. PlayStation uses black to frame hardware the way a museum uses black to frame a sculpture. +> **Source pages:** `/en-tr/` (home), `/en-tr/ps5/games/` (PS5 games listing), `/en-tr/games/marathon/` (single game page), `/tr-tr/support/account/` (support center). The chrome palette is identical across all four pages; the support page uses the light-canvas mode exclusively while marketing pages alternate. -### Secondary & Accent -- **PlayStation Cyan** (`#1eaedb`): The interaction color. Applied ONLY to hover, focus, and active states of buttons and links. Never appears as a default background or a text color at rest. Pair with a 2px `#ffffff` border and a 2px `#0070cc` outer ring on hover for the full signature treatment. -- **Link Hover Blue** (`#1883fd`): The brighter variant used on inline text-link hovers. Distinct from Cyan — this is the link color, Cyan is the button color. -- **Dark Link Blue** (`#0068bd`): The link color at rest on light surfaces — a slightly more saturated cousin of the brand blue. +### Brand & Accent +- **PlayStation Blue** (`{colors.primary}` — `#0070d1`): the brand's universal primary. Every primary CTA pill, the active filter chip, the footer surface, badge fills, and inline link color on dark surfaces. +- **PlayStation Blue Pressed** (`{colors.primary-pressed}` — `#0064b7`): pressed state for the primary pill — also doubles as the inline link color on light surfaces. +- **PlayStation Blue Active** (`{colors.primary-active}` — `#004d8d`): deeply-pressed state for the primary button. +- **Commerce Orange** (`{colors.commerce}` — `#d53b00`): the secondary CTA reserved for store/buy/pre-order actions. The only warm color in the system. +- **Commerce Orange Pressed** (`{colors.commerce-pressed}` — `#aa2f00`): pressed state for commerce buttons. +- **Marathon Yellow** (`{colors.marathon-yellow}` — `#deff20`): a single high-saturation game-page accent extracted from Marathon's product palette — used only inside the dedicated `/marathon/` game page chrome and not part of the system's general accent vocabulary. -### Surface & Background -- **Paper White** (`#ffffff`): Primary content canvas for editorial panels between the masthead and footer. -- **Ice Mist** (`#f5f7fa`): The atmospheric end-stop of the light section-gradient. Used subtly behind certain panels to lift them off pure white. -- **Divider Tint** (`#f3f3f3`): The quiet horizontal-rule color between content rows. -- **Masthead Black** (`#000000`): Top nav and hero canvas — reserved for product-forward zones. -- **Shadow Black** (`#121314`): The starting anchor of the dark section-gradient when a panel needs atmospheric depth. -- **Filter Mist** (`rgba(245, 247, 250, 0.3)`): Translucent background used behind sticky filter bars — the only "glassmorphism" moment on the site. +### Surface +- **Canvas Dark** (`{colors.canvas-dark}` — `#000000`): pure black hero band, primary nav background, footer base. The dominant surface for editorial product moments. +- **Surface Dark Elevated** (`{colors.surface-dark-elevated}` — `#121314`): inset dark panels, PS Plus tier banner background, "ON PLAYSTATION" gradient end. +- **Surface Dark Card** (`{colors.surface-dark-card}` — `#181818`): game tile fill, dark product card background. +- **Canvas Light** (`{colors.canvas-light}` — `#ffffff`): true white console-showcase band, support page body, news strip background. +- **Soft Surface** (`{colors.surface-soft}` — `#f3f3f3`): hairline-soft band fill on light pages, divider rule on light surfaces. +- **Surface Card** (`{colors.surface-card}` — `#f5f7fa`): cool-blue-tinted product card and tier-card background on light canvas. +- **Surface Filter** (`{colors.surface-filter}` — `rgba(245,247,250,0.3)`): translucent fill for filter-pill default state on light canvas. +- **Hairline Light** (`{colors.hairline-light}` — `#f3f3f3`): 1px divider rule on light pages. +- **Hairline Dark** (`{colors.hairline-dark}` — `rgba(229,229,229,0.2)`): translucent 1px divider on dark canvas. -### Neutrals & Text -- **Display Ink** (`#000000`): Primary display headlines on white surfaces. -- **Deep Charcoal** (`#1f1f1f`): Body headlines and link color at rest — slightly softer than pure black to reduce visual ring on large blocks. -- **Body Gray** (`#6b6b6b`): Secondary body text and metadata. -- **Mute Gray** (`#cccccc`): Tertiary labels, disabled states. -- **Placeholder Ink** (`rgba(0, 0, 0, 0.6)`): Form placeholder text — 60% black, not a separate gray value. -- **Inverse White** (`#ffffff`): Primary text on dark and blue surfaces. -- **Dark-Link Blue** (`#53b1ff`): The link color at rest on dark/black surfaces — a lighter airborne variant of PlayStation Blue for legibility on black. +### Text +- **Ink** (`{colors.ink}` — `#000000`): primary text on `{colors.canvas-light}`. Headlines, button text, support body. +- **Ink Deep** (`{colors.ink-deep}` — `#121314`): warmer near-black for in-card titles on dark surfaces and deep-shadow gradients. +- **Ink Elevated** (`{colors.ink-elevated}` — `#181818`): the lightest of the dark-canvas inks, used for elevated card backgrounds. +- **Body Light** (`{colors.body-light}` — `rgba(0,0,0,0.6)`): translucent body text on light canvas — the system's default paragraph color. +- **Mute Light** (`{colors.mute-light}` — `#6b6b6b`): metadata text and footer link captions on light canvas. +- **Ash Light** (`{colors.ash-light}` — `#cccccc`): disabled-state text and lowest-emphasis utility on light surfaces. +- **On Dark** (`{colors.on-dark}` — `#ffffff`): primary text on `{colors.canvas-dark}` — headlines, button text on dark hero bands. +- **Body Dark** (`{colors.body-dark}` — `rgba(255,255,255,0.7)`): translucent body text on dark canvas. +- **On Dark Mute** (`{colors.on-dark-mute}` — `#cccccc`): secondary text and disabled state on dark surfaces. +- **Mute Dark** (`{colors.mute-dark}` — `rgba(229,229,229,0.55)`): captions and metadata on dark canvas. -### Semantic & Commerce -- **Commerce Orange** (`#d53b00`): Reserved for PlayStation Store buy-state CTAs, price callouts, and "on sale" badges. The only warm color on the site — use sparingly and never outside a commerce context. -- **Commerce Orange Active** (`#aa2f00`): The pressed/active state of commerce buttons. -- **Warning Red** (`#c81b3a`): Form errors and destructive-action warnings. -- **Shadow Wash 80** (`rgba(0, 0, 0, 0.8)`): The dramatic scrim used behind hero text on product photography. -- **Shadow Wash 16** (`rgba(0, 0, 0, 0.16)`): Low-weight elevation ring on cards. -- **Shadow Wash 08** (`rgba(0, 0, 0, 0.08)`): Featherweight card elevation — barely visible but separates white panels from white background. -- **Shadow Wash 06** (`rgba(0, 0, 0, 0.06)`): The lightest shadow in the system. +### Semantic +- **Warning** (`{colors.warning}` — `#c81b3a`): validation errors and destructive confirmation copy. +- **Link Light** (`{colors.link-light}` — `#0064b7`): inline body-prose anchor link on light canvas — same hex as `{colors.primary-pressed}`. +- **Link Dark** (`{colors.link-dark}` — `#53b1ff`): inline body-prose anchor link on dark canvas — a brightened blue for dark-mode legibility. -### Gradient System -PlayStation uses **two section gradients** and nothing else: -- **Light Section Gradient**: from `#ffffff` → `#f5f7fa` — an almost-imperceptible wash that quietly lifts a panel off the canvas. -- **Dark Section Gradient**: from `#121314` → `#000000` — a short vertical wash that gives hero panels a subtle vignette without introducing any hue shift. +### Brand Gradient +- **PlayStation Plus Gold Gradient** — a horizontal three-stop gold gradient `{colors.ps-plus-gold-start}` (`#ffce21`) → `{colors.ps-plus-gold-mid}` (`#f5a623`) → `{colors.ps-plus-gold-end}` (`#ee8e00`) that anchors the PS Plus banner on the home page. The only gradient in the system; reserved exclusively for PS Plus chrome. -Both gradients are used **only as section backgrounds**, never inside components. There are no gradient buttons, no gradient text, no glowing halos. The brand is blue — not blue-to-purple, not blue-to-cyan. - -## 3. Typography Rules +## Typography ### Font Family -- **SST** / **Playstation SST** (Sony, proprietary) — fallback: `Arial`, `Helvetica`. Sony's custom global typeface, designed by Toshi Omagari and Akira Kobayashi. Covers weights 300 / 500 / 600 / 700 across the homepage. The weight **300 at 22–54px** is PlayStation's typographic signature. -- **SST (condensed / alternate)** — fallback: `helvetica`, `arial`. A compressed variant used in a handful of UI modules where width matters. -- **Arial** — utility fallback for the rare button variant that renders in system sans. +- **PlayStation SST** is the proprietary brand sans-serif used across every text role on the site. It carries weights 300 (light), 400 (regular), 500 (medium), 600 (semibold), and 700 (bold), and falls back through `sst` → `Arial` → `Helvetica`. The brand's distinctive choice is using **weight 300 (light) for display headlines** — unusual for a gaming brand and the source of the system's editorial, airy character. +- **SST** appears as a secondary cut for in-product surfaces, falling back to Helvetica → Arial. ### Hierarchy -| Role | Font | Size | Weight | Line Height | Letter Spacing | Notes | -|---|---|---|---|---|---|---| -| Hero Display (XL) | SST | 54px / 3.38rem | 300 | 1.25 | -0.1px | The biggest SST moment on the page — quiet-weight luxury headline | -| Hero Display (L) | SST | 44px / 2.75rem | 300 | 1.25 | 0.1px | Secondary hero headlines | -| Large Display | SST | 35px / 2.20rem | 300 | 1.25 | — | Feature panel headlines | -| Mid Display | SST | 28px / 1.75rem | 300 | 1.25 | 0.1px | Section headings | -| Compact Display | SST | 22px / 1.38rem | 300 | 1.25 | 0.1px | Module titles — still in light weight 300 | -| Playstation SST Sub | Playstation SST | 22.5px / 1.41rem | 400 | 1.30 | — | Promotional sub-heading | -| UI Heading Small | SST | 18px / 1.13rem | 600 | 1.00 | — | Tight UI headings | -| Button / CTA | SST | 18px / 1.13rem | 500 | 1.25 | 0.4px | Primary button label | -| Button / Emphasized | SST | 18px / 1.13rem | 700 | 1.25 | 0.45px | Higher-emphasis CTAs (buy, subscribe) | -| Button Serif | SST | 18px / 1.13rem | 600 | 1.50 | — | Secondary button label | -| Body Relaxed | SST | 18px / 1.13rem | 400 | 1.50 | 0.1px | Standard reading body | -| Link Body | SST | 18px / 1.13rem | 400 | 1.50 | — | Inline link text | -| Compact Button | SST | 14px / 0.88rem | 700 | 1.25 | 0.324px | Mini CTAs in cards | -| Utility Caption | SST | 14px / 0.88rem | 500 | 1.50 | — | Captions, tag labels | -| Caption Body | SST | 14px / 0.88rem | 400 | 1.50 | — | Standard metadata | -| Playstation Caption Bold | Playstation SST | 14px / 0.88rem | 700 | 1.40 | — | Emphasized caption | -| Playstation Caption Mid | Playstation SST | 14px / 0.88rem | 600 | 1.40 | — | Semi-bold caption | -| Playstation Button | Playstation SST | 14.4px / 0.90rem | 700 | 1.00 | 0.144px | UI button with tight leading | -| Playstation Tab | Playstation SST | 14px / 0.88rem | 400 | 1.10 | 0.14px | Tab/pill label | -| Playstation Compact Caption | Playstation SST | 12.8px / 0.80rem | 400 | 1.10 | — | Smallest UI caption | -| Micro Caption | SST | 12px / 0.75rem | 500 | 1.50 | — | Footer microcopy, legal text | -| Compact Caption Bold | SST | 12.06px / 0.75rem | 700 | 1.50 | — | Emphasized micro text | +| Token | Size | Weight | Line Height | Letter Spacing | Use | +|---|---|---|---|---|---| +| `{typography.display-xl}` | 54px | 300 | 1.25 | -0.1px | Hero headline ("Discover all PS5 consoles and accessories") | +| `{typography.display-lg}` | 44px | 300 | 1.25 | 0.1px | Section headline ("Great PS4 & PS5 games out now or coming soon") | +| `{typography.display-md}` | 35px | 300 | 1.25 | 0 | Mid-section headline, game-page sub-hero | +| `{typography.heading-xl}` | 28px | 300 | 1.25 | 0.1px | "30 Years of PlayStation" callout, in-band sub-heading | +| `{typography.heading-lg}` | 22px | 300 | 1.25 | 0.1px | News card title, support category title | +| `{typography.heading-md}` | 18px | 600 | 1 | 0 | Card label, navigation menu heading, in-product strong title | +| `{typography.body-md}` | 18px | 400 | 1.5 | 0.1px | Body copy, paragraph text, support article body | +| `{typography.body-strong}` | 18px | 500 | 1.25 | 0.4px | Inline emphasis, primary nav link, button label (large) | +| `{typography.body-sm}` | 16px | 400 | 1.5 | 0 | Card description, secondary body | +| `{typography.caption-md}` | 14px | 400 | 1.5 | 0 | Footer link, metadata, sub-nav text | +| `{typography.caption-sm}` | 12px | 500 | 1.5 | 0 | Smallest utility text, badge label | +| `{typography.link-md}` | 18px | 400 | 1.5 | 0 | Inline body-prose anchor link | +| `{typography.button-lg}` | 18px | 700 | 1.25 | 0.45px | Primary CTA pill | +| `{typography.button-md}` | 14px | 700 | 1.25 | 0.324px | Compact pill, filter chip, secondary CTA | ### Principles -- **Weight 300 at large sizes is the voice.** PlayStation is the only major console brand that uses a light-weight display for its hero headlines. Resist the urge to "upgrade" display type to 500 or 700 — the quietness is the personality. -- **Weight jumps at the UI layer.** Below 18px the system shifts to 500–700 for legibility. The weight gradient from 300 (display) → 400 (body) → 500 (captions) → 700 (buttons) is the hierarchy. -- **Letter-spacing is barely-there.** Most values are 0.1–0.45px, either positive or slightly negative. The `-0.1px` on the 54px hero tightens the display type just enough to read as "designed" without becoming a typographic statement. -- **Two SST casings.** "SST" and "Playstation SST" are functionally the same family with slightly different metric sets (Playstation SST is tighter at small sizes). Treat them as interchangeable for purposes outside Sony's internal licensing. -- **No all-caps.** Unlike The Verge or Wired, PlayStation rarely uses UPPERCASE labels. Kickers and tags stay in title case or sentence case — another "quiet authority" move. -- **No serif anywhere.** The entire system is sans. There is no print-voice counterpoint. +The hierarchy works on a 1.25-line-height ladder almost exclusively — even body sits at 1.5 instead of the typical 1.6 — which keeps long-form support pages tight and console showcases efficient. The weight contrast between display (300) and button (700) is dramatic: a single 18px chrome line might host a heavyweight CTA next to a feather-light 22px headline, giving the system its editorial gaming-magazine feel. -## 4. Component Stylings +### Note on Font Substitutes +PlayStation SST is proprietary. The closest open-source substitutes: +- **Roboto Light (300)** for the display tier — its slightly looser letter-spacing matches SST's display optical fit. +- **Inter** at weights 400/500/600 for body and chrome — the closest geometric sans match for SST's body cut. +- **Source Sans Pro Light (300)** as an alternative for the display tier when Roboto reads too utilitarian. -### Buttons +When substituting, preserve the +0.1px to +0.45px tracking on display and button tiers — the spacing is part of what makes PlayStation SST feel premium at the light weight. -**Primary — PlayStation Blue Pill** -- Background: `#0070cc` (PlayStation Blue) -- Text: `#ffffff`, SST 18px / 500 / 0.4px tracking -- Border: none at rest -- Border radius: `999px` — full pill -- Padding: ~`12px 24px` (variable based on size class) -- Outline: `rgb(255, 255, 255) none 0px` at rest -- **Hover (signature move)**: - - Background fills to `#1eaedb` (PlayStation Cyan) - - Text stays `#ffffff` - - 2px `#ffffff` border appears - - 2px `#0070cc` outer ring shadow blooms (`0 0 0 2px #0070cc`) - - `transform: scale(1.2)` — the button actually grows 20% -- Active: `opacity: 0.6` — a quick dim to signal press -- Focus: Same as hover, but the ring turns into `rgb(0, 114, 206) 0px 0px 0px 2px` focus shadow -- Transition: ~180ms ease on background, transform, and shadow - -**Secondary — White Outline on Dark** -- Background: `#ffffff` -- Text: `#0172ce` (PlayStation Blue variant) -- Border: `2px outset #000000` — a genuine `outset` border, which is extremely rare in modern CSS -- Radius: varies (often `999px` or `36px`) -- Padding: `16px 20px` -- Hover: same signature cyan fill + scale(1.2) + ring treatment -- Focus: same ring treatment - -**Commerce Orange** -- Background: `#d53b00` (Commerce Orange) -- Text: `#ffffff`, SST 18px / 700 / 0.45px tracking -- Border radius: `999px` — pill -- Used only on PS Store / Buy / Subscribe Plus CTAs -- Active: background darkens to `#aa2f00` -- Hover: follows the cyan-invert rule like all other buttons (NOT an orange-specific hover) - -**Transparent Ghost** -- Background: transparent -- Text: `#1f1f1f` (Deep Charcoal) -- Border: `1px solid #dedede` -- Padding: `0 10px` (tight, nav-optimized) -- Hover: cyan fill, white text, 2px white border, scale(1.2) -- Active: text shifts to `#0072ce`, opacity 0.6 - -**Icon Circle** -- Background: `rgba(0, 0, 0, 0.2)` on photography; `#ffffff` on light surfaces -- Border radius: `100%` — perfect circle -- Used for carousel prev/next arrows and share buttons -- Hover: lightens to `var(--color-role-backgrounds-primary-link-hover)` (roughly `#e5e5e5` on light) - -**Mini CTA (In-card)** -- SST 14px / 700 / 0.324px tracking -- Padding ~8px 16px -- Radius: `999px` -- Used inside game cards for "Buy Now" / "Add to Cart" mini CTAs - -### Cards & Containers - -**Hero Card (Game Feature)** -- Background: photography/render — usually black-anchored -- Border radius: `24px` or `19px` for feature cards -- Padding: 32–48px interior -- Shadow: `rgba(0, 0, 0, 0.8) 0px 5px 9px 0px` — a dramatic drop-shadow only used when a card overlaps the hero photography -- Hover: subtle scale transform, cyan outline appears on primary CTA - -**Game Cover Tile** -- Background: game cover art, unpadded -- Border radius: `12px` or `13px` (images) / `19px` (card frame) -- Shadow: `rgba(0, 0, 0, 0.08) 0px 5px 9px 0px` — feather-weight elevation -- Hover: the card's primary CTA lights up cyan, the card itself may scale 1.02× -- Transition: 200ms ease on transform - -**Content Panel (White)** -- Background: `#ffffff` or the light section gradient `#ffffff → #f5f7fa` -- Border: typically none; separated from neighbors by spacing and subtle shadows -- Radius: `12px`–`24px` depending on panel hierarchy -- Shadow: `rgba(0, 0, 0, 0.06) 0px 5px 9px 0px` — the lightest in the system - -**Dark Card on Dark** -- Background: `rgba(0, 0, 0, 0.2)` over photography -- Border radius: `6px` (compact) or `24px` (feature) -- Used for "press kit" or "stat block" inlays over hero video - -### Inputs & Forms -- **Default**: `#ffffff` background, `1px solid #cccccc` border, `3px` border radius (tighter than the rest of the system — inputs are the one place where PlayStation gets genuinely compact), SST 16px text in `#1f1f1f`, placeholder `rgba(0, 0, 0, 0.6)`. -- **Focus**: 2px `#0070cc` focus ring via `box-shadow: 0 0 0 2px #0070cc`. No border-color change — the ring does the work. -- **Error**: border and text shift to `#c81b3a` (Warning Red), inline error text below in the same red. -- **Transition**: ~180ms ease on border and shadow. - -### Navigation - -- **Top nav**: black (`#000000`) full-bleed strip with the PlayStation logo (white) left-aligned, category links centered in SST 14–16px / 500, and a small "Sign In" CTA right-aligned. -- **Hover on nav link**: color transitions from `#ffffff` to `#1883fd` (Link Hover Blue), no underline. -- **Active section**: marked by a subtle 2px underline in `#0070cc`. -- **Mobile**: nav collapses to a hamburger drawer. Inside the drawer, links stack vertically with 16px gaps and 20px horizontal padding. -- **Sticky behavior**: the nav stays pinned at the top on scroll; when it enters a light-surface zone it **does not invert** — it stays black-backed throughout. - -### Image Treatment - -- **Aspect ratios**: 16:9 hero video/photography, 1:1 console renders, 3:4 game cover art, 4:3 lifestyle imagery. -- **Corners**: rounded to `12px`, `13px`, or `24px` depending on card context. Game covers get `6–12px`, hero images get `24px`. -- **Full-bleed**: only in the masthead hero and footer promotional banners. Everything else sits inside a padded content column. -- **Shadow**: dramatic `rgba(0, 0, 0, 0.8) 0 5px 9px 0` drop on heroes, feather `rgba(0, 0, 0, 0.06) 0 5px 9px 0` on grid tiles. -- **Hover**: image stays static, the card frame and primary CTA respond. -- **Lazy loading**: `loading="lazy"` on everything below the fold, `eager` on the masthead hero. - -### Game Store Pill (Distinctive) -- Background: `#ffffff` -- Text: `#000000`, SST 14px / 500 -- Padding: `14px 18px` -- Radius: `9999px` — full pill -- A neutral pill tag that sits next to game covers to label platform ("PS5", "PS4", "PSVR2"). White-on-dark contrast. - -## 5. Layout Principles +## Layout ### Spacing System -- **Base unit**: 8px. -- **Scale**: 1, 2, 3, 4.5, 5, 8, 9, 10, 12, 14, 15, 16, 18, 20, 21px. -- **Section padding**: 48–96px vertical between major panels. Hero-to-content transitions use the larger end. -- **Card padding**: 20–32px interior. Feature hero cards can expand to 48px. -- **Inline spacing**: 8–12px between headline and deck, 12–16px between deck and CTA. -- **Micro-scale**: The 1/2/3/4.5/5/9/10/12 values are used for pill padding, caption spacing, and border offsets — not for editorial rhythm. +- **Base unit:** 8px (with finer 4/12px steps for tight inline gaps). +- **Tokens (front matter):** `{spacing.xxs}` (4px) · `{spacing.xs}` (8px) · `{spacing.sm}` (12px) · `{spacing.md}` (16px) · `{spacing.lg}` (24px) · `{spacing.xl}` (32px) · `{spacing.xxl}` (48px) · `{spacing.section}` (96px). +- **Universal section rhythm:** every page in the set uses `{spacing.section}` (96px) as the vertical gap between major content blocks. Card grids use `{spacing.lg}` (24px) gutters; in-card padding sits at `{spacing.lg}` to `{spacing.xl}` depending on density. +- **Hero band padding:** 96px vertical / 48px horizontal — the largest spacing in the system, reserved for full-bleed surface chapters. ### Grid & Container -- **Max width**: ~1920px (dembrandt detected breakpoints up to 2120px). Container caps typically around `1280–1920px` depending on panel. -- **Column patterns**: 12-column responsive grid that resolves into 3/4/6-column game tile rows depending on hierarchy. Hero zones often span 12 columns; featured tiles sit in 6+3+3 or 4+4+4 configurations. -- **Outer padding**: 16px mobile → 48px tablet → 64–96px desktop. -- **Gutters**: 16–24px between columns, tighter (8–12px) inside tile clusters. +- **Max width:** ~1280px content area for body text on desktop with 24px gutters that expand to ~48px at ultrawide. Hero bands and game-tile rails go full-bleed with no max-width constraint on imagery. +- **Game tile carousel:** 4-up at desktop with horizontal scroll on the same row, collapsing to 3-up at 1024px and 2-up at 768px. Each tile uses 16:9 cover art at `{rounded.md}`. +- **Console showcase grid:** desktop 5-column thumbnail strip below the main hero render, collapsing to 3-up + horizontal scroll at tablet. +- **Support page:** desktop 2-column 30/70 split (sidebar nav + article body), collapsing to single-column with the sidebar promoted to a top accordion at mobile. +- **News strip:** 3-up card grid at desktop, 2-up at tablet, 1-up at mobile. ### Whitespace Philosophy -PlayStation treats whitespace like a luxury brand treats store lighting — as a premium signal. There is noticeably more vertical breathing room between modules than on any other major retail site, and the white editorial panels often hold only one headline + one image + one CTA at hero-scale padding. The effect is a "gallery pace" where each product gets its own room rather than competing in a grid of thumbnails. +Whitespace is structural and band-defined. The 96px `{spacing.section}` between chapters reads as silence between trailer cuts — there's no decorative wash, no gradient transition, no mid-section divider. Inside a section, content is left-aligned in a tight column with the imagery breathing in the right 60-70% of the band. Paragraph text is comfortable at 1.5 line-height but column widths stay narrow (~520px at desktop) to keep long-form copy readable. -### Border Radius Scale -- **2px** — cookie banner buttons and small admin UI -- **3px** — form inputs, tab panels (tighter than everything else — a deliberate "functional UI" cue) -- **6px** — compact buttons and inline images -- **12px** — standard game cover images and content images -- **13px** — certain figure wrappers (a 1px offset from 12px for nesting) -- **19px** — feature cards -- **20px** — inline tag spans -- **24px** — hero cards, primary feature frames -- **36px** — full-pill nav and secondary button variants -- **48px** — large feature buttons -- **999px / 100%** — full pill primary buttons and circular icon buttons - -Eleven discrete radius values — one of the richest radius systems of any site in this catalog. The range exists because PlayStation deliberately uses different radii for different *hierarchies*: 3px for utility, 12px for media, 24px for features, 999px for CTAs. - -## 6. Depth & Elevation +## Elevation & Depth | Level | Treatment | Use | |---|---|---| -| 0 | No shadow | Default content on `#ffffff` | -| 1 | `rgba(0, 0, 0, 0.06) 0 5px 9px 0` | Feather-light editorial panel lift | -| 2 | `rgba(0, 0, 0, 0.08) 0 5px 9px 0` | Standard grid tile elevation | -| 3 | `rgba(0, 0, 0, 0.16) 0 5px 9px 0` | Emphasized card (hover or active) | -| 4 | `rgba(0, 0, 0, 0.8) 0 5px 9px 0` | Hero overlay shadow — dramatic drop used over photography | -| 5 | `0 0 0 2px #0070cc` (focus ring) | Primary button focus state | -| 6 | `0 0 0 2px #000000` (hover ring) | Secondary button hover ring | -| 7 | Section gradient `#121314 → #000000` | Atmospheric depth on dark hero panels | +| 0 — Flat | No border, no shadow | Default for hero bands, footer, full-bleed sections — the dominant treatment | +| 1 — Hairline divider | 1px solid `{colors.hairline-light}` or `{colors.hairline-dark}` | Card borders, support row dividers, footer column rules | +| 2 — Soft active shadow | `0 4px 12px rgba(0,0,0,0.16)` | Active/pressed CTAs, lifted product card | +| 3 — Section gradient | Soft top-to-bottom darkening from `{colors.surface-dark-elevated}` to `{colors.canvas-dark}` | "ON PLAYSTATION" band — only place a gradient appears on chrome | -PlayStation's depth philosophy is **layered but restrained**. The shadow scale runs from 0.06 to 0.16 for normal states, then jumps to 0.8 for hero drops — there is no 0.2, 0.3, 0.4 middle ground. The effect is that most of the page sits almost flat, but when a hero card needs to float over photography, it genuinely *floats*. Elevation is either whispered or shouted, never muttered. +The system has effectively no resting shadow on cards; depth is built from surface-color contrast across band chapters. Cards lift only on press. ### Decorative Depth -- **Section gradients** (dark and light, both described above) — used only as section backgrounds -- **Focus/hover rings** at 2px, always blue or cyan depending on state -- **No glows, blurs, or atmospheric effects** beyond the two section gradients -- **No gradient buttons or text** — the visual system is solid color blocks everywhere except section transitions +Depth comes from the alternating-band rhythm and from the imagery itself: +- **Console product photography** — DualSense controller and PS5 console renders shot on neutral white with crisp edge lighting, full-bleed inside the light-canvas band. +- **Game key art** — full-bleed cinematic stills (Marathon, the latest blockbuster releases) inside dark-canvas bands with title lockup overlaid in the lower-left. +- **PS Plus tier banner** — a subtle horizontal gold gradient (`{colors.ps-plus-gold-start}` → `{colors.ps-plus-gold-end}`) sits as the only chrome gradient in the system, anchoring the "Discover PlayStation Plus" CTA. +- **"ON PLAYSTATION" gradient band** — top-to-bottom deepening from `{colors.surface-dark-elevated}` (`#121314`) to `{colors.canvas-dark}` (`#000000`) creates a cinematic dimming effect under the anniversary callout. -## 7. Do's and Don'ts +## Shapes + +### Border Radius Scale + +| Token | Value | Use | +|---|---|---| +| `{rounded.none}` | 0px | Hero bands, primary nav, footer, sub-nav, support article body — every full-bleed structural surface | +| `{rounded.sm}` | 4px | Text inputs, support search field utilities | +| `{rounded.md}` | 8px | Game tiles, product cards, feature cards, PS Plus banner | +| `{rounded.lg}` | 16px | Rare large container with extra-soft corners (e.g., dialog cards) | +| `{rounded.full}` | 9999px | Every CTA pill (primary / commerce / secondary), filter chips, pagination dots, carousel paddles | + +The radius vocabulary works on a 4 / 8 / pill rhythm for chrome with structural surfaces staying flat at 0px. + +### Photography Geometry +- **Hero console render:** large centered console + DualSense composition on white, ~70% width of the band, with copy slot to the left. +- **Game tiles:** 16:9 key art at `{rounded.md}` (8px), 4-up rail at desktop with horizontal carousel. +- **Marathon game page hero:** full-bleed cinematic 16:9 still with the "MARATHON" wordmark in the lower-left at light weight, brand yellow `{colors.marathon-yellow}` accent on a few small UI tags. +- **News card thumbnails:** 16:9 imagery at `{rounded.md}` with a small text block below. +- **Avatar / brand icons:** 32–40px circles for sub-nav social row. + +## Components + +> **No hover states documented** per system policy. Each spec covers Default and Active/Pressed only. + +### Buttons + +**`button-primary`** — the universal PlayStation CTA +- Background `{colors.primary}` (PlayStation Blue), text `{colors.on-primary}`, type `{typography.button-lg}`, padding `12px 28px`, height ~48px, rounded `{rounded.full}`. +- Used for "Add to bag", "Sign up", "Learn more", "Subscribe" — every primary action across both light and dark canvases. +- Pressed state lives in `button-primary-pressed` — background drops to `{colors.primary-pressed}` (`#0064b7`). + +**`button-commerce`** — orange store CTA +- Background `{colors.commerce}` (`#d53b00`), text `{colors.on-commerce}`, type `{typography.button-lg}`, padding `12px 28px`, height ~48px, rounded `{rounded.full}`. +- Reserved for "Buy now", "Pre-order", "Add to cart" — store actions only. The only warm color in the system. +- Pressed state lives in `button-commerce-pressed` — background drops to `{colors.commerce-pressed}`. + +**`button-secondary-light`** — outline variant on light canvas +- Background transparent, text `{colors.ink}`, 1px solid `{colors.ash-light}` border, type `{typography.button-lg}`, padding `12px 28px`, height ~48px, rounded `{rounded.full}`. +- Lower-emphasis CTA on white surfaces ("Learn more →", "Watch trailer"). + +**`button-secondary-dark`** — outline variant on dark canvas +- Background transparent, text `{colors.on-dark}`, 1px solid `{colors.hairline-dark}`, type `{typography.button-lg}`, padding `12px 28px`, height ~48px, rounded `{rounded.full}`. +- Same role as the light variant but inverted for use on `{colors.canvas-dark}` hero bands. + +**`button-disabled`** +- Background `{colors.surface-soft}`, text `{colors.ash-light}`, rounded `{rounded.full}` — flat soft gray. + +### Filter & Tab Chips + +**`filter-pill`** + **`filter-pill-active`** +- Default: background `{colors.surface-filter}` (translucent), text `{colors.ink}`, type `{typography.button-md}`, padding `8px 16px`, rounded `{rounded.full}`. +- Active: background flips to `{colors.canvas-light}` (opaque white) — the chip "lifts" from the translucent default. +- Used in the PS5 games filter strip ("All", "Coming Soon", "PlayStation VR2", "Recently Released"). + +### Inputs & Forms + +**`text-input`** + **`text-input-focused`** +- Default: background `{colors.canvas-light}`, text `{colors.ink}`, 1px solid `{colors.ash-light}`, type `{typography.body-md}`, padding `12px 16px`, height ~48px, rounded `{rounded.sm}` (4px). +- Focused: 2px solid `{colors.primary}` border, no halo (relies on the border weight increase as the focus signal). + +**`support-search-bar`** — the support-page signature search field +- Background `{colors.canvas-light}`, text `{colors.ink}`, type `{typography.body-md}`, padding `12px 24px`, height ~56px, rounded `{rounded.full}`. +- Sits at the top of the support page hero with a magnifier icon at the left edge and "Search the support center" placeholder. + +### Cards & Containers + +**`product-card`** — light-canvas product/feature card +- Container: background `{colors.surface-card}` (`#f5f7fa` cool-blue-tinted), 1px solid `{colors.hairline-light}` (rare; usually borderless), padding `{spacing.lg}` (24px), rounded `{rounded.md}` (8px). +- Used for the "PlayStation Store" sale callout, news cards, and PS Plus tier comparison cards on light canvas. + +**`product-card-dark`** — dark-canvas product card +- Container: background `{colors.surface-dark-card}` (`#181818`), padding `{spacing.lg}`, rounded `{rounded.md}`. +- Used for game-detail cards and dark-canvas feature panels. + +**`game-tile`** — game/console thumbnail tile +- Container: background `{colors.surface-dark-elevated}`, padding 0, rounded `{rounded.md}`. +- Layout: 16:9 cover art at full bleed inside the radius, with title + platform tag overlaid at the bottom-left in `{typography.body-sm}`. +- Used in the "Great PS4 & PS5 games" rail and the PS5 games listing grid. + +**`feature-card`** — light-canvas marketing card +- Container: background `{colors.canvas-light}`, padding `{spacing.xl}` (32px), rounded `{rounded.md}`. +- Used for the "PlayStation Store" hero card and similar feature panels with a small product icon, title, body, and CTA. + +**`hero-band-blue`** — the PlayStation Blue full-bleed band +- Background `{colors.primary}`, text `{colors.on-primary}` in `{typography.display-md}`, padding `96px 48px`, rounded `{rounded.none}`. +- The Marathon launch CTA strip and the footer surface use this band. The band's defining purpose is "this is the action moment of the page." + +**`hero-band-dark`** — full-bleed dark hero +- Background `{colors.canvas-dark}` (with optional gradient end at `{colors.surface-dark-elevated}`), text `{colors.on-dark}` in `{typography.display-xl}`, padding `96px 48px`, rounded `{rounded.none}`. +- The home-page hero, the game-detail page hero, and the "ON PLAYSTATION" anniversary band. + +**`hero-band-light`** — full-bleed white hero +- Background `{colors.canvas-light}`, text `{colors.ink}` in `{typography.display-xl}`, padding `96px 48px`, rounded `{rounded.none}`. +- The console showcase band ("Discover all PS5 consoles and accessories") and the support page top. + +**`ps-plus-banner`** — PlayStation Plus tier callout +- Background `{colors.surface-dark-elevated}` with the `{colors.ps-plus-gold-start}` → `{colors.ps-plus-gold-end}` gold gradient as a horizontal accent bar across the top, text `{colors.on-dark}` in `{typography.heading-xl}`, padding `48px 32px`, rounded `{rounded.md}`. +- The "Discover PlayStation Plus" full-width banner on the home page. + +**`carousel-paddle`** — circular carousel control +- Background `rgba(255,255,255,0.16)`, icon `{colors.on-dark}`, rounded `{rounded.full}`, size 48px. +- Anchored to the left/right edge of the game tile carousel. + +**`pagination-dot`** + **`pagination-dot-active`** +- 8px circle at `{rounded.full}`. Default fill `{colors.ash-dark}`; active fill `{colors.on-dark}`. +- Carousel position indicator below the game tile rail. + +### Inline + +**`badge-info`** — small info tag +- Background `{colors.primary}`, text `{colors.on-primary}` in `{typography.caption-sm}`, padding `4px 10px`, rounded `{rounded.full}`. +- "New", "Pre-order", "Coming Soon" labels overlaid on game tiles. + +**`link-inline`** — body-prose anchor link +- `{colors.link-light}` text on light canvas / `{colors.link-dark}` on dark canvas, no underline by default. Inline body links inside support article paragraphs. + +### Navigation + +**`primary-nav`** +- Background `{colors.canvas-dark}`, text `{colors.on-dark}`, height ~48px, type `{typography.body-strong}`, rounded `{rounded.none}`. +- Layout (desktop): PlayStation P-logo at far-left, centered nav row ("Games · PS5 · PS4 · PS VR2 · Subscriptions · Hardware · Mobile · News · Shop · Support"), right cluster (search-glyph + locale + cart icon + user-avatar circle). + +**`sub-nav`** — secondary nav strip +- Background `{colors.canvas-dark}`, text `{colors.on-dark}` in `{typography.caption-md}`, height ~40px, rounded `{rounded.none}`. +- Sits directly below the primary nav on PS5 games / single game / PS Plus pages with section-specific anchor links. + +**Top Nav (Mobile)** +- Hamburger menu icon at left, P-logo at center, search + cart icons at right. Primary nav collapses into a full-screen dark drawer that slides from the left. + +### Footer + +**`footer-section`** +- Background `{colors.primary}` (PlayStation Blue), text `{colors.on-primary}` in `{typography.caption-md}`, padding `{spacing.xxl}` (48px) vertical. +- Layout: large PlayStation wordmark at top-left, multi-column link grid (locale selector, store links, account, support, social), bottom row with terms / privacy fine-print in `{typography.caption-sm}`. +- The footer's blue surface is the system's "we're done — return to the brand" anchor. + +### Support-page-specific + +**`support-row`** — support article-list row +- Background `{colors.canvas-light}`, text `{colors.ink}` in `{typography.body-md}`, padding `16px 0`, with a 1px `{colors.hairline-light}` bottom rule. +- Used for FAQ / category-listing rows on the support page with a small chevron-right icon at the right edge. + +## Do's and Don'ts ### Do -- **Do** use PlayStation Blue (`#0070cc`) as the primary CTA fill and the footer anchor. It is the brand's anchor color. -- **Do** use SST weight 300 for every display headline 22px and above. The quiet-weight headline is the voice. -- **Do** apply the full hover signature to every primary button: cyan fill + 2px white border + 2px blue outer ring + `scale(1.2)`. -- **Do** use full-pill radius (`999px`) on primary and commerce buttons. -- **Do** reserve PlayStation Cyan (`#1eaedb`) exclusively for hover, focus, and active states — never as a resting background. -- **Do** use Commerce Orange (`#d53b00`) only on PlayStation Store / purchase CTAs and price callouts. -- **Do** alternate dark hero panels with white content panels and anchor with a deep blue footer — the three-surface channel layout is the page rhythm. -- **Do** use dramatic `rgba(0, 0, 0, 0.8)` hero drop shadows when a card overlaps product photography. -- **Do** keep the top nav black on every scroll position — it does not invert to white over light panels. +- Reserve `{colors.primary}` (PlayStation Blue) for primary CTAs and the footer surface only. The blue band is precious — at most one full-bleed blue band per page. +- Reserve `{colors.commerce}` (orange) for store/buy/pre-order CTAs only. It is never used on marketing chrome or hero pills. +- Use PlayStation SST at weight 300 for display headings (54 / 44 / 35 / 28 / 22). The light weight is the brand voice. +- Stack content sections at `{spacing.section}` (96px) rhythm with the next band's surface color taking over the page edge-to-edge — no decorative dividers between bands. +- Use `{rounded.full}` (9999px) on every CTA pill and `{rounded.md}` (8px) on every product card. The two-radius vocabulary is the entire shape system aside from inputs. +- Pair full-bleed game key art and console renders inside dark or light bands; let imagery occupy 60-90% of the band's vertical height. +- Use `{component.ps-plus-banner}` with the gold gradient exclusively for the PlayStation Plus tier callout — never decorate other components with the gold. ### Don't -- **Don't** bold display headlines. Weight 300 at 22–54px is the PlayStation voice. Weight 700 display type reads as "another game retailer". -- **Don't** use ALL-CAPS labels or kickers. PlayStation rarely uses uppercase — it is a quiet-authority brand, not a hazard-tape one. -- **Don't** use gradient buttons, text, or backgrounds outside the two declared section gradients. -- **Don't** introduce warm colors outside Commerce Orange. No red CTAs, no yellow highlights, no green success pills. -- **Don't** use square corners on buttons or media. The system has eleven radii — pick one, but never `0`. -- **Don't** skip the `scale(1.2)` hover move on primary buttons. The lift-scale is a brand interaction signature. -- **Don't** use serif type. The system is 100% SST sans. -- **Don't** let cyan `#1eaedb` appear as a text or background color at rest. It only exists in motion. -- **Don't** design panels that fight for attention. PlayStation's whitespace rhythm gives each module its own "gallery room". +- Don't introduce drop shadows on resting cards. The system is flat-on-canvas; cards lift only on press. +- Don't replace `{colors.primary}` with another shade of blue. The brand blue is precise — `#0070d1` for default and `#0064b7` for pressed. +- Don't use `{colors.commerce}` (orange) on marketing/hero CTAs. It's reserved exclusively for store actions. +- Don't introduce a sans-serif body font, italic, or monospace style. PlayStation SST carries every text role. +- Don't soften pill geometry. CTAs are always `{rounded.full}` — no medium-radius buttons. +- Don't use the gold PS Plus gradient on anything that isn't the PS Plus banner. It is a tier-specific brand asset. +- Don't put a gradient on chrome. The only allowed gradient is the gold PS Plus accent and the soft top-to-bottom darkening of the "ON PLAYSTATION" band. -## 8. Responsive Behavior +## Responsive Behavior ### Breakpoints | Name | Width | Key Changes | |---|---|---| -| Small Mobile | <400px | Single column, nav collapses to hamburger, SST hero scales to ~28px | -| Mobile | 400–599px | Single column, tiles stack full-width, padding opens to 16px | -| Large Mobile | 600–767px | Still single column but 2-column tile option in select modules | -| Tablet Portrait | 768–1023px | 2-column game grid, nav still condensed | -| Tablet Landscape | 1024–1279px | 3–4 column grid, full nav restored | -| Desktop | 1280–1599px | Full editorial grid, max hero display scale (44–54px) | -| Large Desktop | 1600–1919px | Container caps at 1600px, margins expand | -| 4K / Big-Screen | ≥1920px | Container expands to 1920px max, hero content scales up to match TV viewing distance | -| Ultra-Wide | ≥2120px | Extreme breakpoint — page stays anchored, outer margins absorb extra width | - -The dembrandt sweep detected 30 breakpoints between 320px and 2120px — an unusually wide responsive range. PlayStation tunes specifically for **big-screen contexts** (1920–2120px) because PS5 owners frequently browse the site on TVs via the console's browser or via cast-to-TV from a phone. Most retail sites stop tuning at 1440px; PlayStation keeps tuning through 4K. +| ultrawide | 1920px+ | Hero band stays at content max-width 1280px; outer gutters grow to ~80px | +| desktop-large | 1440px | Default desktop — 4-up game tile carousel, full primary nav | +| desktop | 1280px | Same layout with narrower outer gutters | +| desktop-small | 1024px | Game tile rail collapses to 3-up; sub-nav remains horizontal | +| tablet | 768px | Game tiles → 2-up; primary nav becomes hamburger drawer | +| mobile | 480px | Single-column everything; hero `{typography.display-xl}` scales 54px → ~32px | +| mobile-narrow | 320px | Section padding tightens to 32px; hero further scales to ~28px | ### Touch Targets -- Primary pill buttons are ~48–56px tall (SST 18px text + ~12–16px vertical padding) — comfortably WCAG AAA. -- Nav links are smaller (~32–40px tall) at desktop; on mobile they pad out to 48px+ inside the drawer. -- Icon circle buttons are 40–48px — touch-friendly. +All interactive elements meet WCAG AAA (≥ 44×44px). `{component.button-primary}` and `{component.button-commerce}` sit at 48px height with 28px horizontal padding (effective ~48×100px tappable). `{component.text-input}` sits at 48px. `{component.support-search-bar}` sits at 56px. `{component.filter-pill}` is ~36–40px height with 16px padding extending to 44px tappable via inline padding. `{component.carousel-paddle}` is exactly 48×48 circular. ### Collapsing Strategy -- **Nav**: full nav → condensed → hamburger drawer as viewport narrows. Logo stays pinned left; CTA stays pinned right. -- **Grid**: 6-col → 4-col → 3-col → 2-col → 1-col. Game tile cards reflow without cropping cover art. -- **Spacing**: section padding tightens from 96px → 64px → 48px → 32px → 24px as viewport narrows. -- **Type**: SST hero scales from 54px → 44px → 35px → 28px → 22px. The light weight 300 is preserved at every size. -- **Hero photography**: art-direction swap — desktop uses wide 16:9 crops, mobile uses 4:3 or 1:1 crops with the product centered. +- **Primary nav:** desktop horizontal cluster → tablet hamburger drawer at 768px. The right-cluster icons (search, cart, account) stay visible at every breakpoint. +- **Sub-nav:** desktop horizontal anchor row → tablet horizontal scroll → mobile select dropdown. +- **Game tile carousel:** 4-up → 3-up → 2-up at 1024 and 768px; carousel paddles stay visible at every desktop breakpoint, hide on mobile in favor of touch-swipe. +- **Hero bands:** stay full-bleed at every breakpoint; only the internal content column reflows from 2-column (text-left + image-right) to single-column (text above image). +- **Console showcase:** desktop 5-up thumbnail strip → tablet 3-up + horizontal scroll → mobile 1-up with paddle. +- **Support page:** desktop 30/70 split (sidebar + body) → tablet sidebar promoted to top accordion → mobile fully collapsed accordion. +- **Section padding:** `{spacing.section}` (96px) desktop → 64px tablet → 48px mobile. +- **Hero headline:** `{typography.display-xl}` (54px) at desktop, scaling 44px / 32px / 28px down the breakpoint stack. ### Image Behavior -- Responsive raster (`srcset` + `` with art-direction), aspect ratios preserved per breakpoint. -- 4K-ready: the site serves high-density imagery at 1920px+ to avoid upscaling on TV browsing. -- `loading="lazy"` on everything below the fold; hero is `eager` with a preload hint. +- Hero imagery (console renders, game key art) uses art-direction crops on mobile so the central subject stays centered when the band collapses to single-column. +- Game tile cover art preserves 16:9 ratio at every breakpoint; only the column count changes. +- Console showcase thumbnails maintain their natural aspect (~1:1 product render) across breakpoints. +- All non-critical imagery is lazy-loaded as the user scrolls into the next chapter. -## 9. Agent Prompt Guide +## Iteration Guide -### Quick Color Reference -- **Primary CTA**: "PlayStation Blue (`#0070cc`)" -- **Hover / Focus Accent**: "PlayStation Cyan (`#1eaedb`)" -- **Background (White Surface)**: "Paper White (`#ffffff`)" -- **Background (Dark Surface)**: "Console Black (`#000000`)" -- **Heading Text on White**: "Display Ink (`#000000`)" -- **Body Text on White**: "Deep Charcoal (`#1f1f1f`)" -- **Body Text on Black**: "Inverse White (`#ffffff`)" -- **Commerce / Buy Accent**: "Commerce Orange (`#d53b00`)" -- **Footer Anchor**: "PlayStation Blue (`#0070cc`)" +1. 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.full}`) — 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`) — do not bury them inside prose. +5. Default body to `{typography.body-md}` (18px / 400 / 1.5); reach for `{typography.display-xl}` strictly for the page-top hero headline; use `{typography.body-strong}` for primary nav links. +6. Keep `{colors.primary}` scarce per viewport — at most one full-bleed PlayStation Blue band per page. +7. When introducing a new component, ask whether it can be expressed with the existing pill + 8px-radius card + full-bleed-band vocabulary before adding new tokens. The system's strength is that it almost never needs new ones. -### Example Component Prompts -1. *"Create a primary CTA button with a `#0070cc` PlayStation Blue fill, white text in SST 18px / 500 / 0.4px tracking, 999px border radius, 12px × 24px padding. On hover, the background transitions to `#1eaedb` PlayStation Cyan, a 2px `#ffffff` border appears, a 2px `#0070cc` outer ring blooms via box-shadow, and the entire button scales 1.2× — all in a 180ms ease transition."* -2. *"Design a hero panel on a `#000000` Console Black canvas with a 54px SST weight 300 headline in `#ffffff` with -0.1px letter-spacing and 1.25 line-height. Place a single primary CTA below with the standard PlayStation hover treatment. No ALL-CAPS labels anywhere."* -3. *"Build a game cover tile: 3:4 aspect ratio image with 12px border radius, feather-weight `rgba(0, 0, 0, 0.08) 0 5px 9px 0` drop shadow, a 14px SST 700 title below, a 12px SST 500 platform tag, and a mini 14px / 700 / 0.324px tracking primary CTA in PlayStation Blue."* -4. *"Create a commerce pill button for a PlayStation Store purchase: `#d53b00` Commerce Orange fill, `#ffffff` text in SST 18px / 700 / 0.45px tracking, 999px radius, 12px × 28px padding. Active state darkens to `#aa2f00`. Hover follows the standard cyan-invert with 1.2× scale."* -5. *"Design a white content panel between dark hero sections: `#ffffff` background with the subtle `#ffffff → #f5f7fa` light section gradient, 24px border radius, 48px interior padding, feather-weight `rgba(0, 0, 0, 0.06) 0 5px 9px 0` elevation, a 35px SST 300 headline, a 18px body paragraph, and a single primary CTA."* +## Known Gaps -### Iteration Guide -When refining existing screens generated with this design system: -1. **Audit display weight.** Every headline 22px and above should be SST weight 300. If you see weight 500 or 700 at hero scale, you've lost the PlayStation voice. -2. **Audit the hover treatment.** Every primary button must scale 1.2× on hover with the cyan-fill + white-border + blue-ring combination. Miss any of those four and the interaction signature breaks. -3. **Audit corners.** Every container and button should land on 2, 3, 6, 12, 13, 19, 20, 24, 36, 48, or 999px / 100%. Square corners break the voice. -4. **Audit color sprawl.** Only PlayStation Blue (`#0070cc`), Cyan (`#1eaedb`), Commerce Orange (`#d53b00`), and the declared grays/blacks/whites should appear in chrome. If you see any other hue, correct it. -5. **Audit surface alternation.** The page should alternate dark hero → white content → dark hero → white content → blue footer. If two same-surface panels are adjacent, insert a transition. -6. **Audit casing.** Sentence case and title case only. No ALL-CAPS labels, buttons, or kickers. If you see uppercase, convert it. -7. **Audit shadow weight.** Shadow opacity should land on 0.06 / 0.08 / 0.16 / 0.8 — nothing in between. If you see 0.1, 0.2, 0.3, 0.5 drop shadows, correct to the nearest declared tier. -8. **Audit whitespace.** If two modules feel "competitive" (fighting for attention), add 48–96px of vertical breathing room. PlayStation's gallery-pace rhythm is non-negotiable. +- **Mobile screenshots not captured** — responsive behavior synthesizes PlayStation's known mobile pattern (hamburger drawer, single-column band reflow, hero downscale) from desktop evidence and the breakpoint stack. +- **Hover states not documented** by system policy. +- **Sign-in / authentication chrome** (login modal, account dashboard, profile pages) not in the captured pages. +- **PlayStation Store** in-store browsing surfaces (PDP / cart / checkout) are not in the captured set — those use a more dense data-table layout that this document does not describe. +- **Game-page-specific theming** — the `/marathon/` page uses `{colors.marathon-yellow}` as a chapter accent. Other game pages may pull in their own per-title brand colors that vary outside the documented system. +- **Form validation states** (success / error inline messages) not present in the captured surfaces beyond the `{colors.warning}` color token. diff --git a/design-md/posthog/DESIGN.md b/design-md/posthog/DESIGN.md index 86e6712..a99c176 100644 --- a/design-md/posthog/DESIGN.md +++ b/design-md/posthog/DESIGN.md @@ -1,256 +1,690 @@ -# Design System Inspired by PostHog +--- +version: alpha +name: PostHog +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. -## 1. Visual Theme & Atmosphere +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)" -PostHog's website feels like a startup's internal wiki that escaped into the wild — warm, irreverent, and deliberately anti-corporate. The background isn't the expected crisp white or dark void of developer tools; it's a warm, sage-tinted cream (`#fdfdf8`) that gives every surface a handmade, paper-like quality. Colors lean into earthy olive greens and muted sage rather than the conventional blues and purples of the SaaS world. It's as if someone designed a developer analytics platform inside a cozy garden shed. +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 -The personality is the star: hand-drawn hedgehog illustrations, quirky action figures, and playful imagery replace the stock photography and abstract gradients typical of B2B SaaS. IBM Plex Sans Variable serves as the typographic foundation — a font with genuine technical credibility (created by IBM, widely used in developer contexts) deployed here with bold weights (700, 800) on headings and generous line-heights on body text. The typography says "we're serious engineers" while everything around it says "but we don't take ourselves too seriously." +rounded: + none: 0px + xs: 2px + sm: 4px + md: 6px + lg: 8px + full: 9999px -The interaction design carries the same spirit: hover states flash PostHog Orange (`#F54E00`) text — a hidden brand color that doesn't appear at rest but surprises on interaction. Dark near-black buttons (`#1e1f23`) use opacity reduction on hover rather than color shifts, and active states scale slightly. The border system uses sage-tinted grays (`#bfc1b7`) that harmonize with the olive text palette. Built on Tailwind CSS with Radix UI and shadcn/ui primitives, the technical foundation is modern and component-driven, but the visual output is stubbornly unique. +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 + +PostHog'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:** -- Warm sage/olive color palette instead of conventional blues — earthy and approachable -- IBM Plex Sans Variable font at bold weights (700/800) for headings with generous 1.50+ line-heights -- Hidden brand orange (`#F54E00`) that only appears on hover interactions — a delightful surprise -- Hand-drawn hedgehog illustrations and playful imagery — deliberately anti-corporate -- Sage-tinted borders (`#bfc1b7`) and backgrounds (`#eeefe9`) creating a unified warm-green system -- Dark near-black CTAs (`#1e1f23`) with opacity-based hover states -- Content-heavy editorial layout — the site reads like a magazine, not a typical landing page -- Tailwind CSS + Radix UI + shadcn/ui component architecture +- Warm cream canvas (`{colors.canvas}` — #eeefe9) end-to-end with no surface alternation between sections — the page is one continuous sheet +- Single yellow-orange CTA pill (`{colors.primary}` — #f7a501) with deep olive text (`{colors.on-primary}`) — the brand's only saturated color +- IBM Plex Sans Variable across every text role with weights 400/500/600/700/800 — no other typeface in the system +- Hand-drawn hedgehog mascots scattered across the layout as the entire decorative system — no gradients, no mesh, no atmospheric backgrounds +- 4–8px radius card vocabulary: `{rounded.md}` (6px) for most components, `{rounded.lg}` (8px) for select containers, fully rounded for pill chips +- Pastel callout banners (`{colors.accent-blue-soft}`, `{colors.accent-green-soft}`, `{colors.accent-red-soft}`, `{colors.accent-purple-soft}`) break up doc article body with soft tinted side rails for tips/warnings/info +- Documentation pages add a sticky 240px `{component.doc-sidebar}` with rounded outline-icon section nav and an "Ask PostHog AI" CTA at the top -## 2. Color Palette & Roles +## Colors -### Primary -- **Olive Ink** (`#4d4f46`): Primary text color — a distinctive olive-gray that gives all text a warm, earthy tone -- **Deep Olive** (`#23251d`): Link text and high-emphasis headings — near-black with green undertone -- **PostHog Orange** (`#F54E00`): Hidden brand accent — appears only on hover states, a vibrant orange that surprises +> **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. -### Secondary & Accent -- **Amber Gold** (`#F7A501`): Secondary hover accent on dark buttons — warm gold that pairs with the orange -- **Gold Border** (`#b17816`): Special button borders — an amber-gold for featured CTAs -- **Focus Blue** (`#3b82f6`): Focus ring color (Tailwind default) — the only blue in the system, reserved for accessibility +### Brand & Accent +- **PostHog Yellow** (`{colors.primary}` — `#f7a501`): the universal primary CTA. Sticky "Get started — free" pill in the top-right of every nav, hero CTAs, pricing-tier subscribe buttons, footer signup pill. The system's only saturated chromatic moment. +- **Yellow Pressed** (`{colors.primary-pressed}` — `#dd9001`): pressed state for the primary pill. +- **Yellow Active** (`{colors.primary-active}` — `#b17816`): deeply-pressed yellow + the system's gold-toned border accent (rare 1px gold rule on inline form elements). -### Surface & Background -- **Warm Parchment** (`#fdfdf8`): Primary page background — warm near-white with yellow-green undertone -- **Sage Cream** (`#eeefe9`): Input backgrounds, secondary surfaces — light sage tint -- **Light Sage** (`#e5e7e0`): Button backgrounds, tertiary surfaces — muted sage-green -- **Warm Tan** (`#d4c9b8`): Featured button backgrounds — warm tan/khaki for emphasis -- **Hover White** (`#f4f4f4`): Universal hover background state +### Surface +- **Canvas** (`{colors.canvas}` — `#eeefe9`): the warm cream page background. End-to-end on every page; the brand's most distinctive surface choice. +- **Soft Surface** (`{colors.surface-soft}` — `#e5e7e0`): button-secondary fill, sub-nav strip background, inline-code chip background. +- **Surface Card** (`{colors.surface-card}` — `#ffffff`): true white card and tile background sitting on top of the cream canvas. The dominant card surface. +- **Surface Doc** (`{colors.surface-doc}` — `#fcfcfa`): a faintly cream-warm white used inside doc article body cards — slightly softer than pure white to keep the page tonally unified. +- **Surface Dark** (`{colors.surface-dark}` — `#23251d`): the deep olive-charcoal used inverted as code-block background. The same hex as `{colors.ink}` — the brand uses one olive-near-black for both text and dark code surfaces. +- **Hairline** (`{colors.hairline}` — `#bfc1b7`): 1px card border, table rule, footer column dividers. +- **Hairline Soft** (`{colors.hairline-soft}` — `#dcdfd2`): in-card row divider, soft inset rule. +- **On Dark** (`{colors.on-dark}` — `#ffffff`): primary text on `{colors.surface-dark}` code blocks. -### Neutrals & Text -- **Olive Ink** (`#4d4f46`): Primary body and UI text -- **Muted Olive** (`#65675e`): Secondary text, button labels on light backgrounds -- **Sage Placeholder** (`#9ea096`): Placeholder text, disabled states — warm sage-green -- **Sage Border** (`#bfc1b7`): Primary border color — olive-tinted gray for all borders -- **Light Border** (`#b6b7af`): Secondary border, toolbar borders — slightly darker sage +### Text +- **Ink** (`{colors.ink}` — `#23251d`): headlines, button text on light, primary nav links — deep olive-charcoal that reads near-black against cream. +- **Body** (`{colors.body}` — `#4d4f46`): default paragraph text, doc article body, inline link color before hover. The brand's most-used text color. +- **Charcoal** (`{colors.charcoal}` — `#33342d`): emphasized body text where body is too soft. +- **Mute** (`{colors.mute}` — `#6c6e63`): metadata, footer link text, in-list secondary annotations. +- **Ash** (`{colors.ash}` — `#9b9c92`): disabled-state text and lowest-emphasis utility. +- **Stone** (`{colors.stone}` — `#b6b7af`): least-emphasis caption text and disabled icon color. -### Semantic & Accent -- **PostHog Orange** (`#F54E00`): Hover text accent — signals interactivity and brand personality -- **Amber Gold** (`#F7A501`): Dark button hover accent — warmth signal -- **Focus Blue** (`#3b82f6` at 50% opacity): Keyboard focus rings — accessibility-only color -- **Dark Text** (`#111827`): High-contrast link text — near-black for important links +### Semantic +- **Link Blue** (`{colors.link-blue}` — `#1d4ed8`): inline anchor link inside body prose. The system's primary informational link color. +- **Link Teal** (`{colors.link-teal}` — `#1078a3`): doc-article inline link variant, paired with body text. +- **Accent Blue** (`{colors.accent-blue}` — `#2c84e0`) + **Accent Blue Soft** (`{colors.accent-blue-soft}` — `#dceaf6`): "💡 Tip / Info" callout banner inside docs. +- **Accent Red** (`{colors.accent-red}` — `#cd4239`) + **Accent Red Soft** (`{colors.accent-red-soft}` — `#f7d6d3`): "⚠️ Warning / Caution" callout banner. +- **Accent Green** (`{colors.accent-green}` — `#2c8c66`) + **Accent Green Soft** (`{colors.accent-green-soft}` — `#d9eddf`): "✅ Success / Positive" callout banner. +- **Accent Purple** (`{colors.accent-purple}` — `#7c44a6`) + **Accent Purple Soft** (`{colors.accent-purple-soft}` — `#e7d8ee`): "📘 Note / Reference" callout banner. +- **Focus Ring** (`{colors.focus-ring}` — `rgba(59,130,246,0.5)`): translucent blue browser-default focus ring around interactive elements. -### Gradient System -- No gradients on the marketing site — PostHog's visual language is deliberately flat and warm -- Depth is achieved through layered surfaces and border containment, not color transitions - -## 3. Typography Rules +## Typography ### Font Family -- **Display & Body**: `IBM Plex Sans Variable` — variable font (100–700+ weight range). Fallbacks: `IBM Plex Sans, -apple-system, system-ui, Avenir Next, Avenir, Segoe UI, Helvetica Neue, Helvetica, Ubuntu, Roboto, Noto, Arial` -- **Monospace**: `ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, Liberation Mono, Courier New` — system monospace stack -- **Code Display**: `Source Code Pro` — with fallbacks: `Menlo, Consolas, Monaco` +**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 `` 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 -| Role | Font | Size | Weight | Line Height | Letter Spacing | Notes | -|------|------|------|--------|-------------|----------------|-------| -| Display Hero | IBM Plex Sans Variable | 30px | 800 | 1.20 | -0.75px | Extra-bold, tight, maximum impact | -| Section Heading | IBM Plex Sans Variable | 36px | 700 | 1.50 | 0px | Large but generous line-height | -| Feature Heading | IBM Plex Sans Variable | 24px | 700 | 1.33 | 0px | Feature section titles | -| Card Heading | IBM Plex Sans Variable | 21.4px | 700 | 1.40 | -0.54px | Slightly unusual size (scaled) | -| Sub-heading | IBM Plex Sans Variable | 20px | 700 | 1.40 | -0.5px | Content sub-sections | -| Sub-heading Uppercase | IBM Plex Sans Variable | 20px | 700 | 1.40 | 0px | Uppercase transform for labels | -| Body Emphasis | IBM Plex Sans Variable | 19.3px | 600 | 1.56 | -0.48px | Semi-bold callout text | -| Label Uppercase | IBM Plex Sans Variable | 18px | 700 | 1.50 | 0px | Uppercase category labels | -| Body Semi | IBM Plex Sans Variable | 18px | 600 | 1.56 | 0px | Semi-bold body text | -| Body | IBM Plex Sans Variable | 16px | 400 | 1.50 | 0px | Standard reading text | -| Body Medium | IBM Plex Sans Variable | 16px | 500 | 1.50 | 0px | Medium-weight body | -| Body Relaxed | IBM Plex Sans Variable | 15px | 400 | 1.71 | 0px | Relaxed line-height for long reads | -| Nav / UI | IBM Plex Sans Variable | 15px | 600 | 1.50 | 0px | Navigation and UI labels | -| Caption | IBM Plex Sans Variable | 14px | 400–700 | 1.43 | 0px | Small text, various weights | -| Small Label | IBM Plex Sans Variable | 13px | 500–700 | 1.00–1.50 | 0px | Tags, badges, micro labels | -| Micro | IBM Plex Sans Variable | 12px | 400–700 | 1.33 | 0px | Smallest text, some uppercase | -| Code | Source Code Pro | 14px | 500 | 1.43 | 0px | Code snippets and terminal | +| 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 -- **Bold heading dominance**: Headings use 700–800 weight — PostHog's typography is confident and assertive, not whispery -- **Generous body line-heights**: Body text at 1.50–1.71 line-height creates extremely comfortable reading — the site is content-heavy and optimized for long sessions -- **Fractional sizes**: Several sizes (21.4px, 19.3px, 13.7px) suggest a fluid/scaled type system rather than fixed stops — likely computed from Tailwind's rem scale at non-standard base -- **Uppercase as category signal**: Bold uppercase labels (18px–20px weight 700) are used for product category headings — a magazine-editorial convention -- **Selective negative tracking**: Letter-spacing tightens on display text (-0.75px at 30px) but relaxes to 0px on body — headlines compress, body breathes +The 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. -## 4. Component Stylings +### Note on Font Substitutes +IBM 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. -### Buttons -- **Dark Primary**: `#1e1f23` background, white text, 6px radius, `10px 12px` padding. Hover: opacity 0.7 with Amber Gold text. Active: opacity 0.8 with slight scale transform. The main CTA — dark and confident -- **Sage Light**: `#e5e7e0` background, Olive Ink (`#4d4f46`) text, 4px radius, `4px` padding. Hover: `#f4f4f4` bg with PostHog Orange text. Compact utility button -- **Warm Tan Featured**: `#d4c9b8` background, black text, no visible radius. Hover: same orange text flash. Featured/premium actions -- **Input-style**: `#eeefe9` background, Sage Placeholder (`#9ea096`) text, 4px radius, 1px `#b6b7af` border. Looks like a search/filter control -- **Near-white Ghost**: `#fdfdf8` background, Olive Ink text, 4px radius, transparent 1px border. Minimal presence -- **Hover pattern**: All buttons flash PostHog Orange (`#F54E00`) or Amber Gold (`#F7A501`) text on hover — the brand's signature interaction surprise - -### Cards & Containers -- **Bordered Card**: Warm Parchment (`#fdfdf8`) or white background, 1px `#bfc1b7` border, 4px–6px radius — clean and minimal -- **Sage Surface Card**: `#eeefe9` background for secondary content containers -- **Shadow Card**: `0px 25px 50px -12px rgba(0, 0, 0, 0.25)` — a single deep shadow for elevated content (modals, dropdowns) -- **Hover**: Orange text flash on interactive cards — consistent with button behavior - -### Inputs & Forms -- **Default**: `#eeefe9` background, `#9ea096` placeholder text, 1px `#b6b7af` border, 4px radius, `2px 0px 2px 8px` padding -- **Focus**: `#3b82f6` ring at 50% opacity (Tailwind blue focus ring) -- **Text color**: `#374151` for input values — darker than primary text for readability -- **Border variations**: Multiple border patterns — some inputs use compound borders (top, left, bottom-only) - -### Navigation -- **Top nav**: Warm background, IBM Plex Sans at 15px weight 600 -- **Dropdown menus**: Rich mega-menu structure with product categories -- **Link color**: Deep Olive (`#23251d`) for nav links, underline on hover -- **CTA**: Dark Primary button (#1e1f23) in the nav — "Get started - free" -- **Mobile**: Collapses to hamburger with simplified menu - -### Image Treatment -- **Hand-drawn illustrations**: Hedgehog mascot and quirky illustrations — the signature visual element -- **Product screenshots**: UI screenshots embedded in device frames or clean containers -- **Action figures**: Playful product photography of hedgehog figurines — anti-corporate -- **Trust logos**: Enterprise logos (Airbus, GOV.UK) displayed in a muted trust bar -- **Aspect ratios**: Mixed — illustrations are irregular, screenshots are 16:9 or widescreen - -### AI Chat Widget -- Floating PostHog AI assistant with speech bubble — an interactive product demo embedded in the marketing site - -## 5. Layout Principles +## Layout ### Spacing System -- **Base unit**: 8px -- **Scale**: 2px, 4px, 6px, 8px, 10px, 12px, 16px, 18px, 24px, 32px, 34px -- **Section padding**: 32px–48px vertical between sections (compact for a content-heavy site) -- **Card padding**: 4px–12px internal (notably compact) -- **Component gaps**: 4px–8px between related elements +- **Base unit:** 8px (with finer 2/4/6px steps for tight inline gaps in callout banners and pill buttons). +- **Tokens (front matter):** `{spacing.xxs}` (2px) · `{spacing.xs}` (4px) · `{spacing.sm}` (8px) · `{spacing.md}` (12px) · `{spacing.lg}` (16px) · `{spacing.xl}` (24px) · `{spacing.xxl}` (32px) · `{spacing.section}` (80px). +- **Universal section rhythm:** every page in the set uses `{spacing.section}` (80px) as the vertical gap between major content blocks. Card grids use `{spacing.lg}` (16px) gutters; card internal padding sits at `{spacing.xl}` (24px) for product cards and `{spacing.xxl}` (32px) for pricing tier cards. ### Grid & Container -- **Max width**: 1536px (largest breakpoint), with content containers likely 1200px–1280px -- **Column patterns**: Varied — single column for text content, 2-3 column grids for feature cards, asymmetric layouts for product demos -- **Breakpoints**: 13 defined — 1px, 425px, 482px, 640px, 768px, 767px, 800px, 900px, 1024px, 1076px, 1160px, 1280px, 1536px +- **Max width:** ~1280px content area at desktop with 24px gutters (~48px at ultrawide). Doc article body sits at ~720px max width with the 240px sidebar pushing the article column right of center. +- **Marketing card grid:** 4-up at desktop, 3-up at 1024px, 2-up at 768px, 1-up at 480px. Cards preserve a fixed 1:1 or 4:3 ratio. +- **Pricing tier grid:** 3-up at desktop with a left rail of plan info, collapsing to 2-up + 1 at tablet and 1-up at mobile. +- **Doc layout:** desktop 240px sticky left sidebar + ~720px article body + (optional) 200px right TOC rail = ~1160px content width. +- **Footer:** 6-column horizontal link grid at desktop, 3-up at tablet, 2-up at mobile. ### Whitespace Philosophy -- **Content-dense by design**: PostHog's site is information-rich — whitespace is measured, not lavish -- **Editorial pacing**: Content sections flow like a magazine with varied layouts keeping the eye moving -- **Illustrations as breathing room**: Hand-drawn hedgehog art breaks up dense content sections naturally +Whitespace 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. -### Border Radius Scale -- **2px**: Small inline elements, tags (`span`) -- **4px**: Primary UI components — buttons, inputs, dropdowns, menu items (`button`, `div`, `combobox`) -- **6px**: Secondary containers — larger buttons, list items, card variants (`button`, `div`, `li`) -- **9999px**: Pill shape — badges, status indicators, rounded tags (`span`, `div`) - -## 6. Depth & Elevation +## Elevation & Depth | Level | Treatment | Use | -|-------|-----------|-----| -| Level 0 (Flat) | No shadow, warm parchment background | Page canvas, most surfaces | -| Level 1 (Border) | `1px solid #bfc1b7` (Sage Border) | Card containment, input borders, section dividers | -| Level 2 (Compound Border) | Multiple 1px borders on different sides | Input groupings, toolbar elements | -| Level 3 (Deep Shadow) | `0px 25px 50px -12px rgba(0, 0, 0, 0.25)` | Modals, floating elements, mega-menu dropdowns | +|---|---|---| +| 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 | -### Shadow Philosophy -PostHog's elevation system is remarkably minimal — only one shadow definition exists in the entire system. Depth is communicated through: -- **Border containment**: Sage-tinted borders (`#bfc1b7`) at 1px create gentle warm separation -- **Surface color shifts**: Moving from `#fdfdf8` to `#eeefe9` to `#e5e7e0` creates layered depth without shadows -- **The single shadow**: The one defined shadow (`0 25px 50px -12px`) is reserved for floating elements — modals, dropdowns, popovers. It's a deep, dramatic shadow that creates clear separation when needed +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 -- **Illustration layering**: Hand-drawn hedgehog art creates visual depth naturally -- **No gradients or glow**: The flat, warm surface system relies entirely on border and surface-color differentiation -- **No glassmorphism**: Fully opaque surfaces throughout +Depth comes entirely from illustration and the pastel callout band system, not from CSS effects: +- **Hand-drawn hedgehog mascots** — characters in various costumes (lab coat, terminal, lounge chair, magnifying glass, hammock, hat) scattered across pages as marginalia. Always rendered as flat color illustrations, never photographs. +- **Pastel callout banners** — `{component.banner-tip-blue}` / `-green` / `-red` / `-purple` soft tinted side-rail panels inside doc articles, each prefixed with an emoji icon (💡 ✅ ⚠️ 📘) and carrying tip/warning/note copy. +- **Code blocks** — full-width dark olive-charcoal panels on `{colors.surface-dark}` with white code text. The system's most cinematic surface, used inside white doc cards. +- **Outline product icons** in the doc sidebar — small rounded-square mini-illustrations (chart icon, funnel, session-replay icon) mark each major product section. -## 7. Do's and Don'ts +## Shapes + +### Border Radius Scale + +| Token | Value | Use | +|---|---|---| +| `{rounded.none}` | 0px | Sub-nav strip, footer, doc sidebar, primary nav — flat structural surfaces | +| `{rounded.xs}` | 2px | Inline `` 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 +There is no photography. Visual elements are limited to: +- **Hedgehog character illustrations** — flat-color cartoon hedgehogs ranging from ~80px (in-card mascot) to ~240px (hero illustration). Always at native aspect, never cropped to a frame. +- **Outline product icons** in the doc sidebar — 20–24px rounded-square illustrations. +- **Inline emoji** at 14–16px inside callout banners (💡 ✅ ⚠️ 📘) — used as functional iconography rather than decoration. +- **Section illustrations** on the home page — small hedgehog vignettes paired with each "Understand product usage" / "Build sticky habits" / "Test before launch" feature row. + +## Components + +> **No hover states documented** per system policy. Each spec covers Default and Active/Pressed only. + +### Buttons + +**`button-primary`** — the universal PostHog CTA +- Background `{colors.primary}` (yellow-orange), text `{colors.on-primary}` (deep olive), type `{typography.button-md}`, padding `8px 16px`, height `40px`, rounded `{rounded.md}`. +- Used for "Get started — free" (sticky top-nav CTA), "Sign up", "Try it free", "Subscribe" — every primary action. +- Pressed state lives in `button-primary-pressed` — background drops to `{colors.primary-pressed}`. + +**`button-secondary`** — soft alternative on cream canvas +- Background `{colors.surface-soft}` (`#e5e7e0`), text `{colors.ink}`, type `{typography.button-md}`, padding `8px 16px`, height `40px`, rounded `{rounded.md}`. +- "Talk to sales", "Read docs", "Watch demo" — second-tier actions paired with the yellow primary. + +**`button-tertiary`** — ghost text button +- Background transparent, text `{colors.ink}`, type `{typography.button-md}`, padding `8px 12px`, rounded `{rounded.md}`. +- Lowest-emphasis action: "See all docs →", "Browse all features". + +**`button-disabled`** +- Background `{colors.surface-soft}`, text `{colors.ash}` — flat soft cream-gray. + +### Tabs & Chips + +**`product-tab`** + **`product-tab-active`** — major product section tabs +- Default: transparent background, text `{colors.body}`, type `{typography.body-strong}`, padding `8px 12px`, rounded `{rounded.md}`. +- Active: background flips to `{colors.surface-card}` (white), text `{colors.ink}` — the tab card lifts off the cream canvas as the visual signal of selection. + +**`pill-tab`** + **`pill-tab-active`** — compact filter pill +- Default: transparent background, text `{colors.body}`, type `{typography.button-sm}`, padding `6px 14px`, rounded `{rounded.full}`. +- Active: background flips to `{colors.ink}`, text `{colors.on-dark}` — the chip flips fully inverted on selection. + +**`badge-uppercase`** — text-only utility label +- Background transparent, text `{colors.body}` in `{typography.utility-xs}` (uppercase) — used as in-list category prefix ("FEATURE FLAG", "EXPERIMENT", "HEATMAP"). + +**`badge-promo`** — small inline pill chip +- Background `{colors.accent-blue-soft}`, text `{colors.link-blue}`, type `{typography.caption-xs}`, padding `2px 8px`, rounded `{rounded.full}`. +- "New", "Beta", "Coming soon" pill labels overlaid on cards. + +### Inputs & Forms + +**`text-input`** + **`text-input-focused`** +- Default: background `{colors.surface-card}`, text `{colors.ink}`, 1px solid `{colors.hairline}`, type `{typography.body-md}`, padding `8px 12px`, height `36px`, rounded `{rounded.md}`. +- Focused: same surface; 2px solid `{colors.accent-blue}` border replaces the 1px hairline + a translucent `{colors.focus-ring}` outline. + +**`search-input`** — utility search field (doc sidebar, "Ask PostHog AI") +- Same dimensions as `text-input` with a magnifier glyph at the left edge in `{colors.mute}`. + +### Cards & Containers + +**`product-card`** — marketing tile / feature card +- Container: background `{colors.surface-card}` (white), 1px solid `{colors.hairline}`, padding `{spacing.xl}` (24px), rounded `{rounded.md}`. +- Layout: small hedgehog illustration at top-left, `{typography.heading-sm-mixed}` title, `{typography.body-sm}` description, optional `{component.button-tertiary}` "Learn more →" link. + +**`doc-card`** — doc article body card +- Container: background `{colors.surface-doc}` (`#fcfcfa` warm-white), 1px solid `{colors.hairline}`, padding `{spacing.xl}` (24px), rounded `{rounded.md}`. +- Carries article body sections, code blocks, callout banners, and tables inside doc pages. + +**`feature-tile`** — small marketing feature tile +- Container: background `{colors.surface-card}`, 1px solid `{colors.hairline}`, padding `{spacing.lg}` (20px), rounded `{rounded.md}`. +- Used in 3-up or 4-up grids on home and workflows pages — paired with a small icon and a 1-line description. + +**`pricing-tier-card`** — pricing plan card +- Container: background `{colors.surface-card}`, 1px solid `{colors.hairline}`, padding `{spacing.xxl}` (32px), rounded `{rounded.md}`. +- Layout: tier name in `{typography.display-lg}` (24px / 800 / -0.6px), large price + period, feature checklist with check-icon bullets, primary or secondary CTA at bottom. + +**`hedgehog-mascot-card`** — feature card with margin-anchored hedgehog +- Same chrome as `{component.product-card}` but with a hand-drawn hedgehog illustration anchored in the right margin or top-right corner — the brand's signature card variant. + +### Callout Banners + +**`banner-tip-blue`** + **`banner-tip-green`** + **`banner-tip-red`** + **`banner-tip-purple`** +- Background `{colors.accent-blue-soft}` / `{colors.accent-green-soft}` / `{colors.accent-red-soft}` / `{colors.accent-purple-soft}`, text `{colors.ink}`, type `{typography.body-md}`, padding `16px 20px`, rounded `{rounded.md}`. +- Each prefixed with an inline emoji icon (💡 / ✅ / ⚠️ / 📘) followed by an inline label and body copy. +- Only appear inside doc article body. The four-color callout family is the brand's information-architecture vocabulary for inline tips/warnings/info inside long-form documentation. + +### Code + +**`code-block`** — dark code sample inside doc card +- Container: background `{colors.surface-dark}` (deep olive-charcoal), text `{colors.on-dark}` in `{typography.code-sm}`, padding `16px 20px`, rounded `{rounded.md}`. +- Syntax highlighting uses muted accent colors (blue for keywords, green for strings, purple for numbers) — never the bright accent colors used in callout banners. + +**`inline-code`** — small inline `` chip +- Background `{colors.surface-soft}`, text `{colors.ink}` in `{typography.code-xs}`, padding `2px 6px`, rounded `{rounded.xs}` (2px). +- Used inside body prose to mark code snippets and identifiers. + +### Navigation + +**`primary-nav`** +- Background `{colors.canvas}` (cream — same as the page), text `{colors.ink}`, height `56px`, type `{typography.body-strong}`, rounded `{rounded.none}`. +- Layout (desktop): PostHog wordmark + hedgehog logo at left, nav menu cluster ("Pricing · Docs · Community · Company"), right cluster with a search-glyph, "Login" link, and the always-yellow `{component.button-primary}` "Get started — free" pill anchored to the far right. + +**`sub-nav-strip`** — secondary nav bar (under primary) +- Background `{colors.surface-soft}`, text `{colors.body}` in `{typography.body-xs}`, height `40px`, rounded `{rounded.none}`. +- Sits directly below the primary nav on workflows / product pages with section anchor links and a contextual "Get started →" link at the right. + +**`doc-sidebar`** — sticky doc-page left sidebar +- Background `{colors.canvas}`, text `{colors.body}` in `{typography.body-xs}`, width `240px`, rounded `{rounded.none}`. +- Layout: search-input "Ask PostHog AI" at top, then a vertical list of section headers each with a small rounded outline-icon mini-illustration, then nested item links indented under the active header. + +**Top Nav (Mobile)** +- Hamburger menu icon at left, PostHog wordmark + hedgehog at center, search + sticky yellow "Get started — free" CTA at right. Primary nav collapses into a full-height drawer that slides from the left. + +### Footer + +**`footer-section`** +- Background `{colors.canvas}`, text `{colors.body}` in `{typography.body-xs}`, padding `32px 24px`, rounded `{rounded.none}`, with a 1px `{colors.hairline}` top rule. +- Layout: 6-column horizontal link grid (Product · Resources · Company · Community · Pricing · Legal), each column with a `{typography.utility-xs}` (uppercase) header and a vertical list of links in `{typography.body-xs}` `{colors.body}`. +- Bottom row: PostHog wordmark + small hedgehog illustration, copyright in `{typography.caption-xs}` `{colors.mute}`, social-icon row at far-right. + +### Inline + +**`link-inline`** — body-prose anchor link +- `{colors.link-teal}` (`#1078a3`) in body prose with no underline by default; underline appears on focus. The brand's primary inline link color. + +## Do's and Don'ts ### Do -- Use the olive/sage color family (#4d4f46, #23251d, #bfc1b7) for text and borders — the warm green undertone is essential to the brand -- Flash PostHog Orange (#F54E00) on hover states — it's the hidden brand signature -- Use IBM Plex Sans at bold weights (700/800) for headings — the font carries technical credibility -- Keep body text at generous line-heights (1.50–1.71) — the content-heavy site demands readability -- Maintain the warm parchment background (#fdfdf8) — not pure white, never cold -- Use 4px border-radius for most UI elements — keep corners subtle and functional -- Include playful, hand-drawn illustration elements — the personality is the differentiator -- Apply opacity-based hover states (0.7 opacity) on dark buttons rather than color shifts +- Use `{colors.canvas}` (cream — `#eeefe9`) as the page body. Never substitute pure white as the canvas. +- Reserve `{colors.primary}` (yellow-orange) for the primary CTA pill only. The "Get started — free" treatment is the brand's anchor. +- Render the brand wordmark with the hedgehog illustration alongside it, not as a stand-alone wordmark. The hedgehog IS the brand identity. +- Use IBM Plex Sans Variable across every text role — body 400, emphasis 600/700, display 800. +- Stack content sections at `{spacing.section}` (80px) rhythm with no decorative dividers between them; let the cream canvas continue uninterrupted. +- Use `{component.banner-tip-blue}` / `-green` / `-red` / `-purple` only inside doc article body for tip/warning/note panels — keep marketing chrome out of the four-color callout family. +- Pair every code sample with the dark `{component.code-block}` surface; inline `` chips use `{component.inline-code}` (cream surface-soft chip). +- Anchor a hedgehog mascot illustration in feature tile margins on home and workflows pages — the system's signature decoration. ### Don't -- Use blue, purple, or typical tech-SaaS colors — PostHog's palette is deliberately olive/sage -- Add heavy shadows — the system uses one shadow for floating elements only; everything else uses borders -- Make the design look "polished" or "premium" in a conventional sense — PostHog's charm is its irreverent, scrappy energy -- Use tight line-heights on body text — the generous 1.50+ spacing is essential for the content-heavy layout -- Apply large border-radius (12px+) on cards — PostHog uses 4px–6px, keeping things tight and functional -- Remove the orange hover flash — it's a core interaction pattern, not decoration -- Replace illustrations with stock photography — the hand-drawn hedgehog art is the brand -- Use pure white (#ffffff) as page background — the warm sage-cream (#fdfdf8) tint is foundational +- Don't introduce drop shadows on cards. Cards sit flat on cream with thin olive borders only. +- Don't add a second saturated chromatic CTA. Yellow-orange is the only loud color in the system. +- Don't replace the cream canvas with pure white or full-bleed dark hero bands. The cream is the brand. +- Don't use the four-color callout banner pastels (`{colors.accent-blue-soft}`, `-green`, `-red`, `-purple`) as marketing-card backgrounds. They belong to inline doc content only. +- Don't substitute the hedgehog illustration with a generic icon set. The character system is the brand. +- Don't use uppercase transform outside of `{typography.heading-sm}`, `{typography.utility-xs}`, and `{typography.caption-xs}`. Uppercase is reserved for eyebrows and footer category headers. +- Don't pad cards with 32px+ on all sides except for `{component.pricing-tier-card}`. Standard cards sit at 24px internal padding. -## 8. Responsive Behavior +## Responsive Behavior ### Breakpoints + | Name | Width | Key Changes | -|------|-------|-------------| -| Mobile Small | <425px | Single column, compact padding, stacked cards | -| Mobile | 425px–640px | Slight layout adjustments, larger touch targets | -| Tablet | 640px–768px | 2-column grids begin, nav partially visible | -| Tablet Large | 768px–1024px | Multi-column layouts, expanded navigation | -| Desktop | 1024px–1280px | Full layout, 3-column feature grids, expanded mega-menu | -| Large Desktop | 1280px–1536px | Max-width container, generous margins | -| Extra Large | >1536px | Centered container at max-width | +|---|---|---| +| 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 -- Buttons: 4px–6px radius with `4px–12px` padding — compact but usable -- Nav links: 15px text at weight 600 with adequate padding -- Mobile: Hamburger menu with simplified navigation -- Inputs: Generous vertical padding for thumb-friendly forms +All 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 -- **Navigation**: Full mega-menu with dropdowns → hamburger menu on mobile -- **Feature grids**: 3-column → 2-column → single column stacked -- **Typography**: Display sizes reduce across breakpoints (30px → smaller) -- **Illustrations**: Scale within containers, some may hide on mobile for space -- **Section spacing**: Reduces proportionally while maintaining readability +- **Primary nav:** desktop horizontal cluster → tablet hamburger drawer at 768px. The yellow "Get started — free" CTA stays visible at every breakpoint. +- **Sub-nav strip:** desktop horizontal anchor row → tablet horizontal scroll → mobile select dropdown. +- **Marketing card grid:** 4-up → 3-up → 2-up → 1-up at 1024, 768, and 480px; gutters drop from 16px to 12px on mobile. +- **Pricing grid:** 3-up → 2+1 → 1-up stacked at tablet and below. +- **Doc layout:** desktop 240px sidebar + 720px article → tablet sidebar collapses to a top accordion → mobile fully collapsed accordion. +- **Footer:** 6-up link columns → 3-up at tablet → 2-up at mobile. +- **Section padding:** `{spacing.section}` (80px) desktop → 64px tablet → 48px mobile. +- **Hero headline:** `{typography.display-xl}` (36px) at desktop, scaling to ~28px at mobile, line-height holding at 1.5. ### Image Behavior -- Illustrations scale responsively within containers -- Product screenshots maintain aspect ratios -- Trust logos reflow into multi-row grids on mobile -- AI chat widget may reposition or simplify on small screens +The 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. -## 9. Agent Prompt Guide +## Iteration Guide -### Quick Color Reference -- Primary Text: Olive Ink (`#4d4f46`) -- Dark Text: Deep Olive (`#23251d`) -- Hover Accent: PostHog Orange (`#F54E00`) -- Dark CTA: Near-Black (`#1e1f23`) -- Button Surface: Light Sage (`#e5e7e0`) -- Page Background: Warm Parchment (`#fdfdf8`) -- Border: Sage Border (`#bfc1b7`) -- Placeholder: Sage Placeholder (`#9ea096`) +1. 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. -### Example Component Prompts -- "Create a hero section on warm parchment background (#fdfdf8) with 30px IBM Plex Sans heading at weight 800, line-height 1.20, letter-spacing -0.75px, olive ink text (#4d4f46), and a dark CTA button (#1e1f23, 6px radius, white text, opacity 0.7 on hover)" -- "Design a feature card with #fdfdf8 background, 1px #bfc1b7 border, 4px radius, IBM Plex Sans heading at 20px weight 700, and 16px body text at weight 400 with 1.50 line-height in olive ink (#4d4f46)" -- "Build a navigation bar with warm background, IBM Plex Sans links at 15px weight 600 in deep olive (#23251d), underline on hover, and a dark CTA button (#1e1f23) at the right" -- "Create a button group: primary dark (#1e1f23, white text, 6px radius), secondary sage (#e5e7e0, #4d4f46 text, 4px radius), and ghost/text button — all flash #F54E00 orange text on hover" -- "Design an input field with #eeefe9 background, 1px #b6b7af border, 4px radius, #9ea096 placeholder text, focus ring in #3b82f6 at 50% opacity" +## Known Gaps -### Iteration Guide -When refining existing screens generated with this design system: -1. Verify the background is warm parchment (#fdfdf8) not pure white — the sage-cream warmth is essential -2. Check that all text uses the olive family (#4d4f46, #23251d) not pure black or neutral gray -3. Ensure hover states flash PostHog Orange (#F54E00) — if hovering feels bland, you're missing this -4. Confirm borders use sage-tinted gray (#bfc1b7) not neutral gray — warmth runs through every element -5. The overall tone should feel like a fun, scrappy startup wiki — never corporate-polished or sterile +- **Mobile screenshots not captured** — responsive behavior synthesizes PostHog's mobile pattern (hamburger drawer, single-column grid, doc sidebar accordion) from desktop evidence and the breakpoint stack. +- **Hover states not documented** by system policy. +- **In-product app chrome** (PostHog dashboard, charts, session replay player) not in the captured set — the marketing site is documented here, not the in-product analytics interface. +- **Authenticated chrome** (login modal, account dashboard, billing settings) not in the captured pages. +- **Form validation states** beyond the focused-state input not present in the captured surfaces. +- **Marketing illustration set** — the full library of hedgehog character poses is not enumerated here; specific poses (lab coat hedgehog, terminal hedgehog, hammock hedgehog) are noted as visible in screenshots but the full asset library is page-specific. diff --git a/design-md/raycast/DESIGN.md b/design-md/raycast/DESIGN.md index eba337c..96bc7af 100644 --- a/design-md/raycast/DESIGN.md +++ b/design-md/raycast/DESIGN.md @@ -1,268 +1,669 @@ -# Design System Inspired by Raycast +--- +version: alpha +name: Raycast +属于: 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. -## 1. Visual Theme & Atmosphere +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" -Raycast's marketing site feels like the dark interior of a precision instrument — a Swiss watch case carved from obsidian. The background isn't just dark, it's an almost-black blue-tint (`#07080a`) that creates a sense of being inside a macOS native application rather than a website. Every surface, every border, every shadow is calibrated to evoke the feeling of a high-performance desktop utility: fast, minimal, trustworthy. +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"' -The signature move is the layered shadow system borrowed from macOS window chrome: multi-layer box-shadows with inset highlights that simulate physical depth, as if cards and buttons are actual pressed or raised glass elements on a dark desk. Combined with Raycast Red (`#FF6363`) — deployed almost exclusively in the hero's iconic diagonal stripe pattern — the palette creates a brand that reads as "powerful tool with personality." The red doesn't dominate; it punctuates. +rounded: + none: 0px + xs: 4px + sm: 6px + md: 8px + lg: 10px + xl: 16px + full: 9999px -Inter is used everywhere — headings, body, buttons, captions — with extensive OpenType features (`calt`, `kern`, `liga`, `ss03`) creating a consistent, readable typographic voice. The positive letter-spacing (0.2px–0.4px on body text) is unusual for a dark UI and gives the text an airy, breathable quality that counterbalances the dense, dark surfaces. GeistMono appears for code elements, reinforcing the developer-tool identity. +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 + +Raycast'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:** -- Near-black blue-tinted background (`#07080a`) — not pure black, subtly blue-shifted -- macOS-native shadow system with multi-layer inset highlights simulating physical depth -- Raycast Red (`#FF6363`) as a punctuation color — hero stripes, not pervasive -- Inter with positive letter-spacing (0.2px) for an airy, readable dark-mode experience -- Radix UI component primitives powering the interaction layer -- Subtle rgba white borders (0.06–0.1 opacity) for containment on dark surfaces -- Keyboard shortcut styling with gradient key caps and heavy shadows +- Single dark surface mode with a 4-step surface ladder: `{colors.canvas}` (#07080a) → `{colors.surface}` (#0d0d0d) → `{colors.surface-elevated}` (#101111) → `{colors.surface-card}` (#121212) +- White CTA pill (`{colors.primary}` — #ffffff) is the universal primary action; everything else is monochrome dark +- Inter typography with `font-feature-settings: "calt", "kern", "liga", "ss03"` enabled site-wide — the ss03 alternate `g` is part of the brand voice +- Hairline 1px borders (`{colors.hairline}` — #242728) carry every card edge; there are no drop shadows in the system +- Multi-radius card vocabulary: `{rounded.sm}` (6px) for keycaps, `{rounded.md}` (8px) for buttons and small cards, `{rounded.lg}` (10px) for feature cards, `{rounded.xl}` (16px) for hero command-palette mockup containers +- Saturated category accents (`{colors.accent-yellow}` for Hacker News, `{colors.accent-red}` for Slack/Apple, `{colors.accent-green}` for productivity tools, `{colors.accent-blue}` for info) appear only inside extension tile imagery — never on chrome +- Signature red diagonal-stripe gradient band at the very top of the hero — three angled stripes in `{colors.hero-stripe-start}` → `{colors.hero-stripe-end}`, used once per page maximum -## 2. Color Palette & Roles +## Colors -### Primary -- **Near-Black Blue** (`#07080a`): Primary page background — the foundational void with a subtle blue-cold undertone -- **Pure White** (`#ffffff`): Primary heading text, high-emphasis elements -- **Raycast Red** (`#FF6363` / `hsl(0, 100%, 69%)`): Brand accent — hero stripes, danger states, critical highlights +> **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. -### Secondary & Accent -- **Raycast Blue** (`hsl(202, 100%, 67%)` / ~`#55b3ff`): Interactive accent — links, focus states, selected items -- **Raycast Green** (`hsl(151, 59%, 59%)` / ~`#5fc992`): Success states, positive indicators -- **Raycast Yellow** (`hsl(43, 100%, 60%)` / ~`#ffbc33`): Warning accents, highlights -- **Blue Transparent** (`hsla(202, 100%, 67%, 0.15)`): Blue tint overlay for interactive surfaces -- **Red Transparent** (`hsla(0, 100%, 69%, 0.15)`): Red tint overlay for danger/error surfaces +### Brand & Accent +- **White** (`{colors.primary}` — `#ffffff`): the universal primary CTA pill background. "Download" / "Install Extension" / "Get Pro" — every primary action carries it. +- **White Pressed** (`{colors.primary-pressed}` — `#e8e8e8`): pressed-state for the primary pill — a single notch dimmer. +- **On Primary** (`{colors.on-primary}` — `#000000`): pure black text on the white CTA — the only place black appears as text in the system. -### Surface & Background -- **Deep Background** (`#07080a`): Page canvas, the darkest surface -- **Surface 100** (`#101111`): Elevated surface, card backgrounds -- **Key Start** (`#121212`): Keyboard key gradient start -- **Key End** (`#0d0d0d`): Keyboard key gradient end -- **Card Surface** (`#1b1c1e`): Badge backgrounds, tag fills, elevated containers -- **Button Foreground** (`#18191a`): Dark surface for button text on light backgrounds +### Surface +- **Canvas** (`{colors.canvas}` — `#07080a`): pure-near-black page background. The dominant surface across every page. +- **Surface** (`{colors.surface}` — `#0d0d0d`): card and elevated panel background — one notch lighter than canvas. +- **Surface Elevated** (`{colors.surface-elevated}` — `#101111`): button-tertiary fill, text-input fill, store-search-bar fill, pill-tab-active fill. +- **Surface Card** (`{colors.surface-card}` — `#121212`): app-icon-tile background, keycap fill, command-palette row hover. +- **Button FG (in-card)** (`{colors.button-fg}` — `#18191a`): rare deep-card variant used inside featured pricing tier card backgrounds. +- **Hairline** (`{colors.hairline}` — `#242728`): the universal 1px card border. Carries every card edge across every page. +- **Hairline Soft** (`{colors.hairline-soft}` — `rgba(255,255,255,0.08)`): even fainter border on translucent over-image overlays. +- **Hairline Strong** (`{colors.hairline-strong}` — `rgba(255,255,255,0.16)`): stronger 1px divider where a regular hairline reads as too soft. -### Neutrals & Text -- **Near White** (`#f9f9f9` / `hsl(240, 11%, 96%)`): Primary body text, high-emphasis content -- **Light Gray** (`#cecece` / `#cdcdce`): Secondary body text, descriptions -- **Silver** (`#c0c0c0`): Tertiary text, subdued labels -- **Medium Gray** (`#9c9c9d`): Link default color, secondary navigation -- **Dim Gray** (`#6a6b6c`): Disabled text, low-emphasis labels -- **Dark Gray** (`#434345`): Muted borders, inactive navigation links -- **Border** (`hsl(195, 5%, 15%)` / ~`#252829`): Standard border color for cards and dividers -- **Dark Border** (`#2f3031`): Separator lines, table borders +### Text +- **Ink** (`{colors.ink}` — `#f4f4f6`): primary headlines on dark canvas. Slightly off-white for tonal coherence with the near-black background. +- **Body** (`{colors.body}` — `#cdcdcd`): default paragraph text and inline-link color. +- **Charcoal** (`{colors.charcoal}` — `#d3d3d4`): subtly brighter body where ink reads too soft. +- **Mute** (`{colors.mute}` — `#9c9c9d`): metadata, footer link text, secondary captions. +- **Ash** (`{colors.ash}` — `#6a6b6c`): disabled-state text, lowest-emphasis utility. +- **Stone** (`{colors.stone}` — `#434345`): least-emphasis caption text and disabled icon color. +- **On Dark** (`{colors.on-dark}` — `#ffffff`): interactive-state primary text (button label, focused tab). +- **On Dark Mute** (`{colors.on-dark-mute}` — `rgba(255,255,255,0.72)`): translucent secondary text on dark surfaces. -### Semantic & Accent -- **Error Red** (`hsl(0, 100%, 69%)`): Error states, destructive actions -- **Success Green** (`hsl(151, 59%, 59%)`): Success confirmations, positive states -- **Warning Yellow** (`hsl(43, 100%, 60%)`): Warnings, attention-needed states -- **Info Blue** (`hsl(202, 100%, 67%)`): Informational highlights, links +### Semantic +- **Accent Blue** (`{colors.accent-blue}` — `#57c1ff`) + **Soft** (`{colors.accent-blue-soft}` — `rgba(87,193,255,0.15)`): info and informational badge — used inside feature illustrations and the rare "New" pill. +- **Accent Red** (`{colors.accent-red}` — `#ff6161`) + **Soft** (`{colors.accent-red-soft}` — `rgba(255,97,97,0.15)`): destructive/error indicator + Slack/Apple category accent in extension illustrations. +- **Accent Green** (`{colors.accent-green}` — `#59d499`) + **Soft** (`{colors.accent-green-soft}` — `rgba(89,212,153,0.15)`): success state + productivity category accent in extension illustrations. +- **Accent Yellow** (`{colors.accent-yellow}` — `#ffc533`) + **Soft** (`{colors.accent-yellow-soft}` — `rgba(255,197,51,0.15)`): "warning" semantic + the Hacker News orange-yellow that appears as the most prominent accent illustration on the home page hero. -### Gradient System -- **Keyboard Key Gradient**: Linear gradient from `#121212` (top) to `#0d0d0d` (bottom) — simulates physical key depth -- **Warm Glow**: `rgba(215, 201, 175, 0.05)` radial spread — subtle warm ambient glow behind featured elements +### Brand Gradient +- **Hero Stripe Gradient** — three diagonal red stripes layered across the very top of the home page hero, fading from `{colors.hero-stripe-start}` (`#ff5757`) to `{colors.hero-stripe-end}` (`#a1131a`). The system's only chromatic gradient on chrome — used once per page maximum and reserved for hero launch-banner moments. +- **Keycap Gradient** — the small key-glyph background uses a subtle linear-gradient from `{colors.key-bg-start}` (`#121212`) to `{colors.key-bg-end}` (`#0d0d0d`) that gives Raycast's keycap UI its slight 3D-key feel. -## 3. Typography Rules +## Typography ### Font Family -- **Primary**: `Inter` — humanist sans-serif, used everywhere. Fallbacks: `Inter Fallback`, system sans-serif -- **System**: `SF Pro Text` — Apple system font for select macOS-native UI elements. Fallbacks: `SF Pro Icons`, `Inter`, `Inter Fallback` -- **Monospace**: `GeistMono` — Vercel's monospace font for code elements. Fallbacks: `ui-monospace`, `SFMono-Regular`, `Roboto Mono`, `Menlo`, `Monaco` -- **OpenType features**: `calt`, `kern`, `liga`, `ss03` enabled globally; `ss02`, `ss08` on display text; `liga` disabled (`"liga" 0`) on hero headings +**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 `` chips in documentation; the marketing pages use Inter for everything. ### Hierarchy -| Role | Size | Weight | Line Height | Letter Spacing | Notes | -|------|------|--------|-------------|----------------|-------| -| Display Hero | 64px | 600 | 1.10 | 0px | OpenType: liga 0, ss02, ss08 | -| Section Display | 56px | 400 | 1.17 | 0.2px | OpenType: calt, kern, liga, ss03 | -| Section Heading | 24px | 500 | normal | 0.2px | OpenType: calt, kern, liga, ss03 | -| Card Heading | 22px | 400 | 1.15 | 0px | OpenType: calt, kern, liga, ss03 | -| Sub-heading | 20px | 500 | 1.60 | 0.2px | Relaxed line-height for readability | -| Body Large | 18px | 400 | 1.15 | 0.2px | OpenType: calt, kern, liga, ss03 | -| Body | 16px | 500 | 1.60 | 0.2px | Primary body text, relaxed rhythm | -| Body Tight | 16px | 400 | 1.15 | 0.1px | UI labels, compact contexts | -| Button | 16px | 600 | 1.15 | 0.3px | Semibold, slightly wider tracking | -| Nav Link | 16px | 500 | 1.40 | 0.3px | Links in navigation | -| Caption | 14px | 500 | 1.14 | 0.2px | Small labels, metadata | -| Caption Bold | 14px | 600 | 1.40 | 0px | Emphasized captions | -| Small | 12px | 600 | 1.33 | 0px | Badges, tags, micro-labels | -| Small Link | 12px | 400 | 1.50 | 0.4px | Footer links, fine print | -| Code | 14px (GeistMono) | 500 | 1.60 | 0.3px | Code blocks, technical content | -| Code Small | 12px (GeistMono) | 400 | 1.60 | 0.2px | Inline code, terminal output | +| 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 -- **Positive tracking on dark**: Unlike most dark UIs that use tight or neutral letter-spacing, Raycast applies +0.2px to +0.4px — creating an airy, readable feel that compensates for the dark background -- **Weight 500 as baseline**: Most body text uses medium weight (500), not regular (400) — subtle extra heft improves legibility on dark surfaces -- **Display restraint**: Hero text at 64px/600 is confident but not oversized — Raycast avoids typographic spectacle in favor of functional elegance -- **OpenType everywhere**: `ss03` (stylistic set 3) is enabled globally across Inter, giving the typeface a slightly more geometric, tool-like quality +The 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. -## 4. Component Stylings +### Note on Font Substitutes +Inter 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. -### Buttons -- **Primary Pill**: Transparent background, white text, pill shape (86px radius), multi-layer inset shadow (`rgba(255, 255, 255, 0.1) 0px 1px 0px 0px inset`). Hover: opacity 0.6 -- **Secondary Button**: Transparent background, white text, 6px radius, `1px solid rgba(255, 255, 255, 0.1)` border, subtle drop shadow (`rgba(0, 0, 0, 0.03) 0px 7px 3px`). Hover: opacity 0.6 -- **Ghost Button**: No background or border, gray text (`#6a6b6c`), 86px radius, same inset shadow. Hover: opacity 0.6, text brightens to white -- **CTA (Download)**: Semi-transparent white background (`hsla(0, 0%, 100%, 0.815)`), dark text (`#18191a`), pill shape. Hover: full white background (`hsl(0, 0%, 100%)`) -- **Transition**: All buttons use opacity transition for hover rather than background-color change — a signature Raycast interaction pattern - -### Cards & Containers -- **Standard Card**: `#101111` surface, `1px solid rgba(255, 255, 255, 0.06)` border, 12px–16px border-radius -- **Elevated Card**: Ring shadow `rgb(27, 28, 30) 0px 0px 0px 1px` outer + `rgb(7, 8, 10) 0px 0px 0px 1px inset` inner — creates a double-ring containment -- **Feature Card**: 16px–20px border-radius, subtle warm glow (`rgba(215, 201, 175, 0.05) 0px 0px 20px 5px`) behind hero elements -- **Hover**: Cards brighten slightly via border opacity increase or subtle shadow enhancement - -### Inputs & Forms -- Dark input fields with `#07080a` background, `1px solid rgba(255, 255, 255, 0.08)` border, 8px border-radius -- Focus state: Border brightens, blue glow (`hsla(202, 100%, 67%, 0.15)`) ring appears -- Text: `#f9f9f9` input color, `#6a6b6c` placeholder -- Labels: `#9c9c9d` at 14px weight 500 - -### Navigation -- **Top nav**: Dark background blending with page, white text links at 16px weight 500 -- **Nav links**: Gray text (`#9c9c9d`) → white on hover, underline decoration on hover -- **CTA button**: Semi-transparent white pill at nav end -- **Mobile**: Collapses to hamburger, maintains dark theme -- **Sticky**: Nav fixed at top with subtle border separator - -### Image Treatment -- **Product screenshots**: macOS window chrome style — rounded corners (12px), deep shadows simulating floating windows -- **Full-bleed sections**: Dark screenshots blend seamlessly into the dark background -- **Hero illustration**: Diagonal stripe pattern in Raycast Red — abstract, geometric, brand-defining -- **App UI embeds**: Showing actual Raycast command palette and extensions — product as content - -### Keyboard Shortcut Keys -- **Key cap styling**: Gradient background (`#121212` → `#0d0d0d`), heavy multi-layer shadow (`rgba(0, 0, 0, 0.4) 0px 1.5px 0.5px 2.5px` + inset shadows), creating realistic physical key appearance -- Border-radius: 4px–6px for individual keys - -### Badges & Tags -- **Neutral badge**: `#1b1c1e` background, white text, 6px radius, 14px font at weight 500, `0px 6px` padding -- Compact, pill-like treatment for categorization - -## 5. Layout Principles +## Layout ### Spacing System -- **Base unit**: 8px -- **Scale**: 1px, 2px, 3px, 4px, 8px, 10px, 12px, 16px, 20px, 24px, 32px, 40px -- **Section padding**: 80px–120px vertical between major sections -- **Card padding**: 16px–32px internal spacing -- **Component gaps**: 8px–16px between related elements +- **Base unit:** 8px (with 2/4/12px steps for tight inline gaps). +- **Tokens (front matter):** `{spacing.xxs}` (2px) · `{spacing.xs}` (4px) · `{spacing.sm}` (8px) · `{spacing.md}` (12px) · `{spacing.lg}` (16px) · `{spacing.xl}` (24px) · `{spacing.xxl}` (32px) · `{spacing.section}` (96px). +- **Universal section rhythm:** every page in the set uses `{spacing.section}` (96px) as the vertical gap between major content blocks. Card grids use `{spacing.lg}` (16px) gutters; in-card padding sits at `{spacing.xl}` (24px) for feature cards and `{spacing.lg}` (16px) for store extension cards. ### Grid & Container -- **Max width**: ~1200px container (breakpoint at 1204px), centered -- **Column patterns**: Single-column hero, 2–3 column feature grids, full-width showcase sections -- **App showcase**: Product UI presented in centered window frames +- **Max width:** ~1240px content area at desktop with 24px gutters (~48px at ultrawide). Hero command-palette mockups run wider (~1080px) with the page background extending to full bleed. +- **Store extension grid:** 2-up at desktop with rows of 2 cards stacked, collapsing to 1-up at mobile. Each card is a horizontal layout with a large square app icon at the left and copy + Install button at the right. +- **Pricing tier grid:** 3-up at desktop (Free / Pro / Pro+Advanced AI), collapsing to 1-up stacked at mobile. +- **Featured extension card grid:** 3-up at desktop in the "Featured" row at the top of the store page. +- **Comparison table:** full-width on the pricing page below the tier cards — 5-column table (Free / Pro / Advanced AI / Custom for Teams / Enterprise) with feature rows. +- **Footer:** 6-column horizontal link grid at desktop, collapsing to 2-up at tablet and 1-up at mobile. ### Whitespace Philosophy -- **Dramatic negative space**: Sections float in vast dark void, creating cinematic pacing between features -- **Dense product, sparse marketing**: The product UI screenshots are information-dense, but the surrounding marketing copy uses minimal text with generous spacing -- **Vertical rhythm**: Consistent 24px–32px gaps between elements within sections +Whitespace 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. -### Border Radius Scale -- **2px–3px**: Micro-elements, code spans, tiny indicators -- **4px–5px**: Keyboard keys, small interactive elements -- **6px**: Buttons, badges, tags — the workhorse radius -- **8px**: Input fields, inline components -- **9px–11px**: Images, medium containers -- **12px**: Standard cards, product screenshots -- **16px**: Large cards, feature sections -- **20px**: Hero cards, prominent containers -- **86px+**: Pill buttons, nav CTAs — full pill shape - -## 6. Depth & Elevation +## Elevation & Depth | Level | Treatment | Use | -|-------|-----------|-----| -| Level 0 (Void) | No shadow, `#07080a` surface | Page background | -| Level 1 (Subtle) | `rgba(0, 0, 0, 0.28) 0px 1.189px 2.377px` | Minimal lift, inline elements | -| Level 2 (Ring) | `rgb(27, 28, 30) 0px 0px 0px 1px` outer + `rgb(7, 8, 10) 0px 0px 0px 1px inset` inner | Card containment, double-ring technique | -| Level 3 (Button) | `rgba(255, 255, 255, 0.05) 0px 1px 0px 0px inset` + `rgba(255, 255, 255, 0.25) 0px 0px 0px 1px` + `rgba(0, 0, 0, 0.2) 0px -1px 0px 0px inset` | macOS-native button press — white highlight top, dark inset bottom | -| Level 4 (Key) | 5-layer shadow stack with inset press effects | Keyboard shortcut key caps — physical 3D appearance | -| Level 5 (Floating) | `rgba(0, 0, 0, 0.5) 0px 0px 0px 2px` + `rgba(255, 255, 255, 0.19) 0px 0px 14px` + insets | Command palette, floating panels — heavy depth with glow | +|---|---|---| +| 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 | -### Shadow Philosophy -Raycast's shadow system is the most macOS-native on the web. Multi-layer shadows combine: -- **Outer rings** for containment (replacing traditional borders) -- **Inset top highlights** (`rgba(255, 255, 255, 0.05–0.25)`) simulating light source from above -- **Inset bottom darks** (`rgba(0, 0, 0, 0.2)`) simulating shadow underneath -- The effect is physical: elements feel like glass or brushed metal, not flat rectangles +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 -- **Warm glow**: `rgba(215, 201, 175, 0.05) 0px 0px 20px 5px` behind featured elements — a subtle warm aura on the cold dark canvas -- **Blue info glow**: `rgba(0, 153, 255, 0.15)` for interactive state emphasis -- **Red danger glow**: `rgba(255, 99, 99, 0.15)` for error/destructive state emphasis +Depth comes from product imagery and a single stripe-gradient band: +- **Hero stripe gradient** — three diagonal red stripes (`{colors.hero-stripe-start}` → `{colors.hero-stripe-end}`) layered across the home-page hero band, evoking a launch-banner / motion-blur effect. The system's signature decorative moment. +- **Command-palette mockups** — full-fidelity Raycast in-product UI screenshots (the actual Spotlight-style overlay with rounded keycaps, command rows, and accent-color glyphs) sitting inside the home-page hero and feature rows. These ARE the brand decoration. +- **App icon tiles** — small 48–64px rounded-corner tiles displaying real app icons (Slack, Spotify, Figma, Notion, Linear, Hacker News) inside store and feature illustrations. +- **Keycap glyphs** — subtle gradient-filled rounded keycap glyphs used inline to indicate keyboard shortcuts (e.g., `⌘ K`), with a faint `{colors.key-bg-start}` → `{colors.key-bg-end}` linear gradient suggesting a physical key surface. -## 7. Do's and Don'ts +## Shapes + +### Border Radius Scale + +| 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 +There is no traditional photography. Visual elements are limited to: +- **Command-palette mockups** — full-fidelity Raycast UI screenshots at 16:9 or 4:3 aspect inside `{rounded.xl}` (16px) containers. +- **App icon tiles** — 48–64px square at `{rounded.md}` (8px), displaying real app icons. +- **Avatar circles** — 32–40px at `{rounded.full}` for in-extension author attribution. +- **Hero stripe gradient** — full-bleed wash with no aspect ratio. + +## Components + +> **No hover states documented** per system policy. Each spec covers Default and Active/Pressed only. + +### Buttons + +**`button-primary`** — the universal Raycast CTA +- Background `{colors.primary}` (white), text `{colors.on-primary}` (black), type `{typography.button-md}`, padding `8px 16px`, height ~36px, rounded `{rounded.md}`. +- Used for "Download" (sticky top-nav CTA), "Get Pro", "Install" — every primary action across every surface. +- Pressed state lives in `button-primary-pressed` — background dims to `{colors.primary-pressed}`. + +**`button-secondary`** — transparent text button +- Background transparent, text `{colors.on-dark}`, type `{typography.button-md}`, padding `8px 16px`, height ~36px, rounded `{rounded.md}`. +- Lower-emphasis action: "Sign in" (top nav), "Learn more →", "View on GitHub". + +**`button-tertiary`** — soft surface button +- Background `{colors.surface-elevated}`, text `{colors.on-dark}`, type `{typography.button-md}`, padding `8px 16px`, height ~36px, rounded `{rounded.md}`. +- Mid-emphasis: "Watch demo", "View extension", "Manage" buttons inside cards. + +**`button-disabled`** +- Background `{colors.surface-elevated}`, text `{colors.ash}` — dim utility state. + +**`install-button`** — the store-page install pill +- Background transparent with 1px solid `{colors.hairline-strong}` border, text `{colors.on-dark}`, type `{typography.button-md}`, padding `6px 14px`, rounded `{rounded.md}`. +- Sits at the right edge of every store extension card with the label "Install Extension". + +### Filter & Tab Chips + +**`pill-tab`** + **`pill-tab-active`** — small filter chip strip +- Default: transparent background, text `{colors.body}`, type `{typography.body-sm}`, padding `4px 10px`, rounded `{rounded.full}`. +- Active: background flips to `{colors.surface-elevated}`, text `{colors.on-dark}` — the chip "lifts" by one surface notch. +- Used in the store filter row ("All Extensions", "Recently Added", "Most Popular") and similar segmented controls. + +**`badge-pro`** — small Pro/Plan label +- Background `{colors.surface-elevated}`, text `{colors.on-dark-mute}`, type `{typography.caption-sm}`, padding `2px 6px`, rounded `{rounded.xs}`. +- Inline "Pro" / "Pro+" / "Free" tier indicators on pricing tier cards. + +**`badge-info-soft`** — translucent info chip +- Background `{colors.accent-blue-soft}`, text `{colors.accent-blue}`, type `{typography.caption-sm}`, padding `2px 8px`, rounded `{rounded.xs}`. +- Rare "New" / "Beta" inline tag. + +### Inputs & Forms + +**`text-input`** + **`text-input-focused`** +- Default: background `{colors.surface-elevated}`, text `{colors.on-dark}`, 1px solid `{colors.hairline}`, type `{typography.body-md}`, padding `8px 12px`, height ~36px, rounded `{rounded.md}`. +- Focused: same surface; 1px border becomes `{colors.hairline-strong}` — a subtle brightening rather than a colored ring. + +**`store-search-bar`** — the store-page search field +- Background `{colors.surface-elevated}`, text `{colors.on-dark}`, type `{typography.body-md}`, padding `10px 16px`, height ~44px, rounded `{rounded.md}`. +- Sits at the top of the store page hero with a magnifier icon at the left and "Search the store..." placeholder. Slightly taller than the standard `text-input`. + +### Cards & Containers + +**`command-palette-card`** — the home-page hero command-palette mockup +- Container: background `{colors.surface}`, 1px solid `{colors.hairline}`, padding 0 (the mockup contents fill the card), rounded `{rounded.lg}` or `{rounded.xl}` depending on hero size. +- Layout: top header strip with macOS traffic-light dots + a search input row, body with a vertical stack of `{component.command-palette-row}` items, bottom-right keycap hint cluster. + +**`command-palette-row`** + **`command-palette-row-active`** — single row inside the command palette +- Default: transparent background, text `{colors.on-dark}` in `{typography.body-md}`, padding `6px 10px`, rounded `{rounded.sm}`. +- Active: background `{colors.surface-card}` (one notch lighter than the surrounding palette card) — the selection state. +- Each row contains a small app-icon tile + label + optional keycap shortcut at the right edge. + +**`feature-card-dark`** — standard product feature card +- Container: background `{colors.surface}`, 1px solid `{colors.hairline}`, padding `{spacing.xl}` (24px), rounded `{rounded.lg}`. +- Used in 2- or 3-up grids on home and feature pages — pairs a small product mockup or app-icon row with body copy and a "Learn more →" `{component.button-secondary}`. + +**`feature-card-elevated`** — slightly-elevated variant +- Same chrome as `feature-card-dark` but background flips to `{colors.surface-elevated}` — used to break visual rhythm in alternating feature rows. + +**`store-extension-card`** — store-page extension card +- Container: background `{colors.surface}`, 1px solid `{colors.hairline}`, padding `{spacing.lg}` (16px), rounded `{rounded.md}`. +- Layout: 48px `{component.app-icon-tile}` at left, vertical stack of name + by-author metadata + 1-line description in the center, `{component.install-button}` at the right edge. + +**`pricing-tier-card`** — pricing plan card (default tier) +- Container: background `{colors.surface}`, 1px solid `{colors.hairline}`, padding `{spacing.xl}` (24px), rounded `{rounded.lg}`. +- Layout: tier name in `{typography.heading-xl}` (24px), price in larger numeric in `{typography.display-lg}`, body description in `{typography.body-lg}`, CTA `{component.button-primary}` (or `{component.button-secondary}` for free tier), feature checklist with `✓` glyphs. + +**`pricing-tier-card-featured`** — middle "Pro" featured tier +- Same chrome but background flips to `{colors.surface-elevated}` (one notch lighter) — the only visual cue distinguishing the featured tier from the surrounding cards. + +**`hero-stripe-band`** — home-page hero with red stripe gradient +- Background `{colors.canvas}` with three diagonal red stripes layered across the top half (`{colors.hero-stripe-start}` → `{colors.hero-stripe-end}`). +- Padding `{spacing.section}` 96px vertical / 48px horizontal, rounded `{rounded.none}`. +- Carries the hero headline in `{typography.display-xl}` and a single `{component.button-primary}` "Download" CTA. + +### Decorative + +**`app-icon-tile`** — small 48px square app icon +- Background `{colors.surface-card}`, padding 0 (icon fills the tile), rounded `{rounded.md}`, size 48×48. +- Used in command-palette rows and store extension cards. + +**`app-icon-tile-large`** — 64px feature variant +- Same but at 64×64. Used in featured store cards and home-page hero illustration rows. + +**`keycap`** — keyboard shortcut glyph +- Background `{colors.surface-card}` with a subtle linear gradient `{colors.key-bg-start}` → `{colors.key-bg-end}`, text `{colors.body}` in `{typography.caption-md}`, padding `1px 6px`, height ~20px, rounded `{rounded.xs}`. +- Renders inline command-palette shortcut hints like `⌘ K`, `⏎`, `Esc`. The signature "physical-key" feel on a flat dark canvas. + +### Navigation + +**`primary-nav`** +- Background `{colors.canvas}`, text `{colors.on-dark}`, height ~56px, type `{typography.body-sm-strong}`, rounded `{rounded.none}`, with a 1px `{colors.hairline}` bottom rule. +- Layout (desktop): Raycast wordmark at left, centered nav cluster ("Pro · AI · Store · Manual · Changelog · Blog · Pricing"), right cluster (Sign in link + the always-white `{component.button-primary}` "Download" CTA pill). + +**Top Nav (Mobile)** +- Hamburger menu icon at left, Raycast wordmark at center, "Download" white CTA pill at right. Primary nav collapses into a full-screen drawer that slides from the left. + +### Footer + +**`footer-section`** +- Background `{colors.canvas}`, text `{colors.body}` in `{typography.body-sm}`, padding `64px 48px`, with a 1px `{colors.hairline}` top rule. +- Layout: 6-column horizontal link grid (Product · Core Features · Top Extensions · Company · Community · By Raycast) with column headers in `{typography.body-sm-strong}` `{colors.on-dark}` and link lists in `{typography.body-sm}` `{colors.body}`. +- Bottom row: small Raycast wordmark + a subscribe newsletter input field with `{component.button-primary}` "Subscribe" at the right. +- The very top of the footer band has a faint red stripe-gradient repeat — a smaller echo of the hero's diagonal stripe motif. + +### Inline + +**`link-inline`** — body-prose anchor link +- `{colors.on-dark}` text with no underline by default; underlines on focus. Inline body links are full-white rather than a tinted accent color, which keeps the dark canvas tonally pure. + +## Do's and Don'ts ### Do -- Use `#07080a` (not pure black) as the background — the blue-cold tint is essential to the Raycast feel -- Apply positive letter-spacing (+0.2px) on body text — this is deliberately different from most dark UIs -- Use multi-layer shadows with inset highlights for interactive elements — the macOS-native depth is signature -- Keep Raycast Red (`#FF6363`) as punctuation, not pervasive — reserve it for hero moments and error states -- Use `rgba(255, 255, 255, 0.06)` borders for card containment — barely visible, structurally essential -- Apply weight 500 as the body text baseline — medium weight improves dark-mode legibility -- Use pill shapes (86px+ radius) for primary CTAs, rectangular shapes (6px–8px) for secondary actions -- Enable OpenType features `calt`, `kern`, `liga`, `ss03` on all Inter text -- Use opacity transitions (hover: opacity 0.6) for button interactions, not color changes +- Render the entire site in one continuous dark mode. There is no light variant in the system. +- Use `{colors.primary}` (white pill) for every primary CTA. There is no second primary color — white IS the brand action. +- Build elevation from the surface-color ladder (`{colors.canvas}` → `{colors.surface}` → `{colors.surface-elevated}` → `{colors.surface-card}`), never from drop shadows. +- Enable `font-feature-settings: "calt", "kern", "liga", "ss03"` on the body element. The ss03 alternate `g` is part of the brand identity. +- Anchor a `{component.command-palette-card}` mockup as the hero's load-bearing visual. Real Raycast UI is the brand. +- Use `{component.keycap}` glyphs inline to indicate keyboard shortcuts. Subtle key-bg gradient (`{colors.key-bg-start}` → `{colors.key-bg-end}`) is the brand's only "depth" decoration. +- Reserve `{colors.hero-stripe-start}` → `{colors.hero-stripe-end}` red gradient for the hero band exactly once per page. Never repeat the stripe gradient deeper in the page. +- Use saturated category accents (`{colors.accent-yellow}`, `{colors.accent-red}`, `{colors.accent-green}`, `{colors.accent-blue}`) only inside extension and feature illustrations — never on chrome buttons or text. ### Don't -- Use pure black (`#000000`) as the background — the blue tint differentiates Raycast from generic dark themes -- Apply negative letter-spacing on body text — Raycast deliberately uses positive spacing for readability -- Use Raycast Blue as the primary accent for everything — blue is for interactive/info, red is the brand color -- Create single-layer flat shadows — the multi-layer inset system is core to the macOS-native aesthetic -- Use regular weight (400) for body text when 500 is available — the extra weight prevents dark-mode text from feeling thin -- Mix warm and cool borders — stick to the cool gray (`hsl(195, 5%, 15%)`) border palette -- Apply heavy drop shadows without inset companions — shadows always come in pairs (outer + inset) -- Use decorative elements, gradients, or colorful backgrounds — the dark void is the stage, content is the performer +- Don't introduce a light mode. The system is dark-only by design. +- Don't add drop shadows on cards. Elevation is built from the surface ladder, not from shadows. +- Don't replace `{colors.primary}` (white) with a tinted accent for the primary CTA. Pure white is the brand action color. +- Don't use the saturated accent colors (`{colors.accent-yellow}`, `{colors.accent-red}`, `{colors.accent-green}`, `{colors.accent-blue}`) on text, buttons, or chrome surfaces. They belong inside extension illustrations. +- Don't repeat the hero stripe gradient outside the top hero band. The one-band rule is the system's restraint. +- Don't use Inter without the `ss03` feature flag enabled. The chrome will lose its signature voice. +- Don't pad cards with 32px+ on all sides. The system runs tight at 16–24px in-card padding. -## 8. Responsive Behavior +## Responsive Behavior ### Breakpoints + | Name | Width | Key Changes | -|------|-------|-------------| -| Mobile | <600px | Single column, stacked cards, hamburger nav, hero text reduces to ~40px | -| Small Tablet | 600px–768px | 2-column grid begins, nav partially visible | -| Tablet | 768px–1024px | 2–3 column features, nav expanding, screenshots scale | -| Desktop | 1024px–1200px | Full layout, all nav links visible, 64px hero display | -| Large Desktop | >1200px | Max-width container centered, generous side margins | +|---|---|---| +| 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 -- Pill buttons: 86px radius with 20px padding — well above 44px minimum -- Secondary buttons: 8px padding minimum, but border provides visual target expansion -- Nav links: 16px text with surrounding padding for accessible touch targets +All 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 -- **Navigation**: Full horizontal nav → hamburger at mobile with slide-out menu -- **Hero**: 64px display → 48px → 36px across breakpoints -- **Feature grids**: 3-column → 2-column → single-column stack -- **Product screenshots**: Scale within containers, maintaining macOS window chrome proportions -- **Keyboard shortcut displays**: Simplify or hide on mobile where keyboard shortcuts are irrelevant +- **Primary nav:** desktop horizontal cluster → tablet hamburger drawer at 768px. The white "Download" CTA stays visible at every breakpoint. +- **Hero command-palette mockup:** desktop full-fidelity 2-column with copy at left + mockup at right → tablet stacks vertical with mockup below copy → mobile mockup scales down to ~80% width. +- **Store extension grid:** 2-up → 1-up at tablet. +- **Pricing tier grid:** 3-up → 2+1 at desktop-small → 1-up stacked at tablet. +- **Comparison table:** desktop full 5-column → tablet horizontal scroll → mobile vertical card stack with one tier per card. +- **Footer:** 6-up link columns → 3-up at tablet → 2-up at mobile-landscape → 1-up at mobile. +- **Section padding:** `{spacing.section}` (96px) desktop → 64px tablet → 48px mobile. +- **Hero headline:** `{typography.display-xl}` (64px) at desktop, scaling 56px / 44px / 36px down the breakpoint stack. ### Image Behavior -- Product screenshots scale responsively within fixed-ratio containers -- Hero diagonal stripe pattern scales proportionally -- macOS window chrome rounded corners maintained at all sizes -- No lazy-loading artifacts — images are critical to the product narrative +The only "imagery" in the system is in-product Raycast UI screenshots and small app-icon assets: +- **Command-palette mockups** scale fluidly with the container; the in-product UI itself is responsive and re-renders for each breakpoint. +- **App-icon tiles** stay at 48–64px fixed size at every breakpoint; they tile in flexible rows that wrap at narrower widths. +- **Hero stripe gradient** stays at the top of the hero band at every breakpoint with the stripe angle preserved. -## 9. Agent Prompt Guide +## Iteration Guide -### Quick Color Reference -- Primary Background: Near-Black Blue (`#07080a`) -- Primary Text: Near White (`#f9f9f9`) -- Brand Accent: Raycast Red (`#FF6363`) -- Interactive Blue: Raycast Blue (`hsl(202, 100%, 67%)` / ~`#55b3ff`) -- Secondary Text: Medium Gray (`#9c9c9d`) -- Card Surface: Surface 100 (`#101111`) -- Border: Dark Border (`hsl(195, 5%, 15%)` / ~`#252829`) +1. 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. -### Example Component Prompts -- "Create a hero section on #07080a background with 64px Inter heading (weight 600, line-height 1.1), near-white text (#f9f9f9), and a semi-transparent white pill CTA button (hsla(0,0%,100%,0.815), 86px radius, dark text #18191a)" -- "Design a feature card with #101111 background, 1px solid rgba(255,255,255,0.06) border, 16px border-radius, double-ring shadow (rgb(27,28,30) 0px 0px 0px 1px outer), 22px Inter heading, and #9c9c9d body text" -- "Build a navigation bar on dark background (#07080a), Inter links at 16px weight 500 in #9c9c9d, hover to white, and a translucent white pill button at the right end" -- "Create a keyboard shortcut display with key caps using gradient background (#121212→#0d0d0d), 5-layer shadow for physical depth, 4px radius, Inter 12px weight 600 text" -- "Design an alert card with #101111 surface, Raycast Red (#FF6363) left border accent, translucent red glow (hsla(0,100%,69%,0.15)), white heading, and #cecece description text" +## Known Gaps -### Iteration Guide -When refining existing screens generated with this design system: -1. Check the background is `#07080a` not pure black — the blue tint is critical -2. Verify letter-spacing is positive (+0.2px) on body text — negative spacing breaks the Raycast aesthetic -3. Ensure shadows have both outer and inset layers — single-layer shadows look flat and wrong -4. Confirm Inter has OpenType features `calt`, `kern`, `liga`, `ss03` enabled -5. Test that hover states use opacity transitions (0.6) not color swaps — this is a core interaction pattern +- **Mobile screenshots not captured** — responsive behavior synthesizes Raycast's mobile pattern (hamburger drawer, single-column grid, hero downscale) from desktop evidence and the breakpoint stack. +- **Hover states not documented** by system policy. Raycast's in-product app has rich hover behavior on command-palette rows that this document doesn't capture. +- **In-product app chrome** (the actual Raycast launcher running on macOS) is referenced in marketing screenshots but not documented as a separate UI system here. The marketing site is documented; the in-product app surface is its own design system. +- **Dark mode is the only mode** — no light variant exists in the captured surfaces. +- **Form validation states** beyond the focused-input border treatment are not present in the captured surfaces. +- **Authenticated chrome** (account dashboard, billing settings, team management) not in the captured pages. diff --git a/design-md/renault/DESIGN.md b/design-md/renault/DESIGN.md index 99aaf7d..d0dbb77 100644 --- a/design-md/renault/DESIGN.md +++ b/design-md/renault/DESIGN.md @@ -1,311 +1,589 @@ -# Design System Inspired by Renault +--- +version: alpha +name: Renault +description: | + Renault's web presence pairs the freshly-modernised Renault diamond + (the 2021 flat-line rhombus mark) with a stark black-and-white canvas, a + signature Sunlight Yellow accent, and the proprietary NouvelR display + typeface. The system reads as confident, photography-first automotive — large + hero cars on neutral or atmospheric backdrops, square-edged or barely-rounded + containers, and a small disciplined palette where every coloured element is + intentional. Tile grids, full-bleed banners, and a recurring "configurator" + surface (white card, yellow accent dots, neutral product chrome) carry the + mass-market dealership tone without crossing into luxury. -## 1. Visual Theme & Atmosphere +colors: + primary: "#ffed00" + primary-deep: "#e6d200" + on-primary: "#000000" + ink: "#000000" + body: "#222222" + charcoal: "#333333" + mute: "#666666" + ash: "#8a8a8a" + stone: "#c4c4c4" + on-dark: "#ffffff" + on-dark-mute: "rgba(255,255,255,0.72)" + canvas: "#ffffff" + surface-soft: "#f7f7f7" + surface-card: "#ffffff" + surface-dark: "#000000" + surface-deep: "#111111" + hairline: "#f2f2f2" + hairline-strong: "#000000" + divider-dark: "rgba(255,255,255,0.16)" + badge-new: "#ffed00" + link: "#0000ee" + error: "#be6464" + warning: "#f0ad4e" + success: "#8dc572" + info: "#337ab7" -Renault's website is a vibrant digital showroom that balances French automotive elegance with bold, forward-leaning energy — a departure from the monochromatic austerity of German or Italian luxury brands. The page opens with a full-screen hero that washes the viewport in a sweeping aurora gradient — ribbons of magenta, violet, and teal bleeding across the frame behind a dramatically lit vehicle. This chromatic expressiveness is the site's signature: while the interface structure is disciplined (NouvelR typography, black-and-white CTA framework, zero-radius buttons), the content is alive with color — gradient washes on hero slides, saturated vehicle photography, and splashes of Renault Yellow (`#EFDF00`) on accent CTAs. The effect is a showroom that feels energized rather than hushed. +typography: + display-xl: + fontFamily: NouvelR + fontSize: 56px + fontWeight: 700 + lineHeight: 0.95 + letterSpacing: 0 + display-lg: + fontFamily: NouvelR + fontSize: 40px + fontWeight: 700 + lineHeight: 0.95 + letterSpacing: 0 + display-md: + fontFamily: NouvelR + fontSize: 32px + fontWeight: 700 + lineHeight: 0.95 + letterSpacing: 0 + heading-lg: + fontFamily: NouvelR + fontSize: 24px + fontWeight: 700 + lineHeight: 0.95 + letterSpacing: 0 + heading-md: + fontFamily: NouvelR + fontSize: 20px + fontWeight: 700 + lineHeight: 0.95 + letterSpacing: 0 + heading-sm: + fontFamily: NouvelR + fontSize: 18px + fontWeight: 700 + lineHeight: 1.0 + letterSpacing: 0 + subtitle: + fontFamily: NouvelR + fontSize: 19.2px + fontWeight: 600 + lineHeight: 1.3 + letterSpacing: 0 + body-lg: + fontFamily: NouvelR + fontSize: 18px + fontWeight: 400 + lineHeight: 1.5 + letterSpacing: 0 + body-md: + fontFamily: NouvelR + fontSize: 16px + fontWeight: 400 + lineHeight: 1.4 + letterSpacing: 0 + body-sm: + fontFamily: NouvelR + fontSize: 14px + fontWeight: 400 + lineHeight: 1.57 + letterSpacing: 0 + button-lg: + fontFamily: NouvelR + fontSize: 16px + fontWeight: 700 + lineHeight: 1.0 + letterSpacing: 0 + button-md: + fontFamily: NouvelR + fontSize: 14.4px + fontWeight: 700 + lineHeight: 1.0 + letterSpacing: 0.144px + button-sm: + fontFamily: NouvelR + fontSize: 13px + fontWeight: 600 + lineHeight: 1.2 + letterSpacing: 0.13px + caption: + fontFamily: NouvelR + fontSize: 12px + fontWeight: 400 + lineHeight: 1.4 + letterSpacing: 0 + overline: + fontFamily: NouvelR + fontSize: 10px + fontWeight: 700 + lineHeight: 1.45 + letterSpacing: 0 -The layout follows a card-based editorial rhythm. Below the hero carousel, content is organized into a grid of PromoCards — each a full-bleed photographic panel with a dark gradient overlay at top (fading from `rgba(0,0,0,0.6)` to transparent) to ensure white heading text remains legible over vivid imagery. These cards alternate between light and dark modes: white editorial panels with black text sit beside black `is-alternative-mode` sections with white text, creating a chessboard-like visual cadence. The grid is generous — large card formats dominate, giving each vehicle or campaign its own visual territory. The lower sections shift to a fully dark canvas (Absolute Black backgrounds) for the E-Tech electric and technology showcases, establishing a deliberate mood shift: electrification lives in darkness, tradition in light. +rounded: + none: 0px + xs: 2px + sm: 3px + md: 4px + pill: 46px + full: 9999px -Typography is unified under NouvelR — a proprietary geometric sans-serif designed by Black[Foundry] exclusively for Renault's rebrand. The typeface features a distinctive "radical r" with a terminal cut at 28 degrees to echo the Renault diamond logo's angles. Available in 6 weights from Light to Extrabold, the site primarily uses Bold (700) for headings and Regular (400) for body. Display headlines run large — 56px/0.95 line-height for hero titles, creating dense, impactful text blocks that sit tight against each other. The font supports Latin, Greek, Cyrillic, Hebrew, Arabic, and Korean, reflecting Renault's global market reach. All text rendering feels precise and engineered, with the geometric proportions lending a sense of modernity that aligns with Renault's electric-first brand positioning. +spacing: + xxs: 4px + xs: 8px + sm: 12px + md: 16px + lg: 20px + xl: 24px + xxl: 32px + xxxl: 40px + section: 80px + +components: + button-primary: + backgroundColor: "{colors.primary}" + textColor: "{colors.on-primary}" + typography: "{typography.button-md}" + rounded: "{rounded.xs}" + padding: 14px 24px + height: 48px + button-primary-pressed: + backgroundColor: "{colors.primary-deep}" + textColor: "{colors.on-primary}" + typography: "{typography.button-md}" + rounded: "{rounded.xs}" + button-secondary-dark: + backgroundColor: "{colors.surface-dark}" + textColor: "{colors.on-dark}" + typography: "{typography.button-md}" + rounded: "{rounded.xs}" + padding: 14px 24px + button-outline-dark: + backgroundColor: "{colors.canvas}" + textColor: "{colors.ink}" + typography: "{typography.button-md}" + rounded: "{rounded.xs}" + padding: 13px 23px + button-outline-light: + backgroundColor: "{colors.surface-dark}" + textColor: "{colors.on-dark}" + typography: "{typography.button-md}" + rounded: "{rounded.xs}" + padding: 13px 23px + button-pill: + backgroundColor: "{colors.canvas}" + textColor: "{colors.ink}" + typography: "{typography.button-sm}" + rounded: "{rounded.pill}" + padding: 8px 16px + height: 36px + button-icon-square: + backgroundColor: "{colors.canvas}" + textColor: "{colors.ink}" + rounded: "{rounded.xs}" + size: 40px + text-input: + backgroundColor: "{colors.canvas}" + textColor: "{colors.ink}" + typography: "{typography.body-md}" + rounded: "{rounded.none}" + padding: 12px 16px + height: 48px + hero-banner: + backgroundColor: "{colors.surface-dark}" + textColor: "{colors.on-dark}" + rounded: "{rounded.none}" + padding: 0 + promo-tile-light: + backgroundColor: "{colors.canvas}" + textColor: "{colors.ink}" + typography: "{typography.heading-lg}" + rounded: "{rounded.none}" + padding: 32px + promo-tile-dark: + backgroundColor: "{colors.surface-dark}" + textColor: "{colors.on-dark}" + typography: "{typography.heading-lg}" + rounded: "{rounded.none}" + padding: 32px + promo-tile-yellow: + backgroundColor: "{colors.primary}" + textColor: "{colors.on-primary}" + typography: "{typography.heading-lg}" + rounded: "{rounded.none}" + padding: 32px + vehicle-card: + backgroundColor: "{colors.canvas}" + textColor: "{colors.ink}" + rounded: "{rounded.none}" + padding: 0 + configurator-row: + backgroundColor: "{colors.canvas}" + textColor: "{colors.ink}" + typography: "{typography.body-md}" + rounded: "{rounded.none}" + padding: 24px 0 + configurator-swatch: + backgroundColor: "{colors.surface-soft}" + rounded: "{rounded.full}" + size: 56px + badge-new: + backgroundColor: "{colors.badge-new}" + textColor: "{colors.on-primary}" + typography: "{typography.button-md}" + rounded: "{rounded.full}" + padding: 6px 14px + nav-bar: + backgroundColor: "{colors.canvas}" + textColor: "{colors.ink}" + typography: "{typography.button-md}" + rounded: "{rounded.none}" + height: 60px + sub-nav-pill: + backgroundColor: "{colors.canvas}" + textColor: "{colors.ink}" + typography: "{typography.button-sm}" + rounded: "{rounded.pill}" + padding: 8px 16px + footer: + backgroundColor: "{colors.surface-dark}" + textColor: "{colors.on-dark}" + typography: "{typography.body-sm}" + rounded: "{rounded.none}" + padding: 64px 24px +--- + +## Overview + +Renault's Turkish marketing surfaces are unapologetically high-contrast: a +white canvas for browsing, a black canvas for product storytelling, and a +single Sunlight Yellow accent (`{colors.primary}` — `#ffed00`) reserved for +the most consequential actions. The brand's modernised flat diamond logo sets +the tone — geometric, confident, slightly industrial — and the system follows +suit. Square corners dominate, hairline borders are rare, and elevation is +expressed through colour blocking rather than shadow. + +The typography is monolithic. Every text on the site is set in **NouvelR**, +Renault's bespoke display family, with a strong preference for weight 700 at +display sizes (with a tight `lineHeight: 0.95`) and weight 400 for body. There +is no secondary serif, no decorative italic, no script — the discipline is +the signature. + +Page rhythm cycles between three surface modes: a **white catalogue mode** for +listings and configurators (`{colors.canvas}` with hairline-thin +`{colors.hairline}` dividers), a **black storytelling mode** for hero +sections, lifestyle imagery, and the lower half of campaign pages, and brief +**yellow accent moments** (`{colors.primary}` tiles, "NEW" badges, R5-coded +yellow paint shots) that punctuate the otherwise neutral palette. **Key Characteristics:** -- Full-screen hero carousel with vivid aurora gradient backgrounds (magenta/violet/teal) behind vehicle imagery -- NouvelR proprietary typeface with 28-degree "radical r" cut matching the diamond logo geometry -- Renault Yellow (`#EFDF00`) as the super-primary accent — used sparingly for highest-priority CTAs -- Zero border-radius on all buttons — sharp rectangular forms expressing precision engineering -- Card-based editorial grid with full-bleed photography and dark gradient overlays -- Binary black/white CTA system: primary (black bg/white text) and ghost (transparent/white border) -- PromoCard dark-mode alternation creating a chessboard rhythm between light and dark sections -- PrimeReact (21 components) + Element Plus (19 components) powering interactive elements -- Link hover state in Renault Blue (`#1883FD`) — the sole chromatic interaction color +- Two-tone canvas system — `{colors.canvas}` (white) for browsing, `{colors.surface-dark}` (black) for storytelling — switched in full-bleed bands rather than subtle gradations. +- A single brand accent — `{colors.primary}` Sunlight Yellow — used scarcely on primary CTAs, "NEW" badges, R5 hero photography, and configurator dot indicators. +- **NouvelR everywhere**, with `{typography.display-xl}` headlines at 56px / weight 700 / `lineHeight: 0.95` so condensed multi-line headlines stack cleanly. +- Square geometry: `{rounded.xs}` (2px) on buttons, `{rounded.none}` on tiles and product cards, `{rounded.pill}` reserved exclusively for sub-nav chips and decorative badges. +- Photography-first product tiles — vehicle photos full-bleed inside otherwise neutral cards, with copy stacked beneath rather than overlaid. +- Page-level rhythm cycles white → black → yellow accent → black, with the wordmark and footer always closing on `{colors.surface-dark}`. -## 2. Color Palette & Roles +## Colors -### Primary -- **Renault Yellow** (`#EFDF00`): The brand's signature Pantone — a vivid, saturated yellow used for super-primary CTAs and the highest-priority action buttons. Appears as `--CtaLink-background-color` on `.is-cta-super-primary` class. Carries the energy of the diamond logo -- **Absolute Black** (`#000000`): Primary button background, heading text on light surfaces, and the dominant dark section surface. The structural anchor of the entire interface -- **Pure White** (`#FFFFFF`): Primary surface for editorial content, inverted button backgrounds, hero text color, and the dominant light-mode canvas (--rt-color-white) +### Brand & Accent +- **Sunlight Yellow** (`{colors.primary}` — `#ffed00`): the brand accent. Reserved for primary CTAs, "NEW" / "yeni" badges, configurator dot indicators, and full-bleed promotional tiles. Never decorative. +- **Sunlight Yellow Pressed** (`{colors.primary-deep}` — `#e6d200`): the active/pressed state of `{colors.primary}` buttons and tiles. +- **On-Primary** (`{colors.on-primary}` — `#000000`): label colour on top of `{colors.primary}` surfaces. Yellow always pairs with black text — never white. -### Secondary & Accent -- **Soft Yellow** (`#F8EB4C`): Lighter, warmer variant of Renault Yellow — used for hover/pressed states on yellow CTAs and secondary accent contexts -- **Renault Blue** (`#1883FD`): Link hover color across all link variants — a bright, confident blue that signals interactivity without competing with the yellow brand accent -- **Warm Gray** (`#D9D9D6`): Subtle warm neutral used for disabled states, inactive UI elements, and soft borders — carries a slight warmth that distinguishes it from cold grays +### Surface +- **Canvas** (`{colors.canvas}` — `#ffffff`): the default page background and card surface. +- **Surface Soft** (`{colors.surface-soft}` — `#f7f7f7`): subtle elevation step for grouped configurator rows and inactive form fields. +- **Surface Dark** (`{colors.surface-dark}` — `#000000`): the alternate canvas, used for hero bands, footer, and full-bleed storytelling sections. +- **Surface Deep** (`{colors.surface-deep}` — `#111111`): a one-step-up elevation inside `{colors.surface-dark}` regions for inset cards and form panels. +- **Hairline** (`{colors.hairline}` — `#f2f2f2`): the soft 1px divider between rows on white surfaces. +- **Hairline Strong** (`{colors.hairline-strong}` — `#000000`): full-strength dividers on white, plus all card / button outlines. +- **Divider Dark** (`{colors.divider-dark}` — `rgba(255,255,255,0.16)`): the corresponding low-contrast divider used inside `{colors.surface-dark}` regions. -### Surface & Background -- **Pure White** (`#FFFFFF`): Page background, light editorial sections, navigation bar, and footer -- **Absolute Black** (`#000000`): Hero backgrounds, PromoCard dark-mode sections (`is-alternative-mode`), and E-Tech showcase areas -- **Charcoal** (`#222222`): Secondary dark surface for text-heavy dark sections and footer sub-regions (--rt-color-dark) -- **Pale Silver** (`#F2F2F2`): Subtle alternate light surface for section differentiation and card borders +### Text +- **Ink** (`{colors.ink}` — `#000000`): primary text colour on white surfaces. The same value also drives logos, icons, and outline borders — black is structural, not decorative. +- **Body** (`{colors.body}` — `#222222`): secondary body text where pure black would feel too heavy in long paragraphs. +- **Charcoal** (`{colors.charcoal}` — `#333333`): captions, metadata, and small labels. +- **Mute** (`{colors.mute}` — `#666666`): supporting text and inactive nav labels. +- **Ash** (`{colors.ash}` — `#8a8a8a`): placeholder text, disabled labels. +- **Stone** (`{colors.stone}` — `#c4c4c4`): disabled-state foreground. +- **On-Dark** (`{colors.on-dark}` — `#ffffff`): primary text on `{colors.surface-dark}` surfaces. +- **On-Dark Mute** (`{colors.on-dark-mute}` — `rgba(255,255,255,0.72)`): secondary text in dark regions; preserves the brand's high-contrast feel without resorting to mid-grey. -### Neutrals & Text -- **Absolute Black** (`#000000`): Primary heading and body text on light surfaces — Renault uses true black rather than near-black -- **Pure White** (`#FFFFFF`): Primary text on dark surfaces — hero headlines, dark-section headings, and inverted button labels -- **Warm Gray** (`#D9D9D6`): Tertiary text, metadata, and subdued labels -- **Border Gray** (`#D1D1D1`): Input field borders and subtle separators +### Semantic +- **Error** (`{colors.error}` — `#be6464`): muted desaturated red used for inline form errors. Notably warmer than typical pure-red error states. +- **Warning** (`{colors.warning}` — `#f0ad4e`): amber alert. +- **Success** (`{colors.success}` — `#8dc572`): muted green confirmation. +- **Info** (`{colors.info}` — `#337ab7`): a desaturated mid-blue used in informational chips. +- **Link** (`{colors.link}` — `#0000ee`): the unstyled-anchor default kept for fallback inline text links — production links inherit `{colors.ink}` and rely on underline/weight rather than colour. -### Semantic & Accent -- **Success Green** (`#8DC572`): Positive status indicators and confirmation messages (--rt-color-success) -- **Error Rose** (`#BE6464`): Form validation errors and warning states (--rt-color-error) -- **Warning Amber** (`#F0AD4E`): Cautionary alerts and attention-requiring states (--rt-color-warning) -- **Info Blue** (`#337AB7`): Informational callouts and neutral status messaging (--rt-color-info) - -### Gradient System -- **Hero Aurora**: Sweeping multi-color gradients (magenta → violet → teal) applied to hero slide backgrounds — the site's most distinctive visual element. These are photographic/composited rather than CSS gradients -- **PromoCard Overlay**: `linear-gradient(rgba(0,0,0,0.6) 0%, rgba(0,0,0,0) 40%)` — applied to card tops to ensure heading text legibility over photography -- No flat CSS gradients on surfaces — depth comes from photographic treatment and the black/white alternation - -## 3. Typography Rules +## Typography ### Font Family -- **NouvelR**: The sole typeface. A proprietary geometric sans-serif designed by Black[Foundry] for Renault's 2021+ rebrand. Features a distinctive "radical r" with a 28-degree terminal cut matching the diamond logo angle. Available in 6 weights (Light to Extrabold), supports 6 writing systems. Fallback: `sans-serif`. Declared as `"NouvelR, sans-serif"` in CSS -- **No secondary typeface**: Unlike Ferrari (FerrariSans + Body-Font) or Lamborghini (LamboType + Open Sans), Renault uses a single font family for all text — headings, body, buttons, captions, and navigation + +The entire system is set in **NouvelR**, Renault's proprietary display +family, used across navigation, headlines, body, captions, and button +labels. The family carries a slightly geometric, semi-condensed personality +with tall x-heights and squared apexes that pair naturally with the diamond +logomark. + +When NouvelR cannot be licensed, suitable open-source substitutes include +**Inter Tight**, **Manrope**, or **HK Grotesk Semi Condensed** — all share +the geometric-with-warmth feel and adapt cleanly to weights 400 / 600 / 700. +Tighten `lineHeight` on display sizes to ~0.95 to match the original; do not +relax it. ### Hierarchy -| Role | Size | Weight | Line Height | Letter Spacing | Notes | -|------|------|--------|-------------|----------------|-------| -| Hero Title | 56px (3.50rem) | 700 | 0.95 (53.2px) | normal | NouvelR, white on dark hero, all-caps model names | -| Section Heading | 40px (2.50rem) | 700 | 0.95 (38px) | normal | NouvelR, PromoCard headings on dark/light sections | -| Card Heading | 32px (2.00rem) | 700 | 0.95 | normal | NouvelR, medium-scale card headings | -| Subheading | 24px (1.50rem) | 700 | 0.95 | normal | NouvelR, section sub-titles | -| Module Title | 21.92px (1.37rem) | 600 | 1.20 | normal | NouvelR, component headings | -| Content Title | 20px (1.25rem) | 700 | 0.95 | normal | NouvelR, smaller section titles | -| UI Heading | 19.2px (1.20rem) | 600 | 1.30 | normal | NouvelR, card UI headings | -| Emphasis | 18px (1.13rem) | 700 | 1.00 | normal | NouvelR, emphasized inline text and links | -| Body Heading | 16px (1.00rem) | 700 | 1.40 | normal | NouvelR, paragraph-level headings | -| Body Text | 14px (0.88rem) | 400 | 1.40 | normal | NouvelR, paragraph and descriptive content | -| Body Bold | 14px (0.88rem) | 700 | 1.57 | normal | NouvelR, emphasized body text | -| Button Label | 14.4px (0.90rem) | 700 | 1.00 | 0.144px | NouvelR, primary button text | -| Nav Link | 13px (0.81rem) | 700 | 1.50 | normal | NouvelR, navigation and footer links | -| Caption | 12.8px (0.80rem) | 400 | 1.10 | normal | NouvelR, small descriptive text | -| Small Label | 12px (0.75rem) | 700 | 1.00 | normal | NouvelR, labels and tags | -| Micro Text | 10px (0.63rem) | 700 | 1.45 | normal | NouvelR, smallest UI text, legal fine print | -| Micro Caption | 8.5px (0.53rem) | 400 | normal | normal | NouvelR, absolute smallest text (legal) | +| Token | Size | Weight | Line Height | Letter Spacing | Use | +|---|---|---|---|---|---| +| `{typography.display-xl}` | 56px | 700 | 0.95 | 0 | Hero headlines, campaign titles ("E-TECH ELEKTRİKLİ", "REVOLUTION"). | +| `{typography.display-lg}` | 40px | 700 | 0.95 | 0 | Secondary section titles. | +| `{typography.display-md}` | 32px | 700 | 0.95 | 0 | Page-level H1 on sub-pages and configurator panels. | +| `{typography.heading-lg}` | 24px | 700 | 0.95 | 0 | Section headers, card titles. | +| `{typography.heading-md}` | 20px | 700 | 0.95 | 0 | Sub-section headers, prominent labels. | +| `{typography.heading-sm}` | 18px | 700 | 1.0 | 0 | Tile titles, list group headers. | +| `{typography.subtitle}` | 19.2px | 600 | 1.3 | 0 | Lead paragraphs, hero subtitles. | +| `{typography.body-lg}` | 18px | 400 | 1.5 | 0 | Long-form body. | +| `{typography.body-md}` | 16px | 400 | 1.4 | 0 | Default body and form fields. | +| `{typography.body-sm}` | 14px | 400 | 1.57 | 0 | Captions, metadata. | +| `{typography.button-lg}` | 16px | 700 | 1.0 | 0 | Large CTAs in hero bands. | +| `{typography.button-md}` | 14.4px | 700 | 1.0 | 0.144px | Default button label across the system. | +| `{typography.button-sm}` | 13px | 600 | 1.2 | 0.13px | Sub-nav pills, small in-card actions. | +| `{typography.caption}` | 12px | 400 | 1.4 | 0 | Footer disclosure, regulatory text. | +| `{typography.overline}` | 10px | 700 | 1.45 | 0 | Short uppercase labels above titles. | ### Principles -- **Single-family discipline**: NouvelR handles everything from 56px hero headlines to 8.5px legal captions — the font's geometric precision allows it to scale across this extreme range without losing character -- **Bold-default headings**: Weight 700 dominates the heading hierarchy. Unlike brands that use medium (500) for headings, Renault's Bold weight creates a more assertive, energetic reading experience -- **Ultra-tight display line-heights**: 0.95 line-height on hero and section headings — the lines nearly collide, creating a compressed, punchy typographic texture that feels urgent and modern -- **28-degree radical r**: The typeface's signature detail — the lowercase "r" terminal is cut at precisely 28 degrees to mirror the angles of the Renault diamond logo, embedding brand identity into every word -- **Capitalize transform on captions**: Some caption text uses `text-transform: capitalize` for editorial labeling, while micro text uses `lowercase` — a deliberate inversion for hierarchy signaling +- Display sizes always weight 700, always at `lineHeight: 0.95`. The tightness is what makes the brand feel confident rather than corporate. +- Body copy stays at weight 400 — never 500. The contrast between body and display is part of the system. +- Button labels carry a tiny positive letter-spacing (`0.144px` on `{typography.button-md}`) — almost imperceptible, but it adds the small bit of mechanical precision the brand wants on CTAs. +- No italics, no script, no decorative ligatures. -## 4. Component Stylings +### Note on Font Substitutes + +NouvelR is licensed; substitutes (Inter Tight / Manrope / HK Grotesk Semi +Condensed) preserve the geometric character but typically render with +slightly looser line heights at display sizes — clamp display +`lineHeight` to 0.95 explicitly to match the source. + +## Layout + +### Spacing System +- **Base unit**: 4px, with the working scale built on multiples of 4 and 8. +- **Tokens**: `{spacing.xxs}` 4px · `{spacing.xs}` 8px · `{spacing.sm}` 12px · `{spacing.md}` 16px · `{spacing.lg}` 20px · `{spacing.xl}` 24px · `{spacing.xxl}` 32px · `{spacing.xxxl}` 40px · `{spacing.section}` 80px. +- Section padding (full-bleed band → next band): `{spacing.section}` (80px) on desktop, collapsing to `{spacing.xxxl}` (40px) on mobile. +- Promo-tile internal padding: `{spacing.xxl}` (32px) all sides on desktop. +- Configurator row vertical padding: `{spacing.xl}` (24px) top/bottom with hairline divider between rows. + +### Grid & Container +- **Max content width** ≈ 1440px. Beyond that, content remains centred and the dark/light bands extend full-bleed. +- **Promo grid** on the homepage: a 2-column tile grid on desktop, dropping to 1-up on mobile. Each tile is square-cornered (`{rounded.none}`) with the photography or solid colour as the background. +- **Vehicle range grids**: 3 to 4 cars per row at desktop, collapsing 2-up at tablet and 1-up at small mobile. +- **Configurator** uses a fixed left visualisation pane (~60% width) with a right-hand scrolling option list (~40% width) on desktop. + +### Whitespace Philosophy +- Whitespace is structural, not decorative. Sections are separated by colour-blocking (white → black) rather than soft padding ramps. +- Inside cards and configurator rows, padding is generous but never airy — the brand is mass-market, so density is acceptable. +- Hairline `{colors.hairline}` dividers on white surfaces create the sense of catalogue precision; on dark surfaces, `{colors.divider-dark}` carries the same role. + +## Elevation & Depth + +| Level | Treatment | Use | +|---|---|---| +| 0 — flat | No shadow, no border | Default page surface, full-bleed bands. | +| 1 — outline | 1px solid `{colors.hairline-strong}` or `{colors.hairline}` | Promo tiles on light, vehicle cards, configurator panels. | +| 2 — colour-blocked elevation | Surface colour shift (e.g. `{colors.canvas}` card sitting inside a `{colors.surface-soft}` band) | Configurator detail cards, related-content rows. | +| 3 — dark inversion | Card swaps to `{colors.surface-dark}` against a `{colors.canvas}` band | "Ticari araç" hero promo tiles, lifestyle storytelling cards. | + +Drop shadows are extracted from the system but rarely visible on the marketing +surfaces. When they appear, they are very subtle (~10% opacity, 2–4px blur) +and used on floating elements like the configurator's sticky summary bar. + +### Decorative Depth +- The R5 hero band uses an atmospheric mesh-gradient backdrop — purple-to-pink-to-yellow glow behind the car silhouette — that acts as the only true atmospheric depth in the system. Everywhere else, depth is structural (colour-blocking + outlines), not atmospheric. +- E-TECH electric powertrain pages use a luminous magenta-to-violet gradient behind cutaway diagrams, reserved for the electric sub-brand. + +## Shapes + +### Border Radius Scale + +| Token | Value | Use | +|---|---|---| +| `{rounded.none}` | 0px | Tiles, vehicle cards, dividers, banner bands, full-bleed images. | +| `{rounded.xs}` | 2px | Default buttons (primary yellow, secondary black, outline). | +| `{rounded.sm}` | 3px | Tab panels, small chips. | +| `{rounded.md}` | 4px | Form labels, inline tags. | +| `{rounded.pill}` | 46px | Sub-nav pills, "yeni" / "NEW" badges, decorative carousel chips. | +| `{rounded.full}` | 9999px | Configurator colour swatches, avatar dots. | + +### Photography Geometry +- Vehicle photography is **always square-cornered** (`{rounded.none}`). No rounded vehicle hero shots, no soft-edged car cards. +- Aspect ratios cluster around **16:9** (hero bands), **1:1** (square promo tiles), and **4:3** (vehicle range cards). Lifestyle imagery sometimes runs **2:1 wide** for full-bleed bands. +- Avatars and small profile cues — when present — use `{rounded.full}` circles to contrast with the otherwise square geometry. + +## Components ### Buttons -Renault's buttons are sharp-edged rectangles with zero border-radius — the industrial precision of a pressed metal body panel. -**Super Primary (Yellow)** — The highest-emphasis CTA: -- Default: bg `#EFDF00` (Renault Yellow), text `#000000`, borderRadius 0px, padding 10px 15px, border 1px solid `#EFDF00` -- Inverted: bg `#EFDF00`, text `#000000` — same yellow on dark backgrounds -- fontSize 16px (NouvelR), fontWeight 700, minHeight 46px, minWidth 46px -- Used for: Primary conversion actions (configure, buy now) +**`button-primary`** — yellow CTA +- Background `{colors.primary}`, label `{colors.on-primary}`, type `{typography.button-md}`, padding `14px 24px`, `rounded: {rounded.xs}`. +- The single most important action on a page (e.g. "Hemen randevu al", "Hesapla", "Konfigüratörü başlat"). +- Pressed state lives in `button-primary-pressed` (background `{colors.primary-deep}`). -**Primary (Black)** — The default action button: -- Default: bg `#000000`, text `#FFFFFF`, borderRadius 0px, padding 10px 15px, border 1px solid `#000000` -- Inverted: bg `#FFFFFF`, text `#000000`, border 1px solid `#FFFFFF` — white fill on dark backgrounds -- fontSize 16px (NouvelR), fontWeight 700 -- Used for: "keşfedin" (explore), secondary conversion actions +**`button-secondary-dark`** — solid black CTA +- Background `{colors.surface-dark}`, label `{colors.on-dark}`, type `{typography.button-md}`, `rounded: {rounded.xs}`. +- Equal-weight secondary action paired with `{component.button-primary}`, or the primary action when used on a yellow tile background. -**Ghost** — Transparent outline button: -- Default (on dark): bg transparent, text `#FFFFFF`, border 1px solid `#FFFFFF`, borderRadius 0px, padding 10px 15px -- Default (on light): bg transparent, text `#000000`, border 1px solid `#000000` -- fontSize 16px (NouvelR), fontWeight 700 -- Used for: "ilk sen öğren" (be the first to know), "satın alın" (buy), secondary actions +**`button-outline-dark`** — outlined CTA on light +- Background `{colors.canvas}`, label `{colors.ink}`, 1px solid `{colors.hairline-strong}`, type `{typography.button-md}`, `rounded: {rounded.xs}`. +- Tertiary action; appears alongside primary/secondary for "Detayları gör", "Modeller", etc. -**Text Link** — Inline navigation: -- Default (light): text `#000000`, no border, no background -- Default (dark): text `#FFFFFF` -- Hover: color shifts to `#1883FD` (Renault Blue), text-decoration none -- All link variants hover to the same blue — consistent interactive feedback +**`button-outline-light`** — outlined CTA on dark +- Background `{colors.surface-dark}`, label `{colors.on-dark}`, 1px solid `{colors.on-dark}`, type `{typography.button-md}`, `rounded: {rounded.xs}`. +- The dark-canvas counterpart to `{component.button-outline-dark}`. + +**`button-pill`** — sub-nav chip +- Background `{colors.canvas}`, label `{colors.ink}`, 1px solid `{colors.hairline-strong}`, type `{typography.button-sm}`, `rounded: {rounded.pill}`, height 36px. +- The only place the system uses a pill — for top-level filter chips ("Servis & randevu", "Sahiplik dönemi geçişi", "Kampanyalar") and configurator tab switches. + +**`button-icon-square`** — small icon button +- Background `{colors.canvas}`, 1px solid `{colors.hairline-strong}`, `rounded: {rounded.xs}`, 40×40px square. +- Carousel arrows, share, language switcher. ### Cards & Containers -**PromoCard (Light)** — Editorial content card: -- Background: white or transparent -- Full-bleed photography with dark gradient overlay at top: `linear-gradient(rgba(0,0,0,0.6) 0%, rgba(0,0,0,0) 40%)` -- Heading: NouvelR 40px/700, white text positioned over gradient -- Border-radius: 0px — sharp rectangular containers -- No shadow, no visible border +**`promo-tile-light`** — white promo tile +- Background `{colors.canvas}`, text `{colors.ink}`, type `{typography.heading-lg}`, padding `{spacing.xxl}`, `rounded: {rounded.none}`. +- Used in the homepage 2-up grid for "Hybrid araç modelleri", "binek araç satış kampanyaları" tiles. -**PromoCard (Dark / `is-alternative-mode`)** — Cinematic card: -- Background: `#000000` (Absolute Black) -- Same gradient overlay treatment -- Heading: white NouvelR text -- CTA buttons: inverted primary (white bg) or ghost (white border) +**`promo-tile-dark`** — black promo tile +- Background `{colors.surface-dark}`, text `{colors.on-dark}`, type `{typography.heading-lg}`, padding `{spacing.xxl}`, `rounded: {rounded.none}`. +- Lifestyle / commercial-vehicle storytelling tiles ("ticari araç satış kampanyaları"). -**VehicleRangeCard** — Vehicle showcase: -- Background: transparent -- Vehicle image above, model name and price/spec below -- No shadow, no border, clean flat treatment -- Spacing between cards via grid gap +**`promo-tile-yellow`** — accent promo tile +- Background `{colors.primary}`, text `{colors.on-primary}`, type `{typography.heading-lg}`, padding `{spacing.xxl}`, `rounded: {rounded.none}`. +- The single "PARLAK SARI" / "Sunlight Yellow" attention tile that anchors a campaign band. Reserved — usually one per page maximum. + +**`vehicle-card`** — car listing card +- Background `{colors.canvas}`, full-bleed product photography on top, text below, `rounded: {rounded.none}`, no outer border. +- Includes vehicle name (`{typography.heading-md}`), variant subtitle (`{typography.body-sm}`), and a single trailing arrow icon. + +**`hero-banner`** — full-bleed hero +- Background `{colors.surface-dark}` with full-bleed photo or atmospheric gradient, content stacked left, type `{typography.display-xl}` for the title. +- "SCENIC E-TECH ELEKTRİKLİ" hero on the homepage. ### Inputs & Forms -**Search/Text Input:** -- Background: `#FFFFFF` -- Text: `#000000` -- Border: 1px solid `#D1D1D1` (Border Gray) -- Border-radius: 50px (pill-shaped — unusual deviation from the zero-radius button system) -- Padding: 6px 35px 6px 15px (extra right padding for search icon) -- Font: NouvelR, 12.8px -- Focus: standard browser focus ring +**`text-input`** — default input +- Background `{colors.canvas}`, text `{colors.ink}`, type `{typography.body-md}`, 1px bottom border `{colors.hairline-strong}`, `rounded: {rounded.none}`, padding `{spacing.sm} {spacing.md}`, height 48px. +- Inputs intentionally minimal — borderless on top and sides, single hairline at the bottom — keeping the catalogue feel. + +### Configurator + +**`configurator-row`** — option list row +- Background `{colors.canvas}`, separator hairline `{colors.hairline}` between rows, padding `{spacing.xl}` top/bottom, type `{typography.body-md}`. +- Right-side scrolling list on the configurator: "kasa tipi", "motor seçimi", "versiyon seçimi", "renk seçenekleri", etc. + +**`configurator-swatch`** — circular colour pick +- Background `{colors.surface-soft}` (or the actual car colour), `rounded: {rounded.full}`, 56×56px. +- Used for paint colour selection. Active state adds a 1px solid `{colors.hairline-strong}` ring. ### Navigation -- **Desktop**: Renault diamond logo centered/left, horizontal nav links, sticky positioning -- **Background**: white, no shadow at rest -- **Links**: NouvelR, 13px, weight 700, black text -- **Hover**: color shifts to `#1883FD` (Renault Blue) -- **Mobile**: Hamburger collapse to full-screen navigation drawer -- **CTA in nav**: Primary black button for main conversion action -### Image Treatment -- **Hero**: Full-viewport carousel with dramatic aurora-gradient backgrounds and art-directed vehicle photography — edge-to-edge, no padding -- **PromoCards**: Full-bleed photography within card bounds, dark gradient overlay at top for text legibility -- **Vehicle images**: Transparent-background renders on neutral/gradient backgrounds -- **Aspect ratios**: Mixed — hero at roughly 16:9 viewport, promo cards at various ratios from square to wide panoramic -- **Lazy loading**: Below-fold sections use lazy loading (framework-handled) +**`nav-bar`** — top nav (desktop) +- Background `{colors.canvas}`, type `{typography.button-md}`, height 60px, hairline `{colors.hairline}` bottom border. +- Left: diamond logomark. Centre: top-level nav ("Modeller", "Hizmetler", "Renault Yaşamı", "MyRenault"). Right: language switcher + login icon. -### Carousel Component -- Full-screen hero carousel with auto-advancing slides -- Each slide: background gradient/photo + vehicle image + headline + CTA buttons -- Dot indicators for slide position -- Navigation arrows at edges +**`nav-bar`** (mobile) +- Same height 60px, collapses centre nav into a hamburger icon. Logo stays left, login stays right. -## 5. Layout Principles +**`sub-nav-pill`** — pill-style sub-nav +- Pill chips set in a horizontal scroll bar between hero and content body (e.g. "Servis & randevu", "Sahiplik dönemi geçişi", "Kampanyalar"), `{component.button-pill}` styling. -### Spacing System -- **Base unit**: 8px (detected system base) -- **Scale**: 1px, 4px, 5px, 6px, 6.25px, 8px, 10px, 12px, 13px, 15px, 16px, 20px, 24px, 32px, 40px -- **Button padding**: 10px 15px — consistent across all button variants -- **Section padding**: Generous vertical spacing (40–80px) between major content blocks -- **Card gaps**: 16–24px between grid items -- **Minimum interactive size**: 46px (minWidth and minHeight on all buttons) +### Signature Components -### Grid & Container -- **Max width**: 1440px (largest defined breakpoint) -- **Hero**: Full-bleed, edge-to-edge, viewport-height -- **PromoCard grid**: 2-up and 3-up layouts with mixed card sizes -- **Vehicle range**: Horizontal scrollable card row or grid -- **Footer**: Multi-column layout on white background +**`badge-new`** — "yeni" badge +- Background `{colors.primary}`, label `{colors.on-primary}`, type `{typography.button-md}`, `rounded: {rounded.full}`, padding `6px 14px`. +- Anchored on the bottom-left of new vehicle cards. -### Whitespace Philosophy -Renault uses whitespace moderately — more generously than Ferrari but less extremely than Tesla. The card-based layout means content is organized into defined containers rather than floating in void. The visual breathing room comes primarily from the large card formats and the full-bleed hero carousel, which gives each vehicle its own cinematic moment. Between sections, spacing is consistent (32–40px) creating a rhythmic scroll experience. The alternation between light and dark sections also creates perceived whitespace — the mode switch itself acts as a visual separator. +**`footer`** — global footer +- Background `{colors.surface-dark}`, text `{colors.on-dark}`, type `{typography.body-sm}`, padding `64px 24px`. +- Three-column legal/quick-links/locale grid above a single-line copyright row separated by `{colors.divider-dark}`. -### Border Radius Scale -| Value | Context | -|-------|---------| -| 0px | All buttons, PromoCards, most containers — the zero-radius default | -| 2px | Small UI elements (region controls) | -| 3px | Content panels (div, tabpanel) | -| 4px | Labels and tag elements | -| 46px | Pill-shaped elements (search input, filter chips) | -| 50px | Full pill for search/input fields | - -## 6. Depth & Elevation - -| Level | Treatment | Use | -|-------|-----------|-----| -| Level 0 (Flat) | No shadow | Default for PromoCards, buttons, most containers | -| Level 1 (Soft) | `rgba(0,0,0,0.2) 0px 4px 8px` | Card hover states, subtle lift effect | -| Level 2 (Medium) | `rgba(0,0,0,0.2) 0px 0px 18px` | Floating UI elements, dropdown menus | -| Level 3 (Layered) | `rgba(0,0,0,0) 0px 2px 4px, rgba(50,50,93,0.1) 0px 7px 14px` | Compound shadow for elevated cards and modals | -| Level 4 (Deep) | `rgba(0,0,0,0.15) 0px 40px 80px` | Large floating panels, configurator overlays | -| Level 5 (Directional) | `rgba(0,0,0,0.2) 5px 5px 8px` | Offset directional shadow for specific components | -| Level 6 (Ambient) | `rgb(199,197,199) 0px 0px 12px 2px` | Ambient glow effect for highlighted elements | - -### Shadow Philosophy -Renault uses a richer shadow system than Ferrari or Tesla — seven distinct shadow tokens reflecting a more layered, dimensional interface. The shadows progress from subtle 4px hover lifts to dramatic 80px deep panels. The compound shadow (Level 3) with its dual-layer approach (a tight dark shadow plus a wider purple-tinted one from `rgba(50,50,93,0.1)`) is particularly refined — it creates a photorealistic floating effect. The ambient glow (Level 6) in warm gray adds a unique touch that connects to Renault's warmer color personality. - -### Decorative Depth -- **Hero aurora gradients**: The primary decorative depth element — vivid color gradients create atmospheric depth behind vehicle imagery -- **PromoCard overlays**: `linear-gradient(rgba(0,0,0,0.6) → transparent)` creates depth within cards through transparency -- **No blur effects** on UI elements — depth is communicated through shadow and color contrast - -## 7. Do's and Don'ts +## Do's and Don'ts ### Do -- Use Renault Yellow (`#EFDF00`) exclusively for super-primary CTAs — it carries the full weight of the diamond logo's identity -- Maintain zero border-radius on all buttons — sharp edges are non-negotiable in the Renault system -- Use NouvelR Bold (700) as the default heading weight — the assertive weight is central to the brand's energetic personality -- Apply the dark gradient overlay (`rgba(0,0,0,0.6) → transparent`) on PromoCards to ensure text legibility over photography -- Keep hero line-heights ultra-tight (0.95) for display text — the compressed texture feels urgent and modern -- Alternate between black and white sections to create the signature chessboard rhythm -- Use `#1883FD` (Renault Blue) consistently for all link hover states — one interactive color signal -- Set minimum interactive size at 46×46px for all buttons — accessibility built into the component spec -- Reserve pill-shaped radius (46–50px) exclusively for search inputs and filter elements — never for buttons -- Use the PromoCard gradient overlay on every card that has text over photography +- Reserve `{colors.primary}` exclusively for primary CTAs, "yeni"/"NEW" badges, and at most one accent promo tile per band — `{component.promo-tile-yellow}` is intentionally rare. +- Pair `{colors.primary}` only with `{colors.on-primary}` text. Yellow + white is forbidden. +- Set everything in **NouvelR** — no secondary serif, no script, no decorative italic. +- Hold display headlines at `{typography.display-xl}` weight 700 with `lineHeight: 0.95` so they stack tightly on multi-line wraps. +- Use `{rounded.xs}` (2px) on every standard button — the near-flat corner is part of the brand. +- Switch full bands between `{colors.canvas}` and `{colors.surface-dark}` for storytelling rhythm. Avoid mid-greys as section backgrounds. +- Show vehicle photography full-bleed inside `{component.vehicle-card}` with copy stacked beneath, never overlaid. +- Use `{component.sub-nav-pill}` (`{rounded.pill}`) only for sub-nav and small filter rows — never for primary CTAs. ### Don't -- Apply Renault Yellow as a background color for sections or surfaces — it's a CTA signal, not an atmosphere color -- Add border-radius to buttons — the zero-radius rectangle is a core brand marker -- Use any typeface besides NouvelR — the single-family discipline is a brand pillar -- Mix multiple chromatic accent colors in a single section — the palette is monochrome-plus-yellow -- Soften heading weights to 400 or 500 — NouvelR Bold is the brand voice, lighter weights read as off-brand -- Add decorative borders to PromoCards or content containers — separation comes from background color alternation -- Use the semantic colors (Success Green, Error Rose) for decorative purposes — they're reserved for form states -- Apply the 56px hero size to anything below the fold — hero typography scale is reserved for the carousel -- Create rounded-pill buttons — pill shapes are reserved for inputs, never for action elements -- Use flat CSS gradients on UI surfaces — the only gradients should be the photographic hero auroras and the text-legibility overlays +- Don't introduce a secondary accent colour. Yellow is the only brand accent; semantic colours (`{colors.error}`, `{colors.success}`, `{colors.warning}`) are functional, not decorative. +- Don't round vehicle cards or promo tiles. Square-cornered photography is core to the brand expression. +- Don't soften body weights to 500 or 600 — the system relies on the 400 / 700 contrast. +- Don't apply `{colors.primary}` to body text or large surfaces beyond the single accent tile per band. +- Don't add atmospheric gradient washes outside the dedicated R5 / E-TECH hero contexts. +- Don't pair light grey text on white. Body text steps through `{colors.body}`, `{colors.charcoal}`, `{colors.mute}` — `{colors.ash}` and `{colors.stone}` are reserved for placeholders and disabled states. +- Don't add drop shadows to vehicle cards or promo tiles — the system is shadow-free at the catalogue level. -## 8. Responsive Behavior +## Responsive Behavior ### Breakpoints + | Name | Width | Key Changes | -|------|-------|-------------| -| Mobile Small | ≤425px | Single-column, full-width cards, hero text scales to ~32px, stacked CTAs, hamburger nav | -| Mobile | 426–640px | Single-column, slightly larger cards, hero text at 32–40px | -| Tablet Small | 641–768px | 2-column PromoCard grid begins, hero maintains full-width | -| Tablet | 769–896px | Full 2-column layout, vehicle range shows 2–3 cards | -| Desktop Small | 897–1024px | Navigation fully expanded, hero at 56px, 2-up card grid | -| Desktop | 1025–1280px | Full layout, 3-up card grid, generous whitespace | -| Large Desktop | 1281–1440px | Maximum content width, centered container, hero at full cinematic scale | +|---|---|---| +| Desktop XL | ≥ 1440px | Full max-width container, 3–4 column vehicle grid, 2-up promo tile grid. | +| Desktop | 1280–1439px | Same layout, container shrinks to viewport with `{spacing.xl}` side padding. | +| Tablet Large | 1024–1279px | Vehicle grid drops to 3-up, configurator left/right panes resize to 55/45. | +| Tablet | 768–1023px | Promo tile grid collapses to 2-up, sub-nav pills become horizontal scroll. | +| Mobile Large | 426–767px | Vehicle grid 2-up, configurator switches to stacked panes (visualisation on top, options below), nav collapses to hamburger. | +| Mobile | ≤ 425px | All grids 1-up, hero `{typography.display-xl}` clamps to ~40px, section padding `{spacing.section}` collapses to `{spacing.xxxl}`. | ### Touch Targets -- All buttons: minimum 46×46px (`minWidth: 46px, minHeight: 46px`) — exceeds WCAG AAA 44×44px requirement -- Search input pill: adequate touch target with 50px border-radius creating a large tappable area -- Navigation links: NouvelR 13px with adequate spacing between items -- Carousel navigation: large arrow targets at viewport edges +- All buttons ship at minimum 44×44px on mobile; default `{component.button-primary}` is 48px tall, comfortably exceeding WCAG AAA. +- `{component.sub-nav-pill}` (36px) is bumped to 40px tall on mobile via increased vertical padding. +- `{component.button-icon-square}` (40px) sits at the WCAG AA minimum and remains tappable, but should grow to 44px when used as a primary navigation control. ### Collapsing Strategy -- **Navigation**: Full horizontal nav collapses to Renault diamond logo + hamburger menu on mobile -- **Hero carousel**: Full-width at all breakpoints, headline scales from 56px (desktop) to ~32px (mobile) -- **PromoCard grid**: 3-up → 2-up → single-column as viewport narrows -- **Vehicle range**: Horizontal scroll maintained at all sizes, visible cards reduce -- **CTA pairs**: Side-by-side buttons stack vertically on mobile -- **Footer**: Multi-column collapses to single-column accordion on mobile +- Top-level nav collapses to hamburger at < 1024px; the logo and login icon stay anchored. +- 2-up promo grid collapses to 1-up at < 768px; tile padding shrinks from `{spacing.xxl}` to `{spacing.lg}`. +- Configurator switches from side-by-side to stacked at < 1024px, with the visualisation pinned to the top of the viewport on scroll. +- Display headlines clamp: `{typography.display-xl}` 56px → 40px → 32px across the breakpoint ladder. +- Sub-nav pills convert from a wrap row to a horizontal scroll-rail at < 768px. ### Image Behavior -- Hero images: full-bleed at all breakpoints with `object-fit: cover` -- PromoCard images: responsive within card containers, gradient overlay scales proportionally -- Vehicle images: transparent-background renders scale proportionally within grid cells -- Art direction: mobile may crop to tighter vehicle views, reducing environmental context +- Vehicle photography is served at 1.5× and 2× DPR; below 768px, the system swaps to a portrait-oriented composition where art direction allows. +- Hero atmospheric gradients (R5, E-TECH) load lazily after primary content; they are not blocking. +- Lifestyle / commercial photography in `{component.promo-tile-dark}` keeps the same 16:9 framing across breakpoints, cropping inward rather than letterboxing. -## 9. Agent Prompt Guide +## Iteration Guide -### Quick Color Reference -- Primary CTA (Super): "Renault Yellow (#EFDF00)" -- Primary CTA (Default): "Absolute Black (#000000)" -- Background Light: "Pure White (#FFFFFF)" -- Background Dark: "Absolute Black (#000000)" -- Secondary Dark: "Charcoal (#222222)" -- Heading text (light bg): "Absolute Black (#000000)" -- Body text: "Absolute Black (#000000)" -- Link Hover: "Renault Blue (#1883FD)" -- Border: "Pale Silver (#F2F2F2)" -- Semantic Error: "Error Rose (#BE6464)" +1. Focus on ONE component at a time. Most components share `{rounded.xs}`, `{colors.canvas}` / `{colors.surface-dark}`, and NouvelR — only the role-specific tokens (`{colors.primary}`, `{component.promo-tile-yellow}`) shift between variants. +2. Reference component names and tokens directly (`{colors.primary}`, `{component.button-primary-pressed}`, `{rounded.pill}`) — do not paraphrase. +3. Run `npx @google/design.md lint DESIGN.md` after edits; the orphaned-tokens warning will catch unused entries before they ship. +4. Add new variants as separate entries (`-pressed`, `-disabled`, `-outline`) — do not bury them in prose. +5. Default body type to `{typography.body-md}`; reach for `{typography.subtitle}` only on hero subtitles and lead paragraphs. +6. Keep `{colors.primary}` scarce — if more than one yellow element appears per viewport, ask whether one of them should drop to `{colors.surface-dark}` or `{colors.canvas}` instead. -### Example Component Prompts -- "Create a hero section with a full-viewport aurora gradient background (magenta to violet to teal), a centered vehicle image, a NouvelR Bold headline at 56px with 0.95 line-height in white, and two buttons: a Primary (white bg, black text, 0px radius) 'Explore' and a Ghost (transparent bg, white border, white text, 0px radius) 'Learn More'" -- "Design a PromoCard with a full-bleed photography background, a dark gradient overlay (rgba(0,0,0,0.6) top to transparent at 40%), a NouvelR Bold 40px white heading, a 14px body text line in white, and a Primary inverted button (white bg, black text, 0px radius, 10px 15px padding)" -- "Build a vehicle range grid with 3 columns on white background, each card showing a transparent-background car render above a NouvelR Bold 24px model name in black, a 14px price caption, and a ghost button (black border, black text, 0px radius) labeled 'Configure'" -- "Create a dark E-Tech section on Absolute Black (#000000) with a NouvelR Bold 40px white heading 'E-Tech electric powertrain', a 14px subtitle in white, and a Renault Yellow (#EFDF00) super-primary button with black text, 0px radius, and 10px 15px padding" -- "Design a search input as a pill-shaped field (50px border-radius) with white background, 1px solid #D1D1D1 border, NouvelR 12.8px text, 6px 35px 6px 15px padding, and a search icon positioned inside the right padding area" +## Known Gaps -### Iteration Guide -When refining existing screens generated with this design system: -1. Focus on ONE component at a time — Renault's system has clear component boundaries (PromoCard, VehicleRangeCard, CTA variants) -2. Reference specific color names and hex codes — the palette is small but each color has a precise function -3. Use natural language descriptions, not CSS values — "sharp zero-radius rectangle" conveys intent better than "border-radius: 0" -4. Describe the desired "feel" alongside specific measurements — "assertive automotive energy" communicates the NouvelR Bold heading personality better than "font-weight: 700" -5. Always check whether a section should be light or dark — the chessboard alternation is a core pattern -6. Reserve Renault Yellow for ONE button per screen — if yellow appears in more than one CTA, the hierarchy collapses +- Active/pressed visual states are not consistently observable in static surfaces; `button-primary-pressed` documents the extracted darkened-yellow value, but no other component has a pressed variant promoted to the YAML. +- Drop-shadow values exist in the extracted tokens but are rarely surfaced visually; only the configurator's sticky summary bar uses them on the captured pages. +- The MyRenault application surfaces (logged-in product) are out of scope for this extraction — only the public marketing canvas is documented. +- Form-field focus styling is not extracted; the system likely relies on a thicker bottom border at `{colors.ink}`, but this is not visually confirmed on the captured pages. diff --git a/design-md/replicate/DESIGN.md b/design-md/replicate/DESIGN.md index 889f8de..88b058d 100644 --- a/design-md/replicate/DESIGN.md +++ b/design-md/replicate/DESIGN.md @@ -1,261 +1,616 @@ -# Design System Inspired by Replicate +--- +version: alpha +name: Replicate +description: | + Replicate's marketing surfaces pair the warm-cream developer-tools aesthetic + of an indie ML playground with a confident hot-orange brand accent and a + signature display typeface (rb-freigeist-neue) sized aggressively large at + 72px+. The system reads as "AI lab notebook crossed with print magazine": + cream and bone surfaces, dark ink type, monospace code wells, irregular + hand-drawn-feeling diagrams, and a rich orange used scarcely on the most + consequential CTA. Photography of contributors and example outputs is + square-ish with mid-radius corners; everything else is borderless or hairline. -## 1. Visual Theme & Atmosphere +colors: + primary: "#ea2804" + primary-deep: "#c01f00" + on-primary: "#ffffff" + ink: "#202020" + body: "#3a3a3a" + charcoal: "#575757" + mute: "#646464" + ash: "#8d8d8d" + stone: "#bbbbbb" + on-dark: "#fcfcfc" + on-dark-mute: "rgba(252,252,252,0.72)" + canvas: "#f9f7f3" + surface-bone: "#f3f0e8" + surface-card: "#ffffff" + surface-dark: "#202020" + surface-deep: "#000000" + hairline: "rgba(32,32,32,0.12)" + hairline-strong: "#202020" + divider-dark: "rgba(255,255,255,0.2)" + hero-warm: "#ea2804" + hero-glow: "#ff6a3d" + hero-pink: "#f4a8a0" + badge-success: "#2b9a66" + link: "#ea2804" + ring-focus: "rgba(59,130,246,0.5)" + github-dark: "#24292e" -Replicate's interface is a developer playground crackling with creative energy — a bold, high-contrast design that feels more like a music festival poster than a typical API platform. The hero section explodes with a vibrant orange-red-magenta gradient that immediately signals "this is where AI models come alive," while the body of the page grounds itself in a clean white canvas where code snippets and model galleries take center stage. +typography: + display-xxl: + fontFamily: rb-freigeist-neue + fontSize: 128px + fontWeight: 700 + lineHeight: 1.0 + letterSpacing: -3px + display-xl: + fontFamily: rb-freigeist-neue + fontSize: 72px + fontWeight: 700 + lineHeight: 1.0 + letterSpacing: -1.8px + display-lg: + fontFamily: rb-freigeist-neue + fontSize: 48px + fontWeight: 700 + lineHeight: 1.0 + letterSpacing: -1px + display-md: + fontFamily: rb-freigeist-neue + fontSize: 30px + fontWeight: 600 + lineHeight: 1.2 + letterSpacing: -0.5px + heading-lg: + fontFamily: basier-square + fontSize: 38.4px + fontWeight: 600 + lineHeight: 0.83 + letterSpacing: -0.5px + heading-md: + fontFamily: basier-square + fontSize: 24px + fontWeight: 600 + lineHeight: 1.33 + letterSpacing: -0.35px + heading-sm: + fontFamily: basier-square + fontSize: 20px + fontWeight: 600 + lineHeight: 1.4 + letterSpacing: -0.3px + subtitle: + fontFamily: rb-freigeist-neue + fontSize: 18px + fontWeight: 600 + lineHeight: 1.56 + letterSpacing: 0 + body-lg: + fontFamily: basier-square + fontSize: 18px + fontWeight: 400 + lineHeight: 1.56 + letterSpacing: 0 + body-md: + fontFamily: basier-square + fontSize: 16px + fontWeight: 400 + lineHeight: 1.5 + letterSpacing: 0 + body-sm: + fontFamily: basier-square + fontSize: 14px + fontWeight: 400 + lineHeight: 1.43 + letterSpacing: 0 + button-md: + fontFamily: basier-square + fontSize: 16px + fontWeight: 600 + lineHeight: 1.0 + letterSpacing: 0 + button-sm: + fontFamily: basier-square + fontSize: 14px + fontWeight: 600 + lineHeight: 1.0 + letterSpacing: 0 + caption: + fontFamily: basier-square + fontSize: 12px + fontWeight: 400 + lineHeight: 1.33 + letterSpacing: 0 + caption-tight: + fontFamily: basier-square + fontSize: 14px + fontWeight: 600 + lineHeight: 1.43 + letterSpacing: -0.35px + code-md: + fontFamily: jetbrains-mono + fontSize: 14px + fontWeight: 400 + lineHeight: 1.43 + letterSpacing: 0 + code-sm: + fontFamily: jetbrains-mono + fontSize: 11px + fontWeight: 400 + lineHeight: 1.5 + letterSpacing: 0 -The design personality is defined by two extreme choices: **massive display typography** (up to 128px) using the custom rb-freigeist-neue face, and **exclusively pill-shaped geometry** (9999px radius on everything). The display font is thick, bold, and confident — its heavy weight at enormous sizes creates text that feels like it's shouting with joy rather than whispering authority. Combined with basier-square for body text (a clean geometric sans) and JetBrains Mono for code, the system serves developers who want power and playfulness in equal measure. +rounded: + none: 0px + xs: 4px + sm: 6px + md: 10px + lg: 16px + full: 9999px -What makes Replicate distinctive is its community-powered energy. The model gallery with AI-generated images, the dotted-underline links, the green status badges, and the "Imagine what you can build" closing manifesto all create a space that feels alive and participatory — not a corporate product page but a launchpad for creative developers. +spacing: + xxs: 2px + xs: 4px + sm: 8px + md: 12px + lg: 16px + xl: 24px + xxl: 32px + xxxl: 48px + section: 96px + band: 160px + +components: + button-primary: + backgroundColor: "{colors.primary}" + textColor: "{colors.on-primary}" + typography: "{typography.button-md}" + rounded: "{rounded.full}" + padding: 12px 24px + height: 44px + button-primary-pressed: + backgroundColor: "{colors.primary-deep}" + textColor: "{colors.on-primary}" + typography: "{typography.button-md}" + rounded: "{rounded.full}" + button-dark: + backgroundColor: "{colors.surface-dark}" + textColor: "{colors.on-dark}" + typography: "{typography.button-md}" + rounded: "{rounded.full}" + padding: 12px 24px + height: 44px + button-outline: + backgroundColor: "{colors.surface-card}" + textColor: "{colors.ink}" + typography: "{typography.button-md}" + rounded: "{rounded.full}" + padding: 11px 23px + height: 44px + button-ghost: + backgroundColor: "{colors.canvas}" + textColor: "{colors.ink}" + typography: "{typography.button-md}" + rounded: "{rounded.full}" + padding: 8px 16px + height: 36px + button-icon: + backgroundColor: "{colors.surface-card}" + textColor: "{colors.ink}" + rounded: "{rounded.full}" + size: 36px + text-input: + backgroundColor: "{colors.surface-card}" + textColor: "{colors.ink}" + typography: "{typography.body-md}" + rounded: "{rounded.full}" + padding: 12px 20px + height: 44px + hero-band: + backgroundColor: "{colors.hero-warm}" + textColor: "{colors.on-dark}" + typography: "{typography.display-xl}" + rounded: "{rounded.none}" + padding: 96px 32px + model-card: + backgroundColor: "{colors.surface-card}" + textColor: "{colors.ink}" + typography: "{typography.body-md}" + rounded: "{rounded.md}" + padding: 16px + collection-tile: + backgroundColor: "{colors.canvas}" + textColor: "{colors.ink}" + typography: "{typography.heading-md}" + rounded: "{rounded.md}" + padding: 24px + pricing-tier: + backgroundColor: "{colors.surface-card}" + textColor: "{colors.ink}" + typography: "{typography.body-md}" + rounded: "{rounded.lg}" + padding: 32px + pricing-tier-featured: + backgroundColor: "{colors.surface-dark}" + textColor: "{colors.on-dark}" + typography: "{typography.body-md}" + rounded: "{rounded.lg}" + padding: 32px + code-block: + backgroundColor: "{colors.surface-dark}" + textColor: "{colors.on-dark}" + typography: "{typography.code-md}" + rounded: "{rounded.md}" + padding: 24px + code-tab: + backgroundColor: "{colors.surface-deep}" + textColor: "{colors.on-dark-mute}" + typography: "{typography.code-sm}" + rounded: "{rounded.xs}" + padding: 6px 12px + badge-status: + backgroundColor: "{colors.badge-success}" + textColor: "{colors.on-dark}" + typography: "{typography.caption}" + rounded: "{rounded.full}" + padding: 4px 10px + badge-tag: + backgroundColor: "{colors.canvas}" + textColor: "{colors.ink}" + typography: "{typography.caption}" + rounded: "{rounded.full}" + padding: 4px 10px + nav-bar: + backgroundColor: "{colors.canvas}" + textColor: "{colors.ink}" + typography: "{typography.button-sm}" + rounded: "{rounded.none}" + height: 60px + sub-nav-pill: + backgroundColor: "{colors.surface-card}" + textColor: "{colors.ink}" + typography: "{typography.button-sm}" + rounded: "{rounded.full}" + padding: 6px 14px + contributor-avatar: + backgroundColor: "{colors.surface-card}" + textColor: "{colors.ink}" + rounded: "{rounded.full}" + size: 40px + footer: + backgroundColor: "{colors.surface-deep}" + textColor: "{colors.on-dark}" + typography: "{typography.body-sm}" + rounded: "{rounded.none}" + padding: 64px 32px +--- + +## Overview + +Replicate is a developer-tools platform with the soul of an art zine. The +public marketing surfaces sit on a warm cream canvas (`{colors.canvas}` — +`#f9f7f3`) rather than the white-or-near-black default of typical AI +infrastructure sites, and that single decision colours everything else: +photography reads as editorial, code wells read as printed pull-quotes, and +the brand orange (`{colors.primary}` — `#ea2804`) feels like a stamp rather +than a notification. + +The typography is the load-bearing decoration. **rb-freigeist-neue** — a +heavy, slightly condensed grotesque — appears at sizes up to 128px in hero +bands, with a tight `lineHeight: 1.0` and negative letter-spacing that lets +multi-line headlines pack into geometric blocks. The companion family, +**basier-square**, takes care of body, button labels, and metadata in the +14–18px range. **JetBrains Mono** carries every code well, command, and +example. Three families, three jobs, no overlap. + +Page rhythm cycles between a default cream canvas, a bold full-bleed orange +hero band, and a `{colors.surface-dark}` (`#202020`) section that hosts the +code stories — the "how it works" walkthrough. Curves are intentional and +soft: every interactive surface (buttons, inputs, tags, avatars) uses +`{rounded.full}`, while content cards and code wells step up to `{rounded.md}` +or `{rounded.lg}`. There are no sharp corners on Replicate; the system reads +as friendly precision. **Key Characteristics:** -- Explosive orange-red-magenta gradient hero (#ea2804 brand anchor) -- Massive display typography (128px) in heavy rb-freigeist-neue -- Exclusively pill-shaped geometry: 9999px radius on EVERYTHING -- High-contrast black (#202020) and white palette with red brand accent -- Developer-community energy: model galleries, code examples, dotted-underline links -- Green status badges (#2b9a66) for live/operational indicators -- Bold/heavy font weights (600-700) creating maximum typographic impact -- Playful closing manifesto: "Imagine what you can build." +- A warm cream canvas (`{colors.canvas}` — `#f9f7f3`) replaces the typical white background, paired with `{colors.surface-bone}` for inset cards. +- Hot orange (`{colors.primary}` — `#ea2804`) is reserved for the primary CTA, the hero band, and inline link colour. Never decorative. +- Display headlines run massive — `{typography.display-xxl}` at 128px in hero bands and `{typography.display-xl}` at 72px on section openers — with tight `lineHeight: 1.0` and negative letter-spacing. +- Three-family typography stack: `rb-freigeist-neue` for display, `basier-square` for UI/body, `jetbrains-mono` for code. +- Every interactive element is fully rounded (`{rounded.full}` 9999px) — buttons, inputs, badges, avatars — while content cards step to `{rounded.md}` 10px. +- Dark code wells (`{colors.surface-dark}` background) sit inside the cream canvas as full-bleed reading surfaces, mimicking print pull-quotes. +- Section rhythm: cream → orange hero → cream → dark code-story band → cream → black footer. -## 2. Color Palette & Roles +## Colors -### Primary -- **Replicate Dark** (`#202020`): The primary text color and dark surface — a near-black that's the anchor of all text and borders. Slightly warmer than pure #000. -- **Replicate Red** (`#ea2804`): The core brand color — a vivid, saturated orange-red used in the hero gradient, accent borders, and high-signal moments. -- **Secondary Red** (`#dd4425`): A slightly warmer variant for button borders and link hover states. +### Brand & Accent +- **Replicate Orange** (`{colors.primary}` — `#ea2804`): the brand accent. Reserved for the primary CTA, hero band background, and inline link colour. Treat as a stamp — one orange element per viewport at most. +- **Orange Pressed** (`{colors.primary-deep}` — `#c01f00`): the active/pressed state of `{colors.primary}` — used on `{component.button-primary-pressed}`. +- **Hero Glow** (`{colors.hero-glow}` — `#ff6a3d`): the lighter orange that appears in the radial atmospheric mesh behind the hero copy. +- **Hero Pink** (`{colors.hero-pink}` — `#f4a8a0`): a warm pink wash that softens the bottom edge of the hero band before it transitions to cream. +- **On-Primary** (`{colors.on-primary}` — `#ffffff`): label colour on top of `{colors.primary}` surfaces. -### Secondary & Accent -- **Status Green** (`#2b9a66`): Badge/pill background for "running" or operational status indicators. -- **GitHub Dark** (`#24292e`): A blue-tinted dark used for code block backgrounds and developer contexts. +### Surface +- **Canvas** (`{colors.canvas}` — `#f9f7f3`): the default page background. Warm cream, never pure white. +- **Surface Bone** (`{colors.surface-bone}` — `#f3f0e8`): a half-step deeper cream used for inset card groups and feature bands. +- **Surface Card** (`{colors.surface-card}` — `#ffffff`): pure white for individual model cards, search inputs, and pricing tiers — the only place white appears. +- **Surface Dark** (`{colors.surface-dark}` — `#202020`): code wells, featured pricing tier, and the "how it works" walkthrough band. +- **Surface Deep** (`{colors.surface-deep}` — `#000000`): footer canvas and the inset code-tab strip inside `{component.code-block}`. +- **Hairline** (`{colors.hairline}` — `rgba(32,32,32,0.12)`): low-contrast 1px dividers on cream surfaces. +- **Hairline Strong** (`{colors.hairline-strong}` — `#202020`): button outlines, focused inputs, and structural separators. -### Surface & Background -- **Pure White** (`#ffffff`): The primary page body background. -- **Near White** (`#fcfcfc`): Button text on dark surfaces and the lightest content. -- **Hero Gradient**: A dramatic orange → red → magenta → pink gradient for the hero section. Transitions from warm (#ea2804 family) through hot pink. +### Text +- **Ink** (`{colors.ink}` — `#202020`): primary text colour. Notably warmer than `#000000`, matching the cream canvas. +- **Body** (`{colors.body}` — `#3a3a3a`): long-form body copy where ink would feel too heavy at 18px+ line lengths. +- **Charcoal** (`{colors.charcoal}` — `#575757`): captions, metadata, secondary nav. +- **Mute** (`{colors.mute}` — `#646464`): supporting text and inactive labels. +- **Ash** (`{colors.ash}` — `#8d8d8d`): tertiary text, placeholder copy. +- **Stone** (`{colors.stone}` — `#bbbbbb`): disabled foreground, neutral icon outlines. +- **On-Dark** (`{colors.on-dark}` — `#fcfcfc`): primary text on `{colors.surface-dark}` and `{colors.surface-deep}`. +- **On-Dark Mute** (`{colors.on-dark-mute}` — `rgba(252,252,252,0.72)`): secondary text in dark regions; preserves the off-white feel without pure white pop. -### Neutrals & Text -- **Medium Gray** (`#646464`): Secondary body text and de-emphasized content. -- **Warm Gray** (`#4e4e4e`): Emphasized secondary text. -- **Mid Silver** (`#8d8d8d`): Tertiary text, footnotes. -- **Light Silver** (`#bbbbbb`): Dotted-underline link decoration color, muted metadata. -- **Pure Black** (`#000000`): Maximum-emphasis borders and occasional text. +### Semantic +- **Success** (`{colors.badge-success}` — `#2b9a66`): inline success badges and "running" status pills on model cards. +- **Link** (`{colors.link}` — `#ea2804`): inline link colour — same as primary orange, intentionally pulling links into the brand accent. +- **Focus Ring** (`{colors.ring-focus}` — `rgba(59,130,246,0.5)`): the default focus ring on interactive elements. +- **GitHub Dark** (`{colors.github-dark}` — `#24292e`): the GitHub-branded button surface (kept off-brand-on-purpose to match GitHub's own tokens). -### Gradient System -- **Hero Blaze**: A dramatic multi-stop gradient flowing through orange (`#ea2804`) → red → magenta → hot pink. This gradient occupies the full hero section and is the most visually dominant element on the page. -- **Dark Sections**: Deep dark (#202020) sections with white/near-white text provide contrast against the white body. - -## 3. Typography Rules +## Typography ### Font Family -- **Display**: `rb-freigeist-neue`, with fallbacks: `ui-sans-serif, system-ui` -- **Body / UI**: `basier-square`, with fallbacks: `ui-sans-serif, system-ui` -- **Code**: `jetbrains-mono`, with fallbacks: `ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, Liberation Mono, Courier New` + +Replicate ships a deliberate three-family stack: + +- **rb-freigeist-neue** — proprietary heavy grotesque used for all display sizes (30px+). Carries the editorial-magazine personality through tight `lineHeight: 1.0` and negative letter-spacing. +- **basier-square** — proprietary humanist sans-serif used for body, button labels, captions, and metadata. +- **jetbrains-mono** — open-source monospace used in every code well and inline command. + +When proprietary families cannot be licensed, **Bricolage Grotesque** or **Migra** are credible substitutes for rb-freigeist-neue, and **Geist** or **Inter** can stand in for basier-square. JetBrains Mono is open-source and should always be used directly. ### Hierarchy -| Role | Font | Size | Weight | Line Height | Letter Spacing | Notes | -|------|------|------|--------|-------------|----------------|-------| -| Display Mega | rb-freigeist-neue | 128px (8rem) | 700 | 1.00 (tight) | normal | The maximum: closing manifesto | -| Display / Hero | rb-freigeist-neue | 72px (4.5rem) | 700 | 1.00 (tight) | -1.8px | Hero section headline | -| Section Heading | rb-freigeist-neue | 48px (3rem) | 400–700 | 1.00 (tight) | normal | Feature section titles | -| Sub-heading | rb-freigeist-neue | 30px (1.88rem) | 600 | 1.20 (tight) | normal | Card headings | -| Sub-heading Sans | basier-square | 38.4px (2.4rem) | 400 | 0.83 (ultra-tight) | normal | Large body headings | -| Feature Title | basier-square / rb-freigeist-neue | 18px (1.13rem) | 600 | 1.56 | normal | Small section titles, labels | -| Body Large | basier-square | 20px (1.25rem) | 400 | 1.40 | normal | Intro paragraphs | -| Body / Button | basier-square | 16–18px (1–1.13rem) | 400–600 | 1.50–1.56 | normal | Standard text, buttons | -| Caption | basier-square | 14px (0.88rem) | 400–600 | 1.43 | -0.35px to normal | Metadata, descriptions | -| Small / Tag | basier-square | 12px (0.75rem) | 400 | 1.33 | normal | Tags (lowercase transform) | -| Code | jetbrains-mono | 14px (0.88rem) | 400 | 1.43 | normal | Code snippets, API examples | -| Code Small | jetbrains-mono | 11px (0.69rem) | 400 | 1.50 | normal | Tiny code references | +| Token | Size | Weight | Line Height | Letter Spacing | Use | +|---|---|---|---|---|---| +| `{typography.display-xxl}` | 128px | 700 | 1.0 | -3px | The single hero "Run AI" / "Imagine what you can build" headline. One per page. | +| `{typography.display-xl}` | 72px | 700 | 1.0 | -1.8px | Section openers ("How it works", "Scale on Replicate"). | +| `{typography.display-lg}` | 48px | 700 | 1.0 | -1px | Sub-section titles, pricing tier names. | +| `{typography.display-md}` | 30px | 600 | 1.2 | -0.5px | Feature card titles. | +| `{typography.heading-lg}` | 38.4px | 600 | 0.83 | -0.5px | Tightly-stacked basier-square headlines, used in pricing and enterprise hero. | +| `{typography.heading-md}` | 24px | 600 | 1.33 | -0.35px | Card titles, model detail headers. | +| `{typography.heading-sm}` | 20px | 600 | 1.4 | -0.3px | List section headers. | +| `{typography.subtitle}` | 18px | 600 | 1.56 | 0 | Lead paragraphs in display sections. | +| `{typography.body-lg}` | 18px | 400 | 1.56 | 0 | Marketing prose. | +| `{typography.body-md}` | 16px | 400 | 1.5 | 0 | Default body. | +| `{typography.body-sm}` | 14px | 400 | 1.43 | 0 | Captions, metadata. | +| `{typography.button-md}` | 16px | 600 | 1.0 | 0 | Default button label. | +| `{typography.button-sm}` | 14px | 600 | 1.0 | 0 | Compact button label, sub-nav pills. | +| `{typography.caption}` | 12px | 400 | 1.33 | 0 | Footer disclosure, copyright. | +| `{typography.caption-tight}` | 14px | 600 | 1.43 | -0.35px | Emphatic small caption used in pricing tier rows. | +| `{typography.code-md}` | 14px | 400 | 1.43 | 0 | Code blocks and inline code. | +| `{typography.code-sm}` | 11px | 400 | 1.5 | 0 | Code-tab labels and small inline tokens. | ### Principles -- **Heavy display, light body**: rb-freigeist-neue at 700 weight creates thundering headlines, while basier-square at 400 handles body text with quiet efficiency. The contrast is extreme and intentional. -- **128px is a real size**: The closing manifesto "Imagine what you can build." uses 128px — bigger than most mobile screens. This is the design equivalent of shouting from a rooftop. -- **Negative tracking on hero**: -1.8px letter-spacing at 72px creates dense, impactful hero text. -- **Lowercase tags**: 12px basier-square uses `text-transform: lowercase` — an unusual choice that creates a casual, developer-friendly vibe. -- **Weight 600 as emphasis**: When basier-square needs emphasis, it uses 600 (semibold) — never bold (700), which is reserved for rb-freigeist-neue display text. +- Display sizes hold `lineHeight: 1.0` (or 0.83 on `{typography.heading-lg}`) so multi-line stacks read as single typographic blocks. +- Negative letter-spacing scales with size — bigger types tighten more (-3px at 128px down to -0.3px at 20px). Body type stays at 0. +- Body weight sits at 400 across `{typography.body-lg}` and `{typography.body-md}` — never bumped to 500 for emphasis. Emphasis comes from family change (basier-square → rb-freigeist-neue) rather than weight. +- Code is never set in basier-square, even at small sizes — JetBrains Mono carries every literal command, every model slug, every API call. -## 4. Component Stylings +### Note on Font Substitutes + +When the proprietary families are unavailable, clamp display `lineHeight` to 1.0 explicitly and apply a -3% letter-spacing on display-xxl / display-xl to match the original tightness. Substitutes typically render with looser tracking by default. + +## Layout + +### Spacing System +- **Base unit**: 4px, with the working scale on multiples of 4 / 8 / 16. +- **Tokens**: `{spacing.xxs}` 2px · `{spacing.xs}` 4px · `{spacing.sm}` 8px · `{spacing.md}` 12px · `{spacing.lg}` 16px · `{spacing.xl}` 24px · `{spacing.xxl}` 32px · `{spacing.xxxl}` 48px · `{spacing.section}` 96px · `{spacing.band}` 160px. +- Section padding: `{spacing.section}` (96px) vertical between full-width bands; `{spacing.band}` (160px) when a band needs extra editorial breathing room (the hero, the closing "Imagine what you can build" stripe). +- Card internal padding: `{spacing.lg}` (16px) on `{component.model-card}`, `{spacing.xxl}` (32px) on `{component.pricing-tier}`. + +### Grid & Container +- **Max content width** ≈ 1280px on body sections, 1440px on hero bands which run full-bleed. +- **Model grid** on collections: 4 columns at desktop, 3 at tablet large, 2 at tablet, 1 at mobile. +- **Pricing**: 3-tier grid centred at desktop, stacking vertically below 1024px; the centre tier flips to `{component.pricing-tier-featured}` (dark inversion) as the recommended option. +- **Code-story sections**: a 2-up split — narrative copy left, code well right — collapsing to stacked at < 1024px. + +### Whitespace Philosophy +- Whitespace on cream is generous and editorial — sections breathe at 96px and key bands open at 160px so the typography can scale up without feeling cramped. +- Inside cards, the system tightens to 16–32px so model thumbnails, statuses, and metadata sit in a compact list-of-cards rhythm. +- Hairline `{colors.hairline}` dividers replace shadow on cream surfaces; on dark surfaces, `{colors.divider-dark}` carries the equivalent role. + +## Elevation & Depth + +| Level | Treatment | Use | +|---|---|---| +| 0 — flat | No shadow, no border | Default cream canvas, full-bleed bands. | +| 1 — outline | 1px solid `{colors.hairline}` or `{colors.hairline-strong}` | Model cards, pricing tiers, collection tiles. | +| 2 — bone inset | Surface colour shift to `{colors.surface-bone}` inside a `{colors.canvas}` band | Feature group containers, "How it works" walkthrough. | +| 3 — dark inversion | Card swaps to `{colors.surface-dark}` against cream | Code wells, featured pricing tier, "Scale on Replicate" hero card. | +| 4 — soft drop | `0 8px 24px rgba(32,32,32,0.08)` | Hover-anchored model thumbnails (visual only — not interaction-state-documented). | + +Drop shadows exist in the extracted tokens but are restrained — used sparingly to lift photography thumbnails one step off the cream canvas. The dominant elevation language is colour-blocking. + +### Decorative Depth +- **Hero atmospheric mesh** — the orange-to-pink gradient backing the home hero is a layered radial mesh: `{colors.primary}` core → `{colors.hero-glow}` mid-stop → `{colors.hero-pink}` outer wash. Reserved for the home hero band only. +- **Code-story dark band** — the "How it works" section uses `{colors.surface-dark}` full-bleed with a single hairline `{colors.divider-dark}` separating narrative copy and code well. +- **Contributor mosaic** — the home page features a horizontally-scrolling band of circular avatars (`{component.contributor-avatar}`) over a textured cream canvas; this is the only place avatars appear at the brand level. + +## Shapes + +### Border Radius Scale + +| Token | Value | Use | +|---|---|---| +| `{rounded.none}` | 0px | Hero bands, full-bleed sections, footer. | +| `{rounded.xs}` | 4px | Code tabs, inline tags inside code wells. | +| `{rounded.sm}` | 6px | Mid-radius callouts, small inset chips. | +| `{rounded.md}` | 10px | Model cards, collection tiles, code wells. | +| `{rounded.lg}` | 16px | Pricing tiers, larger feature cards. | +| `{rounded.full}` | 9999px | Buttons, inputs, badges, avatars, pills. | + +### Photography Geometry +- Model thumbnails: square (1:1) with `{rounded.md}` corners, full-bleed image to the card edge. +- Hero example outputs: 4:3 or 16:9 with `{rounded.md}` corners. +- Contributor avatars: circular (`{rounded.full}`), 40px on home, 32px in card metadata. +- The hero band uses a stylised black-ink illustration (the "tinkerer at the workbench") as its photography stand-in — kept inside the orange band rather than overlaid on cream. + +## Components ### Buttons -**Dark Solid** -- Background: Replicate Dark (`#202020`) -- Text: Near White (`#fcfcfc`) -- Padding: 0px 4px (extremely compact) -- Outline: Replicate Dark 4px solid -- Radius: pill-shaped (implied by system) -- Maximum emphasis — dark pill on light surface +**`button-primary`** — orange CTA +- Background `{colors.primary}`, label `{colors.on-primary}`, type `{typography.button-md}`, padding `12px 24px`, `rounded: {rounded.full}`, height 44px. +- The single most important action on a page (e.g. "Sign in with GitHub", "Try a model"). +- Pressed state lives in `button-primary-pressed` (background `{colors.primary-deep}`). -**White Outlined** -- Background: Pure White (`#ffffff`) -- Text: Replicate Dark (`#202020`) -- Border: `1px solid #202020` -- Radius: pill-shaped -- Clean outlined pill for secondary actions +**`button-dark`** — dark CTA +- Background `{colors.surface-dark}`, label `{colors.on-dark}`, type `{typography.button-md}`, `rounded: {rounded.full}`. +- Equal-weight secondary action paired with `{component.button-primary}`, or the primary action on cream when orange would be too loud. -**Transparent Glass** -- Background: `rgba(255, 255, 255, 0.1)` (frosted glass) -- Text: Replicate Dark (`#202020`) -- Padding: 6px 56px 6px 28px (asymmetric — icon/search layout) -- Border: transparent -- Outline: Light Silver (`#bbbbbb`) 1px solid -- Used for search/input-like buttons +**`button-outline`** — outlined CTA +- Background `{colors.surface-card}`, label `{colors.ink}`, 1px solid `{colors.hairline-strong}`, type `{typography.button-md}`, `rounded: {rounded.full}`. +- Tertiary action; appears alongside primary/dark for "View docs", "Read more". + +**`button-ghost`** — inline button +- Background `{colors.canvas}`, label `{colors.ink}`, no border, type `{typography.button-md}`, `rounded: {rounded.full}`, padding `8px 16px`. +- Sub-actions inside cards and inline with body copy. + +**`button-icon`** — icon button +- Background `{colors.surface-card}`, label `{colors.ink}`, 1px solid `{colors.hairline}`, `rounded: {rounded.full}`, 36×36px circular. +- Carousel arrows, copy-to-clipboard, GitHub link icon. ### Cards & Containers -- Background: Pure White or subtle gray -- Border: `1px solid #202020` for prominent containment -- Radius: pill-shaped (9999px) for badges, labels, images -- Shadow: minimal standard shadows -- Model gallery: grid of AI-generated image thumbnails -- Accent border: `1px solid #ea2804` for highlighted/featured items + +**`model-card`** — model listing card +- Background `{colors.surface-card}`, text `{colors.ink}`, type `{typography.body-md}`, `rounded: {rounded.md}`, padding `{spacing.lg}` (16px). +- Square thumbnail on top, model owner + name beneath in `{typography.body-sm}`, single-line description in `{colors.charcoal}`, status pill `{component.badge-status}` bottom-left. + +**`collection-tile`** — collection-of-models tile +- Background `{colors.canvas}`, text `{colors.ink}`, type `{typography.heading-md}`, `rounded: {rounded.md}`, padding `{spacing.xl}` (24px). +- Cream-on-cream tile inside a `{colors.surface-bone}` band, used for browsing model categories. + +**`pricing-tier`** — pricing tier card +- Background `{colors.surface-card}`, text `{colors.ink}`, type `{typography.body-md}`, `rounded: {rounded.lg}`, padding `{spacing.xxl}` (32px). +- 3-up grid; tier name in `{typography.display-lg}` ("Free", "Pro", "Enterprise"), price in `{typography.display-md}`. + +**`pricing-tier-featured`** — featured pricing tier +- Background `{colors.surface-dark}`, text `{colors.on-dark}`, type `{typography.body-md}`, `rounded: {rounded.lg}`, padding `{spacing.xxl}`. +- Centre tier flipped to dark inversion to mark "recommended". + +**`code-block`** — code well +- Background `{colors.surface-dark}`, text `{colors.on-dark}`, type `{typography.code-md}`, `rounded: {rounded.md}`, padding `{spacing.xl}` (24px). +- Tab strip on top using `{component.code-tab}` for switching between languages (Python, Node.js, cURL, HTTP). + +**`code-tab`** — code tab chip +- Background `{colors.surface-deep}`, text `{colors.on-dark-mute}`, type `{typography.code-sm}`, `rounded: {rounded.xs}`, padding `6px 12px`. +- Active tab swaps text colour to `{colors.on-dark}` and adds a 2px bottom underline in `{colors.primary}`. + +**`hero-band`** — full-bleed hero +- Background `{colors.hero-warm}` with the atmospheric mesh detailed in Elevation, text `{colors.on-dark}`, type `{typography.display-xxl}` for the title. +- Used only on the home page; secondary pages open with cream + `{typography.display-xl}`. ### Inputs & Forms -- Background: `rgba(255, 255, 255, 0.1)` (frosted glass) -- Text: Replicate Dark (`#202020`) -- Border: transparent with outline -- Padding: 6px 56px 6px 28px (search-bar style) + +**`text-input`** — default input +- Background `{colors.surface-card}`, text `{colors.ink}`, type `{typography.body-md}`, 1px solid `{colors.hairline}`, `rounded: {rounded.full}`, padding `12px 20px`, height 44px. +- Pill-shaped search and email fields. Focus state adds a `{colors.ring-focus}` 3px ring. ### Navigation -- Clean horizontal nav on white -- Logo: Replicate wordmark in dark -- Links: dark text with dotted underline on hover -- CTA: Dark pill button -- GitHub link and sign-in -### Image Treatment -- AI-generated model output images in a gallery grid -- Pill-shaped image containers (9999px) -- Full-width gradient hero section -- Product screenshots with dark backgrounds +**`nav-bar`** — top nav (desktop) +- Background `{colors.canvas}`, type `{typography.button-sm}`, height 60px, single hairline `{colors.hairline}` bottom border. +- Left: wordmark logo. Centre: top-level nav ("Explore", "Pricing", "Docs", "Blog"). Right: GitHub icon + "Sign in" link + `{component.button-primary}`. -### Distinctive Components +**`nav-bar`** (mobile) +- Same height 60px, collapses centre nav into a hamburger icon. Logo stays left, sign-in CTA stays right. -**Model Gallery Grid** -- Horizontal scrolling or grid of AI-generated images -- Each image in a pill-shaped container -- Model names and run counts displayed -- The visual heart of the community platform +**`sub-nav-pill`** — sub-nav chip +- Pill chips set in a horizontal row above content (e.g. "All", "Featured", "Image generation", "Audio"), `{component.sub-nav-pill}` styling. -**Dotted Underline Links** -- Links use `text-decoration: underline dotted #bbbbbb` -- A distinctive, developer-notebook aesthetic -- Lighter and more casual than solid underlines +### Signature Components -**Status Badges** -- Status Green (`#2b9a66`) background with white text -- Pill-shaped (9999px) -- 14px font size -- Indicates model availability/operational status +**`badge-status`** — model status badge +- Background `{colors.badge-success}`, label `{colors.on-dark}`, type `{typography.caption}`, `rounded: {rounded.full}`, padding `4px 10px`. +- Anchored on the bottom-left of model cards to indicate "running" or "deployed". -**Manifesto Section** -- "Imagine what you can build." at 128px -- Dark background with white text -- Images embedded between words -- The emotional climax of the page +**`badge-tag`** — neutral tag +- Background `{colors.canvas}`, label `{colors.ink}`, 1px solid `{colors.hairline}`, type `{typography.caption}`, `rounded: {rounded.full}`, padding `4px 10px`. +- Capability tags ("text-to-image", "video", "audio") on model cards. -## 5. Layout Principles +**`contributor-avatar`** — community contributor +- Background `{colors.surface-card}` placeholder behind 1:1 photography, `rounded: {rounded.full}`, 40×40px (32px in metadata contexts). +- Used in the home-page contributor mosaic. -### Spacing System -- Base unit: 8px -- Scale: 1px, 2px, 4px, 6px, 8px, 10px, 12px, 16px, 24px, 32px, 48px, 64px, 96px, 160px, 192px -- Button padding: varies widely (0px 4px to 6px 56px) -- Section vertical spacing: very generous (96–192px) +**`footer`** — global footer +- Background `{colors.surface-deep}`, text `{colors.on-dark}`, type `{typography.body-sm}`, `rounded: {rounded.none}`, padding `64px 32px`. +- Multi-column quick-links grid above a copyright row separated by `{colors.divider-dark}`. -### Grid & Container -- Fluid width with responsive constraints -- Hero: full-width gradient with centered content -- Model gallery: multi-column responsive grid -- Feature sections: mixed layouts -- Code examples: contained dark blocks - -### Whitespace Philosophy -- **Bold and generous**: Massive spacing between sections (up to 192px) creates distinct zones. -- **Dense within galleries**: Model images are tightly packed in the grid for browsable density. -- **The gradient IS the whitespace**: The hero gradient section occupies significant vertical space as a colored void. - -### Border Radius Scale -- **Pill (9999px)**: The ONLY radius in the system. Everything interactive, every image, every badge, every label, every container uses 9999px. This is the most extreme pill-radius commitment in any major tech brand. - -## 6. Depth & Elevation - -| Level | Treatment | Use | -|-------|-----------|-----| -| Flat (Level 0) | No shadow | White body, text blocks | -| Bordered (Level 1) | `1px solid #202020` | Cards, buttons, containers | -| Accent Border (Level 2) | `1px solid #ea2804` | Featured/highlighted items | -| Gradient Hero (Level 3) | Full-width blaze gradient | Hero section, maximum visual impact | -| Dark Section (Level 4) | Dark bg (#202020) with light text | Manifesto, footer, feature sections | - -**Shadow Philosophy**: Replicate relies on **borders and background color** for depth rather than shadows. The `1px solid #202020` border is the primary containment mechanism. The dramatic gradient hero and dark/light section alternation provide all the depth the design needs. - -## 7. Do's and Don'ts +## Do's and Don'ts ### Do -- Use pill-shaped (9999px) radius on EVERYTHING — buttons, images, badges, containers -- Use rb-freigeist-neue at weight 700 for display text — go big (72px+) or go home -- Use the orange-red brand gradient for hero sections -- Use Replicate Dark (#202020) as the primary dark — not pure black -- Apply dotted underline decoration on text links (#bbbbbb) -- Use Status Green (#2b9a66) for operational/success badges -- Keep body text in basier-square at 400–600 weight -- Use JetBrains Mono for all code content -- Create a "manifesto" section with 128px type for emotional impact +- Use `{colors.canvas}` (cream) as the default page background. White (`{colors.surface-card}`) appears only on individual cards, inputs, and the hero illustration backdrop. +- Reserve `{colors.primary}` for the primary CTA, the home hero band, and inline links — three roles, nothing else. +- Set every interactive element to `{rounded.full}` — buttons, inputs, badges, avatars, pills. +- Step content cards up to `{rounded.md}` (10px) or `{rounded.lg}` (16px) — never sharp corners. +- Open hero bands with `{typography.display-xxl}` (128px) and `{typography.display-xl}` (72px) at `lineHeight: 1.0` with negative letter-spacing. +- Use `rb-freigeist-neue` for all display, `basier-square` for UI/body, `jetbrains-mono` for code. Keep the lanes strict. +- Render code in `{component.code-block}` with a `{colors.surface-dark}` background — code is print, not an inline grey box. +- Pair photography with `{rounded.md}` corners and full-bleed crop inside cards. ### Don't -- Don't use any border-radius other than 9999px — the pill system is absolute -- Don't use the brand red (#ea2804) as a surface/background color — it's for gradients and accent borders -- Don't reduce display text below 48px on desktop — the heavy display font needs size to breathe -- Don't use light/thin font weights on rb-freigeist-neue — 600–700 is the range -- Don't use solid underlines on links — dotted is the signature -- Don't add drop shadows — depth comes from borders and background color -- Don't use warm neutrals — the gray scale is purely neutral (#202020 → #bbbbbb) -- Don't skip the code examples — they're primary content, not decoration -- Don't make the hero gradient subtle — it should be BOLD and vibrant +- Don't replace cream with pure white at the page level. The brand temperature comes from `{colors.canvas}`. +- Don't introduce a secondary brand colour. Orange is the only accent; semantic green and focus blue are functional, not decorative. +- Don't loosen display `lineHeight` past 1.0. Tight stacking is structural. +- Don't bump body weight to 500 for emphasis — change family (`basier-square` → `rb-freigeist-neue`) instead. +- Don't apply `{rounded.full}` to content cards. Pill-shaped cards break the rhythm. +- Don't put code in a light grey box. Code wells are always `{colors.surface-dark}` or `{colors.surface-deep}`. +- Don't use orange on body text or large surfaces — it loses its stamp quality immediately. +- Don't add drop shadows on cream surfaces. Elevation is colour-blocking; shadows are reserved for floating thumbnails. -## 8. Responsive Behavior +## Responsive Behavior ### Breakpoints -*No explicit breakpoints detected — likely using fluid/container-query responsive system.* + +| Name | Width | Key Changes | +|---|---|---| +| Desktop XL | ≥ 1440px | Full max-width 1280 body, hero band runs full-bleed, 4-up model grid. | +| Desktop | 1280–1439px | Container shrinks; padding `{spacing.xl}` (24px) sides. | +| Tablet Large | 1024–1279px | Model grid 3-up, code-story splits remain 2-up. | +| Tablet | 768–1023px | Model grid 2-up, code-story stacks (narrative on top, code below), pricing stacks vertically. | +| Mobile Large | 426–767px | Model grid 1-up at 480px+, nav collapses to hamburger, hero `{typography.display-xxl}` clamps to 64px. | +| Mobile | ≤ 425px | All grids 1-up, hero clamps to 48px, section padding `{spacing.section}` collapses to 64px. | ### Touch Targets -- Pill buttons with generous padding -- Gallery images as large touch targets -- Navigation adequately spaced +- All buttons ship at minimum 44px tall on mobile; default `{component.button-primary}` is 44px tall — comfortably clearing WCAG AAA. +- `{component.button-icon}` (36px) is bumped to 44px on mobile via increased padding. +- `{component.sub-nav-pill}` stays at 36px on desktop and grows to 40px on mobile via vertical padding adjustment. ### Collapsing Strategy -- **Hero text**: 128px → 72px → 48px progressive scaling -- **Model gallery**: Grid reduces columns -- **Navigation**: Collapses to hamburger -- **Manifesto**: Scales down but maintains impact +- Top-level nav collapses to hamburger at < 1024px; the wordmark and `{component.button-primary}` stay anchored. +- Hero `{typography.display-xxl}` clamps: 128px → 96px → 64px → 48px across the breakpoint ladder. +- Pricing 3-up grid stacks vertically at < 1024px with the featured tier remaining centre-stacked. +- Code-story splits switch from side-by-side to stacked at < 1024px, code well always second. +- Sub-nav pills convert from a wrap row to a horizontal scroll-rail at < 768px. ### Image Behavior -- AI-generated images scale within pill containers -- Gallery reflows to fewer columns on narrow screens -- Hero gradient maintained at all sizes +- Model thumbnails serve at 1.5× and 2× DPR; below 768px the system swaps to a 600×600 export instead of 1200×1200. +- Hero atmospheric mesh is rendered as a CSS gradient — no asset cost, no breakpoint variation. +- Code-block contents wrap softly at < 1024px (no horizontal scroll); long lines break with a continuation marker. -## 9. Agent Prompt Guide +## Iteration Guide -### Quick Color Reference -- Primary Text: "Replicate Dark (#202020)" -- Page Background: "Pure White (#ffffff)" -- Brand Accent: "Replicate Red (#ea2804)" -- Secondary Text: "Medium Gray (#646464)" -- Muted/Decoration: "Light Silver (#bbbbbb)" -- Status: "Status Green (#2b9a66)" -- Dark Surface: "Replicate Dark (#202020)" +1. Focus on ONE component at a time. Most interactive elements share `{rounded.full}` and the `{colors.canvas}` / `{colors.surface-card}` pair — only the role-specific tokens (`{colors.primary}`, `{component.code-block}`) shift between variants. +2. Reference component names and tokens directly (`{colors.primary}`, `{component.button-primary-pressed}`, `{rounded.lg}`) — do not paraphrase. +3. Run `npx @google/design.md lint DESIGN.md` after edits; orphaned-tokens warnings will catch unused entries. +4. Add new variants as separate entries (`-pressed`, `-disabled`, `-featured`) — do not bury them in prose. +5. Default body type to `{typography.body-md}`; reach for `{typography.subtitle}` only on hero subtitles. +6. Keep `{colors.primary}` scarce — if more than one orange element appears per viewport, ask whether one should drop to `{colors.surface-dark}` instead. -### Example Component Prompts -- "Create a hero section with a vibrant orange-red-magenta gradient background. Headline at 72px rb-freigeist-neue weight 700, white text, -1.8px letter-spacing. Include a dark pill CTA button and a white outlined pill button." -- "Design a model card with pill-shaped (9999px) image container, model name at 16px basier-square weight 600, run count at 14px in Medium Gray. Border: 1px solid #202020." -- "Build a status badge: pill-shaped (9999px), Status Green (#2b9a66) background, white text at 14px basier-square." -- "Create a manifesto section on Replicate Dark (#202020) with 'Imagine what you can build.' at 128px rb-freigeist-neue weight 700, white text. Embed small AI-generated images between the words." -- "Design a code block: dark background (#24292e), JetBrains Mono at 14px, white text. Pill-shaped container." +## Known Gaps -### Iteration Guide -1. Everything is pill-shaped — never specify any other border-radius -2. Display text is HEAVY — weight 700, sizes 48px+ -3. Links use dotted underline (#bbbbbb) — never solid -4. The gradient hero is the visual anchor — make it bold -5. Use basier-square for body, rb-freigeist-neue for display, JetBrains Mono for code +- Active/pressed visual states are documented for `button-primary-pressed` only; other components rely on the focus-ring (`{colors.ring-focus}`) for interactive feedback, which is not extracted as a per-component variant. +- The model playground / try-this-model interactive surfaces (logged-in feature) are out of scope; only the public marketing canvas is documented. +- Dashboard / billing / API key management surfaces are not extracted — those live behind authentication. +- The home hero illustration ("the tinkerer at the workbench") is treated as decorative artwork, not a system component; replicating it requires bespoke illustration rather than tokens. diff --git a/design-md/resend/DESIGN.md b/design-md/resend/DESIGN.md index 2f5ad09..e8c278b 100644 --- a/design-md/resend/DESIGN.md +++ b/design-md/resend/DESIGN.md @@ -1,303 +1,585 @@ -# Design System Inspired by Resend +--- +version: alpha +name: Resend +description: | + Resend's marketing surfaces sit on a near-pure black canvas with off-white + text and a single signature color — the deep editorial-serif Domaine + Display headline mark — that gives an otherwise utilitarian developer-tool + brand its print-magazine confidence. The system pairs Domaine Display + (oversized 76px–96px serif, ss01/ss04/ss11 features on) with ABC Favorit + for body and Inter for UI. Surfaces rely on subtle 6–9% opacity gradient + glows, hairline 1px borders made from translucent white, and a strict + rounded-12px container vocabulary. There is no decorative chrome — just + type, code, and atmospheric depth. -## 1. Visual Theme & Atmosphere +colors: + primary: "#fcfdff" + primary-on: "#000000" + ink: "#fcfdff" + body: "rgba(252,253,255,0.86)" + charcoal: "rgba(252,253,255,0.7)" + mute: "#a1a4a5" + ash: "#888e90" + stone: "#464a4d" + on-light: "#000000" + on-light-mute: "rgba(0,0,51,0.7)" + canvas: "#000000" + surface-card: "#0a0a0c" + surface-elevated: "#101012" + surface-deep: "#06060a" + hairline: "rgba(255,255,255,0.06)" + hairline-strong: "rgba(255,255,255,0.14)" + divider-soft: "rgba(255,255,255,0.04)" + accent-orange: "#ff801f" + accent-orange-glow: "rgba(255,89,0,0.22)" + accent-yellow: "#ffc53d" + accent-blue: "#3b9eff" + accent-blue-glow: "rgba(0,117,255,0.34)" + accent-green: "#11ff99" + accent-green-glow: "rgba(34,255,153,0.18)" + accent-red: "#ff2047" + accent-red-glow: "rgba(255,32,71,0.34)" + link: "#3b9eff" + surface-light: "#f1f7fe" -Resend's website is a dark, cinematic canvas that treats email infrastructure like a luxury product. The entire page is draped in pure black (`#000000`) with text that glows in near-white (`#f0f0f0`), creating a theater-like experience where content performs on a void stage. This isn't the typical developer-tool darkness — it's the controlled darkness of a photography gallery, where every element is lit with intention and nothing competes for attention. +typography: + display-xxl: + fontFamily: Domaine Display + fontSize: 96px + fontWeight: 400 + lineHeight: 1.0 + letterSpacing: -0.96px + fontFeature: "ss01, ss04, ss11" + display-xl: + fontFamily: Domaine Display + fontSize: 76.8px + fontWeight: 400 + lineHeight: 1.0 + letterSpacing: -0.768px + fontFeature: "ss01, ss04, ss11" + display-lg: + fontFamily: ABC Favorit + fontSize: 56px + fontWeight: 400 + lineHeight: 1.2 + letterSpacing: -2.8px + fontFeature: "ss01, ss04, ss11" + heading-md: + fontFamily: Inter + fontSize: 24px + fontWeight: 500 + lineHeight: 1.5 + letterSpacing: -0.4px + heading-sm: + fontFamily: Inter + fontSize: 20px + fontWeight: 500 + lineHeight: 1.3 + letterSpacing: -0.3px + subtitle: + fontFamily: ABC Favorit + fontSize: 20px + fontWeight: 400 + lineHeight: 1.3 + fontFeature: "ss01, ss04, ss11" + body-lg: + fontFamily: Inter + fontSize: 18px + fontWeight: 400 + lineHeight: 1.5 + body-md: + fontFamily: ABC Favorit + fontSize: 16px + fontWeight: 400 + lineHeight: 1.5 + letterSpacing: -0.8px + fontFeature: "ss01, ss04, ss11" + body-sm: + fontFamily: Inter + fontSize: 14px + fontWeight: 400 + lineHeight: 1.43 + button-md: + fontFamily: Inter + fontSize: 14px + fontWeight: 500 + lineHeight: 1.43 + button-sm: + fontFamily: ABC Favorit + fontSize: 14px + fontWeight: 500 + lineHeight: 1.43 + letterSpacing: 0.35px + fontFeature: "ss01, ss03, ss04" + caption: + fontFamily: Inter + fontSize: 12px + fontWeight: 400 + lineHeight: 1.5 + caption-emph: + fontFamily: Helvetica + fontSize: 14px + fontWeight: 600 + lineHeight: 1.0 + code-md: + fontFamily: Geist Mono + fontSize: 13px + fontWeight: 400 + lineHeight: 1.6 -The typography system is the star of the show. Three carefully chosen typefaces create a hierarchy that feels both editorial and technical: Domaine Display (a Klim Type Foundry serif) appears at massive 96px for hero headlines with barely-there line-height (1.00) and negative tracking (-0.96px), creating display text that feels like a magazine cover. ABC Favorit (by Dinamo) handles section headings with an even more aggressive letter-spacing (-2.8px at 56px), giving a compressed, engineered quality to mid-tier text. Inter takes over for body and UI, providing the clean readability that lets the display fonts shine. Commit Mono rounds out the family for code blocks. +rounded: + none: 0px + xs: 4px + sm: 6px + md: 8px + lg: 12px + xl: 16px + full: 9999px -What makes Resend distinctive is its icy, blue-tinted border system. Instead of neutral gray borders, Resend uses `rgba(214, 235, 253, 0.19)` — a frosty, slightly blue-tinted line at 19% opacity that gives every container and divider a cold, crystalline quality against the black background. Combined with pill-shaped buttons (9999px radius), multi-color accent system (orange, green, blue, yellow, red — each with its own CSS variable scale), and OpenType stylistic sets (`"ss01"`, `"ss03"`, `"ss04"`, `"ss11"`), the result is a design system that feels premium, precise, and quietly confident. +spacing: + xxs: 2px + xs: 4px + sm: 8px + md: 12px + lg: 16px + xl: 24px + xxl: 32px + xxxl: 48px + section: 96px + band: 128px + +components: + button-primary: + backgroundColor: "{colors.primary}" + textColor: "{colors.primary-on}" + typography: "{typography.button-md}" + rounded: "{rounded.md}" + padding: 8px 16px + height: 36px + button-primary-pressed: + backgroundColor: "{colors.surface-light}" + textColor: "{colors.primary-on}" + typography: "{typography.button-md}" + rounded: "{rounded.md}" + button-ghost: + backgroundColor: "{colors.surface-elevated}" + textColor: "{colors.ink}" + typography: "{typography.button-md}" + rounded: "{rounded.md}" + padding: 8px 16px + height: 36px + button-outline: + backgroundColor: "{colors.canvas}" + textColor: "{colors.ink}" + typography: "{typography.button-md}" + rounded: "{rounded.md}" + padding: 7px 15px + height: 36px + text-input: + backgroundColor: "{colors.surface-card}" + textColor: "{colors.ink}" + typography: "{typography.body-sm}" + rounded: "{rounded.md}" + padding: 10px 14px + height: 40px + hero-stripe: + backgroundColor: "{colors.canvas}" + textColor: "{colors.ink}" + typography: "{typography.display-xxl}" + rounded: "{rounded.none}" + padding: 96px 32px + feature-card: + backgroundColor: "{colors.surface-card}" + textColor: "{colors.ink}" + typography: "{typography.body-md}" + rounded: "{rounded.lg}" + padding: 32px + feature-card-bordered: + backgroundColor: "{colors.surface-card}" + textColor: "{colors.ink}" + typography: "{typography.body-md}" + rounded: "{rounded.lg}" + padding: 32px + pricing-tier: + backgroundColor: "{colors.surface-card}" + textColor: "{colors.ink}" + typography: "{typography.body-md}" + rounded: "{rounded.lg}" + padding: 32px + pricing-tier-featured: + backgroundColor: "{colors.surface-elevated}" + textColor: "{colors.ink}" + typography: "{typography.body-md}" + rounded: "{rounded.lg}" + padding: 32px + code-window: + backgroundColor: "{colors.surface-deep}" + textColor: "{colors.body}" + typography: "{typography.code-md}" + rounded: "{rounded.lg}" + padding: 24px + code-tab: + backgroundColor: "{colors.surface-card}" + textColor: "{colors.charcoal}" + typography: "{typography.code-md}" + rounded: "{rounded.sm}" + padding: 6px 12px + email-mockup: + backgroundColor: "{colors.surface-card}" + textColor: "{colors.ink}" + typography: "{typography.body-md}" + rounded: "{rounded.lg}" + padding: 0 + badge-pill: + backgroundColor: "{colors.surface-elevated}" + textColor: "{colors.body}" + typography: "{typography.caption}" + rounded: "{rounded.full}" + padding: 4px 10px + status-dot: + backgroundColor: "{colors.accent-green}" + rounded: "{rounded.full}" + size: 8px + nav-bar: + backgroundColor: "{colors.canvas}" + textColor: "{colors.body}" + typography: "{typography.button-sm}" + rounded: "{rounded.none}" + height: 64px + sub-nav-pill: + backgroundColor: "{colors.surface-elevated}" + textColor: "{colors.body}" + typography: "{typography.button-sm}" + rounded: "{rounded.full}" + padding: 6px 14px + contributor-avatar: + backgroundColor: "{colors.surface-card}" + rounded: "{rounded.full}" + size: 32px + footer: + backgroundColor: "{colors.canvas}" + textColor: "{colors.charcoal}" + typography: "{typography.body-sm}" + rounded: "{rounded.none}" + padding: 64px 32px +--- + +## Overview + +Resend looks like a developer tool with the typography of an editorial. +Every page opens on `{colors.canvas}` (`#000000`), and the loudest element on +the canvas is not a button or a brand stamp — it's a 96px Domaine Display +serif headline ("Email for developers", "Email reimagined") with the +`ss01 / ss04 / ss11` stylistic alternates engaged. That single typographic +decision sets the brand tone: confident, considered, slightly literary, and +priced on quality rather than novelty. + +The supporting cast is technical. Body copy switches to **ABC Favorit** for +marketing prose and **Inter** for UI labels, while code blocks render in +**Geist Mono** inside `{component.code-window}` shells with hairline traffic- +light dots. Surface depth is built almost entirely from translucent white — +6% borders, 14% strong borders, 4% dividers — over a deep `{colors.surface-deep}` +layer that sits just below the canvas black. There are no gradients painted +across full bands, just **soft atmospheric glows** (orange, blue, green, red, +yellow) anchored at the top of select sections, all at low opacity. + +Page rhythm cycles in a single dark register: hero stripe → atmospheric +section → code window section → email mockup section → pricing or feature +grid → black footer. The brand never warms to a light surface; even +secondary email mockups are rendered as compact white cards inside the dark +canvas, framed like print insets in a black-bordered magazine page. **Key Characteristics:** -- Pure black background with near-white (`#f0f0f0`) text — theatrical, gallery-like darkness -- Three-font hierarchy: Domaine Display (serif hero), ABC Favorit (geometric sections), Inter (body/UI) -- Icy blue-tinted borders: `rgba(214, 235, 253, 0.19)` — every border has a cold, crystalline shimmer -- Multi-color accent system: orange, green, blue, yellow, red — each with numbered CSS variable scales -- Pill-shaped buttons and tags (9999px radius) with transparent backgrounds -- OpenType stylistic sets (`"ss01"`, `"ss03"`, `"ss04"`, `"ss11"`) on display fonts -- Commit Mono for code — monospace as a design element, not an afterthought -- Whisper-level shadows using blue-tinted ring: `rgba(176, 199, 217, 0.145) 0px 0px 0px 1px` +- Pure black canvas (`{colors.canvas}` — `#000000`) on every public page; off-white text (`{colors.ink}` — `#fcfdff`) carries the full read. +- A serif-led type system: **Domaine Display** at 76–96px for hero headlines, **ABC Favorit** for marketing body, **Inter** for UI, **Geist Mono** for code. +- Six accent glow colours used only as low-opacity atmospheric washes (`{colors.accent-orange}`, `{colors.accent-blue}`, `{colors.accent-green}`, `{colors.accent-red}`, `{colors.accent-yellow}`) — never as buttons or solid surfaces. +- Strict container vocabulary: `{rounded.lg}` (12px) for feature cards, code wells, and email mockups; `{rounded.md}` (8px) for buttons; `{rounded.full}` for pills and avatars. +- Translucent white borders (`{colors.hairline}` 6% / `{colors.hairline-strong}` 14%) replace shadows entirely — the system has no traditional drop-shadow elevation language. +- `{component.button-primary}` is a small white rectangle with black text — counterintuitive contrast that becomes the page's brightest pixel and works as a single visual anchor. -## 2. Color Palette & Roles +## Colors -### Primary -- **Void Black** (`#000000`): Page background, the defining canvas color (95% opacity via `--color-black-12`) -- **Near White** (`#f0f0f0`): Primary text, button text, high-contrast elements -- **Pure White** (`#ffffff`): `--color-white`, maximum emphasis text, link highlights +### Brand & Accent +- **Primary White** (`{colors.primary}` — `#fcfdff`): the brand's de facto accent. Reserved for `{component.button-primary}` (white pill on black canvas), Domaine display headlines, and the active text colour. White is the loudest possible colour on this canvas — that's the signature. +- **Primary On** (`{colors.primary-on}` — `#000000`): label colour on top of `{colors.primary}` surfaces. Black text on white pill is the brand's CTA pattern. +- **Surface Light** (`{colors.surface-light}` — `#f1f7fe`): a subtle blue-tinted off-white used as the active/pressed state of `{component.button-primary}`. -### Accent Scale — Orange -- **Orange 4** (`#ff5900`): `--color-orange-4`, at 22% opacity — subtle warm glow -- **Orange 10** (`#ff801f`): `--color-orange-10`, primary orange accent — warm, energetic -- **Orange 11** (`#ffa057`): `--color-orange-11`, lighter orange for secondary use +### Surface +- **Canvas** (`{colors.canvas}` — `#000000`): the default page background. True black, never near-black. +- **Surface Card** (`{colors.surface-card}` — `#0a0a0c`): the standard inset card surface, just lighter than canvas to register a step up in elevation. +- **Surface Elevated** (`{colors.surface-elevated}` — `#101012`): a second elevation step used on featured pricing tiers and ghost button surfaces. +- **Surface Deep** (`{colors.surface-deep}` — `#06060a`): code window background — slightly cooler and darker than the canvas itself, suggesting depth via temperature. +- **Hairline** (`{colors.hairline}` — `rgba(255,255,255,0.06)`): the soft 1px translucent-white divider used between rows and around feature cards. +- **Hairline Strong** (`{colors.hairline-strong}` — `rgba(255,255,255,0.14)`): the structural 1px border on cards, code wells, and form inputs. +- **Divider Soft** (`{colors.divider-soft}` — `rgba(255,255,255,0.04)`): low-contrast dividers between footer columns. -### Accent Scale — Green -- **Green 3** (`#22ff99`): `--color-green-3`, at 12% opacity — faint emerald wash -- **Green 4** (`#11ff99`): `--color-green-4`, at 18% opacity — success indicator glow +### Text +- **Ink** (`{colors.ink}` — `#fcfdff`): primary text colour on the dark canvas. Faintly blue-cool to feel like printed paper rather than pure white pop. +- **Body** (`{colors.body}` — `rgba(252,253,255,0.86)`): long-form body text where pure ink would feel too sharp. +- **Charcoal** (`{colors.charcoal}` — `rgba(252,253,255,0.7)`): captions, secondary nav labels. +- **Mute** (`{colors.mute}` — `#a1a4a5`): supporting text and inactive labels. +- **Ash** (`{colors.ash}` — `#888e90`): tertiary text, footer copy. +- **Stone** (`{colors.stone}` — `#464a4d`): disabled foreground. +- **On-Light** (`{colors.on-light}` — `#000000`): label colour inside the rare email-mockup white cards. +- **On-Light Mute** (`{colors.on-light-mute}` — `rgba(0,0,51,0.7)`): secondary text inside email mockups. -### Accent Scale — Blue -- **Blue 4** (`#0075ff`): `--color-blue-4`, at 34% opacity — medium blue accent -- **Blue 5** (`#0081fd`): `--color-blue-5`, at 42% opacity — stronger blue -- **Blue 10** (`#3b9eff`): `--color-blue-10`, bright blue — links, interactive elements +### Semantic +- **Accent Orange** (`{colors.accent-orange}` — `#ff801f`) + glow (`{colors.accent-orange-glow}` — `rgba(255,89,0,0.22)`): atmospheric warm wash anchored to "Email reimagined" / customer story sections. Solid orange never appears as a button or surface — only the glow. +- **Accent Yellow** (`{colors.accent-yellow}` — `#ffc53d`): used in inline highlight strokes and "first-class developer experience" key callouts. +- **Accent Blue** (`{colors.accent-blue}` — `#3b9eff`) + glow (`{colors.accent-blue-glow}` — `rgba(0,117,255,0.34)`): inline link colour and the cool atmospheric wash on the "Integrate this weekend" section. +- **Accent Green** (`{colors.accent-green}` — `#11ff99`) + glow (`{colors.accent-green-glow}` — `rgba(34,255,153,0.18)`): success status dots and the "delivery confirmed" feature glow. +- **Accent Red** (`{colors.accent-red}` — `#ff2047`) + glow (`{colors.accent-red-glow}` — `rgba(255,32,71,0.34)`): inline error red and the "reach humans, not spam folders" attention wash. +- **Link** (`{colors.link}` — `#3b9eff`): inline link colour — same as accent blue. -### Accent Scale — Other -- **Yellow 9** (`#ffc53d`): `--color-yellow-9`, warm gold for warnings or highlights -- **Red 5** (`#ff2047`): `--color-red-5`, at 34% opacity — error states, destructive actions +## Typography -### Neutral Scale -- **Silver** (`#a1a4a5`): Secondary text, muted links, descriptions -- **Dark Gray** (`#464a4d`): Tertiary text, de-emphasized content -- **Mid Gray** (`#5c5c5c`): Hover states, subtle emphasis -- **Medium Gray** (`#494949`): Quaternary text -- **Light Gray** (`#f8f8f8`): Light mode surface (if applicable) -- **Border Gray** (`#eaeaea`): Light context borders -- **Edge Gray** (`#ececec`): Subtle borders on light surfaces -- **Mist Gray** (`#dedfdf`): Light dividers -- **Soft Gray** (`#e5e6e6`): Alternate light border +### Font Family -### Surface & Overlay -- **Frost Primary** (`#fcfdff`): Primary color token (slight blue tint, 94% opacity) -- **White Hover** (`rgba(255, 255, 255, 0.28)`): Button hover state on dark -- **White 60%** (`oklab(0.999994 ... / 0.577)`): Semi-transparent white for muted text -- **White 64%** (`oklab(0.999994 ... / 0.642)`): Slightly brighter semi-transparent white +Resend ships a four-family stack: -### Borders & Shadows -- **Frost Border** (`rgba(214, 235, 253, 0.19)`): The signature — icy blue-tinted borders at 19% opacity -- **Frost Border Alt** (`rgba(217, 237, 254, 0.145)`): Slightly lighter variant for list items -- **Ring Shadow** (`rgba(176, 199, 217, 0.145) 0px 0px 0px 1px`): Blue-tinted shadow-as-border -- **Focus Ring** (`rgb(0, 0, 0) 0px 0px 0px 8px`): Heavy black focus ring -- **Subtle Shadow** (`rgba(0, 0, 0, 0.1) 0px 1px 3px, rgba(0, 0, 0, 0.1) 0px 1px 2px -1px`): Minimal card elevation +- **Domaine Display** — proprietary editorial serif used exclusively for hero headlines at 76px+, with `ss01 / ss04 / ss11` stylistic sets engaged for a slightly tighter, more print-magazine look. +- **ABC Favorit** — proprietary humanist sans-serif used for marketing body copy, hero subtitles, and pill labels. Carries `ss01 / ss03 / ss04` features for tabular figures and alternate glyphs. +- **Inter** — open-source sans-serif used for UI: button labels, captions, card body text, nav links. +- **Geist Mono** — open-source monospace used in code wells. -## 3. Typography Rules - -### Font Families -- **Display Serif**: `domaine` (Domaine Display by Klim Type Foundry) — hero headlines -- **Display Sans**: `aBCFavorit` (ABC Favorit by Dinamo), fallbacks: `ui-sans-serif, system-ui` — section headings -- **Body / UI**: `inter`, fallbacks: `ui-sans-serif, system-ui` — body text, buttons, navigation -- **Monospace**: `commitMono`, fallbacks: `ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas` -- **Secondary**: `Helvetica` — fallback for specific UI contexts -- **System**: `-apple-system, system-ui, Segoe UI, Roboto` — embedded content +When proprietary families cannot be licensed, **Söhne** or **Tiempos Headline** stand in for Domaine Display, and **Geist** or **Inter Tight** can replace ABC Favorit. Inter and Geist Mono are open-source and should be used directly. ### Hierarchy -| Role | Font | Size | Weight | Line Height | Letter Spacing | Notes | -|------|------|------|--------|-------------|----------------|-------| -| Display Hero | domaine | 96px (6.00rem) | 400 | 1.00 (tight) | -0.96px | `"ss01", "ss04", "ss11"` | -| Display Hero Mobile | domaine | 76.8px (4.80rem) | 400 | 1.00 (tight) | -0.768px | Scaled for mobile | -| Section Heading | aBCFavorit | 56px (3.50rem) | 400 | 1.20 (tight) | -2.8px | `"ss01", "ss04", "ss11"` | -| Sub-heading | aBCFavorit | 20px (1.25rem) | 400 | 1.30 (tight) | normal | `"ss01", "ss04", "ss11"` | -| Sub-heading Compact | aBCFavorit | 16px (1.00rem) | 400 | 1.50 | -0.8px | `"ss01", "ss04", "ss11"` | -| Feature Title | inter | 24px (1.50rem) | 500 | 1.50 | normal | Section sub-headings | -| Body Large | inter | 18px (1.13rem) | 400 | 1.50 | normal | Introductions | -| Body | inter | 16px (1.00rem) | 400 | 1.50 | normal | Standard body text | -| Body Semibold | inter | 16px (1.00rem) | 600 | 1.50 | normal | Emphasis, active states | -| Nav Link | aBCFavorit | 14px (0.88rem) | 500 | 1.43 | 0.35px | `"ss01", "ss03", "ss04"` — positive tracking | -| Button / Link | inter | 14px (0.88rem) | 500–600 | 1.43 | normal | Buttons, nav, CTAs | -| Caption | inter | 14px (0.88rem) | 400 | 1.60 (relaxed) | normal | Descriptions | -| Helvetica Caption | Helvetica | 14px (0.88rem) | 400–600 | 1.00–1.71 | normal | UI elements | -| Small | inter | 12px (0.75rem) | 400–500 | 1.33 | normal | Tags, meta, fine print | -| Small Uppercase | inter | 12px (0.75rem) | 500 | 1.33 | normal | `text-transform: uppercase` | -| Small Capitalize | inter | 12px (0.75rem) | 500 | 1.33 | normal | `text-transform: capitalize` | -| Code Body | commitMono | 16px (1.00rem) | 400 | 1.50 | normal | Code blocks | -| Code Small | commitMono | 14px (0.88rem) | 400 | 1.43 | normal | Inline code | -| Code Tiny | commitMono | 12px (0.75rem) | 400 | 1.33 | normal | Small code labels | -| Heading (Helvetica) | Helvetica | 24px (1.50rem) | 400 | 1.40 | normal | Alternate heading context | +| Token | Size | Weight | Line Height | Letter Spacing | Use | +|---|---|---|---|---|---| +| `{typography.display-xxl}` | 96px | 400 | 1.0 | -0.96px | Home hero ("Email for developers"). One per page. | +| `{typography.display-xl}` | 76.8px | 400 | 1.0 | -0.768px | Section openers ("Email reimagined", "Available today"). | +| `{typography.display-lg}` | 56px | 400 | 1.2 | -2.8px | ABC Favorit display sub-titles. | +| `{typography.heading-md}` | 24px | 500 | 1.5 | -0.4px | Card titles, section sub-titles. | +| `{typography.heading-sm}` | 20px | 500 | 1.3 | -0.3px | List headers. | +| `{typography.subtitle}` | 20px | 400 | 1.3 | 0 | Hero subtitles. | +| `{typography.body-lg}` | 18px | 400 | 1.5 | 0 | Marketing prose. | +| `{typography.body-md}` | 16px | 400 | 1.5 | -0.8px | ABC Favorit body. | +| `{typography.body-sm}` | 14px | 400 | 1.43 | 0 | Captions, metadata. | +| `{typography.button-md}` | 14px | 500 | 1.43 | 0 | Default button label. | +| `{typography.button-sm}` | 14px | 500 | 1.43 | 0.35px | Pill labels, inline links. | +| `{typography.caption}` | 12px | 400 | 1.5 | 0 | Footer disclosure, copyright. | +| `{typography.caption-emph}` | 14px | 600 | 1.0 | 0 | Emphatic small caption — Helvetica fallback. | +| `{typography.code-md}` | 13px | 400 | 1.6 | 0 | Code blocks, inline code. | ### Principles -- **Three-font editorial hierarchy**: Domaine Display (serif, hero), ABC Favorit (geometric sans, sections), Inter (readable body). Each font has a strict role — they never cross lanes. -- **Aggressive negative tracking on display**: Domaine at -0.96px, ABC Favorit at -2.8px. The display type feels compressed, urgent, and designed — like a magazine masthead. -- **Positive tracking on nav**: ABC Favorit nav links use +0.35px letter-spacing — the only positive tracking in the system. This creates airy, spaced-out navigation text that contrasts with the compressed headings. -- **OpenType as identity**: The `"ss01"`, `"ss03"`, `"ss04"`, `"ss11"` stylistic sets are enabled on all ABC Favorit and Domaine text, activating alternate glyphs that give Resend's typography its unique character. -- **Commit Mono as design element**: The monospace font isn't hidden in code blocks — it's used prominently for code examples and technical content, treated as a first-class visual element. +- Display sizes always run at `lineHeight: 1.0` with negative letter-spacing — the Domaine Display headlines pack into solid typographic blocks rather than open prose lines. +- Body weight stays at 400 across `{typography.body-lg}` and `{typography.body-md}`. The serif/sans family change carries hierarchy, not weight bumps. +- ABC Favorit always runs with `ss01 / ss04 / ss11` engaged; Inter never carries OpenType features. Code in Geist Mono never carries ligatures. +- Inline links use `{typography.button-sm}` with positive letter-spacing (`0.35px`) and ABC Favorit — the small spacing nudge gives interactive prose its precision. -## 4. Component Stylings +### Note on Font Substitutes + +When Domaine Display is unavailable, clamp `lineHeight` to 1.0 explicitly and apply `font-feature-settings: "ss01", "liga"` on the substitute serif to mimic the alternate glyphs. Söhne or Tiempos Headline will read closest. ABC Favorit substitutes (Geist, Inter Tight) typically default to looser tracking — apply -0.5% letter-spacing on body sizes to compensate. + +## Layout + +### Spacing System +- **Base unit**: 4px, with the working scale on multiples of 4 / 8 / 16. +- **Tokens**: `{spacing.xxs}` 2px · `{spacing.xs}` 4px · `{spacing.sm}` 8px · `{spacing.md}` 12px · `{spacing.lg}` 16px · `{spacing.xl}` 24px · `{spacing.xxl}` 32px · `{spacing.xxxl}` 48px · `{spacing.section}` 96px · `{spacing.band}` 128px. +- Section padding: `{spacing.section}` (96px) vertical between bands; `{spacing.band}` (128px) on the hero stripe and closing footer transition. +- Card internal padding: `{spacing.xxl}` (32px) on `{component.feature-card}`, `{component.pricing-tier}`, and `{component.code-window}`. + +### Grid & Container +- **Max content width** ≈ 1200px on body sections. +- **Feature grid**: 3 columns at desktop, 2 at tablet, 1 at mobile. +- **Pricing**: 3-tier grid centred at desktop; centre tier promotes to `{component.pricing-tier-featured}` (one-step-elevated surface). +- **Code-story splits**: a 2-up split — narrative copy left, `{component.code-window}` right — collapsing to stacked at < 1024px. +- **Email mockup band**: a single white card (640px max width) centred in the dark canvas with generous vertical padding to read like a print magazine inset. + +### Whitespace Philosophy +- Whitespace is editorial and generous — full-bleed sections breathe at 96–128px so Domaine Display headlines have room to register at scale. +- Inside cards, padding stays at 32px so feature copy and code wells have a consistent rhythm with the outer grid. +- Hairline `{colors.hairline}` and `{colors.hairline-strong}` carry the role drop shadows would in a brighter system; the dark canvas suppresses traditional shadow depth entirely. + +## Elevation & Depth + +| Level | Treatment | Use | +|---|---|---| +| 0 — flat | No shadow, no border | Default canvas, full-bleed bands. | +| 1 — surface card | `{colors.surface-card}` (`#0a0a0c`) + 1px `{colors.hairline-strong}` | Feature cards, pricing tiers, form inputs. | +| 2 — elevated | `{colors.surface-elevated}` (`#101012`) + 1px `{colors.hairline-strong}` | Featured pricing tier, ghost button. | +| 3 — code well | `{colors.surface-deep}` (`#06060a`) + 1px `{colors.hairline-strong}` | Code window, terminal shells. | +| 4 — atmospheric glow | Low-opacity radial gradient (`{colors.accent-*-glow}`) anchored at section top | Section openers ("Integrate this weekend", "Email reimagined"). | + +The system has **no traditional drop shadow language**. Every surface either gets a translucent-white hairline border or sits inside an atmospheric glow. The dark canvas absorbs shadow naturally; surfaces register depth via temperature and luminance shifts rather than blur. + +### Decorative Depth +- **Atmospheric section glows** — six accent colours each with a paired glow token (orange, yellow, blue, green, red, plus a deep slate for "everything in your context"). Each section opens with a single radial wash anchored at the top edge of the section, falling off to canvas black within ~600px vertical distance. Never two glows in the same section. +- **Email card insets** — the "Beyond experience" mockup band lifts a single white email card off the black canvas, giving it the only true light-on-dark contrast in the system. The card uses no shadow; the contrast itself is the elevation. +- **Code window traffic lights** — `{component.code-window}` shells include a row of three coloured dots (red `{colors.accent-red}`, yellow `{colors.accent-yellow}`, green `{colors.accent-green}`) at the top — the only place all three semantic colours appear together as solid surfaces. + +## Shapes + +### Border Radius Scale + +| Token | Value | Use | +|---|---|---| +| `{rounded.none}` | 0px | Hero stripe, full-bleed bands, footer. | +| `{rounded.xs}` | 4px | Inline tags inside code wells. | +| `{rounded.sm}` | 6px | Code tabs, mid-size chips. | +| `{rounded.md}` | 8px | Buttons, form inputs. | +| `{rounded.lg}` | 12px | Feature cards, pricing tiers, code wells, email mockups. | +| `{rounded.xl}` | 16px | Larger feature panels. | +| `{rounded.full}` | 9999px | Pills, status dots, contributor avatars. | + +### Photography Geometry +- The system uses almost no photography. Visual interest comes from typography + atmospheric glows + code wells + the white email-card insets. +- When portraits appear (testimonial avatars), they are circular (`{rounded.full}`) at 32px, sitting inline with body copy. +- Email mockup cards run at 4:5 portrait aspect with `{rounded.lg}` corners. + +## Components ### Buttons -**Primary Transparent Pill** -- Background: transparent -- Text: `#f0f0f0` -- Padding: 5px 12px -- Radius: 9999px (full pill) -- Border: `1px solid rgba(214, 235, 253, 0.19)` (frost border) -- Hover: background `rgba(255, 255, 255, 0.28)` (white glass) -- Use: Primary CTA on dark backgrounds +**`button-primary`** — white CTA +- Background `{colors.primary}`, label `{colors.primary-on}`, type `{typography.button-md}`, padding `8px 16px`, `rounded: {rounded.md}`, height 36px. +- The brightest pixel on the canvas. Used for "Get started", "Sign up", "Try Resend". +- Pressed state lives in `button-primary-pressed` (background `{colors.surface-light}`). -**White Solid Pill** -- Background: `#ffffff` -- Text: `#000000` -- Padding: 5px 12px -- Radius: 9999px -- Use: High-contrast CTA ("Get started") +**`button-ghost`** — translucent CTA +- Background `{colors.surface-elevated}`, label `{colors.ink}`, 1px `{colors.hairline-strong}`, type `{typography.button-md}`, `rounded: {rounded.md}`, height 36px. +- Equal-weight secondary action paired with `{component.button-primary}`. -**Ghost Button** -- Background: transparent -- Text: `#f0f0f0` -- Radius: 4px -- No border -- Hover: subtle background tint -- Use: Secondary actions, tab items +**`button-outline`** — outlined CTA +- Background `{colors.canvas}`, label `{colors.ink}`, 1px `{colors.hairline-strong}`, type `{typography.button-md}`, `rounded: {rounded.md}`, height 36px. +- Tertiary action; appears on its own next to inline links. ### Cards & Containers -- Background: transparent or very subtle dark tint -- Border: `1px solid rgba(214, 235, 253, 0.19)` (frost border) -- Radius: 16px (standard cards), 24px (large sections/panels) -- Shadow: `rgba(176, 199, 217, 0.145) 0px 0px 0px 1px` (ring shadow) -- Dark product screenshots and code demos as card content -- No traditional box-shadow elevation + +**`hero-stripe`** — full-bleed hero +- Background `{colors.canvas}`, text `{colors.ink}`, type `{typography.display-xxl}` for the headline, padding `96px 32px`, `rounded: {rounded.none}`. +- Used only on the home page hero band; carries the 96px Domaine Display headline and a single `{component.button-primary}` CTA. No photography, no atmospheric glow inside the hero itself — the glow appears on the section that follows. + +**`feature-card`** — feature highlight card +- Background `{colors.surface-card}`, text `{colors.ink}`, type `{typography.body-md}`, `rounded: {rounded.lg}`, padding `{spacing.xxl}` (32px). +- Used in the home grid: "Despite emails using React", "So beyond editing", etc. No outline by default — relies on canvas black contrast. + +**`feature-card-bordered`** — outlined feature card +- Background `{colors.surface-card}`, text `{colors.ink}`, 1px `{colors.hairline-strong}`, type `{typography.body-md}`, `rounded: {rounded.lg}`, padding `{spacing.xxl}`. +- Used when feature cards sit close together and need explicit separation. + +**`pricing-tier`** — pricing tier card +- Background `{colors.surface-card}`, text `{colors.ink}`, 1px `{colors.hairline-strong}`, type `{typography.body-md}`, `rounded: {rounded.lg}`, padding `{spacing.xxl}` (32px). +- Tier name in `{typography.heading-md}` + price in `{typography.display-lg}` (ABC Favorit, 56px). + +**`pricing-tier-featured`** — recommended tier +- Background `{colors.surface-elevated}`, text `{colors.ink}`, 1px `{colors.hairline-strong}`, type `{typography.body-md}`, `rounded: {rounded.lg}`, padding `{spacing.xxl}`. +- Centre tier elevated by surface luminance, not by colour. + +**`code-window`** — code well +- Background `{colors.surface-deep}`, text `{colors.body}`, type `{typography.code-md}`, 1px `{colors.hairline-strong}`, `rounded: {rounded.lg}`, padding `{spacing.xl}` (24px). +- Includes a 3-dot traffic-light row at top using `{colors.accent-red}` / `{colors.accent-yellow}` / `{colors.accent-green}` for chrome, plus a tab strip below it. + +**`code-tab`** — code language tab +- Background `{colors.surface-card}`, text `{colors.charcoal}`, type `{typography.code-md}`, `rounded: {rounded.sm}`, padding `6px 12px`. +- Active tab bumps text to `{colors.ink}` and adds a subtle `{colors.hairline-strong}` underline. + +**`email-mockup`** — email-card inset +- Background `{colors.surface-card}` (or the rare `#ffffff` when rendered as a light-island inset), text `{colors.ink}` (or `{colors.on-light}` for white insets), type `{typography.body-md}`, `rounded: {rounded.lg}`, padding 0. +- Used in the "Beyond experience" band to demonstrate rendered email output. ### Inputs & Forms -- Text: `#f0f0f0` on dark, `#000000` on light -- Radius: 4px -- Focus: shadow-based ring -- Minimal styling — inherits dark theme + +**`text-input`** — default input +- Background `{colors.surface-card}`, text `{colors.ink}`, type `{typography.body-sm}`, 1px `{colors.hairline-strong}`, `rounded: {rounded.md}`, padding `10px 14px`, height 40px. +- Sign-up and waitlist email fields. Focus state thickens the border to `{colors.ink}` (no separate ring colour). ### Navigation -- Sticky dark header with frost border bottom: `1px solid rgba(214, 235, 253, 0.19)` -- "Resend" wordmark left-aligned -- ABC Favorit 14px weight 500 with +0.35px tracking for nav links -- Pill CTAs right-aligned -- Mobile: hamburger collapse -### Image Treatment -- Product screenshots and code demos dominate content sections -- Dark-themed screenshots on dark background — seamless integration -- Rounded corners: 12px–16px on images -- Full-width sections with subtle gradient overlays +**`nav-bar`** — top nav (desktop) +- Background `{colors.canvas}`, text `{colors.body}`, type `{typography.button-sm}`, height 64px, single hairline `{colors.hairline}` bottom border. +- Left: wordmark logo. Centre: top-level nav ("Features", "Pricing", "Docs", "Customers"). Right: "Sign in" link + `{component.button-primary}`. -### Distinctive Components +**`nav-bar`** (mobile) +- Same height 64px, collapses centre nav into a hamburger icon. Logo stays left, sign-in CTA stays right. -**Tab Navigation** -- Horizontal tabs with subtle selection indicator -- Tab items: 8px radius -- Active state with subtle background differentiation +**`sub-nav-pill`** — pill-style sub-nav +- Pill chips set in a horizontal row above content (e.g. on the customers index), `{component.sub-nav-pill}` styling. -**Code Preview Panels** -- Dark code blocks using Commit Mono -- Frost borders (`rgba(214, 235, 253, 0.19)`) -- Syntax-highlighted with multi-color accent tokens (orange, blue, green, yellow) +### Signature Components -**Multi-color Accent Badges** -- Each product feature has its own accent color from the CSS variable scale -- Badges use the accent color at low opacity (12–42%) for background, full opacity for text +**`badge-pill`** — neutral pill +- Background `{colors.surface-elevated}`, text `{colors.body}`, type `{typography.caption}`, `rounded: {rounded.full}`, padding `4px 10px`. +- Inline tags ("New", "Beta", "v3.0") inside hero copy and customer story headers. -## 5. Layout Principles +**`status-dot`** — status indicator +- Background `{colors.accent-green}`, `rounded: {rounded.full}`, 8px square. +- Inline indicator next to "Status: Operational" in the footer or system status references. -### Spacing System -- Base unit: 8px -- Scale: 1px, 2px, 4px, 5px, 6px, 7px, 8px, 10px, 12px, 16px, 20px, 24px, 30px, 32px, 40px +**`contributor-avatar`** — testimonial avatar +- Background `{colors.surface-card}` placeholder, `rounded: {rounded.full}`, 32×32px. +- Used inline with customer testimonials. -### Grid & Container -- Centered content with generous max-width -- Full-width black sections with contained inner content -- Single-column hero, expanding to feature grids below -- Code preview panels as full-width or contained showcases +**`footer`** — global footer +- Background `{colors.canvas}`, text `{colors.charcoal}`, type `{typography.body-sm}`, `rounded: {rounded.none}`, padding `64px 32px`. +- Multi-column quick-links grid above a single-line copyright row separated by `{colors.divider-soft}`. -### Whitespace Philosophy -- **Cinematic black space**: The black background IS the whitespace. Generous vertical spacing (80px–120px+) between sections creates a scroll-through-darkness experience where each section emerges like a scene. -- **Tight content, vast surrounds**: Text blocks and cards are compact internally, but float in vast dark space — creating isolated "islands" of content. -- **Typography-led rhythm**: The massive display fonts (96px) create their own vertical rhythm — each headline is a visual event that anchors the surrounding space. - -### Border Radius Scale -- Sharp (4px): Buttons (ghost), inputs, small interactive elements -- Subtle (6px): Menu panels, navigation items -- Standard (8px): Tabs, content blocks -- Comfortable (10px): Accent elements -- Card (12px): Clipboard buttons, medium containers -- Large (16px): Feature cards, images, main buttons -- Section (24px): Large panels, section containers -- Pill (9999px): Primary CTAs, tags, badges - -## 6. Depth & Elevation - -| Level | Treatment | Use | -|-------|-----------|-----| -| Flat (Level 0) | No shadow, transparent background | Default — most elements on dark void | -| Ring (Level 1) | `rgba(176, 199, 217, 0.145) 0px 0px 0px 1px` | Shadow-as-border for cards, containers | -| Frost Border (Level 1b) | `1px solid rgba(214, 235, 253, 0.19)` | Explicit borders — buttons, dividers, tabs | -| Subtle (Level 2) | `rgba(0, 0, 0, 0.1) 0px 1px 3px, rgba(0, 0, 0, 0.1) 0px 1px 2px -1px` | Light card elevation | -| Focus (Level 3) | `rgb(0, 0, 0) 0px 0px 0px 8px` | Heavy black focus ring — accessibility | - -**Shadow Philosophy**: Resend barely uses shadows at all. On a pure black background, traditional shadows are invisible — you can't cast a shadow into the void. Instead, Resend creates depth through its signature frost borders (`rgba(214, 235, 253, 0.19)`) — thin, icy blue-tinted lines that catch light against the darkness. This creates a "glass panel floating in space" aesthetic where borders are the primary depth mechanism. - -### Decorative Depth -- Subtle warm gradient glows behind hero content (orange/amber tints) -- Product screenshots create visual depth through their own internal UI -- No gradient backgrounds — depth comes from border luminance and content contrast - -## 7. Do's and Don'ts +## Do's and Don'ts ### Do -- Use pure black (`#000000`) as the page background — the void is the canvas -- Apply frost borders (`rgba(214, 235, 253, 0.19)`) for all structural lines — they're the blue-tinted signature -- Use Domaine Display ONLY for hero headings (96px), ABC Favorit for section headings, Inter for everything else -- Enable OpenType `"ss01"`, `"ss04"`, `"ss11"` on Domaine and ABC Favorit text -- Apply pill radius (9999px) to primary CTAs and tags -- Use the multi-color accent scale (orange/green/blue/yellow/red) with opacity variants for context-specific highlighting -- Keep shadows at ring level (`0px 0px 0px 1px`) — on black, traditional shadows don't work -- Use +0.35px letter-spacing on ABC Favorit nav links — the only positive tracking +- Use `{colors.canvas}` (true black) as the default page background. Every public page lives here. +- Reserve `{component.button-primary}` (white pill) as the only solid bright surface. One per viewport at most. +- Set hero headlines in **Domaine Display** at 76–96px with `lineHeight: 1.0` and `ss01 / ss04 / ss11` features engaged. +- Use **ABC Favorit** for marketing body, **Inter** for UI labels, **Geist Mono** for code. Keep the lanes strict. +- Build elevation from translucent-white hairlines, not drop shadows. +- Use `{colors.accent-*-glow}` tokens as low-opacity radial atmospheric washes — never as solid surfaces. +- Set buttons and inputs to `{rounded.md}` (8px); cards and code wells to `{rounded.lg}` (12px); pills and avatars to `{rounded.full}`. +- Use the white email-mockup inset sparingly — it's the only deliberately-light surface and should feel like a print pull-quote. ### Don't -- Don't lighten the background above `#000000` — the pure black void is non-negotiable -- Don't use neutral gray borders — all borders must have the frost blue tint -- Don't apply Domaine Display to body text — it's a display-only serif -- Don't mix accent colors in the same component — each feature gets one accent color -- Don't use box-shadow for elevation on the dark background — use frost borders instead -- Don't skip the OpenType stylistic sets — they define the typographic character -- Don't use negative letter-spacing on nav links — ABC Favorit nav uses positive +0.35px -- Don't make buttons opaque on dark — transparency with frost border is the pattern +- Don't use a near-black canvas. The brand sits on `#000000`, not `#0a0a0a`. +- Don't apply solid colour to atmospheric accent tokens. `{colors.accent-orange}` is for inline highlights only — its glow form is for backdrops. +- Don't add drop shadows to feature cards or code wells. Translucent white borders carry depth on this canvas. +- Don't bump body weight to 600 for emphasis. Use family change (Inter → ABC Favorit → Domaine Display) instead. +- Don't render code outside `{component.code-window}` — even small inline code uses Geist Mono and a `{colors.surface-card}` background. +- Don't loosen Domaine Display `lineHeight` past 1.0. Tight stacking is structural to the brand. +- Don't introduce a secondary brand accent. White is the brand on black — accents are atmospheric only. +- Don't bring photography front-and-centre. The brand reads as type-and-code, not photography-led. -## 8. Responsive Behavior +## Responsive Behavior ### Breakpoints -| Name | Width | Key Changes | -|------|-------|-------------| -| Mobile Small | <480px | Single column, tight padding, 76.8px hero | -| Mobile | 480–600px | Standard mobile, stacked layout | -| Desktop | >600px | Full layout, 96px hero, expanded sections | -*Note: Resend uses a minimal breakpoint system — only 480px and 600px detected. The design is desktop-first with a clean mobile collapse.* +| Name | Width | Key Changes | +|---|---|---| +| Desktop XL | ≥ 1440px | Full max-width 1200 body, 3-up feature grid, side-by-side code-story splits. | +| Desktop | 1280–1439px | Container shrinks; xl side padding. | +| Tablet Large | 1024–1279px | Feature grid stays 3-up, code-story remains 2-up. | +| Tablet | 768–1023px | Feature grid 2-up, code-story stacks (narrative on top), pricing stacks vertically. | +| Mobile Large | 426–767px | Feature grid 1-up; nav collapses to hamburger; hero `{typography.display-xxl}` clamps to 56px. | +| Mobile | ≤ 425px | All grids 1-up, hero clamps to 44px, section padding `{spacing.section}` collapses to 64px. | ### Touch Targets -- Pill buttons: adequate padding (5px 12px minimum) -- Tab items: 8px radius with comfortable hit areas -- Navigation links spaced with 0.35px tracking for visual separation +- All buttons ship at minimum 36px tall on desktop, scaling to 44px on mobile via padding adjustment. WCAG AAA met on mobile. +- `{component.text-input}` is 40px tall — comfortable but not large. Mobile scales to 48px via padding. +- `{component.sub-nav-pill}` stays at 36px on desktop, 40px on mobile. ### Collapsing Strategy -- Hero: Domaine 96px → 76.8px on mobile -- Navigation: horizontal → hamburger -- Feature sections: side-by-side → stacked -- Code panels: maintain width, horizontal scroll if needed -- Spacing compresses proportionally +- Top-level nav collapses to hamburger at < 1024px; the wordmark and `{component.button-primary}` stay anchored. +- Hero `{typography.display-xxl}` clamps: 96px → 76px → 56px → 44px across the breakpoint ladder. +- Pricing 3-up stacks vertically at < 1024px with the featured tier remaining centre-stacked. +- Code-story splits switch from side-by-side to stacked at < 1024px, code well always second. +- Atmospheric glows scale with section width but maintain the same opacity — they fade naturally at small viewports. ### Image Behavior -- Product screenshots maintain aspect ratio -- Dark screenshots blend seamlessly with dark background at all sizes -- Rounded corners (12px–16px) maintained across breakpoints +- Email mockup cards reflow at 1:1 aspect on mobile to remain readable. +- Atmospheric glows are CSS gradients — no asset cost, no breakpoint variation. +- Customer testimonial avatars stay 32px circular regardless of breakpoint. -## 9. Agent Prompt Guide +## Iteration Guide -### Quick Color Reference -- Background: Void Black (`#000000`) -- Primary text: Near White (`#f0f0f0`) -- Secondary text: Silver (`#a1a4a5`) -- Border: Frost Border (`rgba(214, 235, 253, 0.19)`) -- Orange accent: `#ff801f` -- Green accent: `#11ff99` (at 18% opacity) -- Blue accent: `#3b9eff` -- Focus ring: `rgb(0, 0, 0) 0px 0px 0px 8px` +1. Focus on ONE component at a time. Most surfaces share `{colors.surface-card}` or `{colors.surface-elevated}` with `{rounded.lg}` — only the role-specific tokens (`{colors.primary}`, `{component.code-window}`) shift between variants. +2. Reference component names and tokens directly (`{colors.primary}`, `{component.button-primary-pressed}`, `{rounded.lg}`) — do not paraphrase. +3. Run `npx @google/design.md lint DESIGN.md` after edits; orphaned-tokens warnings will catch unused entries. +4. Add new variants as separate entries (`-pressed`, `-featured`, `-disabled`) — do not bury them in prose. +5. Default body type to `{typography.body-md}`; reach for `{typography.subtitle}` only on hero subtitles. +6. Keep `{colors.primary}` (white) scarce — if more than one solid white surface appears per viewport, ask whether one should drop to `{component.button-ghost}` instead. -### Example Component Prompts -- "Create a hero section on pure black (#000000) background. Headline at 96px Domaine Display weight 400, line-height 1.00, letter-spacing -0.96px, near-white (#f0f0f0) text, OpenType 'ss01 ss04 ss11'. Subtitle at 20px ABC Favorit weight 400, line-height 1.30. Two pill buttons: white solid (#ffffff, 9999px radius) and transparent with frost border (rgba(214,235,253,0.19))." -- "Design a navigation bar: dark background with frost border bottom (1px solid rgba(214,235,253,0.19)). Nav links at 14px ABC Favorit weight 500, letter-spacing +0.35px, OpenType 'ss01 ss03 ss04'. White pill CTA right-aligned." -- "Build a feature card: transparent background, frost border (rgba(214,235,253,0.19)), 16px radius. Title at 56px ABC Favorit weight 400, letter-spacing -2.8px. Body at 16px Inter weight 400, #a1a4a5 text." -- "Create a code block using Commit Mono 16px on dark background. Frost border container (24px radius). Syntax colors: orange (#ff801f), blue (#3b9eff), green (#11ff99), yellow (#ffc53d)." -- "Design an accent badge: background #ff5900 at 22% opacity, text #ffa057, 9999px radius, 12px Inter weight 500." +## Known Gaps -### Iteration Guide -1. Start with pure black — everything floats in the void -2. Frost borders (`rgba(214, 235, 253, 0.19)`) are the universal structural element — not gray, not neutral -3. Three fonts, three roles: Domaine (hero), ABC Favorit (sections), Inter (body) — never cross -4. OpenType stylistic sets are mandatory on display fonts — they define the character -5. Multi-color accents at low opacity (12–42%) for backgrounds, full opacity for text -6. Pill shape (9999px) for CTAs and badges, standard radius (4px–16px) for containers -7. No shadows — use frost borders for depth against the void +- Pressed/active visual states are documented only for `button-primary-pressed`; other components rely on the default focus-ring (browser default) for interactive feedback. +- Logged-in dashboard surfaces (API keys, sending logs, audience management) are out of scope; only the public marketing canvas is documented. +- Email-template editor surfaces (a key product feature) are not extracted — those live behind authentication. +- The atmospheric glow rendering uses CSS radial gradients; exact stops and angles vary per section and are not standardised as tokens — render per section-specific design judgment. diff --git a/design-md/revolut/DESIGN.md b/design-md/revolut/DESIGN.md index 2b71ea3..8e27c55 100644 --- a/design-md/revolut/DESIGN.md +++ b/design-md/revolut/DESIGN.md @@ -1,185 +1,636 @@ -# Design System Inspired by Revolut +--- +version: alpha +name: Revolut +description: | + Revolut's marketing surfaces pair a stark black canvas with the brand's + cobalt-violet (`#494fdf`) and a wide accent palette of deep, fully-saturated + product colours — teal, light-blue, deep pink, light-green, warning orange. + The system reads as fintech-meets-product-brochure: oversized 80px–136px + Aeonik Pro display headlines, generous whitespace, photography-led hero + bands, and full-width product mockups (cards, phones, terminals) shown as + hero objects inside near-black sections. Most surfaces are either black or + off-white; pill-shaped buttons and rounded-12/20px content cards carry the + consumer-financial-app feel without crossing into playful territory. -## 1. Visual Theme & Atmosphere +colors: + primary: "#494fdf" + primary-bright: "#4f55f1" + primary-deep: "#3a40c4" + on-primary: "#ffffff" + ink: "#191c1f" + body: "#1f2226" + charcoal: "#3a3d40" + mute: "#505a63" + ash: "#5c5e60" + stone: "#8d969e" + faint: "#c9c9cd" + on-dark: "#ffffff" + on-dark-mute: "rgba(255,255,255,0.72)" + canvas-light: "#ffffff" + canvas-dark: "#000000" + surface-soft: "#f4f4f4" + surface-card: "#ffffff" + surface-deep: "#0a0a0a" + surface-elevated: "#16181a" + hairline-light: "#e2e2e7" + hairline-dark: "rgba(255,255,255,0.12)" + hairline-strong: "#191c1f" + divider-soft: "rgba(255,255,255,0.06)" + accent-teal: "#00a87e" + accent-blue-link: "#376cd5" + accent-light-blue: "#007bc2" + accent-light-green: "#428619" + accent-green-text: "#006400" + accent-yellow: "#b09000" + accent-warning: "#ec7e00" + accent-pink: "#e61e49" + accent-danger: "#e23b4a" + accent-deep-red: "#8b0000" + accent-brown: "#936d62" + link: "#376cd5" -Revolut's website is fintech confidence distilled into pixels — a design system that communicates "your money is in capable hands" through massive typography, generous whitespace, and a disciplined neutral palette. The visual language is built on Aeonik Pro, a geometric grotesque that creates billboard-scale headlines at 136px with weight 500 and aggressive negative tracking (-2.72px). This isn't subtle branding; it's fintech at stadium scale. +typography: + display-xxl: + fontFamily: Aeonik Pro + fontSize: 136px + fontWeight: 500 + lineHeight: 1.0 + letterSpacing: -2.72px + display-xl: + fontFamily: Aeonik Pro + fontSize: 80px + fontWeight: 500 + lineHeight: 1.0 + letterSpacing: -0.8px + display-lg: + fontFamily: Aeonik Pro + fontSize: 48px + fontWeight: 500 + lineHeight: 1.21 + letterSpacing: -0.48px + display-md: + fontFamily: Aeonik Pro + fontSize: 40px + fontWeight: 500 + lineHeight: 1.2 + letterSpacing: -0.4px + heading-lg: + fontFamily: Aeonik Pro + fontSize: 32px + fontWeight: 500 + lineHeight: 1.19 + letterSpacing: -0.32px + heading-md: + fontFamily: Aeonik Pro + fontSize: 24px + fontWeight: 500 + lineHeight: 1.33 + letterSpacing: 0 + heading-sm: + fontFamily: Aeonik Pro + fontSize: 20px + fontWeight: 500 + lineHeight: 1.4 + letterSpacing: 0 + body-lg: + fontFamily: Inter + fontSize: 18px + fontWeight: 400 + lineHeight: 1.56 + letterSpacing: -0.09px + body-md: + fontFamily: Inter + fontSize: 16px + fontWeight: 400 + lineHeight: 1.5 + letterSpacing: 0.24px + body-md-bold: + fontFamily: Inter + fontSize: 16px + fontWeight: 600 + lineHeight: 1.5 + letterSpacing: 0.16px + body-sm: + fontFamily: Inter + fontSize: 14px + fontWeight: 400 + lineHeight: 1.43 + button-lg: + fontFamily: Aeonik Pro + fontSize: 20px + fontWeight: 500 + lineHeight: 1.4 + button-md: + fontFamily: Inter + fontSize: 16px + fontWeight: 600 + lineHeight: 1.5 + letterSpacing: 0.24px + button-sm: + fontFamily: Inter + fontSize: 14px + fontWeight: 600 + lineHeight: 1.43 + caption: + fontFamily: Inter + fontSize: 13px + fontWeight: 400 + lineHeight: 1.4 + link-emph: + fontFamily: Inter + fontSize: 16px + fontWeight: 700 + lineHeight: 1.5 + letterSpacing: 0.24px -The color system is built on a comprehensive `--rui-*` (Revolut UI) token architecture with semantic naming for every state: danger (`#e23b4a`), warning (`#ec7e00`), teal (`#00a87e`), blue (`#494fdf`), deep-pink (`#e61e49`), and more. But the marketing surface itself is remarkably restrained — near-black (`#191c1f`) and pure white (`#ffffff`) dominate, with the colorful semantic tokens reserved for the product interface, not the marketing page. +rounded: + none: 0px + sm: 8px + md: 12px + lg: 20px + xl: 28px + full: 9999px -What distinguishes Revolut is its pill-everything button system. Every button uses 9999px radius — primary dark (`#191c1f`), secondary light (`#f4f4f4`), outlined (`transparent + 2px solid`), and ghost on dark (`rgba(244,244,244,0.1) + 2px solid`). The padding is generous (14px 32px–34px), creating large, confident touch targets. Combined with Inter for body text at various weights and positive letter-spacing (0.16px–0.24px), the result is a design that feels both premium and accessible — banking for the modern era. +spacing: + xxs: 4px + xs: 6px + sm: 8px + md: 14px + lg: 16px + xl: 24px + xxl: 32px + xxxl: 48px + block: 80px + section: 88px + band: 120px + +components: + button-primary: + backgroundColor: "{colors.canvas-light}" + textColor: "{colors.canvas-dark}" + typography: "{typography.button-md}" + rounded: "{rounded.full}" + padding: 14px 28px + height: 48px + button-primary-pressed: + backgroundColor: "{colors.faint}" + textColor: "{colors.canvas-dark}" + typography: "{typography.button-md}" + rounded: "{rounded.full}" + button-dark: + backgroundColor: "{colors.canvas-dark}" + textColor: "{colors.on-dark}" + typography: "{typography.button-md}" + rounded: "{rounded.full}" + padding: 14px 28px + height: 48px + button-soft: + backgroundColor: "{colors.surface-soft}" + textColor: "{colors.ink}" + typography: "{typography.button-md}" + rounded: "{rounded.full}" + padding: 14px 28px + height: 48px + button-outline-light: + backgroundColor: "{colors.canvas-light}" + textColor: "{colors.ink}" + typography: "{typography.button-md}" + rounded: "{rounded.full}" + padding: 13px 27px + height: 48px + button-outline-dark: + backgroundColor: "{colors.canvas-dark}" + textColor: "{colors.on-dark}" + typography: "{typography.button-md}" + rounded: "{rounded.full}" + padding: 13px 27px + height: 48px + button-pill-sm: + backgroundColor: "{colors.surface-soft}" + textColor: "{colors.ink}" + typography: "{typography.button-sm}" + rounded: "{rounded.full}" + padding: 8px 16px + height: 36px + text-input: + backgroundColor: "{colors.canvas-light}" + textColor: "{colors.ink}" + typography: "{typography.body-md}" + rounded: "{rounded.md}" + padding: 14px 16px + height: 56px + hero-band-dark: + backgroundColor: "{colors.canvas-dark}" + textColor: "{colors.on-dark}" + typography: "{typography.display-xxl}" + rounded: "{rounded.none}" + padding: 88px 24px + hero-band-photo: + backgroundColor: "{colors.canvas-dark}" + textColor: "{colors.on-dark}" + typography: "{typography.display-xl}" + rounded: "{rounded.none}" + padding: 0 + feature-card-light: + backgroundColor: "{colors.canvas-light}" + textColor: "{colors.ink}" + typography: "{typography.body-md}" + rounded: "{rounded.lg}" + padding: 32px + feature-card-dark: + backgroundColor: "{colors.surface-elevated}" + textColor: "{colors.on-dark}" + typography: "{typography.body-md}" + rounded: "{rounded.lg}" + padding: 32px + plan-card: + backgroundColor: "{colors.surface-elevated}" + textColor: "{colors.on-dark}" + typography: "{typography.body-md}" + rounded: "{rounded.lg}" + padding: 32px + plan-card-featured: + backgroundColor: "{colors.primary}" + textColor: "{colors.on-primary}" + typography: "{typography.body-md}" + rounded: "{rounded.lg}" + padding: 32px + product-mockup: + backgroundColor: "{colors.canvas-dark}" + textColor: "{colors.on-dark}" + rounded: "{rounded.xl}" + padding: 48px + download-tile: + backgroundColor: "{colors.surface-soft}" + textColor: "{colors.ink}" + typography: "{typography.body-sm}" + rounded: "{rounded.md}" + padding: 12px 20px + height: 56px + badge-tag: + backgroundColor: "{colors.surface-soft}" + textColor: "{colors.ink}" + typography: "{typography.caption}" + rounded: "{rounded.full}" + padding: 4px 12px + badge-feature: + backgroundColor: "{colors.primary}" + textColor: "{colors.on-primary}" + typography: "{typography.caption}" + rounded: "{rounded.full}" + padding: 4px 12px + nav-bar: + backgroundColor: "{colors.canvas-dark}" + textColor: "{colors.on-dark}" + typography: "{typography.button-md}" + rounded: "{rounded.none}" + height: 64px + sub-nav-pill: + backgroundColor: "{colors.surface-elevated}" + textColor: "{colors.on-dark}" + typography: "{typography.button-sm}" + rounded: "{rounded.full}" + padding: 8px 16px + footer: + backgroundColor: "{colors.canvas-dark}" + textColor: "{colors.on-dark-mute}" + typography: "{typography.body-sm}" + rounded: "{rounded.none}" + padding: 80px 24px +--- + +## Overview + +Revolut's marketing canvas operates in a high-contrast two-mode system: a +**near-black storytelling canvas** (`{colors.canvas-dark}` — `#000000`) +that hosts hero bands, product mockups, and the planning section, alternating +with **white catalogue bands** (`{colors.canvas-light}` — `#ffffff`) that +host comparison tables, FAQ rows, and download tiles. The two modes switch +in full-bleed bands rather than soft transitions; sections slam against each +other to create the magazine-spread rhythm the brand is known for. + +The display typography is **Aeonik Pro at weight 500**, used at sizes from +20px to 136px. The flagship hero ("Banking & Beyond", "Join the 70+ million +using Revolut") sits at 80–136px with `lineHeight: 1.0` and tight negative +letter-spacing. Body type is **Inter** at weight 400 — open-source, +no-nonsense, paired with positive tracking (`0.24px`) on UI labels for +slightly more mechanical precision. + +The brand accent is `{colors.primary}` (`#494fdf`) — a saturated cobalt +violet — but it appears scarcely on marketing surfaces. The actual primary +CTA on the hero is the **white pill on black** ("Choose your subscription"), +and the cobalt violet is reserved for featured plan cards, secondary CTAs in +white sections, and the brand glyph itself. A wide secondary palette of deep +teal, light-blue, deep-pink, light-green, warning orange, and yellow appears +inside product mockups and feature illustrations — never as button surfaces. **Key Characteristics:** -- Aeonik Pro display at 136px weight 500 — billboard-scale fintech headlines -- Near-black (`#191c1f`) + white binary with comprehensive `--rui-*` semantic tokens -- Universal pill buttons (9999px radius) with generous padding (14px 32px) -- Inter for body text with positive letter-spacing (0.16px–0.24px) -- Rich semantic color system: blue, teal, pink, yellow, green, brown, danger, warning -- Zero shadows detected — depth through color contrast only -- Tight display line-heights (1.00) with relaxed body (1.50–1.56) +- Two-mode canvas system — `{colors.canvas-dark}` (true black) for storytelling, `{colors.canvas-light}` (white) for browsing — switched in full-bleed bands. +- Display typography is **Aeonik Pro 500** at sizes 20–136px with tight `lineHeight: 1.0` and large negative letter-spacing on display sizes. +- The actual primary CTA is `{component.button-primary}` — a **white pill with black text**, sitting on the dark canvas as the brightest pixel. Cobalt-violet `{colors.primary}` is reserved for featured plan cards and secondary CTAs. +- Eight saturated accent colours live inside product mockups and illustrations only, never as button surfaces — teal, light-blue, deep-pink, light-green, warning orange, yellow, brown, danger red. +- All buttons are pill-shaped (`{rounded.full}`); content cards use `{rounded.lg}` (20px); inputs and small chips use `{rounded.md}` (12px). +- Photography is product-led — phone mockups, card mockups, terminal mockups — shown full-bleed inside dark sections with no caption overlay. -## 2. Color Palette & Roles +## Colors -### Primary -- **Revolut Dark** (`#191c1f`): Primary dark surface, button background, near-black text -- **Pure White** (`#ffffff`): `--rui-color-action-label`, primary light surface -- **Light Surface** (`#f4f4f4`): Secondary button background, subtle surface +### Brand & Accent +- **Cobalt Violet** (`{colors.primary}` — `#494fdf`): the brand accent. Reserved for featured plan cards (`{component.plan-card-featured}`), the brand wordmark icon, and secondary CTAs in white-canvas regions. +- **Cobalt Bright** (`{colors.primary-bright}` — `#4f55f1`): a one-step-up bright variant used in inline link colour and accent-photo headers. +- **Cobalt Deep** (`{colors.primary-deep}` — `#3a40c4`): the active/pressed state of cobalt elements. +- **On-Primary** (`{colors.on-primary}` — `#ffffff`): label colour on top of `{colors.primary}` surfaces. -### Brand / Interactive -- **Revolut Blue** (`#494fdf`): `--rui-color-blue`, primary brand blue -- **Action Blue** (`#4f55f1`): `--rui-color-action-photo-header-text`, header accent -- **Blue Text** (`#376cd5`): `--website-color-blue-text`, link blue +### Surface +- **Canvas Light** (`{colors.canvas-light}` — `#ffffff`): the white catalogue mode for FAQ, download tiles, comparison tables. +- **Canvas Dark** (`{colors.canvas-dark}` — `#000000`): the storytelling canvas — true black, never near-black. +- **Surface Soft** (`{colors.surface-soft}` — `#f4f4f4`): a subtle off-white used on download tiles, soft buttons, and inset card groups inside white bands. +- **Surface Card** (`{colors.surface-card}` — `#ffffff`): pure white card surface, used for feature cards in white-canvas regions. +- **Surface Deep** (`{colors.surface-deep}` — `#0a0a0a`): a one-step-up dark surface for inset cards inside black-canvas regions. +- **Surface Elevated** (`{colors.surface-elevated}` — `#16181a`): the planning-section card background — slightly luminous, lifts plan cards off the black canvas. +- **Hairline Light** (`{colors.hairline-light}` — `#e2e2e7`): 1px dividers inside white bands. +- **Hairline Dark** (`{colors.hairline-dark}` — `rgba(255,255,255,0.12)`): the corresponding low-contrast divider in dark regions. +- **Hairline Strong** (`{colors.hairline-strong}` — `#191c1f`): structural full-strength dividers and the outline of light cards. + +### Text +- **Ink** (`{colors.ink}` — `#191c1f`): primary text colour. Notably warmer than pure black, paired with the white canvas for body legibility. +- **Body** (`{colors.body}` — `#1f2226`): long-form body where `{colors.ink}` would feel slightly too sharp. +- **Charcoal** (`{colors.charcoal}` — `#3a3d40`): captions, secondary nav. +- **Mute** (`{colors.mute}` — `#505a63`): supporting text. +- **Ash** (`{colors.ash}` — `#5c5e60`): tertiary text, footer copy. +- **Stone** (`{colors.stone}` — `#8d969e`): metadata, subtle captions. +- **Faint** (`{colors.faint}` — `#c9c9cd`): disabled foreground, hairline replacements. +- **On-Dark** (`{colors.on-dark}` — `#ffffff`): primary text on `{colors.canvas-dark}`. +- **On-Dark Mute** (`{colors.on-dark-mute}` — `rgba(255,255,255,0.72)`): secondary text in dark regions. ### Semantic -- **Danger Red** (`#e23b4a`): `--rui-color-danger`, error/destructive -- **Deep Pink** (`#e61e49`): `--rui-color-deep-pink`, critical accent -- **Warning Orange** (`#ec7e00`): `--rui-color-warning`, warning states -- **Yellow** (`#b09000`): `--rui-color-yellow`, attention -- **Teal** (`#00a87e`): `--rui-color-teal`, success/positive -- **Light Green** (`#428619`): `--rui-color-light-green`, secondary success -- **Green Text** (`#006400`): `--website-color-green-text`, green text -- **Light Blue** (`#007bc2`): `--rui-color-light-blue`, informational -- **Brown** (`#936d62`): `--rui-color-brown`, warm neutral accent -- **Red Text** (`#8b0000`): `--website-color-red-text`, dark red text +- **Accent Teal** (`{colors.accent-teal}` — `#00a87e`): used in product mockup illustrations. +- **Accent Light Blue** (`{colors.accent-light-blue}` — `#007bc2`): inline link colour in dark photo headers. +- **Accent Blue Link** (`{colors.accent-blue-link}` — `#376cd5`): default inline link colour on white surfaces. +- **Accent Light Green** (`{colors.accent-light-green}` — `#428619`): success / positive product callouts. +- **Accent Green Text** (`{colors.accent-green-text}` — `#006400`): inline success text. +- **Accent Yellow** (`{colors.accent-yellow}` — `#b09000`): caution / pending state in product mockups. +- **Accent Warning** (`{colors.accent-warning}` — `#ec7e00`): full-saturation orange used in warning illustrations. +- **Accent Pink** (`{colors.accent-pink}` — `#e61e49`): deep pink — used inside product photography and category iconography. +- **Accent Danger** (`{colors.accent-danger}` — `#e23b4a`): destructive / error state. +- **Accent Deep Red** (`{colors.accent-deep-red}` — `#8b0000`): inline error text. +- **Accent Brown** (`{colors.accent-brown}` — `#936d62`): a single warm-neutral used in metals tier card chrome. +- **Link** (`{colors.link}` — `#376cd5`): default inline link colour. Same as `{colors.accent-blue-link}`. -### Neutral Scale -- **Mid Slate** (`#505a63`): Secondary text -- **Cool Gray** (`#8d969e`): Muted text, tertiary -- **Gray Tone** (`#c9c9cd`): `--rui-color-grey-tone-20`, borders/dividers +## Typography -## 3. Typography Rules +### Font Family -### Font Families -- **Display**: `Aeonik Pro` — geometric grotesque, no detected fallbacks -- **Body / UI**: `Inter` — standard system sans -- **Fallback**: `Arial` for specific button contexts +Revolut ships a two-family stack: + +- **Aeonik Pro** — proprietary humanist sans-serif used for all display sizes (20px+) at weight 500. Carries the brand's editorial confidence; tightens dramatically with negative letter-spacing at large sizes. +- **Inter** — open-source workhorse for body, button labels, captions, and metadata. Always at weight 400 or 600, with positive tracking (`0.16–0.24px`) on UI labels. + +When Aeonik Pro cannot be licensed, **Inter Display**, **General Sans**, or **Söhne** are credible substitutes — all share the warm geometric character. Apply -1% letter-spacing on display sizes to match the original tightness. ### Hierarchy -| Role | Font | Size | Weight | Line Height | Letter Spacing | Notes | -|------|------|------|--------|-------------|----------------|-------| -| Display Mega | Aeonik Pro | 136px (8.50rem) | 500 | 1.00 (tight) | -2.72px | Stadium-scale hero | -| Display Hero | Aeonik Pro | 80px (5.00rem) | 500 | 1.00 (tight) | -0.8px | Primary hero | -| Section Heading | Aeonik Pro | 48px (3.00rem) | 500 | 1.21 (tight) | -0.48px | Feature sections | -| Sub-heading | Aeonik Pro | 40px (2.50rem) | 500 | 1.20 (tight) | -0.4px | Sub-sections | -| Card Title | Aeonik Pro | 32px (2.00rem) | 500 | 1.19 (tight) | -0.32px | Card headings | -| Feature Title | Aeonik Pro | 24px (1.50rem) | 400 | 1.33 | normal | Light headings | -| Nav / UI | Aeonik Pro | 20px (1.25rem) | 500 | 1.40 | normal | Navigation, buttons | -| Body Large | Inter | 18px (1.13rem) | 400 | 1.56 | -0.09px | Introductions | -| Body | Inter | 16px (1.00rem) | 400 | 1.50 | 0.24px | Standard reading | -| Body Semibold | Inter | 16px (1.00rem) | 600 | 1.50 | 0.16px | Emphasized body | -| Body Bold Link | Inter | 16px (1.00rem) | 700 | 1.50 | 0.24px | Bold links | +| Token | Size | Weight | Line Height | Letter Spacing | Use | +|---|---|---|---|---|---| +| `{typography.display-xxl}` | 136px | 500 | 1.0 | -2.72px | The flagship hero ("Banking & Beyond"). One per page. | +| `{typography.display-xl}` | 80px | 500 | 1.0 | -0.8px | Section openers ("Join the 70+ million using Revolut"). | +| `{typography.display-lg}` | 48px | 500 | 1.21 | -0.48px | Sub-section titles. | +| `{typography.display-md}` | 40px | 500 | 1.2 | -0.4px | Feature card titles. | +| `{typography.heading-lg}` | 32px | 500 | 1.19 | -0.32px | Plan card titles. | +| `{typography.heading-md}` | 24px | 500 | 1.33 | 0 | Section sub-titles. | +| `{typography.heading-sm}` | 20px | 500 | 1.4 | 0 | List headers, prominent labels. | +| `{typography.body-lg}` | 18px | 400 | 1.56 | -0.09px | Marketing prose. | +| `{typography.body-md}` | 16px | 400 | 1.5 | 0.24px | Default body. | +| `{typography.body-md-bold}` | 16px | 600 | 1.5 | 0.16px | Emphatic body. | +| `{typography.body-sm}` | 14px | 400 | 1.43 | 0 | Captions, metadata. | +| `{typography.button-lg}` | 20px | 500 | 1.4 | 0 | Hero CTAs (Aeonik Pro). | +| `{typography.button-md}` | 16px | 600 | 1.5 | 0.24px | Default button label. | +| `{typography.button-sm}` | 14px | 600 | 1.43 | 0 | Pill chips, sub-nav. | +| `{typography.caption}` | 13px | 400 | 1.4 | 0 | Footer disclosure, regulatory text. | +| `{typography.link-emph}` | 16px | 700 | 1.5 | 0.24px | Emphatic inline link in dark mode. | ### Principles -- **Weight 500 as display default**: Aeonik Pro uses medium (500) for ALL headings — no bold. This creates authority through size and tracking, not weight. -- **Billboard tracking**: -2.72px at 136px is extremely compressed — text designed to be read at a glance, like airport signage. -- **Positive tracking on body**: Inter uses +0.16px to +0.24px, creating airy, well-spaced reading text that contrasts with the compressed headings. +- Display sizes always run at weight 500 with `lineHeight: 1.0` (or 1.19–1.21 below 48px). The negative letter-spacing scales with size — bigger types tighten more. +- Body Inter sits at weight 400 with positive tracking (`0.24px`) — the small spacing nudge makes UI labels feel slightly mechanical, fitting fintech precision. +- Hero CTAs use the Aeonik Pro `{typography.button-lg}` variant; everything below the hero uses the Inter `{typography.button-md}`. +- Inline links inside dark photo regions step up to weight 700 (`{typography.link-emph}`) so they hold contrast against the canvas without using the cobalt accent. -## 4. Component Stylings +### Note on Font Substitutes + +When Aeonik Pro is unavailable, clamp display `lineHeight` to 1.0 explicitly and apply -1% letter-spacing on display sizes. Inter Display, General Sans, or Söhne will read closest to the original. Inter is open-source and should be used directly. + +## Layout + +### Spacing System +- **Base unit**: 4px, with the working scale on multiples of 4 / 8 / 16. +- **Tokens**: `{spacing.xxs}` 4px · `{spacing.xs}` 6px · `{spacing.sm}` 8px · `{spacing.md}` 14px · `{spacing.lg}` 16px · `{spacing.xl}` 24px · `{spacing.xxl}` 32px · `{spacing.xxxl}` 48px · `{spacing.block}` 80px · `{spacing.section}` 88px · `{spacing.band}` 120px. +- Section padding: `{spacing.section}` (88px) vertical between bands; `{spacing.band}` (120px) on the hero band and the closing planning section. +- Card internal padding: `{spacing.xxl}` (32px) on `{component.feature-card-light}`, `{component.plan-card}`, `{component.feature-card-dark}`. + +### Grid & Container +- **Max content width** ≈ 1200px on body sections; hero bands run full-bleed. +- **Plan grid**: 4-up plan cards on the home page, stacking 2-up at tablet and 1-up at small mobile. +- **Feature grid**: 3-up at desktop, 2-up at tablet, 1-up at mobile. +- **Product mockup bands**: a single full-width hero photo of a phone or card mockup, no surrounding chrome — the asset itself is the section. + +### Whitespace Philosophy +- Whitespace is generous and editorial — sections breathe at 88–120px so display headlines have room to register at 80–136px without feeling cramped. +- Inside cards, padding stays at 32px so feature copy and plan tiers have a consistent rhythm. +- Hairline `{colors.hairline-light}` dividers replace shadow on white surfaces; `{colors.hairline-dark}` carries the corresponding role in dark regions. + +## Elevation & Depth + +| Level | Treatment | Use | +|---|---|---| +| 0 — flat | No shadow, no border | Default canvas bands (light or dark), full-bleed hero. | +| 1 — surface card | `{colors.surface-card}` (white) on `{colors.surface-soft}` band | Feature cards inside light bands. | +| 2 — surface elevated dark | `{colors.surface-elevated}` (`#16181a`) on `{colors.canvas-dark}` | Plan cards inside the planning section. | +| 3 — featured surface | `{colors.primary}` on `{colors.canvas-dark}` | Featured plan card (cobalt violet inversion). | +| 4 — product mockup | Full-bleed photo asset | Hero phone / card / terminal mockup bands. | + +The system has **no traditional drop-shadow language**. Surfaces register depth via colour-blocking (light → dark band switches) and surface-luminance shifts (`{colors.canvas-dark}` → `{colors.surface-elevated}`). Photography mockups carry their own depth from the asset itself. + +### Decorative Depth +- **Product mockup hero bands** — the home page features a phone mockup full-bleed against `{colors.canvas-dark}`, with the device's own glow providing the only atmospheric depth. No additional gradients, no shadows. +- **Featured plan card** — the cobalt-violet `{component.plan-card-featured}` sits inside the otherwise dark planning grid as a single saturated colour block, marking the recommended tier visually. +- **Card metals tier** — the brand uses `{colors.accent-brown}` and a deep gradient on metals card mockups to signal premium without resorting to gold-on-black metallic effects. + +## Shapes + +### Border Radius Scale + +| Token | Value | Use | +|---|---|---| +| `{rounded.none}` | 0px | Hero bands, full-bleed sections, footer. | +| `{rounded.sm}` | 8px | Inline tags, small chips. | +| `{rounded.md}` | 12px | Form inputs, download tiles. | +| `{rounded.lg}` | 20px | Feature cards, plan cards. | +| `{rounded.xl}` | 28px | Product mockup containers. | +| `{rounded.full}` | 9999px | Buttons, pills, badges, tabs. | + +### Photography Geometry +- Phone mockups: 9:19.5 (vertical) with `{rounded.xl}` corners on the device chrome. +- Card mockups: 1.586:1 (credit-card aspect) with `{rounded.lg}` corners. +- Terminal/POS mockups: 4:3 with `{rounded.xl}` corners and substantial padding around the device. +- Lifestyle photography (rare): 16:9 with `{rounded.lg}` corners. + +## Components ### Buttons -**Primary Dark Pill** -- Background: `#191c1f` -- Text: `#ffffff` -- Padding: 14px 32px -- Radius: 9999px (full pill) -- Hover: opacity 0.85 -- Focus: `0 0 0 0.125rem` ring +**`button-primary`** — white CTA on dark +- Background `{colors.canvas-light}`, label `{colors.canvas-dark}`, type `{typography.button-md}`, padding `14px 28px`, `rounded: {rounded.full}`, height 48px. +- The brand's primary CTA, used on every dark hero band ("Choose your subscription", "Get started"). +- Pressed state lives in `button-primary-pressed` (background `{colors.faint}`). -**Secondary Light Pill** -- Background: `#f4f4f4` -- Text: `#000000` -- Padding: 14px 34px -- Radius: 9999px -- Hover: opacity 0.85 +**`button-dark`** — dark CTA on light +- Background `{colors.canvas-dark}`, label `{colors.on-dark}`, type `{typography.button-md}`, `rounded: {rounded.full}`. +- The reverse-canvas equivalent of `{component.button-primary}` — used inside white catalogue bands. -**Outlined Pill** -- Background: transparent -- Text: `#191c1f` -- Border: `2px solid #191c1f` -- Padding: 14px 32px -- Radius: 9999px +**`button-soft`** — soft surface CTA +- Background `{colors.surface-soft}`, label `{colors.ink}`, type `{typography.button-md}`, `rounded: {rounded.full}`. +- Tertiary action in white-canvas regions ("Learn more", "View FAQs"). -**Ghost on Dark** -- Background: `rgba(244, 244, 244, 0.1)` -- Text: `#f4f4f4` -- Border: `2px solid #f4f4f4` -- Padding: 14px 32px -- Radius: 9999px +**`button-outline-light`** — outlined CTA on light +- Background `{colors.canvas-light}`, label `{colors.ink}`, 1px solid `{colors.hairline-strong}`, type `{typography.button-md}`, `rounded: {rounded.full}`. +- Secondary action when paired with `{component.button-dark}`. + +**`button-outline-dark`** — outlined CTA on dark +- Background `{colors.canvas-dark}`, label `{colors.on-dark}`, 1px solid `{colors.on-dark}`, type `{typography.button-md}`, `rounded: {rounded.full}`, padding `13px 27px`, height 48px. +- Dark-canvas counterpart of `{component.button-outline-light}`; used inside dark hero bands as a tertiary action when paired with `{component.button-primary}`. + +**`button-pill-sm`** — small pill chip +- Background `{colors.surface-soft}`, label `{colors.ink}`, type `{typography.button-sm}`, `rounded: {rounded.full}`, padding `8px 16px`, height 36px. +- Sub-nav chips, filter pills. ### Cards & Containers -- Radius: 12px (small), 20px (cards) -- No shadows — flat surfaces with color contrast -- Dark and light section alternation + +**`hero-band-dark`** — full-bleed dark hero +- Background `{colors.canvas-dark}`, text `{colors.on-dark}`, type `{typography.display-xxl}` for the title, padding `{spacing.section}` (88px) vertical, `rounded: {rounded.none}`. +- Used only on the home page hero band. + +**`hero-band-photo`** — photo-led hero +- Background `{colors.canvas-dark}` with full-bleed product photography, text `{colors.on-dark}`, type `{typography.display-xl}`, `rounded: {rounded.none}`. +- Used on product pages — phone or card mockup as the full-band canvas. + +**`feature-card-light`** — feature card on white +- Background `{colors.surface-card}`, text `{colors.ink}`, 1px solid `{colors.hairline-light}`, type `{typography.body-md}`, `rounded: {rounded.lg}`, padding `{spacing.xxl}` (32px). +- Used in white catalogue bands for feature comparisons. + +**`feature-card-dark`** — feature card on dark +- Background `{colors.surface-elevated}`, text `{colors.on-dark}`, type `{typography.body-md}`, `rounded: {rounded.lg}`, padding `{spacing.xxl}`. +- Used inside dark storytelling sections. + +**`plan-card`** — subscription plan card +- Background `{colors.surface-elevated}`, text `{colors.on-dark}`, type `{typography.body-md}`, `rounded: {rounded.lg}`, padding `{spacing.xxl}` (32px). +- Plan name in `{typography.heading-lg}` ("Standard", "Plus", "Premium", "Metal", "Ultra"). + +**`plan-card-featured`** — featured plan card +- Background `{colors.primary}`, text `{colors.on-primary}`, type `{typography.body-md}`, `rounded: {rounded.lg}`, padding `{spacing.xxl}`. +- Cobalt-violet inversion of `{component.plan-card}` — used on the recommended tier. + +**`product-mockup`** — full-bleed product asset +- Background `{colors.canvas-dark}`, the asset itself fills the band, `rounded: {rounded.xl}` on the device chrome. +- Phone, card, and terminal mockups — no caption overlay, no surrounding chrome. + +**`download-tile`** — app store download tile +- Background `{colors.surface-soft}`, text `{colors.ink}`, type `{typography.body-sm}`, `rounded: {rounded.md}`, padding `12px 20px`, height 56px. +- App Store + Google Play download buttons, side-by-side. + +### Inputs & Forms + +**`text-input`** — default input +- Background `{colors.canvas-light}`, text `{colors.ink}`, type `{typography.body-md}`, 1px solid `{colors.hairline-light}`, `rounded: {rounded.md}`, padding `14px 16px`, height 56px. +- Generous height for fintech accessibility — comfortably exceeds WCAG AAA touch target. ### Navigation -- Aeonik Pro 20px weight 500 -- Clean header, hamburger toggle at 12px radius -- Pill CTAs right-aligned -## 5. Layout Principles +**`nav-bar`** — top nav (desktop) +- Background `{colors.canvas-dark}`, text `{colors.on-dark}`, type `{typography.button-md}`, height 64px. +- Left: wordmark logo. Centre: top-level nav ("Personal", "Business", "Company"). Right: language switcher + "Log in" + `{component.button-primary}`. -### Spacing System -- Base unit: 8px -- Scale: 4px, 6px, 8px, 14px, 16px, 20px, 24px, 32px, 40px, 48px, 80px, 88px, 120px -- Large section spacing: 80px–120px +**`nav-bar`** (mobile) +- Same height 64px, collapses centre nav into a hamburger icon. Logo stays left, sign-in CTA stays right. -### Border Radius Scale -- Standard (12px): Navigation, small buttons -- Card (20px): Feature cards -- Pill (9999px): All buttons +**`sub-nav-pill`** — sub-nav chip +- Pill chips set in a horizontal row inside dark sections (e.g. "Personal", "Business", "Premium"), `{component.sub-nav-pill}` styling. -## 6. Depth & Elevation +### Signature Components -| Level | Treatment | Use | -|-------|-----------|-----| -| Flat (Level 0) | No shadow | Everything — Revolut uses zero shadows | -| Focus | `0 0 0 0.125rem` ring | Accessibility focus | +**`badge-tag`** — neutral tag +- Background `{colors.surface-soft}`, text `{colors.ink}`, type `{typography.caption}`, `rounded: {rounded.full}`, padding `4px 12px`. +- Inline tags inside feature cards. -**Shadow Philosophy**: Revolut uses ZERO shadows. Depth comes entirely from the dark/light section contrast and the generous whitespace between elements. +**`badge-feature`** — feature highlight badge +- Background `{colors.primary}`, text `{colors.on-primary}`, type `{typography.caption}`, `rounded: {rounded.full}`, padding `4px 12px`. +- "New", "Most popular" badges anchored on plan cards. -## 7. Do's and Don'ts +**`footer`** — global footer +- Background `{colors.canvas-dark}`, text `{colors.on-dark-mute}`, type `{typography.body-sm}`, `rounded: {rounded.none}`, padding `80px 24px`. +- Multi-column quick-links grid above a copyright + regulatory disclosure block separated by `{colors.divider-soft}`. + +## Do's and Don'ts ### Do -- Use Aeonik Pro weight 500 for all display headings -- Apply 9999px radius to all buttons — pill shape is universal -- Use generous button padding (14px 32px) -- Keep the palette to near-black + white for marketing surfaces -- Apply positive letter-spacing on Inter body text +- Switch full bands between `{colors.canvas-dark}` (storytelling) and `{colors.canvas-light}` (catalogue). The two-mode rhythm is core. +- Use `{component.button-primary}` (white pill on dark) as the primary CTA on every dark hero band. It's the brand's loudest action. +- Reserve `{colors.primary}` for the featured plan card and the brand wordmark — the cobalt should feel like a deliberate stamp, not a colour theme. +- Set hero headlines in **Aeonik Pro 500** at 80–136px with `lineHeight: 1.0` and large negative letter-spacing. +- Use **Inter** for body, button labels, captions — never substitute Aeonik Pro for body type. +- Apply `{rounded.full}` to every button and pill; `{rounded.lg}` (20px) to feature and plan cards; `{rounded.md}` (12px) to inputs. +- Show product mockups full-bleed inside dark sections — the asset IS the section. +- Use the wide accent palette (`{colors.accent-teal}`, `{colors.accent-pink}`, `{colors.accent-light-green}`, etc.) inside product illustrations and iconography only. ### Don't -- Don't use shadows — Revolut is flat by design -- Don't use bold (700) for Aeonik Pro headings — 500 is the weight -- Don't use small buttons — the generous padding is intentional -- Don't apply semantic colors to marketing surfaces — they're for the product +- Don't use accent colours (`{colors.accent-teal}`, `{colors.accent-pink}`, etc.) as button surfaces. They live inside illustrations only. +- Don't use a near-black canvas. The brand is `#000000`, not `#0a0a0a`. +- Don't pair white text with cobalt violet inside body content — `{colors.primary}` is for the featured plan card surface, not large prose. +- Don't add drop shadows on cards. Elevation is canvas + surface-luminance shifts. +- Don't introduce a secondary brand colour. Cobalt violet is the only brand stamp. +- Don't loosen Aeonik Pro `lineHeight` past 1.0 on display sizes. Tight stacking is structural. +- Don't bump body Inter to weight 500. Use 400 (default) or 600 (emphatic) — never the in-between. +- Don't pair `{colors.canvas-dark}` with another dark surface beyond `{colors.surface-elevated}`. The surface ladder has only two dark steps. -## 8. Responsive Behavior +## Responsive Behavior ### Breakpoints + | Name | Width | Key Changes | -|------|-------|-------------| -| Mobile Small | <400px | Compact, single column | -| Mobile | 400–720px | Standard mobile | -| Tablet | 720–1024px | 2-column layouts | -| Desktop | 1024–1280px | Standard desktop | -| Large | 1280–1920px | Full layout | +|---|---|---| +| Desktop XL | ≥ 1440px | 4-up plan grid, full-bleed product mockup bands, max content 1200. | +| Desktop | 1280–1439px | Container shrinks; xl side padding. | +| Tablet Large | 1024–1279px | Plan grid 4-up; feature grid 3-up. | +| Tablet | 768–1023px | Plan grid 2-up; feature grid 2-up. | +| Mobile Large | 426–767px | Plan grid 1-up; feature grid 1-up; nav collapses to hamburger; hero `display-xxl` clamps to 64px. | +| Mobile | ≤ 425px | All grids 1-up; hero clamps to 48px; section padding `{spacing.section}` collapses to 64px. | -## 9. Agent Prompt Guide +### Touch Targets +- All buttons ship at minimum 48px tall — comfortably exceeds WCAG AAA (44px). Default `{component.button-primary}` is 48px. +- `{component.text-input}` is 56px tall — fintech-grade accessibility. +- `{component.button-pill-sm}` (36px) is bumped to 44px on mobile via padding adjustment. -### Quick Color Reference -- Dark: Revolut Dark (`#191c1f`) -- Light: White (`#ffffff`) -- Surface: Light (`#f4f4f4`) -- Blue: Revolut Blue (`#494fdf`) -- Danger: Red (`#e23b4a`) -- Success: Teal (`#00a87e`) +### Collapsing Strategy +- Top-level nav collapses to hamburger at < 1024px; the wordmark and `{component.button-primary}` stay anchored. +- Hero `{typography.display-xxl}` clamps: 136px → 80px → 64px → 48px across the breakpoint ladder. +- Plan grid steps from 4-up to 2-up at < 1024px to 1-up at < 768px. +- Product mockup bands maintain full-bleed at every breakpoint; the asset crops inward rather than letterboxing. +- Sub-nav pills convert from a wrap row to a horizontal scroll-rail at < 768px. -### Example Component Prompts -- "Create a hero: white background. Headline at 136px Aeonik Pro weight 500, line-height 1.00, letter-spacing -2.72px, #191c1f text. Dark pill CTA (#191c1f, 9999px, 14px 32px). Outlined pill secondary (transparent, 2px solid #191c1f)." -- "Build a pill button: #191c1f background, white text, 9999px radius, 14px 32px padding, 20px Aeonik Pro weight 500. Hover: opacity 0.85." +### Image Behavior +- Phone and card mockups are served at 1.5× and 2× DPR; below 768px the system swaps to a smaller hero crop. +- Product photography retains its own atmospheric lighting at every breakpoint — no responsive variant assets. -### Iteration Guide -1. Aeonik Pro 500 for headings — never bold -2. All buttons are pills (9999px) with generous padding -3. Zero shadows — flat is the Revolut identity -4. Near-black + white for marketing, semantic colors for product +## Iteration Guide + +1. Focus on ONE component at a time. Most surfaces share the `{colors.canvas-dark}` / `{colors.canvas-light}` pair with `{rounded.full}` for buttons and `{rounded.lg}` for cards. +2. Reference component names and tokens directly (`{colors.primary}`, `{component.plan-card-featured}`, `{rounded.lg}`) — do not paraphrase. +3. Run `npx @google/design.md lint DESIGN.md` after edits; orphaned-tokens warnings will catch unused entries. +4. Add new variants as separate entries (`-pressed`, `-featured`, `-disabled`) — do not bury them in prose. +5. Default body type to `{typography.body-md}` (Inter 400 with positive tracking); reach for `{typography.body-md-bold}` only on emphasis. +6. Keep `{colors.primary}` scarce — if more than one cobalt-violet element appears per viewport, ask whether one should drop to `{component.plan-card}` (`{colors.surface-elevated}`) instead. + +## Known Gaps + +- Pressed/active visual states are documented for `button-primary-pressed` only; other components rely on focus-ring (browser default) for interactive feedback. +- Logged-in app surfaces (transactions, transfers, account settings) are out of scope — only the public marketing canvas is documented. +- The wide accent palette (`{colors.accent-teal}` through `{colors.accent-brown}`) is captured from the extracted token set, but exact usage inside product illustrations varies per market and product line; document per-illustration rather than as system buttons. +- Mobile-app screenshot art direction (phone bezels, status bars) is product-photography territory and not standardised as design tokens.