← Design system

Component preview

The controls Velta actually ships — styles extracted verbatim from app/css/main.css @ bc1f3e8f and scoped to this stage, with the states forced side by side. Usage rules live in the component contracts; the tokens behind them are on the reference page.

hover / pressed / focus are forced classes with the exact declarations of the real pseudo-class rules; disabled is the real attribute

Button — primary

The one filled accent action per view (.btn-primary on a .btn-text base): accent fill, --on-accent ink. One per dialog foot or screen; never in lists.

default
hover --accent-hover
pressed --accent-active
focus-visible --focus-ring
disabled

Button — text (tertiary)

Compact accent-text action for rows, footers, secondary choices (.btn-text). It is a BUTTON, not a link — never inline inside a sentence. No hover state by design: hover changes surfaces, never text.

default
focus-visible
destructive — --danger ink, no red fill

Icon button

40px round, svg 20–22, 50% radius; aria-label required. Hover tints the surface; keyboard focus rides the shared button:focus-visible ring (--focus-ring, #182).

default
hover --bg-hover

Tabs — category chips

Equal-width chips (.chat-cats); active = accent fill + --on-accent-chip; a disabled category hides its chip entirely, it never greys out.

default · selected
hover (non-active)

Chip — relay capability flag

Passive metadata pill (.relay-flag); letters with a green corner dot when the relay advertises the capability. Status chips use their status token, never accent.

CIW
off · offered

Day chip

Sticky date divider between message groups; opaque fill (blur is a scroll-frame cost on Android), theme-specific ink measured in the comment block.

Today
default

Text field

Full-width, 12/14px padding, 10px radius, --bg-hover fill; focus recolors the border to accent. The placeholder is a hint, not a label — label above or aria-label.

default
focus

Dialog

Bottom sheet on phones, centered card on desktop (.modal): one primary action in the foot, cancel as .btn-text. History-back integration follows the modalHistorySettled contract. Static demo — the real sheet animates in and docks.

card · foot buttons