UX audit found that the empty dashboard state (no servers in swarm) rendered an instruction — “Add a server to get started” — with no actionable button. The user is told what to do but given no mechanism to do it.
ServerSearchBubbleContent displayed instructional text only. No CTA existed to
launch the add-server flow directly from the empty state. The empty-state pattern
(message + primary action) was incomplete.
onAddServer: (() -> Unit)? parameter to ServerSearchBubbleContent
in StartupOverlays.kt. When non-null, renders a full-width + Add Server Button
below the description text, sized to CommonLayout.BUTTON_HEIGHT_STANDARD (48dp).ClientScreen.kt: passes screenCore.selectAvatar() +
screenCore.executeCommand(KrillApp.Server) which navigates to EditServer(null).DashboardSurface test helper in Scenarios.kt to include the button
so dashboard__empty screenshots reflect the corrected empty state.Empty-state composables should satisfy the “message + primary CTA” pattern: if the screen tells the user what to do next, there must be a tappable affordance that does it. UX audit review against this pattern catches violations before ship.