nexus/docs/plans/2026-04-11-nexus-phase-15-mobile.md
Nexus Dev 87b45c730c docs(nexus): wave 3 plans (phases 12-16) + phase 11.5 backlog
Six plans drafted after Wave 2 completed:

Phase 11.5 — per-project scoping follow-up (BACKLOG)
  The 5 BLOCKED tabs from Phase 11 (Agents, Gates, Costs, Activity,
  Org) each need projectId scoping in the corresponding backend types
  and list components. Not time-critical — shipped as TabPlaceholder
  components in Phase 11 with honest data-gap badges. Each of the 5
  tickets is self-contained and can run independently when the
  placeholder UX hurts or when Wave 3 completes. Recommends dropping
  the Org tab entirely rather than building per-project scoping for it.

Phase 12 — Promote-to-project transition (WAVE 3)
  Replaces Phase 9's synchronous assistantHandoff() with the animated
  700ms compress-and-rise from spec 5.6. New files: PromoteTransition,
  BrainstormerPanel, usePromoteToProject state machine. CSS-first
  animation, not Motion library. Respects prefers-reduced-motion.
  Depends on Phase 9 (Assistant) and Phase 11 (Projects).

Phase 13 — Settings consolidation (WAVE 3)
  Collapses the nested instance-settings tree into a single-column
  scroll with 8 section cards (Workspace, LocalAI, Cloud, Skills,
  Routines, Telegram, About, Danger). Phase 13 is the one phase
  where routing changes ARE phase-owned: it strips nested
  /instance/settings sub-routes and replaces with Navigate redirects.

Phase 14 — Voice + CmdK globalization (WAVE 3)
  Lifts voice state out of ChatInput's internal VoiceMicButton into
  a shared VoiceContext so the top-strip GlobalMicButton becomes
  functional from any route, with speech queued to the Assistant
  inbox per spec 5.5. Replaces the CmdKButton synthetic-keydown shim
  with a real CommandPaletteContext. Extends CommandPalette search
  to cover conversations, projects, issues, agents, settings,
  workshops. Also fixes the pre-existing useKeyboardShortcuts.ts
  destructure bug caught during Phase 6/11 reviews.

Phase 15 — Mobile parity (WAVE 3)
  4-destination MobileTabBar replacing MobileBottomNav. History +
  Memory sheets become full-screen on mobile. Promote transition
  uses a full-screen takeover instead of split layout. BuilderTabStrip
  scrolls horizontally with edge fades. Single 768px breakpoint.

Phase 16 — Cleanup pass (WAVE 4, sequential)
  Deletes dead chrome files (ChatPanel, ChatPanelContext, Sidebar,
  InstanceSidebar, BreadcrumbBar, PropertiesPanel, MobileBottomNav).
  Migrates ChatMessageList off ChatPanelContext first (flagged
  hazard from Phase 9). Vocabulary sweep company to workspace in
  UI strings only (backend keeps company identifiers per upstream
  sync constraint). Fixes the minor issues accumulated across
  Phase 8-15 reviews (useKeyboardShortcuts destructure bug,
  GlobalMicButton test double-render, Projects umbrella regex
  duplication, PersonalAssistant brittle fixed height). Visual
  QA pass.

Wave structure for Wave 3 dispatch:
  Wave 3A: Phase 12, Phase 13, Phase 14, Phase 15 in parallel
           (4 subagents, disjoint file ownership)
  Wave 3B: Phase 16 sequential (intentionally touches everything)

Phase 11.5 stays in backlog — not in any wave. It activates when
the TabPlaceholder UX becomes a friction point or when a milestone
explicitly pulls one of its tickets into scope.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 13:11:12 +00:00

6 KiB
Raw Blame History

Nexus Phase 15 — Mobile Parity

Use superpowers:test-driven-development. Commit atomically.

Goal: Bring the new frame to mobile breakpoint < 768px. Replace the legacy MobileBottomNav with a 4-destination bottom tab bar matching the desktop IconRail destinations (Assistant, Studio, Projects, Settings). Collapse the desktop slide-overs (History, Memory) to full-screen sheets on mobile. Make the project tab strip scroll horizontally without shrinking. Adapt the promote-to-project transition to a full-screen takeover on mobile instead of the split layout.

Source of truth: spec §9 (Mobile).

Branch: nexus/design-system-migration.


Ownership boundaries

You may create or modify ONLY:

Path Action
ui/src/components/frame/MobileTabBar.tsx Create
ui/src/components/frame/MobileTabBar.test.tsx Create
ui/src/components/Layout.tsx Modify — swap MobileBottomNav for MobileTabBar
ui/src/components/assistant/HistorySheet.tsx Modify — add mobile full-screen variant
ui/src/components/assistant/MemorySheet.tsx Modify — add mobile full-screen variant
ui/src/components/assistant/PromoteTransition.tsx Modify — mobile full-screen takeover variant
ui/src/components/projects/BuilderTabStrip.tsx Modify — horizontal scroll on mobile
ui/src/components/frame/TopStrip.tsx Modify if needed — mobile tweaks to cluster spacing

