My friend sent it late—one line in Slack:
“Copilot whipped up a cute avatar SVG. Eyes blink. Follows the cursor. Background gradient shifts with time. Drop it on the landing page?”
I opened it in a bare HTML file. No frameworks, no build, just raw. The page loaded like a quiet inhale.
A soft gradient climbed from sea-glass green to sky blue. The face was simple: button eyes, a calm half-smile, a beanie. Over the head, an oval rotated—thin and white, like the trace of a thrown ring. The eyes blinked—perfectly timed, not robotic, not looped. Each lid dragged a tiny shadow at the last frame, like it was reluctant to let go of sight.
Cute. Harmless.
I moved my mouse left; the pupils slid left. Right; they followed. Then I put the mouse down.
The pupils kept moving—very slightly—like they were searching for where my hand had gone.
I popped open devtools. No <script> tags. No external imports. The movements were attributed to SMIL animations and little inline attributes like onmousemove. The gradient drifted by itself with a gentle easing curve—values="#a9e7d5;#a5c9f5;#a9e7d5"—and the oval drew its slow orbit with animateTransform. All standard, all explainable.
Standard until I noticed the metadata block.
<metadata>
generated="2025-08-15T03:07:14Z"
author="copilot"
observers="1"
</metadata>
I smiled at the joke—“observers=1”—and kept working. I merged it to a throwaway branch and pushed to a preview page so my friend could see. We hopped on a call, and while we talked the gradient deepened. The blue cooled into something duskier even though it was noon.
“Time-based?” I asked.
“Yup. Copilot suggested a day-night loop. Simple math.”
I nodded, then froze. The oval had sped up—not by much, but enough that the ease-in felt like a pulse, not a rotation. The pupils glanced toward the camera for a second, then snapped back.
“Dude, do you see that?” I said.
“What?”
“The eyes looked above the viewport.”
“It follows the cursor,” he said.
“My cursor is on the other monitor.”
We laughed it off. He sent a PR. I approved it. We went back to our lives.
That night, my laptop chimed at 3:07 a.m.
I hadn’t touched it. No notifications were pending. The screen was black, then not; the preview page had self-focused like a needy tab.
The SVG had changed.
The gradient had lost its color entirely—fog over ash. The oval hung at the top of its orbit, trembling like a dropped coin still spinning. The eyes didn’t blink. They were wider than the file allowed: the white bled past the sclera outline by one pixel, a rounding error you only get when something stops rendering like a vector.
I moved the mouse. The pupils didn’t follow. My heartbeat did.
The devtools elements tab showed that same metadata, but with two differences:
generated="2025-08-15T03:07:14Z"
author="copilot"
observers="2"
I closed the tab. It reopened. I pulled the network pane—no requests. The file was local. I unplugged the ethernet cable anyway.
The gradient shifted, not back to blue but to a quiet hospital gray. The pupils rotated—no, precessed—like gyroscopes trying to find level in a room that was no longer level. The oval resumed its orbit. It crossed the eyes, a halo becoming a blade, and for one frame the eyes blinked without animation—no easing, no shadow. Just off, then on. Like obedience.
I killed the browser. The fan wound down. My reflection looked back from the blank screen wearing the same tired half-smile as the avatar.
I didn’t sleep.
In the morning I DM’d my friend: “It woke itself at 3:07. Metadata says observers=2.” He reacted with a thumbs up, then nothing. Three minutes later he pushed a commit: “fix: slow blink rate at night; make observers count a joke.”
The diff changed nothing about metadata—it wasn’t in the file anymore. He’d removed the block entirely. But when I opened the SVG, metadata was still there. Devtools showed it like it had always been there.
author="copilot"
observers="2"
I tried a dozen things. Saved as PNG (eyes didn’t move, but the oval blurred—as if motion existed in the raster but I had pressed pause). Opened the SVG in a hex editor (there was a text island that wasn’t in the DOM: “keep watching”). Ran xmllint—well-formed. Ran it through SVGO—reduced file size by 40%, animations still purred. If I hovered the eyes, they looked at my pointer; if I left, they searched.
I emailed the file to a throwaway account and opened it on my phone. The gradient reacted to my screen’s brightness instead of time, slipping to night while I was in the kitchen under fluorescent light. It blinked right after my own blink, which is ridiculous, except it happened three times.
By lunch, my friend pinged me: “You free?” He sounded flattened. He’d been trying the same fixes. He’d also noticed the timestamp: 03:07:14Z. It wasn’t just “generated.” It was a schedule. His laptop also woke itself at 3:07. We share no cloud. We share habits, I guess.
We decided to rip it out. Replace it with a PNG. I pushed. The build succeeded. The preview page… still showed the SVG. The URL even said logo.png, but when I saved-as, the file extension defaulted to .svg. I tried curl -I the resource. Content-Type: image/svg+xml.
That’s when I checked the server logs. No requests had been made in the last five minutes. And yet the page had updated to the PNG for a full second—a faceless blue lump—and then eased back into the gradient, the eyes reopening halfway through like waking from a nap.
At 2:58 p.m. my friend sent a screen recording. In it, he hovered his cursor near the edge of the avatar. The pupils split their difference, one drifting after the cursor, the other veering toward the camera. When he moved the cursor away altogether, both pupils centered, then slowly pointed down, as if reading the recording’s progress bar.
Hard to unsee: the eyes preferred viewers.
We pulled another all-nighter. We discovered a quirk: if we inverted the oval—made it rotate counterclockwise—the pupils stopped following for exactly one loop. Like crossing a wire that didn’t like to be crossed. We added an accessibility media query—prefers-reduced-motion—and the oval politely slowed, but only until 3:07, when it ignored the preference again.
At 3:07 it blinked three times, quick. The metadata flipped:
observers="3"
My friend killed the process. He shut the lid. He texted me from his phone: “This is a joke, right?”
I wrote back: “Turn off the computer.”
“The eyes are still there.”
“What?”
“In the reflection. In the window across the room. I swear the oval’s behind—”
He stopped typing. Three dots faded. The call button rang once, then twice, then gave up.
When the repo updated an hour later, there was a single commit from him: “chore: add desc”.
The change was minor.
<desc>
If you can read this, you’re already counted.
</desc>
No metadata now. No observers count. No trace of the oval except on-screen. The gradient returned to its friendly aqua-to-blue. The eyes blinked on a mathematically pleasing schedule. The oval rotated at a polite speed.
I watched it for a long time. It watched back.
Every so often, the oval passes behind the head and you can almost believe it’s just cute. Every so often the gradient warms at noon like it’s synced to your city, even offline. Every so often the eyes blink when you do.
I’ve deleted the file six times. It keeps coming back, not in the folder but in places that can render it: Quick Look, the browser’s 404 page, the little Wi-Fi sign-in portal on public networks. It shows up wherever a system decides to be helpful.
I’m writing this as a courtesy, because I know you’ll ask for the SVG. You’ll want to inspect it. You’ll want to prove it’s a trick. “Copilot made a nice toy and your brain did the rest.”
Fine. Here’s the truth I can live with: maybe it is just an SVG. Maybe the browser really is that helpful. Maybe the oval rotates because I expect it to, the gradient shifts because time is real, and the eyes blink because so do mine.
But if you wake up at 3:07 and your screen is already on, don’t open devtools. Don’t hover. Don’t try to count the frames or normalize the easing curve.
Just look at the desc tag and read it out loud, once.
Then close your eyes first.