Components

Component library

28 components covering forms, feedback, navigation, overlays, and data. Every component is plain HTML + a class — no framework, no runtime. Click "Code" on any demo to copy the markup.

Accordion

.accordion · .accordion-item · .accordion-trigger · .accordion-content

Collapsible sections. The chevron rotates 180° when the item opens.

A minimal, warm-neutral design system with a single cobalt accent, built for dense operational interfaces — control panels, dashboards, and monitoring tools.
No. Plain HTML + CSS classes. Works with any framework or no framework at all.
Yes — every token has a dark variant. Toggle data-theme="dark" on the html element.
<div class="accordion">
  <div class="accordion-item" data-state="open">
    <button class="accordion-trigger">Question</button>
    <div class="accordion-content">Answer.</div>
  </div>
</div>

Alert

.alert .alert-danger | .alert-warn | .alert-success | .alert-info

Inline messages for validation, system feedback, and contextual notes. Composable with an icon and title.

Connection lost
We're trying to reconnect — your last changes will be saved when you're back online.
Current rate (3.2%) already meets this threshold — system is now in warn.
Changes saved
Your settings will apply on the next eval window.
Evaluation window closes in 47 minutes.
<div class="alert alert-danger">
  <svg class="alert-icon"></svg>
  <div class="alert-body">
    <div class="alert-title">Connection lost</div>
    We're trying to reconnect.
  </div>
</div>

Avatar

.avatar .avatar-sm | .avatar-lg | .avatar-xl · .avatar-group

Initials fallback, image override, four sizes. Stack into a .avatar-group for team displays.

SC TO JL MR
SC TO JL +5
<span class="avatar">SC</span>
<span class="avatar avatar-lg"><img src="/me.jpg"></span>

<div class="avatar-group">
  <span class="avatar">SC</span>
  <span class="avatar">TO</span>
</div>
.banner .banner-danger | .banner-success | .banner-info

Full-width contextual banners for system-wide state. The pulsing .banner-dot signals an active condition.

<div class="banner banner-danger">
  <span class="banner-dot"></span>
  <span>Dialing stopped</span>
  <span class="tag tag-danger">Hard stop</span>
</div>
.breadcrumb · .breadcrumb-item · .breadcrumb-sep

Hierarchical location indicator. Mark the current page with aria-current="page".

<nav class="breadcrumb">
  <a class="breadcrumb-item" href="#">Workspace</a>
  <span class="breadcrumb-sep">/</span>
  <span class="breadcrumb-item" aria-current="page">Settings</span>
</nav>

Button

.btn .btn-primary | .btn-secondary | .btn-outline | .btn-ghost | .btn-brand | .btn-danger | .btn-link

Seven variants from primary confirmation to inline link. Three sizes via .btn-sm and .btn-lg. Add .btn-icon for a square icon-only button.

7 variants
<button class="btn btn-primary">Apply changes</button>
<button class="btn btn-secondary">Cancel</button>
<button class="btn btn-outline">Outline</button>
<button class="btn btn-ghost">Ghost</button>
<button class="btn btn-brand">Continue</button>
<button class="btn btn-danger">Delete</button>
<button class="btn btn-link">Read more</button>

Sizes

<button class="btn btn-primary btn-sm">Small</button>
<button class="btn btn-primary">Default</button>
<button class="btn btn-primary btn-lg">Large</button>

States

Default
Hover
Focus
Disabled
Primary
Outline
Danger

Icon button

<button class="btn-icon"><svg ... /></button>
<button class="btn-icon btn-icon-outline"><svg ... /></button>
<button class="btn-icon btn-icon-outline btn-sm"><svg ... /></button>

Operational variants

Specialized buttons for control-panel UIs: a hard-stop and a compact rollback.

<button class="btn-stop">Stop all dialing <span class="tag tag-danger">Hard stop</span></button>
<button class="btn-rollback">Rollback</button>

Button group

<div class="btn-group">
  <button class="btn btn-sm active">Day</button>
  <button class="btn btn-sm">Week</button>
  <button class="btn btn-sm">Month</button>
</div>

Card

.card · .card-header · .card-title · .card-desc · .card-footer

The primary container. White surface, 1px border, 8px radius, 16px padding. Add .card-disabled for a locked state.

Monthly active
+12%
24,892

vs 22,184 last month

Confirm action

This will permanently delete the selected items. This action cannot be undone.

Locked card

Controls are disabled while another operation is in progress.

<div class="card">
  <div class="card-header">
    <div class="card-title">Monthly active</div>
    <span class="tag tag-success">+12%</span>
  </div>
  <p class="card-desc">vs 22,184 last month</p>
  <div class="card-footer">
    <button class="btn btn-ghost">Cancel</button>
    <button class="btn btn-danger btn-sm">Delete</button>
  </div>
