AI Orb Face

A cartoon character whose expression carries the AI state — gaze that follows the cursor, natural blinks, thinking saccades, happy arcs and spiral eyes.

Open in v0

Last updated: July 31, 2026

Installation

npx smoothui-cli add ai-orb-face

Features

  • Gaze follows the pointer with a spring, and looks away while thinking
  • Blinks on a natural cadence — snap shut, ease open, occasionally a double
  • Squints while thinking, widens while listening, half-closes while streaming
  • Happy arc eyes and a squash-and-stretch hop when it finishes
  • Spiral eyes and a woozy wobble on error, then it recovers on its own
  • Body breathes with the voice, driven from a MotionValue so audio never re-renders React

Expression instead of iconography

Status here is carried by the face, which is the thing humans read fastest. That is also why the other orbs in this family carry state in their material rather than wearing a badge: a checkmark stuck onto a decorative orb looks like a sticker. A character can simply be pleased.

StateExpression
idleEyes open, follows the cursor, occasional blink
listeningEyes widen, body breathes with the voice
thinkingSquints and looks away in saccades, off-centre "hmm" mouth
streamingEyes half-closed and focused
doneHappy arc eyes, curved smile, a small hop
errorSpiral eyes, woozy mouth, one wobble — confused, not scolding

The gaze and blink timings are lifted from the SmoothUI moai in the site header, so the two read as the same creature.

Usage

"use client";

import type { AIState } from "@/components/smoothui/ai-core";
import AIOrbFace from "@/components/smoothui/ai-orb-face";

export const Companion = ({ state }: { state: AIState }) => (
  <AIOrbFace aria-label={`Assistant is ${state}`} size={96} state={state} />
);

Turn the gaze off where many instances would compete for attention:

<AIOrbFace gaze={false} size={32} state={state} />

Accessibility

Reduced Motion

Uses useReducedMotion. Blinking, saccades, the hop and the dizzy wobble are all disabled; expressions still change, they just arrive instantly. Pointer tracking is also disabled, since involuntary following motion is exactly what motion sensitivity is about.

Labelling

Without aria-label the character is aria-hidden. When it is the only status indicator, pass a label that states the state in words — an expression is not available to a screen reader.

Props

Created by

© 2026 SmoothUI. Built by Eduardo Calvo.