Research

The Page That Gestures Back

A small creature lives in the margins of this site, and is probably beside you now. It points at what you hover, beats on the words you read, eats radishes, and thumps when you startle it. It is also, quietly, a demo of what I study.

Prateek Gupta · October 2026 · source

4
kinds of co-speech gesture
1
file, no dependencies
3
animals tried, one kept
9
rabbit behaviours checked against the literature

My home page is plain text: one serif, a lot of white space, a list of things I have made and written. In the margin sits a small teal creature called Mooli. When you hover a link it walks over and points at it. When you read the intro it does a little hop on the stressed words. If you rush your pointer at it, it freezes, thumps the ground and bolts.

Most people will take it for a nice detail, and that is fine. But I work on digital humans, and the thing I care about most in that work is the part nobody notices when it is done well: the body language that goes along with speech. So the creature is a small, honest attempt at that, running in a browser margin. The page never explains it. This article does.

Where it comes from

Little creatures have lived on our screens for almost as long as screens have had pointers. The first I know of is Neko, a cat that chases your cursor, written in the 1980s for Japanese NEC PC-9801 computers. It went to the Macintosh, then to Unix as xneko (Masayuki Koba, 1990), and lives on as oneko, still packaged for Linux today. Neko is Japanese for cat, and the o- is a polite prefix, so the name is partly a pun.

Then came creatures you had to look after. Activision's Little Computer People (1985) put a tiny person in your computer. PF.Magic's Dogz (1995) and Catz (1996) put pets on the desktop. And in November 1996 Bandai released the Tamagotchi in Japan, an egg-shaped keyring with a pet inside that you had to feed and clean up after, or it would get ill. Its name, by Bandai's account, joins tamago (egg) and "watch". It was devised by Akihiro Yokoi and Aki Maita, who shared the 1997 Ig Nobel Prize in economics for diverting millions of hours of work into the care of virtual pets.

The line kept going: Neopets moved them onto the web in 1999, Nintendogs onto the Nintendo DS in 2005. And around 2009 Yuki Yamada of Group Finity made Shimeji, small desktop mascots that climbed your windows, sat on top of them and multiplied (shimeji is a kind of mushroom). By the early 2010s people were redrawing them as every character they loved.

And they are back. In 2025 Bongo Cat, a free cat that sits above your taskbar and taps along as you type, became a Steam phenomenon, with close to 200,000 people running it at once. Websites have their own cats again: oneko.js puts the old Neko on any page, and small libraries like desksprite let visitors grab, throw and seat a mascot on a site. Browser extensions put pets on every page you visit. Browser Pet wanders along the bottom of pages and, if you let it, walks up to paragraphs and eats them. PixelCat reacts to YouTube and Google. Tabagotchi is a Tamagotchi that gets ill if you hoard tabs. Even programmers' tools have them: Claude Code, Anthropic's coding assistant, hides a Tamagotchi-style pet in the terminal (/buddy), and there are galleries of companions for OpenAI's Codex. And there are tiny avatars for AI agents in web apps, like agent-pet, which shows states such as thinking, success and error in a speech bubble.

Almost all of them react to you: your typing, your cursor, your tabs, your app's state. Very few react to what you are reading, and the ones that could have to ask for access to every page you open, which is why a privacy-minded pet like Pawly makes a point of not reading pages at all. Mooli gets around that by living on my own site. It can read the page because the page is mine, and it reads nothing else.

The creature in my margin borrows from all of them. From Neko, the habit of following your pointer. From the Tamagotchi, being fed, getting full and falling asleep. From Shimeji, living on top of the page instead of inside a window, and sometimes sitting on the link you wanted. What it adds is the part I actually study: it does not just live on the page, it reads along with you and gestures at what you read.

Gesture as a channel

When people talk, their hands talk too, and not at random. Research on embodied conversational agents, most of all Justine Cassell's, treats gesture as a channel that carries meaning alongside speech, timed to it. David McNeill's taxonomy splits co-speech gesture into four kinds, and the creature does all four.

KindWhat it isWhat the creature does
Beata small rhythmic flick on stressed wordsa hop on each emphasised word of the intro, as if it were saying it, and again as those words cross the reading line when you scroll
Deicticpointing at somethingwalks to the link you hover and points at it, aimed with real geometry
Iconicdrawing the thing in the aira T-pose for the motion-capture viewer (the calibration pose every mocap take starts with), a slithering arm for the snake game
Metaphoricshaping an ideaa director's frame with both hands for the short film, hand to chin for the thought canvas