</div>

Checkbox

.checkbox

16px square, fills with the brand cobalt when checked. Pair with .field-check wrapper for inline labels.

<label class="field-check">
  <input type="checkbox" class="checkbox">
  <span class="field-check-label">Subscribe to updates</span>
</label>

Command

.command · .command-input · .command-list · .command-group-label

Searchable action palette (⌘K). The list scrolls; groups are labeled with a small caps header.

⌘K
Suggestions
Navigate
<div class="command">
  <div class="command-input-wrap">
    <input class="command-input" placeholder="Search...">
    <kbd>⌘K</kbd>
  </div>
  <div class="command-list">
    <div class="command-group-label">Suggestions</div>
    <button class="menu-item">...</button>
  </div>
</div>

Dialog

.dialog · .dialog-overlay · .dialog-header · .dialog-body · .dialog-footer

Centered modal with a blurred scrim. Use for confirmations, forms, and any flow that should block the rest of the page.

Accessibility: render with role="dialog" aria-modal="true" and point aria-labelledby at the title. On open, move focus into the dialog and trap Tab inside it; on close, return focus to the trigger and dismiss on Esc. The demo above does this.

<div class="dialog-overlay"></div>
<div class="dialog">
  <div class="dialog-header">
    <div class="dialog-title">Delete this segment?</div>
    <p class="dialog-desc">This action can't be undone.</p>
  </div>
  <div class="dialog-body">...</div>
  <div class="dialog-footer">
    <button class="btn btn-ghost">Cancel</button>
    <button class="btn btn-danger">Delete</button>
  </div>
</div>
.menu · .menu-item · .menu-label · .menu-separator

List-of-actions menu. Supports icons, keyboard shortcuts, grouped sections, and a destructive variant.

<div class="menu">
  <div class="menu-label">Account</div>
  <button class="menu-item">
    <svg class="menu-item-icon"></svg> Profile
    <span class="menu-item-shortcut">⇧ ⌘ P</span>
  </button>
  <div class="menu-separator"></div>
  <button class="menu-item menu-item-danger">Sign out</button>
</div>

Empty State

.empty-state · .empty-state-icon · .empty-state-title · .empty-state-desc · .empty-state-actions

Centered placeholder for tables, search results, and feature onboarding. Always include an icon and a primary action.

No results found
Try adjusting your filters or searching with different keywords.
<div class="empty-state">
  <div class="empty-state-icon"><svg /></div>
  <div class="empty-state-title">No results found</div>
  <div class="empty-state-desc">Try adjusting your filters.</div>
  <div class="empty-state-actions"><button class="btn btn-primary btn-sm">New search</button></div>
</div>

Input

.input

32px tall, 6px radius. Full width by default; .input-sm (24px) for inline numeric fields, .input-lg (40px) for hero inputs. Pair with .label, .helper, and .field-error.

We'll never share your email.

<label class="label" for="email">Email</label>
<input class="input" id="email" type="email" placeholder="you@example.com">
<p class="helper">We'll never share your email.</p>

<!-- Sizes -->
<input class="input input-sm" type="number">
<input class="input input-lg" type="search">

States

Please enter a valid email address.

Input group (addons)

https://
USD
<div class="input-group">
  <span class="input-group-addon">https://</span>
  <input class="input" placeholder="example.com">
</div>

Pagination

.pagination · .pagination-item · .pagination-ellipsis
<nav class="pagination">
  <button class="pagination-item">1</button>
  <button class="pagination-item active">2</button>
  <span class="pagination-ellipsis"></span>
</nav>

Popover

.popover · .popover-header

Click-anchored floating panel. Use for rich content — forms, color pickers, inline editors.

Quick settings
<div class="popover">
  <div class="popover-header">Quick settings</div>
  ...
</div>

Progress

.progress · .progress-bar

6px-tall bar with a brand cobalt fill by default. Use .progress-bar-danger or .progress-bar-warning for critical states.

Uploading62%
Disk usage88%
Quota96%
<div class="progress">
  <span class="progress-bar" style="width: 62%;"></span>
</div>

Spinner

Radio

.radio

Single-selection variant. Same sizing and color treatment as Checkbox.

<label class="field-check">
  <input type="radio" name="plan" class="radio">
  <span class="field-check-label">Starter</span>
</label>

Select

.select

Native select with a custom chevron. Matches input height and focus styles.

<select class="select">
  <option>United States</option>
  <option>United Kingdom</option>
</select>

Sheet

.sheet · .sheet-header · .sheet-body · .sheet-footer

Side-anchored drawer. Use for detail panels, filter sets, and contextual forms that should stay accessible alongside the main view.

Accessibility: same contract as the dialog — role="dialog" aria-modal="true", aria-labelledby on the title, focus moved in and trapped on open, returned to the trigger on close, Esc to dismiss.

