Component Library 43

Copy-paste HTML + CSS for every component. Requires design system tokens (see design-tokens.json).

Buttonvariant: primary|secondary|ghost|destructive, size: sm|md|lg, disabled: boolean
Preview
CSS
.btn { display: inline-flex; align-items: center; justify-content: center; gap: 8px; font-family: var(--font-sans); font-weight: 600; border: none; border-radius: var(--radius-md); cursor: pointer; transition: all var(--duration-fast) var(--ease-default); text-decoration: none; }
.btn--primary { background: var(--color-brand-primary); color: var(--color-text-on-brand); }
.btn--primary:hover { filter: brightness(1.1); box-shadow: var(--shadow-md); }
.btn--secondary { background: transparent; color: var(--color-text-primary); border: 1px solid var(--color-border-default); }
.btn--secondary:hover { border-color: var(--color-brand-primary); color: var(--color-brand-primary); }
.btn--ghost { background: transparent; color: var(--color-text-secondary); }
.btn--ghost:hover { background: var(--color-bg-secondary); color: var(--color-text-primary); }
.btn--destructive { background: var(--color-error); color: var(--color-text-on-error, var(--color-text-on-brand)); }
.btn--sm { height: 36px; padding: 0 16px; font-size: var(--text-body-sm); min-width: 44px; }
.btn--md { height: 44px; padding: 0 20px; font-size: var(--text-body-md); }
.btn--lg { height: 52px; padding: 0 28px; font-size: var(--text-body-lg); }
.btn:focus-visible { outline: 2px solid var(--color-brand-primary); outline-offset: 2px; }
.btn:disabled { opacity: var(--opacity-disabled); cursor: not-allowed; }
HTML
<button class="btn btn--primary btn--md">Get Started</button>
<button class="btn btn--secondary btn--md">Learn More</button>
<button class="btn btn--ghost btn--md">Cancel</button>
<button class="btn btn--destructive btn--md">Delete</button>
React
import React from 'react';

export const Button = ({ variant = 'primary', size = 'md', children, disabled = false }) => {
  return (
    <button className={`btn btn--${variant} btn--${size}`} disabled={disabled}>
      {children}
    </button>
  );
};

// Usage:
// <Button variant="primary" size="md">Get Started</Button>
// <Button variant="secondary">Learn More</Button>
Vue
<template>
  <button :class="['uds-btn', `uds-btn--${variant}`, `uds-btn--${size}`]" :disabled="disabled">
    <slot>Button</slot>
  </button>
</template>

<script setup>
defineProps({
  variant: { type: String, default: 'primary' },
  size: { type: String, default: 'md' },
  disabled: { type: Boolean, default: false }
});
</script>
Svelte 5
<script lang="ts">
  let { variant = 'primary', size = 'md', onclick, children, ...restProps }: {
    variant?: 'primary' | 'secondary' | 'ghost' | 'destructive';
    size?: 'sm' | 'md' | 'lg';
    onclick?: (e: MouseEvent) => void;
    children?: import('svelte').Snippet;
    [key: string]: unknown;
  } = $props();
</script>

<button class="uds-btn uds-btn--{variant} uds-btn--{size}" {onclick} {...restProps}>
  {@render children?.()}
</button>

<style>
  .uds-btn { display: inline-flex; align-items: center; justify-content: center; border-radius: var(--radius-md); font-weight: 500; transition: all var(--duration-fast) var(--ease-out); cursor: pointer; border: none; }
  .uds-btn--primary { background: var(--color-brand-primary); color: var(--color-text-on-brand); }
  .uds-btn--secondary { background: var(--color-bg-secondary); color: var(--color-text-primary); }
  .uds-btn--ghost { background: transparent; color: var(--color-text-primary); }
  .uds-btn--destructive { background: var(--color-error); color: white; }
  .uds-btn--sm { height: 36px; padding: 0 12px; font-size: 0.875rem; }
  .uds-btn--md { height: 44px; padding: 0 16px; }
  .uds-btn--lg { height: 48px; padding: 0 24px; font-size: 1.125rem; }
</style>
Inputvariant: text|email|password|number|search|textarea, size: sm|md|lg, state: default|focus|error|disabled
Preview
CSS
.input { height: 44px; width: 100%; padding: 0 12px; border: 1px solid var(--color-border-input); border-radius: var(--radius-md); font-family: var(--font-sans); font-size: 16px; color: var(--color-text-primary); background: var(--color-bg-primary); transition: border-color var(--duration-fast), box-shadow var(--duration-fast); }
.input:focus { outline: none; border-color: var(--color-brand-primary); box-shadow: 0 0 0 3px rgba(var(--color-brand-primary-rgb), 0.15); }
.input--error { border-color: var(--color-error); }
.input-label { display: block; font-size: var(--text-body-sm); font-weight: 500; margin-bottom: 4px; }
.input-helper { font-size: var(--text-body-sm); color: var(--color-text-tertiary); margin-top: 4px; }
.input-error { font-size: var(--text-body-sm); color: var(--color-error); margin-top: 4px; }
HTML
<div>
  <label class="input-label" for="name">Full name</label>
  <input class="input" id="name" type="text" placeholder="Enter your name">
  <div class="input-helper">As it appears on your ID</div>
</div>

<!-- Error state -->
<div>
  <label class="input-label" for="email">Email</label>
  <input class="input input--error" id="email" type="email" value="bad" aria-invalid="true" aria-describedby="email-err">
  <div class="input-error" id="email-err" role="alert">Please enter a valid email</div>
</div>
React
import React, { useState } from 'react';

export const Input = ({ label, error, helper, type = 'text', placeholder = '', disabled = false }) => {
  const [value, setValue] = useState('');
  return (
    <div>
      {label && <label className="input-label">{label}</label>}
      <input
        className={`input ${error ? 'input--error' : ''}`}
        type={type}
        placeholder={placeholder}
        value={value}
        onChange={(e) => setValue(e.target.value)}
        disabled={disabled}
      />
      {error && <div className="input-error">{error}</div>}
      {helper && <div className="input-helper">{helper}</div>}
    </div>
  );
};
Vue
<template>
  <div>
    <label v-if="label" class="input-label">{{ label }}</label>
    <input
      :class="['input', { 'input--error': error }]"
      :type="type"
      :placeholder="placeholder"
      :value="modelValue"
      :disabled="disabled"
      @input="$emit('update:modelValue', $event.target.value)"
    />
    <div v-if="error" class="input-error">{{ error }}</div>
    <div v-if="helper" class="input-helper">{{ helper }}</div>
  </div>
