| name | Codewhale | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| description | Quiet, dense, navy-and-blue design system for Codewhale — the terminal shell, the website, and the docs. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| colors |
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| typography |
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| rounded |
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| spacing |
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| components |
|
Codewhale is an open-source Rust coding agent and TUI. Everything it shows — the shell, the website, the docs — is built to feel like one tool: a flat navy field, one blue action colour, white type, thin hairlines, and nothing decorative. The direction in one line: it doesn't need to look special — it needs to look like Codewhale. Density over drama, facts over claims, documentation-grade restraint on every surface including the landing page and the launch hero.
This file is shared design context for every 0.9.12 lane (web, docs, TUI). The
web-specific product truth is in PRODUCT.md next to it.
These are hard rules, not taste notes. A surface that breaks one is wrong even if it looks fine in a screenshot.
- No gradients for decoration. The ombre
#1535B2 → #6AA6DClives in the mark and the wordmark only. No gradient backgrounds, gradient text, gradient rules, radial "spotlight" glows, or gradient borders anywhere else. - No glassmorphism. No
backdrop-filter, no translucent frosted panels, no blur. Surfaces are opaque tokens from the palette. - No generic SaaS hero. No three-column feature grid with icons, no logo wall, no testimonials, no floating product mock at an angle, no "trusted by", no neon eyebrow line. The landing page states what the tool is, shows one real screenshot, and gives the install command.
- No fabricated evidence. No invented terminal transcripts, reasoning traces, benchmarks, or screenshots of a UI that has not shipped. Pending media is labelled pending.
- No shadow theatre. No drop shadows on cards, buttons, or figures; depth is one surface step and one hairline.
- No second accent. One action blue. Cyan is bounded to the composer prompt glyph; state colours carry state only; violet is 1px rules, never text.
- No status-chip soup, no emoji, no all-caps headings. Labels are letterspaced mono at ≥ 0.7rem and there are few of them.
- No text below the floors (12px functional, 11.2px labels) and no text/background pair under 4.5:1.
One palette, owned by crates/tui/src/palette/tokens.rs, exported to
web/app/tokens.css by scripts/export-design-tokens.py (regenerate, never
edit). The brand-name aliases used in conversation map onto it: black #000,
ink #070c1d = bg, navy #0c1531 = chrome, stage #142352 = composer,
ivory #fff, ice #ddeef9, cobalt #1535b2, blue/sky #6aa6dc = action,
cyan #78bce8. The TUI uses the same tokens through palette::grammar for
status colours. web/app/globals.css maps them to semantic names: --paper
(bg), --paper-deep (panel), --ink (text), --ink-soft, --ink-mute,
--indigo (action), --hairline (action at 20 % alpha).
- Field: on the web,
bgfor the page and the transcript andchromefor bars and the dock; in the TUI the ground is the terminal's own background (Color::Reset), and the navy field is painted only under the opt-inocean_treatment = "deepsea"(aliasunderwater) column.panelfor cards and code,composerfor the raised input plate,elevatedonly for overlays. Never stack more than two surface steps in one view. - Type:
text-bodyfor copy,text-softfor secondary,text-mutedfor meta.text-dim(#697791) is for borders only — it fails AA on the panels. - Action: one blue (
action) for links, buttons, and focus rings; hover lifts toaction-hover.cyanis a bounded accent (eyebrow chrome, composer prompt) — never body text, never fills. - Brand ombre
#1535B2 → #6AA6DCexists only in the mark and wordmark. Do not paint UI with it. - State colours (
success,warning,error,human) carry meaning; do not use them decoratively, and never convey state by colour alone.
Contrast: every text/background pair in use is ≥ 4.5:1 (text-muted on
panel 6.3:1, on composer 5.7:1, on bg 7.4:1; action on bg 7.5:1).
Three faces, one job each:
- IBM Plex Sans Condensed 600 — display and all headings (
--font-display). Also the wordmark: "codewhale" in Plex Sans Condensed SemiBold, outlined to paths, letter-spacing −0.01em. Tight leading (1.0–1.08), no all-caps headings. - IBM Plex Sans 400/500/600 — body (
--font-body). Measure ≤ 70ch. - JetBrains Mono 400/500 — code and the mono meta rows (
--font-mono). Letterspaced uppercase mono is the only "label" style.
Floors: functional text (links, nav, labels, meta, footer) never below 12px (0.75rem); letterspaced micro-labels never below 11.2px (0.7rem); legal smallprint never below 10px. Heading outline is strict: h1 → h2 → h3, no skipped levels; use CSS, not a lower heading tag, to make something smaller.
The redesigned 0.9.12 shell is the reference the website mirrors. Top to
bottom (founder decisions, 2026-09-01/02 — see
codewhale-ops/design/SHELL-DESIGN-20260901.md for the dated record):
- Transcript first. The conversation owns the screen: no permanent side
chrome, no top bar. Turns are plain text on the terminal's own ground;
tool output is
text-softonpanel; reasoning is the reasoning tint, collapsed by default. - Launch is a card, not a hero. A thin top line (
⑂ branch path); a centred bordered card: the whale mark at left,Codewhale+ version, one announcement line only when it is true, then the menu New worktree · Resume session · Changelog · Quit with real chords right-aligned. Enter runs the highlighted entry; typing goes straight to the composer; the card dissolves on the first keystroke or command. - Composer. The raised
composerplate directly under the transcript, cyan❯prompt glyph. While the card is up its bottom rule carriesmodel (effort) · permission— the route's one launch reading. - Posture bar + metrics line under the composer, once a session
exists:
▶▶ ask (Shift+Tab) · work (Tab) · 2 agents · Esc to interrupt …andmodel · ctx NN% · $cost · ttft · tok/s · ↓ tokens … Ctrl+/ help. Context % lives in the metrics line only. - Bottom views, not a dock. One region under the composer cycles through agents → tasks → background → files → notepad → context → git → price (Ctrl+Tab forward, Ctrl+Shift+Tab back where the terminal delivers it). Zero rows when idle with nothing to show. There is no rail, no sidebar, no tab band.
- Single content column,
.product-containermax 72rem, 1rem side padding at 390px. The landing has no permanent side chrome; docs have a left contents rail at ≥ 1050px that collapses into a top list below. - Sections are separated by one hairline and generous vertical space
(
spacing.section), not by background colour changes. - Prose measure ≤ 70ch on docs; wide code blocks scroll horizontally inside their panel rather than widening the column.
- Breakpoints in use: 640px (hero stacks, h1 drops to
clamp(2rem, 10vw, 3rem)), 900px (hero two-column), 1050px (docs rail). - No horizontal overflow at 390px, ever.
Flat. Depth is expressed by one surface step (bg → panel) and one hairline.
No drop shadows on cards or buttons; the only shadow is the raised composer
plate in the TUI screenshot itself. No blur, no glass, no glow.
Small radii: 4px on controls, 6px on cards and code panels, 999px only on the GitHub-stars pill. No rounded-2xl, no circles as decoration. Whale mark is the only curved form.
- Nav: 62px bar,
bg, hairline below. Left: whale mark (22px) + wordmark (20px) as one link labelled "Codewhale home". Centre: text links in body face. Right: theme, locale, stars pill, sign in / register (mono meta), one filled Install button. Collapses to a menu button below 900px. - Buttons: filled action blue (primary), panel with hairline (secondary),
text-only (ghost). Mono meta type, uppercase, 0.08em tracking. Visible focus
ring in
actionon every control. - Cards / steps:
panelbg, hairline border, 16–18px padding, number inactionmono, h3 in display face, body intext-soft. - Code blocks:
panelbg, JetBrains Mono 0.85rem, copy button top-right, scroll-x inside. - Eyebrow: mono, uppercase, 0.7rem,
cyanortext-muted. - Footer:
bg, hairline top, inverted wordmark, column links at 0.75rem mono; legal line at 0.7rem. - Media slots: real assets only; a
pendingslot renders a labelled empty panel, never a mock.
Do
- Derive every fact from the repo; one owner per number.
- Keep the whale mark and wordmark together in the nav; wordmark alone in the footer.
- Use the display face for headings and the wordmark, nothing else.
- Meet AA and the 12px floor before shipping any new surface.
Don't
- Fabricate terminal output, reasoning traces, testimonials, or screenshots.
- Introduce a second accent colour, gradients on UI, shadows, or glass.
- Add a UI library or page-local copy; extend
lib/content/and the dictionaries. - Use
text-dimfor text, skip heading levels, or shrink type below the floors.