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>
6 KiB
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
isActivefunctions — 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
⌘Ktext 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
- On a viewport
< 768px, the new MobileTabBar renders with 4 destinations matching the IconRail; clicking each navigates correctly - The 56px desktop IconRail is hidden on mobile (already
hidden md:flexfrom Phase 8 — verify) - HistorySheet and MemorySheet render full-screen on mobile
- The promote-to-project transition completely covers the chat on mobile
- BuilderTabStrip scrolls horizontally on mobile with no tabs cropped
- TopStrip remains 48px and functional on mobile
- Safe-area insets (notch, home indicator) respected
MobileBottomNavfile deleted or clearly documented as dead- All existing frame + assistant + projects tests pass
- 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