# Bun — Marketing site Design Spec

> Source: bun.sh (live DOM, computed styles + published CSS custom properties), 2026-07-19.
> Coverage: home / runtime landing. No logged-in surface exists.
> Note 1: the site is now **DARK**, not the cream/white canvas the category hint suggested — that redesign postdates the older brand.
> Note 2: reference screenshots could not be captured — the page repeatedly timed out script injection (heavy benchmark animations). All values below are read from computed styles, which is the authoritative source anyway; layout description is correspondingly conservative.

## 1. Visual Theme & Atmosphere

Bun runs a dark, benchmark-forward developer page: a near-black `#0d0e11`/`#14151a` ground with `#282a36` panels, and hot pink `#f472b6` as the single brand colour, carried onto the primary button and the section headings (`#fbcfe8`). Type is deliberately un-designed — **`system-ui` throughout, no webfont** — but pushed to weight **800** at 53px, which gives the page a blunt, performance-poster energy rather than a crafted one. The signature structural device is the **tab-topped panel**: platform and tool switchers are rendered as `6px 6px 0 0` / `7px 7px 0 0` tabs sitting flush on the panel below them, like a physical file divider. Buttons carry a `0 -2px 0 inset` keycap bevel. Colour beyond pink appears only in benchmark bars and framework gradients. Feels: fast, blunt, benchmark-driven, developer-native.

## 2. Color Palette & Roles

### Core

| Token | Hex | Role / usage |
|---|---|---|
| `--black` | `#0b0a08` | Deepest ground |
| `--gray-950` | `#0d0e11` | Page canvas |
| `--gray-900` | `#14151a` | Body / panel ground, text on pink |
| `--gray-800` | `#282a36` | Panel fill (most common surface) |
| `--dark-gray` | `#282a35` | Alternate panel |
| `--gray-700` | `#3b3f4b` | Raised chrome, inactive tab |
| `--gray-600` | `#4f5666` | Border / muted fill |
| `--gray-500` | `#6b7280` | Muted, inactive tab border |
| `--gray-400` | `#9ca3af` | Caption text |
| `--gray-300` | `#d1d5db` | Body copy |
| `--gray-200` | `#e5e7eb` | Emphasised body |
| `--gray-100` | `#f3f4f6` | Near-white |
| `--gray-50` | `#f9fafb` | Headline white |

### Brand &amp; accents

| Token | Hex | Role / usage |
|---|---|---|
| `pink` | `#f472b6` | THE brand colour — primary button, active tab, section headings |
| `pink-tint` | `#fbcfe8` | Large section headings |
| `--blue` | `#00a6e1` | Published accent |
| `--orange` | `#f89b4b` | Published accent |
| `--orange-light` | `#d4d3d2` | Published (reads as a light neutral) |
| `--link-hover-color` | `#a03939` | Link hover |
| `--dark-border` | `rgba(200,200,25,0.2)` | Published border token |

### Published purple ramp

`50 #f3e8f9` &middot; `100 #e1d0f2` &middot; `200 #cfc8ec` &middot; `300 #bdb1e5` &middot; `400 #ab99de` &middot; `500 #9982d8` &middot; `600 #876ad1` &middot; `700 #7553cb` &middot; `800 #633bc4` &middot; `900 #5122bd`

### Benchmark / status tints (translucent bar fills)

`green rgba(35,195,95,.20)` (`#23c35f`) &middot; `red rgba(240,70,70,.20)` (`#f04646`) &middot; `blue rgba(59,128,245,.10)` (`#3b80f5`) &middot; `yellow rgba(235,180,10,.20)` (`#ebb40a`) &middot; `pink rgba(235,70,155,.20)` (`#eb469b`) &middot; `white rgba(255,255,255,.06)`

**Rules.** Pink `#f472b6` is the only brand colour in chrome. The green/red/yellow/blue tints exist solely as benchmark-bar fills at low alpha — never as UI status colours. The published purple ramp and the blue/orange accents did not appear in the captured chrome.

## 3. Typography Rules

- UI + display: `system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, …` (published as `--system-font`) — **no webfont for text**
- Code: `"JetBrains Mono", "Fira Code", "Hack", "Source Code Pro", "SF Mono", "Inconsolata", monospace` (published as `--monospace-font`)

