---
name: Biome
tagline: 'A white-canvas Rust toolchain page where one deep azure blue does all the work.'
updated_at: 2026-05-29T00:00:00.000Z
published_at: 2026-05-28T23:12:12.523Z
author: webdesignhot
source_url: https://biomejs.dev
spec: webdesignhot/0.1
quality: curated
featured: false
categories: [dev-tools]
tags: [light, minimal, sans, developer, toolchain, swiss, blue]
preview_swatch: ['#ffffff', '#0065da', '#17181c']
related: []
description: 'Biome''s site is the cleanest formatter-and-linter page in the JavaScript world — a pure white `#ffffff` canvas, cool-gray `#353841` body type, near-black `#17181c` headings, and a single deep azure `#0065da` that carries every primary action. Where dev tools reach for gradients and dark mode, Biome reaches for restraint: one accent blue, a tight cool-neutral gray ramp, system-sans set at 600 for headings, and a near-zero radius (4.8px on the "Get started" CTA) that reads as engineered rather than soft. It is Rust-grade precision rendered as Swiss-minimal web design — the discipline of the codebase made visible in the chrome.'

# Canonical 8-role aliases (bg / text / brand / border / accent / muted / surface / danger).
# Maps role names to this entry's actual token names so role-aware
# downstream tools resolve `theme.background` → entry's `bg`, etc.
# Auto-generated by scripts/add-aliases.mjs — do not edit manually;
# regenerate after changing color token names.
aliases:
  background: bg
  foreground: text
  primary: brand
  primary-foreground: on-brand
  accent: accent
  muted: text-muted
  border: border
  ring: brand
colors:
  # — Primary —
  bg: '#ffffff'                  # pure-white canvas, the default page ground
  bg-soft: '#f7f8fa'             # faint cool-gray section band for alternation
  bg-strong: '#eef0f3'           # darker cool-gray for active/pressed surfaces
  surface: '#ffffff'             # card surface, identical to canvas, separated by border
  surface-soft: '#fbfcfd'        # barely-off-white for nested panels
  text: '#353841'                # cool-gray body, the workhorse reading color
  text-strong: '#17181c'         # near-black headings, h1 register
  text-muted: '#6b7280'          # captions, metadata, secondary copy
  text-faint: '#9ca3af'          # tertiary, helper labels, disabled hints
  # — Brand & Accents —
  brand: '#0065da'               # signature Biome azure, every primary CTA
  brand-strong: '#0052b3'        # pressed/hover-down azure
  brand-soft: '#e6f0fc'          # pale azure wash for callouts and highlights
  brand-faint: '#f2f7fe'         # palest azure tint, decorative
  accent: '#0065da'              # accent collapses onto brand — one-color discipline
  accent-soft: '#e6f0fc'         # azure wash, same as brand-soft
  # — Interactive —
  link: '#0065da'                # links pick up the brand azure
  link-hover: '#0052b3'          # darker azure on hover
  selected: '#e6f0fc'            # selected-row / active-nav tint
  disabled-bg: '#eef0f3'         # disabled control surface
  disabled-text: '#9ca3af'       # disabled label
  # — Neutrals & Borders —
  border: '#e4e7ec'              # default hairline border on white
  border-strong: '#d0d5dd'       # emphasized divider, input borders
  border-subtle: '#f0f1f4'       # near-invisible internal rule
  divider: '#e4e7ec'             # table and list dividers
  # — Inverse / Dark Surfaces —
  inverse-bg: '#17181c'          # dark code-block / footer background
  inverse-text: '#e4e7ec'        # light cool-gray text on dark
  inverse-text-muted: '#9ca3af'  # muted comment color on dark
  # — Shadow tints (neutral, cool) —
  shadow-ambient: 'rgba(16, 24, 40, 0.04)'  # faint cool ambient shadow
  shadow-standard: 'rgba(16, 24, 40, 0.08)' # standard card shadow
  shadow-brand: 'rgba(0, 101, 218, 0.18)'   # azure-tinted focus halo
  # — Semantic —
  success-bg: '#ecfdf3'
  success-text: '#027a48'
  success-border: '#abefc6'
  warning-bg: '#fffaeb'
  warning-text: '#b54708'
  warning-border: '#fedf89'
  danger-bg: '#fef3f2'
  danger-text: '#b42318'
  danger-border: '#fecdca'
  info-bg: '#e6f0fc'
  info-text: '#0052b3'
  info-border: '#b3d4f5'
  on-brand: '#ffffff'            # white text ON the azure — the standard inversion
  on-inverse: '#e4e7ec'          # light text on the dark inverse surface

