# Keyboard Integration as Shared Input, Not as Gesture

## Decision

Keyboard is not a `GestureType`.

v2 treats pointer gestures and keyboard events as parallel input streams that share:

- one context stack
- one resolver
- one action dispatcher
- one provider-owned keyboard listener per active canvas

## Runtime Shape

- Pointer stays gesture-native:
  - `tap`
  - `double-tap`
  - `triple-tap`
  - `long-press`
  - `drag`
  - `pinch`
  - `scroll`
- Keyboard uses a separate event shape:
  - `kind: 'key'`
  - `phase: 'down' | 'up'`
  - `key`
  - `code`
  - `repeat`
- Shared runtime event union:
  - `PointerGestureEvent`
  - `KeyInputEvent`
  - `InputEvent`
- Held keyboard state is explicit:
  - `heldKeys.byKey`
  - `heldKeys.byCode`
- Pointer events carry a held-key snapshot so bindings like `Space+drag` are modeled as pointer gestures with keyboard context.

## Resolver Rules

- Pointer patterns still match pointer gesture types.
- Keyboard patterns match `phase`, `key`, and/or `code`.
- `key` score: `+64`
- `code` score: `+64`
- held-key positive score: `+16`
- held-key negative score: `+8`
- If both `key` and `code` are present, both must match.

## Ownership

- `InputProvider` is the single keyboard owner for the active canvas.
- The last canvas root to receive pointer interaction or focus becomes keyboard-active.
- Keyboard routing is suppressed when:
  - target is `input`
  - target is `textarea`
  - target is `contentEditable`
  - IME composition is active
- Held keys clear on `blur` and `visibilitychange`.

## Default Behavior

- `/` opens command line
- `Cmd/Ctrl+F` opens search
- `Cmd/Ctrl+C/X/V/D` route through shared input actions
- `Cmd/Ctrl+Z`, `Cmd/Ctrl+Shift+Z`, `Cmd/Ctrl+Y` route through shared input actions
- `Delete` / `Backspace` delete current selection
- `Escape` precedence:
  1. cancel active interaction
  2. exit keyboard manipulate mode
  3. clear search / selection / close palette
- `keyboardInteractionMode` is explicit:
  - `'navigate'`
  - `'manipulate'`
- Navigate mode:
  - arrows move focus
  - `Enter` selects and enters manipulate mode
  - `Space` activates focused node
  - `Tab` cycles focus
- Manipulate mode:
  - arrows nudge selection by `10`
  - `Shift+Arrow` nudges by `50`
  - `Escape` returns to navigate mode

## Cutoff

- Remove keyboard ownership from:
  - `packages/canvas/src/commands/keyboard.ts`
  - `packages/canvas/src/hooks/useCanvasHistory.ts`
  - `packages/canvas/src/hooks/useArrowKeyNavigation.ts`
- Keep those exports as compatibility shims only if needed for callers during the repo migration.

## Verification

- resolver tests for key/code/held-key matching
- runtime tests for `Space+drag`, `Escape`, copy/paste, undo/redo, and active-canvas ownership
- behavior tests for navigate vs manipulate mode
