Evasive Contact Form
A contact form where the Submit button doesn't want to be clicked — spring physics, escalating personality, and a deadpan punchline.
Started as a throwaway AI Studio export: 48 lines, a Submit button that teleports on mouse hover. Dead Gemini dependencies, mouse-only, the button clipped at the container edge. The concept was funny — the execution was a napkin sketch.
Rebuilt it with a philosophy: the form is the straight man. Gray-50, corporate, looks like every contact form you've ever closed without reading. The comedy comes entirely from the button — which develops a personality arc over four escalating tiers. First hover: "Not today." Fourth hover: "My therapist said I don't have to do this." Seventh: "We both know they're not going to read it." Tenth: "I've filed a restraining order."
Under the hood, the spring physics panic alongside the personality — stiffness climbs from 300 to 900, damping drops from 20 to 6, dodge range expands, and the button physically shrinks at high counts. Viewport-aware bounds keep it on-screen. onPointerEnter + onFocus with immediate blur means nobody escapes — mouse, touch, pen, keyboard all get dodged.
The secret exit is Ctrl+Enter. The reward: "Thank you for your inquiry. A member of our team will reach out within 7–10 business days. Just kidding. Nobody works here." Plus your dodge count, because the app was keeping score.
Mid-build inflection: realized the existential and unhinged tiers were gated behind 15+ hovers. Nobody hovers fifteen times. Dropped all thresholds so the arc hits fast enough for casual visitors to see the good stuff.
Still one component. Still 214 lines. The joke is that something this simple has this much going on under the hood.
Latest Update
Nobody hovers fifteen times
Fri, Jul 31, 2026
Timeline
Opened an AI Studio export and found a contact form where the Submit button runs away from your cursor. That's the whole app — 48 lines in a single React component, onMouseEnter triggers a random translate, the button teleports. Funny concept, zero craft. The Gemini API dependency was dead weight (no AI actually used), five npm packages existed for a backend that didn't exist, and overflow-hidden clipped the button at the container edge, killing the joke mid-punchline. Mouse-only — touch users and keyboard users got a static form that did nothing. Took 67 steps: read every file, traced every import, started the dev server, confirmed the gag worked in principle but broke in practice. Verdict: great concept, weak execution, ~3 hours to plate it properly.
Told the model: swing for the fences on humor, but the punchline is the simplicity. The form stays boring — gray-50, corporate, looks like you've filled it out 400 times. The button develops a personality arc across four escalating tiers of 33 dodge messages. First two hovers, it scoots politely: "Not today." By hover four, it's dramatic: "My therapist said I don't have to do this." By seven, existential crisis: "We both know they're not going to read it." Past ten, fully unhinged: "I've filed a restraining order." Spring physics panic alongside — stiffness climbs from 300 to 900, damping drops from 20 to 6, and the button starts physically shrinking at high dodge counts like it's trying to hide. Viewport-aware bounds keep it from clipping off-screen. onPointerEnter replaced onMouseEnter so touch and pen get dodged too. onFocus fires a dodge and immediately blurs so keyboard tabbing is equally futile. The secret exit is Ctrl+Enter — and the reward is deliberately anticlimactic: "Thank you for your inquiry. A member of our team will reach out within 7–10 business days. Just kidding. Nobody works here." Still one component. Still 214 lines.
Watched the build live and realized the best jokes were buried behind thresholds nobody would reach. The original tier breakpoints were 6, 10, and 15 — but who's going to hover a button fifteen times? The existential messages ("What are you even going to say?" "This says more about you than it does about me.") and the unhinged tier ("I'm not even a real button." "At this point we're in a relationship.") would never be seen. Dropped the thresholds to 2, 4, 7, and 10. Added a fourth "unhinged" tier with nine new messages. Now the personality arc hits fast enough that a casual visitor gets dramatic by the fourth hover and existential by the seventh. The model's humor was too good to waste on theoretical edge cases.