Gestures also have phases, described by Adam Kendon: a preparation, a stroke, a hold and a retraction. The stroke is the part that should land with the word. So the creature's beats are timed to arrive just before the word reaches the reading line, and when you move off a link it holds the point for a moment before relaxing. Its eyes get to a link before its arm does, because gaze leads gesture. When you stop scrolling it gives a little nod, the "mm-hm" of backchannel. When a heading scrolls past, it shifts its weight, the way speakers change posture at a topic boundary.

The creature in a T-pose next to the BVH Viewer link
Figure 1. An iconic gesture: hovering the motion-capture viewer gets the T-pose.

It started life as a stick figure, a few strokes and three dots in an SVG. That version taught one lesson worth keeping: pointing at something far below you reads as an arm hanging down. So the figure walked along the margin to stand level with whatever it pointed at, and the creature still does. The stick figure was then replaced by the round thing you see now, drawn on its own canvas so it can go anywhere on the page.

What makes it feel alive

Almost everything in the creature is a spring. Its position, its squash and stretch, its tilt, where it looks, its eyelids, its mouth, its arms and its belly each chase a target, and every frame a small decision function moves the targets. Springs get you natural motion for free; the craft is in which springs you add and how stiff they are. Most of what I added comes from the classic animation principles, done in code rather than by hand.

PrincipleIn the creature
Anticipationevery jump starts with a crouch and launches 70 ms later
Squash and stretchon landing, hopping and gulping, capped so it can never flatten into a line
Follow-througha sprout on its head that hangs off a spring and trails every move; arms drawn as curves that bend against their own swing, like 1930s rubber-hose cartoons
Slow in, slow outeased tricks, sprung everything else
Secondary actionbreathing (a quick in, a slow out), blinking, a soft shadow that shrinks as it leaves the ground

The single biggest improvement was the eyes. Research on believable characters keeps finding that eyes which glide smoothly, or never move, read as dead. Lee, Badler and Badler's Eyes Alive modelled the quick jumps and fixations of real eyes, called saccades, and a later Bamberg study found that a little noise in eye rotation makes characters look more natural. So the creature's eyes jump to a new spot every second or two and hold there, and the body tilts after them on a slower spring. The eyes lead, the body follows.

The creature mid-hop with its sprout trailing and its shadow below
Figure 2. Mid-hop: the sprout trails behind, the face turns toward where it is going, and the shadow shrinks.

Then there are the things it does when you play with it. Circle your pointer around it twice and it gets dizzy, with spiral eyes. Scrub back and forth across it and it giggles. Select some text and it walks over to read along, its eyes running along the line and snapping back. Leave the tab for a while and it waves when you return. After 11pm it yawns more and falls asleep sooner.

The creature dizzy, with spiral eyes
Figure 3. Dizzy.
The creature giggling, eyes closed and mouth open
Figure 4. Tickled.

A language of its own

It talks, in a made-up language. The same feelings always get the same words, so if you visit often you start to pick it up: bwee-lo is hello, ba-bai is goodbye, bapa is good, nom is food. Between those it babbles. Exclamations go in a speech bubble and musings in a thought cloud. The bubble types itself out, and the mouth opens on each vowel as it is typed, which is crude lip sync but surprisingly effective.

The first bubble was a hard ink box. It became a wash of the creature's own colour with a soft outline, a pill-shaped bubble with a curved tail, and a proper scalloped cloud for thoughts. Every letter hops into place as it appears.

The first speech bubble, a plain outlined box
Figure 5. Before: a plain box, and a line that did not fit the moment.
The redesigned thought cloud with trailing puffs
Figure 6. After: a cloud for thoughts, in the creature's own colour.

Figure 5 also shows a mistake. Selecting any text used to get a generic "mm... yes... sooo.", which made no sense next to "I'm a software engineer". Now it reacts to what you selected: software engineer gets "bip-bop! codo!", digital humans gets "oh! like mi!", film gets "kino! popcorni?", and anything it does not recognise gets its main word echoed back in its accent. Responding to content, not just to the act of selecting, is a small version of a large problem in conversational agents.

The creature saying bip-bop codo next to the selected words I'm a software engineer
Figure 7. Reacting to what was selected.

Radishes, and a belly

Click any blank part of the page and a radish drops in with a bounce. The creature fetches it and eats it in four beats: it grabs it, chews three bites with it held under its chin (bits fly, cheeks puff), gulps, and pats its belly.

