New127 components, light & dark

Crisp, dense UI,
built to disappear.

SlateOS is an open design system for the web. Three-layer tokens, plain-CSS components, accessible by default and enforced at build time.

127
components
119
icons
2
themes
AA
contrast, enforced
0
dependencies
app.acme.co / invoices

Invoices

142 total · 9 awaiting approval

Outstanding$184,3206.2%
Collected · 30d$246,11812.4%
Avg. days to pay28.42.1 days
InvoiceCustomerStatusAmount
INV-2041Kestrel LogisticsOverdue$12,480.00
INV-2040Halvorsen MarinePending$3,215.40
INV-2039Brightwater DentalSent$8,760.00
INV-2038Oakline FoodsPaid$21,904.75
Foundations

Tokens, in three layers

Primitives hold raw values. Semantic tokens give them meaning per theme. Component tokens capture per-component decisions. Switch theme in the header: nothing in your markup changes.

Color

Typography

Spacing

Radius

Elevation

Icons 119

Components

127 components

Every specimen is live and shows the exact markup. Copy it straight into your project.

18 components

General

The small parts everything else is built from.

Button

Five emphasis levels, five sizes. Primary is the one action that matters on a screen.

View code
<button class="slate-button">Primary</button>
<button class="slate-button slate-button--secondary">Secondary</button>
<button class="slate-button slate-button--soft">Soft</button>
<button class="slate-button slate-button--outline">Outline</button>
<button class="slate-button slate-button--ghost">Ghost</button>
<button class="slate-button slate-button--danger">Delete</button>
<button class="slate-button slate-button--danger-soft">Remove</button>
<button class="slate-button slate-button--inverse">Inverse</button>
<button class="slate-button slate-button--link">Link button</button>
<button class="slate-button" disabled>Disabled</button>

Button sizes

xs 24 · sm 28 · md 32 · lg 40 · xl 48. Touch devices lift md to 44px automatically.

View code
<button class="slate-button slate-button--xs">Extra small</button>
<button class="slate-button slate-button--sm">Small</button>
<button class="slate-button">Medium</button>
<button class="slate-button slate-button--lg">Large</button>
<button class="slate-button slate-button--xl">Extra large</button>

Button with icon

Icons sit before or after the label. Add a shortcut hint with kbd.

View code
<button class="slate-button"><svg class="slate-icon" aria-hidden="true"><use href="#slate-icon-plus"/></svg>New project</button>
<button class="slate-button slate-button--secondary"><svg class="slate-icon" aria-hidden="true"><use href="#slate-icon-download"/></svg>Export</button>
<button class="slate-button slate-button--secondary">Continue<svg class="slate-icon" aria-hidden="true"><use href="#slate-icon-arrow-right"/></svg></button>
<button class="slate-button"><svg class="slate-icon" aria-hidden="true"><use href="#slate-icon-plus"/></svg>New invoice <kbd>N</kbd></button>

Icon button

Square button for toolbars. Always set aria-label.

View code
<button class="slate-button slate-button--secondary slate-button--icon" aria-label="Settings"><svg class="slate-icon" aria-hidden="true"><use href="#slate-icon-settings"/></svg></button>
<button class="slate-button slate-button--ghost slate-button--icon" aria-label="More" data-tooltip="More actions"><svg class="slate-icon" aria-hidden="true"><use href="#slate-icon-more-horizontal"/></svg></button>
<button class="slate-button slate-button--soft slate-button--icon slate-button--lg" aria-label="Add"><svg class="slate-icon" aria-hidden="true"><use href="#slate-icon-plus"/></svg></button>
<button class="slate-button slate-button--icon slate-button--sm" aria-label="Send"><svg class="slate-icon" aria-hidden="true"><use href="#slate-icon-send"/></svg></button>

Button states

Loading keeps width; disabled drops shadow and interaction.

View code
<button class="slate-button slate-button--loading">Saving</button>
<button class="slate-button slate-button--secondary slate-button--loading">Loading</button>
<button class="slate-button" disabled>Disabled</button>
<button class="slate-button slate-button--secondary" disabled>Disabled</button>
<button class="slate-button slate-button--block" style="max-width:14rem">Full width</button>

Button group

Joined buttons for related actions or view switching.

View code
<div class="slate-button-group">
<button class="slate-button slate-button--secondary" aria-pressed="true">Day</button>
<button class="slate-button slate-button--secondary" aria-pressed="false">Week</button>
<button class="slate-button slate-button--secondary" aria-pressed="false">Month</button>
</div>
<div class="slate-button-group">
<button class="slate-button">Save</button>
<button class="slate-button slate-button--icon" aria-label="More options"><svg class="slate-icon" aria-hidden="true"><use href="#slate-icon-chevron-down"/></svg></button>
</div>

Toggle button

A button with a pressed state.

View code
<button class="slate-button slate-button--secondary slate-toggle-button" aria-pressed="true"><svg class="slate-icon" aria-hidden="true"><use href="#slate-icon-bold"/></svg>Bold</button>
<button class="slate-button slate-button--secondary slate-toggle-button" aria-pressed="false"><svg class="slate-icon" aria-hidden="true"><use href="#slate-icon-italic"/></svg>Italic</button>
<button class="slate-button slate-button--secondary slate-toggle-button slate-button--icon" aria-pressed="false" aria-label="Star"><svg class="slate-icon" aria-hidden="true"><use href="#slate-icon-star"/></svg></button>

Badge

Compact labels. Soft by default; use tone for meaning.

Default Neutral Success Warning Danger Info Outline Solid Active v2.4.0 12
View code
<span class="slate-badge">Default</span>
<span class="slate-badge slate-badge--neutral">Neutral</span>
<span class="slate-badge slate-badge--success">Success</span>
<span class="slate-badge slate-badge--warning">Warning</span>
<span class="slate-badge slate-badge--danger">Danger</span>
<span class="slate-badge slate-badge--info">Info</span>
<span class="slate-badge slate-badge--outline">Outline</span>
<span class="slate-badge slate-badge--solid">Solid</span>
<span class="slate-badge slate-badge--success slate-badge--dot">Active</span>
<span class="slate-badge slate-badge--neutral slate-badge--square">v2.4.0</span>
<span class="slate-badge slate-badge--solid slate-badge--count">12</span>

Status

A dot and a word. Quieter than a badge in dense tables; never relies on colour alone.

Active Pending Failed Syncing Live Archived
View code
<span class="slate-status slate-status--success">Active</span>
<span class="slate-status slate-status--warning">Pending</span>
<span class="slate-status slate-status--danger">Failed</span>
<span class="slate-status slate-status--info">Syncing</span>
<span class="slate-status slate-status--accent slate-status--pulse">Live</span>
<span class="slate-status">Archived</span>

Tag

Removable labels for filters and metadata.

Design Engineering Priority EMEA
View code
<span class="slate-tag">Design</span>
<span class="slate-tag">Engineering <button aria-label="Remove"><svg class="slate-icon slate-icon--sm" aria-hidden="true"><use href="#slate-icon-x"/></svg></button></span>
<span class="slate-tag slate-tag--filled"><svg class="slate-icon slate-icon--sm" aria-hidden="true"><use href="#slate-icon-tag"/></svg>Priority</span>
<span class="slate-tag"><svg class="slate-icon slate-icon--sm" aria-hidden="true"><use href="#slate-icon-map-pin"/></svg>EMEA <button aria-label="Remove"><svg class="slate-icon slate-icon--sm" aria-hidden="true"><use href="#slate-icon-x"/></svg></button></span>

Chip

Selectable filter pills.

View code
<button class="slate-chip" aria-pressed="true">All</button>
<button class="slate-chip" aria-pressed="false">Open</button>
<button class="slate-chip" aria-pressed="false">Closed</button>
<button class="slate-chip slate-chip--dashed"><svg class="slate-icon slate-icon--sm" aria-hidden="true"><use href="#slate-icon-plus"/></svg>Add filter</button>

Avatar

Initials, image or icon. Squares are for organisations.

AB CD EF GH IJ KL PN MK
View code
<span class="slate-avatar slate-avatar--xs">AB</span>
<span class="slate-avatar slate-avatar--sm">CD</span>
<span class="slate-avatar">EF</span>
<span class="slate-avatar slate-avatar--lg slate-avatar--accent">GH</span>
<span class="slate-avatar slate-avatar--xl slate-avatar--success">IJ</span>
<span class="slate-avatar slate-avatar--square slate-avatar--lg">KL</span>
<span class="slate-avatar slate-avatar--warning"><svg class="slate-icon" aria-hidden="true"><use href="#slate-icon-user"/></svg></span>
<span class="slate-avatar-wrap" data-status="online"><span class="slate-avatar">PN</span></span>
<span class="slate-avatar-wrap" data-status="busy"><span class="slate-avatar slate-avatar--lg">MK</span></span>

Avatar group

Overlapping stack with overflow count.

PNAKRS+4
View code
<div class="slate-avatar-group"><span class="slate-avatar">PN</span><span class="slate-avatar slate-avatar--accent">AK</span><span class="slate-avatar slate-avatar--success">RS</span><span class="slate-avatar">+4</span></div>

Keyboard key

Shortcut hints.

⌘K Esc ⇧⌘P
View code
<kbd>⌘</kbd><kbd>K</kbd>
<kbd>Esc</kbd>
<span class="slate-row slate-row--xs"><kbd>⇧</kbd><kbd>⌘</kbd><kbd>P</kbd></span>

Divider

Hairline separators, with optional label.


or continue with
LeftRight
View code
<div style="width:100%" class="slate-stack"><hr class="slate-divider"><div class="slate-divider slate-divider--label">or continue with</div><div class="slate-row" style="height:1.5rem"><span>Left</span><span class="slate-divider slate-divider--vertical"></span><span>Right</span></div></div>

Spinner

Indeterminate loading.

View code
<span class="slate-spinner" role="status" aria-label="Loading"></span>
<span class="slate-spinner slate-spinner--lg"></span>
<span class="slate-spinner slate-spinner--xl"></span>
<span class="slate-dots" aria-label="Loading"><i></i><i></i><i></i></span>

Skeleton

Placeholder shapes that match real content.

View code
<div class="slate-stack" style="width:18rem"><div class="slate-row"><span class="slate-skeleton slate-skeleton--circle" style="width:2rem;height:2rem"></span><div class="slate-grow slate-stack slate-stack--sm"><span class="slate-skeleton" style="width:60%"></span><span class="slate-skeleton" style="width:40%"></span></div></div><span class="slate-skeleton slate-skeleton--block"></span></div>
6 components

Typography

Inter for text, JetBrains Mono for code. Tight tracking on large sizes, 14px body for dense interfaces.

Headings

Display through h6. Sizes tighten as they grow.

Display
Heading 1
Heading 2
Heading 3
Heading 4
Heading 5
Heading 6
View code
<div class="slate-display">Display</div>
<div class="slate-h1">Heading 1</div>
<div class="slate-h2">Heading 2</div>
<div class="slate-h3">Heading 3</div>
<div class="slate-h4">Heading 4</div>
<div class="slate-h5">Heading 5</div>
<div class="slate-h6">Heading 6</div>

Text styles

Body, lead, muted, small and eyebrow.

Lead paragraph for introductions and page summaries.

Body text at 14px with a 1.5 line height. Comfortable for dense product UI.

Muted supporting text for descriptions and helper content.

Subtle caption text for timestamps and metadata.

Eyebrow label

Monospace · INV-2041 · sk_live_9f2a

Gradient text for hero moments

View code
<p class="slate-lead">Lead paragraph for introductions and page summaries.</p>
<p>Body text at 14px with a 1.5 line height. Comfortable for dense product UI.</p>
<p class="slate-muted slate-text-sm">Muted supporting text for descriptions and helper content.</p>
<p class="slate-subtle slate-text-xs">Subtle caption text for timestamps and metadata.</p>
<p class="slate-eyebrow">Eyebrow label</p>
<p class="slate-mono slate-text-sm">Monospace · INV-2041 · sk_live_9f2a</p>
<p class="slate-gradient-text slate-h3">Gradient text for hero moments</p>

