Rendering used to clear the whole canvas and redraw every cell on
every frame callback (~60 fps) even though the simulation ticks at
20 tps and starts paused, keeping CPU usage at ~85% while idle.
Split simulation timing out of redraw() into the event loop and
render only when displayed content can have changed (tick, painting,
pattern placement, preview movement, grid-line toggle, resize);
idle frames commit only a new frame callback. Repaint incrementally
by diffing the grid against a rendered-state snapshot per row and
redrawing just the changed cells, with damage limited to the
repainted bounding box.
Idle CPU drops to ~1% of one core; running frames render at tick
rate (~20 fps) at microsecond cost. Adds grid_copy() snapshot
helper with tests and archives the optimize-render-on-demand change
with the new on-demand-rendering spec.
Add configurable key bindings (TOML), modifier-aware dispatch, mouse-driven
pattern placement with preview and rotation, cell grid storage/rendering,
and fractional/integer HiDPI scaling. Archive the input-and-placement change
and sync its specs to main specs.
Tests: Hashtable, Config, Grid, Pattern (4/4 pass).
Plan input handling and pattern placement before Game of Life mechanics:
keyboard bindings config, mouse placement with preview/rotation,
HiDPI scaling, and cell grid. Update AGENTS.md project notes.