| Role | Size/Line | Weight | Tracking |
|---|---|---|---|
| Hero h1 | 53.33/53.33 | **800** | normal (`#f9fafb`) |
| Section h2 | 48/48 | **800** | normal (`#fbcfe8`) |
| Sub-headline h2 | 24/33 | 500 | normal (`#d1d5db`) |
| Card h3 | 24/32 | 700 | normal (`#ffffff`) |
| Lead paragraph | 20.8/31.2 | 400 | normal (`#d1d5db`) |
| Emphasis paragraph | 18.67/28 | 600 | normal (`#e5e7eb`) |
| Install line | 20/28 | 600 | normal (`#ffffff`) |
| Caption | 16/24 | 400 | normal (`#9ca3af`) |
| Button label | 16-18 | 400-500 | normal |

Patterns: line-height is set to **exactly 1.0 on both display roles** (53.33/53.33 and 48/48), which is what makes the headlines feel packed. Weight swings hard — 800 for display, 400 for body — with no intermediate display weight. Tracking is `normal` everywhere. Published `--line-height: 1.4` governs body text. Sentence case throughout.

## 4. Component Stylings

**Nav** — published `--navbar-height: 60px`.

**Buttons**:

| Variant | Fill | Text | Border | Radius | Height | Padding | Type |
|---|---|---|---|---|---|---|---|
| Primary | `#f472b6` | `#14151a` | `rgba(255,255,255,.16)` | 8px | 44px | 8px 16px | 18/500 |
| Pill / Ask AI | `#282a35` | `#ffffff` | `rgba(255,255,255,.16)` | 9999px | 48px | 12px 18px | 16/500 |
| Outline (brand) | transparent | `#ffffff` | 1px `#8043c8` | 8px | 50px | 12px 24px | 16/700 |
| Outline (neutral) | transparent | `#d1d5db` | 2px `#9ca3af` | 5px | 61px | 12px 36px | 18/600 |

The primary button's bevel: `rgb(40,45,85) 0px -2px 0px 0px inset, rgb(81,87,125) 0px 0px 1px 1px inset, rgba(3,4,9,0.3) 0px 2px 2px 0px` — an inset bottom edge plus a 1px inner ring, reading as a physical key.

**Signature tab-topped panel** — switchers rendered as tabs with only their top corners rounded, sitting flush on the panel beneath:

| Tab | Fill | Text | Border | Radius | Height |
|---|---|---|---|---|---|
| Platform active | `#f472b6` | `#000000` | none | `6px 6px 0 0` | 42px |
| Platform inactive | `#3b3f4b` | `#e5e7eb` | 2px `#6b7280` | `6px 6px 0 0` | 42px |
| Tool active | `#282a36` | `#f472b6` | `rgba(59,63,75,.75)` | `7px 7px 0 0` | 59px |
| Tool inactive | transparent | `#d1d5db` | `rgba(59,63,75,.75)` | `7px 7px 0 0` | 59px |

Note the active tool tab keeps the panel fill and switches only the *label* to pink.

**Benchmark bars** — horizontal bars on low-alpha tint fills (green/red/yellow/blue/pink at 10-20%) with a `#9ca3af` caption underneath; these carry the page's argument.

**Inputs** — not captured (no exposed form fields).

## 5. Layout Principles

Published layout tokens: `--max-width: 1280px`, `--horizontal-padding: 3rem`, `--vertical-padding: 4rem`, `--list-padding: 0.9em`, `--list-item-padding: 0.375em`, `--navbar-height: 60px`. Radius census: `3 / 4 / 5 / 6 / 8 / 30 / 40px`, `9999px`, plus the `6px 6px 0 0` and `7px 7px 0 0` tab caps.

## 6. Depth &amp; Elevation

Radius scale: `3 / 4 / 5 / 6 / 8 / 30 / 40px` / `9999px`, plus top-only tab caps.

Shadow recipes:

- `rgb(40, 45, 85) 0px -2px 0px 0px inset, rgb(81, 87, 125) 0px 0px 1px 1px inset, rgba(3, 4, 9, 0.3) 0px 2px 2px 0px` — the keycap button bevel
- `rgba(0,0,0,0.1) 0px 10px 15px -3px, rgba(0,0,0,0.05) 0px 4px 6px -2px` — panel lift
- `rgba(0,0,0,0.05) 0px 1px 2px 0px` — subtle
- `rgb(80, 80, 80) -1px -1px 0px 0px` — a hard top-left hairline

Depth is bevel-and-hairline plus the `#0d0e11` &rarr; `#282a36` &rarr; `#3b3f4b` surface ladder.

## 7. Motion

Transition census resolved only generic values on the landing surface; specific durations and easings are **not captured**. The benchmark visualisations animate on scroll.

## 8. Backgrounds, Effects &amp; WebGL

Gradients observed:

