Skip to content
slate
Contents — 29 sections

01 · Foundations

Colour tokens

Every colour in this design comes from one of these. Nothing below hard-codes a value. Toggle dark mode in the header to see each token's dark counterpart.

Aa

--background

page surface

Aa

--card

raised surface

Aa

--popover

floating surface

Aa

--primary

5.66:1 light · 6.35:1 dark

Aa

--secondary

low-emphasis fill

Aa

--muted

4.41:1 light · 5.25:1 dark

Aa

--accent

hover surface

Aa

--destructive

4.62:1 light · 5.13:1 dark

--border

hairlines

--input

control border

--ring

focus ring

Aa

--sidebar

nav surface

Chart series — use in order

chart-1

chart-2

chart-3

chart-4

chart-5

02 · Foundations

Typography

Inter for everything, JetBrains Mono for code and data. Two weights only — 400 and 600. Negative tracking scales with size.

Display

48 / 600 / 1.05 / -0.03em

Heading one

36 / 600 / 1.15 / -0.025em

Heading two

24 / 600 / 1.25 / -0.02em

Heading three

20 / 600 / 1.35 / -0.015em

Heading four

16 / 600 / 1.4 / -0.01em

Lead paragraph. Used once, directly beneath a page title, to say what the page is for before the interface starts.

18 / 400 / 1.6

Body copy is 14px, not 16px. This is an application rather than an article, and 16px body in a data-dense tool spends a third of the vertical space on air. Body text is capped at 70 characters — you can link inline and set inline code without breaking the line rhythm.

14 / 400 / 1.6 — the default

Small text. Help text beneath a field, timestamps, secondary metadata.

13 / 400 / 1.5

Caption / overline

12 / 600 / 1.4 / +0.01em
A blockquote. Left rule, no background fill, italic. Used in changelogs and documentation, never as a testimonial device.

Unordered

  • Deploy previews per branch
  • Automatic TLS certificates
  • Rollback to any prior release

Ordered

  1. Connect your repository
  2. Choose a build command
  3. Ship

03 · Foundations

Surface & elevation

Borders separate, shadows float. A surface in the page flow gets a border and no shadow; a surface above the page gets both, because a shadow alone is nearly invisible in dark mode.

border only — cards, panels

shadow-xs — buttons

shadow-md — menus, popovers

shadow-lg — dialogs

Radius ramp — everything derives from --radius: 0.5rem

sm · 4px

md · 6px

lg · 8px

xl · 12px

full · badges, avatars

04 · Primitives

Button

Six variants, four sizes. Default height is 36px (h-9). Icons are 16px with gap-2.

Variants

Sizes

icon · h-9 w-9

States

Hover and active are shown statically here. No transform, no scale — targets never move.

With icons, and button groups

05 · Primitives

Form controls

All controls are 36px tall to match buttons. The error state changes colour only — the border does not thicken, because a thicker border shifts layout by a pixel.

Lowercase letters, numbers and hyphens.

With a leading icon at 16px, inset 12px.

Enter a valid email address.

Disabled — 50% opacity, muted fill.

Cannot be changed after creation.

Runs in the project root.

Checkbox

Radio group

Switch

Slider

0620 MB1 GB

06 · Primitives

Composed form

Individual controls do not show spacing or rhythm. This does. Sibling fields sit gap-4 apart, groups gap-6.

Deployment settings

Applies to every environment in this project.

General

Not a valid hostname — check for a repeated dot.


Automation

Deploy every push to a tracked branch.

Block promotion until CI passes on the commit.

07 · Data display

Card

Border, no shadow — a card sits in the page, not above it. Padding is p-6, or p-4 for compact variants.

Basic card

Header, content, footer. The default container for everything.

Content sits at 14px with a 1.6 line height. Card titles use the h3 scale so they do not compete with the page title.

With header action

The action is a ghost icon button, aligned to the title baseline.

Regionap-southeast-2
Runtimenodejs22.x
Last deploy4 minutes ago

Media card

Media is flush to the card edge. The card clips it with overflow-hidden.

Stat cards

Requests

1.28M

12.4% vs last week

p95 latency

184ms