Eighteen frames of the creature fetching and eating a radish
Figure 8. A meal, one frame every 110 ms: arrive, grab, three bites, gulp, belly pat.

Each radish fills it up a little, and it digests about one every forty seconds. On the third it says it is full. The fourth gets a burp and an apology. After that it refuses food, shaking its head with its hands up. Overfeeding also changes its shape, and I wanted the fat on its belly, not a bigger creature. Only the lower half of its outline widens and sags. A lighter belly patch and a belly button appear, its feet spread, and it slows down and waddles. As it digests, it slims back down.

The creature before eating
Figure 9a. Before.
The creature after four radishes, with a rounder belly and a belly button
Figure 9b. After four radishes. The head is the same size; only the belly has grown.

Choosing an animal

The creature is not any particular animal, which left its personality open. So I gave it three sets of animal habits and tried each on the real page.

  • Pup: eager. Its sprout wags like a tail. It tilts its head at you, play-bows then pounces at your pointer, gets the zoomies after food, and follows you around.
  • Cat: aloof. It ignores about half of what you point at, slow-blinks at you, sits in a loaf, kneads while you pet it and then leaves ("hmph."), and bats its food across the page.
  • Bunny: soft. Its sprout becomes an ear. It flops over when content, does a twisting leap when happy, and carries its radish home before eating it.
Contact sheet of the bunny personality through a scripted session
Figure 10. The bunny through a scripted session, including carrying a radish home over its head ("mine-a! hehe.") and a binky ("boing!"). The pup and the cat have sheets of their own in the source folder.

Why a rabbit

Watching each one run on the page, the deciding question turned out not to be which animal is cutest. It was which animal's behaviour suits a web page, where the reader is there to read and the creature is a guest in the margin. The bunny won on both counts that mattered: how it reacts, and how it behaves the rest of the time.

It reacts to you, and its reactions are easy to read. A rabbit is a prey animal. Its whole repertoire is about noticing change and answering it: it freezes at a sudden movement, thumps to say something is wrong, stands up on its hind legs to look around, rubs its chin on anything new. That maps almost one to one onto the things that happen on a page: your pointer rushing in, your pointer leaving the window, a link it has not met before. Each reaction is short and clear. A thump is over in half a second and nobody could mistake it for anything else. For a gesture demo that is the point: the behaviour has to be legible at the size of a margin, in the time it takes to read a line.

It has a signal you can read at a glance. On the bunny the sprout became an ear: up when alert, flopped when relaxed, pinned flat when afraid. That is a whole channel of state on top of the face, and it reads at twenty pixels. Rabbit welfare research uses ear position the same way, as one of the units of the Rabbit Grimace Scale. Neither the pup's wagging sprout nor the cat's held as much.

It is calm when nothing is happening. Most of the time a page is just being read, so a creature in the margin should mostly sit still. Rabbits do a lot of sitting: loafed with their paws tucked in, or flopped over on one side when they are at ease. They save their bursts of play, a few fast laps and a twisting leap, for after something good. That is the right rhythm for a web page: quiet while you read, lively when you do something.

The other two showed why this matters. The pup was lovely and far too much. It followed my pointer across the page, play-bowed and pounced at it, and tore round the margin with the zoomies after most meals. On a page you came to read, that is a dog that will not let you read. The cat had the opposite problem. It ignored about half the links I hovered and walked off after three seconds of petting. That is a very good cat, but a gesture agent that ignores half of what you point at is failing at its one job.

PupCatBunny
Attends to what you point atalways, eagerlyabout half the timealways, and chin-marks new links
While you are just readingfollows you, play-bows, zoomiesloafs, grooms, ignores yousits, loafs, flops
Reaction to a sudden movementa pouncea pouncefreeze, thump, bolt
State you can read at a glancea wagging tailslow blinksears: up, flopped or pinned
Suits a page you came to readno, too muchno, too littleyes

It asks you to be gentle. Rabbits do not like being picked up. Hold Mooli for more than a second and it goes rigid and wide-eyed, and when you let go it thumps and runs. I could have made dragging it around pure fun. Instead, the most obvious way to play with it is the one it minds, which nudges you towards the kind of attention it does enjoy: a radish, a stroke, a link to look at. I like that a web toy can have a small opinion about how it is treated.

