Acme Design System  ·  Master Reference

Design System

The single source of truth for colors, typography, spacing, and components across every Acme product surface.

17
Components
56
Icons
80+
Tokens
WCAG AA
Accessibility

Colors

All color tokens from design-tokens.ts. Hover any swatch to see its name. Switch to Dev mode to reveal CSS variable names. Contrast ratios shown against white (#FFFFFF).

Neutral Scale
0
50
100
200
300
400
500
600
700
800
900
1000
White
#FFFFFF
--color-neutral-0
Neutral 50
#F7F7F7
--color-neutral-50
Neutral 100
#F0F0F0
--color-neutral-100
Neutral 200
#E0E0E0
--color-neutral-200
Neutral 400
#B0B0B0
--color-neutral-400
Neutral 600
#707070
--color-neutral-600
AA ✓ 5.7:1
Neutral 800
#383838
--color-neutral-800
AA ✓ 11.4:1
Black
#111111
--color-neutral-1000
AA ✓ 19.2:1
Brand
Primary
#1955A6
--color-brand-primary
AA ✓ 5.2:1
Primary Dark
#0B2F5C
--color-brand-primary-dark
AA ✓ 13.1:1
Primary Light
#A8C4E4
--color-brand-primary-light
Primary Bg
#E7EFF7
--color-brand-primary-bg
Info
Info
#1FA4B6
--color-info-main
AA ✓ 4.5:1
Info Dark
#0E6F7C
--color-info-dark
AA ✓ 7.3:1
Info Light
#A8E4EC
--color-info-light
Info Bg
#D9F4F7
--color-info-bg
Success
Success
#529604
--color-success-main
AA ✓ 4.6:1
Success Dark
#244A02
--color-success-dark
AA ✓ 13.8:1
Success Light
#C4E17F
--color-success-light
Success Bg
#E6F3C3
--color-success-bg
Error
Error
#FF4242
--color-error-main
Fail 3.6:1
Error Dark
#C62828
--color-error-dark
AA ✓ 7.1:1
Error Light
#F2A7A7
--color-error-light
Error Bg
#F7D7D7
--color-error-bg
Warning
Warning
#FF8505
--color-warning-main
Fail 3.1:1
Warning Dark
#C15C02
--color-warning-dark
AA ✓ 5.9:1
Warning Light
#FFC176
--color-warning-light
Warning Bg
#F8D1A3
--color-warning-bg
Accent — Yellow
Yellow
#F5D44B
--color-accent-yellow-main
Yellow Dark
#D4A61A
--color-accent-yellow-dark
AA ✓ 4.8:1
Yellow Light
#F9E89A
--color-accent-yellow-light
Yellow Bg
#FFEBBB
--color-accent-yellow-bg
Accent — Pink
Pink
#D96FA8
--color-accent-pink-main
Pink Dark
#A44E7C
--color-accent-pink-dark
AA ✓ 5.3:1
Pink Light
#EFBBD0
--color-accent-pink-light
Pink Bg
#F7D7D7
--color-accent-pink-bg
Accent — Cyan
Cyan
#3BAFC4
--color-accent-cyan-main
Cyan Dark
#247A8A
--color-accent-cyan-dark
AA ✓ 6.1:1
Cyan Light
#AEE4EC
--color-accent-cyan-light
Cyan Bg
#D2F3F9
--color-accent-cyan-bg
Accent — Purple
Purple
#A255FF
--color-accent-purple-main
Purple Dark
#6A0FB8
--color-accent-purple-dark
AA ✓ 7.4:1
Purple Light
#B377F3
--color-accent-purple-light
Purple Bg
#EACEFF
--color-accent-purple-bg
CSS — using color tokens
/* Reference colors via CSS custom properties */
.element {
  color:            var(--color-brand-primary);
  background-color: var(--color-brand-primary-bg);
  border-color:     var(--color-brand-primary-light);
}

/* Semantic usage */
.error-text    { color: var(--color-error-main); }
.success-text  { color: var(--color-success-dark); }
.warning-bg    { background: var(--color-warning-bg); }

/* Accent usage */
.highlight     { background: var(--color-accent-yellow-bg); }
.purple-badge  { background: var(--color-accent-purple-bg); color: var(--color-accent-purple-dark); }

Typography

Font family: Mulish (Google Fonts). All sizes, weights, and spacing from design-tokens.ts. Switch to Dev mode to reveal CSS variables and copy snippets on each style.

Font Families
Base 'Mulish', sans-serif Aa Bb Cc — The quick brown fox
Mono 'JetBrains Mono', monospace const token = var(--color-primary)
Type Scale
Headline 1
28px · 1.75rem Weight 800 Line height 1.2 −0.01em tracking
The quick brown fox jumps over the lazy dog
Headline 2
16px · 1rem Weight 700 Line height 1.3
Section Heading — Clear and Concise
Headline 3
16px · 1rem Weight 400 Line height 1.4
Subheading — Supporting context with lighter weight
Headline 4
14px · 0.875rem Weight 700 Line height 1.4
Card Title or Inline Label
Body Regular
14px · 0.875rem Weight 400 Line height 1.5
The quick brown fox jumps over the lazy dog. This is standard body copy used for descriptions, paragraphs, and general UI content throughout the application.
Body Bold
14px · 0.875rem Weight 700 Line height 1.5
Emphasised body text, inline labels, key values
Small
12px · 0.75rem Weight 400 Line height 1.5
Helper text, captions, metadata, timestamps, field hints
Label / Caps
11px Weight 700 +0.08em tracking UPPERCASE
Table Header · Section Label · Filter Tag · Nav Group
Font Weights
Light
300
Design System
Regular
400
Design System
Semi-Bold
600
Design System
Bold
700
Design System
Extra Bold
800
Design System
Black
900
Design System
Letter Spacing
tight −0.01em Headlines, compact display labels, hero text
default 0em Body text, buttons, inputs, general UI copy
loose +0.01em Small caps, helper text, supporting copy
wide +0.02em Navigation items, section headers, tabs
xwide +0.04em Overlines, micro-labels, group headings, eyebrows
Line Height
tight · 1.2

The quick brown fox jumps over the lazy dog. A compact rhythm for headlines, hero copy, and display text where lines sit close together.

base · 1.5

The quick brown fox jumps over the lazy dog. The standard reading rhythm for body copy, UI labels, and most interface text.

relaxed · 1.75

The quick brown fox jumps over the lazy dog. Open breathing room for long-form prose, descriptions, and content-heavy layouts.

CSS — typography token usage
/* Type scale via CSS variables */
h1 { font-size: var(--font-size-h1);    font-weight: 800; letter-spacing: var(--letter-spacing-tight); }
h2 { font-size: var(--font-size-h2);    font-weight: 700; }
h3 { font-size: var(--font-size-h3);    font-weight: 400; }

body {
  font-family:  var(--font-family-base);
  font-size:    var(--font-size-body);
  line-height:  var(--line-height-base);
  font-weight:  var(--font-weight-regular);
}

/* Label / caps pattern */
.label {
  font-size:      11px;
  font-weight:    var(--font-weight-bold);
  text-transform: uppercase;
  letter-spacing: var(--letter-spacing-wide);
}

/* Mono — code, tokens, values */
code { font-family: var(--font-family-mono); font-size: var(--font-size-small); }

Spacing & Foundations

7-step spacing scale, border radius, elevation, border widths, icon sizes, z-index, and breakpoints — all drawn directly from design-tokens.ts. Dev mode reveals CSS variable names and rem values.

Spacing Scale
xxs 2px 0.125rem
--space-xxs
xs 4px 0.25rem
--space-xs
sm 8px 0.5rem
--space-sm
md 12px 0.75rem
--space-md
lg 16px 1rem
--space-lg
xl 24px 1.5rem
--space-xl
xxl 32px 2rem
--space-xxl
Border Radius
xs
2px
--radius-xs
Chips, tags, dense rows
sm
4px
--radius-sm
Inputs, buttons
md Default
6px
--radius-md
Modals, panels
lg
12px
--radius-lg
Large cards
xl
16px
--radius-xl
Hero, marketing
full
9999px
--radius-full
Pills, avatars, tags
Elevation & Shadows
xs
Sticky headers, table rows, inset panels
0 1px 2px rgba(0,0,0,0.06)
sm
Cards, dropdowns, tooltips
0 1px 3px rgba(0,0,0,0.10)
md
Default cards, panels, sheets
0 2px 6px rgba(0,0,0,0.12)
lg
Modals, drawers, floaters
0 4px 12px rgba(0,0,0,0.16)
xl
High-emphasis, onboarding, hero
0 8px 24px rgba(0,0,0,0.20)
Border Widths
hairline
0.5px
--border-hairline
Dividers, subtle separators between adjacent content
default
1px
--border-default
Inputs, cards, table rows, all standard UI borders
strong
2px
--border-strong
Focus rings, selected states, active indicators
Icon Sizes
xs
12px
sm
16px
md
20px
lg
24px
xl
32px
In context
New project
Delete item
Save draft
Z-Index Scale
Token Value Usage
base 0 Default document flow — tables, cards, panels
sticky 10 Sticky table headers, sticky sub-nav, filter bars
dropdown 100 Menus, dropdowns, popovers, tooltips
overlay 1000 Side panels, drawers, floating detail panes
modal 2000 Modal dialogs, blocking UI, confirmation sheets
toast 3000 Toast notifications, snackbars, global alerts
max 9999 Emergency override — never use in components
Breakpoints ⚠ placeholder
xs
sm
md
lg
xl
2xl
0640768102412801536px
NamepxremCSS Variable
sm640px40rem--bp-sm
md768px48rem--bp-md
lg1024px64rem--bp-lg
xl1280px80rem--bp-xl
2xl1536px96rem--bp-2xl
CSS — spacing & foundation token usage
/* Spacing */
.card        { padding: var(--space-xl); }
.card-header { padding: var(--space-lg) var(--space-xl); gap: var(--space-sm); }
.badge       { padding: var(--space-xxs) var(--space-xs); }

/* Radius */
.btn    { border-radius: var(--radius-md); }
.card   { border-radius: var(--radius-lg); }
.pill   { border-radius: var(--radius-full); }

/* Elevation */
.card       { box-shadow: var(--shadow-sm); }
.dropdown   { box-shadow: var(--shadow-lg); }
.modal      { box-shadow: var(--shadow-xl); }

/* Borders */
.input  { border: var(--border-default) solid var(--color-neutral-300); }
.divider{ height: var(--border-hairline); }
.focus  { border: var(--border-strong) solid var(--color-brand-primary); }

/* Z-index */
.modal    { z-index: var(--z-modal); }
.dropdown { z-index: var(--z-dropdown); }
.toast    { z-index: var(--z-toast); }

Buttons

4 variants × 3 sizes × 4 states shown inline. Hover any live button to see the interaction. Focus rings use brand primary at 14% opacity.

Variants
Primary
Secondary
Ghost
Danger
HTML — button variants
<button class="btn btn-md btn-primary">Primary</button>
<button class="btn btn-md btn-secondary">Secondary</button>
<button class="btn btn-md btn-ghost">Ghost</button>
<button class="btn btn-md btn-danger">Danger</button>
<button class="btn btn-md btn-primary" disabled>Disabled</button>
Sizes
Small
Medium (default)
Large
HTML — button sizes
<button class="btn btn-sm btn-primary">Small</button>
<button class="btn btn-md btn-primary">Medium</button>
<button class="btn btn-lg btn-primary">Large</button>
With icons
HTML — button with icon
<button class="btn btn-md btn-primary">
  <svg width="14" height="14" ...>...</svg>
  New project
</button>

<!-- Icon-only (add title for accessibility) -->
<button class="btn btn-md btn-ghost" style="padding:8px;" title="Settings">
  <svg width="16" height="16" ...>...</svg>
</button>

Inputs

All states shown inline. Focus ring uses brand primary at 14% opacity. Error uses error-main at 14% opacity.

Text input states
This is helper text
Click any input to see live
Please enter a valid email address
This field cannot be edited
This field is required
HTML — input states
<!-- Default -->
<div class="field">
  <label class="field-label">Label</label>
  <input class="input" placeholder="Enter value…">
  <span class="field-hint">Helper text</span>
</div>

<!-- Error -->
<div class="field">
  <label class="field-label">Email</label>
  <input class="input is-error" value="bad@@email">
  <span class="field-err-msg">Invalid email address</span>
</div>

<!-- Disabled -->
<input class="input" disabled value="Locked value">
Textarea & Select
Resize by dragging the bottom-right corner
This field contains invalid content
HTML — textarea & select
<!-- Textarea -->
<textarea class="input" rows="4" placeholder="Long-form text…"></textarea>

<!-- Select with arrow -->
<div class="select-wrap">
  <select class="input">
    <option value="" disabled selected>Choose…</option>
    <option>Option A</option>
    <option>Option B</option>
  </select>
</div>

Badges

Status indicators using semantic color tokens. All 10 colour variants shown. The dot can be removed with .badge-no-dot. Pill shape with .badge-pill.

Semantic
Info Success Error Warning Neutral Brand
Accent Yellow Pink Cyan Purple
HTML — badges
<span class="badge badge-info">Info</span>
<span class="badge badge-success">Success</span>
<span class="badge badge-error">Error</span>
<span class="badge badge-warning">Warning</span>
<span class="badge badge-neutral">Neutral</span>
<span class="badge badge-brand">Brand</span>

<!-- No dot -->
<span class="badge badge-info badge-no-dot">Info</span>

<!-- Pill shape -->
<span class="badge badge-success badge-pill">Success</span>
Variants & in-context use
No dot
Info Success Error Warning Neutral
Pill shape
Info Active Failed Pending New
In-context — table row
Alex Johnson Administrator Active
Marcus Webb Reviewer Pending
Elena Russo Read only Suspended

Cards

Surface containers using elevation, radius-lg, and border tokens. Hover any card to see the lift interaction. Stat cards use the full spacing and typography scale.

Variants
Project
Default Card
shadow-sm · border · radius-lg. Hover to see lift.
Report
Elevated Card
shadow-md · stands out from bg. Use for primary content.
Live
Status
Card with Badge
Badge overlays the image area. Use for status or category.
Featured
Hover State
shadow-lg · translateY(−3px). This is what hover looks like.
HTML — card
<div class="card">
  <div class="card-img-area">
    <!-- image or illustration -->
    <div class="card-badge-overlay">
      <span class="badge badge-success badge-pill">Live</span>
    </div>
  </div>
  <div class="card-body">
    <div class="card-eyebrow">Category</div>
    <div class="card-title">Card Title</div>
    <div class="card-text">Supporting description text.</div>
  </div>
  <div class="card-footer">
    <span class="card-meta">Updated 2h ago</span>
    <button class="btn btn-sm btn-ghost">View</button>
  </div>
</div>
Stat cards
Total projects
142
+12% this month
Active users
2.4k
+8.3% vs last week
Conversion rate
3.6%
−0.4% vs last week
Avg response time
98ms
14ms faster
HTML — stat card
<div class="stat-card">
  <div class="stat-eyebrow">Total projects</div>
  <div class="stat-value">142</div>
  <div class="stat-change up">
    <!-- up arrow svg -->
    +12% this month
  </div>
</div>

Alerts

In-page feedback banners using semantic colour tokens. Left-border accent establishes visual hierarchy at a glance. Dismiss button optional.

All variants
Changes saved successfully
Your profile has been updated and is now live for all users.
Failed to submit form
Please check the highlighted fields and try again. Required fields cannot be empty.
Session expiring soon
You will be logged out in 5 minutes due to inactivity. Save your work now.
New features available
The March release includes improved table sorting, bulk actions, and a new export format. View changelog
HTML — alerts
<div class="alert alert-success">
  <span class="alert-icon">✓</span>
  <div class="alert-body">
    <div class="alert-title">Changes saved</div>
    <div class="alert-text">Supporting detail.</div>
  </div>
  <button class="alert-dismiss" aria-label="Dismiss">✕</button>
</div>

<!-- Variants: alert-error · alert-warning · alert-info -->
With action buttons
Unsaved changes
You have unsaved changes that will be lost if you navigate away.
Update available
Version 2.4.0 is ready to install. This update includes security patches and performance improvements.
HTML — alert with actions
<div class="alert alert-warning">
  <span class="alert-icon">⚠</span>
  <div class="alert-body">
    <div class="alert-title">Unsaved changes</div>
    <div class="alert-text">These will be lost if you navigate away.</div>
    <div style="display:flex;gap:8px;margin-top:10px;">
      <button class="btn btn-sm btn-danger">Discard</button>
      <button class="btn btn-sm btn-ghost">Keep editing</button>
    </div>
  </div>
</div>

Toggles

Binary on/off switches. Use in place of a checkbox when the change takes immediate effect without a form submit.

States
Off
On
Disabled off
Disabled on
HTML — toggle states
<!-- Off -->
<label class="toggle-wrap">
  <span class="toggle">
    <input type="checkbox">
    <span class="toggle-slider"></span>
  </span>
  <span class="toggle-label">Notifications</span>
</label>

<!-- On -->
<label class="toggle-wrap">
  <span class="toggle">
    <input type="checkbox" checked>
    <span class="toggle-slider"></span>
  </span>
  <span class="toggle-label">Notifications</span>
</label>

<!-- Disabled -->
<label class="toggle-wrap" style="cursor:not-allowed;opacity:0.5;">
  <span class="toggle">
    <input type="checkbox" disabled>
    <span class="toggle-slider"></span>
  </span>
  <span class="toggle-label">Label</span>
</label>
With description
Email notifications
Receive updates about activity on your account.
Marketing emails
Tips, product updates, and offers from the team.
Security alerts
Sign-in attempts and password changes.
Two-factor authentication
Requires a verified phone number to enable.
HTML — toggle with description (settings row)
<div style="display:flex;align-items:center;justify-content:space-between;padding:16px 20px;">
  <div>
    <div class="toggle-label" style="font-weight:700;">Email notifications</div>
    <div class="toggle-sublabel">Receive updates about your account.</div>
  </div>
  <label class="toggle-wrap" style="margin-left:16px;flex-shrink:0;">
    <span class="toggle">
      <input type="checkbox" checked>
      <span class="toggle-slider"></span>
    </span>
  </label>
</div>
Sizes
Small
Default
Large
HTML — toggle sizes (inline override)
<!-- Small: 32×18px -->
<span class="toggle" style="width:32px;height:18px;"> ... </span>

<!-- Default: 40×22px (no override needed) -->
<span class="toggle"> ... </span>

<!-- Large: 52×28px -->
<span class="toggle" style="width:52px;height:28px;"> ... </span>

Checkboxes

Multi-select controls. Use when the user can pick zero or more options from a list, or to confirm a single boolean preference.

States
Unchecked
Checked
Indeterminate
Disabled
Disabled checked
HTML — checkbox states
<input type="checkbox" class="checkbox-input">
<input type="checkbox" class="checkbox-input" checked>
<input type="checkbox" class="checkbox-input" disabled>
<input type="checkbox" class="checkbox-input" checked disabled>

<!-- Indeterminate requires JS -->
<input type="checkbox" class="checkbox-input" id="chk">
<script>document.getElementById('chk').indeterminate = true;</script>
With labels
Label only
Label + description
HTML — checkbox with label
<!-- Label only -->
<label class="checkbox-wrap">
  <input type="checkbox" class="checkbox-input" checked>
  <span class="checkbox-label">Remember me</span>
</label>

<!-- Label + description -->
<label class="checkbox-wrap">
  <input type="checkbox" class="checkbox-input" checked>
  <span>
    <span class="checkbox-label">Email notifications</span>
    <span class="checkbox-sublabel">Alerts when someone mentions you.</span>
  </span>
</label>
Group with select-all
Permissions 3 of 5
HTML — checkbox group with select-all
<!-- Select-all header (indeterminate when partial) -->
<div style="display:flex;align-items:center;gap:12px;padding:12px 16px;">
  <input type="checkbox" class="checkbox-input" id="select-all">
  <span class="checkbox-label" style="font-weight:700;">Permissions</span>
</div>

<!-- Row -->
<label style="display:flex;align-items:center;gap:12px;padding:11px 16px;">
  <input type="checkbox" class="checkbox-input" checked>
  <span>
    <span class="checkbox-label">Read</span>
    <span class="checkbox-sublabel">View content and data.</span>
  </span>
</label>

<!-- JS: wire up select-all -->
<script>
const all = document.getElementById('select-all');
const items = document.querySelectorAll('.checkbox-input:not(#select-all)');
all.addEventListener('change', () => items.forEach(c => c.checked = all.checked));
items.forEach(c => c.addEventListener('change', () => {
  const checked = [...items].filter(i => i.checked).length;
  all.indeterminate = checked > 0 && checked < items.length;
  all.checked = checked === items.length;
}));
</script>

Radio Buttons

Single-select controls. Use when exactly one option must be chosen from a visible list. For binary choices, prefer a toggle; for many options, prefer a select.

States
Unselected
Selected
Disabled
Disabled selected
HTML — radio states
<input type="radio" class="radio-input" name="group">
<input type="radio" class="radio-input" name="group" checked>
<input type="radio" class="radio-input" name="group" disabled>
<input type="radio" class="radio-input" name="group" checked disabled>
Standard group
Vertical
1 of 3
Horizontal
1 of 4
HTML — radio group
<!-- All radios in the same group share name="…" -->
<label class="radio-wrap">
  <input type="radio" class="radio-input" name="notify" checked>
  <span>
    <span class="radio-label">Mentions only</span>
    <span class="radio-sublabel">Only when you are directly mentioned.</span>
  </span>
</label>

<label class="radio-wrap">
  <input type="radio" class="radio-input" name="notify">
  <span class="radio-label">Digest</span>
</label>
Card group
Select a plan 1 of 3
HTML — radio card group
<label class="radio-card">
  <input type="radio" class="radio-input" name="plan" checked>
  <span style="flex:1;">
    <span class="radio-label">Pro</span>
    <span class="radio-sublabel">Unlimited projects and priority support.</span>
  </span>
</label>

<!-- CSS drives the selected state -->
<!-- .radio-card:has(.radio-input:checked) -->
<!--   border-color: var(--color-brand-primary)   -->
<!--   background:   var(--color-brand-primary-bg) -->

Modals

Overlay dialogs that interrupt the current flow to request input or confirm an action. Keep content concise — use a page instead for complex multi-step tasks.

Default
HTML — modal structure
<!-- Backdrop -->
<div class="modal-backdrop" onclick="closeModal(this)">
  <div class="modal" onclick="event.stopPropagation()">

    <div class="modal-header">
      <span class="modal-title">Edit profile</span>
      <button class="modal-close" onclick="closeModal()">✕</button>
    </div>

    <div class="modal-body">
      <!-- content -->
    </div>

    <div class="modal-footer">
      <button class="btn btn-md btn-ghost">Cancel</button>
      <button class="btn btn-md btn-primary">Save changes</button>
    </div>

  </div>
</div>
Variants
Confirm
Destructive
HTML — modal variants
<!-- Confirm -->
<div class="modal-footer">
  <button class="btn btn-md btn-ghost">Cancel</button>
  <button class="btn btn-md btn-primary">Publish</button>
</div>

<!-- Destructive: warning icon in header + btn-danger -->
<div class="modal-header">
  <span style="display:flex;align-items:center;gap:8px;">
    <span style="width:28px;height:28px;border-radius:9999px;
      background:var(--color-error-bg);display:inline-flex;
      align-items:center;justify-content:center;">⚠</span>
    <span class="modal-title">Delete project?</span>
  </span>
  <button class="modal-close">✕</button>
</div>
<div class="modal-footer">
  <button class="btn btn-md btn-ghost">Cancel</button>
  <button class="btn btn-md btn-danger">Delete project</button>
</div>
Live demo
JS — modal open / close
function openModal(id) {
  document.getElementById(id).style.display = 'flex';
  document.body.style.overflow = 'hidden';
}
function closeModal(id) {
  document.getElementById(id).style.display = 'none';
  document.body.style.overflow = '';
}

// Close on backdrop click
document.querySelectorAll('.modal-backdrop').forEach(el => {
  el.addEventListener('click', e => {
    if (e.target === el) closeModal(el.id);
  });
});

// Close on Escape
document.addEventListener('keydown', e => {
  if (e.key === 'Escape') {
    document.querySelectorAll('.modal-backdrop')
      .forEach(el => closeModal(el.id));
  }
});

Tooltips

Short contextual labels that appear on hover or focus. Keep copy under ~60 characters. Never put interactive content (links, buttons) inside a tooltip.

Placement — hover each button
Tooltip on top top
Tooltip on right right
Tooltip on bottom bottom
Tooltip on left left
HTML — tooltip placement
<!-- Add placement class to the anchor -->
<span class="tooltip-anchor tooltip-top">
  <button class="btn btn-sm btn-ghost">Top</button>
  <span class="tooltip-bubble">Tooltip on top</span>
</span>

<!-- tooltip-top | tooltip-right | tooltip-bottom | tooltip-left -->
Variants
Default dark tooltip dark (default)
Light surface tooltip light
Longer tooltip that wraps across two lines when needed. multiline
HTML — tooltip variants
<!-- Dark (default) -->
<span class="tooltip-anchor tooltip-top">
  <button>...</button>
  <span class="tooltip-bubble">Default dark tooltip</span>
</span>

<!-- Light -->
<span class="tooltip-anchor tooltip-top tooltip-light">
  <button>...</button>
  <span class="tooltip-bubble">Light surface tooltip</span>
</span>

<!-- Multiline -->
<span class="tooltip-bubble" style="white-space:normal;max-width:180px;">
  Longer tooltip that wraps when needed.
</span>
Trigger types
Download icon button
i Storage is calculated across all projects in your workspace. info icon
Q4 Marketing Campaign Final v3.pdf Q4 Marketing Campaign Final v3.pdf truncated text
Complete all required fields to continue. disabled action
HTML — tooltip trigger types
<!-- Icon button -->
<span class="tooltip-anchor tooltip-top">
  <button class="btn btn-sm btn-ghost" aria-label="Download">
    <svg ...></svg>
  </button>
  <span class="tooltip-bubble">Download</span>
</span>

<!-- Disabled button (wrap in span — disabled blocks pointer events) -->
<span class="tooltip-anchor tooltip-top">
  <button class="btn btn-md btn-primary" disabled
          style="pointer-events:none;">Submit</button>
  <span class="tooltip-bubble">Complete all required fields.</span>
</span>

<!-- CSS-only hover (no JS needed) -->
<style>
  .tooltip-bubble { display: none; }
  .tooltip-anchor:hover .tooltip-bubble,
  .tooltip-anchor:focus-within .tooltip-bubble { display: block; }
</style>

Tables

Structured data display with sortable columns, status badges, row actions, and bulk selection. Always provide a column header; avoid more than 6–7 columns on one view.

Basic with sorting
Name Role Department Joined Location
Sarah Chen Product Designer Design 2021-03-14 San Francisco, CA
Marcus Webb Engineering Lead Engineering 2019-07-02 Austin, TX
Priya Nair Data Analyst Analytics 2022-11-28 New York, NY
James Okafor Marketing Manager Marketing 2020-05-19 Chicago, IL
Luna Reyes Customer Success Support 2023-01-09 Remote
HTML — basic table
<div class="ds-table-wrap">
  <table class="ds-table">
    <thead>
      <tr>
        <th class="sortable sorted">Name <span class="sort-icon">↑</span></th>
        <th class="sortable">Role</th>
        <th>Location</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td><strong>Sarah Chen</strong></td>
        <td>Product Designer</td>
        <td class="td-muted">San Francisco, CA</td>
      </tr>
    </tbody>
  </table>
</div>

<!-- td-mono: monospace cell (dates, IDs, code) -->
<!-- td-muted: de-emphasised secondary text     -->
<!-- th.sortable + th.sorted: sort affordance   -->
Status badges and row actions
Project Status Owner Due date Progress
Acme Rebrand
Brand & identity
Active Sarah Chen 2026-04-30
72%
Q2 Campaign
Marketing
In review James Okafor 2026-05-15
45%
API v3 Docs
Engineering
Blocked Marcus Webb 2026-03-31
20%
Onboarding Flow
Product
Draft Priya Nair 2026-06-01
8%
HTML — badges, progress, row actions
<!-- Status badge in cell -->
<td><span class="badge badge-success">Active</span></td>

<!-- Progress bar in cell -->
<td>
  <div style="display:flex;align-items:center;gap:8px;">
    <div style="flex:1;height:4px;background:var(--color-neutral-100);
      border-radius:9999px;overflow:hidden;">
      <div style="width:72%;height:100%;
        background:var(--color-success-main);"></div>
    </div>
    <span style="font-size:11px;font-weight:700;">72%</span>
  </div>
</td>

<!-- Row actions -->
<td>
  <div class="table-row-actions">
    <button class="row-action">Edit</button>
    <button class="row-action row-action-danger">Delete</button>
  </div>
</td>
Row selection and bulk actions
2 selected
Invoice Client Amount Status Issued
#INV-0041 Acme Corp $4,800.00 Paid 2026-02-01
#INV-0040 Bright Labs $2,250.00 Pending 2026-01-18
#INV-0039 Nova Studio $9,100.00 Overdue 2026-01-05
#INV-0038 Drift Media $1,600.00 Draft 2025-12-22
HTML — row selection + bulk actions
<!-- Bulk action bar (shown when rows are selected) -->
<div style="display:flex;align-items:center;gap:12px;padding:10px 16px;
  background:var(--color-brand-primary-bg);
  border:1px solid var(--color-brand-primary-light);">
  <span style="font-weight:700;color:var(--color-brand-primary);">2 selected</span>
  <div style="margin-left:auto;display:flex;gap:8px;">
    <button class="btn btn-sm btn-ghost">Export</button>
    <button class="btn btn-sm btn-danger">Delete</button>
  </div>
</div>

<!-- Checkbox column header (indeterminate = partial selection) -->
<th><input type="checkbox" class="checkbox-input" id="select-all"></th>

<!-- Selected row -->
<tr class="row-selected">
  <td><input type="checkbox" class="checkbox-input" checked></td>
  ...
</tr>

Form Layout

Grid-based layouts for arranging fields. Single-column for simple flows; two- or three-column grids for dense settings panels. Always group related fields together.

Single column
Sign in to your account
Enter your credentials to continue.
Minimum 8 characters.
HTML — single-column form block
<div class="form-block">
  <div class="form-block-header">
    <div class="form-block-title">Sign in</div>
    <div class="form-block-desc">Enter your credentials.</div>
  </div>
  <div class="form-block-body">
    <div class="field">
      <label class="field-label">Email <span class="req">*</span></label>
      <input class="input" type="email" placeholder="[email protected]">
    </div>
    <div class="field">
      <label class="field-label">Password <span class="req">*</span></label>
      <input class="input" type="password">
      <span class="field-hint">Minimum 8 characters.</span>
    </div>
  </div>
  <div class="form-block-footer">
    <button class="btn btn-md btn-primary">Sign in</button>
  </div>
</div>
Two-column grid
Personal information
Update your name, contact details, and location.
HTML — two-column form grid
<div class="form-block-body">

  <!-- Equal two-column row -->
  <div class="form-row form-row-2">
    <div class="field"> ... </div>
    <div class="field"> ... </div>
  </div>

  <!-- Unequal: 2fr 1fr 1fr (address + city + postcode) -->
  <div class="form-row"
       style="grid-template-columns:2fr 1fr 1fr;">
    <div class="field"> ... </div>
    <div class="field"> ... </div>
    <div class="field"> ... </div>
  </div>

</div>

<!-- Footer: cancel left, save right -->
<div class="form-block-footer">
  <button class="btn btn-md btn-ghost">Cancel</button>
  <div class="form-footer-right">
    <button class="btn btn-md btn-primary">Save changes</button>
  </div>
</div>
Multi-section form
Account
Basic account details and login credentials.
@
Shown on your public profile. Max 200 characters.
Notifications
Choose how and when you receive alerts.
Email notifications
Project updates, mentions, and comments.
Weekly digest
A summary of activity delivered every Monday.
Marketing emails
Tips, new features, and offers from our team.
Danger zone
These actions are permanent and cannot be undone.
Transfer ownership
Hand over full control of this workspace to another member.
Delete account
Permanently remove your account, data, and all workspaces.
Unsaved changes
HTML — multi-section settings form
<!-- Each section is its own form-block -->
<div class="form-block"> ... </div>
<div class="form-block"> ... </div>

<!-- Danger zone: tinted header + coloured border -->
<div class="form-block"
     style="border-color:var(--color-error-light);">
  <div class="form-block-header"
       style="background:var(--color-error-bg);
              border-bottom-color:var(--color-error-light);">
    <div class="form-block-title"
         style="color:var(--color-error-dark);">Danger zone</div>
  </div>
  ...
</div>

<!-- Sticky save footer -->
<div style="position:sticky;bottom:0;
  background:var(--color-neutral-0);
  border:1px solid var(--color-neutral-200);
  border-radius:var(--radius-lg);
  padding:14px 20px;
  box-shadow:var(--shadow-md);">
  <button class="btn btn-md btn-ghost">Discard</button>
  <button class="btn btn-md btn-primary">Save all changes</button>
</div>