Buttons & badges

Pills, semibold, tight tracking, a scale on press. Primary is the one call to action on a screen; secondary is a filled chip. There is no outlined button in the dashboard, so there is none here.

Button.folio-btn
tsx
import { Button } from '@/components/ui/button'

<Button onClick={save}>Save</Button>
<Button variant="secondary">Cancel</Button>
<Button variant="destructive" size="sm">Delete</Button>
<Button variant="secondary" size="icon" aria-label="More"><DotsSolid /></Button>

// Plain HTML
<button class="folio-btn">Save</button>
<button class="folio-btn folio-btn-secondary folio-btn-sm">Cancel</button>
variantdefault | secondary | ghost | destructive | link
Default is primary. outline is accepted as an alias of secondary.
sizedefault | sm | lg | icon
40px / 32px / 44px / 40px square.
asChildboolean
Render the child (a Link, an anchor) with the button’s styling.

Inside a popup a button squares to 12px and a footer button stretches to full width; both happen automatically.

Badge

A badge is a label, not a click target. The default is the inverse chip: emphasis without claiming to be an action.

Badge.folio-badge
Default
Pending
Draft
Succeeded
Attention
Sandbox
Failed
With icon
tsx
import { Badge, StatusBadge } from '@/components/ui/badge'

<Badge variant="success">Succeeded</Badge>
<StatusBadge variant="warning" icon={ClockSolid}>Pending</StatusBadge>   // icon + label, for rows

Semantic variants (success, warning, info, destructive) carry meaning; use them for states, not decoration.