# UX Improvements — Implementation Plan (Merged) ## Context Five frontend UX improvements for tree navigation, my-trees, and app layout. Changes are primarily frontend with minimal backend updates for session rewind tracking. Single branch: `feat/ux-improvements`. ## Locked Decisions - Breadcrumb rewind **persists immediately** via API call. - Rewound steps are **soft-abandoned** (history preserved via rewind markers, never deleted). - Shortcuts modal is **global from AppLayout** and **route-aware**. - Follow existing **monochrome design system** with subtle keycap/hint styling. - `sessions.decisions` is JSONB — no DB migration needed for rewind marker fields. --- ## Step 1: Command Copy UX (Quick Win) **Files:** `TreeNavigationPage.tsx` ### Changes - Add a copy-to-clipboard button next to every command block: - Action node commands (`currentNode.commands`) - Custom step commands (`currentCustomStep.step_data.content.commands`) - Command output textarea (when content exists) - Button styling: `opacity-0 group-hover:opacity-100` with `Clipboard` icon, positioned `absolute top-1.5 right-1.5` inside a `group relative` wrapper. - On click: `navigator.clipboard.writeText(text)`, swap icon to `Check` for 2 seconds. - Track copied state with `copiedCommand: string | null`. - Show toast only on copy failure to avoid noisy UX on success. - **Refactor** duplicate command block rendering into a single local render helper to keep behavior consistent across action/custom-step sections. --- ## Step 2: Keyboard Hints + Global Shortcuts Modal (Quick Win) **Files:** `AppLayout.tsx`, `TreeNavigationPage.tsx`, new `shortcutCatalog.ts` ### In-Page Hints (TreeNavigationPage.tsx) - Add keycap-style badges (`[1]`, `[2]`, etc.) next to decision option buttons. Style: `kbd` look, lower contrast, subtle. - Add `[Esc]` hint next to the Back button label. ### Global Shortcuts Modal (AppLayout.tsx) - Add `?` icon button in the app header (desktop + mobile drawer). - Opens a modal (reuse existing `Modal` component). - Modal is **route-aware** using `location.pathname` via a `shortcutCatalog.ts` file: - **Tree Navigation routes:** `1-9` Select option, `Esc` Go back, `Enter` Continue. - **Tree Editor routes:** `Ctrl+S` Save, `Ctrl+Z` Undo, `Ctrl+Shift+Z` Redo. - **Other routes:** Minimal generic navigation shortcuts. - **Do NOT bind `?` as a keyboard shortcut** — it conflicts with text inputs. The modal is click-driven only. ### Keyboard Listener (TreeNavigationPage.tsx) - Add `useEffect` keydown listener on `document`. - Keys `1-9`: If current node is a decision node with options, call `handleSelectOption` for the corresponding option (index = key - 1). - `Escape`: Trigger back/rewind navigation (same handler as breadcrumb rewind — see Step 3). - Guards: - Only active when `currentNode?.type === 'decision'` and options exist. - Ignore if `selectingOption` is truthy (loading state). - Ignore if any modal is open. - Cleanup: Return removal function for the listener. --- ## Step 3: Interactive Breadcrumbs with Soft-Abandon Rewind (Medium) **Files:** `TreeNavigationPage.tsx`, `session.py`, `session_to_tree.py`, `export_service.py`, `SessionDetailPage.tsx`, `SessionHistoryPage.tsx` ### Public Interface Changes Extend `DecisionRecord` in `session.py` and `session.ts` with optional fields: ``` decision_kind?: 'step' | 'rewind_marker' (default 'step') rewind_source?: 'breadcrumb' | 'back_button' rewind_from_node_id?: string rewind_to_node_id?: string abandoned_path_segment?: string[] ``` No DB migration required — `sessions.decisions` is JSONB and stores these optional fields directly. ### Frontend Changes (TreeNavigationPage.tsx) - Replace static breadcrumb `` elements with `