typography:
  display:
    family: 'Inter, -apple-system, system-ui, "Segoe UI", Roboto, sans-serif'
    weights: [500, 600, 700]
    opentype-features: ['cv05', 'ss01']
  body:
    family: 'Inter, -apple-system, system-ui, "Segoe UI", Roboto, sans-serif'
    weights: [400, 500, 600]
    opentype-features: ['cv05']
  mono:
    family: '"JetBrains Mono", ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace'
    weights: [400, 500, 700]
    opentype-features: ['zero']
  scale:
    display-hero:    { size: 80, weight: 700, lineHeight: 1.0,  tracking: '-0.03em',  family: display }
    display-lg:      { size: 56, weight: 700, lineHeight: 1.05, tracking: '-0.02em',  family: display }
    h1:              { size: 64, weight: 600, lineHeight: 1.05, tracking: '-0.02em',  family: display }
    h2:              { size: 40, weight: 600, lineHeight: 1.15, tracking: '-0.015em', family: display }
    h3:              { size: 32, weight: 600, lineHeight: 1.2,  tracking: '-0.01em',  family: display }
    h4:              { size: 24, weight: 600, lineHeight: 1.25, tracking: '-0.005em', family: display }
    h5:              { size: 20, weight: 600, lineHeight: 1.3,  tracking: '0',        family: display }
    eyebrow:         { size: 13, weight: 600, lineHeight: 1.4,  tracking: '0.06em',   family: body, transform: 'uppercase' }
    body-lg:         { size: 18, weight: 400, lineHeight: 1.6,  tracking: '0',        family: body }
    body:            { size: 16, weight: 400, lineHeight: 1.6,  tracking: '0',        family: body }
    body-sm:         { size: 14, weight: 400, lineHeight: 1.55, tracking: '0',        family: body }
    label:           { size: 13, weight: 500, lineHeight: 1.4,  tracking: '0',        family: body }
    caption:         { size: 12, weight: 500, lineHeight: 1.45, tracking: '0.02em',   family: body }
    micro:           { size: 11, weight: 600, lineHeight: 1.4,  tracking: '0.04em',   family: body, transform: 'uppercase' }
    code:            { size: 14, weight: 400, lineHeight: 1.6,  tracking: '0',        family: mono, opentype: 'zero' }
    code-sm:         { size: 12, weight: 400, lineHeight: 1.55, tracking: '0',        family: mono, opentype: 'zero' }

radius:
  micro: 2
  sm: 4
  md: 5
  lg: 8
  xl: 12
  xxl: 16
  card: 12
  pill: 9999

spacing:
  base: 4
  scale: [0, 4, 8, 12, 16, 24, 32, 48, 64, 96, 128]

layout:
  page-width: 1280
  prose-width: 720
  header-height: 64
  gutter: 24
  section-padding: 96
  grid: 12

components:
  button-primary:
    bg: '#0065da'
    color: '#ffffff'
    radius: 5
    weight: 600
    padding: '10px 16px'
    font: body
    hover: 'bg #0052b3'
  button-secondary:
    bg: '#ffffff'
    color: '#353841'
    border: '1px solid #d0d5dd'
    radius: 5
    weight: 600
    padding: '10px 16px'
    hover: 'bg #f7f8fa'
  button-ghost:
    bg: 'transparent'
    color: '#353841'
    radius: 5
    weight: 500
    padding: '10px 16px'
    hover: 'bg #f7f8fa'
  button-link:
    bg: 'transparent'
    color: '#0065da'
    underline: 'on hover'
    weight: 500
  card:
    bg: '#ffffff'
    border: '1px solid #e4e7ec'
    radius: 12
    padding: '24px'
    shadow: 'rgba(16, 24, 40, 0.04) 0 1px 2px'
  card-callout:
    bg: '#e6f0fc'
    border: '1px solid #b3d4f5'
    radius: 12
    padding: '20px'
  badge:
    bg: '#e6f0fc'
    color: '#0052b3'
    radius: 9999
    padding: '2px 10px'
    weight: 600
    font: body
  input:
    bg: '#ffffff'
    color: '#353841'
    border: '1px solid #d0d5dd'
    radius: 8
    padding: '8px 12px'
    focus-ring: '0 0 0 3px rgba(0, 101, 218, 0.18)'
  nav:
    bg: '#ffffffcc'
    backdrop-blur: 8
    border-bottom: '1px solid #e4e7ec'
    height: 64
  search:
    bg: '#ffffff'
    color: '#353841'
    border: '1px solid #d0d5dd'
    radius: 8
    padding: '8px 12px'
    hint: '⌘K'
  code-block:
    bg: '#17181c'
    color: '#e4e7ec'
    radius: 12
    padding: '20px 24px'
    font: mono

motion:
  ease-standard: 'cubic-bezier(0.4, 0, 0.2, 1)'
  ease-emphasized: 'cubic-bezier(0.2, 0, 0, 1)'
  duration-fast: 150
  duration-standard: 240
  duration-slow: 320
  duration-page: 400
  reduced-motion: 'respects prefers-reduced-motion: reduce — transforms collapse to opacity-only fades.'

breakpoints:
  mobile: 640
  tablet: 1024
  desktop: 1280
  wide: 1536

shadows:
  none: 'none'
  ambient: 'rgba(16, 24, 40, 0.04) 0 1px 2px'
  standard: 'rgba(16, 24, 40, 0.08) 0 4px 12px'
  elevated: 'rgba(16, 24, 40, 0.10) 0 12px 24px -8px'
  brand-ring: '0 0 0 3px rgba(0, 101, 218, 0.18)'

accessibility:
  contrast-text-on-bg: 9.7                 # AAA (#353841 on #ffffff)
  contrast-heading-on-bg: 16.4             # AAA (#17181c on #ffffff)
  contrast-on-brand: 4.6                   # AA at body sizes (#ffffff on #0065da)
  contrast-muted-on-bg: 4.8                # AA (#6b7280 on #ffffff)
  contrast-link-on-bg: 5.1                 # AA (#0065da on #ffffff)
  focus-ring: '3px solid rgba(0, 101, 218, 0.18)'
  focus-offset: '2px'
  reduced-motion-honored: true
  min-touch-target: 44

dark-mode:
  strategy: 'data-theme attribute toggle'
  bg: '#17181c'
  surface: '#1f2025'
  text: '#c8cbd4'
  text-strong: '#f3f4f6'
  brand: '#4d97f0'
  border: '#2a2c33'
  note: 'Theme toggle detected on production (data-theme attribute). Dark canvas is near-black cool gray; brand azure lightens to ~#4d97f0 to hold contrast on dark.'

