Files
werkator/docs/rfcs/0001-web-ui-instrument-panel.md
mhoennigandClaude Fable 5.1 11f6f9bd26 docs(rfcs): RFC 0001 proposes the Instrument Panel web UI redesign
Six explored directions, the chosen one (E) worked out in a light and a dark
teal palette, with a repository strip previewing every served repository,
the ten-repository and the phone case, and the backend it needs (/api/repos).
Renderings of all artboards live next to the RFC; AGENTS.md registers docs/rfcs/.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-03 20:15:04 +02:00

13 KiB
Raw Permalink Blame History

RFC 0001: Web UI Redesign — the Instrument Panel

Status:

  • proposed: 2026-09-03
  • accepted: -
  • rejected: -

Proposal: The Werkator web UI adopts the Instrument Panel direction: a teal palette in a light and a dark mode, IBM Plex typography, a repository strip that previews the state of every served repository, a title hierarchy that names the view first and explains it second, and a tab bar at the foot that becomes the mobile navigation. The architecture does not change: server-rendered Thymeleaf, one werkator.css, one hand-written werkator.js, JSON polling, no framework, no frontend build pipeline.

Context and Problem Statement

The current UI is a functional port of the legacy generated pages: a table per view, pill badges, system font, blue links. It is correct and calm, but it looks like every other CI page and gives no hint of the other repositories an instance serves (ADR 0009). The brief for this RFC was "fancy, but serious and trustworthy", with two references from the same author for visual kinship:

  • werkbaum.javagil.de — light paper with a fine grid, IBM Plex, a petrol accent, panel labels in small caps.
  • javagil.de/vibe-engineering — a dark instrument panel: ink and petrol, clay for warnings, monospaced spaced labels, a tab bar at the foot.

A hard constraint of this RFC is honesty towards the data. The mockups show only what the API delivers today; nothing is invented to make a screen look richer.

What the UI Has to Work With

Per build row (BuildRowView, BuildResultDto): status, branch name, commit (12-character abbreviation, full id for copying), started at (yyyy-MM-dd HH:mm), duration (m:ss; a pending build shows its wait time in italics), artifact key with the artifact, permalink and live-log links, and the actions restart and delete (history has no restart). Statuses: pending, running, success, failed, interrupted, cancelled, plus unknown for a never-built branch and the client-side finished on a card whose build has left the current list. Views: Latest (one build per name), Branches (every origin branch and its latest build), History (all stored builds), Current (running builds with their live log), System (seven metric rows with current/min/max/avg, warn from 80 %, critical from 90 %), the artifact page, and the release notes. Live state: the indicator is static, live or error; the watcher banner reports watcher stopped, origin unreachable or poll cycle failed. Multi-repo: the repository switcher is a server-rendered <select> of names; WatcherState.repositories already carries a per-repository watcher state that the UI does not show.

What does not exist, and therefore appears in no mockup: a commit subject line, a typical or expected duration, an ETA, a per-branch build history, test counts on a row, and any cross-repository status summary in the API.

Considered Options

Six directions were sketched on a shared design canvas, two rounds of three, all with the same sample rows.

Option Idea Why Tradeoff
A · Quiet Console Today's design refined: top bar, dot-plus-word statuses, hover actions Smallest step, everything stays valid Least distinctive
B · Mission Board Health tiles, one card per branch with a history strip, running build with progress Answers "is everything fine?" at a glance Needs data the API does not have (history, typical duration)
C · Ledger Warm paper, serif masthead, hairline rules, typographic status marks The most "serious"; reads like a signed record Leaves the system font, needs its own dark theme
D · Paper Rail Werkbaum's paper and grid, a repository rail on the left with per-branch dots Family resemblance to Werkbaum; other repositories visible 250 px of table width lost; empty with one repository
E · Instrument Panel Vibe-Engineering's dark panel, repositories as tiles, tab bar at the foot Reads like a control room; failures in clay stay serious without alarm Dark-only as drawn; needs a light palette
F · Fleet Overview A new landing page with one panel per repository, ledger typography on paper One page answers the question for the whole instance Becomes a list beyond five repositories

Round one (AC) still contained invented data; it is kept on the canvas for the visual ideas only. E was chosen, and round three worked out what it lacked: the light mode, the ten-repository case, the title hierarchy, and the phone layout.

The Design

Palette

Both modes are CSS custom properties on :root, switched by prefers-color-scheme as today (color-scheme: light dark). Failures use clay, not red, so they stay serious without shouting; the accent is teal in both modes.

Token Dark Light Used for
bg #061C1F #EAF4F2 page ground
panel #0A2A2E #FFFFFF tables, cards, chips
panel-2 #0F3A3D #D6ECE8 the current repository, the active tab
line #17474B #C9DFDB borders and rules
text #E4EEEC #0B2B2E body text
text-2 #B4CBC8 #35595B timestamps
muted #7DA19E #5E8583 labels, footers
accent #5FD3C7 #0E8079 links, success, running, the live indicator
accent-2 #1E9A93 #149A90 underlines, the current repository's border
clay #E09070 #B0563B failed, error, delete, watcher warnings
clay-2 #C4664A #C4664A the border of a failing repository chip
ghost #4A7370 #BFD4D1 cancelled, interrupted, unknown

Tinted rows: a running row gets 16 % (dark) or 10 % (light) of accent-2 as background, a failed row 12 % or 10 % of clay-2. The reference's background grid was tried and dropped: it competes with the table, especially in light mode.