Prose

Long-form content with comfortable measure and rhythm.

Designing for density

Software for work lives or dies on how much it can show without feeling crowded. Tight type, hairline borders and restrained colour do most of the work.

Use whitespace to group, not to decorate. When everything has a border, nothing does.

View code
<div class="slate-prose">
<h3 class="slate-h3">Designing for density</h3>
<p>Software for work lives or dies on how much it can show without feeling crowded. <strong>Tight type, hairline borders and restrained colour</strong> do most of the work.</p>
<p>Use whitespace to group, not to decorate. When everything has a border, nothing does.</p>
</div>

Inline code and pre

Code that sits in a sentence or stands alone.

Run npm install slateos then import the stylesheet.

.card {
  border: 1px solid var(--slate-border);
  border-radius: var(--slate-radius-lg);
}
View code
<p>Run <code class="slate-code">npm install slateos</code> then import the stylesheet.</p>
<pre class="slate-pre" style="width:100%"><code>.card {
border: 1px solid var(--slate-border);
border-radius: var(--slate-radius-lg);
}</code></pre>

Blockquote

For pull quotes and citations.

Simplicity is the ultimate sophistication.
View code
<blockquote class="slate-blockquote">Simplicity is the ultimate sophistication.</blockquote>

Lists

Bulleted, numbered and checked.

  • Tokens in three layers
  • Plain CSS components
  • Light and dark themes
  • WCAG AA contrast, enforced at build time
  • Works without JavaScript
  • Self-hosted open-licensed fonts
View code
<ul class="slate-list"><li>Tokens in three layers</li><li>Plain CSS components</li><li>Light and dark themes</li></ul>
<ul class="slate-list slate-list--check"><li>WCAG AA contrast, enforced at build time</li><li>Works without JavaScript</li><li>Self-hosted open-licensed fonts</li></ul>
9 components

Layout

Structure for pages and apps.

Stack and row

The two flex primitives. Gap scales xs to xl.

One
Two
Three
LeftRight
View code
<div class="slate-stack slate-stack--sm" style="width:12rem"><div class="slate-badge slate-badge--neutral">One</div><div class="slate-badge slate-badge--neutral">Two</div><div class="slate-badge slate-badge--neutral">Three</div></div>
<div class="slate-row"><span class="slate-badge">Left</span><span class="slate-spacer"></span><span class="slate-badge">Right</span></div>

Grid

Responsive columns that collapse on small screens.

One
Two
Three
View code
<div class="slate-grid slate-grid--3">
<div class="slate-card slate-card--sunken slate-card__body">One</div>
<div class="slate-card slate-card--sunken slate-card__body">Two</div>
<div class="slate-card slate-card--sunken slate-card__body">Three</div>
</div>

Bento grid

Mixed-size tiles for dashboards and feature sections.

Revenue
$84,210
Users
1,284
Churn
1.8%
Uptime
99.98%
View code
<div class="slate-bento">
<div class="slate-card slate-card__body slate-span-2" style="grid-row:span 2"><span class="slate-eyebrow">Revenue</span><div class="slate-stat__value slate-stat">$84,210</div></div>
<div class="slate-card slate-card__body"><span class="slate-eyebrow">Users</span><div class="slate-h3">1,284</div></div>
<div class="slate-card slate-card__body"><span class="slate-eyebrow">Churn</span><div class="slate-h3">1.8%</div></div>
<div class="slate-card slate-card__body slate-span-2"><span class="slate-eyebrow">Uptime</span><div class="slate-h3">99.98%</div></div>
</div>

Split layout

Sidebar plus content, stacks on mobile.

Filters
Results
View code
<div class="slate-split"><div class="slate-card slate-card__body slate-card--sunken">Filters</div><div class="slate-card slate-card__body">Results</div></div>

Section

A titled block with optional actions.

Recent activity

View all
Section content goes here.
View code
<section class="slate-section" style="width:100%"><div class="slate-section__head"><h2 class="slate-section__title">Recent activity</h2><a class="slate-link slate-link--muted slate-text-sm" href="#section">View all</a></div><div class="slate-card slate-card__body slate-muted slate-text-sm">Section content goes here.</div></section>

App shell

Sidebar, sticky top bar and content area.

Overview
Page content
View code
<div class="slate-preview-frame" style="height:22rem;width:100%"><div class="slate-shell" style="height:100%;grid-template-columns:12rem 1fr"><aside class="slate-sidebar" style="height:100%;position:static"><button class="slate-sidebar__workspace"><span class="slate-logo" style="width:1.5rem;height:1.5rem;font-size:.7rem">S</span>Acme</button><a class="slate-nav-item" aria-current="page" href="#shell"><svg class="slate-icon" aria-hidden="true"><use href="#slate-icon-home"/></svg>Overview</a><a class="slate-nav-item" href="#shell"><svg class="slate-icon" aria-hidden="true"><use href="#slate-icon-layers"/></svg>Projects</a><a class="slate-nav-item" href="#shell"><svg class="slate-icon" aria-hidden="true"><use href="#slate-icon-users"/></svg>Team</a></aside><div class="slate-shell__main"><div class="slate-topbar" style="position:static"><span class="slate-text-sm slate-strong">Overview</span><span class="slate-spacer"></span><button class="slate-button slate-button--ghost slate-button--icon slate-button--sm" aria-label="Notifications"><svg class="slate-icon" aria-hidden="true"><use href="#slate-icon-bell"/></svg></button></div><div class="slate-shell__content"><div class="slate-card slate-card__body slate-muted slate-text-sm">Page content</div></div></div></div></div>

Aspect ratio

Keep media at a fixed ratio.

16 / 9
1 / 1
4 / 3
View code
<div class="slate-aspect" style="width:14rem">16 / 9</div>
<div class="slate-aspect slate-aspect--square" style="width:7rem">1 / 1</div>
<div class="slate-aspect slate-aspect--4x3" style="width:9rem">4 / 3</div>

Scroll area

Constrained scrolling with quiet scrollbars.

Item one

Item two

Item three

Item four

Item five

Item six

View code
<div class="slate-scroll slate-card" style="width:18rem;max-height:9rem"><div class="slate-card__body slate-stack slate-stack--sm"><p>Item one</p><p>Item two</p><p>Item three</p><p>Item four</p><p>Item five</p><p>Item six</p></div></div>
25 components

Forms

Dense 32px controls with crisp borders and a soft accent ring on focus.

Field

Label above, hint or error below. Errors replace hints so the layout never jumps.

Shown to everyone on the team.
Enter a full email address.
Available
View code
<div class="slate-field" style="width:16rem"><label class="slate-label" for="f1">Project name</label><input class="slate-input" id="f1" placeholder="Acme redesign"><span class="slate-hint">Shown to everyone on the team.</span></div>
<div class="slate-field" style="width:16rem"><label class="slate-label slate-label--required" for="f2">Email</label><input class="slate-input" id="f2" value="ada@" aria-invalid="true"><span class="slate-error"><svg class="slate-icon slate-icon--sm" aria-hidden="true"><use href="#slate-icon-alert-circle"/></svg>Enter a full email address.</span></div>
<div class="slate-field" style="width:16rem"><label class="slate-label" for="f3">Handle <span class="slate-label__opt">optional</span></label><input class="slate-input slate-input--valid" id="f3" value="ada"><span class="slate-success-text">Available</span></div>

Input

Text entry in three sizes plus disabled and read-only.

View code
<input class="slate-input slate-input--sm" style="width:12rem" placeholder="Small">
<input class="slate-input" style="width:12rem" placeholder="Default">
<input class="slate-input slate-input--lg" style="width:12rem" placeholder="Large">
<input class="slate-input" style="width:12rem" value="Disabled" disabled>
<input class="slate-input" style="width:12rem" value="Read only" readonly>
<input class="slate-input slate-input--mono" style="width:12rem" value="sk_live_4eC39Hq">

Textarea

Multi-line text with counter.

Bio 42 / 200
View code
<div class="slate-field" style="width:20rem"><div class="slate-label">Bio <span class="slate-counter">42 / 200</span></div><textarea class="slate-textarea" placeholder="Tell us about yourself"></textarea></div>

Select

Native select styled to match. Keeps mobile pickers and accessibility.

View code
<select class="slate-select" style="width:14rem"><option>Net 30</option><option>Net 15</option><option>Due on receipt</option></select>
<select class="slate-select" style="width:14rem" aria-invalid="true"><option>Choose a role</option></select>
<select class="slate-select" style="width:14rem" disabled><option>Disabled</option></select>

Input group

Add icons, text addons or actions to either end.

https://
$USD
.slateos.app
View code
<div class="slate-input-group" style="width:17rem"><span class="slate-input-group__addon">https://</span><input class="slate-input" placeholder="acme.com"></div>
<div class="slate-input-group" style="width:14rem"><span class="slate-input-group__addon">lt;/span><input class="slate-input slate-input--right" value="12,480.00"><span class="slate-input-group__addon">USD</span></div>
<div class="slate-input-group" style="width:17rem"><input class="slate-input" value="acme"><span class="slate-input-group__addon">.slateos.app</span></div>

Password

Reveal toggle and strength meter.

Strong · 21 characters
View code
<div class="slate-field" style="width:18rem"><label class="slate-label">Password</label><div class="slate-input-group"><input class="slate-input" type="password" value="correct-horse-battery"><span class="slate-input-group__action"><button class="slate-button slate-button--ghost slate-button--icon slate-button--xs" aria-label="Show password"><svg class="slate-icon" aria-hidden="true"><use href="#slate-icon-eye"/></svg></button></span></div><div class="slate-strength" data-level="4"><i></i><i></i><i></i><i></i></div><span class="slate-hint">Strong · 21 characters</span></div>

Number stepper

Increment and decrement with buttons.

View code
<div class="slate-stepper-input"><button aria-label="Decrease"><svg class="slate-icon" aria-hidden="true"><use href="#slate-icon-minus"/></svg></button><input value="12" aria-label="Seats"><button aria-label="Increase"><svg class="slate-icon" aria-hidden="true"><use href="#slate-icon-plus"/></svg></button></div>

Checkbox

With descriptions, indeterminate and disabled states.

View code
<div class="slate-check-group"><label class="slate-check"><input type="checkbox" checked><span>Email notifications<span class="slate-check__desc">Get a digest every Monday.</span></span></label><label class="slate-check"><input type="checkbox"><span>Product updates</span></label><label class="slate-check"><input type="checkbox" data-indeterminate><span>Select all (partial)</span></label><label class="slate-check"><input type="checkbox" disabled><span>Disabled</span></label></div>

Radio

Single choice from a short list.

View code
<div class="slate-check-group"><label class="slate-radio"><input type="radio" name="r1" checked><span>Monthly</span></label><label class="slate-radio"><input type="radio" name="r1"><span>Quarterly</span></label><label class="slate-radio"><input type="radio" name="r1"><span>Yearly <span class="slate-badge slate-badge--success">Save 20%</span></span></label></div>

Switch

Immediate on/off. Use a checkbox when a form needs saving.

View code
<label class="slate-switch"><input type="checkbox" role="switch" checked>Auto-renew</label>
<label class="slate-switch"><input type="checkbox" role="switch">Notifications</label>
<label class="slate-switch slate-switch--lg"><input type="checkbox" role="switch" checked>Large</label>
<label class="slate-switch"><input type="checkbox" role="switch" disabled>Disabled</label>

Option card

Radio or checkbox presented as a selectable card.