lineage:
  summary: |
    Biome's homepage is a study in subtraction. The canvas is pure
    white `#ffffff`, the body is a cool gray `#353841`, headings drop
    to a near-black `#17181c`, and a single deep azure `#0065da`
    carries every primary action — the "Get started" CTA, links,
    active states, focus rings. There is no second accent. There is no
    gradient. There is no dark-by-default hero. The radius is almost
    nothing (the CTA samples at 4.8px, inputs at 8px), which reads as
    engineered rather than rounded-friendly. Type is set in a clean
    grotesk sans (Inter, falling back to the system stack) at 600 for
    headings — confident but never heavy. The whole page behaves like
    the tool it sells: a Rust formatter and linter whose entire value
    proposition is removing noise and enforcing one consistent style.
    Where Bun leans warm-retro and Vercel leans dark-gradient, Biome
    leans Swiss-minimal — a white grid, one functional accent, and the
    discipline to stop there. The restraint is the brand.
  influences:
    - name: International Typographic Style (Swiss design)
      role: White ground, grid discipline, one functional accent color, sans-serif rigor.
      url: https://en.wikipedia.org/wiki/International_Typographic_Style
    - name: Stripe
      role: Cool-neutral gray ramp, single saturated brand accent, restrained product-doc layout.
      url: https://stripe.com
    - name: Rust language brand
      role: Engineering-first minimalism and the toolchain-precision ethos Biome inherits.
      url: https://www.rust-lang.org
    - name: Inter typeface (Rasmus Andersson)
      role: Neutral grotesk sans optimized for UI, the display and body voice.
      url: https://rsms.me/inter
    - name: Tailwind CSS palette
      role: The cool-gray neutral steps and semantic color conventions the system echoes.
      url: https://tailwindcss.com
---

## 1. Visual Theme & Atmosphere

Biome's homepage is what happens when a Rust toolchain designs its own
marketing page: it removes everything that does not earn its place.
The canvas is pure white `#ffffff`. The body copy is a cool gray
`#353841` — not black, slightly desaturated, easy on the eyes across a
long docs page. Headings drop to a near-black `#17181c` at a confident
600 weight, and a single deep azure `#0065da` carries every action on
the page. That is the entire palette doing the heavy lifting: white,
two grays, one blue. There is no gradient, no second accent, no
dark-by-default hero theatrics. The page sells a formatter and a
linter, and it looks like one.

The atmosphere is **Swiss-minimal engineering**. Where Vercel leans
dark-gradient drama and Bun leans warm-retro bakery, Biome leans the
International Typographic Style: a white grid, generous whitespace, a
clean grotesk sans, and exactly one functional accent. The blue is not
decorative — it is a signal. It means "this is the thing to click."
The "Get started" CTA is a solid azure rectangle with white text and a
near-zero corner radius (sampled at 4.8px), which reads as *machined*
rather than soft. Nothing about the page is trying to be friendly;
it is trying to be correct.

Depth is almost entirely flat. Cards are white-on-white separated by a
single `#e4e7ec` hairline border, lifted at most by a 4% cool-tinted
ambient shadow. The page does not stack elevation the way a Material
surface does; it relies on borders and whitespace to organize content.
The only genuinely dark surface is the code block (`#17181c` with light
gray text) — fitting for a product whose output is code, where the
terminal/editor register is the natural home for a dark panel.

The voice of the type is restrained confidence. Headings are 600
weight — heavy enough to anchor the page, light enough to avoid
shouting. The hero h1 runs 64px at -0.02em tracking, tight and
modern. Body sits at 16px with a relaxed 1.6 line height for long-form
docs readability. The system stack (Inter, falling back to
`-apple-system`) is deliberately neutral; the typeface is not the
brand, the discipline is.

The net impression is **precision made visible**. Biome's whole pitch
is "one tool, one config, one consistent style — fast, in Rust." The
homepage is the visual proof of that claim: one accent, one neutral
ramp, one weight for headings, near-zero ornament. The design is the
product demo.

**Key Characteristics**

- Pure white canvas (`#ffffff`) — no warmth, no off-white, no tint
- Single azure accent (`#0065da`) — carries every CTA, link, and active state
- Cool-gray body (`#353841`) with near-black headings (`#17181c`)
- Near-zero radius (CTA ~5px, inputs 8px) — engineered, not rounded-friendly
- One-color discipline — no second accent, no gradients anywhere
- Flat depth — hairline borders and whitespace over stacked shadows
- Clean grotesk sans at 600 for headings — confident, never heavy
- Dark code block (`#17181c`) — the only dark surface, the product's home turf
- Swiss-grid layout — white ground, generous whitespace, functional color
- White-on-azure inversion — the standard, not a signature flip

## 2. Color Palette & Roles

### Primary

- **bg** (`#ffffff`) [→ `--background`]: pure-white canvas, every page-level ground
- **text** (`#353841`) [→ `--text`]: cool-gray body copy, the workhorse reading color
- **text-strong** (`#17181c`) [→ `--heading`]: near-black headings, h1 and section openers
- **brand** (`#0065da`) [→ `--accent`]: signature azure, every primary CTA, link, and focus state
- **on-brand** (`#ffffff`) [→ `--accent-fg`]: white text on the azure — the standard inversion

### Brand & Accent

- **brand-strong** (`#0052b3`): pressed/hover-down azure for solid buttons and active links
- **brand-soft** (`#e6f0fc`): pale azure wash for callouts, badges, selected rows
- **brand-faint** (`#f2f7fe`): palest azure tint, rare decorative fill
- **accent** (`#0065da`): accent collapses onto brand — Biome runs a strict one-color system
- **accent-soft** (`#e6f0fc`): the same azure wash, used for highlight surfaces

### Interactive

