π The Introduction
Most AI chatbots are boring. They are usually just a static box in the corner of the screen. When I was building the AI assistant for Trainlytic, I wanted something different. I wanted a bot that felt "alive",an assistant that acknowledges your presence before you even start typing.
In this post, Iβll show you how I built a futuristic, robot-faced AI coach using Mistral AI, Next.js, and some clever Framer Motion math to make its eyes follow your cursor.
π€ The Vision: A Bot with Personality
I didn't want a "wrapper." I wanted a UI that felt like the year 3026. The goal was to combine Glassmorphism, Neon accents, and Interactive Animation to create a high-fidelity user experience.
Key Features:
Cursor Tracking: Eyes follow the user's mouse movement.
Natural Blinking: Randomized double-blinks to mimic biological behavior.
Mistral AI Integration: Specialized fitness and nutrition coaching.
ποΈ The "Eye" Logic: Mathematical Cursor Tracking
The standout feature is the eye-tracking. The eyes don't just move; they calculate the distance between your cursor and the center of the bot's face using a limited "visor" range.
I used useEffect to listen for mouse movements. Here is the core logic:
TypeScript
// Cursor tracking for eyes
useEffect(() => {
const handleMouseMove = (e: MouseEvent) => {
if (!robotRef.current || isOpen) return;
const rect = robotRef.current.getBoundingClientRect();
const robotCenterX = rect.left + rect.width / 2;
const robotCenterY = rect.top + rect.height / 2;
const deltaX = e.clientX - robotCenterX;
const deltaY = e.clientY - robotCenterY;
// Limit eye movement range (max 4px offset for natural movement)
const maxOffset = 4;
const distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
const normalizedDistance = Math.min(distance / 300, 1);
const offsetX = (deltaX / (Math.abs(deltaX) + 100)) * maxOffset * normalizedDistance;
const offsetY = (deltaY / (Math.abs(deltaY) + 100)) * maxOffset * normalizedDistance;
setEyeOffset({ x: offsetX, y: offsetY });
};
window.addEventListener("mousemove", handleMouseMove);
return () => window.removeEventListener("mousemove", handleMouseMove);
}, [isOpen]);
β‘ The Brain: Mistral AI & Streaming
For the "brain," I chose Mistral AI. Itβs incredibly fast and perfect for the specific fitness and nutrition prompts I use to help guys reach their goals.
To prevent a clunky user experience, I implemented Streaming Responses. Instead of waiting for the full response, the text "flows" into the bubble using a ReadableStream.
π¨ UI/UX: Natural Blinking
I wrote a performDoubleBlink function that triggers at random intervals. This small detail makes the bot feel less like an icon and more like an entity.
TypeScript
const performDoubleBlink = () => {
setIsBlinking(true); // First blink
setTimeout(() => {
setIsBlinking(false);
setTimeout(() => {
setIsBlinking(true); // Second rapid blink
setTimeout(() => setIsBlinking(false), 100);
}, 150);
}, 100);
};
π‘ Conclusion
Building this taught me that UX engineering is just as important as the AI itself. People stay on the page longer just to play with the bot's eyes!
Check it out live at Trainlytic.net and let me know what you think of the design in the comments!


Top comments (0)