Signal
Warm black bands, bold white Inter and one lime button, with a caret blinking after the headline.
- Dark by default
- 35 colours · 14 type steps
- Inspired by clickhouse.com
The same generated app in every design. Scroll inside the window to see the whole page.
What it is
Signal is a dark system for developer tools: a warm near-black canvas, one electric lime and big white headlines in Inter Bold. The page is built from wide bands that start black on the left and warm to olive charcoal on the right, split by 1px iron seams. Surfaces step up in tone (void, carbon, graphite) instead of casting shadows. Lime is rationed to the primary button, the eyebrows, the focus ring and a caret that blinks after the hero headline. The light theme turns the night into ink: black buttons with lime labels on warm paper.
Maintained by @agentic-studio in the open registry.
Best for
Developer tools, databases, APIs and infrastructure products that sell on speed and precision. It suits teams with a sharp one-line promise and a product screen that can carry the page.
Trade-offs
- Lime only works when it is rare. A second lime button or a lime band in the same view flattens the whole page.
- Headlines at 96px need short copy. A headline over 45 characters wraps to four lines on a phone and turns into a wall.
- Dark is the real Signal. The light theme keeps the identity (black buttons with lime labels, a lime highlighter, the paper bands), but it reads calmer and less electric.
Tokens
Generated from this design’s design.yaml, and shipped as CSS variables plus a Tailwind theme. Templates may use these names and nothing else.
Colours
Every colour token in design.yaml, grouped the way the system documents them. These are the dark palette's values. The light palette uses the same names with its own values, and tokens.css ships both.
Brand and accent
accent
#faff69
accent-1
#faff69
accent-2
#5cc8f2
accent-3
#ff7575
accent-4
#a88bff
accent-5
#f5a524
accent-6
#bcbcbb
accent-hover
#fbff46
accent-soft
#2a2b08
primary
#faff69
Surface
canvas
#151515
hairline
#3a3a3a
surface-card
#282826
surface-dark
#0e0e0e
surface-dark-elevated
#1f1f1c
surface-soft
#1a1a18
surface-solid
#282828
surface-strong
#343434
Text
body
#bcbcbb
body-strong
#dfdfdf
ink
#ffffff
muted
#a0a0a0
muted-soft
#808080
on-accent
#151515
on-dark
#ffffff
on-primary
#151515
Semantic
error
#ff7575
success
#5cd68d
warning
#ffb547
Other
danger
#ff7575
danger-soft
#2e1717
error-soft
#2e1717
primary-hover
#fbff46
success-soft
#13261a
warning-soft
#2c2210
Type scale
Each token rendered at its real size, weight, line height and tracking. Specimens fall back to this site's typeface when the design's own face is not installed locally, so read the numbers, not the letterforms.
Ship faster
- Token
- display-xl
- Values
- 6rem · 96px · 700 · lh 1 · ls 0
Ship faster
- Token
- display-lg
- Values
- 4.5rem · 72px · 700 · lh 1 · ls 0
Ship faster
- Token
- display-md
- Values
- 3rem · 48px · 700 · lh 1.1 · ls -0.01em
Ship faster
- Token
- display-sm
- Values
- 2.25rem · 36px · 600 · lh 1.2 · ls -0.005em
Ship faster
- Token
- title-lg
- Values
- 1.5rem · 24px · 700 · lh 1.33 · ls 0
Ship faster
- Token
- title-md
- Values
- 1.25rem · 20px · 600 · lh 1.4 · ls 0
Ship faster
- Token
- body-lg
- Values
- 1.125rem · 18px · 400 · lh 1.55 · ls 0
Ship faster
- Token
- body-md
- Values
- 1rem · 16px · 400 · lh 1.5 · ls 0
Ship faster
- Token
- title-sm
- Values
- 1rem · 16px · 600 · lh 1.4 · ls 0
Ship faster
- Token
- body-sm
- Values
- 0.875rem · 14px · 400 · lh 1.45 · ls 0
Ship faster
- Token
- button
- Values
- 0.875rem · 14px · 600 · lh 1 · ls 0
SHIP FASTER
- Token
- caption-uppercase
- Values
- 0.875rem · 14px · 600 · lh 1.4 · ls 0.1em
Ship faster
- Token
- nav-link
- Values
- 0.875rem · 14px · 500 · lh 1.4 · ls 0
Ship faster
- Token
- caption
- Values
- 0.75rem · 12px · 500 · lh 1.5 · ls 0
Typefaces
The families the generated Tailwind theme points at. A licensed face is named here even when the substitute below is what actually renders.
- DisplayInter, ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif
- BodyInter, ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif
- MonoInconsolata, ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace
Spacing scale
Drawn at true size. These are the only gaps and paddings a generated repo is allowed to use.
- xxs0.25rem · 4px
- xs0.5rem · 8px
- sm0.75rem · 12px
- md1rem · 16px
- lg1.5rem · 24px
- xl2rem · 32px
- xxl4rem · 64px
- section5rem · 80px
Radius scale
Sample shapes at true corner radius. Buttons and inputs sit at the small end of this scale, feature cards at the large end.
- xs0.125rem · 2px
- sm0.25rem · 4px
- md0.375rem · 6px
- lg0.5rem · 8px
- xl0.75rem · 12px
- full9999px
- pill9999px
Elevation
Shadow tokens on a neutral card, at true blur and spread.
- insetinset 0 4px 25px 0 rgb(0 0 0 / 0.14)
- lift0 24px 48px -16px rgb(0 0 0 / 0.65)
- overlay0 16px 40px -8px rgb(0 0 0 / 0.7), 0 0 0 1px rgb(0 0 0 / 0.35)
- ring0 0 0 3px rgb(250 255 105 / 0.25)
- soft0 0 #0000
- xs0 0 #0000
DESIGN.md
Ships in your repo as DESIGN.md. The designer agent reads it before it may introduce a new visual pattern. This is the briefing, not a page about the briefing.
Signal is a phosphor terminal at midnight: one lime caret glowing on warm black glass. Wide bands run from black on the left to olive charcoal on the right, headlines are big white Inter Bold, and one electric lime marks the primary button, the eyebrows, the focus ring and a caret that blinks after the hero headline. Surfaces step up in tone instead of casting shadows.
Read this before you add a screen, a component or a colour. The tokens live in
src/app/globals.css, the faces in src/app/fonts.ts, the kit in
src/components/ui/.
At a glance
| Theme | Dark native on a #151515 void. Light is ink on warm paper (#f7f7f3): black buttons with lime labels. |
| Type | Inter for display and body (headlines 700 with no tracking, titles 600). Inconsolata 600 for code, keys and ids only. |
| Colour | Warm near-black greys, one lime (#faff69) with one fill per view, olive (#4f5100) edges, coral for danger. |
| Shape | Crisp: 4px controls, 8px cards and dialogs, 12px on the product window only, pills for badges, avatars and switches. |
| Depth | Tone, not blur: canvas, carbon, graphite, slate. Real shadows only on the product window, the featured price card and overlays. |
| Signature | A blinking lime caret after the hero headline, on a black band that stops on a 1px seam above a warmer lift. |
Principles
- One lime fill per view: the primary button. Every other lime is text, a 1px line, a dot or the caret.
- Step surfaces by tone before you reach for a shadow.
- Two band materials, both left to right: the band and the lift. Everything else is flat canvas.
- Inter everywhere. A switch to mono always means developer content.
- Crisp radii and 1px solid lines, never dashed and never doubled.
Colour
Palette
| Token | Light | Dark | Role |
|---|---|---|---|
canvas (--background) | #f7f7f3 | #151515 | The page floor |
surface-soft | #f1f1ec | #1a1a18 | Section bands, sidebars, table heads |
surface-card (--muted) | #efefe9 | #282826 | Tinted fills: inactive tabs, hover rows, code |
surface-strong | #e3e3dc | #343434 | Pressed fills, progress tracks |
surface-solid (--popover) | #ffffff | #282828 | Menus, selects, toasts: always opaque |
card | #ffffff | #1f1f1c | The card fill |
surface-dark | #151515 | #0e0e0e | The inverted panel |
hairline (--border) | #dcdcd4 | #3a3a3a | Every border and divider |
ink (--foreground) | #151515 | #ffffff | Headings and primary text |
body-strong | #282828 | #dfdfdf | Emphasised body text |
body | #3f3f3c | #bcbcbb | Running text |
muted (--muted-foreground) | #62625d | #a0a0a0 | Secondary text, captions |
muted-soft | #8a8a83 | #808080 | Placeholders, disabled text, icons at rest |
primary | #151515 | #faff69 | The action colour |
accent (--accent-fill) | #4f5100 | #faff69 | The saturated accent: links, the accent badge |
accent-soft | #eff4b8 | #2a2b08 | The tint an accent label sits on |
danger (--destructive) | #b8302a | #ff7575 | Destructive actions and errors |
success, warning and error each come with a -soft tint for the back of a
badge or an alert: #1a7039, #8f5a00 and #b8302a in light, #5cd68d, #ffb547 and
#ff7575 in dark.
Signal's own variables, read by the landing hooks and the kit: --band-from
(#fbfbf8 light, #101010 dark), --band-to (#eceedb light, #24251f dark),
--lift-from (#f1f1ec light, #202020 dark), --lift-to (#e4e6d0 light, #30312c
dark), --highlight (#f2f84a light, #faff69 dark), --glow (rgb(200 208 0 /
0.28) light, rgb(251 255 70 / 0.35) dark), --olive (#8a8e2a light, #4f5100
dark).
How colour is used
- Lime (
text-accent, dark olive in light) marks eyebrows, links, focus rings, selected checks and the caret. Its only fill is the primary button. - Olive (
--olive) is the edge colour: outline buttons, the accent badge, feature icon tiles, step markers and the open FAQ chevron. - Text steps from white headlines to bone (#dfdfdf) strong body, fog (#bcbcbb) body and smoke (#a0a0a0) muted copy.
- Green, amber and coral mark status only, as soft tints with a coloured icon or dot.
- Selected text and
<mark>are a lime highlighter pen with near-black text.
Charts
accent-1 to accent-6 (also chart-1 to chart-6) are six series colours
ordered so neighbours stay distinguishable. Six series lead with lime, then sky,
coral, violet, amber and fog in dark (olive, cyan, coral, violet, amber and grey
in light). Every pair stays apart under common colour blindness, and every light
series holds 3.2:1 on the canvas. Assign them in order; never let colour be the
only way to tell two series apart.
Dark mode
The palette is declared twice in src/app/globals.css: light on :root, dark
under @media (prefers-color-scheme: dark) and again on .dark, where the
class wins in both directions. @theme inline points every utility at those
variables, so bg-canvas is one class that follows the mode.
src/lib/design.ts sets the theme a first visit opens in: dark here, because
Signal is drawn in dark first. The theme menu in the header offers light, dark
and system and remembers the choice.
Type
Faces
- Inter (
font-display,font-body): headings and display type; running text and interface copy. - Inconsolata (
font-mono): code, ids and tabular labels.
Inter Bold in its text cut sets sturdy, open headlines, and the same family carries the body, so the page has one voice. Inconsolata is narrow and a little humanist: code, keys and ids read as a terminal line without looking like an editor.
Every face loads through next/font/google in src/app/fonts.ts: downloaded at
build time and served from this app. Change a face there and here, together.
Scale
| Token | Size | Line | Tracking | Weight | Use |
|---|---|---|---|---|---|
text-display-xl | 96px | 1 | 0 | 700 | The hero headline, desktop |
text-display-lg | 72px | 1 | 0 | 700 | The hero headline, tablet |
text-display-md | 48px | 1.1 | -0.01em | 700 | Section headlines, the hero on phones |
text-display-sm | 36px | 1.2 | -0.005em | 600 | Section headlines on phones, big numbers |
text-title-lg | 24px | 1.33 | 0 | 700 | Page titles in the app |
text-title-md | 20px | 1.4 | 0 | 600 | Card titles |
text-title-sm | 16px | 1.4 | 0 | 600 | Small headings, table titles |
text-body-lg | 18px | 1.55 | 0 | 400 | Lead paragraphs |
text-body-md | 16px | 1.5 | 0 | 400 | Running text |
text-body-sm | 14px | 1.45 | 0 | 400 | Interface copy, table cells |
text-caption | 12px | 1.5 | 0 | 500 | Metadata, helper text |
text-caption-uppercase | 14px | 1.4 | 0.1em | 600 | Eyebrows above headings |
text-button | 14px | 1 | 0 | 600 | Buttons |
text-nav-link | 14px | 1.4 | 0 | 500 | Header and footer links |
Rules: one h1 per page. Display sizes are for marketing pages; the app tops
out at text-title-lg. Headlines are Inter 700 with open spacing: 96px in the
hero, 72px and 48px below it, line height 1 to 1.1. Titles are Inter 600 from 16
to 36px; body runs 14 to 18px. Eyebrows are lime caps at 14px, 600 and 0.1em,
with nothing in front of them.
Space and layout
- Spacing tokens:
xxs4px,xs8px,sm12px,md16px,lg24px,xl32px,xxl64px,section80px (the gap between landing sections). - Content sits in
max-w-content(1280px) withpx-mdon phones andpx-lgfromsmup. Reading text stops atmax-w-measure(672px). - Spacing steps are 4, 8, 12, 16, 24, 32 and 64px, with 80px between sections.
- Density is comfortable: cards pad 24 to 32px and elements sit 12 to 16px apart.
- Vertical air is generous, because the dark canvas has no tonal break to rest the eye.
Shape and depth
| Token | Value | Where |
|---|---|---|
rounded-xs | 2px | Breadcrumb, Checkbox, DropdownMenu, Kbd, Select, Tooltip |
rounded-sm | 4px | Accordion, Button, Dialog, Input, Sheet, Skeleton, Tabs, Toaster, the landing page |
rounded-md | 6px | Alert, DropdownMenu, Popover, Select, Tabs, Toaster, the landing page |
rounded-lg | 8px | AlertDialog, Card, Dialog, Table, the landing page |
rounded-xl | 12px | The landing page |
rounded-pill | 9999px | Badge, Progress, Switch, the landing page |
rounded-full | 9999px | Accordion, Avatar, RadioGroup, Spinner, Switch |
Radii are 2px on checkboxes, keys and menu items, 4px on buttons and inputs, 6px on menus and alerts, 8px on cards and dialogs and 12px on the product window only. Borders are 1px solid: iron on cards and rows, steel on inputs, grey on checkboxes and radios, olive on outline buttons. Only a key adds a 2px bottom edge. Elevation is tone; cards carry an inset shade and never a drop shadow. Real shadows sit only under the product window, the featured price card and overlays.
Components
Every component lives in src/components/ui/ and is written against the tokens
above. Import from there; never restyle a kit component inline to make a
one-off.
| Component | In Signal |
|---|---|
Button | 4px corners, Inter 600 at 14px, sentence case, flat at rest. Primary is lime with a black label (black with a lime label in light), a soft 3px halo on hover and a 1px press; outline is transparent with an olive edge that turns lime on hover; secondary is graphite with a hairline; ghost lifts one tone on hover; danger is coral with a black label. Every kind shows the focus ring with a 2px gap and fades to 40% when disabled. Large is 48px tall with 32px sides and a 16px label. |
Badge | A pill with a 1px border and a 12px label. Accent is the olive pill with lime text (pale lime with olive text in light); neutral is graphite; status badges are soft tints led by a 6px dot. |
Card | 8px corners, a 1px iron hairline, a carbon fill with an inset shade, no drop shadow and no hover lift. Soft, strong, outline and dark variants step the tone; titles are 20px 600. |
Input, Textarea, Select | 40px wells on the canvas with a steel line and 4px corners, so they read darker than the card around them. Focus turns the line lime with a 3px lime halo (olive in light). Select content is graphite with 6px corners and a lime check on the chosen item. |
Checkbox, RadioGroup, Switch | Checkboxes and radios sit on the canvas with a grey line that holds 3:1; the switch is a slate track with a steel line and a grey thumb. On, the checkbox is a lime box with a black tick, the radio a lime ring around a lime dot and the switch a lime track with a black thumb (black with lime in light). Focus adds the ring with a 2px gap. No glow. |
Tabs | Default tabs sit in a graphite track; the active tab is a dark well with a hairline. Line tabs mark the active tab with a 2px lime underline, the caret laid flat. |
Accordion | Rows split by iron hairlines, white semibold triggers, and a chevron in a 24px hairline circle that turns lime with an olive edge when open. |
Dialog, AlertDialog, Sheet | Graphite panels with a hairline, 8px corners and an overlay shadow over a dark scrim with a 2px blur. Alert dialogs pair an olive outline cancel with a primary or danger action. Sheets are carbon and flush to the edge. |
DropdownMenu, Popover, Select content, Tooltip | Graphite, a hairline, 6px corners and an overlay shadow. Items are 32px with 2px corners and highlight to slate, group labels are 12px caps, checks are lime and shortcuts are Inconsolata. Tooltips are a lime highlight with black text (black with lime in light). |
Table | A hairline wrapper with 8px corners, a soft header row in 12px caps, hairline rows that lift one tone on hover, and tabular numbers. Ids go in code, which sets them in Inconsolata. Selected rows take the olive tint. |
Alert | 6px corners and a 1px border. Info is an olive tint with an olive edge and a lime icon; success, warning and danger are soft tints with a status border at 35%. |
Avatar, Progress, Skeleton, Spinner, Separator, Kbd, Breadcrumb, Pagination, Field, Label, Toaster | Avatars are circles with a hairline ring and bone initials on slate. Progress is a 6px pill with a lime fill. Skeletons pulse on slate, and spinners are thin rings whose lead arc takes the text colour, so they still read inside a lime button. Separators are 1px hairlines. Kbd is Inconsolata on graphite with a 2px bottom edge. Breadcrumbs split with a thin slanted slash, like a path; the current page in pagination is the outline square on the olive tint with accent text. Labels are 14px 500 in bone; field errors are 12px semibold coral. Toasts are graphite and show status only in the icon. |
The landing page
The landing page is the same in every design; the design decides how it looks.
Its sections carry data-slot hooks (listed at the top of
src/components/marketing/section-heading.tsx) that globals.css may style.
Signal styles these:
hero: wears the lift, a second sheet one tone up, and closes on a hairline unless the logo strip follows.hero-backdrop: paints the band from the top to 11rem above the hero's bottom and ends on a 1px iron seam that crosses the product window. No grid, dots or blobs.hero-title: white Inter Bold with balanced lines, ending in a blinking lime caret with a lime bloom (ink in light). Reduced motion keeps it lit.hero-eyebrow: an olive pill with lime text; a linked eyebrow warms its edge to lime on hover.hero-subtitle: 18 to 24px regular in white, not a grey lead.sectionlogos: carries the lift on under the seam and closes it with a hairline; its title turns lime and eachlogois a bone Inter Bold wordmark.section-title: balances its lines.stat-gridandstat-value: an 8px grid with Inter Bold tabular numbers.sectionhow-it-works and soft sections: wear the lift, so every band is one of two sheets.step-marker: olive-edged squares with lime Inter Bold numbers and no fill.feature-icon: 56px olive-edged squares with 28px lime line icons; a hoveredfeature-cardwarms its hairline to olive.product-preview: a void terminal with 12px corners and the lift shadow;product-preview-barturns its first dot into a lime signal light and its address field into a command line with a lime$prompt.showcase-visual: each stage takes the band at 8px corners.cta-panel: the band inside, no drop shadow, and a 1px lime line across the top that fades out at both ends.faq: no lines between questions, 18px questions with 20px of air, a hairline circle chevron that turns lime when open, smoke answers.site-header: rides the band at 88% with a 60% hairline;site-navlinks are white and the current page gets a 2px lime underline.brand-mark: an 800 letter with a soft lime bloom.site-footer: the band again as a bookend to the hero, with smoke column titles.
Everything else is type, space and the kit.
Signed-in screens
The dashboard sits on the canvas with a soft sidebar whose active item is an olive tint with lime text and a 2px lime bar; stat tiles are carbon cards with Inter Bold numbers and charts lead with lime.
Sign-in is one 400px carbon card centred on the canvas, with dark input wells, a full-width lime primary and lime text links.
Do and don't
Do
- Keep one lime fill per view: the primary button. Every other lime is text, a 1px line, a status dot or the caret.
- Write hero headlines of 45 characters or less, so 96px Inter Bold sets them in two or three lines.
- Step surfaces by tone (canvas #151515, card #1f1f1c, graphite #282828, slate #343434) before you reach for a shadow.
- Give every outline button the olive edge (
border-(--olive)). It is the second button's whole personality. - Set eyebrows in lime caps: 14px, weight 600, 0.1em tracking, nothing in front of them.
- Keep radii crisp: 4px on controls, 8px on cards and dialogs, 12px on the product window only.
- Use Inconsolata only for code, keys, ids and the
$prompt. - Check light mode every time: there, lime lives inside black (black buttons with lime labels, the black brand mark, the lime highlighter).
Don't
- Don't add a second accent hue. Status colours mark status; charts are the one place six hues meet.
- Don't write lime as a text colour by hand.
text-accentis lime in dark and olive in light; hard-coded lime disappears on paper. - Don't round cards or buttons past 8px, and never make a button a pill.
- Don't glow anything except the caret, the brand mark, the lime dot in the product window and the primary button's hover halo.
- Don't put drop shadows on cards. A 1px iron hairline and the inset shade are the whole elevation.
- Don't set body copy under 14px or over 18px. The hero subtitle (up to 24px) is the only exception.
- Don't add grids, dot patterns, noise or radial blobs. The only backdrops are the two left-to-right bands.
- Don't set eyebrows, buttons, nav links or step numbers in mono, and don't push display type past 700.
Working in this design
Pasting from shadcn/ui. The token layer carries shadcn's variable names, so
most snippets render unmodified. Two utility names mean something else here:
bg-muted becomes bg-surface-card, and bg-accent / text-accent-foreground
(a hover surface upstream) become bg-surface-card / text-ink. Here muted
is a text colour and accent is the saturated accent.
Adding a token. Add it to all three palette blocks in globals.css (light,
the dark media query, .dark), map it in @theme inline, and document it in
the palette table above. Check contrast in both modes.
Adding a component. Check the kit first: most needs are a variant of
Button, Card or Badge, or a composition on the page. A new component gets
its own file in src/components/ui/, token classes only, a data-slot, and a
row in the Components table here. The designer subagent owns this.
Build a repo in Signal
The builder opens with Signal picked. Pick your batteries and the design is applied to every template before the zip is built.