- **link** (`#0065da`): inline links pick up the brand azure, underlined or color-only by context
- **link-hover** (`#0052b3`): darker azure on hover
- **selected** (`#e6f0fc`): active-nav and selected-row tint
- **disabled-bg** (`#eef0f3`): disabled control surface
- **disabled-text** (`#9ca3af`): disabled label and helper text

### Neutral Scale

- **text-strong** (`#17181c`): near-black, headings only
- **text** (`#353841`): cool gray, body default
- **text-muted** (`#6b7280`): captions, metadata, secondary copy
- **text-faint** (`#9ca3af`): tertiary labels, deemphasized hints
- **bg-strong** (`#eef0f3`): darker cool-gray for active/pressed surfaces

### Surface & Borders

- **bg-soft** (`#f7f8fa`): faint cool-gray band for section alternation
- **surface** (`#ffffff`): card surface, identical to canvas — separated by border, not fill
- **surface-soft** (`#fbfcfd`): barely-off-white for nested panels
- **border** (`#e4e7ec`): default hairline on white, the primary separator
- **border-strong** (`#d0d5dd`): emphasized dividers, input and button borders
- **border-subtle** (`#f0f1f4`): near-invisible internal rule
- **divider** (`#e4e7ec`): table and list dividers

### Inverse / Dark Surfaces

- **inverse-bg** (`#17181c`): dark code-block and footer ground — the only dark surface
- **inverse-text** (`#e4e7ec`): light cool-gray text on dark
- **inverse-text-muted** (`#9ca3af`): muted comment color in code blocks

### Shadow Colors

Shadows are cool-tinted (`rgba(16, 24, 40, …)`), low-alpha, and used
sparingly. Biome is a **near-flat depth** brand: separation comes from
hairline borders and whitespace, not stacked elevation. When a shadow
appears it is a 4–8% cool ambient at 1–12px blur — enough to lift a
card off the canvas, never enough to dramatize it.

### Semantic

- **success-bg** (`#ecfdf3`) / **success-text** (`#027a48`) / **success-border** (`#abefc6`)
- **warning-bg** (`#fffaeb`) / **warning-text** (`#b54708`) / **warning-border** (`#fedf89`)
- **danger-bg** (`#fef3f2`) / **danger-text** (`#b42318`) / **danger-border** (`#fecdca`)
- **info-bg** (`#e6f0fc`) / **info-text** (`#0052b3`) / **info-border** (`#b3d4f5`) — info reuses the brand azure, keeping the chromatic family closed

## 3. Typography Rules

### Font Family

