Goal: Create a "Typewriter" card animation.
Visual behavior: The card has a terminal/code aesthetic. On hover, the title text erases character by character (30ms per deletion), then retypes a new string (40ms per character). The description does the same after the title finishes. A blinking cursor (| or _) is visible during the erase and type phases. On mouse leave, both strings reverse back to their originals. The header area shows a static terminal prompt (> run_) with a blinking underscore cursor.
Technique:
- Store displayed title and description in useState
- Track phase: 'idle' | 'erasing' | 'typing'
- On hover, use recursive setTimeout chains: erase one char at a time (30ms), then type target chars (40ms)
- Store the timer ref in useRef for cancellation on mouse leave
- When mouse leaves mid-animation, cancel current timer and start the reverse sequence immediately
- Blinking cursor: CSS keyframe @keyframes blink { 50% { opacity: 0 } } with animation: blink 0.8s step-start infinite
- Show the cursor span only when phase !== 'idle'
- Use monospace font for the text area to reinforce terminal feel
Accessibility: Under prefers-reduced-motion, skip the erase/retype animation; show final text immediately and hide the cursor.
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.