# Design Document: Detail Window Feature Specification

## Overview
A detail window shows one view (YAML / Describe / Logs / Shell) for one Kubernetes object. Windows are grouped into krates and can be resized/moved within their container.

## Core Responsibilities
- Display object data in one of four view types
- Allow window dragging within krate
- Support window resizing with proportional sibling adjustment
- Implement maximize/restore functionality
- Route keyboard focus on mouse-over

## Window Types

### Detail View (default)
- **Purpose**: Display static object information
- **Content types**: YAML, Describe, Logs (for pods/workloads)

### Collection Window
- **Purpose**: List/Tree view of multiple objects
- **Special features**: Filter input, selection highlighting, view shortcuts

## Window anatomy (380×362px default)

### Header (36px height)
- Left: Shape glyph (8px, color-coded by object type)
- Middle: View label (uppercase, accent-colored) + object name + status badge
- Right: × button (close window)
- **Cursor**: `grab` — drag to reposition within canvas
- **Double-click header**: Maximize / restore window
- **Drag**: Move window within krate

### Tab Bar
- Tabs: YAML · Describe · Logs · Shell
- Shell tab: disabled (opacity 0.45) for non-exec object types
- Active tab: accent underline/highlight
- Click tab: Switch view content

### Content Area (286px height)
- Element: `<pre>` (preformatted text)
- Styling:
  - `overflow: auto`
  - `height: 286px`
  - `font-family: 'IBM Plex Mono'`
  - `font-size: 12px`
  - `line-height: 1.65`
- Scrollbar:
  - Width: 8px
  - Color: rgba(140,165,200,.18)

## Resize Behavior

### Resize Handle
- Positioned at bottom-right corner
- Drag to resize
- **Proportional adjustment**: When one window resized, siblings in same column/row resize proportionally
- Storage: Use `rowHeights` and `colWidths` arrays per krate (future enhancement)

### Window Grid
- **Column pitch**: 412px
- **Row pitch**: 416px
- **Window default**: 380×362px (leaves room for grip/padding)

## Maximize Functionality

### Maximize State
- Width: `viewport.width - 44px` (22px margins)
- Height: `viewport.height - topBarHeight(68px) - bottomBarHeight(66px)`
- Camera adjusted: `camX = 22 - krate.wx - window.dx`, `camY = 68 - krate.wy - window.dy`, `zoom = 1`

### Trigger
- **Key**: `z` (when mouse is over window)
- **Mouse**: Double-click header
- Restore: Same trigger again

## Keyboard Focus Routing

### Mouse-Over Detection
- Track `mouseenter`/`mouseleave` per window
- Set `hoveredWindowId` ref
- Clear on `mouseleave`

### Key Event Routing
Global `keydown` handler with `{ capture: true }`:
```
if (hoveredWindowId is shell) {
  route keypress to shell
} else if (hoveredWindowId is collection) {
  route keypress to filter input
} else {
  let it fall through to canvas shortcuts
}
```

### Shell Special Case
- Space character goes to terminal (NOT spotlight)
- Must distinguish between canvas space-pan and shell space-input

## View-Specific Content

### YAML View
- Display full object YAML
- **Secret objects**: Base64-decode all data values
- Show banner: `⊙ secret values auto-decoded`
- Security: Handle carefully, never log decoded values

### Describe View
- Human-readable object description
- Formatted for readability
- All metadata sections included

### Logs View
- **Pods/workloads only**
- **Live-tailing**: Stream via WebSocket
- Auto-scroll to bottom on new lines (unless user scrolled up)
- Color-code:
  - ERROR: `#ef6f6f`
  - WARN: `#e8b54a`
  - INFO: `#b9c6d8`

### Shell View
- **Implementation**: xterm.js (real terminal)
- **Backend**: WebSocket → `kubectl exec -it <pod> -n <ns> -- sh`
- **Keyboard routing**: Route keypresses to terminal, passthrough terminal output
- **Scroll wheel**: Scroll terminal content (NOT canvas pan)
- **Ctrl/⌘+scroll**: Zoom canvas (not terminal zoom)

## Collection Window Specifics

### Size
- Default: 540×480px (larger than detail windows)

### Header
- Title: `pods · ns/payments`
- Status summary badges: `✓ N / ⚠ N / ✗ N`
- Filter input (auto-focused on open)
- List / Tree toggle buttons
- Keyboard hint: `↑↓ ⌥L/S/D/Y`

### List Mode
- Rows: shape glyph + name + health metric + type badge + view buttons + status dot
- Selected row: `background: accentDim; border-left: 2px solid accent`
- Hover row: `background: rgba(255,255,255,.04)`
- Sorted: degraded/failed first, then pending, then ready; alpha within groups

### Tree Mode (k9s xray)
- Workloads expand to show pods
- Pods expand to show configMaps, secrets, PVCs
- Services/ingresses expand to show targets
- Relation tags: `pod`, `configMap`, `secret`, `volume`, `selects`, `routes`, `used by`
- Indent: `20px * depth`
- Filtering: Keep matching nodes + all ancestors for hierarchy

## Window State
```typescript
interface Window {
  wid: string;             // unique window ID
  kind: 'detail' | 'collection';
  tab: 'logs' | 'shell' | 'describe' | 'yaml';
  dx: number;              // offset within krate (column * 412)
  dy: number;              // offset within krate (row * 416)
  w: number;               // width
  h: number;               // height
  isMaximized: boolean;    // current state
  prevW?: number;          // previous width (for restore)
  prevH?: number;          // previous height (for restore)
}
```

## Gotchas
1. **Space key**: Must distinguish between canvas space-pan (capture with `{ capture: true }`) and shell space-input
2. **Ctrl/⌘+scroll**: Use `{ capture: true }` on canvas to intercept before window scroll containers
3. **Secret decoding**: Do server-side or careful client-side; never log decoded values
4. **Window resizing**: Proportional siblings requires storing `rowHeights`/`colWidths` arrays (not just individual `dx/dy`)
5. **Focus routing**: Mouse-over + type should focus shell/filter, not trigger canvas shortcuts
6. **Collection auto-focus**: On creation, focus filter input in next tick using ref + `useEffect`
