Plum
Cream paper, plum ink, one pale lavender button. Ruled in warm hairlines, labelled in mono caps.
- Light by default
- 35 colours · 14 type steps
- Inspired by throxy.com
The same generated app in every design. Scroll inside the window to see the whole page.
What it is
Plum is a warm, ruled system. Paper cream, plum-black ink and white boxes held by a visible warm hairline, with no shadow under anything that stays on the page. The one loud colour is a pale lavender that always carries dark type, and a soft mint only ever means good news. Every small label, from eyebrows and badges to buttons and nav links, is set in mono caps, and corners stay near square. Mid-page, one full-bleed plum-black band flips the palette while the lavender stays exactly the same.
Maintained by @agentic-studio in the open registry.
Best for
B2B products with a lot of structure: sales and outbound tools, CRMs, reporting, back-office screens and data tables. Also any brand that wants to feel calm, printed and precise rather than glossy.
Trade-offs
- Nothing casts a shadow, so every surface leans on its hairline. Drop a border and a white box melts into the cream.
- Mono caps run wide. Keep button and badge labels to two or three words, and never set a sentence in them.
- The pale lavender carries plum-black text only and is too pale for thin lines. Links, checks and progress use a deeper violet, so there are two lavenders to keep straight.
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 light palette's values. The dark palette uses the same names with its own values, and tokens.css ships both.
Brand and accent
accent
#6b4fae
accent-1
#9c70e3
accent-2
#15833e
accent-3
#c2551f
accent-4
#1d5f9e
accent-5
#493c00
accent-6
#9e3a6e
accent-hover
#5a3f9b
accent-soft
#ede5ff
primary
#d2beff
Surface
canvas
#f8f4f0
hairline
#e7e0d7
surface-card
#ffffff
surface-dark
#241f23
surface-dark-elevated
#2e2830
surface-soft
#f3eee7
surface-solid
#ffffff
surface-strong
#ebe4db
Text
body
#554f54
body-strong
#352d33
ink
#241f23
muted
#6a6469
muted-soft
#8a8489
on-accent
#ffffff
on-dark
#f8f4f0
on-primary
#241f23
Semantic
error
#9d3a37
success
#2e6b47
warning
#735b23
Other
danger
#9d3a37
danger-soft
#fdeae7
error-soft
#fdeae7
primary-hover
#c4adff
success-soft
#ddf7e4
warning-soft
#f8eeda
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
- 4rem · 64px · 500 · lh 1.02 · ls -0.03em
Ship faster
- Token
- display-lg
- Values
- 3.5rem · 56px · 500 · lh 1.05 · ls -0.025em
Ship faster
- Token
- display-md
- Values
- 2.5rem · 40px · 500 · lh 1.08 · ls -0.02em
Ship faster
- Token
- display-sm
- Values
- 2rem · 32px · 500 · lh 1.12 · ls -0.015em
Ship faster
- Token
- title-lg
- Values
- 1.5rem · 24px · 500 · lh 1.25 · ls -0.01em
Ship faster
- Token
- body-lg
- Values
- 1.125rem · 18px · 400 · lh 1.55 · ls 0.005em
Ship faster
- Token
- title-md
- Values
- 1.125rem · 18px · 500 · lh 1.35 · ls -0.005em
Ship faster
- Token
- body-md
- Values
- 1rem · 16px · 400 · lh 1.55 · ls 0.01em
Ship faster
- Token
- title-sm
- Values
- 1rem · 16px · 500 · lh 1.4 · ls 0
Ship faster
- Token
- body-sm
- Values
- 0.875rem · 14px · 400 · lh 1.5 · ls 0.01em
Ship faster
- Token
- button
- Values
- 0.8125rem · 13px · 400 · lh 1 · ls 0.04em
Ship faster
- Token
- caption
- Values
- 0.8125rem · 13px · 400 · lh 1.4 · ls 0.01em
Ship faster
- Token
- nav-link
- Values
- 0.8125rem · 13px · 400 · lh 1.3 · ls 0.04em
SHIP FASTER
- Token
- caption-uppercase
- Values
- 0.75rem · 12px · 400 · lh 1.3 · ls 0.06em
Typefaces
The families the generated Tailwind theme points at. A licensed face is named here even when the substitute below is what actually renders.
- DisplayHost Grotesk, ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif
- BodyHost Grotesk, ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif
- MonoFragment 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
- section7rem · 112px
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.3125rem · 5px
- lg0.625rem · 10px
- xl0.75rem · 12px
- full9999px
- pill9999px
Elevation
Shadow tokens on a neutral card, at true blur and spread.
- inset0 0 #0000
- lift0 0 #0000
- overlay0 16px 40px rgb(36 31 35 / 0.14), 0 2px 6px rgb(36 31 35 / 0.06)
- ring0 0 0 3px rgb(139 111 196 / 0.3)
- 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.
Plum is a ledger on cream paper. White boxes sit on a warm cream canvas, ruled in warm hairlines, with plum-black ink, one pale lavender button and every small label in mono caps. Nothing that stays on the page casts a shadow. Mid-page, one plum-black band turns the page over while the lavender stays exactly the same.
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 | Light native: cream canvas (#f8f4f0) with white boxes. Dark is plum-black (#241f23) with cream ink and the same lavender, not an inversion. |
| Type | Host Grotesk for headlines and text, never past 500 (headlines 500 with tight tracking, text 400). Fragment Mono 400 in caps for every small label: eyebrows, buttons, badges, nav links, table heads. |
| Colour | Cream and plum neutrals, one pale lavender fill (#d2beff) that always carries plum-black type, a deep violet (#6b4fae) for links, checks and progress, and mint for good news only. |
| Shape | Near square: 2px checkboxes, tags and icon tiles, 4px badges, 5px buttons and inputs, 10px cards and tables, 12px dialogs and the closing panel. Round only for avatars and radios. |
| Depth | Fills and lines, no shadows. White boxes on cream held by a 1px warm hairline. A plum-tinted shadow only under menus, popovers, dialogs, sheets and toasts. |
| Signature | A ruled ledger grid behind the hero with booked lavender and mint cells, ruled tables for logos, features and stats, and one full-bleed plum-black band mid-page. |
Principles
- The line is the lift. Every white box on cream carries a 1px warm hairline and no shadow.
- One lavender fill per view, always with plum-black type.
- Small labels in mono caps, two or three words each. Sentences stay in the grotesque.
- 500 is the heaviest weight anywhere. Headlines, titles, labels and the brand at 500, text at 400.
- Rule, don't float. Neighbouring cells share one 1px line, never two, and never a dashed one.
Colour
Palette
| Token | Light | Dark | Role |
|---|---|---|---|
canvas (--background) | #f8f4f0 | #241f23 | The page floor |
surface-soft | #f3eee7 | #201b21 | Section bands, sidebars, table heads |
surface-card (--muted) | #ffffff | #2e2830 | Tinted fills: inactive tabs, hover rows, code |
surface-strong | #ebe4db | #413a44 | Pressed fills, progress tracks |
surface-solid (--popover) | #ffffff | #2e2830 | Menus, selects, toasts: always opaque |
card | #ffffff | #2e2830 | The card fill |
surface-dark | #241f23 | #1a161a | The inverted panel |
hairline (--border) | #e7e0d7 | #423b45 | Every border and divider |
ink (--foreground) | #241f23 | #f8f4f0 | Headings and primary text |
body-strong | #352d33 | #ece7e2 | Emphasised body text |
body | #554f54 | #d0ccc8 | Running text |
muted (--muted-foreground) | #6a6469 | #a5a19d | Secondary text, captions |
muted-soft | #8a8489 | #807b7f | Placeholders, disabled text, icons at rest |
primary | #d2beff | #d2beff | The action colour |
accent (--accent-fill) | #6b4fae | #c9b3ff | The saturated accent: links, the accent badge |
accent-soft | #ede5ff | #3a2f52 | The tint an accent label sits on |
danger (--destructive) | #9d3a37 | #e2908a | Destructive actions and errors |
success, warning and error each come with a -soft tint for the back of a
badge or an alert: #2e6b47, #735b23 and #9d3a37 in light, #7fc596, #c0a468 and
#e2908a in dark.
Plum's own variables, read by the landing hooks and the kit: --grid-line
(rgb(36 31 35 / 0.08) light, rgb(248 244 240 / 0.07) dark),
--cell-lavender (#e4d8ff light, #382c50 dark), --cell-mint (#cdf9d6 light,
#213829 dark), --band-body (#d0ccc8 light, #d0ccc8 dark), --band-muted
(#a5a19d light, #a5a19d dark), --band-line (#423b45 light, #3a333c dark).
How colour is used
- Pale lavender (
bg-primary) is the one loud fill: the primary button, the brand mark, step markers, checked controls and selected text. It always carries plum-black type (text-on-primary). - Deep violet (
text-accent,bg-accent) points: links, eyebrows, checks, progress fills and info. It is the only lavender used for text, icons and thin lines. - Mint (
success,success-soft) only means good news: shipped, paid, done, booked. - Every neutral is cream or plum, never grey: the canvas, white cards, sunken cream, the warm tint and the strong fill, with text stepping from ink to body to muted.
- Plum-black (
surface-dark) is the band, the closing panel, tooltips and the dark card. On it the cream becomes the ink and the lavender stays the same.
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: violet, green,
orange, blue, olive and plum. Every series clears 3:1 on the canvas and on cards
in both themes; the dark set is lifted so each hue reads on plum-black. 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: light here, because
Plum is drawn in light first. The theme menu in the header offers light, dark
and system and remembers the choice.
Type
Faces
- Host Grotesk (
font-display,font-body): headings and display type; running text and interface copy. - Fragment Mono (
font-mono): code, ids and tabular labels (weights 400).
Host Grotesk is a neo-grotesque with a large x-height, round bowls and a solid 500 that holds a 64px headline at 1.02, so one family carries headings and text. Fragment Mono is drawn from a grotesque, so the mono caps labels sit beside it without looking like a terminal.
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 | 64px | 1.02 | -0.03em | 500 | The hero headline, desktop |
text-display-lg | 56px | 1.05 | -0.025em | 500 | The hero headline, tablet |
text-display-md | 40px | 1.08 | -0.02em | 500 | Section headlines, the hero on phones |
text-display-sm | 32px | 1.12 | -0.015em | 500 | Section headlines on phones, big numbers |
text-title-lg | 24px | 1.25 | -0.01em | 500 | Page titles in the app |
text-title-md | 18px | 1.35 | -0.005em | 500 | Card titles |
text-title-sm | 16px | 1.4 | 0 | 500 | Small headings, table titles |
text-body-lg | 18px | 1.55 | 0.005em | 400 | Lead paragraphs |
text-body-md | 16px | 1.55 | 0.01em | 400 | Running text |
text-body-sm | 14px | 1.5 | 0.01em | 400 | Interface copy, table cells |
text-caption | 13px | 1.4 | 0.01em | 400 | Metadata, helper text |
text-caption-uppercase | 12px | 1.3 | 0.06em | 400 | Eyebrows above headings |
text-button | 13px | 1 | 0.04em | 400 | Buttons |
text-nav-link | 13px | 1.3 | 0.04em | 400 | 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 Host Grotesk 500 at 64, 56, 40 and 32px,
tracked in (-0.03em at the top) with line heights from 1.02 to 1.12. Text is 400
at 14 to 18px with a hair of open tracking. Labels are Fragment Mono caps at 11
to 13px, tracked +0.04em to +0.06em.
Space and layout
- Spacing tokens:
xxs4px,xs8px,sm12px,md16px,lg24px,xl32px,xxl48px,section112px (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 48px, with 112px between landing sections on desktop and 48px on phones.
- Tight inside, generous between: 40px controls (32px small) and 16 to 32px of card padding.
- Grids are ruled tables:
gap-px bg-hairlineon the parent,bg-cardon each cell, one outer hairline with 10px corners.
Shape and depth
| Token | Value | Where |
|---|---|---|
rounded-xs | 2px | Breadcrumb, Checkbox, DropdownMenu, Kbd, Progress, Select, Switch, Tabs, the landing page |
rounded-sm | 4px | Accordion, Badge, Skeleton, Switch, Tabs, Tooltip, the landing page |
rounded-md | 5px | Alert, Button, Dialog, DropdownMenu, Input, Popover, Select, Sheet, Tabs, Toaster, the landing page |
rounded-lg | 10px | Card, Table, the landing page |
rounded-xl | 12px | The landing page |
rounded-pill | 9999px | The landing page |
rounded-full | 9999px | Avatar, RadioGroup |
Corners stay crisp: 2px on checkboxes, kbd, tags and icon tiles, 4px on badges,
tooltips and the switch, 5px on buttons, inputs, menus and alerts, 10px on
cards, tables and the product window, 12px on dialogs and the closing panel.
Borders are 1px solid: hairline for structure, the stronger input line for
controls. Nothing on the page casts a shadow; the plum-tinted overlay shadow
marks only what leaves the page, and fields focus with a 3px violet halo.
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 Plum |
|---|---|
Button | Mono caps at 13px (+0.04em, 400), 5px corners, no shadow and a 1px press on click. Focus is a 2px violet outline with a 2px gap. Primary is pale lavender with plum-black type; secondary is the warm tint; outline is a 1px input line that lifts to white on hover; ghost tints on hover; danger is soft red that turns solid on hover; link is violet text in the grotesque, underlined on hover. Sizes are 32, 40 and 48px. |
Badge | A ruled tag, not a pill: mono caps at 11px (12px with uppercase), 4px corners, no border, 22px tall, tabular figures. Neutral is the strong fill; accent (lavender tint with violet text), success, warning and danger are soft tints. A leading dot, when a page adds one, is a 6px square. |
Card | White, flat and held by a 1px hairline with 10px corners. Soft and strong drop the line for a sunken or stronger fill, outline drops the fill, and dark is the plum-black panel. Titles are 18px 500, descriptions 14px muted. |
Input, Textarea, Select | 40px white fields with the stronger input line and 5px corners, even on cream; textareas start at 96px. Focus turns the line violet with a 3px halo; invalid turns it red; disabled sinks to the soft cream. Select content is a white menu with a hairline, the overlay shadow and a violet check. |
Checkbox, RadioGroup, Switch | Checkboxes are 16px with 2px corners, radios are circles, and switches are square-ish 36 by 20px tracks with 4px corners and square thumbs. Off, they sit on white (the switch on the strong fill) with the input line. On, they fill lavender with a violet edge and a plum-black tick, dot or thumb. Each keeps a 32px hit area. |
Tabs | Default tabs sit in a warm-tint track; the active tab is a white chip held by a hairline (the strong fill in dark). Line tabs mark the active tab with a 2px ink rule. Tab labels stay in the grotesque. |
Accordion | Open rows ruled by hairlines, no cards. Triggers are 16px 500 in ink and turn violet on hover, the soft chevron turns over, and answers sit in body text. |
Dialog, AlertDialog, Sheet | A sunken cream tray with 12px corners holds one white card, and the footer is split off by a strip of tray. The close is a 32px ghost button. The scrim is flat plum at 40%, no blur. Sheets are white panels with one hairline edge and no corners, with hairlines under the header and over the footer. |
DropdownMenu, Popover, Select content, Tooltip | White, a hairline, 5px corners and the plum-tinted overlay shadow. Items highlight to the warm tint, group labels are mono caps and checks are violet. Tooltips are plum-black chips with cream text. |
Table | A white panel with a hairline and 10px corners. The head is a sunken cream band in mono caps; rows split by hairlines, figures are tabular, and there are no zebra stripes or vertical rules. Selected rows take the lavender tint. |
Alert | A soft tint with 5px corners, no border and no shadow: lavender for info, mint for success, sand for warning, rose for danger, with the icon and title in the matching deep colour. |
Avatar, Progress, Skeleton, Spinner, Separator, Kbd, Breadcrumb, Pagination, Field, Label, Toaster | Avatars are the one full circle besides the radio, with a hairline ring and mono caps initials on the warm tint. Progress is a 6px violet fill on a strong track with 2px corners. Skeletons pulse on the strong fill and spinners are thin rings. Separators are 1px solid hairlines. Kbd is flat mono caps on white with the input line. Breadcrumbs are caption text with the current page in ink at 500. Pagination keys are mono figures, and the current page is ruled by the input line. Labels are 13px 500 in ink, legends 16px 500. Toasts are white with a hairline, show status only in the icon and carry mono caps action buttons. |
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.
Plum styles these:
hero-backdrop: a ruled ledger grid of 120 by 56px cells with two lavender and two mint booked cells, fading out before the buttons. On phones, two cells sit in the top row.hero-eyebrow: a white ruled tag in mono caps with 2px corners, led by a mint booked square. A linked tag warms its line to violet on hover.hero-titleandsection-title: balance their lines.hero-subtitle: steps up from muted to the body colour.hero-note: mono caps.hero-actions: the arrow leads the label, as it does in the closing panel.site-header: solid cream with no blur. Its call to action is an ink block (cream in dark), so the hero keeps the only lavender button above the fold.site-nav: mono caps links with square hover chips.brand-mark: a 2px-corner lavender tile with a mono letter.section: each one is ruled off by a full-bleed hairline, except the logo strip and the section right after the plum band.section-eyebrow: mono caps led by a 16px rule in its own colour, in sections and showcase rows alike.product-preview: sits flat in a tray, an 8px ring of sunken cream and a 1px outer line, with 10px corners.product-preview-barsquares its dots and address bar, and caps labels in the window are mono.logo-cloudandlogo: one ruled row of white cells that grow to fill the width, under a mono caps title.feature-gridandfeature-card: a ruled table of white cells with shared 1px rules, 10px outer corners and 32px padding.feature-icontiles get 2px corners.stat-grid,statandstat-value: the same ruled table of white cells, with mono caps labels and tabular figures.sectionhow-it-works: the plum band. Full-bleed plum-black where the cream becomes the ink and the lavender stays put;step-markerturns into a lavender square with a mono number.showcase-visual: a sunken cream stage with 10px corners, ruled with a fine 24px ledger grid.testimonial: the quote name holds the 500 ceiling.sectionpricing: the highlighted plan wears a 6px lavender cap on its top edge.cta-panel: flat plum-black in both themes with a 64px ledger grid, 12px corners and no shadow. Its raised layer and accent wash go flat.site-footer: link columns ruled apart by 1px lines, with mono caps heads.
Everything else is type, space and the kit.
Signed-in screens
The dashboard uses the same materials: a sunken cream sidebar and a cream top bar, each with a hairline, white flat cards, tables in white ruled panels with a mono caps head, and one lavender action per page.
Sign-in is one white card on sunken cream with a hairline, 10px corners and no shadow, 40px white fields and a full-width lavender button in mono caps.
Do and don't
Do
- Put content in white boxes (
bg-card) on the cream canvas, each with a 1pxborder-hairline. The line is the whole lift. - Keep one lavender
primarybutton per view, always with plum-black type (text-on-primary). - Set short labels in mono caps:
font-mono uppercaseon the caption-uppercase or button step, two or three words each. - Use the deep violet (
text-accent,bg-accent) for action links, checks, progress, unread dots and eyebrows. Use the pale lavender only as a fill. - Keep mint (
success,success-soft) for good news only: shipped, paid, done, booked. - Rule grids with shared lines:
gap-px bg-hairlineon the parent,bg-cardon each cell, one outerborder-hairlinewithrounded-lg. - Put fields on white with the stronger
border-input, even on cream. - Check every screen in light and dark, and anything on the landing page inside the plum band too.
Don't
- Don't put a shadow on anything that stays on the page.
shadow-overlayis for menus, popovers, dialogs, sheets and toasts only. - Don't use pills.
rounded-fullis for avatars and radio buttons; buttons, badges, tabs, switches, eyebrows and progress stay square-ish. - Don't put white text on the lavender, and don't use the pale lavender for text, icons or thin lines. It is too pale.
- Don't go heavier than 500. No
font-semibold, nofont-bold. - Don't use grey. No hex and no Tailwind palette classes (
bg-gray-100,text-zinc-500); every neutral is a cream or plum token. - Don't add gradients, glows or blur to structure. The header is solid, scrims are flat and the hero cells are flat fills.
- Don't set sentences in mono caps. Paragraphs, form labels, menu items, toasts and tooltips stay in the grotesque.
- Don't add a second accent colour or a dashed line. Lavender acts, violet points, mint confirms, and 1px solid rules separate.
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 Plum
The builder opens with Plum picked. Pick your batteries and the design is applied to every template before the zip is built.
