Goal: Create a "Shockwave" button animation.
Visual behavior: On click, 3 concentric rings expand outward from the click point with staggered timing (0ms, 120ms, 240ms delays). Each ring is slightly larger and more transparent than the previous, creating a powerful shockwave ripple effect. The button has a solid gradient background.
Technique: On click, iterate over 3 wave configs [{ delay: '0ms', dur: '500ms', color: 'rgba(99,102,241,0.7)' }, { delay: '120ms', ... }, { delay: '240ms', ... }]. For each: create a DOM span with data-shock attribute, set inline cssText with position:absolute, width/height 36px, border-radius 50%, border with the wave color, background transparent, left/top at the click coords, and CSS custom properties --delay and --dur. Append to the button (useRef), then remove after 800ms. The @keyframes btn-shockwave animates: from { transform: translate(-50%,-50%) scale(0.1); opacity: 0.9 } to { transform: translate(-50%,-50%) scale(3); opacity: 0 }. CSS rule: [data-shock] { animation: btn-shockwave var(--dur) ease-out var(--delay) forwards }.
Accessibility: Animation skipped under prefers-reduced-motion.
My stack: {{USER_STACK}}
My styling: {{USER_STYLING}}
My constraints: {{USER_CONSTRAINTS}}
Return a single self-contained component. Do not introduce dependencies beyond what I've listed.
Paste into Claude, ChatGPT, or Cursor. Edit YOUR_STACK /
YOUR_STYLING / YOUR_CONSTRAINTS before sending.