- Add boocode-lift-analysis.md: comprehensive 30-repo lift matrix across 25 domains - Add openspec/ change docs: domain2-code-intelligence, domain3-multi-agent, impeccable-wave, streaming-codeblocks - Update .gitignore: .impeccable/, .omo/, bun.lock, DESIGN.md, PRODUCT.md - Update dependencies in package.json + pnpm-lock.yaml - Update .codesight/ analysis cache
6.4 KiB
The Data Terminal — Animation, Polish & Perceptual Design Wave
Why
BooCode's frontend is functionally complete but perceptually unfinished. The gap analysis against impeccable-level quality identified 8 critical gaps holding back the "cutting edge, modern, bold" identity you want:
- No layout animations — The workspace pane grid (core UX) has zero transitions. Panes snap open/closed/reordered. The interface feels static where it should feel alive.
- No JS animation library — Pure CSS only. No springs, no stagger entrances, no shared-element transitions, no interruptible motion. The "Data Terminal" should hum and respond.
- Messages teleport in — No stagger entrance on the message list. Every message appears instantly, robbing the conversation of rhythm.
- Motion timing is ad-hoc — 22 files hardcode durations independently. No shared easing curves, no timing tokens.
- No keyboard shortcut reference — Comprehensive shortcuts exist (C, T, W, Tab, 1-9, backtick) but are invisible. Help/Docs scored 2/40 in the critique.
- Font choice is safe — Inter is the shadcn-default AI slop tell. A bolder pairing would elevate the entire identity.
- No route-level code splitting — Entire app loads in one bundle. Per Vite best practices, this is CRITICAL.
- No undo system — Destructive actions confirm but don't offer recovery. Undo toast is standard UX.
- Empty states are text-only — "No projects" / "No sessions" with no illustration or guidance.
This batch addresses all of these in a structured, layered approach — from foundational motion tokens through to perceptual polish.
Principles
- Motion is telemetry, not decoration. Every animation communicates state. If it doesn't serve understanding, it doesn't exist.
- The Data Terminal should feel alive. The workspace, messages, and tool calls should have presence — appearing, responding, transitioning with purpose.
- Cutting edge does not mean gratuitous. Animations serve the power user. Fast, interruptible, under 300ms. No bounce, no elastic, no choreographed page-load sequences.
- Accessibility is not optional. Every animation has a
prefers-reduced-motionalternative. Every interactive element is keyboard-accessible. Empty states teach. - Consistency over surprise. Motion tokens, easing curves, and timing are shared across every component. Same feel, everywhere.
What Changes
Phase 1 — Foundation (motion tokens + animation library)
Install framer-motion, define motion design tokens (--duration-*, --ease-*, --motion-*) in globals.css, replace all hardcoded timing values across components with the token system. This is the prerequisite for everything else.
Phase 2 — Workspace (pane grid animation)
Animate the multi-pane workspace: pane open/close transitions (slide + fade), pane reorder via layout animation, tab switch transitions. This is the core UX — the single most visible animation gap.
Phase 3 — Chat (message animation + stagger)
Add stagger entrance to the message list. Messages appear in sequence (30ms apart, max 300ms total). New messages scroll-anchor with a subtle entrance. Tool calls expand with spring physics. Reasoning block opens with a smooth height transition.
Phase 4 — Visual identity (typography + empty states)
Swap Inter for a bolder, more distinctive font pairing (e.g. Public Sans + JetBrains Mono, or Instrument Sans + JetBrains Mono — something unexpected but technical). Replace text-only empty states with illustrated CTAs. Add noise/grain texture layer to the background for atmosphere.
Phase 5 — UX depth (undo, keyboard reference, code splitting)
Add undo toasts for destructive actions. Build a keyboard shortcut reference dialog (Cmd+/ or ?). Add route-level React.lazy() code splitting with Suspense boundaries.
Phase 6 — Polish pass (critique close-out)
Fix the P0-P3 issues from the impeccable critique: rounding consistency (done), "tap" label removal, bubble side-stripe, StatusDot transform-origin, ChatInput toolbar density, CompactCard popover overflow. Run a follow-up critique to verify score improvement.
New Capabilities
motion-token-system: CSS custom properties for durations, easing curves, and motion presets inglobals.css. Every component references tokens, not hardcoded values.pane-layout-animations: Workspace pans animate open/close/reorder via framer-motionAnimatePresence+layoutprop.message-stagger-entrance: Message list items stagger in at 30ms intervals on first render and on new messages.keyboard-shortcuts-dialog:Cmd+/panel listing all keyboard shortcuts, grouped by category (navigation, chat, terminal, general).undo-toast-system: Sonner toast with "Undo" action for destructive operations (delete chat, archive project, close pane).route-code-splitting: All 6 page components wrapped inReact.lazy(() => import(...))with Suspense fallbacks.bold-font-pairing: Replace Inter with a distinctive sans (e.g. Instrument Sans, Public Sans, or Satoshi) while keeping JetBrains Mono for code.illustrated-empty-states: New user/project/session empty states with inline SVG illustrations + CTA buttons.
Modified Capabilities
ChatInput-toolbar: Secondary controls (Flows, SlashCommands, WebSearch) moved to overflow menu. Toolbar density reduced from 7→4 items.ToolCallGroup: "tap" label removed — chevron rotation is sufficient.MessageBubble-actions: Share popover uses portal-based positioning to prevent viewport overflow.StatusDot:transform-origin: centeradded to streaming spinner +prefers-reduced-motionguard.ember-user-bubble: Side-stripe accent replaced with solid top-border accent for design system compliance.Dynamic-imports: App.tsx routes switch from static imports toReact.lazy()with Suspense boundaries.
Impact
- apps/web: 20–30 files modified across components, styles, and pages. New files:
lib/motion.ts(token constants + helpers),components/KeyboardShortcutsDialog.tsx,components/UndoToast.tsx, empty state SVG illustrations. - dependencies:
framer-motionadded toapps/web/package.json. - No server/coder/schema changes: Purely a frontend batch. No API changes, no new endpoints, no DB migrations.
- Risk areas: framer-motion bundle size (~30KB gzipped), animation performance on low-end devices,
prefers-reduced-motioncoverage completeness.