Skip to content

Pulse

Cream type on a midnight console, an ember and mint pill pair, and a six hue waveform under the hero.

  • Dark by default
  • 35 colours · 14 type steps
  • Inspired by vapi.ai
Use Pulse
localhost:3000

The same generated app in every design. Scroll inside the window to see the whole page.

What it is

Pulse is a dark console system for voice, audio and developer products. Headlines whisper in Hanken Grotesk at weight 300 on a near-black void, and every label speaks in Geist Mono caps. Buttons are full pills, ember for the main action and mint for the second one, while cards, inputs and menus keep a near-sharp 5.6px corner and a 1px hairline instead of a shadow. All the colour lives in one signature: a waveform of stacked dashes in six hues that rises behind the product window. The light theme turns the page to cream paper with void ink and keeps the same pills, labels and waveform.

Maintained by @agentic-studio in the open registry.

Best for

Voice, audio, AI and API products sold to developers, where a console feel builds trust and a waveform tells the story at a glance. It also suits dev tools and infrastructure dashboards that want a calm dark UI with one clear call to action.

Trade-offs

  • Weight 300 headlines need short copy and big sizes. Below 40px they turn thin, so on small screens the mono labels carry the structure.
  • Colour is rationed. Ember marks the one action and mint marks live state, so a brand that wants its colour on every screen will feel held back.
  • Mono caps on buttons, nav, badges, tabs and table heads read as a console. That suits technical buyers, but long labels in caps are slower to read and can feel cold in a consumer product.

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

    #d9e6ef

  • accent-1

    #62f6b5

  • accent-2

    #de94e2

  • accent-3

    #e96b34

  • accent-4

    #9977ff

  • accent-5

    #ffdd03

  • accent-6

    #4dcafa

  • accent-hover

    #edf4f9

  • accent-soft

    #172029

  • primary

    #e96b34

Surface

  • canvas

    #0e0e13

  • hairline

    #27272a

  • surface-card

    #18181b

  • surface-dark

    #060608

  • surface-dark-elevated

    #18181b

  • surface-soft

    #09090b

  • surface-solid

    #18181b

  • surface-strong

    #27272a

Text

  • body

    #d8d7d4

  • body-strong

    #f4f4f5

  • ink

    #fffaea

  • muted

    #a1a1aa

  • muted-soft

    #71717a

  • on-accent

    #0e0e13

  • on-dark

    #fffaea

  • on-primary

    #09090b

Semantic

  • error

    #ff6b81

  • success

    #62f6b5

  • warning

    #f5c542

Other

  • danger

    #ff6b81

  • danger-soft

    #2d1219

  • error-soft

    #2d1219

  • primary-hover

    #f27a43

  • success-soft

    #0f2a21

  • warning-soft

    #2b2310

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
    5.5rem · 88px · 300 · lh 1 · ls -0.035em
  • Ship faster

    Token
    display-lg
    Values
    4.25rem · 68px · 300 · lh 1.03 · ls -0.032em
  • Ship faster

    Token
    display-md
    Values
    3.5rem · 56px · 300 · lh 1.07 · ls -0.028em
  • Ship faster

    Token
    display-sm
    Values
    2.5rem · 40px · 300 · lh 1.12 · ls -0.022em
  • Ship faster

    Token
    title-lg
    Values
    1.5rem · 24px · 400 · lh 1.3 · ls -0.012em
  • Ship faster

    Token
    body-lg
    Values
    1.125rem · 18px · 400 · lh 1.55 · ls 0
  • Ship faster

    Token
    title-md
    Values
    1.125rem · 18px · 500 · lh 1.4 · ls -0.005em
  • Ship faster

    Token
    body-md
    Values
    1rem · 16px · 400 · lh 1.6 · ls 0
  • Ship faster

    Token
    title-sm
    Values
    1rem · 16px · 500 · lh 1.45 · ls 0
  • Ship faster

    Token
    body-sm
    Values
    0.9375rem · 15px · 400 · lh 1.55 · ls 0
  • Ship faster

    Token
    button
    Values
    0.8125rem · 13px · 500 · lh 1 · ls 0.08em
  • Ship faster

    Token
    caption
    Values
    0.8125rem · 13px · 400 · lh 1.45 · ls 0
  • SHIP FASTER

    Token
    caption-uppercase
    Values
    0.75rem · 12px · 500 · lh 1.5 · ls 0.08em
  • Ship faster

    Token
    nav-link
    Values
    0.75rem · 12px · 400 · lh 1.5 · ls 0.08em