</template>

<script setup>
defineProps({
  label: String,
  error: String,
  helper: String,
  type: { type: String, default: 'text' },
  placeholder: String,
  modelValue: String,
  disabled: Boolean
});
defineEmits(['update:modelValue']);
</script>
Svelte 5
<script lang="ts">
  let { type = 'text', value = $bindable(''), placeholder = '', label = '', error = '', helper = '', disabled = false, ...restProps }: {
    type?: string;
    value?: string;
    placeholder?: string;
    label?: string;
    error?: string;
    helper?: string;
    disabled?: boolean;
    [key: string]: unknown;
  } = $props();
</script>

{#if label}
  <label class="input-label">{label}</label>
{/if}
<input
  class={['input', error ? 'input--error' : ''].filter(Boolean).join(' ')}
  {type}
  bind:value
  {placeholder}
  {disabled}
  aria-invalid={error ? 'true' : undefined}
  {...restProps}
/>
{#if error}
  <div class="input-error" role="alert">{error}</div>
{:else if helper}
  <div class="input-helper">{helper}</div>
{/if}
SelectSame sizing and states as Input
Preview
CSS
/* Uses .input class from Input component */
HTML
<label class="input-label" for="country">Country</label>
<select class="input" id="country">
  <option>United States</option>
  <option>United Kingdom</option>
  <option>Canada</option>
</select>
Checkboxchecked: boolean, disabled: boolean
Preview
CSS
.checkbox-group { display: flex; align-items: center; gap: 8px; min-height: 44px; }
.checkbox-group input[type="checkbox"] { width: 20px; height: 20px; accent-color: var(--color-brand-primary); cursor: pointer; }
.checkbox-group label { font-size: var(--text-body-md); cursor: pointer; }
HTML
<div class="checkbox-group">
  <input type="checkbox" id="terms" />
  <label for="terms">I agree to the terms and conditions</label>
</div>
Togglechecked: boolean, disabled: boolean
Preview
CSS
.toggle { position: relative; width: 48px; height: 28px; background: var(--color-border-default); border-radius: var(--radius-full); border: none; cursor: pointer; transition: background var(--duration-fast); }
.toggle::after { content: ""; position: absolute; top: 3px; left: 3px; width: 22px; height: 22px; background: white; border-radius: var(--radius-full); transition: transform var(--duration-fast); }
.toggle.on { background: var(--color-brand-primary); }
.toggle.on::after { transform: translateX(20px); }
.toggle:focus-visible { outline: 2px solid var(--color-brand-primary); outline-offset: 2px; }
HTML
<button class="toggle on" role="switch" aria-checked="true" aria-label="Enable notifications"
  onclick="this.classList.toggle('on'); this.setAttribute('aria-checked', this.classList.contains('on'))">
</button>
Tabsvariant: line|pill|segmented, size: sm|md, orientation: horizontal|vertical
Preview
CSS
.tabs { border-bottom: 1px solid var(--color-border-default); display: flex; }
.tab { height: 44px; padding: 0 16px; border: none; background: none; font-family: var(--font-sans); font-size: var(--text-body-sm); font-weight: 500; color: var(--color-text-secondary); cursor: pointer; border-bottom: 2px solid transparent; transition: all var(--duration-fast); }
.tab:hover { color: var(--color-text-primary); background: rgba(0,0,0,0.04); }
.tab.active { color: var(--color-text-primary); border-bottom-color: var(--color-brand-primary); font-weight: 600; }
.tab:focus-visible { outline: 2px solid var(--color-brand-primary); outline-offset: -2px; }
.tab-panel { padding: 16px 0; }
HTML
<div role="tablist" class="tabs" aria-label="Settings">
  <button class="tab active" role="tab" aria-selected="true" id="tab-1" aria-controls="panel-1">General</button>
  <button class="tab" role="tab" aria-selected="false" id="tab-2" aria-controls="panel-2">Security</button>
  <button class="tab" role="tab" aria-selected="false" id="tab-3" aria-controls="panel-3">Billing</button>
</div>
<div class="tab-panel" role="tabpanel" id="panel-1" aria-labelledby="tab-1">
  General settings content...
</div>
Accordiontype: single|multi, variant: bordered|flush
Preview
Answer content
CSS
.accordion { border: 1px solid var(--color-border-default); border-radius: var(--radius-lg); overflow: hidden; }
.accordion-trigger { width: 100%; display: flex; align-items: center; justify-content: space-between; height: 52px; padding: 0 16px; border: none; border-bottom: 1px solid var(--color-border-default); background: var(--color-bg-primary); font-family: var(--font-sans); font-size: var(--text-body-md); font-weight: 500; color: var(--color-text-primary); cursor: pointer; }
.accordion-trigger:hover { background: var(--color-bg-secondary); }
.accordion-trigger:focus-visible { outline: 2px solid var(--color-brand-primary); outline-offset: -2px; }
.accordion-chevron { width: 20px; height: 20px; transition: transform var(--duration-fast); }
.accordion-trigger[aria-expanded="true"] .accordion-chevron { transform: rotate(180deg); }
.accordion-content { padding: 16px; font-size: var(--text-body-sm); color: var(--color-text-secondary); }
HTML
<div class="accordion">
  <button class="accordion-trigger" aria-expanded="true" aria-controls="acc-1">
    <span>Question text</span>
    <svg class="accordion-chevron" viewBox="0 0 20 20" fill="currentColor"><path d="M5.23 7.21a.75.75 0 011.06.02L10 11.168l3.71-3.938a.75.75 0 111.08 1.04l-4.25 4.5a.75.75 0 01-1.08 0l-4.25-4.5a.75.75 0 01.02-1.06z"/></svg>
  </button>
  <div class="accordion-content" id="acc-1">Answer content...</div>
</div>
Cardelevation: flat|raised|interactive
Preview

Card Title

Card description with supporting text.

CSS
.card { background: var(--color-bg-tertiary); border: 1px solid var(--color-border-default); border-radius: var(--radius-lg); padding: 24px; transition: transform var(--duration-normal) var(--ease-default), box-shadow var(--duration-normal) var(--ease-default); }
.card:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); }
HTML
<div class="card">
  <h3>Card Title</h3>
  <p>Card description with supporting text.</p>