- `linear-gradient(-26.5deg, rgb(86,88,114), rgb(49,53,91))` — the slate panel gradient
- `linear-gradient(rgba(244,114,182,0.03), rgba(20,21,26,0.5))` — a very faint pink-to-dark wash
- `linear-gradient(to right bottom, rgba(20,21,26,0.8), rgba(20,21,26,0.5))` — panel scrim
- `linear-gradient(to right, rgb(230,126,34), rgb(243,156,18))` — an orange framework gradient
- `radial-gradient(134.26% 244.64% at 42.92% -80.36%, rgb(179,1,179) 25.45%, rgb(56,29,189) 100%)` — a magenta-to-indigo framework gradient

No WebGL, no canvas, no backdrop-filter, no grain. The framework gradients belong to third-party logos/cards, not to Bun's own chrome.

## 9. Do's and Don'ts

### Do
- Render the brand dark — `#0d0e11` canvas, `#282a36` panels, `#3b3f4b` raised chrome.
- Use `system-ui` for all text; do not introduce a display webfont.
- Set display roles at weight 800 with a **1.0 line-height** (53.33/53.33, 48/48).
- Keep pink `#f472b6` as the only brand colour in chrome, with `#fbcfe8` for large headings.
- Render switchers as **tab-topped panels** with `6px 6px 0 0` / `7px 7px 0 0` caps sitting flush on the panel.
- Give the primary button the `0 -2px 0 inset` + 1px inner-ring keycap bevel.
- Confine green/red/yellow/blue to low-alpha benchmark-bar fills.

### Don't
- Don't render this brand on a cream or white canvas — that is the retired look.
- Don't add a display webfont; the bluntness of `system-ui` is the point.
- Don't use intermediate display weights — it is 800 or body 400.
- Don't use the benchmark tints as UI status colours.
- Don't fully round the switcher tabs; only the top corners are rounded.
- Don't put the purple ramp or the framework gradients into chrome.

## 10. Responsive Behavior

Published breakpoint tokens: `--phone: 600px` and `--tablet: 900px`. Exact adaptations were not observed (screenshots unavailable).

## 11. Agent Prompt Guide

- Canvas `#0d0e11` · Body `#14151a` · Panel `#282a36` · Raised `#3b3f4b` · Text `#f9fafb` · Body copy `#d1d5db` · Muted `#9ca3af` · Accent `#f472b6`
- Font: `system-ui` (all text), JetBrains Mono (code) · Body: 20.8/31.2 lead, `--line-height: 1.4` · Radius: 8px button / `6px 6px 0 0` tab / 9999px pill · Control height: 44-48px
- Focus: not captured · Bevel: `rgb(40,45,85) 0 -2px 0 inset, rgb(81,87,125) 0 0 1px 1px inset, rgba(3,4,9,.3) 0 2px 2px` · Motion: not captured

<bun_design_language>
A dark, benchmark-forward JavaScript-runtime page — note this is the CURRENT look, not the retired cream canvas. Ground steps #0d0e11 canvas, #14151a body, #282a36 panels, #3b3f4b raised chrome, over a full published gray ramp (#4f5666, #6b7280, #9ca3af, #d1d5db, #e5e7eb, #f3f4f6, #f9fafb). Hot pink #f472b6 is the only brand colour in chrome — the primary button, the active tab, and large section headings in the lighter #fbcfe8. Type is deliberately un-designed: system-ui for ALL text with no display webfont, but pushed to weight 800 at 53.33/53.33 and 48/48 — a 1.0 line-height on both display roles is what makes headlines feel packed — against 400-weight body at 20.8/31.2, with no intermediate display weight and normal tracking throughout; code is JetBrains Mono. The signature structural device is the TAB-TOPPED PANEL: platform and tool switchers render as tabs with only their top corners rounded (6px 6px 0 0 at 42px, 7px 7px 0 0 at 59px) sitting flush on the panel beneath, like a file divider — and the active tool tab keeps the panel fill, switching only its label to pink. Buttons are 44-48px at 8px radius (or a 9999px pill) and carry a keycap bevel: rgb(40,45,85) 0 -2px 0 inset, rgb(81,87,125) 0 0 1px 1px inset, rgba(3,4,9,.3) 0 2px 2px. Green #23c35f, red #f04646, yellow #ebb40a, blue #3b80f5 and pink #eb469b exist ONLY as 10-20% alpha benchmark-bar fills, never as UI status colours. Layout runs a 1280px max width with 3rem horizontal and 4rem vertical padding, breakpoints at 600px and 900px. Feels: fast, blunt, benchmark-driven, developer-native. Avoid: a cream or white canvas, adding a display webfont, intermediate display weights, benchmark tints as status colours, fully rounded switcher tabs, and the purple ramp or framework gradients in chrome.
</bun_design_language>