Typefaces

The families the generated Tailwind theme points at. A licensed face is named here even when the substitute below is what actually renders.

  • DisplayHanken Grotesk, ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif
  • BodyHanken Grotesk, ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif
  • MonoGeist Mono, 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
  • xxl3rem · 48px
  • 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
  • lg0.35rem · 6px
  • md0.35rem · 6px
  • xl0.5rem · 8px
  • full9999px
  • pill9999px

Elevation

Shadow tokens on a neutral card, at true blur and spread.

  • inset0 0 #0000
  • lift0 0 #0000
  • overlay0 24px 48px -16px rgb(0 0 0 / 0.8)
  • ring0 0 0 3px rgb(98 246 181 / 0.22)
  • 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.

Pulse is a quiet midnight console where one six hue waveform does all the talking. Headlines whisper in Hanken Grotesk at weight 300 on a near-black void, and every label speaks in Geist Mono caps. Buttons are full pills, ember for the main action and mint for the second one, while cards, inputs and menus keep a near-sharp 5.6px corner and a 1px hairline instead of a shadow.

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

ThemeDark native on a #0e0e13 void. Light is cream paper (#fffaea) with void ink and the same pills, labels and waveform.
TypeHanken Grotesk for display and body (headlines 300 with tight tracking, titles 400 to 500). Geist Mono caps at 12 to 13px with +0.08em for every console label.
ColourCream, bone and pearl text on void, carbon and slab greys. Ember (#e96b34) for the one primary action, mint (#62f6b5) for the second action and for live state, ice for links and eyebrows, six hues for data only.
ShapeNear-sharp containers, round actions: 5.6px on cards, inputs, menus and badges, 8px on the four big frames, full pills on every button, switch and avatar.
DepthShadowless. Tone steps (void page, carbon cards and fields, slab chips and menus) plus a 1px hairline. Only overlays cast a shadow.
SignatureA static waveform of rounded dashes in six hues that rises from the hero floor behind the product window, on a faint 16px dot grid.

Principles

  1. One ember fill per view: the primary action. Mint is its partner pill and the mark for live state.
  2. Colour lives in the waveform and the data. Everything else is cream, greys and hairlines.
  3. Headlines whisper: Hanken Grotesk 300, big sizes, short copy.
  4. Mono caps mean console label. Keep them short and never use them for headings or paragraphs.
  5. Separate by tone and a 1px hairline, never by a shadow or a tinted band.

Colour

Palette

TokenLightDarkRole
canvas (--background)#fffaea#0e0e13The page floor
surface-soft#f8f2de#09090bSection bands, sidebars, table heads
surface-card (--muted)#f4eedb#18181bTinted fills: inactive tabs, hover rows, code
surface-strong#ebe3cb#27272aPressed fills, progress tracks
surface-solid (--popover)#ffffff#18181bMenus, selects, toasts: always opaque
card#fffdf6#09090bThe card fill
surface-dark#0e0e13#060608The inverted panel
hairline (--border)#e5ddc7#27272aEvery border and divider
ink (--foreground)#0e0e13#fffaeaHeadings and primary text
body-strong#27272a#f4f4f5Emphasised body text
body#3f3f46#d8d7d4Running text
muted (--muted-foreground)#5c5c66#a1a1aaSecondary text, captions
muted-soft#85858d#71717aPlaceholders, disabled text, icons at rest
primary#e96b34#e96b34The action colour
accent (--accent-fill)#2d5068#d9e6efThe saturated accent: links, the accent badge
accent-soft#e1ebf0#172029The tint an accent label sits on
danger (--destructive)#c42b45#ff6b81Destructive actions and errors

success, warning and error each come with a -soft tint for the back of a badge or an alert: #087a51, #8f5a00 and #c42b45 in light, #62f6b5, #f5c542 and #ff6b81 in dark.

Pulse's own variables, read by the landing hooks and the kit: --grid-dot (rgb(14 14 19 / 0.14) light, rgb(255 250 234 / 0.1) dark), --secondary-hover (#4ee8a4 light, #8af9c9 dark), --pulse (#087a51 light, #62f6b5 dark).

How colour is used

  • Ember (bg-primary) is the one primary button per view, with a carbon label. It is never text and never a band.
  • Mint (--secondary) is the second call to action, always beside ember. As --pulse and --ring it marks live or current state: focus, a switch that is on, the current page, success and the eyebrow dot matrix.
  • Ice (text-accent, slate ice on cream) marks links, eyebrows and check icons.
  • Cream is content: checked boxes, radios, progress and the active tab are ink, not colour.
  • The six hues belong to data: the waveform, chart series, feature icons and topic dots. Never on a button, a badge or a heading.

Charts

accent-1 to accent-6 (also chart-1 to chart-6) are six series colours ordered so neighbours stay distinguishable. Six series in order: mint, pink, ember, violet, yellow, blue, with deeper versions on cream. Neighbours stay apart under common colour blindness; light series hold 3:1 or better on every light surface and dark ones 5.4:1 or better on every dark surface. 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 Pulse is drawn in dark first. The theme menu in the header offers light, dark and system and remembers the choice.

Type

Faces

  • Hanken Grotesk (font-display, font-body): headings and display type; running text and interface copy.
  • Geist Mono (font-mono): code, ids and tabular labels.

Hanken Grotesk is a round, open grotesque that stays calm at weight 300 and big sizes, and the same family sets the text, so the page has one voice. Geist Mono is the console label face: buttons, nav, eyebrows, badges, tabs and table heads in caps, plus code and ids.

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

TokenSizeLineTrackingWeightUse
text-display-xl88px1-0.035em300The hero headline, desktop
text-display-lg68px1.03-0.032em300The hero headline, tablet
text-display-md56px1.07-0.028em300Section headlines, the hero on phones
text-display-sm40px1.12-0.022em300Section headlines on phones, big numbers
text-title-lg24px1.3-0.012em400Page titles in the app
text-title-md18px1.4-0.005em500Card titles
text-title-sm16px1.450500Small headings, table titles
text-body-lg18px1.550400Lead paragraphs
text-body-md16px1.60400Running text
text-body-sm15px1.550400Interface copy, table cells
text-caption13px1.450400Metadata, helper text
text-caption-uppercase12px1.50.08em500Eyebrows above headings
text-button13px10.08em500Buttons
text-nav-link12px1.50.08em400Header and footer links

Rules: one h1 per page. Display sizes are for marketing pages; the app tops out at text-title-lg. Display steps run from 40 to 88px in Hanken Grotesk 300, tracked from -0.022em to -0.035em, and the hero pulls its word spacing in too. Titles are 400 to 500 from 16 to 24px and reading text is 15 to 18px, never smaller. Console labels are Geist Mono caps at 12 or 13px with +0.08em.

Space and layout

  • Spacing tokens: xxs 4px, xs 8px, sm 12px, md 16px, lg 24px, xl 32px, xxl 48px, section 80px (the gap between landing sections).
  • Content sits in max-w-content (1280px) with px-md on phones and px-lg from sm up. Reading text stops at max-w-measure (672px).
  • Spacing steps are 4, 8, 12, 16, 24, 32 and 48px, with 80px between sections.
  • Density is comfortable: cards pad 24px, elements sit 8px apart and fields stack 24px apart.
  • Rhythm comes from air plus one full width hairline at the top of each section, never from tinted bands.

Shape and depth

TokenValueWhere
rounded-xs2pxBreadcrumb, Checkbox, Kbd
rounded-sm4pxAccordion, DropdownMenu, Select, Skeleton, Tabs, Tooltip, the landing page
rounded-md5.6pxAlert, Badge, DropdownMenu, Input, Popover, Select, Tabs, Toaster, the landing page
rounded-lg5.6pxAlertDialog, Card, Dialog, Table, the landing page
rounded-xl8pxThe landing page
rounded-pill9999pxBadge, Button, Dialog, Progress, Sheet, Switch, Toaster, the landing page
rounded-full9999pxAvatar, RadioGroup, Switch

Containers are near-sharp and actions are round: 2px on checkboxes and keys, 4px on menu items and tooltips, 5.6px on inputs, badges, cards, menus and dialogs, 8px on the product window, showcase stages, stat grid and CTA panel, and full pills on buttons, switches, avatars and the eyebrow chip. Borders are always 1px solid: iron on cards and rules, steel on inputs and outline buttons. Nothing casts a shadow except menus, selects, popovers, dialogs, sheets and toasts.

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.

ComponentIn Pulse
ButtonA full pill in Geist Mono 500 caps with +0.08em tracking, flat, with no border on filled kinds. Primary is ember with a carbon label; secondary is the mint pill; outline is a steel line with an ink label; ghost fills a faint ink tint on hover; danger is rose with a carbon label (crimson with cream in light). Filled kinds press in to 98%. Sizes are 32, 40 and 48px tall with 12, 13 and 14px labels, and disabled drops to 40%. Link is the only sentence case kind, in ice Hanken 15px. Focus is a mint ring with a canvas gap.
Badge5.6px corners, a 1px border, 20px tall, Geist Mono 12px in sentence case. Neutral is the slab chip with a hairline, accent is ice on a cool tint, and success, warning and danger are soft tints with no line, led by a 6px dot. Uppercase mode switches to mono caps. Never ember, mint or a spectrum hue.
Card5.6px corners, a 1px iron hairline and a carbon fill one step deeper than the void page (warm white on cream), with no shadow and no hover lift. Soft, strong, outline and dark variants step the tone, and the dark card keeps an edge on a dark page; titles are Hanken 18px 500 and padding is 16, 24 or 32px.
Input, Textarea, Select40px carbon wells with a steel line, 5.6px corners and 15px text. Focus turns the edge mint with a 3px mint halo; invalid turns it rose with a rose halo. Textareas start at 96px and the mono option is Geist Mono 14px. The select chevron turns ink when open; its content is slab with a hairline and the overlay shadow, and the chosen item shows a mint check.
Checkbox, RadioGroup, SwitchCheckboxes (2px corners) and radios are carbon with a grey line that holds 3:1; checked is ink, a cream box with a void tick in dark and the reverse on cream. Focus is a mint ring 2px out. The switch is the one control that turns mint when on; off is an iron track with a grey thumb.
TabsMono caps triggers in mercury. The default list is a slab track with a hairline and the active tab is a carbon chip with a hairline; line tabs mark the active tab with a 2px mint underline.
AccordionRows split by iron hairlines, Hanken 16px 500 triggers that turn ice on hover with no underline, a soft grey chevron that flips when open, and 16px pearl answers.
Dialog, AlertDialog, SheetSlab panels with a hairline, 5.6px corners and the overlay shadow over a 70% dark scrim with a 2px blur. Titles are Hanken 24px 400, the close button is a round ghost icon, and footer pills sit on the right 12px apart, primary last. Alert dialogs are narrower and pair an outline cancel with a primary or danger action. Sheets are carbon, flush to the edge, with a hairline under the header.
DropdownMenu, Popover, Select content, TooltipSlab, a hairline, 5.6px corners and the overlay shadow. Items are 36px tall in Hanken 15px and highlight to iron, checks are mint, group labels are mono caps and shortcuts are Geist Mono. The tooltip is the console chip in small: cream with void mono text in dark, the reverse on cream.
TableA hairline frame with 5.6px corners, a carbon head band with mono caps heads, hairline rows that turn slab on hover, and tabular numbers. Selected rows take the ice tint. Right-align numbers and set ids in font-mono.
Alert5.6px corners, a 1px border, 16px padding and an icon. Info is an ice tint with no line and an ice icon; success, warning and danger are soft tints with a status border at 30% and a status icon. Titles are Hanken 15px 500 in ink over pearl text.
Avatar, Progress, Skeleton, Spinner, Separator, Kbd, Breadcrumb, Pagination, Field, Label, ToasterAvatars are circles with a hairline ring and Geist Mono caps initials on iron. Progress is a level meter: an ink bar on an iron track, cut into 10px dashes. Skeletons pulse on a faint ink tint with 4px corners, and the spinner is a plain ring in the current text colour. Separators are 1px hairlines and Kbd is flat Geist Mono caps on slab. Breadcrumbs are a mono caps path split by chevrons. Pagination numbers are 40px mono circles and the current page is the outline circle. Labels are Hanken 15px 500, never mono, and legends are mono caps. Toasts are slab, show status only in the icon and carry small mono caps action pills.

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. Pulse styles these:

  • hero-backdrop: a faint 16px dot grid over the whole hero, with no glow and no wash.
  • hero: ends on a full width hairline, the floor the waveform stands on.
  • hero-eyebrow: the console pill, an inverted cream chip (void on cream) with mono caps inside a hairline ring that lights mint on hover.
  • hero-title: Hanken 300 with the word spacing pulled in, 36px under the pill.
  • hero-actions: the ember and mint pill pair, 56px tall and at least 240px wide from 40rem up; the stack's outline button becomes the mint pill.
  • hero-note: a mono console line under the pair.
  • hero-visual: a static waveform of rounded dashes in six palette hues rises from the hero floor behind the product window, full bleed, faded at both edges and half size on phones.
  • product-preview: a flat carbon console with 8px corners; product-preview-bar turns its dots into short dashes and lights the first one mint.
  • section: every section starts on one full width hairline, with no bottom rules and no tinted bands.
  • logo-cloud and logo: a strip with a mono caps title and equal cells split by vertical hairlines from 64rem up, wordmarks in pearl Hanken 500.
  • section-eyebrow: mono caps in ice, led by a 3 by 3 mint dot matrix; section-title is Hanken 300.
  • feature-card and feature-icon: hairline rows with no fill or corners; each bare 24px icon takes one spectrum hue in order.
  • step-marker: 40px steel rings on the canvas with mono numbers, joined by a dotted line.
  • stat-grid and stat-value: an 8px hairline grid with light tabular numbers over mono caps labels.
  • showcase-visual: an 8px hairline frame over the dot grid, and the digest chart's bars break into stacked dashes.
  • cta-panel: the night in both themes, void with the dot grid, the ember and mint pair, and the waveform at half size along its floor.
  • site-nav: mono caps links in mercury with no fill and a mint dot before the current page; a text ghost button in the header (an auth battery's Sign in) becomes the mint pill.
  • brand-mark: a console disc, cream in dark and void on cream, with a mono initial and a hairline ring; brand sets the name at weight 650.
  • site-footer: mono caps column titles on the carbon footer.

Everything else is type, space and the kit.

Signed-in screens

The dashboard sits on the void with a carbon sidebar split by a hairline, mono caps group labels, carbon stat tiles with Hanken 300 numbers, and charts in the six hues in order.

Sign-in is one 400px carbon card centred on the canvas, with carbon input wells, a mint focus halo, a full width ember pill and outline pills for providers.

Do and don't

Do

  • Pair ember and mint as the two calls to action: ember first, mint beside it, same size, 12px apart.
  • Set every display step in Hanken Grotesk 300 with tight tracking, and keep headlines to about 45 characters so 88px sets in two lines.
  • Put every console label in Geist Mono caps at 12 or 13px with +0.08em: eyebrows, nav links, buttons, uppercase badges, tab triggers, table heads, breadcrumbs and stat labels.
  • Keep containers at 5.6px and actions at a full pill. Only the product window, showcase stages, stat grid and CTA panel go to 8px.
  • Separate surfaces by tone and a 1px hairline: void page, carbon cards and fields, slab chips and menus.
  • Use mint (--pulse) only for live or current state: the focus ring, a switch that is on, the current page, success and the eyebrow dot matrix.
  • Keep the six hues for data: the waveform, chart series in order (mint, pink, ember, violet, yellow, blue), feature icons and topic dots.
  • Write cream (#fffaea) text on dark, never pure white, and check every new screen in the cream light theme too.

Don't

  • Don't add drop shadows to cards, buttons, inputs or the product window. Only menus, dialogs, sheets, popovers and toasts get the overlay shadow.
  • Don't round cards, inputs or menus past 5.6px, and never square off a button.
  • Don't use ember or mint as a text colour, a link colour or a section background.
  • Don't add glows, gradients, aurora washes or noise. Beyond the pill pair, the only colour on the page is the waveform and the data.
  • Don't put a spectrum hue (pink, yellow, violet, blue) on a button, a badge or a heading.
  • Don't set reading text below 15px, and don't track anything except the mono labels.
  • Don't set headings, paragraphs, labels or input text in mono. Mono means console label, so it stays short.
  • Don't animate the waveform or show it more than twice (hero and CTA panel), and don't put a third filled pill next to the pair.

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 Pulse

The builder opens with Pulse picked. Pick your batteries and the design is applied to every template before the zip is built.