View code
<div class="slate-grid slate-grid--3" style="width:100%"><label class="slate-option-card"><input class="slate-sr-only" type="radio" name="plan"><div><div class="slate-option-card__title">Starter</div><div class="slate-option-card__desc">Up to 5 seats</div></div></label><label class="slate-option-card"><input class="slate-sr-only" type="radio" name="plan" checked><div><div class="slate-option-card__title">Business</div><div class="slate-option-card__desc">Up to 50 seats</div></div></label><label class="slate-option-card"><input class="slate-sr-only" type="radio" name="plan"><div><div class="slate-option-card__title">Enterprise</div><div class="slate-option-card__desc">Unlimited + SSO</div></div></label></div>

Segmented control

Switch between views with a sliding selection look.

View code
<div class="slate-segmented"><button aria-pressed="true">Overview</button><button aria-pressed="false">Activity</button><button aria-pressed="false">Settings</button></div>
<div class="slate-segmented"><button aria-pressed="true"><svg class="slate-icon slate-icon--sm" aria-hidden="true"><use href="#slate-icon-list"/></svg>List</button><button aria-pressed="false"><svg class="slate-icon slate-icon--sm" aria-hidden="true"><use href="#slate-icon-grid"/></svg>Grid</button></div>

Slider

Single value range with fill.

View code
<div class="slate-field" style="width:18rem"><label class="slate-label">Discount <span class="slate-counter">35%</span></label><input type="range" class="slate-slider" min="0" max="100" value="35"></div>

Rating

Click to rate.

View code
<div class="slate-rating"><button aria-pressed="true" aria-label="1 star"><svg viewBox="0 0 24 24"><path d="m12 3.500 2.600 5.400 5.900.8-4.300 4.100 1 5.800L12 16.800 6.800 19.600l1-5.800L3.500 9.700l5.900-.8z"/></svg></button><button aria-pressed="true" aria-label="2 stars"><svg viewBox="0 0 24 24"><path d="m12 3.500 2.600 5.400 5.900.8-4.300 4.100 1 5.800L12 16.800 6.800 19.600l1-5.800L3.500 9.700l5.900-.8z"/></svg></button><button aria-pressed="true" aria-label="3 stars"><svg viewBox="0 0 24 24"><path d="m12 3.500 2.600 5.400 5.900.8-4.300 4.100 1 5.800L12 16.800 6.800 19.600l1-5.800L3.500 9.700l5.900-.8z"/></svg></button><button aria-pressed="false" aria-label="4 stars"><svg viewBox="0 0 24 24"><path d="m12 3.500 2.600 5.400 5.900.8-4.300 4.100 1 5.800L12 16.800 6.800 19.600l1-5.800L3.500 9.700l5.900-.8z"/></svg></button><button aria-pressed="false" aria-label="5 stars"><svg viewBox="0 0 24 24"><path d="m12 3.500 2.600 5.400 5.900.8-4.300 4.100 1 5.800L12 16.800 6.800 19.600l1-5.800L3.500 9.700l5.900-.8z"/></svg></button></div>

File upload

Drop zone plus file rows with progress and errors.

Click to upload or drag and drop
PDF, PNG up to 10 MB
PDF
contract-signed.pdf
PNG
remittance.png
ZIP
export.zip
Unsupported file type
View code
<div class="slate-dropzone" style="width:100%"><span class="slate-dropzone__icon"><svg class="slate-icon" aria-hidden="true"><use href="#slate-icon-upload"/></svg></span><div><strong>Click to upload</strong> or drag and drop</div><span class="slate-hint">PDF, PNG up to 10 MB</span></div>
<div class="slate-file" style="width:100%"><span class="slate-file__icon">PDF</span><div class="slate-grow"><div class="slate-text-sm slate-strong">contract-signed.pdf</div><div class="slate-progress slate-progress--sm slate-progress--success" style="margin-top:.35rem;--slate-value:100%"><i></i></div></div><svg class="slate-icon" aria-hidden="true"><use href="#slate-icon-check-circle"/></svg></div>
<div class="slate-file" style="width:100%"><span class="slate-file__icon">PNG</span><div class="slate-grow"><div class="slate-text-sm slate-strong">remittance.png</div><div class="slate-progress slate-progress--sm" style="margin-top:.35rem;--slate-value:62%"><i></i></div></div><button class="slate-close" aria-label="Cancel"><svg class="slate-icon slate-icon--sm" aria-hidden="true"><use href="#slate-icon-x"/></svg></button></div>
<div class="slate-file slate-file--error" style="width:100%"><span class="slate-file__icon">ZIP</span><div class="slate-grow"><div class="slate-text-sm slate-strong">export.zip</div><div class="slate-error">Unsupported file type</div></div><button class="slate-button slate-button--ghost slate-button--sm">Retry</button></div>

OTP input

One-time code entry.

View code
<div class="slate-otp"><input maxlength="1" value="4" aria-label="Digit 1"><input maxlength="1" value="8" aria-label="Digit 2"><input maxlength="1" value="2" aria-label="Digit 3"><span class="slate-otp__sep"></span><input maxlength="1" aria-label="Digit 4"><input maxlength="1" aria-label="Digit 5"><input maxlength="1" aria-label="Digit 6"></div>

Tag input

Type and press Enter to add values.

design engineering ops
View code
<div class="slate-tag-input" style="width:22rem"><span class="slate-tag">design <button aria-label="Remove"><svg class="slate-icon slate-icon--sm" aria-hidden="true"><use href="#slate-icon-x"/></svg></button></span><span class="slate-tag">engineering <button aria-label="Remove"><svg class="slate-icon slate-icon--sm" aria-hidden="true"><use href="#slate-icon-x"/></svg></button></span><span class="slate-tag">ops <button aria-label="Remove"><svg class="slate-icon slate-icon--sm" aria-hidden="true"><use href="#slate-icon-x"/></svg></button></span><input placeholder="Add tag…" aria-label="Add tag"></div>

Combobox

Searchable select with highlighted matches and groups.

Finance
PNPriya NairController
PSPrincess Sato
PMPriya MenonOn leave
View code
<div class="slate-combobox" style="width:18rem"><div class="slate-input-group"><span class="slate-input-group__icon"><svg class="slate-icon" aria-hidden="true"><use href="#slate-icon-search"/></svg></span><input class="slate-input" value="pri" aria-label="Assign to"></div>
<div class="slate-listbox" role="listbox" style="position:static;margin-top:.25rem"><div class="slate-option-group">Finance</div><div class="slate-option is-active" role="option"><span class="slate-avatar slate-avatar--sm">PN</span><span><mark>Pri</mark>ya Nair</span><span class="slate-option__meta">Controller</span></div><div class="slate-option" role="option" aria-selected="true"><span class="slate-avatar slate-avatar--sm">PS</span><span><mark>Pri</mark>ncess Sato</span></div><div class="slate-option" role="option" aria-disabled="true"><span class="slate-avatar slate-avatar--sm">PM</span><span><mark>Pri</mark>ya Menon</span><span class="slate-option__meta">On leave</span></div></div></div>

Date picker

Month grid with range selection.

October 2026
MTWTFSS
Oct 13 – Oct 17 · 5 days
View code
<div class="slate-calendar"><div class="slate-calendar__head"><button class="slate-button slate-button--ghost slate-button--icon slate-button--xs" aria-label="Previous month"><svg class="slate-icon" aria-hidden="true"><use href="#slate-icon-chevron-left"/></svg></button>October 2026<button class="slate-button slate-button--ghost slate-button--icon slate-button--xs" aria-label="Next month"><svg class="slate-icon" aria-hidden="true"><use href="#slate-icon-chevron-right"/></svg></button></div>
<div class="slate-calendar__grid"><span class="slate-calendar__dow">M</span><span class="slate-calendar__dow">T</span><span class="slate-calendar__dow">W</span><span class="slate-calendar__dow">T</span><span class="slate-calendar__dow">F</span><span class="slate-calendar__dow">S</span><span class="slate-calendar__dow">S</span>
<button class="slate-calendar__day slate-calendar__day--out">28</button><button class="slate-calendar__day slate-calendar__day--out">29</button><button class="slate-calendar__day slate-calendar__day--out">30</button><button class="slate-calendar__day">1</button><button class="slate-calendar__day">2</button><button class="slate-calendar__day">3</button><button class="slate-calendar__day">4</button>
<button class="slate-calendar__day">5</button><button class="slate-calendar__day">6</button><button class="slate-calendar__day">7</button><button class="slate-calendar__day">8</button><button class="slate-calendar__day">9</button><button class="slate-calendar__day">10</button><button class="slate-calendar__day">11</button>
<button class="slate-calendar__day">12</button><button class="slate-calendar__day slate-calendar__day--selected">13</button><button class="slate-calendar__day slate-calendar__day--range">14</button><button class="slate-calendar__day slate-calendar__day--range">15</button><button class="slate-calendar__day slate-calendar__day--range">16</button><button class="slate-calendar__day slate-calendar__day--selected">17</button><button class="slate-calendar__day">18</button>
<button class="slate-calendar__day">19</button><button class="slate-calendar__day">20</button><button class="slate-calendar__day">21</button><button class="slate-calendar__day">22</button><button class="slate-calendar__day">23</button><button class="slate-calendar__day">24</button><button class="slate-calendar__day">25</button>
<button class="slate-calendar__day">26</button><button class="slate-calendar__day">27</button><button class="slate-calendar__day slate-calendar__day--today">28</button><button class="slate-calendar__day" disabled>29</button><button class="slate-calendar__day" disabled>30</button><button class="slate-calendar__day" disabled>31</button><button class="slate-calendar__day slate-calendar__day--out">1</button></div>
<div class="slate-calendar__foot"><span class="slate-text-xs slate-subtle">Oct 13 – Oct 17 · 5 days</span><button class="slate-button slate-button--sm">Apply</button></div></div>

Time picker

Pick from a list of slots.

Start time
View code
<div class="slate-card" style="width:16rem"><div class="slate-card__body"><div class="slate-label" style="margin-bottom:.5rem">Start time</div><div class="slate-time-grid"><button class="slate-chip">09:00</button><button class="slate-chip">09:30</button><button class="slate-chip" aria-pressed="true">10:00</button><button class="slate-chip">10:30</button><button class="slate-chip">11:00</button><button class="slate-chip">11:30</button></div></div></div>

Color swatches

Pick from a palette.

View code
<div class="slate-swatches"><button class="slate-swatch" style="--c:#4155e8" aria-pressed="true" aria-label="Indigo"></button><button class="slate-swatch" style="--c:#0f9d8a" aria-label="Teal"></button><button class="slate-swatch" style="--c:#d98a0b" aria-label="Amber"></button><button class="slate-swatch" style="--c:#d6456b" aria-label="Rose"></button><button class="slate-swatch" style="--c:#8b5cf6" aria-label="Violet"></button><button class="slate-swatch" style="--c:#64748b" aria-label="Slate"></button></div>

Inline edit

Looks like text until hovered.

Q4 roadmap
View code
<span class="slate-inline-edit slate-h4" tabindex="0">Q4 roadmap <svg class="slate-icon" aria-hidden="true"><use href="#slate-icon-edit"/></svg></span>

Rich text editor

Toolbar chrome around any editable region.

Start typing…
View code
<div class="slate-editor" style="width:24rem"><div class="slate-editor__toolbar"><button class="slate-button slate-button--ghost slate-button--icon slate-button--sm" aria-label="Bold"><svg class="slate-icon" aria-hidden="true"><use href="#slate-icon-bold"/></svg></button><button class="slate-button slate-button--ghost slate-button--icon slate-button--sm" aria-label="Italic"><svg class="slate-icon" aria-hidden="true"><use href="#slate-icon-italic"/></svg></button><button class="slate-button slate-button--ghost slate-button--icon slate-button--sm" aria-label="Link"><svg class="slate-icon" aria-hidden="true"><use href="#slate-icon-link"/></svg></button><span class="slate-divider slate-divider--vertical"></span><button class="slate-button slate-button--ghost slate-button--icon slate-button--sm" aria-label="List"><svg class="slate-icon" aria-hidden="true"><use href="#slate-icon-list"/></svg></button><button class="slate-button slate-button--ghost slate-button--icon slate-button--sm" aria-label="Code"><svg class="slate-icon" aria-hidden="true"><use href="#slate-icon-code"/></svg></button></div><div class="slate-editor__body" contenteditable>Start typing…</div></div>