8.1% vs last week

Error rate

0.03%

Within the 0.1% budget

Build minutes

412

of 1,000 included

08 · Data display

Table

Rows are 44px. Numeric columns are right-aligned with tabular-nums — always. Header is bg-muted/50 with uppercase caption type.

Deployment Status Author Duration
acme-web-8f21ba9 Ready RKRina Kaur 4 min ago 1m 04s
acme-web-3c90d17 Building TOTomás Ortiz 22 min ago
acme-web-71b0e42 Failed RKRina Kaur 1 hr ago 0m 38s
acme-web-d4419aa Ready JWJoan Weller 3 hr ago 1m 12s
acme-web-0ae7c31 Cancelled TOTomás Ortiz Yesterday 0m 09s

1 of 5 rows selected

09 · Data display

List & feed

Three list shapes that carry most of an application: a settings list, an activity feed, and a description list.

Notifications

Deployment failures

Email me when a production deploy fails.

Weekly digest

Usage and performance summary each Monday.

Product updates

Occasional news about new features.

Activity

RK

Rina Kaur promoted 8f21ba9 to production

4 minutes ago

TO

Tomás Ortiz opened #412 Cache invalidation

22 minutes ago

JW

Joan Weller added the eu-central-1 region

3 hours ago

Automatic rollback triggered by health check

Yesterday at 23:41

Build details

Commit
8f21ba9
Branch
main
Node
22.11.0
Output size
4.2 MB
Duration
1m 04s

10 · Data display

Badge & status

Status colours signal state. They are never used decoratively, and never to distinguish categories in navigation.

Badge variants

Default Secondary Destructive Outline

Status pills

Healthy Degraded Down Deploying Paused

Counters

Issues 7 Drafts 99+

11 · Data display

Avatar

Initials on bg-muted are the fallback. No generated colours per user — that reintroduces uncontrolled colour into the palette.

Sizes

RK RK RK RK

With image

Image slot, icon fallback

With status

JW TO

Group

RK TO JW +3

12 · Data display

Data visualisation

Chart series are used in order: a two-series chart uses chart-1 and chart-2, never chart-1 and chart-4. Gridlines are border, labels are muted-foreground.

Requests by region

Last 7 days

Sydney Frankfurt
240k180k120k60k0 MonTueWedThuFriSatSun

p95 latency

Area chart, single series

Sparklines

1.28M +12.4%
184ms −8.1%
0.03% flat

14 · Navigation

Tabs & segmented control

Tabs are underline style, not shadcn's default filled pill — a filled tab bar competes with buttons for attention. The segmented control keeps the filled treatment, because it is a control.

Horizontal tabs

The active panel renders below the bar with no additional container. A tab panel that adds its own border doubles the rule already drawn by the tab bar.

Segmented control

Vertical tabs

Vertical tabs use the sidebar item treatment rather than an underline, because a vertical rule reads as a container edge.

17 · Feedback

Alert & callout

Intent is carried by the icon and a /10 tinted background — not by a heavy coloured left bar, which fights the card border for the same job.

Preview deployments are enabled

Every pull request gets its own URL. Previews are deleted 30 days after the branch is merged.

Domain verified

acme.com is now serving from the production deployment.

Approaching your build minute limit

You have used 412 of 1,000 minutes this cycle.

Upgrade plan

Build failed

Module not found: @acme/ui-tokens. Check that the package is listed in dependencies.

View build log

18 · Overlays

Dialog, sheet & popover

All shown inline rather than as real overlays. Floating surfaces get both a shadow and a border — in dark mode a shadow against a dark background is nearly invisible, so the border is what keeps the edge legible.

Dialog

Add a custom domain

Point your domain at Acme and we will issue a certificate automatically.

Alert dialog — destructive

Delete acme-web?

This removes all deployments, logs, and environment variables. It cannot be undone.

Popover

Build minutes

Time spent compiling, across all projects in this workspace.

412 / 1,000

Tooltip

Copy deployment URL

Sheet / drawer

Environment variables

Applied at build and at runtime.

DATABASE_URL ••••••••
NEXT_PUBLIC_API https://api.acme.com
LOG_LEVEL info