Filter calls

Refine the table by segment, status, and date range.

<div class="sheet">
  <div class="sheet-header">...</div>
  <div class="sheet-body">...</div>
  <div class="sheet-footer">...</div>
</div>
.sidebar | .sidebar--rail | .sidebar-link | .sidebar-link.active

The application sidebar. .sidebar is the full 240px form with labeled links and grouped sections. Add .sidebar--rail for the collapsed, icon-only rail at --sidebar-w (56px). Active state is .sidebar-link.active; icons use currentColor, so they inherit --text-tertiary and shift to --text-primary when active. A Shift-branded example lives at sidebar-rail.html.

<!-- Collapsed icon rail -->
<aside class="sidebar sidebar--rail">
  <div class="sidebar-header">…brand…</div>
  <div class="sidebar-group">
    <a class="sidebar-link active"><svg class="sidebar-link-icon" /></a>
    <a class="sidebar-link"><svg class="sidebar-link-icon" /></a>
  </div>
</aside>

Skeleton

.skeleton

Animated shimmer placeholder. Use any width/height — it inherits the rounded corner of its parent or you can set border-radius directly.

<div class="skeleton" style="height:10px; width:60%;"></div>
<div class="skeleton" style="width:34px; height:34px; border-radius:var(--radius-full);"></div>

Slider

.slider

Range input with pill track and circular thumb. Pair with .slider-val for a display-font numeric readout.

1.2
1.02.0
<div class="slider-wrap">
  <input type="range" class="slider" min="1.0" max="2.0" step="0.1" value="1.2">
  <span class="slider-val">1.2</span>
</div>

Status Chip

.chip .chip-ok | .chip-warn | .chip-critical | .chip-info | .chip-stopped

Pill-shaped semantic status indicators. Always pair with a .chip-dot that inherits the chip color.

Active Warning Critical Monitoring Stopped
<span class="chip chip-ok">
  <span class="chip-dot"></span>Active
</span>

Status dots

.dot-green
.dot-amber
.dot-red
.dot-blue
.dot-muted
.monitoring-dot

Switch

.switch

Toggle for boolean settings. Use when the state takes effect immediately; use Checkbox when paired with a form submission.

<label class="field-check">
  <input type="checkbox" class="switch" checked>
  <span class="field-check-label">Email notifications</span>
</label>

Table

.table · .table-bordered

Borderless by default — relies on light row dividers. Add .table-bordered for a card-wrapped variant.

NameRoleStatusCalls today
SCSasha Chen
Senior Agent Available 84
TOTobi Okafor
Manager On call 62
JLJamie Lee
Agent Away 47
<table class="table">
  <thead><tr>
    <th>Name</th>
    <th class="td-num">Calls</th>
  </tr></thead>
  <tbody><tr>
    <td class="td-primary">Sasha Chen</td>
    <td class="td-num td-primary">84</td>
  </tr></tbody>
</table>

Tabs

.tabs-list · .tab · .tab-panel · .tabs-list-pill

Two variants: bottom-border tabs for primary navigation, pill tabs for filter/segment switching.

Overview content goes here. Switch tabs to see different panels.

<div class="tabs-list">
  <button class="tab active">Overview</button>
  <button class="tab">Activity</button>
</div>
<div class="tab-panel">...</div>

Tag & Badge

.tag .tag-danger | .tag-success | .tag-info | .tag-warn | .tag-accent · .badge

Tags are loud: all-caps, semantic-colored fill. Badges are quiet: muted, used for metadata.

Hard stop Active Info Review New Default rolled back v1.3
<span class="tag tag-danger">Hard stop</span>
<span class="tag tag-success">Active</span>
<span class="badge">rolled back</span>

Textarea

.textarea

Multiline input, vertically resizable, with a 72px minimum height.

Markdown is supported.

<textarea class="textarea" placeholder="Add a note..."></textarea>

Toast

.toast · .toast-icon · .toast-body · .toast-title · .toast-desc

Transient feedback. Anchor to a corner (usually bottom-right) and stack.

Changes applied
Dial speed set to 1.2. Expect ~22 additional dials/hr.
Failed to save
Network error. Your changes are preserved locally.
Approaching quota
96% of monthly limit used.
<div class="toast">
  <svg class="toast-icon"></svg>
  <div class="toast-body">
    <div class="toast-title">Changes applied</div>
    <div class="toast-desc">Detail…</div>
  </div>
</div>

Tooltip

.tooltip · .tooltip-wrap

Hovers show after a short delay. Always wrap in .tooltip-wrap for the auto-show behavior.

Tooltip text
Tooltip text
Tooltip text
<div class="tooltip-wrap">
  <button class="btn btn-outline">Hover me</button>
  <div class="tooltip" data-side="top">Tooltip text</div>
</div>