</div>
React
import React from 'react';

export const Card = ({ title, children }) => (
  <div className="card">
    {title && <h3>{title}</h3>}
    {children}
  </div>
);
Vue
<template>
  <div class="uds-card">
    <h3 v-if="title">{{ title }}</h3>
    <slot />
  </div>
</template>

<script setup>
defineProps({ title: String });
</script>
Svelte 5
<script lang="ts">
  let { title = '', children }: {
    title?: string;
    children?: import('svelte').Snippet;
  } = $props();
</script>

<div class="uds-card">
  {#if title}<h3>{title}</h3>{/if}
  {@render children?.()}
</div>
Alertvariant: success|warning|error|info, dismissible: boolean
Preview
Success
Your changes have been saved.
CSS
.alert { display: flex; gap: 12px; padding: 16px; border-radius: var(--radius-md); border-left: 4px solid; }
.alert--success { border-color: var(--color-success); background: var(--color-success-bg); }
.alert--warning { border-color: var(--color-warning); background: var(--color-warning-bg); }
.alert--error { border-color: var(--color-error); background: var(--color-error-bg); }
.alert--info { border-color: var(--color-info); background: var(--color-info-bg); }
.alert-title { font-weight: 600; margin-bottom: 4px; }
.alert-body { font-size: var(--text-body-sm); color: var(--color-text-secondary); }
HTML
<div class="alert alert--success" role="status">
  <div>
    <div class="alert-title">Success</div>
    <div class="alert-body">Your changes have been saved.</div>
  </div>
</div>

<div class="alert alert--error" role="alert">
  <div>
    <div class="alert-title">Error</div>
    <div class="alert-body">Payment failed. Please try again.</div>
  </div>
</div>
React
import React, { useState } from 'react';

export const Alert = ({ variant = 'info', title, message, dismissible = false }) => {
  const [visible, setVisible] = useState(true);
  return visible && (
    <div className={`alert alert--${variant}`}>
      <div>
        {title && <div className="alert-title">{title}</div>}
        {message && <div className="alert-body">{message}</div>}
      </div>
      {dismissible && <button onClick={() => setVisible(false)}>✕</button>}
    </div>
  );
};
Vue
<template>
  <div v-if="visible" :class="['uds-alert', `uds-alert--${variant}`]">
    <div>
      <div v-if="title" class="uds-alert-title">{{ title }}</div>
      <div v-if="message" class="uds-alert-body">{{ message }}</div>
    </div>
    <button v-if="dismissible" @click="visible = false" aria-label="Dismiss">✕</button>
  </div>
</template>

<script setup>
import { ref } from 'vue';
defineProps({ variant: { type: String, default: 'info' }, title: String, message: String, dismissible: Boolean });
const visible = ref(true);
</script>
Svelte 5
<script lang="ts">
  let { variant = 'info', title = '', message = '', dismissible = false }: {
    variant?: 'success' | 'warning' | 'error' | 'info';
    title?: string;
    message?: string;
    dismissible?: boolean;
  } = $props();
  let visible = $state(true);
</script>

{#if visible}
  <div class={`uds-alert uds-alert--${variant}`} role={variant === 'error' ? 'alert' : 'status'}>
    <div>
      {#if title}<div class="uds-alert-title">{title}</div>{/if}
      {#if message}<div class="uds-alert-body">{message}</div>{/if}
    </div>
    {#if dismissible}
      <button onclick={() => visible = false} aria-label="Dismiss">✕</button>
    {/if}
  </div>
{/if}
Badgevariant: brand|success|warning|error|neutral, size: sm|md
Preview NewActiveFailed
CSS
.badge { display: inline-flex; align-items: center; gap: 4px; padding: 2px 10px; border-radius: var(--radius-full); font-size: var(--text-label); font-weight: 600; }
.badge--brand { background: var(--color-brand-muted); color: var(--color-brand-primary); }
.badge--success { background: var(--color-success-bg); color: var(--color-success); }
.badge--error { background: var(--color-error-bg); color: var(--color-error); }
.badge--neutral { background: var(--color-bg-tertiary); color: var(--color-text-secondary); }
HTML
<span class="badge badge--brand">New</span>
<span class="badge badge--success">Active</span>
<span class="badge badge--error">Failed</span>
<span class="badge badge--neutral">Draft</span>
React
import React from 'react';

export const Badge = ({ variant = 'brand', children }) => (
  <span className={`badge badge--${variant}`}>{children}</span>
);
Vue
<template>
  <span :class="['uds-badge', `uds-badge--${variant}`]"><slot /></span>
</template>

<script setup>
defineProps({ variant: { type: String, default: 'brand' } });
</script>
Avatarsize: xs|sm|md|lg|xl, shape: circle|square, status: online|offline|busy|away
Preview
CSS
.avatar { display: inline-flex; align-items: center; justify-content: center; border-radius: var(--radius-full); overflow: hidden; background: var(--color-brand-muted); color: var(--color-brand-primary); font-weight: 700; flex-shrink: 0; position: relative; }
.avatar--xs { width: 24px; height: 24px; font-size: 10px; }
.avatar--sm { width: 32px; height: 32px; font-size: 12px; }
.avatar--md { width: 40px; height: 40px; font-size: 14px; }
.avatar--lg { width: 48px; height: 48px; font-size: 16px; }
.avatar--xl { width: 64px; height: 64px; font-size: 20px; }
.avatar-group { display: flex; }
.avatar-group .avatar { border: 2px solid var(--color-bg-primary); margin-left: -8px; }
.avatar-group .avatar:first-child { margin-left: 0; }
.avatar-status { position: absolute; bottom: 0; right: 0; width: 10px; height: 10px; border-radius: var(--radius-full); border: 2px solid var(--color-bg-primary); }
.avatar-status--online { background: var(--color-success); }
.avatar-status--busy { background: var(--color-error); }
.avatar-status--away { background: var(--color-warning); }
HTML
<div class="avatar avatar--md">MK</div>

<!-- With status -->
<div class="avatar avatar--lg" style="position:relative">
  JD
  <span class="avatar-status avatar-status--online"></span>
</div>

<!-- Group -->
<div class="avatar-group">
  <div class="avatar avatar--md">A</div>
  <div class="avatar avatar--md">B</div>
  <div class="avatar avatar--md">C</div>
  <div class="avatar avatar--md" style="background:var(--color-bg-tertiary);color:var(--color-text-secondary)">+5</div>
</div>
Tooltipposition: top|bottom|left|right, delay: number (ms), maxWidth: number (px)
Preview
Tooltip text
CSS
.tooltip-wrap { position: relative; display: inline-block; }
.tooltip-content { position: absolute; bottom: calc(100% + 8px); left: 50%; transform: translateX(-50%); background: var(--color-bg-inverse); color: var(--color-bg-primary); padding: 6px 12px; border-radius: var(--radius-sm); font-size: var(--text-body-sm); white-space: nowrap; opacity: 0; pointer-events: none; transition: opacity var(--duration-fast); z-index: var(--z-dropdown); }
.tooltip-content::after { content: ""; position: absolute; top: 100%; left: 50%; transform: translateX(-50%); border: 6px solid transparent; border-top-color: var(--color-bg-inverse); }
.tooltip-wrap:hover .tooltip-content, .tooltip-wrap:focus-within .tooltip-content { opacity: 1; }
HTML
<div class="tooltip-wrap">
  <button class="btn btn--secondary btn--sm" aria-describedby="tip-1">Hover me</button>
  <div class="tooltip-content" id="tip-1" role="tooltip">Tooltip text here</div>
</div>
Toastvariant: success|error|warning|info|neutral, position: top-right|bottom-right|top-center|bottom-center, duration: number (ms)
Preview
Saved
Changes saved.
CSS
.toast-container { position: fixed; bottom: 16px; right: 16px; z-index: var(--z-toast); display: flex; flex-direction: column; gap: 8px; }
.toast { display: flex; align-items: flex-start; gap: 12px; min-width: 320px; max-width: 420px; padding: 12px 16px; background: var(--color-bg-primary); border: 1px solid var(--color-border-default); border-radius: var(--radius-lg); box-shadow: var(--shadow-lg); border-left: 4px solid; }
.toast--success { border-left-color: var(--color-success); }
.toast--error { border-left-color: var(--color-error); }
.toast--warning { border-left-color: var(--color-warning); }
.toast--info { border-left-color: var(--color-info); }
.toast-title { font-weight: 600; font-size: var(--text-body-sm); }
.toast-message { font-size: var(--text-body-sm); color: var(--color-text-secondary); margin-top: 2px; }
HTML
<div class="toast-container">
  <div class="toast toast--success" role="status">
    <div>
      <div class="toast-title">Saved</div>
      <div class="toast-message">Changes saved successfully.</div>
    </div>
  </div>
</div>
Skeletonvariant: text|circle|rectangle|custom
Preview
CSS
.skeleton { background: linear-gradient(90deg, var(--color-bg-tertiary) 25%, var(--color-bg-secondary) 50%, var(--color-bg-tertiary) 75%); background-size: 200% 100%; animation: shimmer 1.5s infinite; border-radius: 4px; }
.skeleton-line { height: 16px; margin-bottom: 12px; }
.skeleton-circle { border-radius: var(--radius-full); }
@keyframes shimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }
@media (prefers-reduced-motion: reduce) { .skeleton { animation: none; } }
HTML
<div aria-busy="true">
  <div style="display:flex;gap:16px;align-items:flex-start">
    <div class="skeleton skeleton-circle" style="width:48px;height:48px;flex-shrink:0" aria-hidden="true"></div>
    <div style="flex:1">
      <div class="skeleton skeleton-line" style="width:40%" aria-hidden="true"></div>
      <div class="skeleton skeleton-line" style="width:100%" aria-hidden="true"></div>
      <div class="skeleton skeleton-line" style="width:80%" aria-hidden="true"></div>
    </div>
  </div>
</div>
DataTablesortable: boolean, selectable: boolean, striped: boolean, stickyHeader: boolean, density: compact|default|comfortable
Preview
NameStatusRole
AliceActiveAdmin
CSS
.data-table { width: 100%; border-collapse: collapse; border: 1px solid var(--color-border-default); border-radius: var(--radius-lg); overflow: hidden; }
.data-table th { padding: 0 16px; height: 44px; background: var(--color-bg-secondary); font-weight: 600; font-size: var(--text-body-sm); text-align: left; border-bottom: 2px solid var(--color-border-default); }
.data-table td { padding: 0 16px; height: 48px; border-bottom: 1px solid var(--color-border-subtle); font-size: var(--text-body-sm); }
.data-table tr:hover td { background: var(--color-bg-secondary); }
.data-table--striped tr:nth-child(odd) td { background: var(--color-bg-secondary); }
HTML
<table class="data-table">
  <thead>
    <tr><th>Name</th><th>Status</th><th>Role</th></tr>
  </thead>
  <tbody>
    <tr><td>Alice Johnson</td><td><span class="badge badge--success">Active</span></td><td>Admin</td></tr>
    <tr><td>Bob Smith</td><td><span class="badge badge--brand">Pending</span></td><td>Editor</td></tr>
  </tbody>
</table>
CodeBlocklanguage: string, showLineNumbers: boolean
CSS
.code-block { background: #1E1E2E; color: #D4D4E8; border-radius: var(--radius-lg); overflow: hidden; }
.code-block-header { display: flex; align-items: center; justify-content: space-between; padding: var(--space-2) var(--space-4); background: var(--color-code-header-bg); font-size: var(--text-label); }
.code-block-lang { color: var(--color-code-muted); }
.code-block-copy { padding: var(--space-1) var(--space-3); font-size: 11px; background: rgba(255,255,255,0.1); color: var(--color-code-muted); border: none; border-radius: var(--radius-sm); cursor: pointer; }
.code-block pre { padding: 20px; font-family: var(--font-mono); font-size: 13px; line-height: 1.6; overflow-x: auto; margin: 0; }
HTML
<div class="code-block">
  <div class="code-block-header">
    <span class="code-block-lang">javascript</span>
    <button class="code-block-copy">Copy</button>
  </div>
  <pre><code>const greeting = 'Hello, World!';</code></pre>
</div>
PricingTablecolumns: 2|3|4, featured: index, toggle: boolean (monthly/annual)
CSS
.pricing-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px; max-width: 1120px; }
.pricing-card { padding: 40px; border: 1px solid var(--color-border-default); border-radius: var(--radius-lg); background: var(--color-bg-primary); }
.pricing-card--featured { border: 2px solid var(--color-brand-primary); box-shadow: var(--shadow-lg); position: relative; }
.pricing-name { font-size: var(--text-heading-sm); font-weight: 600; }
.pricing-price { font-size: var(--text-display-md); font-weight: 800; margin: 16px 0; }
.pricing-price span { font-size: var(--text-body-sm); font-weight: 400; color: var(--color-text-secondary); }
.pricing-features { list-style: none; margin: 24px 0; }
.pricing-features li { padding: 8px 0; font-size: var(--text-body-sm); color: var(--color-text-secondary); }
HTML
<div class="pricing-grid">
  <div class="pricing-card">
    <div class="pricing-name">Starter</div>
    <div class="pricing-price">$9<span>/mo</span></div>
    <ul class="pricing-features"><li>✓ 5 projects</li><li>✓ Basic analytics</li></ul>
    <button class="btn btn--secondary btn--md" style="width:100%">Get Started</button>
  </div>
  <div class="pricing-card pricing-card--featured">
    <div class="pricing-name">Pro</div>
    <div class="pricing-price">$29<span>/mo</span></div>
    <ul class="pricing-features"><li>✓ Unlimited projects</li><li>✓ Advanced analytics</li></ul>
    <button class="btn btn--primary btn--md" style="width:100%">Get Started</button>
  </div>
</div>
Radiochecked: boolean, disabled: boolean, variant: standard|card
CSS
.radio-group { display: flex; flex-direction: column; gap: 4px; }
.radio-label { display: flex; align-items: center; gap: 8px; min-height: 44px; cursor: pointer; font-size: var(--text-body-md); }
.radio-label input[type="radio"] { width: 20px; height: 20px; accent-color: var(--color-brand-primary); cursor: pointer; flex-shrink: 0; }
.radio-label input:disabled { opacity: var(--opacity-disabled); cursor: not-allowed; }
.radio-label input:focus-visible { outline: 2px solid var(--color-brand-primary); outline-offset: 2px; }
HTML
<fieldset>
  <legend class="input-label">Billing frequency</legend>
  <div class="radio-group">
    <label class="radio-label">
      <input type="radio" name="billing" value="monthly" checked /> Monthly
    </label>
    <label class="radio-label">
      <input type="radio" name="billing" value="annual" /> Annual (save 20%)
    </label>
  </div>
</fieldset>
Hero Sectionvariant: centered|split|gradient-mesh|video-bg, size: full(85vh)|compact(60vh)
CSS
.hero { text-align: center; padding: 80px 24px; min-height: 85vh; display: flex; flex-direction: column; align-items: center; justify-content: center; }
.hero-headline { font-family: var(--font-display); font-size: var(--text-display-xl); font-weight: 800; letter-spacing: -0.02em; max-width: 800px; margin-bottom: 16px; }
.hero-subheadline { font-size: var(--text-body-lg); color: var(--color-text-secondary); max-width: 600px; margin-bottom: 32px; }
.hero-actions { display: flex; gap: 12px; flex-wrap: wrap; justify-content: center; }
.hero--gradient { background: var(--gradient-hero); color: var(--color-text-on-brand); }
.hero--gradient .hero-subheadline { color: rgba(255,255,255,0.85); }
.hero--dark { background: var(--color-bg-inverse); color: var(--color-bg-primary); }
.hero--dark .hero-subheadline { color: rgba(255,255,255,0.7); }
HTML
<section class="hero">
  <h1 class="hero-headline">Build faster, ship smarter</h1>
  <p class="hero-subheadline">The platform teams love for building products that delight customers.</p>
  <div class="hero-actions">
    <button class="btn btn--lg btn--primary">Start Free Trial</button>
    <button class="btn btn--lg btn--secondary">Watch Demo</button>
  </div>
</section>
Social Proof Barvariant: logo-strip|stats-counter|testimonial-mini|combined
Trusted by industry leaders
GoogleStripeShopifyNotion
CSS
.social-proof { text-align: center; padding: 40px 24px; }
.social-proof-label { font-size: var(--text-label); text-transform: uppercase; letter-spacing: 0.08em; font-weight: 600; color: var(--color-text-tertiary); margin-bottom: 24px; }
.logo-bar { display: flex; align-items: center; justify-content: center; gap: 48px; flex-wrap: wrap; }
.logo-bar img { height: 32px; opacity: 0.6; filter: grayscale(100%); transition: all var(--duration-normal); }
.logo-bar img:hover { opacity: 1; filter: grayscale(0%); }
HTML
<section class="social-proof">
  <p class="social-proof-label">Trusted by industry leaders</p>
  <div class="logo-bar" role="list" aria-label="Trusted companies">
    <img src="logo-google.svg" alt="Google" role="listitem" />
    <img src="logo-stripe.svg" alt="Stripe" role="listitem" />
    <img src="logo-shopify.svg" alt="Shopify" role="listitem" />
    <img src="logo-notion.svg" alt="Notion" role="listitem" />
  </div>
</section>
Testimonial Cardvariant: quote-card|video|metric|carousel
“This design system transformed our workflow completely.”
Sarah Kim
VP Engineering, TechCorp
CSS
.testimonial { padding: 32px; background: var(--color-bg-tertiary); border: 1px solid var(--color-border-default); border-radius: var(--radius-lg); }
.testimonial blockquote { font-size: var(--text-body-lg); font-style: italic; line-height: 1.7; margin-bottom: 24px; }
.testimonial-author { display: flex; align-items: center; gap: 12px; }
.testimonial-avatar { width: 48px; height: 48px; border-radius: var(--radius-full); background: var(--color-brand-muted); display: flex; align-items: center; justify-content: center; font-weight: 700; color: var(--color-brand-primary); }
.testimonial-name { font-weight: 600; }
.testimonial-role { font-size: var(--text-body-sm); color: var(--color-text-secondary); }
HTML
<div class="testimonial">
  <blockquote>&ldquo;This platform transformed our workflow.&rdquo;</blockquote>
  <div class="testimonial-author">
    <div class="testimonial-avatar">SK</div>
    <div>
      <div class="testimonial-name">Sarah Kim</div>
      <div class="testimonial-role">VP Engineering, TechCorp</div>
    </div>
  </div>
</div>
Progress Indicatorvariant: bar|circular|stepper, value: number, max: number, indeterminate: boolean
Uploading... 65%
Processing...
CSS
.progress { height: 8px; background: var(--color-bg-tertiary); border-radius: var(--radius-full); overflow: hidden; }
.progress-bar { height: 100%; background: var(--color-brand-primary); border-radius: var(--radius-full); transition: width var(--duration-normal) var(--ease-default); }
.progress-label { font-size: var(--text-body-sm); font-weight: 500; margin-bottom: 4px; }
/* Indeterminate */
.progress--indeterminate .progress-bar { width: 100%; background: linear-gradient(90deg, var(--color-brand-primary) 0%, var(--color-brand-muted) 50%, var(--color-brand-primary) 100%); background-size: 200% 100%; animation: progress-shimmer 1.5s linear infinite; }
@keyframes progress-shimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }
@media (prefers-reduced-motion: reduce) { .progress--indeterminate .progress-bar { animation: none; } }
HTML
<div>
  <div class="progress-label">Uploading... 65%</div>
  <div class="progress" role="progressbar" aria-valuenow="65" aria-valuemin="0" aria-valuemax="100">
    <div class="progress-bar" style="width: 65%"></div>
  </div>
</div>

<!-- Indeterminate -->
<div class="progress progress--indeterminate" role="progressbar" aria-label="Loading">
  <div class="progress-bar"></div>
</div>
Date Pickervariant: single|range|with-time, min: date, max: date, locale: string
CSS
.date-input { width: 100%; max-width: 280px; height: 44px; padding: 0 12px; font-family: var(--font-sans); font-size: var(--text-body-md); color: var(--color-text-primary); background: var(--color-bg-primary); border: 1px solid var(--color-border-input); border-radius: var(--radius-md); transition: border-color var(--duration-fast), box-shadow var(--duration-fast); }
.date-input:focus { outline: none; border-color: var(--color-brand-primary); box-shadow: 0 0 0 3px rgba(var(--color-brand-primary-rgb), 0.15); }
.date-calendar { background: var(--color-bg-primary); border: 1px solid var(--color-border-default); border-radius: var(--radius-lg); box-shadow: var(--shadow-lg); padding: 16px; width: 300px; }
.date-calendar-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 12px; font-weight: 600; }
.date-calendar-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; text-align: center; }
.date-cell { width: 36px; height: 36px; display: flex; align-items: center; justify-content: center; border-radius: var(--radius-full); font-size: var(--text-body-sm); cursor: pointer; }
.date-cell:hover { background: var(--color-bg-secondary); }
.date-cell--selected { background: var(--color-brand-primary); color: var(--color-text-on-brand); }
.date-cell--today { font-weight: 700; color: var(--color-brand-primary); }
.date-cell--disabled { opacity: var(--opacity-disabled); cursor: not-allowed; }
HTML
<label class="input-label" for="date">Select date</label>
<input type="date" class="date-input" id="date" />

<!-- Custom calendar panel (JS required for full implementation) -->
<div class="date-calendar" role="grid" aria-label="March 2026">
  <div class="date-calendar-header">
    <button aria-label="Previous month">&lsaquo;</button>
    <span>March 2026</span>
    <button aria-label="Next month">&rsaquo;</button>
  </div>
  <div class="date-calendar-grid" role="row">
    <div class="date-cell date-cell--today" role="gridcell" aria-selected="false">11</div>
    <div class="date-cell date-cell--selected" role="gridcell" aria-selected="true">15</div>
  </div>
</div>
Command Paletteactions: Action[], groups: Group[], placeholder: string
CSS
.command-palette-overlay { position: fixed; inset: 0; background: rgba(0,0,0,0.5); backdrop-filter: blur(4px); display: flex; align-items: flex-start; justify-content: center; padding-top: 20vh; z-index: var(--z-modal); }
.command-palette { width: 560px; max-height: 400px; background: var(--color-bg-primary); border: 1px solid var(--color-border-default); border-radius: var(--radius-xl); box-shadow: var(--shadow-xl); overflow: hidden; }
.command-input { width: 100%; height: 52px; padding: 0 20px; border: none; border-bottom: 1px solid var(--color-border-default); font-family: var(--font-sans); font-size: var(--text-body-md); background: transparent; color: var(--color-text-primary); outline: none; }
.command-input::placeholder { color: var(--color-text-tertiary); }
.command-list { overflow-y: auto; max-height: 320px; padding: 8px; }
.command-group-label { padding: 8px 12px; font-size: var(--text-label); font-weight: 600; color: var(--color-text-tertiary); text-transform: uppercase; letter-spacing: 0.05em; }
.command-item { display: flex; align-items: center; gap: 12px; padding: 0 12px; height: 40px; border-radius: var(--radius-md); cursor: pointer; font-size: var(--text-body-sm); }
.command-item:hover, .command-item--active { background: var(--color-bg-secondary); }
.command-shortcut { margin-left: auto; font-size: var(--text-label); color: var(--color-text-tertiary); font-family: var(--font-mono); }
HTML
<div class="command-palette-overlay">
  <div class="command-palette" role="combobox" aria-expanded="true" aria-haspopup="listbox">
    <input class="command-input" type="text" placeholder="Type a command or search..." aria-label="Command palette" />
    <div class="command-list" role="listbox">
      <div class="command-group-label">Actions</div>
      <div class="command-item command-item--active" role="option" aria-selected="true">
        New project <span class="command-shortcut">⌘N</span>
      </div>
      <div class="command-item" role="option">
        Search files <span class="command-shortcut">⌘P</span>
      </div>
      <div class="command-group-label">Navigation</div>
      <div class="command-item" role="option">Go to Dashboard</div>
      <div class="command-item" role="option">Go to Settings</div>
    </div>
  </div>
</div>
Side Navigationvariant: default|collapsed|with-sections, collapsed: boolean, width: default(240px)|collapsed(64px)
CSS
.sidenav { width: 240px; height: 100vh; background: var(--color-bg-primary); border-right: 1px solid var(--color-border-default); padding: 16px 8px; display: flex; flex-direction: column; position: sticky; top: 0; }
.sidenav-brand { padding: 8px 12px; font-weight: 700; font-size: var(--text-heading-sm); margin-bottom: 16px; }
.sidenav-section { margin-bottom: 16px; }
.sidenav-section-label { padding: 4px 12px; font-size: var(--text-label); font-weight: 600; color: var(--color-text-tertiary); text-transform: uppercase; letter-spacing: 0.05em; margin-bottom: 4px; }
.sidenav-item { display: flex; align-items: center; gap: 10px; height: 36px; padding: 0 12px; border-radius: var(--radius-md); font-size: var(--text-body-sm); font-weight: 500; color: var(--color-text-secondary); cursor: pointer; text-decoration: none; transition: all var(--duration-fast); }
.sidenav-item:hover { background: var(--color-bg-secondary); color: var(--color-text-primary); }
.sidenav-item--active { background: var(--color-brand-muted); color: var(--color-brand-primary); font-weight: 600; }
.sidenav-item:focus-visible { outline: 2px solid var(--color-brand-primary); outline-offset: -2px; }
/* Collapsed variant */
.sidenav--collapsed { width: 64px; align-items: center; }
.sidenav--collapsed .sidenav-item { justify-content: center; padding: 0; width: 40px; height: 40px; }
.sidenav--collapsed .sidenav-item span { display: none; }
HTML
<nav class="sidenav" aria-label="Side navigation">
  <div class="sidenav-brand">Acme</div>
  <div class="sidenav-section">
    <div class="sidenav-section-label">Main</div>
    <a href="#" class="sidenav-item sidenav-item--active" aria-current="page">
      <span>Dashboard</span>
    </a>
    <a href="#" class="sidenav-item"><span>Projects</span></a>
    <a href="#" class="sidenav-item"><span>Analytics</span></a>
  </div>
  <div class="sidenav-section">
    <div class="sidenav-section-label">Settings</div>
    <a href="#" class="sidenav-item"><span>Account</span></a>
    <a href="#" class="sidenav-item"><span>Team</span></a>
  </div>
</nav>
Feature Cardvariant: icon-top|image-top|horizontal|stat-card, title, description, link
Preview

Feature title

Supporting description for the feature.

CSS
.feature-card { padding: 24px; border: 1px solid var(--color-border-default); border-radius: var(--radius-lg); background: var(--color-bg-primary); }
.feature-card__icon { width: 48px; height: 48px; border-radius: var(--radius-md); background: var(--color-brand-muted); margin-bottom: 16px; }
.feature-card__title { font-size: var(--text-heading-sm); margin-bottom: 8px; }
.feature-card__desc { font-size: var(--text-body-sm); color: var(--color-text-secondary); }
HTML
<div class="feature-card">
  <div class="feature-card__icon" aria-hidden="true"></div>
  <h3 class="feature-card__title">Feature title</h3>
  <p class="feature-card__desc">Supporting description.</p>
</div>
File Uploadvariant: dropzone|button|avatar-upload, accept, maxSize, multiple
Preview
Drag and drop files or click to upload
CSS
.file-dropzone { border: 2px dashed var(--color-border-default); border-radius: var(--radius-lg); padding: 32px; text-align: center; background: var(--color-bg-tertiary); cursor: pointer; transition: border-color var(--duration-fast); }
.file-dropzone:hover { border-color: var(--color-brand-primary); }
.file-dropzone input[type="file"] { position: absolute; opacity: 0; width: 100%; height: 100%; cursor: pointer; }
HTML
<label class="file-dropzone">
  <input type="file" multiple aria-label="Upload files" />
  Drag and drop or click to upload
</label>
Drawerside: left|right|top|bottom, open: boolean, onClose
CSS
.drawer-overlay { position: fixed; inset: 0; background: rgba(0,0,0,0.4); z-index: var(--z-modal); }
.drawer { position: fixed; top: 0; right: 0; width: 400px; max-width: 100%; height: 100vh; background: var(--color-bg-primary); box-shadow: var(--shadow-xl); z-index: var(--z-modal); padding: 24px; overflow-y: auto; }
.drawer-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 24px; }
HTML
<div class="drawer-overlay" aria-hidden="true">
  <div class="drawer" role="dialog" aria-modal="true" aria-label="Panel">
    <div class="drawer-header"><h2>Title</h2><button aria-label="Close">&times;</button></div>
    <p>Drawer content.</p>
  </div>