And it was already halfway there. The creature was a round thing with a sprout on its head that eats radishes. Bunny habits made all of that look deliberate. It got a name at the same time: Mooli, Hindi for radish, which seemed only fair for a bunny that lives on them. It knows its name: select it anywhere on this page and it will tell you so. It now follows you around the site too, everywhere except the tools and games, and stays fed or full from one page to the next. The pup and the cat are still there if you add ?pet=pup or ?pet=cat to the address.

What rabbits actually do

Then I did what I should have done first, and read about rabbits. Some of my guesses were simply wrong. My bunny bolted and then thumped; real rabbits freeze, thump the ground with their hind feet to warn others, and then bolt. My bunny's ears stood up when it was scared; up means alert, and fear pins them flat. Its nose twitched on a timer, when sniffing should rise and fall with how alert it is.

The evidence is uneven, so the table says how strong each piece is. "Strong" means a peer-reviewed study or a scientific review; "moderate" means veterinary or welfare-body guidance; "weak" means pet-care advice that agrees with itself but cites nothing.

The bunnyWhat rabbits doEvidence
Startled, it freezes, thumps, then boltsFrightened rabbits thump with their hind feet as an alarm; the ancestral defence is to freeze, hide, then escape undergroundstrong, moderate
Ears up when alert, pinned flat when afraid, flopped when relaxedA crouch with flattened ears reads as fear; ear position is part of the Rabbit Grimace Scalemoderate, strong
Rubs its chin on a link it has not met beforeRabbits chin-mark with scent glands, and new objects trigger itstrong
Stands up on its hind legs to scan when something changesVigilance rises with threat; rabbits rear up to look and listenmoderate
Held too long, it goes rigid and still, then thumps and bolts when let goTonic immobility is a fear response, a last defence, not relaxationstrong
Fast laps ending in a twisting leap after something goodRunning and leaping play is read as a positive state, commoner where there is roomstrong for play as positive, weak for the leap's exact meaning
Loafs with paws tucked, flops onto its side when at easeTucked or stretched-out lying shows ease; flopping shows comfortmoderate, weak
Sniffs faster when alert, slower when relaxed, not at all when floppedSniffing is fast and breath-locked when exploring; measured in rats, not rabbitsstrong in rats, weak in rabbits
Carries food home before eating itNot a documented rabbit habitnone: a liberty
Frames of the bunny freezing, then bolting with a THMP
Figure 11. Startled: frozen, ears up (first frames), then a thump and a bolt.
Frames of the bunny held in a trance, standing up to scan, and chin-rubbing a link
Figure 12. Held too long (rigid, wide-eyed), standing up to scan, and chin-marking a new link ("mine-a.").

The trance taught me the most. A rabbit lying still on its back, eyes open, looks calm. It is terrified. Pet owners have done it for years thinking it soothes them. The obvious reading of the signal and what the signal means come apart, and that is exactly the problem with reading gesture in agents. A nod does not always mean yes, and a hand on the chin does not always mean thought. Building the bunny correctly meant building it to look less cute at that moment, not more.

An avatar for an agent

While I was building Mooli, the big AI companies started giving their agents faces. It is worth placing Mooli next to them, because a creature that reads along with you and gestures at what you are looking at is a small working sketch of what an agent's avatar could be.

The ancestor is Clippy, the paperclip that shipped with Office 97 as one of a set of animated assistants. It is remembered as a failure, and the reasons are well documented: it appeared on crude cues, like typing "Dear" at the start of a line, and it interrupted you without helping. Microsoft turned it off by default a few years later. The lesson the industry took was "no cute characters". The better lesson is "no interruptions".

The faces came back anyway. In 2025 Microsoft gave Copilot's voice mode Mico, a small glowing blob whose colour and expression follow the tone of the conversation. It even has a hidden reaction for Clippy if you tap it quickly. In the same year xAI added companions to Grok, animated characters including a red panda called Rudi, to a lot of criticism. And in September 2026 Meta launched its Muse agent with a default character called Jolly, a cream-coloured figure with beady eyes, alongside a keychain gadget, the Muse Charm, that shows the avatar on a small screen. TechCrunch called it Tamagotchi-like, and the line from the first section of this article runs straight to it. OpenAI introduced characters of its own, the Dots.

These avatars are not decoration. Muse and its rivals are agents: they can act for you, search for things and prepare purchases. That is why the cute faces have drawn criticism as well as downloads. Fortune asked whether a friendly face earns trust that the agent has not, and the research on friendly design and trust is, so far, mixed. The children's advocacy group Fairplay asked US regulators to look into whether the mascots draw in children. A cute face on something that can spend your money is a different thing from a cute face in a margin.

