Buttons
Action-oriented buttons designed to feel approachable and responsive. Every button provides clear feedback and accessibility.
Interactive Playground
Build your button by selecting options below.
<button class="btn btn-primary btn-md">Button</button>
Button Variants
Three variants for different levels of visual emphasis.
<button class="btn btn-primary">Primary</button>
<button class="btn btn-secondary">Secondary</button>
<button class="btn btn-ghost">Ghost</button>
Sizes
Three sizes to fit different contexts and hierarchy.
<button class="btn btn-primary btn-sm">Small</button>
<button class="btn btn-primary btn-md">Medium</button>
<button class="btn btn-primary btn-lg">Large</button>
With Icons
Buttons can include icons for additional visual context.
<button class="btn btn-primary btn-icon-left">
<svg>...</svg>
Continue
</button>
<button class="btn btn-ghost btn-icon-only" aria-label="Settings">
<svg>...</svg>
</button>
Persona Variants
Buttons can adopt persona colors for contextual actions.
<button class="btn btn-persona btn-persona--ferni">Talk to Ferni</button>
<button class="btn btn-persona btn-persona--maya">Talk to Maya</button>
<button class="btn btn-persona btn-persona--peter">Talk to Peter</button>
States
Buttons provide visual feedback for different interaction states.
<button class="btn btn-primary">Default</button>
<button class="btn btn-primary" disabled>Disabled</button>
<button class="btn btn-primary btn-loading">
<span class="btn-spinner"></span>
Loading
</button>
Full Width
Buttons can expand to fill their container.
<button class="btn btn-primary btn-block">Full Width Button</button>
CSS Custom Properties
| Token | Description |
|---|---|
--accent-primary |
Primary button background |
--accent-hover |
Primary button hover state |
--border-medium |
Secondary button border |
--radius-md |
Button border radius |
--duration-fast |
Transition duration |
Full CSS
.btn {
display: inline-flex;
align-items: center;
justify-content: center;
gap: var(--space-2);
font-family: var(--font-body);
font-weight: var(--font-weight-semibold);
font-size: var(--text-sm);
border-radius: var(--radius-md);
padding: var(--space-3) var(--space-5);
border: none;
cursor: pointer;
transition: all var(--duration-fast) var(--ease-ease-out);
text-decoration: none;
}
/* Primary */
.btn-primary {
background: var(--accent-primary);
color: var(--text-inverse);
}
.btn-primary:hover {
background: var(--accent-hover);
transform: translateY(-1px);
}
/* Secondary */
.btn-secondary {
background: transparent;
color: var(--text-primary);
border: 1px solid var(--border-medium);
}
.btn-secondary:hover {
border-color: var(--accent-primary);
color: var(--accent-primary);
}
/* Ghost */
.btn-ghost {
background: transparent;
color: var(--text-secondary);
}
.btn-ghost:hover {
background: var(--bg-secondary);
color: var(--text-primary);
}
/* Sizes */
.btn-sm { padding: var(--space-2) var(--space-4); font-size: var(--text-xs); }
.btn-md { padding: var(--space-3) var(--space-5); font-size: var(--text-sm); }
.btn-lg { padding: var(--space-4) var(--space-6); font-size: var(--text-base); }
/* States */
.btn:disabled {
opacity: 0.5;
cursor: not-allowed;
transform: none;
}
.btn-block {
width: 100%;
}
/* Loading */
.btn-loading {
pointer-events: none;
}
.btn-spinner {
width: 16px;
height: 16px;
border: 2px solid transparent;
border-top-color: currentColor;
border-radius: 50%;
animation: btn-spin 0.8s linear infinite;
}
@keyframes btn-spin {
to { transform: rotate(360deg); }
}
Accessibility
Focus Indicators
All buttons have visible focus rings for keyboard navigation. Never remove :focus-visible styles.
Icon-Only Buttons
Always include aria-label on icon-only buttons to describe the action.
Loading States
Use aria-busy="true" during loading to announce state to screen readers.