Source of truth for the browser hub (web/). Do not improvise a second personality.
CatCode is a self-hosted coding-agent foundry. The logo is a glossy dark badge, amber spark, gold chevron. Design from that: cooled iron, copper used only when something is live, a reaction that stays hot when you walk away.
- Leptos 0.8 CSR (WASM) for the live hub UI. Axum still owns HTTP, cookies, and
/ws. app.cssfor generated surfaces (turns, sessions, composer heat, overlays) and the grid shell.- Bricolage Grotesque + IBM Plex Mono. No Inter, no Geist, no cream + serif.
- Tailwind v4 browser (
@tailwindcss/browser) remains only for static chrome utilities on the shell.
Product UI. Compete with Codex, Claude, OpenCode, and Hermes on conversation-first chrome. Not a marketing landing. Not a VS Code clone.
| Dial | Value | Why |
|---|---|---|
| DESIGN_VARIANCE | 3 | Product chrome. Conversation is the page. |
| MOTION_INTENSITY | 4 | Composer heat, turn rise, hover. No GSAP. |
| VISUAL_DENSITY | 5 | Quiet rail. Breath in the transcript. |
One accent (filament), used only on live states and the send disc. Hairlines are neutral, never orange. One radius scale (8 / 14 / 24 / pill). Dark foundry locked; day is a cool paper invert of the same personality.
| Token | Hex | Use |
|---|---|---|
void |
#090B0D |
page and chrome, one plane |
hearth |
#12151A |
composer, hover, overlays |
slag |
#1C2128 |
pressed / chip hover |
filament |
#E08A2C |
send, live ticks, streaming rim |
spark |
#F3C27A |
caret, hover on send |
oxide |
#6BA8A0 |
attention / links |
ash |
#8B949E |
secondary text |
paper |
#E6E8EB |
primary text (cool, not cream) |
danger |
#E25A45 |
deny / delete |
ok |
#6FBF7A |
done / approved |
Heat lives on the composer, not a 3px page border.
- Idle: quiet hearth island
- Streaming: copper rim + soft glow (
.crucible.hot) - Needs you: oxide rim (
.crucible.attn) - Turn ticks: YOU filament, AGENT dim slate, streaming spark
prefers-reduced-motion: reduce: static color only
┌──────────┬──────────────────────────────────────────┐
│ mark │ ⌘K notify … │
│ projects │ session title (whisper) │
│ new │ │
│ sessions │ transcript as a document │
│ │ empty: display type + starter rows │
│ │ │
│ │ ╭──────────────────────────────────╮ │
│ │ │ composer island │ │
│ │ ╰──────────────────────────────────╯ │
└──────────┴──────────────────────────────────────────┘
No spanning top bar. Projects live in the rail. Inspect (⌘I) is a right drawer, closed by default: Work (live diffs), Crew (subagent tools and notes), Repo (git + goal). Sessions collapse on desktop with ⌘B.
Mobile < 840px: rail and inspect become drawers. Composer sticky.
Overlays are one host (#overlay → #overlay-card) but five placements. The job picks the shape. No native confirm() / prompt().
data-kind |
Surfaces | Placement | Flow |
|---|---|---|---|
palette |
command palette, project picker | Top-center command menu. Search is the header. Chat stays readable. | Enter/click runs. Destinations replace the menu (no close-then-open flicker). Completing actions dismiss. |
browse |
open folder | Tall centered picker. List is the job. | Filter, crumbs, hidden off. Create/Clone stay compact. Open this folder. |
confirm / login |
confirm, prompt, provider login | Small centered dialog. Title is the action. | Cancel / OK. Rename device returns to Devices, not the chat. Login is OAuth-first. |
modal |
settings | Large centered dialog. Tabs are the job. | Esc / backdrop close. Opened from ⌘K shows Back to the palette. |
drawer |
account, devices, notes, models, goal, help, keys | Right sheet. Transcript stays visible. | Opened from ⌘K shows Back to the palette. Esc / backdrop close. |
-
Palette items that open another overlay set
palette_return. Back chevron restores ⌘K. Toolbar entry points do not show Back. -
Tab cycles inside
#overlay-card. -
Lists sit in void wells. Current project/model get a
Currentmark. -
Mobile
< 840px: palette, browse, and drawers dock as bottom sheets. Confirm/login/modal stay centered cards. -
HITL stays in
#gate-banner. -
HITL (approval, ask, sudo, intercom, OAuth) stays in
#gate-bannerso the composer can keep heat.
The transcript is a document. renderMd owns blocks; inlineMd owns spans. No third-party parser.
- Fences keep a language chip and Copy. Tables, task lists, quotes, and nested lists are first-class.
- Copper stays off markdown chrome. Code sits on hearth with a hairline. Quotes use an oxide rule.
- Escape HTML first. Links and images are
https?only.
- VS Code clone (activity bar + file tree + tabs + terminal)
- Cream + serif + terracotta; near-black + acid green; orange hairlines on every box
- Inter / Geist / system-ui as the personality face
- PTY terminal, Monaco, preview iframe
- A second agent loop
- Always-on inspect column
- Grain overlays, glowing status orbs, chat bubbles
Tactile press on the send disc and starter cards is allowed. Do not add a second modal language.