fix(web): polish Ghostty terminal scrolling, selection, and input

Reliability pass over the browser surface, renderer, and ABI layer:

- normalize wheel deltas by deltaMode with fractional accumulation, so
  Firefox line-mode wheels and pixel-mode trackpads both scroll at the
  device rate instead of a forced row per event
- translate wheel motion into arrow keys on the alternate screen so
  vim/less scroll without mouse tracking, honoring DECCKM
- re-arm a resolution media query to refit the canvas when
  devicePixelRatio changes from monitor moves or zoom
- anchor drag selections in Ghostty screen coordinates so streaming
  output can no longer shift the selection origin mid-drag, and
  autoscroll the viewport when a drag passes the canvas edge
- keep the blink cycle in the visible phase across writes, stop
  blinking while unfocused, and render a hollow cursor when the surface
  does not own keyboard focus
- move the IME textarea to the terminal cursor each frame so candidate
  windows appear where the user types, and guard Safari's keyCode 229
  composition keydown from double-encoding
- encode keyup as Ghostty release events, which stay silent for legacy
  sessions and emit event-typed codes under Kitty report-event-types
- report unknown instead of the shifted character for unshifted
  codepoints on non-US layouts without NavigatorKeyboard data
- take selection colors from the theme with xterm-parity overlays and
  no forced white foreground; give the canvas a text cursor and a
  pointer over link gestures
- measure cell metrics only after the bundled webfonts load
- harden ABI error paths: zero opaque slots before first write, free
  temporaries on every throwing path in selection/grid-ref/paste
  helpers, and read grapheme codepoints without an alignment assumption

New wheel/keyboard behavior is covered by unit tests and vendored-WASM
ABI regressions, including release encoding under CSI > 3 u.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
da91992d10Wout Stiens committed on 7/31/2026, 7:21:07 AMparent91de531
9 files changedLine totals unavailable