Skip to content

[Feature] UI polish batch: cohesion, affordance, hierarchy #77

@Astro-Han

Description

@Astro-Han

Context

Outcome of a UI audit covering the right-panel Status tab, the session header, the sidebar, the home screen, and the review shell. Everything here is visual polish, not functional bugs. The product already looks coherent (warm linen palette, consistent upstream icon system, sensible spacing); what remains is cohesion inside the new Status tab, first-frame perception on the home screen, and a few affordance gaps. Items grouped by P-level; within a level, ordered by blast radius (smallest risk first) so execution can be incremental.

All references to files are relative to packages/app/src/. Line numbers are approximate — they may drift by one or two lines during normal development.

P0 — blocks a "finished product" impression

P0-2 — Collapse the Status tab hierarchy

Status currently stacks four visual layers inside one ~320px panel: uppercase tracking-wide section labels in Summary, an extra uppercase "CONNECTIONS" header in Connections, collapsible rows, and leaf rows. The Codex reference uses a single layer (Progress / Branch details / Artifacts / Sources) with normal-case section titles. Drop the "CONNECTIONS" header in components/session/session-status-connections.tsx:178 and unify Progress / Sources / Servers / MCP / LSP / 插件 under one Section component with an optional collapsible flag. The collapse behaviour stays only on the four connection sections.

Files: components/session/session-status-summary.tsx, components/session/session-status-connections.tsx. Blast radius: SessionStatusPanel is only mounted at pages/session/session-side-panel.tsx:272, so this change is isolated to the Status tab.

P0-3 — Raise logo opacity on first frame

pages/home.tsx:73 and pages/error.tsx:268 both render the logo at opacity-12. On the linen background this is faint enough to read as "still loading" on cold open. Raise to opacity-30 (or 25% if still too strong). Only these two occurrences exist in the codebase.

P0-4 — Redraw the custom SVGs to match neighbouring icons

Superseded by #143 (2026-04-22): PinIcon / FilterIcon redraw moves into the session-row leading-slot issue. Do not implement this item. The rest of this batch still stands.

pages/layout/pawwork-sidebar.tsx:20-41 ships two hand-drawn SVGs (FilterIcon, PinIcon) at viewBox="0 0 12 12" with explicit stroke-width="1.1" / "1.2" and stroke-linecap="round" (or stroke-linejoin="round" on PinIcon). Most upstream icons in packages/ui/src/components/icon.tsx use a 20×20 viewBox and default stroke weight, giving a consistent line density; these two custom icons render noticeably bolder at the same render size. Redraw against 20×20 so they visually match their neighbours in the sidebar. Upstream has no pin / filter / bookmark / star / flag, so this is a redraw, not a swap. Both components are file-private, so the blast radius is the sidebar pin + filter buttons only.

P1 — meaningful polish

P1-5 — Reserve the brand accent for primary actions

text-accent-brand (#ff5910 at full saturation) is currently used for two state indicators: pinned session icon at pages/layout/pawwork-sidebar.tsx:147, and filter toggle in project mode at pages/layout/pawwork-sidebar.tsx:319. It competes with the "New session" primary button for visual weight. Swap both to text-text-strong (or text-accent-brand/60 if you still want a hint of colour). No other text-accent-brand usage exists elsewhere in packages/app/src/, so this is a self-contained change.

P1-6 — Give the side-panel resize handle a hover hint

pages/session/session-side-panel.tsx:227-240 wraps ResizeHandle in a transparent 100%-height div. Add w-1 hover:bg-border-base transition-colors so a 1px vertical line reveals on hover. No change to drag behaviour.

P1-7 — Weaken the project name in the breadcrumb

components/session/session-header.tsx:88-108 currently gives the project-name Button text-text-weak hover:text-text-strong, so on hover it matches the session title and the breadcrumb reads as two peers instead of "prefix → current". Change to text-text-weaker hover:text-text-weak so the session title always dominates.

P1-8 — Integrate "Manage servers" into its section

components/session/session-status-connections.tsx:301-305 dangles a secondary Button after all four SectionRows. Either fold it into the Servers section as a trailing IconButton (settings-gear) action, or demote the whole block to a footer link styled text-12-regular text-text-weak underline-offset-4 hover:underline so it stops looking like a primary CTA in an informational panel.

P1-9 — Keep the inner review sub-tab bar stable in the empty state

Superseded by #85 (2026-04-21): newer product decision removes the Review + button unless a clear workflow requires it. Do not implement this item. The rest of this batch still stands.

Inside the Review tab pane, pages/session/session-side-panel.tsx:291-311 hides the inner sub-tab bar (which normally holds the "Review" anchor + context tab + opened file tabs + + button) when no file tabs are open and there is no context tab, falling back to a lone + icon floating on an empty strip. The Codex reference shows Summary / Review / + / expand as a permanent inner row. Make the Review anchor trigger always render and let the + sit at the right edge unconditionally. This does not affect the outer shell tabs (Status / Files / Review / Terminal at :249-263), which already always render.

P1-10 — Surface keyboard shortcuts on the right-panel tabs

pages/session/session-side-panel.tsx:249-268 renders the four shell tabs (Status / Files / Review / Terminal) with no tooltip. Wrap each Tabs.Trigger in TooltipKeybind and register ⌘1-4 in pages/session/use-session-commands.tsx (which already hosts review.toggle, panel.toggle, etc.). Do this in two steps: add the tooltip with an empty keybind first (purely visual), then wire up the command IDs. Keybind-collision check required (especially against sidebar and composer commands).

P2 — consistency

P2-12 — Match MCP status label colour to the status dot

components/session/session-status-connections.tsx:243-246 applies text-text-weaker to every status label regardless of severity. The left-side dot already distinguishes failed / disabled / connected at line 234-240. Sync the label: text-icon-critical-base when bad(), text-text-weaker for disabled / unknown.

P2-13 — Rename "Plugins" to "插件" in the Chinese copy

Update status.popover.tab.plugins value in i18n/zh.ts to "插件". Keep i18n/en.ts as "Plugins". MCP and LSP stay as-is (MCP is an industry term; LSP is developer-facing).

P2-14 — Tighten the right-panel tab bar

pages/session/session-side-panel.tsx:249 uses h-11 (44px) for Tabs.List around h-7 (28px) triggers, leaving 16px combined vertical slack. Change to h-9. This only affects the right-panel Tabs instance; composer and Review secondary tabs have their own styles.

Execution order (smallest blast radius first)

  1. Zero-risk visual tweaks: P0-3, P1-6, P2-12, P2-13, P2-14
  2. Single-file, self-contained: P1-7, P1-8 (P1-9 now superseded — skip)
  3. Needs visual review: P1-5 (self-contained two-site change) (P0-4 superseded by [Feature] Stabilize session row left-side visuals (status slot width + Pin/Filter icons) #143 — skip)
  4. Structural, last: P0-2 (Section unification), P1-10 (command registration)

After each group, verify with bun dev:desktop — typecheck does not catch visual regressions.

Not in scope

  • Tab row icon-only mode (Codex-style icon+text row is intentional; revisit only if a fifth tab gets added)
  • Pin button keyboard a11y (current hover-to-discover behaviour is intentional)
  • Home screen restructure (minimal first frame is intentional; only the opacity is in scope)

Metadata

Metadata

Assignees

No one assigned

    Labels

    P3Low priorityenhancementNew feature or requestuiDesign system and user interface

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions