Magnetic button

The button drifts toward the pointer while hovered and springs back to centre when the pointer leaves.

ButtonHover Vanilla JSGSAP time-based Targets: Web All modern browsers
Target
Implement the "Magnetic button" effect in vanilla HTML/CSS/JS.

Context: The button drifts toward the pointer while hovered and springs back to centre when the pointer leaves.
Trigger: the pointer hovers the element (fall back to focus on touch devices).
Timeline: time-based (duration + easing).

Motion tokens (normal):
- translate (button): 0,0 → up to 35% of pointer offset, max 24px
- translate (label): 0,0 → an extra 15% of pointer offset
- duration: follow ≈ 120ms lerp · release 600ms
- easing: follow: linear interpolation 0.18/frame · release: elastic.out(1, 0.4)

Motion tokens (prefers-reduced-motion):
- translate: 0 → 0
- duration: 0
- note: disabled entirely; keep the hover colour change only

Technique: plain JavaScript (requestAnimationFrame / class toggles), no animation library required; GSAP (ScrollTrigger where relevant) is acceptable as an alternative.

Acceptance:
- animate only transform and opacity unless the spec lists other properties
- no layout shift; content is visible without the animation
- when prefers-reduced-motion is set, use the reduced tokens only
- pointer-only; never active on touch devices (check hover: hover media query)
- clamp displacement so the button never leaves its hit area by more than 24px

Generated from the spec. Prompts differ by target name only; the tokens are the source of truth.