Form section

Two-column layout: description left, fields right.

Company
Appears on invoices sent to customers.
Required
View code
<form class="slate-form" style="width:100%" onsubmit="return false"><div class="slate-form-section"><div><div class="slate-form-section__title">Company</div><div class="slate-form-section__desc">Appears on invoices sent to customers.</div></div><div class="slate-form-grid"><div class="slate-field slate-span-full"><label class="slate-label slate-label--required">Legal name</label><input class="slate-input" aria-invalid="true"><span class="slate-error">Required</span></div><div class="slate-field"><label class="slate-label">Tax ID</label><input class="slate-input"></div><div class="slate-field"><label class="slate-label">Phone</label><input class="slate-input"></div></div></div><div class="slate-form-actions"><button class="slate-button slate-button--ghost">Cancel</button><button class="slate-button">Save changes</button></div></form>
23 components

Data display

Tables, cards, charts and the building blocks of dashboards.

Card

Hairline border, 8px radius, a whisper of shadow. Header and footer are optional.

Simple card

Content sits inside with consistent padding.

With header
Body content
View code
<div class="slate-card" style="width:18rem"><div class="slate-card__body"><div class="slate-card__title">Simple card</div><p class="slate-muted slate-text-sm" style="margin-top:.25rem">Content sits inside with consistent padding.</p></div></div>
<div class="slate-card" style="width:18rem"><div class="slate-card__header"><span class="slate-card__title">With header</span><button class="slate-button slate-button--ghost slate-button--icon slate-button--sm" aria-label="More"><svg class="slate-icon" aria-hidden="true"><use href="#slate-icon-more-horizontal"/></svg></button></div><div class="slate-card__body slate-muted slate-text-sm">Body content</div><div class="slate-card__footer"><button class="slate-button slate-button--secondary slate-button--sm">Cancel</button><button class="slate-button slate-button--sm">Save</button></div></div>

Card variants

Interactive, selected, glow and media.

Interactive
Hover me
Selected
Chosen plan
Glow
Featured
Media card
View code
<a class="slate-card slate-card--interactive slate-card__body" style="width:14rem;text-decoration:none;color:inherit" href="#card-variants"><span class="slate-eyebrow">Interactive</span><div class="slate-strong" style="margin-top:.25rem">Hover me <svg class="slate-icon slate-icon--sm" aria-hidden="true"><use href="#slate-icon-arrow-up-right"/></svg></div></a>
<div class="slate-card slate-card--selected slate-card__body" style="width:14rem"><span class="slate-eyebrow">Selected</span><div class="slate-strong" style="margin-top:.25rem">Chosen plan</div></div>
<div class="slate-card slate-card--glow slate-card__body" style="width:14rem"><span class="slate-eyebrow">Glow</span><div class="slate-strong" style="margin-top:.25rem">Featured</div></div>
<div class="slate-card slate-card--media" style="width:14rem"><div class="slate-aspect" style="border-radius:0"><svg class="slate-icon slate-icon--lg" aria-hidden="true"><use href="#slate-icon-image"/></svg></div><div class="slate-card__body"><div class="slate-strong">Media card</div></div></div>

Table

Sticky header, hairline rows, tabular numbers, hover actions.

CustomerStatusPlanMRRRenews
KLKestrel Logisticskestrel.coActiveEnterprise$4,200.00Nov 12, 2026
HMHalvorsen Marinehalvorsen.noPendingBusiness$980.00Dec 01, 2026
BWBrightwater Dentalbrightwater.comOverdueStarter$120.00Oct 30, 2026
View code
<div class="slate-table-wrap" style="width:100%"><table class="slate-table"><thead><tr><th>Customer</th><th>Status</th><th>Plan</th><th class="slate-table__num">MRR</th><th>Renews</th><th></th></tr></thead><tbody>
<tr><td><span class="slate-row slate-row--sm"><span class="slate-avatar slate-avatar--sm slate-avatar--square">KL</span><span><span class="slate-table__primary">Kestrel Logistics</span><span class="slate-table__sub">kestrel.co</span></span></span></td><td><span class="slate-status slate-status--success">Active</span></td><td>Enterprise</td><td class="slate-table__num">$4,200.00</td><td>Nov 12, 2026</td><td class="slate-table__actions"><button class="slate-button slate-button--ghost slate-button--icon slate-button--sm slate-row-actions" aria-label="Actions"><svg class="slate-icon" aria-hidden="true"><use href="#slate-icon-more-horizontal"/></svg></button></td></tr>
<tr><td><span class="slate-row slate-row--sm"><span class="slate-avatar slate-avatar--sm slate-avatar--square">HM</span><span><span class="slate-table__primary">Halvorsen Marine</span><span class="slate-table__sub">halvorsen.no</span></span></span></td><td><span class="slate-status slate-status--warning">Pending</span></td><td>Business</td><td class="slate-table__num">$980.00</td><td>Dec 01, 2026</td><td class="slate-table__actions"><button class="slate-button slate-button--ghost slate-button--icon slate-button--sm slate-row-actions" aria-label="Actions"><svg class="slate-icon" aria-hidden="true"><use href="#slate-icon-more-horizontal"/></svg></button></td></tr>
<tr><td><span class="slate-row slate-row--sm"><span class="slate-avatar slate-avatar--sm slate-avatar--square">BW</span><span><span class="slate-table__primary">Brightwater Dental</span><span class="slate-table__sub">brightwater.com</span></span></span></td><td><span class="slate-status slate-status--danger">Overdue</span></td><td>Starter</td><td class="slate-table__num">$120.00</td><td>Oct 30, 2026</td><td class="slate-table__actions"><button class="slate-button slate-button--ghost slate-button--icon slate-button--sm slate-row-actions" aria-label="Actions"><svg class="slate-icon" aria-hidden="true"><use href="#slate-icon-more-horizontal"/></svg></button></td></tr></tbody></table></div>

Data table

Selection, sortable columns, bulk actions and pagination in one.

Status
INV-2041Kestrel LogisticsOverdue$12,480.00
INV-2040Halvorsen MarinePending$3,215.40
INV-2039Brightwater DentalSent$8,760.00
INV-2038Oakline FoodsPaid$21,904.75
View code
<div style="width:100%"><div class="slate-table-toolbar"><div class="slate-input-group" style="width:15rem;height:var(--slate-size-control-sm)"><span class="slate-input-group__icon"><svg class="slate-icon slate-icon--sm" aria-hidden="true"><use href="#slate-icon-search"/></svg></span><input class="slate-input slate-input--sm" placeholder="Search invoices"></div><button class="slate-chip slate-chip--dashed"><svg class="slate-icon slate-icon--sm" aria-hidden="true"><use href="#slate-icon-plus"/></svg>Status</button><button class="slate-chip slate-chip--dashed"><svg class="slate-icon slate-icon--sm" aria-hidden="true"><use href="#slate-icon-plus"/></svg>Owner</button><span class="slate-spacer"></span><button class="slate-button slate-button--secondary slate-button--sm"><svg class="slate-icon slate-icon--sm" aria-hidden="true"><use href="#slate-icon-columns"/></svg>View</button><button class="slate-button slate-button--sm"><svg class="slate-icon slate-icon--sm" aria-hidden="true"><use href="#slate-icon-plus"/></svg>New</button></div>
<div class="slate-bulk-bar" id="demo-bulk" hidden style="margin-bottom:.75rem"><span><strong data-count>0</strong> selected</span><span class="slate-spacer"></span><button class="slate-button slate-button--ghost slate-button--sm"><svg class="slate-icon slate-icon--sm" aria-hidden="true"><use href="#slate-icon-send"/></svg>Remind</button><button class="slate-button slate-button--ghost slate-button--sm"><svg class="slate-icon slate-icon--sm" aria-hidden="true"><use href="#slate-icon-download"/></svg>Export</button><button class="slate-button slate-button--ghost slate-button--sm"><svg class="slate-icon slate-icon--sm" aria-hidden="true"><use href="#slate-icon-trash"/></svg>Delete</button></div>
<div class="slate-table-wrap"><table class="slate-table" data-selectable data-bulk="#demo-bulk"><thead><tr><th class="slate-table__check"><label class="slate-check"><input type="checkbox" aria-label="Select all"></label></th><th aria-sort="descending"><button class="slate-table__sort">Invoice <svg class="slate-icon slate-icon--sm" aria-hidden="true"><use href="#slate-icon-arrow-down"/></svg></button></th><th><button class="slate-table__sort">Customer <svg class="slate-icon slate-icon--sm" aria-hidden="true"><use href="#slate-icon-chevrons-up-down"/></svg></button></th><th>Status</th><th class="slate-table__num"><button class="slate-table__sort">Amount <svg class="slate-icon slate-icon--sm" aria-hidden="true"><use href="#slate-icon-chevrons-up-down"/></svg></button></th></tr></thead><tbody>
<tr><td class="slate-table__check"><label class="slate-check"><input type="checkbox" aria-label="Select row"></label></td><td class="slate-mono" data-sort="2041">INV-2041</td><td>Kestrel Logistics</td><td><span class="slate-status slate-status--danger">Overdue</span></td><td class="slate-table__num" data-sort="12480">$12,480.00</td></tr>
<tr><td class="slate-table__check"><label class="slate-check"><input type="checkbox" aria-label="Select row"></label></td><td class="slate-mono" data-sort="2040">INV-2040</td><td>Halvorsen Marine</td><td><span class="slate-status slate-status--warning">Pending</span></td><td class="slate-table__num" data-sort="3215">$3,215.40</td></tr>
<tr><td class="slate-table__check"><label class="slate-check"><input type="checkbox" aria-label="Select row"></label></td><td class="slate-mono" data-sort="2039">INV-2039</td><td>Brightwater Dental</td><td><span class="slate-status slate-status--info">Sent</span></td><td class="slate-table__num" data-sort="8760">$8,760.00</td></tr>
<tr><td class="slate-table__check"><label class="slate-check"><input type="checkbox" aria-label="Select row"></label></td><td class="slate-mono" data-sort="2038">INV-2038</td><td>Oakline Foods</td><td><span class="slate-status slate-status--success">Paid</span></td><td class="slate-table__num" data-sort="21904">$21,904.75</td></tr></tbody></table>
<div class="slate-table-footer"><span>1–4 of 128</span><div class="slate-pagination"><button class="slate-page" disabled aria-label="Previous"><svg class="slate-icon slate-icon--sm" aria-hidden="true"><use href="#slate-icon-chevron-left"/></svg></button><button class="slate-page" aria-current="page">1</button><button class="slate-page">2</button><button class="slate-page">3</button><button class="slate-page" aria-label="Next"><svg class="slate-icon slate-icon--sm" aria-hidden="true"><use href="#slate-icon-chevron-right"/></svg></button></div></div></div></div>

Table density

Dense, default and comfortable rows, plus striped and bordered.

Dense + stripedQty
Design review3
Engineering8
QA pass2
ComfortableQty
Design review3
Engineering8
Total11
View code
<div class="slate-grid slate-grid--2" style="width:100%"><div class="slate-table-wrap"><table class="slate-table slate-table--dense slate-table--striped"><thead><tr><th>Dense + striped</th><th class="slate-table__num">Qty</th></tr></thead><tbody><tr><td>Design review</td><td class="slate-table__num">3</td></tr><tr><td>Engineering</td><td class="slate-table__num">8</td></tr><tr><td>QA pass</td><td class="slate-table__num">2</td></tr></tbody></table></div><div class="slate-table-wrap"><table class="slate-table slate-table--comfy slate-table--bordered"><thead><tr><th>Comfortable</th><th class="slate-table__num">Qty</th></tr></thead><tbody><tr><td>Design review</td><td class="slate-table__num">3</td></tr><tr><td>Engineering</td><td class="slate-table__num">8</td></tr></tbody><tfoot><tr><td>Total</td><td class="slate-table__num">11</td></tr></tfoot></table></div></div>

