# 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: 1. **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. 2. **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. 3. **Messages teleport in** — No stagger entrance on the message list. Every message appears instantly, robbing the conversation of rhythm. 4. **Motion timing is ad-hoc** — 22 files hardcode durations independently. No shared easing curves, no timing tokens. 5. **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. 6. **Font choice is safe** — Inter is the shadcn-default AI slop tell. A bolder pairing would elevate the entire identity. 7. **No route-level code splitting** — Entire app loads in one bundle. Per Vite best practices, this is CRITICAL. 8. **No undo system** — Destructive actions confirm but don't offer recovery. Undo toast is standard UX. 9. **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 1. **Motion is telemetry, not decoration.** Every animation communicates state. If it doesn't serve understanding, it doesn't exist. 2. **The Data Terminal should feel alive.** The workspace, messages, and tool calls should have presence — appearing, responding, transitioning with purpose. 3. **Cutting edge does not mean gratuitous.** Animations serve the power user. Fast, interruptible, under 300ms. No bounce, no elastic, no choreographed page-load sequences. 4. **Accessibility is not optional.** Every animation has a `prefers-reduced-motion` alternative. Every interactive element is keyboard-accessible. Empty states teach. 5. **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 in `globals.css`. Every component references tokens, not hardcoded values. - `pane-layout-animations`: Workspace pans animate open/close/reorder via framer-motion `AnimatePresence` + `layout` prop. - `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 in `React.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: center` added to streaming spinner + `prefers-reduced-motion` guard. - `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 to `React.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-motion` added to `apps/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-motion` coverage completeness.