</div>
Popoverposition: top|bottom|left|right|auto, content, trigger
Preview
Popover content
CSS
.popover { position: absolute; padding: 12px; background: var(--color-bg-primary); border: 1px solid var(--color-border-default); border-radius: var(--radius-md); box-shadow: var(--shadow-lg); z-index: var(--z-dropdown); font-size: var(--text-body-sm); }
HTML
<div style="position:relative">
  <button id="popover-trigger" aria-haspopup="true" aria-expanded="false">Trigger</button>
  <div class="popover" role="dialog" id="popover-content" hidden>Content</div>
</div>
Comboboxvariant: autocomplete|multiselect|creatable, options[], placeholder, onSelect
Preview
Option 1
Option 2
Option 3
CSS
.combobox-listbox { margin-top: 4px; padding: 8px; background: var(--color-bg-primary); border: 1px solid var(--color-border-default); border-radius: var(--radius-md); max-height: 240px; overflow-y: auto; }
.combobox-option { padding: 8px 12px; border-radius: var(--radius-sm); cursor: pointer; }
.combobox-option[aria-selected="true"] { background: var(--color-brand-muted); }
HTML
<div role="combobox" aria-expanded="false" aria-haspopup="listbox">
  <input type="text" aria-autocomplete="list" aria-controls="listbox" aria-activedescendant="" />
  <ul id="listbox" role="listbox" class="combobox-listbox" hidden><li role="option">Option 1</li></ul>