- **Display & Body**: `Inter`, falling back to `-apple-system`, `system-ui`, `"Segoe UI"`, `Roboto`, `sans-serif`. Biome uses one neutral grotesk for both display and body — the production audit rendered the `-apple-system` fallback, which is by design: the system stack and Inter are nearly interchangeable at these weights, and the brand voice is the discipline, not the face.
- **Mono**: `"JetBrains Mono"`, falling back to `ui-monospace`, `SFMono-Regular`, `"SF Mono"`, `Menlo`, `Consolas`, `monospace` — code surfaces and inline `code`
- **OpenType features used**: `cv05` (Inter's single-story lowercase `l` for clarity), `ss01` (alternate stylistic set on display), `zero` (slashed zero in mono for code legibility)

### Hierarchy

| Role | Font | Size | Weight | Line Height | Letter Spacing | OT Features | Notes |
| --- | --- | --- | --- | --- | --- | --- | --- |
| display-hero | Inter | 80 | 700 | 1.0 | -0.03em | ss01 | Largest marketing hero; one per page |
| display-lg | Inter | 56 | 700 | 1.05 | -0.02em | — | Marketing sub-hero |
| h1 | Inter | 64 | 600 | 1.05 | -0.02em | — | Page title (live-sampled at 64/600) |
| h2 | Inter | 40 | 600 | 1.15 | -0.015em | — | Section headers |
| h3 | Inter | 32 | 600 | 1.2 | -0.01em | — | Sub-section headers |
| h4 | Inter | 24 | 600 | 1.25 | -0.005em | — | Feature/card titles |
| h5 | Inter | 20 | 600 | 1.3 | 0 | — | Sidebar and small headers |
| eyebrow | Inter | 13 | 600 | 1.4 | 0.06em | uppercase | Section labels above h2 |
| body-lg | Inter | 18 | 400 | 1.6 | 0 | — | Hero subhead, lead paragraphs |
| body | Inter | 16 | 400 | 1.6 | 0 | — | Default body (live-sampled at 16/400) |
| body-sm | Inter | 14 | 400 | 1.55 | 0 | — | Secondary body, sidebars |
| label | Inter | 13 | 500 | 1.4 | 0 | — | Form labels, table headers |
| caption | Inter | 12 | 500 | 1.45 | 0.02em | — | Metadata, footnotes |
| micro | Inter | 11 | 600 | 1.4 | 0.04em | uppercase | Tags, smallest UI labels |
| code | JetBrains Mono | 14 | 400 | 1.6 | 0 | zero | Code blocks default |
| code-sm | JetBrains Mono | 12 | 400 | 1.55 | 0 | zero | Inline code, footnote code |

### Principles

1. **Headings at 600, never 700 in body chrome.** The live hero h1 samples at 64px/600 — confident but not heavy. The 700 weights are reserved for oversized marketing display only. Reaching for 700 in section headers makes the page read as louder than the brand intends.
2. **One family does everything.** Display and body share the same grotesk sans. There is no secondary display face, no serif, no decorative cut. The discipline mirrors the single-accent color system.
3. **Negative tracking on headings, neutral on body.** Headings tighten (`-0.02em` to `-0.03em`); body sits at `0`. Never positive-track display copy — it breaks the modern-grotesk register.
4. **Generous body line height for docs.** Body runs at 1.6 line height — Biome is a documentation-heavy site, and the relaxed leading keeps long-form reading comfortable.
5. **Slashed zero in mono.** OpenType `zero` is enabled on all mono surfaces; in code samples the slashed zero disambiguates `0` from `O`, which matters in a developer-tool context.
6. **System stack is intentional, not lazy.** The fallback to `-apple-system`/`system-ui` is deliberate: Inter and the system grotesk are near-identical at these weights, so the page loads fast and stays neutral. The typeface is not the brand.
7. **Eyebrow → heading → body cadence.** Sections open with an uppercase eyebrow (13px, 600, +0.06em), then a heading, then body. This three-step rhythm carries the long-form layout.

## 4. Component Stylings

### Buttons

**Primary (solid azure)**: `#0065da` background, `#ffffff` white text, ~5px radius (sampled at 4.8px on the "Get started" CTA), weight 600, padding `10px 16px`. Hover deepens to `#0052b3`. This is the dominant CTA — "Get started", "Install", "Read the docs."

**Secondary (outline)**: `#ffffff` background, `#353841` text, 1px solid `#d0d5dd` border, ~5px radius, weight 600, padding `10px 16px`. Hover fills to `#f7f8fa`. Used for the lower-priority action sitting beside the primary CTA.

**Ghost**: transparent background, `#353841` text, no border, ~5px radius, weight 500, padding `10px 16px`. Hover fills to `#f7f8fa`. Used for tertiary actions and nav items.

**Link button**: transparent background, `#0065da` azure text, weight 500, underline on hover. Used inline in copy and as docs-nav links.

### Cards

**Default**: `#ffffff` background on the white canvas, 1px solid `#e4e7ec` hairline border, 12px radius, padding `24px`, and at most a 4% cool ambient shadow (`rgba(16, 24, 40, 0.04) 0 1px 2px`). The border does the separation work — white-on-white with a hairline rather than a fill change.

**Callout**: `#e6f0fc` azure-soft background, 1px solid `#b3d4f5` border, 12px radius, padding `20px`. Used for tips, notes, and "good to know" blocks in docs.

### Badges & Tags

`#e6f0fc` azure-soft background, `#0052b3` text, 9999 (pill) radius, padding `2px 10px`, weight 600. Used for version numbers, "new" markers, and rule-category tags. Neutral-gray variants (`#eef0f3` bg, `#6b7280` text) cover non-emphasized labels.

### Inputs & Search

`#ffffff` background, `#353841` text, 1px solid `#d0d5dd` border, 8px radius, padding `8px 12px`. Focus ring: `0 0 0 3px rgba(0, 101, 218, 0.18)` — the azure halo. Placeholder: `#9ca3af`. The site's prominent search field carries a `⌘K` hint and the same border/radius treatment — search is a first-class control, befitting a docs-heavy product.

### Navigation

`#ffffffcc` (80% white) background with `8px` backdrop-blur, 1px solid `#e4e7ec` bottom border, 64px height. Wordmark left, primary nav center, search + "Get started" CTA right. Sticks to top; the translucent white wash keeps the canvas continuous as content scrolls underneath.

### Code blocks

`#17181c` near-black background, `#e4e7ec` light-gray text, 12px radius, padding `20px 24px`, JetBrains Mono at 14px. The only dark surface on the page — and the natural one, since Biome's output is formatted/linted code. Syntax highlighting is restrained and cool-toned; the azure brand color appears on keywords or accents to tie the panel back to the system.

## 5. Layout Principles

### Spacing System

Base unit is **4px**. Scale: `0, 4, 8, 12, 16, 24, 32, 48, 64, 96, 128`. Biome is a **mid-density** brand — airier than Linear, tighter than Stripe Press. 96px section padding gives the marketing room to breathe, while docs pages tighten internal spacing to 16/24px for information density.

### Grid & Container

Container caps at **1280px** with **24px gutters**. Prose width: 720px — comfortable for long-form documentation. The grid is 12-column and held strictly: this is a Swiss-grid brand, so columns align, gutters are consistent, and content rarely bleeds the grid. Docs pages run a classic three-zone layout (left nav rail, center prose, right on-this-page TOC).

### Whitespace Philosophy

Whitespace is structural, not decorative. The white canvas means negative space *is* the page — there is no texture, no tint, no fill to hide behind. Sections are separated by padding and the occasional `#f7f8fa` band rather than by color shifts. The discipline: if a divider can be removed and whitespace can do the job, remove the divider.

### Section Cadence

The white canvas runs continuously; alternation happens via the faint `#f7f8fa` section band and card surfaces. Brand-band moments (a full azure section) are rare — used once per page at most, typically the final CTA, so the accent never loses its signal value.

## 6. Shapes & Radius Scale

| Tier | Value | Use |
| --- | --- | --- |
| Micro | 2px | Inline tags, micro-accents |
| Standard | 4px | Small chips, the floor of the scale |
| Comfortable | 5px | Primary/secondary buttons (CTA samples at ~4.8px) |
| Relaxed | 8px | Inputs, search field, secondary surfaces |
| Large | 12px | Cards, code blocks, callouts |
| Featured | 16px | Hero panels, oversized containers |
| Pill | 9999px | Badges, status pills, avatar chrome |

The near-zero radius on buttons is the brand's most telling shape
decision: at ~5px the corners read as *machined* rather than friendly.
Where consumer products round to 8–12px for approachability, Biome
keeps buttons crisp — a small but deliberate engineering signal.
Larger surfaces (cards, code blocks) relax to 12px so they don't feel
sharp at scale, but the interactive controls stay tight.

## 7. Depth & Elevation

| Level | Treatment | Use |
| --- | --- | --- |
| 0 — Flat | No shadow, no border | Page canvas, full-bleed sections |
| 1 — Hairline | 1px solid `#e4e7ec`, no shadow | Default cards, dividers, panels |
| 2 — Lifted | 1px border + `rgba(16, 24, 40, 0.04) 0 1px 2px` | Subtle card lift on white |
| 3 — Hovered | 1px border + `rgba(16, 24, 40, 0.08) 0 4px 12px` | Card hover, dropdown panels |
| 4 — Elevated | `rgba(16, 24, 40, 0.10) 0 12px 24px -8px` | Modals, command palette, popovers |
| 5 — Brand ring | `0 0 0 3px rgba(0, 101, 218, 0.18)` | Focus state on interactive controls |

**Shadow Philosophy** — Biome is a **near-flat depth** brand. Most
separation comes from the `#e4e7ec` hairline border and from
whitespace, not from stacked shadows. When a shadow is used it is
cool-tinted (`rgba(16, 24, 40, …)`, never warm or neutral-black),
low-alpha (4–10%), and soft. The page philosophy is closer to a
Swiss print layout than a Material surface — elevation is implied by
border and space, not by simulated light. The one place depth turns
literal is the focus ring, where the azure halo signals interactivity
clearly.

## 8. Interaction & Motion

### Easing

- **Standard**: `cubic-bezier(0.4, 0, 0.2, 1)` — default for color, opacity, and small transforms
- **Emphasized**: `cubic-bezier(0.2, 0, 0, 1)` — entrance animations, dropdown reveals
- **Linear** is avoided except for spinners

### Durations

- **Fast (150ms)**: hover color shifts, link underline, focus-ring fade-in
- **Standard (240ms)**: button hover, card border emphasis, dropdown open
- **Slow (320ms)**: section reveals, modal entrance, command-palette open
- **Page (400ms)**: route transitions, docs page swaps

### Per-component Micro-states

- **Button hover**: solid buttons deepen from `#0065da` to `#0052b3` over 150ms; outline/ghost fill to `#f7f8fa`. No vertical lift — Biome keeps interactions flat.
- **Card hover**: ambient shadow grows from 4% to 8% over 240ms; border may darken from `#e4e7ec` to `#d0d5dd`.
- **Link hover**: color deepens to `#0052b3` and underline appears over 150ms.
- **Focus**: 3px azure ring (`rgba(0, 101, 218, 0.18)`) fades in over 150ms with 2px offset on all interactive controls.
- **Command palette / search**: opens with a 240ms emphasized ease, backdrop fades in; `⌘K` invokes it from anywhere.

### Page Transitions

Docs navigation uses a fast cross-fade (~240–400ms); the white canvas
stays constant and only the prose column swaps. The left nav and TOC
persist across page loads to maintain orientation in the docs.

### Reduced Motion

`prefers-reduced-motion: reduce` is honored. Transforms collapse to
opacity-only fades, the command-palette entrance becomes instant, and
section reveals disable. Focus rings remain fully visible —
accessibility is never traded away for motion reduction.

## 9. Accessibility & A11y

### Contrast Pairs

- **Body text on canvas** (`#353841` on `#ffffff`): **9.7:1** — AAA at all sizes
- **Heading on canvas** (`#17181c` on `#ffffff`): **16.4:1** — AAA
- **White on brand azure** (`#ffffff` on `#0065da`): **4.6:1** — AA at body sizes (the on-brand pairing; use ≥16px or bold for small text)
- **Muted text on canvas** (`#6b7280` on `#ffffff`): **4.8:1** — AA
- **Link on canvas** (`#0065da` on `#ffffff`): **5.1:1** — AA
- **Brand text on brand-soft** (`#0052b3` on `#e6f0fc`): **6.9:1** — AA+
- **Light text on dark code** (`#e4e7ec` on `#17181c`): **14.1:1** — AAA

### Focus Indicators

3px solid `rgba(0, 101, 218, 0.18)` azure ring with 2px offset, applied
consistently across buttons, links, inputs, and the command palette.
Never rely on the default browser outline alone — always render the
brand azure ring. Because the azure is the only accent, the focus state
is unmistakable.

### ARIA Patterns

- **Combobox (search / command palette)**: `role="combobox"` with `aria-expanded`, `aria-controls`, `aria-activedescendant`; results in a `listbox`
- **Dialog**: `role="dialog"` with `aria-modal="true"`, focus trap on open, focus restore on close
- **Tooltip**: `role="tooltip"` with `aria-describedby` on the trigger; show on hover/focus, hide on blur/Escape
- **Tabs** (docs examples, config formats): `role="tablist"` / `role="tab"` / `role="tabpanel"` with arrow-key navigation
- **Code-copy button**: `aria-label="Copy code"` with `aria-live="polite"` for the confirmation toast

### Keyboard Navigation

- `⌘K` / `Ctrl+K` opens the command palette / search from anywhere
- Tab order follows visual order; left nav, prose links, and TOC are all reachable
- Skip-to-content link present at top of every page (visually hidden until focused)
- Code blocks: Tab into the copy button, Enter to copy, focus returns to the block
- Modals and the palette: Tab cycles within, Escape closes, focus restores to the invoker

### Screen Reader Hints

- Decorative SVGs and icons carry `aria-hidden="true"`
- Visible button labels are not duplicated by `aria-label` (avoid double-announcement)
- Code blocks expose language via `aria-label` (e.g., "JavaScript code")
- The `⌘K` hint in the search field is decorative; the field has a real accessible label

### Reduced Motion

See §8. All non-essential animation collapses to opacity fades or is disabled.

## 10. Responsive Behavior

### Breakpoints

| Name | Width | Notes |
| --- | --- | --- |
| Mobile | < 640px | Single column; nav collapses to hamburger; TOC hidden |
| Tablet | 640–1024px | Two-zone docs (nav drawer + prose); 8-column grid |
| Desktop | 1024–1280px | Full three-zone docs; 12-column grid |
| Wide | 1280–1536px | Container caps at 1280px; side gutters expand |
| Ultra-wide | > 1536px | Container holds at 1280px; additional negative space |

### Touch Targets

Minimum 44×44px on mobile. Buttons that read `10px 16px` on desktop
expand their hit area on mobile; nav and palette items get ≥44px
height. The `⌘K` field becomes a tappable search icon on small screens.

### Collapsing Strategy

- **Hero**: side-by-side becomes stacked single-column on mobile; hero h1 drops one tier (display → h1)
- **Feature grid**: 3-up desktop → 2-up tablet → 1-up mobile
- **Docs layout**: three-zone (nav / prose / TOC) → prose-only with the nav behind a drawer and the TOC hidden below tablet
- **Navigation**: horizontal nav becomes a hamburger drawer below 1024px
- **Code blocks**: gain horizontal scroll on mobile rather than wrapping, preserving line integrity

### Image Behavior

Logos and icons are SVG and scale losslessly. Marketing illustrations
use `srcset` for 1x/2x. Diagrams and screenshots respect the prose
width (720px) and never bleed the column.

### Container Queries

Used in feature and config cards: when a card drops below ~480px wide,
its internal layout collapses from horizontal (icon left, text right)
to a vertical stack regardless of viewport width.

## 11. Content & Voice

### Tone

**Precise, technical, and quietly confident.** Biome is a Rust
toolchain that formats and lints; the copy is matter-of-fact and
benefit-led ("Format, lint, and more in a fraction of a second"). There
is no hype, no exclamation, no emoji. The voice trusts the reader to be
a developer and respects their time — short sentences, concrete claims,
numbers where they help.

### Microcopy Patterns

- **Button verbs**: concrete and product-named ("Get started", "Install Biome", "Try the playground") over vague ("Learn more")
- **Error messages**: plain-language problem first, then the fix — mirroring Biome's own diagnostic style, which is famous for being readable
- **Success confirmations**: brief and unpunctuated. "Copied." not "Copied!"
- **Performance claims**: stated as facts with numbers ("97% Prettier compatibility", "in a fraction of a second") rather than adjectives

### Empty States

What they say: "No issues found. Your code is clean." (Direct, affirming, no fluff.)

What they don't say: "Great job! Looks like everything is perfect here — keep up the awesome work!" (Too effusive; Biome's voice is calm, not cheerleading.)

