The problem
One visual state for every kind of latency. Users can't calibrate patience against a signal that never changes.
Twenty ways to say "I'm working on it." A dotted 3D sphere, one canvas, zero dependencies.
Ai Spheres also ships inside the consumer design system's Status Orb component
Almost every AI product says "something is happening" with the same generic spinner, whether the model is listening, calling a tool, reading a document, or about to fail. A spinner can't distinguish a two-second wait from a twenty-second one — and a user's patience depends entirely on knowing which one they're in. The brief was to design a motion vocabulary, not one more loading animation.
One visual state for every kind of latency. Users can't calibrate patience against a signal that never changes.
No WebGL, no physics engine, no external dependency — it has to be cheap enough to run a dozen at once, in a chat log, without cost.
A shared point field (one Fibonacci sphere) with twenty distinct motion programs reads as one coherent family, not twenty unrelated icons.
Every state maps to a distinct visual mechanism — an orbital ring, a LiDAR sweep, a DNA braid, a digital-rain cascade — so the shape of the wait tells you the kind of work, not just that work is happening. Grouped here by what they communicate to the user, not by how they're implemented.
A motion component that skips accessibility or performance discipline is a liability wearing a nice animation. These four rules are load-bearing — they were designed in from the first commit, not patched on afterward.
The orb freezes on its current frame rather than disappearing. A user who has turned off motion still needs to know the agent is working — hiding the indicator would be a second failure stacked on the first.
Each instance uses IntersectionObserver to stop animating once it scrolls out of view, and the whole page pauses on document.hidden. A gallery of twenty spheres costs nothing off-screen.
role="img" plus an aria-label auto-derived from the active state's status text ("Agent searching…") — not the internal id, which would mean nothing to a screen reader.
Follows prefers-color-scheme, a page-level data-theme attribute, or an explicit override on the element — in that order, so it drops into an existing design system without a wrapper.
No 3D engine. Points are distributed on a sphere with a Fibonacci lattice, rotated with a hand-written 3D transform, and shaded by depth. Each state is a small function that perturbs that same point field differently — an orbital sweep, a braid, a step function — so the twenty states share one skeleton and never drift into twenty unrelated visual languages.
A spinner is a perfectly honest signal that time is passing. It just can't say anything about what kind of time is passing — and in an agentic product, that distinction is most of what a user wants to know.
I designed a vocabulary, not an animation.
Anyone can draw a spinner. The work here was deciding what twenty different kinds of "working" should each look like, keeping every one of them legible without motion, and making the whole thing cheap enough to run a dozen at once. Ai Spheres is a small, focused project on purpose — proof that the same design discipline that goes into an 86-scene engine or a 150-component fintech system applies just as well to one honest loading indicator.