</div>
Alert Dialogvariant: info|warning|destructive, title, description, onConfirm, onCancel
CSS
.alert-dialog-overlay { position: fixed; inset: 0; background: rgba(0,0,0,0.5); display: flex; align-items: center; justify-content: center; z-index: var(--z-modal); }
.alert-dialog { max-width: 400px; padding: 24px; background: var(--color-bg-primary); border-radius: var(--radius-lg); box-shadow: var(--shadow-xl); }
.alert-dialog__actions { display: flex; gap: 12px; justify-content: flex-end; margin-top: 24px; }
HTML
<div class="alert-dialog-overlay" role="alertdialog" aria-modal="true" aria-labelledby="alert-title" aria-describedby="alert-desc">
  <div class="alert-dialog">
    <h2 id="alert-title">Confirm action</h2>
    <p id="alert-desc">This action cannot be undone.</p>
    <div class="alert-dialog__actions"><button class="btn btn--secondary">Cancel</button><button class="btn btn--primary">Confirm</button></div>
  </div>
</div>
Chip Inputchips[], onAdd, onRemove, maxChips, placeholder
Preview
Tag 1Tag 2
CSS
.chip-input { display: flex; flex-wrap: wrap; gap: 8px; padding: 8px 12px; border: 1px solid var(--color-border-input); border-radius: var(--radius-md); min-height: 44px; background: var(--color-bg-primary); }
.chip { padding: 4px 8px; background: var(--color-brand-muted); border-radius: var(--radius-sm); font-size: var(--text-body-sm); display: inline-flex; align-items: center; gap: 4px; }
.chip-remove { background: none; border: none; cursor: pointer; padding: 0 2px; }
.chip-input input { border: none; flex: 1; min-width: 80px; background: transparent; outline: none; font-size: var(--text-body-md); }
HTML
<div class="chip-input" role="listbox">
  <span class="chip" role="option">Tag 1 <button class="chip-remove" aria-label="Remove">&times;</button></span>
  <input type="text" aria-label="Add chip" placeholder="Add..." />
