Move the cursor across the title and each letter interpolates its weight and width by distance to the cursor, then eases back to rest.
Pick a variable font — Roboto Flex, Inter and Open Sans Variable all expose the weight and width axes — and the ripple is real: the component reads the rendered width of a sample letter to confirm the axes actually respond before it commits to the effect. With a static font, or on a system where the browser won't apply variable axes to an installed font, it falls back to a scale ripple instead of doing nothing.
Follows the cursor with frame-rate-independent smoothing, so it feels the same at 60 and 144 Hz.
DOM and requestAnimationFrame, no dependencies, nothing loaded from outside. Honours prefers-reduced-motion, and freezes on a still, representative wave inside the Framer canvas. Free.
Move the cursor across the title and each letter interpolates its weight and width by distance to the cursor, then eases back to rest.
Pick a variable font — Roboto Flex, Inter and Open Sans Variable all expose the weight and width axes — and the ripple is real: the component reads the rendered width of a sample letter to confirm the axes actually respond before it commits to the effect. With a static font, or on a system where the browser won't apply variable axes to an installed font, it falls back to a scale ripple instead of doing nothing.
Follows the cursor with frame-rate-independent smoothing, so it feels the same at 60 and 144 Hz.
DOM and requestAnimationFrame, no dependencies, nothing loaded from outside. Honours prefers-reduced-motion, and freezes on a still, representative wave inside the Framer canvas. Free.