### CTA Verb Conventions

- **Primary action**: "Get started" (the live hero CTA) or "Install Biome"
- **Secondary action**: "Read the docs" / "Try the playground" / "View on GitHub"
- **Footer CTA**: a single azure "Get started" — the one full-accent moment per page
- **Not used**: "Sign up free", "Learn more", "Discover" — too generic for a toolchain

## 12. Dark Mode & Theming

**Dark mode is offered** — the production site carries a theme toggle
(detected via a `data-theme` attribute), so unlike a light-only brand,
Biome ships both modes.

In dark mode the canvas inverts to a near-black cool gray (`#17181c`,
the same value used for the light-mode code-block ground and headings),
surfaces lift to `~#1f2025`, body text becomes a light cool gray
(`~#c8cbd4`) with `~#f3f4f6` headings, and borders drop to a dim
`~#2a2c33`. The brand azure lightens from `#0065da` to roughly
`#4d97f0` so it holds contrast against the dark canvas — the same
signal, retuned for legibility.

The system is genuinely token-driven: because the light theme already
runs on a strict three-gray-plus-one-blue palette, the dark theme is a
clean inversion of the same roles rather than a separate visual
language. The discipline carries across both modes — one accent, one
neutral ramp, near-flat depth — which is exactly what you'd expect from
a tool that exists to enforce consistency.

