Design system

Tokens, building blocks, voice.

The open reference for Struqo's visual system, from tokens to whole pages. Every value comes live from the code, Figma follows it. Agents read the same building blocks in apps/web/components/styleguide/catalog.ts.

02

Atoms

Building blocks that cannot be split further without losing their purpose. Independent of timber or editor state.

Button
Sizes sm 28, md 36, lg 44, xl 48 (marketing, two register modules)
<Button variant="primary | secondary | ghost | destructive" size="sm | md | lg | xl">

Text button in four ranks: main action (primary), side path (secondary), quiet action (ghost), irreversible (destructive).

Atoms · ReadyCode: components/ui/Button.tsx
IconButton
Default, active
<IconButton variant="topbar | tool | ghost" ariaLabel active shortcut>

Icon-only button with mandatory label and tooltip.

Atoms · ReadyCode: components/editor/IconButton.tsx

Composed of: Icon set

Tooltip
Hover
<Tooltip label position="bottom | top | left | right">

Short hint on hover, via .tooltip-wrap.

Atoms · ReadyCode: components/ui/Tooltip.tsx

Brand lockup for marketing, app and editor.

Atoms · ReadyCode: components/ui/Logo.tsx
Avatar
<Avatar label={name | email | null} />

Account initials in the account menu.

Atoms · ReadyCode: components/ui/Avatar.tsx
ProgressBar

The bar on its own, for waits outside the loading indicator. Deliberately without a value prop: as long as no load path measures real progress, a filling bar would be a claim without ground. Silent for screen readers, the surrounding live region carries the statement.

Determinacy without measurable progress
<ProgressBar />

Bar for waits of unknown length.

Atoms · ReadyCode: components/ui/ProgressBar.tsx

Marketing navigation link, with a coming-soon state instead of a dead link.

Atoms · ReadyCode: components/marketing/NavLink.tsx
Save dot

Saved is the resting state and stays put, saving pulses. Offline and a save error are two situations: amber means it carries on by itself, red means there is something to do. The title beside it keeps its colour in every state.

Nothing to save yet
idle
Saving
saving
Saved
saved
Offline, will catch upWill catch up
offline
Saving failed, Struqo keeps tryingKeep this window open
error
Draft in this browserDraft in this browser
guest

Dot at the top of the editor: saved, saving, offline, error.

Atoms · ReadyCode: components/editor/SaveDot.tsx
ThemeToggle

Switch for system, light, dark.

Atoms · ReadyCode: components/ui/ThemeToggle.tsx

No live demo on this page.

Eyebrow (.eyebrow)

The only approved mono label style, 12 px, uppercase.

Atoms · ReadyCode: app/globals.css

No live demo on this page.

Color-Swatch-Dot

Colour dot in pickers such as the pen colour choice.

Atoms · DraftCode: components/canvas/PenStrokeContextMenu.tsx

No live demo on this page.

Select

Select field in Struqo style.

Atoms · DraftCode: components/editor/panels/PanelProperties.tsx

No live demo on this page.

Design system · Struqo