Mooli has no access to anything, so it can afford to be cute. But building it suggested four things I would want from any agent's avatar.

What an agent's avatar should doWhat Mooli doesWhy it matters for an agent
Point at what it is about to act onwalks to the link you hover and points at it; looks at a thing before reaching for itan agent that points at the field it will fill or the button it will press makes its intentions visible before it acts. Deixis as transparency.
Be quiet until it is neededsits, loafs and reads along; reacts to what you do, not on a timerClippy's real failure was interruption. A rabbit's rhythm, calm by default and quick to answer, is the right one.
Show its state at a glanceears up when alert, flopped when relaxed, pinned when afraidan agent's equivalent is working, waiting for you, unsure, or stuck. One glanceable signal beats a status message.
Never perform a feeling it does not havewhen held too long it looks frozen and frightened, not calm, because that is what a rabbit in that state isan avatar that smiles while the agent is uncertain, or looks relaxed while it spends your money, is the trance problem in reverse: the signal and the state come apart.

The last one matters most. The point of embodiment, in Cassell's sense, is that the body carries information that the words leave out. A face that is only there to be liked carries none. If agents are going to have faces, those faces should do what Mooli's gestures do: show you where its attention is, what it is about to do, and how sure it is. Cute should come second.

How I tested it

An animated character is hard to test by clicking around, because what matters happens in a few hundred milliseconds. So every behaviour was checked in a real browser driven by a script: headless Microsoft Edge through Playwright, against a small local server.

  • Finding it. The creature draws on a canvas, so it does not exist in the page's structure. The script reads the canvas pixels back and takes the bounding box of everything teal.
  • Hearing it. A hook on the canvas's text drawing logs every word it says, which is how I checked that the fourth radish really got "oof. biggo belly." then "BUURP!" then "...sorry-a.".
  • Watching it. Frames captured every 70 to 110 ms, laid out as contact sheets like the ones in this article, so an animation can be read at a glance.
  • Provoking it. Synthetic pointer events in a circle to make it dizzy, a programmatic text selection to make it read, a fast burst of pointer moves to startle it.

Bugs worth telling

A few were more interesting than the features.

  • It could not get dizzy. It counted how far your pointer went around it, but near the margin it follows your pointer, so the angle barely changed. Now it measures the turning of your pointer's own path.
  • Three quick clicks smeared it into a line. Each click added a squash, and three stacked until it was flat. The clicks also passed through the canvas and selected the paragraph underneath, so it wandered off to read it mid-trick. Now the squash is capped, a quick tap is a "boop", and a double-click is a clean flip.
  • It vanished for good. If the pointer left the window while it was over the creature, the next frame thought it was still being petted, with no pointer, and threw an error on every frame after. It was in the code from the start, and the personality tests found it.
  • The test that lied. My first startle test never startled it, because the script moved the pointer in a few big jumps and the speed estimate averaged over three seconds of stillness. The bunny was right; the test was wrong.

The creature is one JavaScript file with no dependencies: margin-creature.js. It respects reduced motion: with that setting on, it sits still and says nothing.

References

Gesture and conversational agents

  • Cassell, J., Sullivan, J., Prevost, S. and Churchill, E. (eds.) (2000). Embodied Conversational Agents. MIT Press.
  • McNeill, D. (1992). Hand and Mind: What Gestures Reveal about Thought. University of Chicago Press.
  • Kendon, A. (2004). Gesture: Visible Action as Utterance. Cambridge University Press.

Animation and believable characters

  • Thomas, F. and Johnston, O. (1981). The Illusion of Life: Disney Animation. Abbeville Press.
  • Lee, S. P., Badler, J. B. and Badler, N. I. (2002). Eyes Alive. ACM Transactions on Graphics, 21(3).
  • Jörg et al. (2018), University of Bamberg, on how much noise in eye rotation and pupil size makes virtual characters look natural (PDF).
  • Willett, N. S., Li, W., Popović, J., Berthouzoz, F. and Finkelstein, A. (2017). Secondary Motion for Performed 2D Animation. UIST 2017.
  • Procedural Animation in Games. On springs for secondary motion.
  • oneko, the desktop cat that chases your pointer, and the long line of desktop pets after it.

Virtual pets

Pets now

AI agent avatars

Rabbits