# TailMux Menu UI Redesign Mockups

Date: 2026-06-08

These mockups redesign the TailMux menu bar app around the product's actual job:
route local developer traffic to isolated Tailscale profile identities by hostname
suffix, while failing closed.

The images were generated with the built-in `imagegen` workflow and should be
treated as visual direction, not literal SwiftUI source. Text and field names in
implementation should follow the real model in `Apps/TailMuxMenu/Sources`.

## Screens

1. `01-menubar-popover.png`
   - Primary menubar surface.
   - Makes router state, proxy endpoints, profile ownership, and fail-closed
     guarantees visible in one glance.
   - Recommended as the strongest direction for the first implementation pass.

2. `02-settings-profile-editor.png`
   - Settings/profile editor direction.
   - Uses a persistent sidebar, selected-profile health summary, editable routing
     fields, and an explicit safety checklist.
   - Implementation should keep the current fields: name, display name, hostname,
     backend, suffixes, IP routes, match root, HTTP proxy, SOCKS5 proxy, and UDP
     port.

3. `03-login-approval-modal.png`
   - Login approval modal.
   - Shows the target profile identity before opening the Tailscale approval URL.
   - Important behavior: the modal must state that the official Tailscale GUI
     account is not reused.

4. `04-diagnostics-modal.png`
   - Path diagnostics modal.
   - The generated image uses a generic step table. Implementation should map this
     to the real `TailMuxPathReport`: target, host, profile, route type, suffix or
     IP route, DNS profile resolution, matched state, and recommendations.

5. `05-stop-router-confirmation.png`
   - Destructive confirmation for stopping the router.
   - Confirms proxy/PAC routing stops while profile state remains untouched.

6. `06-new-profile-modal.png`
   - New profile modal/wizard.
   - Keeps the action scoped to one isolated profile and ends with `Save & Login`.
   - Implementation should use TailMux defaults for `tsnet`, generated hostname,
     suffix placeholder, loopback proxy ports, and stable UDP port.

## Design Direction

- Treat TailMux as a compact developer control surface, not a settings-heavy app.
- Put the routing topology in the popover: client/PAC, loopback router, selected
  isolated profile lanes.
- Show safety guarantees as first-class status, especially:
  - loopback-only listeners
  - unknown `.ts.net` denied
  - raw IP denied unless explicitly routed
  - no cross-profile fallback
  - separate profile state
- Use concise status labels: `Online`, `Router Active`, `Needs Login`,
  `Disconnected`, `Denied`, `Enforced`.
- Prefer icon-only utility buttons with tooltips in the popover footer where the
  action is obvious: refresh, diagnose, copy PAC, open GUI, settings, quit.
- Keep controls explicit for risky operations: stop router, logout, delete
  profile, reset/rotate state.

## Implementation Notes

- The menubar host uses an AppKit `NSStatusItem`: primary click toggles the
  dashboard popover, while secondary click (or Control-click) opens a compact
  menu with Open Options, About, and Quit. The popover remains wide and
  dashboard-like, follows its natural content height, and scrolls only when
  that height exceeds the active display.
- Keep at most six tunnel rows directly actionable in the popover. Above that,
  show a count/state summary and a CTA to Settings → Tunnels, where every tunnel
  remains reachable and editable.
- Avoid showing profile-local compatibility proxy ports as the primary mental
  model for `tsnet` profiles. The primary user-facing router endpoints remain:
  - HTTP proxy: `127.0.0.1:43100`
  - SOCKS5 proxy: `127.0.0.1:43101`
  - PAC: `http://127.0.0.1:43180/proxy.pac`
- For profile rows, show ownership before raw config:
  - display name
  - suffix chips
  - backend
  - hostname
  - status/login action
- For diagnostics, use a modal sheet from the popover and a full diagnostics page
  in Settings. The modal should answer one question quickly: "Which profile owns
  this target, and will TailMux route or deny it?"
- Do not expose controls that imply fallback, global route injection, or mutation
  of the official Tailscale GUI session.