List group

Rows with avatar, text and trailing actions.

View code
<div class="slate-list-group" style="width:22rem"><a class="slate-list-item" href="#list"><span class="slate-avatar slate-avatar--accent">AK</span><span class="slate-grow"><span class="slate-list-item__title">Aisha Khan</span><br><span class="slate-list-item__sub">Design lead</span></span><svg class="slate-icon" aria-hidden="true"><use href="#slate-icon-chevron-right"/></svg></a><a class="slate-list-item" href="#list"><span class="slate-avatar">RS</span><span class="slate-grow"><span class="slate-list-item__title">Rahul Sharma</span><br><span class="slate-list-item__sub">Engineering</span></span><span class="slate-status slate-status--success">Online</span></a><div class="slate-list-item"><span class="slate-avatar slate-avatar--success">LM</span><span class="slate-grow"><span class="slate-list-item__title">Lena Müller</span><br><span class="slate-list-item__sub">Finance</span></span><span class="slate-badge slate-badge--neutral">Away</span></div></div>

Description list

Key–value pairs for detail views.

Owner
Priya Nair
Plan
Enterprise · $4,200/mo
Billing email
ap@kestrel.co
Status
Active
View code
<dl class="slate-dl" style="width:26rem"><dt>Owner</dt><dd>Priya Nair</dd><dt>Plan</dt><dd>Enterprise · $4,200/mo</dd><dt>Billing email</dt><dd>ap@kestrel.co</dd><dt>Status</dt><dd><span class="slate-status slate-status--success">Active</span></dd></dl>

Stat

Metric with trend. Use a row to group related numbers.

Outstanding$184,320.506.2% vs last month
Collected · 30d$246,11812.4%
Avg. days to pay28.4 days2.1 days faster
View code
<div class="slate-stat-row" style="width:100%"><div class="slate-stat"><span class="slate-stat__label">Outstanding</span><span class="slate-stat__value">$184,320<small>.50</small></span><span class="slate-delta slate-delta--down"><svg class="slate-icon slate-icon--sm" aria-hidden="true"><use href="#slate-icon-trending-up"/></svg>6.2% vs last month</span></div><div class="slate-stat"><span class="slate-stat__label">Collected · 30d</span><span class="slate-stat__value">$246,118</span><span class="slate-delta slate-delta--up"><svg class="slate-icon slate-icon--sm" aria-hidden="true"><use href="#slate-icon-trending-up"/></svg>12.4%</span></div><div class="slate-stat"><span class="slate-stat__label">Avg. days to pay</span><span class="slate-stat__value">28.4<small> days</small></span><span class="slate-delta slate-delta--up"><svg class="slate-icon slate-icon--sm" aria-hidden="true"><use href="#slate-icon-trending-down"/></svg>2.1 days faster</span></div></div>

Progress

Linear bars in five tones, striped and indeterminate.

View code
<div class="slate-progress" style="--slate-value:68%;width:100%"><i></i></div>
<div class="slate-progress slate-progress--success" style="--slate-value:100%;width:100%"><i></i></div>
<div class="slate-progress slate-progress--warning slate-progress--lg" style="--slate-value:45%;width:100%"><i></i></div>
<div class="slate-progress slate-progress--danger slate-progress--sm" style="--slate-value:92%;width:100%"><i></i></div>
<div class="slate-progress slate-progress--striped" style="--slate-value:55%;width:100%"><i></i></div>
<div class="slate-progress slate-progress--indeterminate" style="width:100%"><i></i></div>

Progress ring and meter

Circular and segmented indicators.

72%
40%
View code
<div class="slate-ring" style="--slate-value:72"><span>72%</span></div>
<div class="slate-ring slate-ring--lg" style="--slate-value:40"><span>40%</span></div>
<div class="slate-meter" style="width:8rem"><i class="is-on"></i><i class="is-on"></i><i class="is-on"></i><i></i><i></i></div>

Bar chart

CSS-only bars using chart tokens. Swap in any chart library and keep the palette.

Revenue by month
SubscriptionsServices
60k40k20k0
MayJunJulAugSepOct
View code
<div class="slate-chart" style="width:100%"><div class="slate-row slate-row--between"><div class="slate-strong slate-text-sm">Revenue by month</div><div class="slate-legend"><span>Subscriptions</span><span style="--c:var(--slate-chart-2)">Services</span></div></div>
<div class="slate-chart__plot"><div class="slate-chart__ylabels"><span>60k</span><span>40k</span><span>20k</span><span>0</span></div>
<div class="slate-chart__bar"><i style="--h:42%"></i><i style="--h:12%"></i></div><div class="slate-chart__bar"><i style="--h:52%"></i><i style="--h:14%"></i></div><div class="slate-chart__bar"><i style="--h:48%"></i><i style="--h:18%"></i></div><div class="slate-chart__bar"><i style="--h:63%"></i><i style="--h:15%"></i></div><div class="slate-chart__bar"><i style="--h:70%"></i><i style="--h:20%"></i></div><div class="slate-chart__bar"><i style="--h:78%"></i><i style="--h:16%"></i></div></div>
<div class="slate-chart__axis"><span>May</span><span>Jun</span><span>Jul</span><span>Aug</span><span>Sep</span><span>Oct</span></div></div>

Sparkline

Tiny inline trend.

View code
<svg class="slate-sparkline" viewBox="0 0 100 30" preserveAspectRatio="none" style="width:8rem"><path class="area" d="M0 24 L12 20 L25 22 L38 14 L50 16 L63 8 L76 11 L88 4 L100 6 V30 H0Z"/><path d="M0 24 L12 20 L25 22 L38 14 L50 16 L63 8 L76 11 L88 4 L100 6"/></svg>
<svg class="slate-sparkline" viewBox="0 0 100 30" preserveAspectRatio="none" style="width:8rem;--slate-chart-1:var(--slate-chart-4)"><path d="M0 6 L14 10 L28 8 L42 18 L56 14 L70 22 L84 20 L100 26"/></svg>

Donut chart

Proportions with a centre label.

1,284
accounts
Enterprise · 45%Business · 25%Starter · 18%Free · 12%
View code
<div class="slate-row slate-row--lg"><div class="slate-donut" style="--a:45%;--b:70%;--c:88%"><div><div class="slate-h4">1,284</div><div class="slate-text-xs slate-subtle">accounts</div></div></div><div class="slate-stack slate-stack--sm slate-legend" style="flex-direction:column;gap:.5rem"><span>Enterprise · 45%</span><span style="--c:var(--slate-chart-2)">Business · 25%</span><span style="--c:var(--slate-chart-3)">Starter · 18%</span><span style="--c:var(--slate-chart-6)">Free · 12%</span></div></div>

Heatmap

Intensity grid for activity over time.

View code
<div class="slate-heatmap" style="--cols:16;width:24rem"><i style="--v:.1"></i><i style="--v:.3"></i><i style="--v:.6"></i><i style="--v:.2"></i><i style="--v:.9"></i><i style="--v:.5"></i><i style="--v:.1"></i><i style="--v:.0"></i><i style="--v:.4"></i><i style="--v:.7"></i><i style="--v:.8"></i><i style="--v:.3"></i><i style="--v:.2"></i><i style="--v:.6"></i><i style="--v:1"></i><i style="--v:.5"></i><i style="--v:.2"></i><i style="--v:.0"></i><i style="--v:.4"></i><i style="--v:.9"></i><i style="--v:.6"></i><i style="--v:.3"></i><i style="--v:.1"></i><i style="--v:.7"></i><i style="--v:.5"></i><i style="--v:.8"></i><i style="--v:.2"></i><i style="--v:.0"></i><i style="--v:.3"></i><i style="--v:.6"></i><i style="--v:.9"></i><i style="--v:.4"></i></div>

Empty state

Explain why it is empty and offer one next step.

No invoices yet

Create your first invoice or import a CSV from your old system.

View code
<div class="slate-empty"><span class="slate-empty__icon"><svg class="slate-icon" aria-hidden="true"><use href="#slate-icon-inbox"/></svg></span><div class="slate-empty__title">No invoices yet</div><p class="slate-empty__desc">Create your first invoice or import a CSV from your old system.</p><div class="slate-row"><button class="slate-button slate-button--secondary slate-button--sm">Import CSV</button><button class="slate-button slate-button--sm"><svg class="slate-icon slate-icon--sm" aria-hidden="true"><use href="#slate-icon-plus"/></svg>New invoice</button></div></div>

Accordion

Native details elements: accessible with no JavaScript.

Billing
Invoices are generated on the first business day.
Security
SSO, two-factor and session policies.
Integrations
Connect Slack, Notion and your accounting tool.
View code
<div class="slate-accordion" style="width:100%"><details open><summary>Billing</summary><div class="slate-accordion__body">Invoices are generated on the first business day.</div></details><details><summary>Security</summary><div class="slate-accordion__body">SSO, two-factor and session policies.</div></details><details><summary>Integrations</summary><div class="slate-accordion__body">Connect Slack, Notion and your accounting tool.</div></details></div>

Timeline

Vertical history with tonal markers.

  • Payment received
    $12,480.00 from Kestrel
  • Reminder sent
  • Payment failed
    Card declined
  • Invoice created
View code
<ul class="slate-timeline" style="width:20rem"><li data-tone="success"><strong>Payment received</strong><br><span class="slate-muted">$12,480.00 from Kestrel</span><time>2 hours ago</time></li><li data-tone="accent"><strong>Reminder sent</strong><time>Yesterday</time></li><li data-tone="danger"><strong>Payment failed</strong><br><span class="slate-muted">Card declined</span><time>Oct 20</time></li><li><strong>Invoice created</strong><time>Oct 02</time></li></ul>

Tree

Nested navigation for files and hierarchies.

  • src
    • index.html
    • styles.css
    • assets
  • docs
View code
<ul class="slate-tree" style="width:14rem"><li><div class="slate-tree__item"><svg class="slate-icon slate-icon--sm" aria-hidden="true"><use href="#slate-icon-chevron-down"/></svg><svg class="slate-icon slate-icon--sm" aria-hidden="true"><use href="#slate-icon-folder"/></svg>src</div><ul><li><div class="slate-tree__item" aria-selected="true"><svg class="slate-icon slate-icon--sm" aria-hidden="true"><use href="#slate-icon-file-text"/></svg>index.html</div></li><li><div class="slate-tree__item"><svg class="slate-icon slate-icon--sm" aria-hidden="true"><use href="#slate-icon-file-text"/></svg>styles.css</div></li><li><div class="slate-tree__item"><svg class="slate-icon slate-icon--sm" aria-hidden="true"><use href="#slate-icon-chevron-right"/></svg><svg class="slate-icon slate-icon--sm" aria-hidden="true"><use href="#slate-icon-folder"/></svg>assets</div></li></ul></li><li><div class="slate-tree__item"><svg class="slate-icon slate-icon--sm" aria-hidden="true"><use href="#slate-icon-chevron-right"/></svg><svg class="slate-icon slate-icon--sm" aria-hidden="true"><use href="#slate-icon-folder"/></svg>docs</div></li></ul>

Kanban board

Columns of draggable cards.

Lead 2
Kestrel renewal
$4,200 · Nov 12
Halvorsen upsell
$1,200 · Dec 01
Negotiation 1
Oakline expansion
$9,800 · Jan 15
Won 0
View code
<div class="slate-board" style="width:100%"><div class="slate-board__col"><div class="slate-board__head">Lead <span class="slate-badge slate-badge--count slate-badge--neutral">2</span></div><div class="slate-board__card">Kestrel renewal<div class="slate-text-xs slate-subtle" style="margin-top:.25rem">$4,200 · Nov 12</div></div><div class="slate-board__card">Halvorsen upsell<div class="slate-text-xs slate-subtle" style="margin-top:.25rem">$1,200 · Dec 01</div></div></div><div class="slate-board__col"><div class="slate-board__head">Negotiation <span class="slate-badge slate-badge--count slate-badge--neutral">1</span></div><div class="slate-board__card is-dragging">Oakline expansion<div class="slate-text-xs slate-subtle" style="margin-top:.25rem">$9,800 · Jan 15</div></div></div><div class="slate-board__col"><div class="slate-board__head">Won <span class="slate-badge slate-badge--count slate-badge--neutral">0</span></div><div class="slate-board__drop"></div></div></div>

Code block

Filename bar with a copy action.

index.html
<link rel="stylesheet" href="slateos.css">
<button class="slate-button">Save</button>
View code
<div class="slate-codeblock" style="width:100%"><div class="slate-codeblock__bar"><span>index.html</span><button class="slate-button slate-button--ghost slate-button--icon slate-button--xs" data-slate-copy="#cb1" aria-label="Copy" data-tooltip="Copy"><svg class="slate-icon" aria-hidden="true"><use href="#slate-icon-copy"/></svg></button></div><pre id="cb1"><code>&lt;link rel="stylesheet" href="slateos.css"&gt;
&lt;button class="slate-button"&gt;Save&lt;/button&gt;</code></pre></div>

Diff

Before and after values.

Business → Enterprise
View code
<span class="slate-diff"><del>Business</del> → <ins>Enterprise</ins></span>

Feature

Icon, title and description for marketing and onboarding.

Fast by default

Plain CSS and zero runtime dependencies.

View code
<div class="slate-feature" style="width:16rem"><span class="slate-feature__icon"><svg class="slate-icon" aria-hidden="true"><use href="#slate-icon-zap"/></svg></span><div class="slate-strong">Fast by default</div><p class="slate-muted slate-text-sm">Plain CSS and zero runtime dependencies.</p></div>
8 components

Feedback

Tell people what happened, calmly.

Alert

Inline messages in five tones. Soft fill, tinted hairline.

Trial ends in 5 days
Add a payment method to keep your data and integrations.
Payment received
Invoice INV-2038 was paid in full.
Seats nearly full
48 of 50 seats are in use.
Bank sync failed
Reconnect to resume imports.
View code
<div class="slate-alert" style="width:100%"><svg class="slate-icon slate-icon--lg" aria-hidden="true"><use href="#slate-icon-info"/></svg><div><div class="slate-alert__title">Trial ends in 5 days</div><div class="slate-alert__body">Add a payment method to keep your data and integrations.</div></div></div>
<div class="slate-alert slate-alert--success" style="width:100%"><svg class="slate-icon slate-icon--lg" aria-hidden="true"><use href="#slate-icon-check-circle"/></svg><div><div class="slate-alert__title">Payment received</div><div class="slate-alert__body">Invoice INV-2038 was paid in full.</div></div></div>
<div class="slate-alert slate-alert--warning" style="width:100%"><svg class="slate-icon slate-icon--lg" aria-hidden="true"><use href="#slate-icon-alert-triangle"/></svg><div><div class="slate-alert__title">Seats nearly full</div><div class="slate-alert__body">48 of 50 seats are in use.</div></div></div>
<div class="slate-alert slate-alert--danger" style="width:100%"><svg class="slate-icon slate-icon--lg" aria-hidden="true"><use href="#slate-icon-x-circle"/></svg><div class="slate-grow"><div class="slate-alert__title">Bank sync failed</div><div class="slate-alert__body">Reconnect to resume imports.</div></div><button class="slate-button slate-button--secondary slate-button--sm">Reconnect</button></div>

Alert variants

Neutral, accent and left-rule styles.

A neutral note with no tone.
New: command palette
Press ⌘K from anywhere.
View code
<div class="slate-alert slate-alert--neutral" style="width:100%"><svg class="slate-icon slate-icon--lg" aria-hidden="true"><use href="#slate-icon-info"/></svg><div>A neutral note with no tone.</div></div>
<div class="slate-alert slate-alert--accent slate-alert--leading" style="width:100%"><svg class="slate-icon slate-icon--lg" aria-hidden="true"><use href="#slate-icon-sparkles"/></svg><div><div class="slate-alert__title">New: command palette</div><div class="slate-alert__body">Press ⌘K from anywhere.</div></div></div>

Callout

Highlighted guidance inside documentation.

Good to know
Tokens are checked for WCAG AA contrast at build time, so themes can't regress.
View code
<div class="slate-callout" style="width:26rem"><div class="slate-callout__title"><svg class="slate-icon" aria-hidden="true"><use href="#slate-icon-info"/></svg>Good to know</div>Tokens are checked for WCAG AA contrast at build time, so themes can't regress.</div>

Announcement pill

A small link above a hero heading.

View code
<a class="slate-announcement" href="#announce"><span class="slate-badge slate-badge--solid">New</span>Dark mode is here <svg class="slate-icon slate-icon--sm" aria-hidden="true"><use href="#slate-icon-arrow-right"/></svg></a>

Toast

Transient confirmation. Fire from code with slate.toast(). Click to try.

Invoice sent
Kestrel Logistics will receive it shortly.
Project archived
View code
<div class="slate-toast slate-toast--success" style="width:22rem"><svg class="slate-icon slate-icon--lg" aria-hidden="true"><use href="#slate-icon-check-circle"/></svg><div class="slate-grow"><div class="slate-toast__title">Invoice sent</div><div class="slate-toast__desc">Kestrel Logistics will receive it shortly.</div></div><button class="slate-close" aria-label="Dismiss"><svg class="slate-icon slate-icon--sm" aria-hidden="true"><use href="#slate-icon-x"/></svg></button></div>
<div class="slate-toast slate-toast--inverse" style="width:22rem"><div class="slate-grow">Project archived</div><button class="slate-button slate-button--ghost slate-button--xs">Undo</button></div>
<button class="slate-button slate-button--secondary" data-slate-toast="Changes saved|Your profile was updated.|success">Show success</button>
<button class="slate-button slate-button--secondary" data-slate-toast="Upload failed|File is larger than 10 MB.|danger">Show error</button>
<button class="slate-button slate-button--secondary" data-slate-toast="Heads up|Seats are nearly full.|warning">Show warning</button>

Result page

Success, 404 and error states for full screens.

You're all set

Your workspace is ready. Invite your team to get started.

404
Page not found

The page you're looking for was moved or never existed.

View code
<div class="slate-grid slate-grid--2" style="width:100%"><div class="slate-result"><span class="slate-result__icon"><svg class="slate-icon slate-icon--lg" aria-hidden="true"><use href="#slate-icon-check"/></svg></span><div class="slate-result__title">You're all set</div><p class="slate-result__desc">Your workspace is ready. Invite your team to get started.</p><button class="slate-button">Invite teammates</button></div><div class="slate-result"><div class="slate-result__code">404</div><div class="slate-result__title">Page not found</div><p class="slate-result__desc">The page you're looking for was moved or never existed.</p><button class="slate-button slate-button--secondary">Back to dashboard</button></div></div>

Upgrade banner

A soft call to action inside the app.

Unlock unlimited projects
Upgrade to Business for SSO, audit logs and priority support.
View code
<div class="slate-banner-cta" style="width:100%"><div><div class="slate-strong">Unlock unlimited projects</div><div class="slate-muted slate-text-sm">Upgrade to Business for SSO, audit logs and priority support.</div></div><button class="slate-button">Upgrade</button></div>
11 components

Navigation

Moving around: top bars, sidebars, tabs and steps.

Tabs

Underlined tabs with arrow-key support. Add the runtime for panel switching.

Overview panel content.
View code
<div class="slate-tabs" role="tablist" style="width:100%"><button class="slate-tab" role="tab" aria-selected="true" aria-controls="p1">Overview</button><button class="slate-tab" role="tab" aria-selected="false" aria-controls="p2">Invoices <span class="slate-badge slate-badge--neutral slate-badge--count">14</span></button><button class="slate-tab" role="tab" aria-selected="false" aria-controls="p3">Activity</button><button class="slate-tab" disabled>Disabled</button></div>
<div class="slate-tabpanel" id="p1" role="tabpanel">Overview panel content.</div><div class="slate-tabpanel" id="p2" role="tabpanel" hidden>Invoices panel content.</div><div class="slate-tabpanel" id="p3" role="tabpanel" hidden>Activity panel content.</div>

Pill tabs

Filled selection for dense toolbars.

View code
<div class="slate-tabs slate-tabs--pills" role="tablist"><button class="slate-tab" role="tab" aria-selected="true">All</button><button class="slate-tab" role="tab" aria-selected="false">Open</button><button class="slate-tab" role="tab" aria-selected="false">Closed</button></div>

Vertical tabs

Settings-style side navigation.

View code
<div class="slate-tabs slate-tabs--vertical" role="tablist" style="width:11rem"><button class="slate-tab" role="tab" aria-selected="true"><svg class="slate-icon slate-icon--sm" aria-hidden="true"><use href="#slate-icon-user"/></svg>Profile</button><button class="slate-tab" role="tab" aria-selected="false"><svg class="slate-icon slate-icon--sm" aria-hidden="true"><use href="#slate-icon-bell"/></svg>Notifications</button><button class="slate-tab" role="tab" aria-selected="false"><svg class="slate-icon slate-icon--sm" aria-hidden="true"><use href="#slate-icon-shield"/></svg>Security</button><button class="slate-tab" role="tab" aria-selected="false"><svg class="slate-icon slate-icon--sm" aria-hidden="true"><use href="#slate-icon-credit-card"/></svg>Billing</button></div>

Pagination

Compact page control.

…
View code
<div class="slate-pagination"><button class="slate-page" disabled aria-label="Previous"><svg class="slate-icon slate-icon--sm" aria-hidden="true"><use href="#slate-icon-chevron-left"/></svg></button><button class="slate-page" aria-current="page">1</button><button class="slate-page">2</button><button class="slate-page">3</button><span class="slate-page" style="pointer-events:none">…</span><button class="slate-page">24</button><button class="slate-page" aria-label="Next"><svg class="slate-icon slate-icon--sm" aria-hidden="true"><use href="#slate-icon-chevron-right"/></svg></button></div>

Steps

Progress through a multi-step flow.

  1. Account
  2. 2Team
  3. 3Billing
  1. Create
  2. 2Invite
  3. 3Launch
View code
<ol class="slate-steps"><li class="slate-step slate-step--done"><span class="slate-step__dot"><svg class="slate-icon slate-icon--sm" aria-hidden="true"><use href="#slate-icon-check"/></svg></span>Account</li><li class="slate-steps__line"></li><li class="slate-step slate-step--current"><span class="slate-step__dot">2</span>Team</li><li class="slate-steps__line"></li><li class="slate-step"><span class="slate-step__dot">3</span>Billing</li></ol>
<ol class="slate-steps slate-steps--vertical" style="width:10rem"><li class="slate-step slate-step--done"><span class="slate-step__dot"><svg class="slate-icon slate-icon--sm" aria-hidden="true"><use href="#slate-icon-check"/></svg></span>Create</li><li class="slate-steps__line"></li><li class="slate-step slate-step--current"><span class="slate-step__dot">2</span>Invite</li><li class="slate-steps__line"></li><li class="slate-step"><span class="slate-step__dot">3</span>Launch</li></ol>

Table of contents

In-page anchors with a current marker.

View code
<nav class="slate-toc" style="width:12rem"><a href="#toc">Overview</a><a href="#toc" aria-current="true">Installation</a><a href="#toc">Usage</a><a href="#toc">Theming</a></nav>

App bar and tab bar

Mobile chrome: title bar on top, thumb-reachable navigation below.

Invoices