19 · Feedback

Progress & loading

Progress bar

68% — uploading assets

24% — quota used

Spinner

Checking…

Progress ring

68%

Skeleton

20 · Feedback

Toast & notification

Popover surface, shadow-lg, stacked bottom-right in a real application. Every toast is dismissible; destructive ones do not auto-dismiss.

Settings saved

Changes apply to the next deployment.

Deployment promoted

8f21ba9 is now live on acme.com.

Could not reach the build server

Retrying in 30 seconds.

21 · Feedback

Empty, error & loading states

Empty states are the one place a heading may be centred. The icon sits in a muted circle rather than floating, so it reads as deliberate rather than as a missing image.

No projects yet

Import a repository to get your first deployment running in about a minute.

No results for “rollbck”

Check the spelling, or search across all workspaces instead.

Could not load deployments

The API returned a 503. This is usually temporary.

23 · Composed

Marketing hero

Marketing bands use py-16 rather than the in-app py-8. Note there is no gradient — slate never uses one.

v4.0 is now generally available

Ship every branch without thinking about it.

Connect a repository and get a URL for every commit, a certificate for every domain, and a rollback that takes one click.

Free for personal projects. No card required.

acme-web · production

$ acme deploy --prod

Building… 1m 04s

Uploading 128 files

Certificate issued for acme.com

→ https://acme.com

24 · Composed

Feature grid

Instant previews

Every pull request gets a URL before the reviewer opens it.

Certificates handled

TLS issued and renewed automatically for every domain you add.

One-click rollback

Every deployment stays addressable. Promote any of them back to production.

Analytics built in

Real user metrics per route, without adding a third-party script.

Edge by default

Static assets served from 40 regions with no configuration.

Team permissions

Per-project roles, SSO, and an audit log of every promotion.

25 · Composed

Pricing table

The recommended tier is marked with a border and a badge — not with a different background colour, which would introduce a second accent surface.

Hobby

For personal projects and experiments.

$0/month

  • Unlimited static deployments
  • 100 build minutes
  • Community support
Recommended

Pro

For teams shipping to production.

$24/user/month

  • Everything in Hobby
  • 1,000 build minutes
  • Password-protected previews
  • Email support, 1 business day

Enterprise

For organisations with compliance requirements.

Custom

  • Everything in Pro
  • SAML SSO and SCIM
  • Audit log export
  • 99.99% uptime SLA

26 · Composed

Testimonial

We moved eleven services across in an afternoon. The part I did not expect was that our review cycle got faster — every PR having a real URL removed an entire round of “can you screenshot it”.
JW Joan Weller Staff Engineer, Northbound
“Rollback used to be a meeting. Now it is a button, and I have stopped dreading Friday releases.”
TO Tomás Ortiz · Platform Lead, Kestrel
“The audit log alone got it through our security review. That never happens.”
RK Rina Kaur · CTO, Vellum Health

27 · Composed

Call to action band

The one inverted surface in the design. It works because it is used once per page — a second inverted band would stop reading as emphasis.

Deploy your first project today.

Connect a repository and be live in under a minute. Free for personal projects.

29 · Utility

Icon set

Lucide, inline SVG, 16px in controls and 20px standalone, stroke width 2 (1.5 above 24px). Never an emoji, never a filled glyph icon — the stroke weight is what keeps the set coherent.

plus
search
settings
user
users
folder
file
chart
bell
info
check-circle
alert
x
chevron-down
arrow-right
refresh
copy
trash

30 · Utility

Motion & interaction

One duration for everything interactive. Colour and opacity animate; layout and position do not.

StateTreatmentTiming
DefaultBase token colours
HoverSurface shifts to bg-accent, or fill drops to /90. No transform.150ms
Focusring-2 ring-ring ring-offset-2, on :focus-visible onlyinstant
ActiveFill drops to /80. No scale.150ms
Disabledopacity-50 pointer-events-none. Never a colour change.
Overlay entryFade plus 4px rise200ms
Reduced motionAll durations collapse to ~0 — handled in theme.css0.01ms

Try it — tab through these

The ring uses ring-offset-background so it stays visible on both page and card surfaces.