## 13. Lineage & Influences

Biome's design language descends directly from the **International
Typographic Style** — the Swiss school of white grounds, strict grids,
sans-serif rigor, and a single functional accent color. Strip the
content away and the page is a Swiss poster: white field, aligned
columns, one blue. From **Stripe**, Biome borrows the cool-neutral gray
ramp and the convention of a single saturated brand accent carrying all
the action in an otherwise restrained product-doc layout. From the
**Rust language brand** — Biome is written in Rust and inherits its
toolchain — comes the engineering-first minimalism and the cultural
allergy to ornament for ornament's sake.

What Biome rejects is as defining as what it adopts: no dark-by-default
hero (Vercel, Turborepo), no gradient drama, no warm-retro palette
(Bun), no second accent competing with the first. The near-zero button
radius is a quiet rejection of the friendly-rounded consumer aesthetic;
the type stays on a neutral grotesk (Inter / system) rather than a
branded display face. The restraint is not an absence of design — it is
the design. Biome looks like its own diagnostics: clean, legible, and
unwilling to waste your attention.

**Named influences**

- **International Typographic Style (Swiss design)** — white ground, grid discipline, one functional accent, sans rigor. https://en.wikipedia.org/wiki/International_Typographic_Style
- **Stripe** — cool-neutral gray ramp, single saturated brand accent, restrained doc layout. https://stripe.com
- **Rust language brand** — engineering-first minimalism and the toolchain-precision ethos. https://www.rust-lang.org
- **Inter (Rasmus Andersson)** — neutral grotesk sans optimized for UI, the display and body voice. https://rsms.me/inter
- **Tailwind CSS palette** — the cool-gray neutral steps and semantic color conventions. https://tailwindcss.com

