The crop overlay looked finished. A dim backdrop, the image centered, four corner handles, a draggable frame. I grabbed a corner handle with the mouse and pulled. Nothing moved. I grabbed the frame to drag the whole crop box. Nothing moved. The handles rendered, the cursor changed on hover, and not one pixel followed the drag. The overlay was position: fixed and sat on top of everything. By every visual signal it owned the screen. By every drag it owned nothing.

What follows is the hunt for why, and the one sentence I wish I had known going in: a fixed overlay is decoupled from its ancestors for painting and not for events. Those are two different machines, and I had assumed they were one.

What I thought was wrong

My first guess was the math. Crop handles do real arithmetic: pointer position to canvas fraction, clamp to bounds, write back the frame rectangle. A sign flip or a stale rect would freeze the box while everything else worked. So I logged the computed fraction on every move. The log stayed empty. The math was not wrong; the math was never running.

Second guess: the handle was not wired. Easy mistake, a listener attached to the wrong node, a typo in an id. I checked. The pointerdown handler on the crop layer fired exactly once when I pressed the mouse. So the handler existed and the first event reached it. The problem was not the press. It was everything after the press.