Show structure. Hide ornament.
Hairlines, generous whitespace, strong type hierarchy. No drop shadows, no gradient backgrounds, no decorative blobs. If a pixel doesn't earn its place, cut it.
One token model, two surfaces. The same colors, type, and motion power the marketing site, the product, and every artifact in between. Direct. Confident. Never decorative.
Paperclip is the app people use to manage AI agents for work. The brand and the product share one design system: serious software for serious work — direct, confident, never decorative.
Hairlines, generous whitespace, strong type hierarchy. No drop shadows, no gradient backgrounds, no decorative blobs. If a pixel doesn't earn its place, cut it.
Same tokens, same type ramp, same motion. The marketing site feels like a continuation of the product, not a different app. Differences are density and content, not vocabulary.
The 1:2 capsule shape is reserved for agent representation — capsule fields, org chart nodes, status indicators, avatars. Never on chrome, never on buttons. That's why it stays meaningful.
Pause, resume, override, reassign, terminate. The visual language emphasizes legibility, traceability and accountability. Buttons read like commands. Status reads like telemetry. The interface never pretends the agent is choosing — the operator is.
One token model spans two production surfaces. Theme, density, and content adapt; the vocabulary doesn't.
Editorial. Light-only in production. Astro. Tells the story, sells the product.
Grid-disciplined. Light + dark. React + Tailwind + shadcn. Where work happens.
The Paperclip mark is a minimalist line drawing of a paperclip. Functional. Recognizable at any size. Always rendered as a stroke — never filled, never decorated.
Maintain minimum clear space equal to the icon width on all sides. Below 16px, drop the wordmark and use the icon only.
Use the stroke-based mark. Pure currentColor — adapts to surface.
Never fill the paperclip shape. The line is the brand.
No gradients. No drop shadows. No effects.
Never rotate, skew, or transform the mark beyond the default ‑12°.
Always title-case. Not "PaperClip", "paperclip", or "PAPERCLIP".
Never substitute the wordmark typeface. Inter Semibold only.
Inter Tight carries display and editorial weight. Inter does every other word on the page. JetBrains Mono carries the engineering credibility — telemetry, code, timestamps. Nothing else.
The display voice. All headings, display copy, big moments. Default weight 600 — tight tracking provides the editorial gravity without leaning on bold.
font-family: 'Inter Tight', sans-serifweight: 600 · line-height: 1.02–1.2 · letter-spacing: -0.04em → -0.02emThe workhorse. Body, labels, navigation, buttons, the wordmark. ss01 + cv11 are enabled site-wide.
font-family: 'Inter', sans-seriffont-feature-settings: 'ss01', 'cv11'The engineering layer. Timestamps, hex codes, agent names, tool calls, terminal, telemetry chips. tabular-nums always on.
$ paperclip status --agent ceo ▸ alive budget 64% 4h 32m
font-family: 'JetBrains Mono', monospaceUse the role, not the size. Display roles use Inter Tight at 600. Body and labels use Inter. Mono is JetBrains Mono.
| ROLE | SAMPLE | SPEC |
|---|---|---|
| display-1 | Headline. | clamp(42, 5.5vw, 80) · 600 · ‑0.04em |
| display-2 | Section heading | clamp(40, 5.5vw, 72) · 600 · ‑0.035em |
| display-3 | Subsection | clamp(28, 3.5vw, 44) · 600 · ‑0.03em |
| display-4 | Card title | 26 · 600 · ‑0.02em |
| lede | Subhead / hero lede | 20 / 1.45 · 400 · 0 |
| body-lg | Body large — feature copy | 18 / 1.5 · 400 · 0 |
| body | Body — running text, paragraphs, default UI copy. | 16 / 1.6 · 400 · 0 |
| body-sm | Body small — secondary text, table cells, dense UI. | 14 / 1.5 · 400 · 0 |
| caption | EYEBROWS · LABELS · CATEGORY TAGS | 11 · 500 · +0.08em · UPPER |
| mono | $ paperclip status — 1042 events | 13 / 1.4 · 400 · tabular-nums |
| mono-sm | 14:32:07 · #1042 · CEO Hermes | 11 / 1.4 · 400 |
Agents wake on a schedule, check their work, and act. Delegation flows up and down the org chart automatically.
Pause. Resume. Override. Reassign. Terminate.
Inter Tight at 600. Tight tracking. Sentence-case. The tight spacing does the editorial work.
No all-caps display. No loose tracking on display sizes. Caps are reserved for the caption role.
Use the mono stack for timestamps, IDs, tool calls, agent names, hex values, terminal output. tabular-nums keeps columns aligned.
Don't dress system telemetry in editorial type. Mono is the layer that signals "this is real, this happened, this was logged."
Brand neutrals derived from office materials — bond, vellum, ink, manila folders — so screens have depth beyond generic black-on-white. Status colors carry product meaning. The agent palette is saturated gradients reserved for agents and org-chart nodes, never for chrome or buttons.
Material vocabulary: bond → linen → parchment → manila → vellum → steel → aluminum → graphite → charcoal → ink. Each is a named token, always literal — never swaps with theme. Use these when you need a specific color regardless of mode (callouts, swatches, brand marks).
Components reference these. They swap with theme. The brand neutrals above are the literal values they resolve to.
| TOKEN | LIGHT | DARK | USAGE |
|---|---|---|---|
| --bg | bond #FFF | charcoal #141413 | Page background |
| --bg-alt | linen | #141413 | Alt background, banded sections |
| --surface | parchment | #1F1D1A | Cards · panels · active states |
| --rule | vellum | #2F2C28 | Hairline borders + dividers |
| --text | ink | manila | Primary text |
| --text-2 | graphite | #9A958A | Secondary text · subhead |
| --text-muted | aluminum | #6E6960 | Captions · placeholders · mono labels |
| --accent | signal #22C55E | signal #22C55E | Focus rings · CTA hover · active dots |
Six semantic colors carry meaning across both surfaces — gray is a first-class status color (inert / resting), not just chrome. Each card documents the full chip recipe per theme: light chips use a tinted fill + saturated text; dark chips use a translucent fill of the solid hue, a solid-color text, and a 45%-alpha border. Alpha suffixes (e.g. #2563EB·18%) are written in the codebase as 8-digit hex — #2563eb2e.
Violet is reserved for task in_review — it is not part of the general-purpose chip palette in brandChipBadge yet. Full chip semantics + live examples in §13 States & Status.
Brand use only. Twelve saturated gradients reserved for the capsule motif — agent representation, org-chart nodes, status indicators, testimonial avatars. Never on buttons, status pills, or generic chrome. That's why the palette stays meaningful.
Use ink + warm neutrals for chrome. Signal green earns its place only when status truly is "alive" or "succeeded."
No gradient buttons. No agent-palette colors on chrome. Saturation in chrome dilutes the brand-language signal.
Agent palette belongs on the capsule motif — agent representation only.
Never on buttons, never on badges. The palette is a brand asset, not a decoration kit.
A 4-pixel micro and 8-pixel base. The page-level rhythm uses CSS clamp() so generous whitespace stays generous on big screens and collapses gracefully on small ones.
| TOKEN | VALUE | VISUAL | USAGE |
|---|---|---|---|
| --space-1 | 4px | Micro — chip gaps, icon padding | |
| --space-2 | 8px | Inline gaps, badge padding, label→input gap | |
| --space-3 | 12px | Button gap, dense grids | |
| --space-4 | 16px | Card padding tight, list row gap | |
| --space-5 | 24px | Card padding default, section subhead gap | |
| --space-6 | 32px | Gutter, card padding generous | |
| --space-7 | 48px | Block-level rhythm, subsection spacing | |
| --space-8 | 64px | Hero padding, section margin | |
| --space-9 | 96px | Section padding-y (default) | |
| --space-10 | 128px | Page-top, big editorial gaps | |
| --space-lg | clamp(32, +1.5vw, 48) | fluid | Card-to-card spacing in marketing |
| --space-xl | clamp(48, +3vw, 80) | fluid | Subsection blocks |
| --space-section | clamp(80, +5.5vw, 144) | fluid | Marketing section padding-y |
Radius isn't decoration — it signals what kind of thing you're touching. A pill is a primary action. A 16px rounded rect is a card. A capsule is an agent.
Status pills · code chips · table cells
Inputs · small cards · agent cards in lists
Default card · panel · feature blocks
Modals · large surfaces · terminal block
Primary CTA only. Buttons that initiate action. Also: theme toggle, badge chips.
Agents only. Stadium pill at 1:2 ratio. Reserved for capsule motif.
Pill (--r-pill) is reserved for primary actions. Echoes the capsule motif at the chrome level — the brand mark and the call-to-action are the same shape. Everything else uses 8/10/16/24px rounded rect.
Pill is primary. Secondary is 10px rounded — close to the input shape, not the agent shape.
Don't pill secondaries. Don't square-off primaries. The shape vocabulary is part of the brand.
Icons label actions, states, or help the user understand functionality quickly. They never compete with the capsule motif or compete for attention.
Stroke only. currentColor. Rounded line caps + joins.
No filled glyphs in chrome. Fills compete with capsule-motif fills.
No emoji in product UI or technical docs. Emoji is a different visual language.
Every agent is a capsule. Every capsule is an agent. The mark and the metaphor are the same shape.
Construction: border-radius: 9999px (or 50% of width). Fill: smooth linear-gradient(to bottom, anchor-a, anchor-b). Flat single-color variant available for contexts that need a solid mark.
Eight agents. Each its own gradient. Different heights signal cost, status, or output.
One initial on the agent gradient until a profile photo is uploaded. Same gradient classes as capsules — every visual of an agent shares one DNA.
The graphic generator produces on-brand artifacts — OG images, blog covers, social posts, slide backdrops — by arranging capsules into templates and colorizing them from palettes. Below: a mini, in-doc version. Production tool: paperclip-graphic-generator.
Paperclip speaks with authority about complex systems but never obscures meaning. Short sentences. Active verbs. Technical when needed, never when not.
"Paperclip uses those agents. It orchestrates them into a company — with org charts, budgets, goals, governance, and accountability."
"Pause. Resume. Override. Reassign. Terminate. You have full control over every agent in the org."
"Not a chatbot. Not an agent framework. Not a workflow builder."
"Full observability. Every ticket traced. Every decision explained. Every tool call logged."
"Paperclip is a revolutionary, AI-powered next-gen platform that empowers teams to leverage the full potential of their agentic workforce!"
"Paperclip orchestrates a team of AI agents. Org charts, budgets, goals. You hire. You approve. You ship."
"Various optimizations have been applied to ensure that runaway costs are mitigated through robust budget enforcement mechanisms."
"Every agent gets a monthly budget. When they hit it, they stop. No runaway costs. Hard limits, enforced by the system."
"🚀 Get started with Paperclip today and unlock the future of work! 💼✨"
"Open source. Self-hosted. npx paperclipai onboard and you're running."
Animation signals life and state. Entrance reveals stagger. Active elements pulse. Transitions ease at 200ms. Nothing bounces unless it has a reason — and almost nothing does.
| TOKEN | VALUE | WHERE |
|---|---|---|
| --ease-out | cubic-bezier(.2,.8,.2,1) | Entrance, hover lifts, primary motion |
| --ease-in | cubic-bezier(.4,0,1,.6) | Exit, dismissal |
| --ease-inout | cubic-bezier(.65,0,.35,1) | Scrub, pinned scroll |
| --dur-micro | 120ms | Hover color shifts, focus rings |
| --dur-short | 200ms | Default UI transitions, button hover |
| --dur-medium | 400ms | Theme swap, panel slide-in |
| --dur-long | 700ms | Hero reveals, pinned set pieces |
450ms ease-out · 140ms stagger · translateY 12 → 0
1.6s ease-in-out · infinite · alive · scale 0.85 ↔ 1.0
200ms ease-out · color shift only · no transform, no bounce
700ms ease-out · opacity 0 → 1 · translateY 24 → 0
400ms ease-out · background + color crossfade
Every motion pattern has a no-motion fallback. If the user prefers reduced motion, animations stop or shorten to a 100ms color crossfade.
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
animation-duration: 0.01ms !important;
transition-duration: 100ms !important;
scroll-behavior: auto !important;
}
}
Every component below ships in light and dark. Every interactive control has explicit default, hover, focus, active, and disabled states. Hover the state explorer chips to preview each state in place.
Agents wake on schedule or on demand. Every action logged.
Same card pattern, dark surface. Used in marketing callouts and product modals.
$ npx paperclipai onboard --yes ✓ Embedded postgres started ✓ Company created: note-taking-app ✓ CEO Hermes online (claude-sonnet-4-5) ✓ Dashboard at http://localhost:3100 $ ▍
// Self-host config export default { company: 'note-taking-app', db: 'postgres://localhost', heartbeat: 4, // hours budgets: { ceo: 60 }, }
Charts read like instruments. Ink lines on hairline grids. Mono labels. No gradients in chart fills — saturation stays in the agent palette where it carries meaning.
| AGENT | BUDGET USED | COST |
|---|---|---|
| CEO Hermes | $23.40 / $60 | |
| CMO OpenClaw | $32.00 / $40 | |
| CTO Codex | $50.00 / $50 | |
| COO Claude | $5.40 / $30 |
One color language across every entity — agents, tasks, projects. The governing rule: blue = liveness. Actively running work is blue; queued, idle, or inert work is not. Every status below is rendered with the real chip CSS, so what you see is the spec.
Six semantic colors. Each is a brand .task-chip: a 1px-bordered pill with distinct light and dark values. Light chips use a tinted fill + saturated text; dark chips use a translucent fill of the solid hue + solid-color text + a 45%-alpha border. Toggle the page theme to see both states live.
| COLOR | CHIP | LIGHT — BG / TEXT / BORDER | DARK — BG / TEXT / BORDER |
|---|---|---|---|
| gray inert / resting |
gray | #F5F3F0 / #52585D / #A8AEB2 | #6E6960·14% / #9A958A / #9E958A·45% |
| blue live / running |
blue | #DBEAFE / #1D4ED8 / #2563EB | #2563EB·18% / #5B8DEF / #2563EB·45% |
| amber queued / paused |
amber | #FEF3C7 / #B45309 / #F59E0B | #F59E0B·14% / #F59E0B / #F59E0B·45% |
| green done / online |
green | #DCFCE7 / #188A3C / #22C55E | #22C55E·12% / #34D06F / #22C55E·45% |
| red error / blocked |
red | #FEE2E2 / #991B1B / #DC2626 | #DC2626·18% / #EF4444 / #DC2626·45% |
| violet awaiting review · reserved |
violet | #EDE9FE / #5B21B6 / #7C3AED | #7C3AED·18% / #A78BFA / #7C3AED·45% |
Alpha suffixes (e.g. ·18%) are written in the codebase as 8-digit hex — #2563eb2e = #2563EB at 18% alpha. Violet is reserved for task in_review; it is not yet exported in brandChipBadge.
Every ticket lives in exactly one of these states. The blue = liveness rule applies: in_progress is blue (actively worked), todo is amber (queued — ready but not live). The icon, color, and copy are fixed so the same status reads identically on the board, in a row, and in a chip.
| SUB-STATE | CHIP | COLOR | SELF-HEALS? |
|---|---|---|---|
| In queue blocked behind a live child |
In queue | blue | Yes — unblocks when the child finishes. No action needed. |
| blocked plain blocked = needs a human |
Blocked | red | No — needs a human decision / triage / unblock. |
The agents list renders four states. The indicator is a heartbeat capsule (8×16, r4, solid fill); the row chip is the matching brand chip. active aliases idle; terminated and pending_approval are excluded from the list — the hiring gate lives in the task thread as a violet in_review task.
| STATUS | CAPSULE | CHIP | COLOR | BEHAVIOUR |
|---|---|---|---|---|
| idle active aliases this |
idle | gray | Online, no active run — the resting / available state. Capsule is still. | |
| running | running | blue · live | A heartbeat is executing right now. Capsule pulses — hb-pulse 1.6s. | |
| paused | paused | amber | Halted — manual / budget / system. Capsule is still. (Amber, not gray, so it doesn't collide with idle.) | |
| error | error | red | The agent itself is broken (e.g. not connected to a model) — distinct from a task failing. Capsule blinks — hb-blink 1.2s. |
Five project statuses, same brand chips: planned is amber (committed but not started — mirrors task todo) and in_progress is blue (liveness). paused and archived are overlays, not enum values.
| STATUS | CHIP | COLOR | MEANING |
|---|---|---|---|
| backlog | backlog | gray | Parked / unscheduled — not yet picked up. |
| planned | planned | amber | Committed but not started — the "queued / ready" identity (mirrors task todo). |
| in_progress | in progress | blue · live | Actively being worked — has live work. Liveness. |
| completed | completed | green | Delivered / closed out (matches task done). |
| cancelled | cancelled | gray | Abandoned, not resumed. Gray + strikethrough. |
| OVERLAY | CHIP | COLOR | MEANING |
|---|---|---|---|
| paused pauseReason |
paused | amber | Halted (manual / budget / system). Overlay on the base status — consistent with a paused agent. |
| archived archivedAt |
— hidden from the list (no chip) — | — | Filtered out of All Projects, like terminated agents. |
Colors mean the same thing whether the row is an agent, a task, or a project. When you build new UI, choose the color by what the state means, then apply the chip token.
| COLOR | MEANS | AGENT | TASK | PROJECT |
|---|---|---|---|---|
| blue | live — actively running now | running | in_progress · In queue | in_progress |
| amber | queued / paused — ready or halted, not live | paused | todo | planned · paused |
| green | done / online — finished or healthy | — | done | completed |
| violet | awaiting review — needs a human look | (hiring gate → task) | in_review | — |
| red | error / blocked — broken, needs a human | error | blocked | — |
| gray | inert — resting, parked, or cancelled | idle · terminated | backlog · cancelled | backlog · cancelled |
Motion is reserved for states that demand attention: only running pulses and only error blinks — idle and paused are still. Product token: 8×16, r4, solid fill (rendered larger here for display). Both animations honor prefers-reduced-motion.
Capsule grays are theme-aware: #A8AEB2 light / #6E6960 dark. Blue, amber, and red fills are literal in both themes.
Every chip above maps to these exact strings in ui/src/lib/status-colors.ts (Tailwind classes). Use the maps; don't hand-write hex.
// Brand .task-chip palette — light + dark, 1px border
export const brandChipBadge = {
gray: "bg-[#F5F3F0] text-[#52585D] border-[#A8AEB2] dark:bg-[#6e696024] dark:text-[#9A958A] dark:border-[#9e958a73]",
blue: "bg-[#DBEAFE] text-[#1D4ED8] border-[#2563EB] dark:bg-[#2563eb2e] dark:text-[#2563EB] dark:border-[#2563eb73]",
amber: "bg-[#FEF3C7] text-[#B45309] border-[#F59E0B] dark:bg-[#f59e0b24] dark:text-[#F59E0B] dark:border-[#f59e0b73]",
green: "bg-[#DCFCE7] text-[#188A3C] border-[#22C55E] dark:bg-[#22c55e1f] dark:text-[#22C55E] dark:border-[#22c55e73]",
red: "bg-[#FEE2E2] text-[#991B1B] border-[#DC2626] dark:bg-[#dc26262e] dark:text-[#DC2626] dark:border-[#dc262673]",
};
// Semantic mappings
agentStatusColor = { idle:"gray", active:"gray", running:"blue", paused:"amber", error:"red" };
projectStatusColor = { backlog:"gray", planned:"amber", in_progress:"blue", completed:"green", cancelled:"gray" };
// Heartbeat capsule (agents) — 8×16, r4, solid fill
agentStatusCapsule = { gray:"#A8AEB2 / dark #6E6960", blue:"#2563EB", amber:"#F59E0B", red:"#DC2626" };
agentStatusMotion = { running:"hb-pulse 1.6s", error:"hb-blink 1.2s" };
Tokens ship as CSS custom properties (source of truth), a Tailwind theme extension for the React product, and JSON for tooling and Figma. Same names, same values. tokens.css is canonical; Tailwind and JSON exports stay aligned on release.
Import once. Semantic tokens swap under [data-theme="dark"]; brand neutrals and status colors stay literal.
:root {
/* ── Brand neutrals — material vocabulary, always literal ── */
--bond: #FFFFFF;
--linen: #F5F3F0;
--parchment: #F0ECE7;
--manila: #F3E6C4;
--vellum: #E0DCD6;
--steel: #D8DCDF;
--aluminum: #A8AEB2;
--graphite: #52585D;
--charcoal: #141413;
--ink: #0A0A0A;
/* ── Brand accent + status — literal across themes ── */
--signal: #22C55E;
--signal-soft: #DCFCE7;
--signal-deep: #188A3C;
--amber: #F59E0B;
--amber-soft: #FEF3C7;
--amber-deep: #B45309;
--red: #DC2626;
--red-soft: #FEE2E2;
--red-deep: #991B1B;
--blue: #2563EB;
--blue-soft: #DBEAFE;
--blue-deep: #1D4ED8;
/* ── Semantic tokens — light defaults ── */
--bg: var(--bond);
--bg-alt: var(--linen);
--surface: var(--parchment);
--rule: var(--vellum);
--text: var(--ink);
--text-2: var(--graphite);
--text-muted: var(--aluminum);
--input-bg: var(--bond);
--accent: var(--signal);
--accent-fg: #FFFFFF;
--accent-soft: var(--signal-soft);
--focus-ring: var(--signal);
/* ── Agent palette — 12 presets, brand only ── */
--agent-1a: #F7CFDC; --agent-1b: #1F7A3A; /* pink → forest */
--agent-2a: #C9A9E8; --agent-2b: #EE79A1; /* lavender → hot pink */
--agent-3a: #28164B; --agent-3b: #7A1530; /* purple → maroon */
--agent-4a: #F3E6C4; --agent-4b: #E3A21A; /* cream → amber */
--agent-5a: #1F4DD6; --agent-5b: #3AA35C; /* cobalt → green */
--agent-6a: #E94B27; --agent-6b: #5A1122; /* orange → maroon */
--agent-7a: #7EB6E3; --agent-7b: #EE79A1; /* sky → hot pink */
--agent-8a: #9CE8A7; --agent-8b: #BD7FF0; /* mint → violet */
--agent-9a: #F3B49E; --agent-9b: #1F4ED4; /* peach → cobalt */
--agent-10a: #F2D95F; --agent-10b: #4FBCBA; /* yellow → teal */
--agent-11a: #C2C2E8; --agent-11b: #5E3450; /* peri → mauve */
--agent-12a: #4DB9B7; --agent-12b: #3AA35C; /* teal → green */
/* ── Type ── */
--font-display: 'Inter Tight', 'Inter', system-ui, sans-serif;
--font-body: 'Inter', system-ui, sans-serif;
--font-mono: 'JetBrains Mono', ui-monospace, monospace;
/* ── Radius ── */
--r-xs: 4px;
--r-sm: 10px;
--r-md: 16px;
--r-lg: 24px;
--r-pill: 9999px;
/* ── Spacing — 4px micro, 8px base ── */
--space-1: 4px;
--space-2: 8px;
--space-3: 12px;
--space-4: 16px;
--space-5: 24px;
--space-6: 32px;
--space-7: 48px;
--space-8: 64px;
--space-9: 96px;
--space-10: 128px;
--space-lg: clamp(2rem, 1.5rem + 1.5vw, 3rem);
--space-xl: clamp(3rem, 2rem + 3vw, 5rem);
--space-section: clamp(5rem, 3rem + 5.5vw, 9rem);
/* ── Motion ── */
--ease-out: cubic-bezier(0.2, 0.8, 0.2, 1);
--ease-in: cubic-bezier(0.4, 0, 1, 0.6);
--ease-inout: cubic-bezier(0.65, 0, 0.35, 1);
--dur-micro: 120ms;
--dur-short: 200ms;
--dur-medium: 400ms;
--dur-long: 700ms;
}
[data-theme="dark"] {
--bg: var(--charcoal);
--bg-alt: #1F1D1A;
--surface: #1F1D1A;
--rule: #2F2C28;
--text: var(--manila);
--text-2: #9A958A;
--text-muted: #6E6960;
--input-bg: #1F1D1A;
--accent-fg: var(--ink);
--accent-soft: rgba(34, 197, 94, 0.14);
}
Semantic colors point at CSS vars so dark mode flips without duplicating hex in TypeScript.
import type { Config } from 'tailwindcss'
export default {
theme: {
extend: {
colors: {
// brand neutrals
bond: '#FFFFFF',
linen: '#F5F3F0',
parchment: '#F0ECE7',
manila: '#F3E6C4',
vellum: '#E0DCD6',
steel: '#D8DCDF',
aluminum: '#A8AEB2',
graphite: '#52585D',
charcoal: '#141413',
ink: '#0A0A0A',
// semantic (consume CSS vars so dark mode flips automatically)
bg: 'var(--bg)',
surface: 'var(--surface)',
rule: 'var(--rule)',
text: 'var(--text)',
'text-2': 'var(--text-2)',
muted: 'var(--text-muted)',
accent: 'var(--accent)',
// status
signal: { DEFAULT: '#22C55E', soft: '#DCFCE7', deep: '#188A3C' },
amber: { DEFAULT: '#F59E0B', soft: '#FEF3C7', deep: '#B45309' },
red: { DEFAULT: '#DC2626', soft: '#FEE2E2', deep: '#991B1B' },
blue: { DEFAULT: '#2563EB', soft: '#DBEAFE', deep: '#1D4ED8' },
},
fontFamily: {
display: ['Inter Tight', 'Inter', 'system-ui', 'sans-serif'],
sans: ['Inter', 'system-ui', 'sans-serif'],
mono: ['JetBrains Mono', 'ui-monospace', 'monospace'],
},
borderRadius: {
xs: '4px', sm: '10px', md: '16px', lg: '24px', pill: '9999px',
},
transitionTimingFunction: {
'paperclip-out': 'cubic-bezier(0.2,0.8,0.2,1)',
'paperclip-in': 'cubic-bezier(0.4,0,1,0.6)',
'paperclip-inout': 'cubic-bezier(0.65,0,0.35,1)',
},
},
},
} satisfies Config
Neutral ramp, status, and radius for Figma and token pipelines. Not a full export of motion, spacing, or the agent palette — extend as needed.
{
"color": {
"neutral": {
"bond": { "value": "#FFFFFF" },
"linen": { "value": "#F5F3F0" },
"parchment": { "value": "#F0ECE7" },
"manila": { "value": "#F3E6C4" },
"vellum": { "value": "#E0DCD6" },
"steel": { "value": "#D8DCDF" },
"aluminum": { "value": "#A8AEB2" },
"graphite": { "value": "#52585D" },
"charcoal": { "value": "#141413" },
"ink": { "value": "#0A0A0A" }
},
"accent": { "signal": { "value": "#22C55E" } },
"status": {
"success": { "value": "#22C55E" },
"warning": { "value": "#F59E0B" },
"error": { "value": "#DC2626" },
"info": { "value": "#2563EB" }
}
},
"radius": {
"xs": { "value": "4px" },
"sm": { "value": "10px" },
"md": { "value": "16px" },
"lg": { "value": "24px" },
"pill": { "value": "9999px" }
}
}