INV-2041Overdue
INV-2040Pending
View code
<div class="slate-preview-frame" style="height:24rem;width:20rem;margin:1rem auto;border:1px solid var(--slate-border);border-radius:1.5rem;display:flex;flex-direction:column;background:var(--slate-bg)"><div class="slate-appbar"><button class="slate-button slate-button--ghost slate-button--icon" aria-label="Menu"><svg class="slate-icon" aria-hidden="true"><use href="#slate-icon-menu"/></svg></button><h1>Invoices</h1><button class="slate-button slate-button--ghost slate-button--icon" aria-label="Search"><svg class="slate-icon" aria-hidden="true"><use href="#slate-icon-search"/></svg></button></div><div class="slate-grow" style="padding:1rem"><div class="slate-list-group"><div class="slate-list-item">INV-2041<span class="slate-spacer"></span><span class="slate-status slate-status--danger">Overdue</span></div><div class="slate-list-item">INV-2040<span class="slate-spacer"></span><span class="slate-status slate-status--warning">Pending</span></div></div></div><nav class="slate-tabbar"><a href="#tb"><svg class="slate-icon" aria-hidden="true"><use href="#slate-icon-home"/></svg>Home</a><a href="#tb" aria-current="page"><svg class="slate-icon" aria-hidden="true"><use href="#slate-icon-file-text"/></svg>Invoices</a><a href="#tb"><svg class="slate-icon" aria-hidden="true"><use href="#slate-icon-building"/></svg>Customers</a><a href="#tb"><svg class="slate-icon" aria-hidden="true"><use href="#slate-icon-credit-card"/></svg>Payments<span class="slate-tabbar__pip"></span></a></nav></div>
10 components

Overlays

The only elements with real depth. Native dialog and popover patterns for accessibility.

Dialog

Native dialog element: focus trap, Esc to close and backdrop included.

Invite teammates
They'll get an email with a link to join.
View code
<button class="slate-button" data-slate-open="#dlg1">Open dialog</button>
<dialog class="slate-dialog" id="dlg1"><div class="slate-dialog__header"><div><div class="slate-dialog__title">Invite teammates</div><div class="slate-dialog__desc">They'll get an email with a link to join.</div></div><button class="slate-close" data-slate-close aria-label="Close"><svg class="slate-icon" aria-hidden="true"><use href="#slate-icon-x"/></svg></button></div><div class="slate-dialog__body"><div class="slate-field"><label class="slate-label">Email addresses</label><input class="slate-input" placeholder="name@company.com"></div></div><div class="slate-dialog__footer"><button class="slate-button slate-button--secondary" data-slate-close>Cancel</button><button class="slate-button" data-slate-close>Send invites</button></div></dialog>

Confirm dialog

Destructive confirmation that states the consequence in plain words.

Void INV-2041?

This removes $12,480.00 from receivables. The record is kept and you can't undo this.

View code
<div class="slate-dialog slate-dialog--static slate-dialog--sm"><div class="slate-dialog__body" style="display:flex;gap:.75rem"><span class="slate-dialog__icon"><svg class="slate-icon" aria-hidden="true"><use href="#slate-icon-alert-triangle"/></svg></span><div><div class="slate-dialog__title">Void INV-2041?</div><p class="slate-muted slate-text-sm" style="margin-top:.25rem">This removes $12,480.00 from receivables. The record is kept and you can't undo this.</p></div></div><div class="slate-dialog__footer"><button class="slate-button slate-button--secondary">Cancel</button><button class="slate-button slate-button--danger">Void invoice</button></div></div>

Drawer

Side panel for create, edit and detail flows.

View code
<div class="slate-preview-frame" style="height:26rem;width:100%;background:var(--slate-surface)"><div class="slate-scrim"></div><aside class="slate-drawer"><div class="slate-drawer__header"><span class="slate-strong">New customer</span><button class="slate-close" aria-label="Close"><svg class="slate-icon" aria-hidden="true"><use href="#slate-icon-x"/></svg></button></div><div class="slate-drawer__body slate-stack"><div class="slate-field"><label class="slate-label slate-label--required">Name</label><input class="slate-input"></div><div class="slate-field"><label class="slate-label">Plan</label><select class="slate-select"><option>Business</option></select></div></div><div class="slate-drawer__footer"><button class="slate-button slate-button--secondary">Cancel</button><button class="slate-button">Create</button></div></aside></div>

Bottom sheet

The mobile replacement for menus and dialogs.

View code
<div class="slate-preview-frame" style="height:22rem;width:20rem;margin:1rem auto;border:1px solid var(--slate-border);border-radius:1.5rem;background:var(--slate-surface)"><div class="slate-scrim"></div><div class="slate-sheet"><div class="slate-sheet__grab"></div><div class="slate-menu"><button class="slate-menu__item"><svg class="slate-icon" aria-hidden="true"><use href="#slate-icon-edit"/></svg>Edit</button><button class="slate-menu__item"><svg class="slate-icon" aria-hidden="true"><use href="#slate-icon-copy"/></svg>Duplicate</button><button class="slate-menu__item"><svg class="slate-icon" aria-hidden="true"><use href="#slate-icon-download"/></svg>Download PDF</button><button class="slate-menu__item slate-menu__item--danger"><svg class="slate-icon" aria-hidden="true"><use href="#slate-icon-trash"/></svg>Void invoice</button></div></div></div>

Popover

Rich content on click, with a small pointer.

View code
<div class="slate-dropdown"><button class="slate-button slate-button--secondary" data-slate-toggle="#pop1"><svg class="slate-icon slate-icon--sm" aria-hidden="true"><use href="#slate-icon-users"/></svg>Share</button><div class="slate-popover" id="pop1" hidden style="top:calc(100% + 8px);left:0;width:18rem"><div class="slate-strong">Invite people</div><p class="slate-muted slate-text-sm" style="margin:.25rem 0 .75rem">They'll have edit access.</p><div class="slate-row"><input class="slate-input slate-input--sm" placeholder="Email"><button class="slate-button slate-button--sm">Send</button></div></div></div>

Tooltip

CSS-only via data-tooltip. Appears on hover and focus.

Search ⌘K
View code
<button class="slate-button slate-button--secondary slate-button--icon" data-tooltip="Settings" aria-label="Settings"><svg class="slate-icon" aria-hidden="true"><use href="#slate-icon-settings"/></svg></button>
<button class="slate-button slate-button--secondary" data-tooltip="Duplicate this invoice" data-tooltip-pos="bottom">Hover me</button>
<span class="slate-tooltip">Search <kbd>⌘K</kbd></span>

Hover card

A richer preview of a link target.

PN
Priya Nair
Controller · Finance

Owns accounts receivable and month-end close.

View code
<div class="slate-hovercard"><div class="slate-row slate-row--top"><span class="slate-avatar slate-avatar--lg slate-avatar--accent">PN</span><div><div class="slate-strong">Priya Nair</div><div class="slate-muted slate-text-sm">Controller · Finance</div></div></div><p class="slate-muted slate-text-sm" style="margin-top:.75rem">Owns accounts receivable and month-end close.</p></div>

Command palette

Press ⌘K anywhere. Search, jump and act from one place.

esc
Customers
Kestrel Logistics14 invoices
Halvorsen Marine
Actions
New invoiceN
Export all⇧E
Toggle theme
↑ ↓ navigate↵ openesc close
View code
<div class="slate-command" style="margin:1.5rem auto"><div class="slate-command__input"><svg class="slate-icon" aria-hidden="true"><use href="#slate-icon-search"/></svg><input placeholder="Search or run a command…" value=""><kbd>esc</kbd></div><div class="slate-command__list"><div class="slate-menu__label">Customers</div><div class="slate-command__item" aria-selected="true"><svg class="slate-icon" aria-hidden="true"><use href="#slate-icon-building"/></svg>Kestrel Logistics<span class="slate-spacer"></span><span class="slate-text-xs slate-subtle">14 invoices</span></div><div class="slate-command__item"><svg class="slate-icon" aria-hidden="true"><use href="#slate-icon-building"/></svg>Halvorsen Marine</div><div class="slate-menu__label">Actions</div><div class="slate-command__item"><svg class="slate-icon" aria-hidden="true"><use href="#slate-icon-plus"/></svg>New invoice<span class="slate-spacer"></span><kbd>N</kbd></div><div class="slate-command__item"><svg class="slate-icon" aria-hidden="true"><use href="#slate-icon-download"/></svg>Export all<span class="slate-spacer"></span><kbd>⇧E</kbd></div><div class="slate-command__item"><svg class="slate-icon" aria-hidden="true"><use href="#slate-icon-moon"/></svg>Toggle theme</div></div><div class="slate-command__foot"><span><kbd>↑</kbd> <kbd>↓</kbd> navigate</span><span><kbd>↵</kbd> open</span><span><kbd>esc</kbd> close</span></div></div>

Context menu

The same menu, opened on right click.

View code
<div class="slate-menu" style="width:14rem"><button class="slate-menu__item"><svg class="slate-icon" aria-hidden="true"><use href="#slate-icon-arrow-up-right"/></svg>Open in new tab</button><button class="slate-menu__item"><svg class="slate-icon" aria-hidden="true"><use href="#slate-icon-link"/></svg>Copy link</button><button class="slate-menu__item"><svg class="slate-icon" aria-hidden="true"><use href="#slate-icon-pin"/></svg>Pin to top</button><div class="slate-menu__sep"></div><button class="slate-menu__item slate-menu__item--danger"><svg class="slate-icon" aria-hidden="true"><use href="#slate-icon-trash"/></svg>Delete</button></div>
17 components

Patterns

Complete compositions assembled from the components above.

Sign in

Centered auth form with social login.

Welcome back

Sign in to your workspace

or
Password Forgot?
View code
<div class="slate-auth"><div class="slate-auth__head"><span class="slate-logo">S</span><h3 class="slate-h4">Welcome back</h3><p class="slate-muted slate-text-sm">Sign in to your workspace</p></div><button class="slate-button slate-button--secondary slate-button--block slate-button--lg"><svg class="slate-icon" aria-hidden="true"><use href="#slate-icon-globe"/></svg>Continue with Google</button><div class="slate-divider slate-divider--label">or</div><div class="slate-field"><label class="slate-label">Email</label><input class="slate-input slate-input--lg" placeholder="you@company.com"></div><div class="slate-field"><div class="slate-label">Password <a class="slate-link slate-text-xs" style="margin-left:auto" href="#auth">Forgot?</a></div><input class="slate-input slate-input--lg" type="password" value="password123"></div><button class="slate-button slate-button--block slate-button--lg">Sign in</button></div>

Pricing

Plan cards with a featured tier.

Starter
For individuals
$12/mo
  • 5 projects
  • Basic analytics
Enterprise
For large teams
Custom
  • SSO and SCIM
  • Audit logs
View code
<div class="slate-grid slate-grid--3" style="width:100%"><div class="slate-pricing"><div><div class="slate-strong">Starter</div><div class="slate-muted slate-text-sm">For individuals</div></div><div class="slate-pricing__price">$12<small>/mo</small></div><ul class="slate-list slate-list--check slate-text-sm"><li>5 projects</li><li>Basic analytics</li></ul><button class="slate-button slate-button--secondary slate-button--block">Choose Starter</button></div><div class="slate-pricing slate-pricing--featured"><div class="slate-row slate-row--between"><div class="slate-strong">Business</div><span class="slate-badge slate-badge--solid">Popular</span></div><div class="slate-pricing__price">$49<small>/mo</small></div><ul class="slate-list slate-list--check slate-text-sm"><li>Unlimited projects</li><li>Advanced analytics</li><li>Priority support</li></ul><button class="slate-button slate-button--block">Choose Business</button></div><div class="slate-pricing"><div><div class="slate-strong">Enterprise</div><div class="slate-muted slate-text-sm">For large teams</div></div><div class="slate-pricing__price">Custom</div><ul class="slate-list slate-list--check slate-text-sm"><li>SSO and SCIM</li><li>Audit logs</li></ul><button class="slate-button slate-button--secondary slate-button--block">Contact sales</button></div></div>

