Love the clean look. And cool how you did the animations with only CSS.
Looking at the code, seems like the refresh rate depends on how often the browser is able to call the onmousemove callback, which might not be enough. If I move the mouse fast enough, I can go through the needle without registering a win or a loss.
Usually for this kind of thing you'd use interpolation: every update, draw a line between the previous mouse position and the current one, and check if the line intersects the needle threading area.
Probably nothing new for you, totally understandable if you just wanna keep it simple.