Typography

IBM Plex Sans for text, IBM Plex Mono for commits, timestamps, durations and every label. Labels are 10 px Mono, uppercase, letter-spaced 0.12 em, in muted; statuses are 11 px Mono uppercase in their status color, each preceded by an 8 px dot (outlined for pending, pulsing for running). Fallback stacks: "IBM Plex Sans", "Segoe UI", system-ui, sans-serif and "IBM Plex Mono", ui-monospace, Consolas, monospace. Whether Plex is bundled under static/ or the fallback stack is accepted is an open question below.

Anatomy of a Page (desktop)

  1. Header, 52 px: logo, Werkator with the Gitea repository name in accent, a small label updated HH:mm:ss; right: the live indicator as an outlined chip with a pulsing dot, the reload button.
  2. Repository strip: see below.
  3. Panel with the view's title: the view name at 22 px semibold with a 2 px accent-2 underline, followed by a one-line label that explains it (Latestone build per branch, newest first; Branchesevery origin branch and its latest build; Historyall stored builds, newest first; Systeminstance metrics since first start); on the right a Mono line with the row count, the last poll and the watcher state.
  4. Table, columns as today (Status, Branch, Commit, Started, Duration, Artifacts, Actions), rows 9 px padding on a 1 px line rule; copy buttons as outlined 13 px icons; artifact links and actions as stroke icons (no emoji).
  5. Footer: version and copyright left, the navigation as a Mono tab bar in the middle (Latest, Branches, History, System with icons; the active tab in panel-2 with an accent underline), Impressum and Privacy right.

The Repository Strip

The <select> switcher is replaced by a strip below the header that shows every served repository with its state, so a failure elsewhere is visible without leaving the page.

  • Up to about three repositories: tiles (220 px), each with current or repo label, the name, one dot per branch in the branch's latest status, a summary line (6 builds · 1 failed · 1 running), and the watcher warning in clay when that repository's watcher reports an error.
  • More repositories: chips (30 px), each with one dot for the worst status in the repository, the name, an optional short finding (1 failed, main, never built), and a warning triangle when the watcher reports an error; the current repository has an accent-2 border on panel-2, a failing one a clay-2 border on the clay tint.
  • Order is failing first: the current repository, then failing, running, then green; a summary line above (10 served · 2 failing · 1 unreachable · 2 running) and a sort control on the right.
  • The strip scrolls: horizontally on the phone, and on the desktop it wraps to a second row up to about ten repositories and becomes a horizontally scrollable band beyond that, with the failing chips pinned at the front so they never scroll out of view.
  • Beyond roughly twenty repositories the strip shows only the conspicuous chips (failing, running, unreachable) plus a search field for the rest.
  • With a single served repository the strip is omitted, as the switcher is today.

Phone (below 680 px)

The existing breakpoint behaviour is kept and restyled: rows become cards with the data-label captions, the live indicator collapses to a dot. The header stacks Werkator over the repository name; the repository strip scrolls horizontally under its summary line; the panel title keeps its hierarchy; each card carries the status line with the branch, then commit, started and duration, then the artifact icons and the actions as 44 px targets. The footer tab bar becomes a fixed bottom tab bar with icons — the same four entries as on the desktop. No painted status bar or keyboard; the device provides those.

What Is Deliberately Not in the Proposal

  • The DE language button in the mockups is a leftover of the reference; the UI stays English-only.
  • No commit subjects, typical durations, ETAs or history strips: they need data the server does not have, and each would be its own RFC with its own storage.
  • No manual theme toggle; prefers-color-scheme decides, as today.

Consequences

Backend

  • One new endpoint, GET /api/repos: for every served repository its name, its UI root (/repos/<name>), whether it is the current one, the latest status per build name (the Latest view's latestPerName reduced to counts, plus the worst status), and its RepoWatcherState (lastFetchError, lastPollError, lastPollAt). With one served repository the endpoint returns a list of one and the strip stays hidden.
  • werkator.js polls it on the table interval (10 s) and renders the strip; every fetch keeps the timeout and the explicit error badge.
  • UiFormats and werkator.js keep producing identical formats; the palette and the title labels are template and CSS only.

Rollout, One Concern per Pull Request

  1. Palette, typography and the title hierarchy in werkator.css and the fragments — no data change, both modes.
  2. Header and footer tab bar, including the phone tab bar.
  3. GET /api/repos and the repository strip, replacing the <select>.
  4. Card refinements on the phone and the System and artifact pages in the new vocabulary.

Each step leaves the UI usable, and the tests in server that assert on markup are adjusted with the step that changes it.

Open Questions

  • Fonts: bundle IBM Plex Sans and Mono under static/fonts/ (about 100150 KB in WOFF2 for the four faces), or accept the fallback stack on hosts without the font; the reference sites load Plex from a CDN, which the deployment behind a strict reverse proxy may not want.
  • Current view: it is reachable today only from a running row's live icon; the tab bar has room for it as a fifth entry with a count badge, or it stays a link from the row.
  • Instance pages: /system and /releases are instance-level; in the tab bar they sit next to the per-repository views, which the strip makes visible enough, or they move to the footer's right side.

Design Sources

The design canvas with all eleven artboards (rounds one to three, desktop and phone) is a private Claude artifact of the author; its renderings live next to this RFC under 0001-web-ui-instrument-panel/. The sample rows are real field shapes with invented values; the repositories other than werkator are invented.

The proposal:

The alternatives, for the record: