v1 · Component reference

The system, in one place.

Every reusable piece across the v1 mockups, lifted out and shown beside its states. If something appears in a screen but not here, it shouldn’t — it’s either drift or a candidate for promotion. The Go templates (P1-23 onwards) lean on this file: a partial gets a name in here before it gets a {{define}} in the templates.

Every CSS class on this page is real and copy-able into the Tailwind build. Anything inline is a one-off and shouldn’t be.

01Tokenscolours · type · spacing · the alphabet of v1

Surface, line, ink
bg
--bg
panel
--panel
panel-hi
--panel-hi
line
--line
ink
--ink
ink-mid
--ink-mid
ink-mute
--ink-mute
ink-fade
--ink-fade
State + accent
ok
--ok · success / online
warn
--warn · degraded / cache-warning
bad
--bad · failed / alert
off
--off · offline (neutral)
accent
--accent · running, links
Type scale
28 / 500 Hero / numeric stat stat tile values
22 / 500 Page title h1 in body
18 / 500 Section header h2 above panels
13 / 400 Body & table cells default for prose
12 / 400 Helper, captions, secondary detail .field-help, meta lines
11 / 600 · 0.08em Section heading · column header all caps tracking

02Statusfive states · only place colour is used as semantic

online heartbeat received within last 90 seconds .dot.dot-online
online · running a job is in flight on this host — pulse only when active .dot.dot-online.pulse
degraded online, but open alerts > 0 — soft amber, not loud .dot.dot-degraded
offline no heartbeat for > 90 seconds — neutral, not alarming .dot.dot-offline
last job failed distinct from offline — host is up, but its last job did not succeed .dot.dot-failed

03Buttonsone primary per page · everything else is the neutral secondary

Primary · the one verb the page is about. Use at most once per page.
Secondary · everything else. Run-now per row, all panel actions.
Ghost · inline / “View →” affordances inside cards and rows.
Danger · destructive verbs only. Always pair with a confirmation modal for irreversible ones.
Disabled · 0.4 opacity, not-allowed cursor, no hover.
Sizes · default 12px. .btn-lg for the page-level primary (slightly bigger affordance).

04Form fieldslabels above · helper below · 0.005em letter-spacing

Helper text. Plain prose.
Use .field.mono for URLs, IDs, anything machine-shaped.
repo:
Border becomes accent on focus.
repo_url must look like rest: / s3: / b2:
prod × cache ×
Free-form tags. Comma or Enter to commit.

05Tags & chipslabels for hosts · status pills · removable in form

prod db homelab storage edge test prod ×
succeeded running failed cancelled expires in 59m

06Tabsprimary nav (accent underline) · sub-nav (ink underline)

07Host rowthe dashboard's load-bearing row · degraded/failed/offline get a left edge

Host
OS · arch
Last backup
Repo size
Snapshots
Alerts
Tags
healthy-host
linux/amd64
succeeded · 5m ago
87 GB
2,103
prod
degraded-host
linux/amd64
succeeded · 1h ago
128 GB
1,402
3
prod
failed-host
linux/amd64
failed · 47m ago
97 GB
2,847
1
ci
offline-host
linux/amd64
last seen 2d ago
64 GB
127
1
dev
offline

08Log viewerlive or replayed · ts · stream · payload · color reserved for events & stderr

11:43:21.039EVENT{"message_type":"status","percent_done":0.000,"total_files":21402,"files_done":0}
11:43:21.412OUTscan finished in 0.371s
11:43:25.812ERRwarn: file changed during read: /var/lib/postgresql/13/main/pg_wal/000000010000007800000042
11:43:31.625EVENT{"message_type":"status","percent_done":0.380,"files_done":8124,"bytes_done":1503870976}
11:43:32.122···

09Progress barrunning · complete · failed

running · 38%42 MB/s · ETA 2m 14s
complete · 100%finished in 5m 21s
failed · 0%repo locked

10Stat tileused in summary strips · fleet, host header, job summary

Hosts
12 total
10 online · 1 degraded
Backed up
4.9 TB
23,649 snapshots
Last 24h
147 jobs
144 ok · 2 failed
Open alerts
5
oldest 3h

11Modalused for confirms · destructive actions · short prompts

12Toastsuccess and error variants · auto-dismiss after 4s

Token minted
install command shown below — expires in 1h
×
Couldn’t reach the agent
prod-cache-01 didn’t respond within 5s. Try again or check the WS connection.
×

13Install snippetload-bearing affordance on Add host · Empty state · Settings → Agents

install command · 59m left
curl -fsSL https://restic.lab.example/install.sh | sudo \
  RM_SERVER=https://restic.lab.example \
  RM_TOKEN=HdqFbQh8U-I1fb52iP1M8qxvoYS5t9VZ-T-yghr_CzA sh

14Empty-state patternnothing-yet screens · centred prompt + the affordance that fixes it

Nothing here yet.

Empty states always pair a one-sentence explanation with a single primary affordance. Don’t fill the space with stats or graphics — the void is the message.

end of v1 component reference · 14 sections · ~all the pieces the Phase 1 templates need