## 14. Do's and Don'ts

### Do's

- **Do** keep the canvas pure white `#ffffff`. No off-white, no warm tint — the cleanliness is the brand.
- **Do** let the single azure `#0065da` carry every primary action. One accent, no exceptions.
- **Do** use near-zero radius on buttons (~5px). The machined-corner detail is a deliberate engineering signal.
- **Do** set headings at 600 weight, not 700. Confident, not loud — the live hero h1 is 64px/600.
- **Do** separate cards with the `#e4e7ec` hairline border rather than a fill change. White-on-white plus a hairline.
- **Do** keep body type cool-gray `#353841`, not pure black — it reads easier across long docs.
- **Do** reserve the dark surface for code blocks (`#17181c`). That's the product's natural home for dark.
- **Do** use white text on the azure (`#ffffff` on `#0065da`) — the standard inversion.
- **Do** lean on whitespace and the strict 12-column grid for structure. Swiss discipline.
- **Do** enable the `⌘K` command palette / search — it's a first-class control on a docs-heavy site.
- **Do** keep semantic colors muted and reuse the azure for info states to hold the one-color discipline.
- **Do** retune the azure lighter (`~#4d97f0`) in dark mode so it stays legible.

### Don'ts

- **Don't** introduce a second accent color. Biome runs on one blue; a competing hue dilutes the signal.
- **Don't** add gradients — on the brand azure, on backgrounds, anywhere. The palette is flat by design.
- **Don't** round buttons to 8–12px. The near-zero radius is intentional; rounding makes it read as a consumer SaaS.
- **Don't** use pure black `#000000` for headings. Headings are `#17181c`; body is `#353841`. The cool grays are the brand.
- **Don't** stack heavy drop shadows. Depth is near-flat — hairline borders and whitespace, not Material elevation.
- **Don't** set headings at 700 in normal section chrome — reserve 700 for oversized marketing display only.
- **Don't** warm up the palette. There is no warm gray, no cream — Biome is cool-neutral throughout.
- **Don't** make the whole page dark by default. Biome offers dark mode via toggle, but light is the canonical first impression.
- **Don't** swap in a branded display typeface. The neutral grotesk (Inter / system) is the point — the discipline is the voice.
- **Don't** let the azure cover large areas. It's an accent on CTAs, links, and active states — full-azure sections appear once per page at most.

## 15. Agent Prompt Guide

### Quick Color Reference

```
bg: #ffffff
bg-soft: #f7f8fa
surface: #ffffff
text: #353841
text-strong: #17181c
text-muted: #6b7280
brand: #0065da
brand-strong: #0052b3
brand-soft: #e6f0fc
border: #e4e7ec
inverse-bg: #17181c
link: #0065da
```

### Example Component Prompts

1. *"Create a hero on a pure white `#ffffff` canvas: a 64px Inter 600 headline at -0.02em tracking in near-black `#17181c`, an 18px cool-gray `#353841` subhead, and a solid azure `#0065da` 'Get started' button with white text, weight 600, ~5px radius, padding 10px 16px. No gradient, no shadow drama, strict left-aligned grid."*
2. *"Design a feature card: `#ffffff` background on the white canvas, 1px solid `#e4e7ec` hairline border, 12px radius, 24px padding, a 24px Inter 600 title in `#17181c`, and 16px `#353841` body. On hover, raise a 8% cool ambient shadow over 240ms — no vertical lift."*
3. *"Build a dark code block: `#17181c` background, light-gray `#e4e7ec` text, JetBrains Mono at 14px, 12px radius, 20px 24px padding, slashed-zero OpenType enabled, azure `#0065da` keyword highlighting, and a copy button with `aria-label='Copy code'`."*
4. *"Create an outline secondary button: `#ffffff` background, `#353841` text, 1px solid `#d0d5dd` border, ~5px radius, weight 600, padding 10px 16px. Hover fills to `#f7f8fa`. Place it beside the azure primary CTA."*
5. *"Render the navigation: 64px height, `#ffffffcc` background with 8px backdrop-blur, 1px `#e4e7ec` bottom border, wordmark left, nav center, a `⌘K` search field plus a 'Get started' azure CTA on the right. No shadow."*
6. *"Add an info callout: `#e6f0fc` azure-soft background, 1px solid `#b3d4f5` border, 12px radius, 20px padding, a 20px Inter 600 title and 16px body in `#0052b3`. Use for docs tips and notes."*

### Iteration Guide

1. **Lock the white canvas first.** If the background is off-white or tinted, it isn't Biome. Pure `#ffffff`, then iterate on everything else.
2. **Count the accents.** There should be exactly one — the azure `#0065da`. If a second saturated color appears, remove it; the one-color discipline is the brand.
3. **Check the button radius.** If buttons are rounded to 8–12px, tighten them to ~5px. The near-zero corner is the engineering signal that separates Biome from consumer SaaS.
4. **Verify heading weight.** Headings should be 600, not 700. If the page feels loud, drop the weight — the live hero h1 is 64px/600.
5. **Confirm the grays are cool.** Body is `#353841`, headings `#17181c`, muted `#6b7280` — all cool-neutral. If any gray reads warm, recolor it.
6. **Audit depth.** Cards should separate via the `#e4e7ec` hairline border, not heavy shadows. If you see Material-style elevation, flatten it.
7. **Keep the azure scarce.** It belongs on CTAs, links, focus rings, and active states — roughly 5% of the visual area. Full-azure sections appear once per page at most.
8. **Add the dark theme as a clean inversion.** If you ship dark mode, invert the same role tokens (canvas → `#17181c`, azure → `~#4d97f0`) rather than inventing a new palette — the system is token-driven both ways.