</div>
Steppersteps[], activeStep, orientation: horizontal|vertical, linear: boolean
Preview
123
CSS
.stepper { display: flex; align-items: center; gap: 8px; }
.stepper-step { width: 28px; height: 28px; border-radius: 9999px; display: flex; align-items: center; justify-content: center; font-size: var(--text-body-sm); font-weight: 600; }
.stepper-step--active, .stepper-step--completed { background: var(--color-brand-primary); color: var(--color-text-on-brand); }
.stepper-step--pending { border: 2px solid var(--color-border-default); color: var(--color-text-tertiary); }
.stepper-connector { width: 40px; height: 2px; background: var(--color-border-subtle); }
.stepper-connector--completed { background: var(--color-brand-primary); }
HTML
<nav class="stepper" aria-label="Progress">
  <span class="stepper-step stepper-step--completed" aria-current="step">1</span>
  <span class="stepper-connector stepper-connector--completed"></span>
  <span class="stepper-step stepper-step--active">2</span>
  <span class="stepper-connector"></span>
  <span class="stepper-step stepper-step--pending">3</span>
</nav>
Segmented Controloptions[], value, onChange, variant: default|icon-only
Preview
CSS
.segmented-control { display: inline-flex; padding: 4px; background: var(--color-bg-tertiary); border-radius: var(--radius-md); gap: 2px; }
.segmented-control [role="radio"] { border-radius: 6px; }
.segmented-control [role="radio"][aria-checked="true"] { background: var(--color-bg-primary); box-shadow: var(--shadow-xs); }
HTML
<div class="segmented-control" role="radiogroup" aria-label="Options">
  <button role="radio" aria-checked="true">Option A</button>
  <button role="radio" aria-checked="false">Option B</button>
  <button role="radio" aria-checked="false">Option C</button>
