Forge
Warm near-black, one loud orange slab, dashed rules pinned with square ticks, and pills for every control.
- Dark by default
- 35 colours · 14 type steps
- Inspired by cloudflare.com
The same generated app in every design. Scroll inside the window to see the whole page.
What it is
Forge sets the page on a warm near-black and splits it with 1px hairlines, dashed rules and small square ticks. One orange carries every action, and it arrives at full size as whole slabs: the hero, one feature cell and the closing call to action, each lit by a warm glow and halftone dots. Nothing casts a shadow except menus and dialogs, and every button, tab, badge and nav link is a pill. Schibsted Grotesk sets every word at 400 and 500, with DM Mono for code and numbers. It opens in dark, and the light palette is the same page on warm white.
Maintained by @agentic-studio in the open registry.
Best for
Infrastructure, developer and security products, where dense technical information should read as engineered and exact. Also API platforms, observability tools and devtools that want one confident colour on a dark page.
Trade-offs
- The orange is loud on purpose. It fills the hero, one feature cell and the closing band, so a product with its own strong brand colour will fight it. Change
--primary,--slaband--accent-filltogether. - Depth is nearly flat. The dark surfaces sit within a few percent of each other, so hairlines and dashed rules carry all the structure. A screen that drops them turns into one brown field.
- The orange never carries white text. White on #ff5e1f measures 3:1, so every label on orange is near-black, and light mode needs a deeper orange (#bb3c00) for links and accent text.
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
#ff5e1f
accent-1
#ff5e1f
accent-2
#18c383
accent-3
#9bcaff
accent-4
#ffdf9e
accent-5
#9b47df
accent-6
#a39d98
accent-hover
#ff7038
accent-soft
#331d13
primary
#ff5e1f
Surface
canvas
#151414
hairline
rgb(240 227 222 / 0.1)
surface-card
#242322
surface-dark
#0f0e0d
surface-dark-elevated
#1c1b1a
surface-soft
#191817
surface-solid
#1e1d1c
surface-strong
#2a2927
Text
body
#f0e3de
body-strong
#f8f0eb
ink
#fffbf5
muted
#9a9390
muted-soft
#6f6a66
on-accent
#150a03
on-dark
#fffbf5
on-primary
#150a03
Semantic
error
#ef6e68
success
#10ae65
warning
#bf9000
Other
danger
#ef6e68
danger-soft
#2e1917
error-soft
#2e1917
primary-hover
#ff7038
success-soft
#112418
warning-soft
#271e0b
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
- 3.5rem · 56px · 500 · lh 0.99 · ls -0.025em
Ship faster
- Token
- display-lg
- Values
- 3rem · 48px · 500 · lh 1 · ls -0.025em
Ship faster
- Token
- display-md
- Values
- 2.5rem · 40px · 500 · lh 1 · ls -0.025em
Ship faster
- Token
- display-sm
- Values
- 2rem · 32px · 500 · lh 1 · ls -0.025em
Ship faster
- Token
- title-lg
- Values
- 1.5rem · 24px · 500 · lh 1.15 · ls -0.025em
Ship faster
- Token
- body-lg
- Values
- 1.125rem · 18px · 400 · lh 1.45 · ls -0.01em
Ship faster
- Token
- title-md
- Values
- 1.125rem · 18px · 500 · lh 1.2 · ls -0.02em
Ship faster
- Token
- body-md
- Values
- 1rem · 16px · 400 · lh 1.5 · ls -0.003em
Ship faster
- Token
- button
- Values
- 1rem · 16px · 500 · lh 1 · ls -0.005em
Ship faster
- Token
- title-sm
- Values
- 1rem · 16px · 500 · lh 1.3 · ls -0.01em
Ship faster
- Token
- nav-link
- Values
- 0.9375rem · 15px · 500 · lh 1.3 · ls -0.005em
Ship faster
- Token
- body-sm
- Values
- 0.875rem · 14px · 400 · lh 1.45 · ls -0.01em
Ship faster
- Token
- caption
- Values
- 0.8125rem · 13px · 400 · lh 1.35 · ls 0
SHIP FASTER
- Token
- caption-uppercase
- Values
- 0.8125rem · 13px · 500 · lh 1.3 · ls 0.025em
Typefaces
The families the generated Tailwind theme points at. A licensed face is named here even when the substitute below is what actually renders.
- DisplaySchibsted Grotesk, ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif
- BodySchibsted Grotesk, ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif
- MonoDM 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
- xxl2.5rem · 40px
- 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.5rem · 8px
- lg0.75rem · 12px
- xl1rem · 16px
- full9999px
- pill9999px
Elevation
Shadow tokens on a neutral card, at true blur and spread.
- insetinset 0 1px 0 rgb(255 255 255 / 0.14)
- lift0 0 #0000
- overlay0 20px 40px rgb(0 0 0 / 0.55), 0 6px 12px rgb(0 0 0 / 0.35)
- ring0 0 0 3px rgb(255 94 31 / 0.35)
- 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.
Forge is warm black iron with one slab of hot orange. The page sits on a warm near-black, split by 1px hairlines and dashed rules pinned with small square ticks. The orange arrives at full size as whole slabs (the hero, one feature cell and the closing band) with near-black type on top. Every button, tab, badge and nav link is a pill.
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 warm #151414. Light is the same page on warm white (#fbfaf8), and the slabs stay orange. |
| Type | Schibsted Grotesk for every word at 400 and 500, headlines at -0.025em. DM Mono for code, ids, numbers, step numerals and the hero note. |
| Colour | Warm near-black greys, cream headings and blush body text, one orange (#ff5e1f) for actions, focus and the slabs. Light mode uses #bb3c00 for links and accent text. |
| Shape | Pills for every button, tab, badge, switch and nav link. 8px fields, 12px menus, 16px panels and slabs, square lattice cells. |
| Depth | Flat. Hairlines and dashed rules carry the structure. Only menus, dialogs, sheets, tooltips and toasts cast a shadow. |
| Signature | An orange hero slab with near-black type, halftone corners and a warm glow, over dashed section rules pinned by square ticks. |
Principles
- One solid orange pill per view. Every other action is an outline pill with a hairline.
- Orange at full size or not at all: the hero, one feature cell, the closing band.
- Near-black on orange, every time. Never white or cream.
- Lines carry the structure: 1px hairlines, dashed rules, 7px square ticks where they cross.
- Dashed means drawing furniture (rules, tags, diagrams). Anything you click or type into keeps a solid line.
Colour
Palette
| Token | Light | Dark | Role |
|---|---|---|---|
canvas (--background) | #fbfaf8 | #151414 | The page floor |
surface-soft | #f5f3f0 | #191817 | Section bands, sidebars, table heads |
surface-card (--muted) | #f0eeea | #242322 | Tinted fills: inactive tabs, hover rows, code |
surface-strong | #e9e6e1 | #2a2927 | Pressed fills, progress tracks |
surface-solid (--popover) | #ffffff | #1e1d1c | Menus, selects, toasts: always opaque |
card | #ffffff | #191817 | The card fill |
surface-dark | #151414 | #0f0e0d | The inverted panel |
hairline (--border) | rgb(38 33 28 / 0.1) | rgb(240 227 222 / 0.1) | Every border and divider |
ink (--foreground) | #221f1c | #fffbf5 | Headings and primary text |
body-strong | #3a3633 | #f8f0eb | Emphasised body text |
body | #4f4b47 | #f0e3de | Running text |
muted (--muted-foreground) | #6b6661 | #9a9390 | Secondary text, captions |
muted-soft | #8f8a84 | #6f6a66 | Placeholders, disabled text, icons at rest |
primary | #ff5e1f | #ff5e1f | The action colour |
accent (--accent-fill) | #bb3c00 | #ff5e1f | The saturated accent: links, the accent badge |
accent-soft | #fff0e8 | #331d13 | The tint an accent label sits on |
danger (--destructive) | #ac3131 | #ef6e68 | Destructive actions and errors |
success, warning and error each come with a -soft tint for the back of a
badge or an alert: #006e3d, #7a5a00 and #ac3131 in light, #10ae65, #bf9000 and
#ef6e68 in dark.
Forge's own variables, read by the landing hooks and the kit: --slab (#ff5e1f
light, #ff5e1f dark), --on-slab (#150a03 light, #150a03 dark),
--on-slab-soft (#371807 light, #371807 dark), --slab-line (rgb(21 10 3 /
0.25) light, rgb(21 10 3 / 0.25) dark), --slab-hover (rgb(21 10 3 / 0.08)
light, rgb(21 10 3 / 0.08) dark), --slab-dot (rgb(21 10 3 / 0.14) light,
rgb(21 10 3 / 0.14) dark), --slab-glow (rgb(255 244 230 / 0.55) light,
rgb(255 244 230 / 0.55) dark), --slab-button (#fffbf5 light, #fffbf5 dark),
--slab-button-hover (#f0e3de light, #f0e3de dark), --on-slab-button (#150a03
light, #150a03 dark), --rule (rgb(38 33 28 / 0.18) light, rgb(240 227 222 /
0.16) dark), --tick (#b3aea9 light, #5c5753 dark), --grid-dot (rgb(38 33
28 / 0.09) light, rgb(240 227 222 / 0.07) dark).
How colour is used
- Orange (
bg-primary) fills the one main pill, the active tab, checked checkboxes, switches and progress.text-accentis the same orange in dark and a deeper #bb3c00 in light. - The slabs use
--slabwith near-black--on-slabtext and brown--on-slab-softsubtitles. On a slab the primary turns into a cream pill (--slab-button). - Text steps from cream headings (#fffbf5) to blush body (#f0e3de) and warm grey muted copy (#9a9390). Every grey comes from the warm ramp.
- Green, amber and red mark status only, as soft tints with status text or icons. Orange tints are for badges and selected rows.
- Selected text is the orange itself with near-black on it.
Charts
accent-1 to accent-6 (also chart-1 to chart-6) are six series colours
ordered so neighbours stay distinguishable. Six series: orange, green, sky blue,
sand, violet and warm grey in dark. Light mode takes a deeper cut of each, and
every light series holds 3:1 on warm white. 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
Forge is drawn in dark first. The theme menu in the header offers light, dark
and system and remembers the choice.
Type
Faces
- Schibsted Grotesk (
font-display,font-body): headings and display type; running text and interface copy. - DM Mono (
font-mono): code, ids and tabular labels (weights 400, 500).
Schibsted Grotesk has compact, slightly squared forms that hold -0.025em tracking at 56px and still read cleanly at 13px, so one family sets every word. DM Mono is round and low in contrast, so code, ids and numbers sit calmly beside the grotesk.
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 | 56px | 0.99 | -0.025em | 500 | The hero headline, desktop |
text-display-lg | 48px | 1 | -0.025em | 500 | The hero headline, tablet |
text-display-md | 40px | 1 | -0.025em | 500 | Section headlines, the hero on phones |
text-display-sm | 32px | 1 | -0.025em | 500 | Section headlines on phones, big numbers |
text-title-lg | 24px | 1.15 | -0.025em | 500 | Page titles in the app |
text-title-md | 18px | 1.2 | -0.02em | 500 | Card titles |
text-title-sm | 16px | 1.3 | -0.01em | 500 | Small headings, table titles |
text-body-lg | 18px | 1.45 | -0.01em | 400 | Lead paragraphs |
text-body-md | 16px | 1.5 | -0.003em | 400 | Running text |
text-body-sm | 14px | 1.45 | -0.01em | 400 | Interface copy, table cells |
text-caption | 13px | 1.35 | 0 | 400 | Metadata, helper text |
text-caption-uppercase | 13px | 1.3 | 0.025em | 500 | Eyebrows above headings |
text-button | 16px | 1 | -0.005em | 500 | Buttons |
text-nav-link | 15px | 1.3 | -0.005em | 500 | Header and footer links |
Rules: one h1 per page. Display sizes are for marketing pages; the app tops
out at text-title-lg. One grotesk at 400 and 500 only. Headlines run 56, 48,
40 and 32px at -0.025em with a line height of 1 or tighter; body runs 14 to 18px
at 1.45 to 1.5. Eyebrows, table heads, menu group labels and footer column heads
are 13px uppercase at 500, and mono appears only for code, keys, ids, dates,
amounts, shortcuts, step numerals and the hero note.
Space and layout
- Spacing tokens:
xxs4px,xs8px,sm12px,md16px,lg24px,xl32px,xxl40px,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 40px, with 80px between sections.
- Controls are 40px tall with 8px gaps inside. Landing cells pad 32px and app cards 24px.
- Section headings sit left like a spec sheet. The hero and the CTA band are the only centred blocks.
Shape and depth
| Token | Value | Where |
|---|---|---|
rounded-xs | 2px | Breadcrumb, Checkbox |
rounded-sm | 4px | Accordion, Kbd, Tabs, the landing page |
rounded-md | 8px | DropdownMenu, Input, Select, Skeleton, Tooltip, the landing page |
rounded-lg | 12px | Alert, DropdownMenu, Popover, Select, Toaster, the landing page |
rounded-xl | 16px | AlertDialog, Card, Dialog, the landing page |
rounded-pill | 9999px | Badge, Button, Progress, Switch, Tabs, Toaster, the landing page |
rounded-full | 9999px | Avatar, Dialog, RadioGroup, Sheet, Switch |
Radii are 2px on checkboxes, the brand tile and step markers, 4px on keys and icon tiles, 8px on fields and menu items, 12px on menus, alerts and the product window, and 16px on cards, dialogs and slabs. Every button, tab, badge and switch is a pill; lattice cells and diagram boxes are square. Borders are 1px: solid hairlines on cards and rows, a stronger solid line on fields and outline pills, dashed rules for furniture, and nothing thicker than the 2px tab underline. Only overlays cast a shadow, and solid orange fills get a faint inset highlight.
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 Forge |
|---|---|
Button | Every size is a pill with a sentence-case label at 500. Primary is solid orange with near-black text and a faint inset highlight, the only shadow; outline is transparent with the stronger input line and is the dominant control; secondary is a warm grey fill with a hairline; ghost has no fill or line; danger is a soft red tint with a red line; link is accent text. Hover steps to the strong surface, a press drops 1px, and focus is the 2px orange outline with a 2px gap. Sizes are 32, 40 and 44px tall, and icon buttons are 40px circles. |
Badge | A 24px pill at 13px 500 with no shadow. Neutral is a transparent chip with a hairline and muted text, accent is a soft orange tint, and status badges are soft tints with no line. The uppercase badge leads with a 5px square, the tick at badge scale. |
Card | Hairline panels with 16px corners on the card fill and no shadow. Soft and strong step the fill with no line, dark is the forge black with a faint line, and outline is the diagram box: square, dashed, with 7px ticks on two opposite corners. |
Input, Textarea, Select | 40px fields with 8px corners, the stronger input line on the card fill and no shadow. Focus turns the line orange with a 3px orange halo; invalid keeps a red line and takes a red halo on focus. mono switches to DM Mono, and textareas start at 96px and resize vertically. Select content is the 12px menu with an orange check on the chosen item. |
Checkbox, RadioGroup, Switch | A 16px checkbox with 2px corners and a 16px radio circle, both on the card fill with the input line. Checked is solid orange with a bold near-black check, or an orange dot. Switches are pill tracks: warm grey with a grey thumb when off, orange with a near-black thumb when on. Focus is the 2px orange outline with a 2px gap. |
Tabs | Default tabs are a hairline pill track with no fill, and the active tab is the solid orange pill with near-black text. Line tabs sit on a hairline, and the active one gets ink text and a 2px orange underline. |
Accordion | Rows split by solid hairlines. Triggers are 16px 500 in ink and turn accent on hover, with no underline; a muted chevron turns over when a row opens. Answers are 16px body text. |
Dialog, AlertDialog, Sheet | Panels on the menu fill with a hairline, 16px corners and the overlay shadow, over a dark scrim with a 2px blur. The footer is a sunken band under a dashed rule with right-aligned pills, and the close button is a 32px ghost circle. Sheets round only their two inner corners, keep a hairline on the inner edge and stack full-width pills. |
DropdownMenu, Popover, Select content, Tooltip | One menu surface: a hairline, 12px corners and the overlay shadow. Items are 32px rows with 8px corners that highlight warm grey, group labels are uppercase captions, separators are dashed, shortcuts are DM Mono and checks are orange. Tooltips are small 8px chips on the menu fill with a hairline and no arrow. |
Table | No zebra and no filled header. Heads are 13px uppercase grotesk in muted, rows split by hairlines, hover is a warm grey and selected rows take an orange tint. Every cell uses tabular figures; set ids, dates and amounts in DM Mono with font-mono. |
Alert | 12px corners, no visible border and a 16px icon in the first column. Info sits on the card grey with an orange icon; success, warning and danger take their soft tint with the icon and title in the status colour. |
Avatar, Progress, Skeleton, Spinner, Separator, Kbd, Breadcrumb, Pagination, Field, Label, Toaster | Avatars are circles with hairline rings and ink initials on warm grey. Progress is a 6px orange bar on a warm grey pill track. Skeletons pulse flat on warm grey, and spinners are thin 1.5 strokes. Separators are 1px dashed rules. Kbd is DM Mono in a 4px hairline box. Breadcrumbs split with small chevrons, and the current page is ink at 500. Pagination numbers are 40px ghost circles with an outline circle on the current page, and previous and next are ghost pills. Labels are 14px 500 in ink, legends 16px 500, and field errors are red captions. Toasts use the menu surface with 12px corners, status only in the icon, and outline and ghost pills for actions. |
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.
Forge styles these:
hero: an orange slab inset 8px from the viewport with 16px corners. The headline turns near-black, and the subtitle and the DM Mono note turn brown.hero-backdrop: a warm glow on the slab's bottom edge, and from 48rem halftone dots in the top-right and bottom-left corners, clear of the subtitle.hero-eyebrow: a transparent pill with a dark hairline, a near-black arrow and an underlined label.hero-actionsandcta-panel: re-point the tokens, so the primary is a cream pill with near-black ink, the outline is a dark hairline pill, and focus and selection turn near-black.hero-visual: extra orange under the window, so the glow shows below and beside it.product-preview: sits flat with 12px corners;product-preview-bargets a dashed rule and square window controls.section: a full-width dashed top rule pinned by two 7px square ticks on the column's text edges. The logo strip has no rule.section-heading: sits left like a spec sheet, andsection-eyebrowbecomes a legend key: an orange swatch and an uppercase label in a dashed tag.feature-gridandfeature-card: a gapless lattice of square cells with a tick on each crossing. The first cell is solid orange with near-black text and halftone in its corner.feature-icon: a hairline tile with 4px corners and an orange icon.showcase-visual: a dashed diagram box with square corner ticks and a faint 16px dot grid.step-marker: square hairline tiles with orange DM Mono numerals.stat-value: tabular figures, so the numbers line up.logo-cloudandlogo: grey wordmarks at 80% under one dashed rule, full strength on hover.cta-panel: the second slab, with a glow on its bottom edge and from 64rem halftone down both side edges.site-headerandsite-nav: a hairline under the header, nav links as hairline pills with a warm hover fill, and a stronger ring on the current page.brand-mark: an orange square with 2px corners and a near-black letter.site-footer: the soft surface under a dashed rule with a tick at each column edge. The highlighted pricing card trades its ring for one 1px orange line.
Everything else is type, space and the kit.
Signed-in screens
The dashboard sidebar sits on the soft surface behind a hairline, with the active item on the card grey and a hairline ring. Cards are flat hairline panels with orange icons in hairline tiles, tables use uppercase heads and DM Mono ids, and each page has one orange pill.
Sign-in is one hairline panel with 16px corners on the canvas: 40px fields, a full-width orange pill and a dashed rule for the "or" line. No slab and no halftone.
Do and don't
Do
- Keep one solid orange pill per view. Every other action is an outline pill with a hairline.
- Use the orange at full strength and full size: the hero slab, one feature cell, the closing band. Tints are for badges and selected rows only.
- Put near-black on orange every time (
text-on-primary,--on-slab). - Separate regions with 1px hairlines and dashed rules, and mark crossings with 7px square ticks.
- Draw every section eyebrow as a legend key: an orange swatch and an uppercase label in a dashed box.
- Make every button, tab, badge, chip, switch and nav link a pill. Fields keep 8px corners, panels 16px, lattice cells none.
- Draw diagrams, empty states and drop zones as dashed 1px boxes with square corner ticks.
- Set ids, keys, code and aligned numbers in DM Mono with
tabular-nums, and check every screen in dark and light.
Don't
- Don't add a second interface hue. Green, blue, sand and violet live in charts and status only.
- Don't use pure black, pure white or cool greys. Every grey comes from the warm ramp.
- Don't put a shadow on a card, button, input, section or the product window. Only overlays float.
- Don't use weights above 500, and don't uppercase anything but eyebrows, table heads, menu group labels, footer column heads and uppercase badges.
- Don't put white or cream text on orange, and don't set orange text on a slab.
- Don't put a gradient on a control. The only gradients are the slab glow and the halftone.
- Don't let halftone run behind brown slab text. Keep it in corners and edges, and off phones.
- Don't frame whole sections or run rails down the page, and don't use
bg-accentas a hover fill: here it is the orange, and hover isbg-surface-strong.
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 Forge
The builder opens with Forge picked. Pick your batteries and the design is applied to every template before the zip is built.