Settings page

Rows with a title, description and control, plus a danger zone.

Two-factor authentication
Require a code from your authenticator app.
Email digests
A weekly summary of activity.
Delete workspace
Permanently remove all data. This can't be undone.
View code
<div class="slate-card slate-card__body" style="width:100%"><div class="slate-setting"><div><div class="slate-setting__title">Two-factor authentication</div><div class="slate-setting__desc">Require a code from your authenticator app.</div></div><label class="slate-switch"><input type="checkbox" role="switch" checked></label></div><div class="slate-setting"><div><div class="slate-setting__title">Email digests</div><div class="slate-setting__desc">A weekly summary of activity.</div></div><select class="slate-select" style="width:9rem"><option>Weekly</option><option>Daily</option></select></div></div>
<div class="slate-danger-zone" style="width:100%"><div class="slate-setting"><div><div class="slate-setting__title">Delete workspace</div><div class="slate-setting__desc">Permanently remove all data. This can't be undone.</div></div><button class="slate-button slate-button--danger-soft">Delete…</button></div></div>

Filter bar

Compound filters: field, operator and value.

StatusAmount
View code
<div class="slate-filter-bar"><span class="slate-filter"><span>Status</span><button>is</button><button>Open <svg class="slate-icon slate-icon--sm" aria-hidden="true"><use href="#slate-icon-chevron-down"/></svg></button><button aria-label="Remove"><svg class="slate-icon slate-icon--sm" aria-hidden="true"><use href="#slate-icon-x"/></svg></button></span><span class="slate-filter"><span>Amount</span><button>&gt;</button><button>$1,000</button><button aria-label="Remove"><svg class="slate-icon slate-icon--sm" aria-hidden="true"><use href="#slate-icon-x"/></svg></button></span><button class="slate-chip slate-chip--dashed"><svg class="slate-icon slate-icon--sm" aria-hidden="true"><use href="#slate-icon-plus"/></svg>Add filter</button><button class="slate-button slate-button--link slate-text-sm">Clear all</button></div>

Activity feed

Who did what, when.

PN
Priya Nair sent INV-2041
2 hours ago
Kestrel Logistics paid $6,120.00
Yesterday
View code
<div style="width:26rem"><div class="slate-feed-item"><span class="slate-avatar slate-avatar--sm slate-avatar--accent">PN</span><div><strong>Priya Nair</strong> sent <a class="slate-link" href="#feed">INV-2041</a><div class="slate-text-xs slate-subtle">2 hours ago</div></div></div><div class="slate-feed-item"><span class="slate-avatar slate-avatar--sm slate-avatar--success"><svg class="slate-icon slate-icon--sm" aria-hidden="true"><use href="#slate-icon-check"/></svg></span><div><strong>Kestrel Logistics</strong> paid <strong>$6,120.00</strong><div class="slate-text-xs slate-subtle">Yesterday</div></div></div></div>

Comments

Threaded discussion with a composer.

AK
Aisha Khan · 1h
Can we move the due date to the 30th?
View code
<div class="slate-stack" style="width:26rem"><div class="slate-comment"><span class="slate-avatar">AK</span><div class="slate-comment__body"><div class="slate-text-sm"><strong>Aisha Khan</strong> <span class="slate-subtle">· 1h</span></div><div class="slate-comment__bubble">Can we move the due date to the 30th?</div></div></div><div class="slate-input-group"><input class="slate-input" placeholder="Write a reply…"><span class="slate-input-group__action"><button class="slate-button slate-button--icon slate-button--xs" aria-label="Send"><svg class="slate-icon slate-icon--sm" aria-hidden="true"><use href="#slate-icon-send"/></svg></button></span></div></div>

Notifications

Unread items carry a dot and a tint.

Payment failed for Brightwater Dental
5 minutes ago
Oakline Foods paid INV-2038
Yesterday
View code
<div class="slate-list-group" style="width:26rem"><div class="slate-notification slate-notification--unread"><span class="slate-avatar slate-avatar--sm slate-avatar--danger"><svg class="slate-icon slate-icon--sm" aria-hidden="true"><use href="#slate-icon-alert-triangle"/></svg></span><div class="slate-grow"><div><strong>Payment failed</strong> for Brightwater Dental</div><div class="slate-text-xs slate-subtle">5 minutes ago</div></div></div><div class="slate-notification"><span class="slate-avatar slate-avatar--sm slate-avatar--success"><svg class="slate-icon slate-icon--sm" aria-hidden="true"><use href="#slate-icon-check"/></svg></span><div class="slate-grow"><div><strong>Oakline Foods</strong> paid INV-2038</div><div class="slate-text-xs slate-subtle">Yesterday</div></div></div></div>

Profile header

Avatar, identity and actions.

PN
Priya Nair
Controller · Bengaluru
View code
<div class="slate-profile" style="width:100%"><span class="slate-avatar slate-avatar--xl slate-avatar--accent">PN</span><div class="slate-grow"><div class="slate-h4">Priya Nair</div><div class="slate-muted slate-text-sm">Controller · Bengaluru</div></div><button class="slate-button slate-button--secondary">Message</button><button class="slate-button">Follow</button></div>

Team members

Row with role and actions.

AK
Aisha Khan
aisha@acme.com
RS
Rahul Sharma
rahul@acme.com
View code
<div style="width:30rem"><div class="slate-member"><span class="slate-avatar">AK</span><div class="slate-grow"><div class="slate-strong">Aisha Khan</div><div class="slate-text-xs slate-subtle">aisha@acme.com</div></div><select class="slate-select slate-input--sm" style="width:7rem"><option>Admin</option><option>Editor</option></select></div><div class="slate-member"><span class="slate-avatar slate-avatar--accent">RS</span><div class="slate-grow"><div class="slate-strong">Rahul Sharma</div><div class="slate-text-xs slate-subtle">rahul@acme.com</div></div><select class="slate-select slate-input--sm" style="width:7rem"><option>Editor</option><option>Admin</option></select></div></div>

Integrations

Connect external tools.

Slack
Connected

Send alerts to any channel.

Notion

Sync docs and databases.

GitHub

Link commits to tasks.

View code
<div class="slate-grid slate-grid--3" style="width:100%"><div class="slate-integration"><div class="slate-row"><span class="slate-integration__logo">S</span><div class="slate-grow slate-strong">Slack</div><span class="slate-status slate-status--success">Connected</span></div><p class="slate-muted slate-text-sm">Send alerts to any channel.</p><button class="slate-button slate-button--secondary slate-button--sm">Configure</button></div><div class="slate-integration"><div class="slate-row"><span class="slate-integration__logo">N</span><div class="slate-grow slate-strong">Notion</div></div><p class="slate-muted slate-text-sm">Sync docs and databases.</p><button class="slate-button slate-button--sm">Connect</button></div><div class="slate-integration"><div class="slate-row"><span class="slate-integration__logo">G</span><div class="slate-grow slate-strong">GitHub</div></div><p class="slate-muted slate-text-sm">Link commits to tasks.</p><button class="slate-button slate-button--sm">Connect</button></div></div>

Onboarding checklist

Guide new users with visible progress.

Get started2 of 4
Create your workspace
Invite a teammate
Connect your bank
Send your first invoice
View code
<div class="slate-card" style="width:24rem"><div class="slate-card__header"><span class="slate-card__title">Get started</span><span class="slate-text-xs slate-subtle">2 of 4</span></div><div class="slate-card__body"><div class="slate-progress slate-progress--sm" style="--slate-value:50%;margin-bottom:.75rem"><i></i></div><div class="slate-checklist"><div class="slate-checklist__item slate-checklist__item--done"><span class="slate-checklist__box"><svg class="slate-icon slate-icon--sm" aria-hidden="true"><use href="#slate-icon-check"/></svg></span><span>Create your workspace</span></div><div class="slate-checklist__item slate-checklist__item--done"><span class="slate-checklist__box"><svg class="slate-icon slate-icon--sm" aria-hidden="true"><use href="#slate-icon-check"/></svg></span><span>Invite a teammate</span></div><div class="slate-checklist__item"><span class="slate-checklist__box"></span><span>Connect your bank</span></div><div class="slate-checklist__item"><span class="slate-checklist__box"></span><span>Send your first invoice</span></div></div></div></div>

API key

A secret with reveal and copy.

sk_live_••••••••••••••••9f2a
Keep this secret. Rotate it if it leaks.
View code
<div class="slate-field" style="width:24rem"><label class="slate-label">Secret key</label><div class="slate-secret"><span>sk_live_••••••••••••••••9f2a</span><button class="slate-button slate-button--ghost slate-button--icon slate-button--xs" aria-label="Reveal"><svg class="slate-icon slate-icon--sm" aria-hidden="true"><use href="#slate-icon-eye"/></svg></button><button class="slate-button slate-button--ghost slate-button--icon slate-button--xs" aria-label="Copy" data-slate-copy="sk_live_example" data-tooltip="Copy"><svg class="slate-icon slate-icon--sm" aria-hidden="true"><use href="#slate-icon-copy"/></svg></button></div><span class="slate-hint">Keep this secret. Rotate it if it leaks.</span></div>

Usage meter

Plan consumption with a threshold warning.

Seats48 / 50
Upgrade to add more seats.
View code
<div class="slate-card slate-card__body" style="width:24rem"><div class="slate-row slate-row--between slate-text-sm"><span class="slate-strong">Seats</span><span class="slate-muted">48 / 50</span></div><div class="slate-progress slate-progress--warning" style="--slate-value:96%;margin:.5rem 0"><i></i></div><div class="slate-text-xs slate-subtle">Upgrade to add more seats.</div></div>

Hero

Marketing intro with a soft accent glow.

NewSlateOS 1.0

Design that stays out of the way.

Tokens, components and patterns for crisp, dense, accessible products.

View code
<div class="slate-hero" style="width:100%"><a class="slate-announcement" href="#hero"><span class="slate-badge slate-badge--solid">New</span>SlateOS 1.0 <svg class="slate-icon slate-icon--sm" aria-hidden="true"><use href="#slate-icon-arrow-right"/></svg></a><h1 class="slate-display" style="max-width:14ch">Design that stays out of the way.</h1><p class="slate-lead" style="max-width:34rem">Tokens, components and patterns for crisp, dense, accessible products.</p><div class="slate-row"><button class="slate-button slate-button--lg">Get started</button><button class="slate-button slate-button--secondary slate-button--lg"><svg class="slate-icon slate-icon--sm" aria-hidden="true"><use href="#slate-icon-github"/></svg>Star on GitHub</button></div></div>

Testimonial

A customer quote.

"We replaced three internal libraries with SlateOS and shipped faster than ever."

LM
Lena Müller
Head of Design, Kestrel
View code
<div class="slate-testimonial" style="width:24rem"><p>"We replaced three internal libraries with SlateOS and shipped faster than ever."</p><div class="slate-row"><span class="slate-avatar slate-avatar--accent">LM</span><div><div class="slate-strong slate-text-sm">Lena Müller</div><div class="slate-text-xs slate-subtle">Head of Design, Kestrel</div></div></div></div>
Get started

One stylesheet. No build step.

1 · Add the files

index.html
<link rel="stylesheet" href="https://slateos.ajinkya.design/dist/slateos.css">
<script src="https://slateos.ajinkya.design/dist/slateos.js" defer></script>
<script src="https://slateos.ajinkya.design/dist/icons.js" defer></script>

2 · Use the classes

<button class="slate-button">Save</button>
<button class="slate-button slate-button--secondary">Cancel</button>

3 · Theme it

Dark mode follows the system. Force a theme, or override any token, with plain CSS.

<html data-theme="dark">

:root { --slate-accent-solid: #0f9d8a; }
Tokens

JSON, three layers.

tokens.json
Stylesheet

Layered, 8 KB gzipped.

slateos.min.css
Runtime

Optional, no dependencies.

slateos.js
esc
↑ ↓ navigate↵ go to