feat: Add comprehensive design documentation for Krates

- Canvas: Infinite zoomable workspace with LOD and navigation
- Spotlight: Fuzzy search with type filters and view shortcuts
- Krate: Window group container with non-overlapping placement
- Detail Window: YAML/Describe/Logs/Shell views with maximize
- Top Bar: Cluster info, user presence, admin toggle
- Admin Drawer: Multi-user presence and spectate functionality
- Minimap: Browse and navigate canvas overview
- Collection Window: List/tree views with filtering and sorting
- Shell/Logs: Real-time terminal and log streaming
- Backend: Go service with K8s API, WebSocket handlers, CRDT sync
- Architecture: Full project structure and tech stack
This commit is contained in:
Hermes Agent
2026-06-16 08:32:47 -04:00
parent b31fa3cde5
commit 78f19cde7d
12 changed files with 2709 additions and 2 deletions

149
design/minimap.md Normal file
View File

@@ -0,0 +1,149 @@
# Minimap Feature Specification
## Overview
The minimap provides a bird's-eye overview of all krates' positions on the canvas. It allows navigation by clicking to fly the camera to any location.
## Position & Size
### Placement
- Position: `absolute; right: 18px; bottom: 64px` (above zoom pill)
- Size: 180×120px
- Z-index: Must be above canvas but below spotlight (z-index: 20-30 range)
### Background
- Base: `rgba(16,20,28,.97)`
- Border: `1px solid rgba(140,165,200,.2)`
- Border-radius: `4px`
- Padding: None (full content area)
## Viewport Indicator
### Rectangle
- Shows current camera view frustum
- Position: Relative to minimap content (proportionally mapped)
- Size: Proportional to zoom level
- Color: Accent (e.g., `#4dd6e8` cyan) with 40% opacity
- Stroke: Solid line, 1px
### Mapping
- World position (wx, wy) → Minimap coordinates
- Formula:
```
mx = (wx + camX) / zoom scaling factor
my = (wy + camY) / zoom scaling factor
```
- Zoom mapping: Larger viewport indicator = lower zoom level
## Krate Visualization
### Representation
- Each krate = small rectangle (8×6px default)
- Color: Matches krate's namespace color
- Position: Relative to minimap origin
- Scaled down: ~1/60th of world space
### Content
- Krate positions only (not internal windows)
- All active krates on canvas
- Update on: krate create, delete, move
### Performance Optimization
- Only render visible krates (cull distant ones)
- Batch updates (throttle minimap render)
- Use CSS transform, not re-layout
## Interaction
### Click Navigation
- Click anywhere → fly camera to world position
- Calculate world coordinates from click position:
```
worldX = (clickX / minimapWidth) * worldWidth - viewportWidth/2
worldY = (clickY / minimapHeight) * worldHeight - viewportHeight/2
```
- Animate camera fly: `.52s cubic-bezier(.22,.8,.28,1)`
- Zoom: Set to `0.92` or user's preferred zoom
### Hover Effects (Optional)
- Hover krate rectangle → highlight preview on canvas
- Show tooltip: krate name, window count
## Canvas Synchronization
### Updates Triggered By
1. New krate creation
2. Krate movement (drag)
3. Krate deletion
4. Canvas resize (re-calculate scale)
5. Camera change (update viewport indicator)
### Throttling
- Debounce minimap render: 100ms
- Don't update on every pixel of drag
- Batch: Collect all krate changes, render once
## Visual Styling
### Krate Rectangles
- Size: 8×6px (small but visible)
- Color: Krate's namespace color
- Fill: Solid
- Border: None (or very subtle: rgba(255,255,255,.1))
### Viewport Indicator
- Fill: None
- Stroke: `#4dd6e8` (accent), 1px
- Opacity: 0.4
- Rounded corners: 2px
### Background Patterns (Optional)
- Subtle grid overlay (same as main canvas, fainter)
- Stars or dots for visual interest
- Very low opacity: rgba(255,255,255,.05)
## Coordinate Mapping
### World to Minimap
```
minimapScale = minimapWidth / worldWidth (e.g., 180 / 12000 = 0.015)
minimapX = (worldX + camX) * minimapScale
minimapY = (worldY + camY) * minimapScale
```
### Minimap to World (for click)
```
worldX = (minimapX / minimapScale) - camX
worldY = (minimapY / minimapScale) - camY
```
### Viewport Rect
```
viewportWidthWorld = viewportWidth / zoom
viewportHeightWorld = viewportHeight / zoom
viewportMinimapX = (camX * minimapScale)
viewportMinimapY = (camY * minimapScale)
viewportMinimapW = (viewportWidthWorld * minimapScale)
viewportMinimapH = (viewportHeightWorld * minimapScale)
```
## Animation
### Camera Fly
- Duration: `.52s`
- Easing: `cubic-bezier(.22,.8,.28,1)`
- Target: Center minimap-clicked position
- Zoom: Set to `0.92` (or user preference)
### Smooth Updates
- Smooth viewport indicator movement: CSS transition
- Avoid jitter during drag
- Use `requestAnimationFrame` for updates
## Gotchas
1. **Coordinate precision**: Use floating-point for accurate mapping
2. **Zoom handling**: Viewport indicator must scale inversely with zoom
3. **Performance**: Minimap should never block main thread
4. **Culling**: Don't render krates far outside view
5. **Click handling**: Ensure click z-index > canvas but < spotlight
6. **Responsiveness**: Recalculate mapping on window resize