</div>
Toolbarorientation: horizontal|vertical, items[], ariaLabel
Preview
CSS
.toolbar { display: flex; gap: 4px; padding: 8px; background: var(--color-bg-tertiary); border-radius: var(--radius-md); }
.toolbar-divider { width: 1px; background: var(--color-border-default); align-self: stretch; }
HTML
<div class="toolbar" role="toolbar" aria-label="Formatting">
  <button type="button" aria-label="Bold">B</button>
  <button type="button" aria-label="Italic">I</button>
  <span class="toolbar-divider" aria-hidden="true"></span>
  <button type="button" aria-label="List">List</button>
</div>
Tree Viewdata[], selectionMode: single|multi|checkbox, onSelect, onExpand
Preview
Documents
File 1
File 2
CSS
.tree { font-size: var(--text-body-sm); }
.tree-item { display: flex; align-items: center; gap: 8px; padding: 8px 12px; cursor: pointer; border-radius: var(--radius-sm); }
.tree-item:hover { background: var(--color-bg-secondary); }
.tree-item[aria-expanded="true"] { font-weight: 600; }
.tree-group { padding-left: 20px; }
.tree-leaf { padding: 6px 12px; border-radius: var(--radius-sm); }
HTML
<div class="tree" role="tree" aria-label="Folder structure">
  <div class="tree-item" role="treeitem" aria-expanded="true"><span>&#9660;</span><span>Documents</span></div>
  <div class="tree-group" role="group"><div class="tree-leaf" role="treeitem">File 1</div><div class="tree-leaf" role="treeitem">File 2</div></div>
</div>
OTP Inputlength: 4|6, value, onChange, inputMode: numeric|alphanumeric
Preview
CSS
.otp-input { display: flex; gap: 8px; }
.otp-input input { width: 48px; height: 52px; text-align: center; font-size: 1.5rem; border: 1px solid var(--color-border-input); border-radius: var(--radius-md); font-family: var(--font-mono); }
.otp-input input:focus { outline: none; border-color: var(--color-brand-primary); box-shadow: 0 0 0 3px rgba(var(--color-brand-primary-rgb), 0.15); }
HTML
<div class="otp-input" role="group" aria-label="One-time code">
  <input type="text" inputmode="numeric" maxlength="1" aria-label="Digit 1" autocomplete="one-time-code" />
  <input type="text" inputmode="numeric" maxlength="1" aria-label="Digit 2" />
  <input type="text" inputmode="numeric" maxlength="1" aria-label="Digit 3" />
  <input type="text" inputmode="numeric" maxlength="1" aria-label="Digit 4" />
</div>