You MUST NOT touch:

  • Phase 8 icon rail semantics (desktop behavior stays)
  • Phase 9 Assistant thread layout (desktop stays)
  • Phase 10 Studio grid (mobile already collapses to 1-col)
  • Phase 11 Project card layout (desktop stays)
  • ui/src/App.tsx

Scope

1. MobileTabBar component

Replacement for MobileBottomNav. Renders 4 tab links at the bottom of the viewport:

  • Assistant (MessageCircle)
  • Studio (Sparkles)
  • Projects (FolderKanban)
  • Settings (Settings)

Specs:

  • fixed bottom-0 left-0 right-0 h-14 (56px tall)
  • border-t border-border bg-background — charcoal top border, pure black fill
  • Each tab is a flex column: icon on top (20×20), label below (10px uppercase 1.4px tracking)
  • Silver default, volt active with a 2px volt bar above the icon
  • Focus-visible styles per DESIGN.md
  • Safe-area aware: pb-[env(safe-area-inset-bottom)]
  • Active state derivation: same regex patterns as IconRail's isActive functions — factor out if possible

Delete the existing MobileBottomNav.tsx after confirming the new bar covers its behavior. If MobileBottomNav has non-destination features (e.g., a "new issue" FAB), report them and the controller will decide whether to keep or drop.

2. Mobile slide-over → full-screen sheet

Phase 9's HistorySheet and MemorySheet are desktop slide-overs at 320px / 340px. On mobile:

  • Take the full viewport width
  • Full viewport height below the top strip (48px)
  • Close button in the top-right of the sheet
  • Swipe-down-to-close gesture (optional — acceptable if CSS-only)

Implementation: add a useMediaQuery("(min-width: 768px)") check; when mobile, render different class names that go full-screen. Do NOT duplicate the component — same file, conditional rendering.

3. Promote-to-project mobile takeover

Phase 12's PromoteTransition split-screen layout (30% chat ribbon / 70% brainstormer) doesn't fit on mobile. On mobile, the brainstormer completely covers the chat — slides up to 100% viewport height instead of 70%.

Implementation: same PromoteTransition.tsx file, conditional max-height and translate values based on useMediaQuery. Tests need a mobile case.

4. BuilderTabStrip horizontal scroll

Phase 11's Project tab strip has 7 tabs that don't fit on narrow mobile. Spec §9.1 says "Project sub-tabs become a horizontally-scrolling strip under the header, no shrinking."

Implementation: on mobile, wrap the tab list in a flex overflow-x-auto container with scroll-snap-type: x mandatory for tab-sized snapping. Add edge fades (mask-image or left/right gradient overlays) so users see there's more content. Tests need a mobile case.

5. TopStrip mobile polish

On mobile, the top strip should:

  • Keep the 48px height
  • Drop the ⌘K text label and show only the kbd glyph (already minimal — verify)
  • Keep the mic button
  • Keep the mode breadcrumb but allow it to truncate if too long
  • Consider whether to hide the breadcrumb entirely on very narrow screens

Implementation notes

useMediaQuery("(min-width: 768px)") already exists

ui/src/hooks/useMediaQuery.ts (or similar) is used throughout the codebase. Consume it rather than adding a new media-query hook.

Mobile breakpoint is single — 768px

Per spec §9.2: "Single breakpoint: >= 768px is desktop frame, < 768px is mobile frame." Don't introduce intermediate breakpoints; everything is binary.

Tailwind responsive classes vs runtime media query

For simple show/hide behavior, use Tailwind's hidden md:block / md:hidden. For layout variants that need JS logic (like the promote transition's translate values), use useMediaQuery. Prefer CSS when possible.


Acceptance criteria

  1. On a viewport < 768px, the new MobileTabBar renders with 4 destinations matching the IconRail; clicking each navigates correctly
  2. The 56px desktop IconRail is hidden on mobile (already hidden md:flex from Phase 8 — verify)
  3. HistorySheet and MemorySheet render full-screen on mobile
  4. The promote-to-project transition completely covers the chat on mobile
  5. BuilderTabStrip scrolls horizontally on mobile with no tabs cropped
  6. TopStrip remains 48px and functional on mobile
  7. Safe-area insets (notch, home indicator) respected
  8. MobileBottomNav file deleted or clearly documented as dead
  9. All existing frame + assistant + projects tests pass
  10. Mobile-specific tests added

Report format

  • Status
  • Commit SHAs
  • Files created / modified / deleted
  • Mobile tests added
  • Features carried over from MobileBottomNav (if any)
  • Gesture support (swipe-down-to-close etc.)
  • Concerns, deviations, self-review