Companion

After x.ai/bot

The eyes are flat marks lying on the surface of a sphere. Gaze rotates the sphere and the far eye foreshortens into a rotated ellipse. The head is a circle and looks the same from every angle, so the eyes are the only thing that reveals the rotation.

Studied 2026-08-18SVG + DOM, CSS custom properties. One rAF loop. No WebGL, no Rive, no Lottie.

attention locked
move your pointer · click to startle · the mood changes on its own

The eyes are on a sphere

This is the structural idea the whole rig rests on. The eyes are not two shapes sliding around a face; they are flat marks lying on the surface of the head. Gaze rotates the sphere, and the far eye then compresses into a rotated ellipse because that is what a flat mark on a turning ball does. The head is a circle, so it looks identical from every angle: the eyes are the only thing that reveals the rotation.

TurningDrag across it. Watch the far eye foreshorten.
Three shapesParallel, arch, round — cycling.
OutlineSame rig, hairline stroke, no fill.
Avatar · 44pxGaze only. Everything else dropped.

Attention has modes, and the eyes say which

It does not track the pointer with one constant law. Sometimes it watches you closely, sometimes it is vaguely aware, sometimes it is plainly doing its own thing. What sells it is that the eye shape changes with the mode, so the state is readable before you test it: parallel when locked on, arched when merely interested, round and wide when absorbed in something of its own.

Connect the Bots

Put a few in one thread and they pass work between themselves. You watch them act instead of approving every step.

Asking Research

Weather

Gradient arcs sweep past on their own schedule and a burst of colour fires on arrival. Occasional, unrequested, and the main reason the thing reads as inhabited rather than merely responsive.

Behaviour

Attention
Rig
Satellites
Weather

Attention mode sets the eye shape. Everything else is scheduling.

What it actually does

  • Three eye states, and the state is the message: parallel capsules when locked on you, an arched pair when merely aware, wide circles when absorbed in something of its own.
  • The far eye compresses AND rotates. That is not an art choice, it is what a flat mark on a turning ball does, and it is the tell that the model is spherical rather than planar.
  • Attention is not one constant law. The tracking gain, the wander and the eye shape all change together on a jittered timer, so you can read the mode before you test it.
  • Satellites are antipodal pairs on slowly precessing axes: two dots at the poles of one line, passing behind the head as the axis turns.
  • Gradient arcs sweep past on their own schedule, and a burst of colour fires on first load which settles into faint drifting specks. Both are launched into three dimensions, so roughly half of each one emerges from behind the head.
  • There is an outline variant: identical rig, hairline stroke, no fill.

What the rebuild taught

  • A phase that wraps reads as a stutter. Antipodal pairs on an ever-increasing angle are continuous by construction and never restart.
  • Eye separation belongs to the shape, not to the rig. Round eyes need to sit noticeably wider apart than capsules or they collide at the centre.
  • SVG rotate is clockwise, so an arched pair is left-positive and right-negative. Getting this mirrored is the difference between "focused" and a vaguely wrong expression nobody can name.
  • Stiffness and damping are the personality. Everything else is scheduling.
  • Decay must be per second, not per frame. A per-frame multiplier made the arrival burst collapse before it left the head.
  • Two copies of each satellite, one behind the head and one in front, with opacity toggled on the sign of z. Cheaper and steadier than reordering the DOM every frame.
  • Every layer has to obey the sphere, not just the ones you thought about. The satellites got depth first and the weather did not, so arcs and sparks slid over the face and quietly flattened the whole thing back into a sticker.
  • A great circle drawn around a solid head must be cut at the horizon and drawn as two paths, one on each side. Consecutive runs share their boundary point, or a seam opens where the arc crosses.

Rebuild

One Spring factory, one Bot function, a capability flag per instance, six instances. Eye shape, separation and tilt are all spring-morphed so a mode change never pops. The loop is split into a synchronous tick(dt) on window, because a throttled background tab starves rAF and makes the page impossible to QA otherwise.

Primitives

Surface markA flat shape living on a curved surface, foreshortened along its own normal. Buys rotation from almost no geometry.
State machineNamed modes with their own laws AND their own look, so the state is readable before you test it.
SpringDamped follow. Nothing snaps, and stiffness/damping carry most of the perceived personality.
Pointer gazeContinuous, saturating response to pointer position rather than discrete hover states.
SchedulerJittered periodic events. What makes a thing feel alive when nobody is interacting with it.
Antipodal pairTwo marks at +axis and -axis of a rotating axis. Continuous by construction, with no phase to wrap.
Z-crossingObjects passing behind each other. The single cheapest cue that sells depth in a flat scene.
HandoffState visibly travelling between UI elements, so a system reads as a set of actors.

The work it is after

x.ai/bot