KS77: Design system foundation + P0 graph polish#18
Conversation
- Add document keydown listener in NodeDetail useEffect - Guard: only registers when selectedNode is not null - Proper cleanup on unmount/dependency change - Designer approved: correct a11y pattern, no side effects Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Auto-select center node in expandNode() so detail panel appears after search→click (fixes DP-01) - Click-outside closes SearchBar dropdown (mousedown + ref) - Node/edge count display in toolbar for cluster/neighborhood views - Designer approved: no race conditions, correct cleanup, tokens intact Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Smooth opacity fade on SizeLegend + CommunityLegend (duration-panel, motion-reduce:transition-none, pointer-events-none when hidden) - Ctrl+K keyboard shortcut focuses SearchBar input - Placeholder updated: "Search memories... (Ctrl+K)" - Designer approved: correct tokens, reduced-motion respected, no layout impact from always-rendered absolute legends Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- CommunityLegend matches community members to clusters via top_members
overlap, shows truncated summary (20 chars) or "Group A/B/C" fallback
- aria-hidden={!visible} on SizeLegend + CommunityLegend for screen readers
- Panel component: new optional aria-hidden prop passthrough
- Designer approved: correct a11y, no token regressions, layout safe
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- CommunityPanel shows 5 shimmer skeleton rectangles during initial load (staggered widths, animate-pulse, motion-reduce:animate-none, aria-hidden) - Badge count variant shows "N members" tooltip on hover - Designer approved skeleton: correct tokens, reduced-motion, no layout shift Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Sidebar collapses to 48px icon strip (Layers/Search/Settings) with PanelLeftClose expand button, smooth transition-all duration-panel - sidebarCollapsed + toggleSidebar added to graphStore - Empty state overlay on canvas when clusters=0 && !loading: Network icon + "No memories yet" heading - motion-reduce:transition-none on sidebar animation Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Refactored CommunityPanel to single Panel element with dynamic width so CSS transition-all actually animates (was mount/unmount swap) - Simplified collapsed strip to Layers icon only (removed misleading Search/Settings no-op icons) - overflow-hidden prevents content bleed during transition Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Greptile SummaryThis PR establishes a design system foundation (Tailwind 4 Key changes:
Confidence Score: 4/5Safe to merge after the empty- The PR is large (+1516/−302) but well-structured: design tokens are cleanly consolidated, UI components follow consistent patterns, and the Louvain + sizing logic is correct. The previously flagged double-
Important Files Changed
Sequence DiagramsequenceDiagram
participant U as User
participant CP as CommunityPanel
participant GS as graphStore
participant API as Daemon API
participant GC as GraphCanvas
U->>CP: Click cluster
CP->>GS: drillIntoCommunity(label)
GS->>GS: Guard: cluster exists & top_member content non-empty
GS->>API: searchMemories(content_preview, 100)
API-->>GS: EchoResults[]
GS->>GS: Build graph nodes (log-scale sizing)
GS->>GS: Create O(n²) similarity edges (cap 200)
GS->>GS: assignCommunityColors → Louvain → Tableau10
GS-->>GC: set { graph, communityMap, zoomLevel:cluster }
GC->>GC: LayoutRunner runs ForceAtlas2 (~100 frames)
GC->>GC: animateToNodes(allNodes) — fit camera
U->>GC: Click node
GC->>GS: selectNode(id)
GS->>API: fetchMemoryGet(id)
API-->>GS: MemoryDetail
GS-->>GC: set { selectedNode, selectedDetail }
GC->>GC: animateToNode(id) — 250ms camera transition
U->>GC: Click Expand neighbors
GC->>GS: expandNode(id)
GS->>API: fetchMemoryGet(id)
API-->>GS: center MemoryDetail
GS->>API: searchMemories(center.content slice 200, 20)
API-->>GS: neighbor EchoResults
GS->>GS: Build neighborhood graph + Louvain colors
GS-->>GC: set { graph, selectedNode:id, selectedDetail:center }
GC->>GC: animateToNode(id) immediate
GC->>GC: LayoutRunner → animateToNodes(all) after layout
Reviews (2): Last reviewed commit: "fix(viz): address Greptile PR review fin..." | Re-trigger Greptile |
- P1: Eliminate double fetchMemoryGet in expandNode — pass already-fetched center as selectedDetail directly instead of re-fetching via selectNode - P2: Move d3-scale-chromatic import to top of categoryColors.ts - P2: Remove dead SIDEBAR_COLLAPSE_ICONS export from layout.ts Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Summary
@themeblock with 4-surface color hierarchy (canvas/base/elevated/overlay), 30 design tokens (colors, typography, animation, z-index, spacing),prefers-reduced-motionsupportsrc/components/ui/useCameraTransitionhookStats
tsc --noEmitclean,vite buildclean (375KB JS, 27KB CSS)Known issues (pre-existing, not introduced)
/api/graph/neighbors,/api/memory_related,/api/graph/subgraph) deadlock under load. Frontend uses/api/echoworkaround for drill-in and expand.Test plan
🤖 Generated with Claude Code