How it works
Each press appends a ripple {x, y, size} to local state; AnimatePresence removes it on complete.
Material-style ink ripples that originate exactly at the pointer (or centre, for keyboard).
Each press appends a ripple {x, y, size} to local state; AnimatePresence removes it on complete.
Ripples scale a pre-sized circle (transform) instead of animating width/height.
Keyboard activation spawns the ripple from the centre, so feedback is equal for all inputs.
transition={{ duration: 0.65, ease: [0.2, 0.7, 0.3, 1] }}