This site is haunted. Not in the "nobody remembers why this code exists" way: there are actual spiders on it. From October 25 to 31 they show up on every page. The rest of the year they only haunt this one, and only if you ask. Either way, there may be one hanging over this paragraph. Go ahead, grab it. It's only CSS. Until you grab it.
Easter egg #1 was the birthday balloons, which get one day a year. This one gets a whole week, October 25 to 31. In theory. I merged the first spider at 01:58 on October 30, my time (UTC-3), so the haunt arrived on day six of a seven-day season.
It's 6,886 lines of code, 2,759 of them CSS, for a feature that's live seven days a year. Two, this year. Any day you ask, on this page.
It leaves at midnight, your midnight
There's no feature flag. The date is the flag: isHalloweenSeason() checks that today is between October 25 and 31 using your browser's local date, so the haunt runs on your timezone, not mine. Once October 31 ends where you are, a fresh page load renders nothing, and it all comes back on October 25 next year. With one exception: when the date says no, resolveHalloween() asks one more question, whether you're on this post. I didn't write a secret URL that brings it back in November. I wrote a public one, and you're reading it. It waits to be asked.
One loophole: the date is only checked when a page opens. Leave a tab sitting past midnight and the spiders stay until you reload or open another page. They don't own a watch.
So if it's still October 25 to 31 where you are, go to the home page now. This post will still be here tomorrow. So will the spiders, if you want them.
Egg one: the spiders do physics
Two webs spin themselves into the top corners, then spiders drop out of the top of the screen on their silk. Most stop just under the header. The rest drop a long way down into the page, which, according to a comment in the code, "is where the actual jump-scare comes from".
The opening wave drops five (three on a phone); after that it keeps up to four hanging at a time (two on a phone), because a narrow screen fills up fast. The opening wave only drops once per tab session, so clicking around the site doesn't replay the scare.
While they hang, they're plain CSS animation. Grab one and it gets handed to a physics loop, with GRAVITY = 2200 pixels per second squared:
Drag it and its thread stretches like a bungee. Let go and the silk slings it back.
Pull too far and the thread snaps. "Too far" is 45% of the screen height past its resting length, never less than 220px or more than 460px.
Swipe fast through a thread, faster than 0.9 pixels per millisecond, and you cut it. The loose end whips back up, a blade streak flashes, and the spider tumbles to the bottom of the screen.
Once it lands it crawls along the bottom edge, pausing and turning at random. Get the cursor within 90px and it runs. After 14 to 24 seconds it gets bored and walks off the nearest edge.
Click it instead of dragging and it bolts back up its silk.
Leave it alone back on its thread and after 3.2 seconds it climbs home.
The physics lives in src/lib/halloween-physics.ts as pure functions with no DOM, which means it has unit tests. Sixteen for the spider physics, 78 across the Halloween modules. Priorities.
If your system asks for reduced motion, you get the decorations and none of the movement: the webs and two spiders hanging perfectly still. Nobody gets jump-scared who asked not to be.
Egg two: a bat sleeps on my job title
The headline on the home page says "Software Engineer,". About six and a half seconds after the page loads, a bat swoops in from the top right and lands on the "r" at the end of "Engineer". It stands on the letter's arm looking around for 3.8 seconds, then flips over and hangs upside down underneath it, asleep, with z's drifting up.
The landing spot is measured, not hardcoded. The code draws an "r" on a canvas in the headline's own font, scans the pixels for where the stem ends and the arm sticks out, and lands the bat there. So it works at any screen size and in every language: the Portuguese headline is "Engenheiro de Software," and the bat still finds an "r" to sleep under. Spiders dropping in afterwards try to steer clear of it, so nobody lands on a sleeping bat. When this post is haunted, one sleeps on its title too: the "r" in "Easter", the only "r" up there.
Egg three: the o in Software is a pumpkin
The "o" in "Software" carves itself into a jack-o'-lantern, in 3.8 seconds: the letter blushes orange and swells like it's being inflated, a pumpkin pops out of it, the stem sprouts, a leaf unfurls, a knife traces the eyes, nose and mouth, and the plugs fly out as the candle catches.
Then it idles: the candle flickers, it glances around and tilts every 7 seconds, it blinks, it breathes. Hover it and it gives you what the stylesheet calls "an evil little cackle". Whenever this page is haunted, the "o" in "Halloween" up in the title does all of it too.
Now the part you can't see. The real "o" never leaves the page. Screen readers, search engines and copy-paste all still get "Software": a CSS custom highlight paints that one character transparent and the pumpkin sits on top of it. The server-rendered headline isn't touched.
The rest, as riddles
There are more. I'm not telling you where. Well, I am, at the bottom, but try these first:
The pumpkin skipped dinner, and it isn't vegetarian.
Don't poke the pumpkin. It knows where the light switch is.
Let sleeping bats lie. Or don't.
One of the webs has a landlord. Evict them.
One spider in five is friendlier than the rest. Watch them hang around.
Four spiders not enough? The address bar takes requests.
Write me a letter in Halloween week. The courier is nocturnal.
Developers: the spiders left you a note where developers look.
The egg you'll never find
There was one more. At 00:50 on October 30 I committed a "one-time web-slinger swing across the page on Halloween": a masked silhouette swinging on a web line in a pendulum arc, in from the top left, low through the hero, out the top right. Then I gave it the spiders' level of detail. Fourteen minutes after the first commit, I reverted it. It never reached production.
A masked figure, a web line, a site full of spiders. I'll let you work out who it was.
Spoilers, if curiosity wins
One per riddle, in the same order. Click to open.
Spoiler: The pumpkin skipped dinner
Grab a hanging spider and drag it toward the jack-o'-lantern: its eyes follow the spider, its mouth opens wider the closer you get, and it starts to drool. Let go right over its mouth and it eats it, chews, burps and looks smug; let go too far away after getting its hopes up and it droops and dims, visibly disappointed.
Spoiler: Don't poke the pumpkin
Click the jack-o'-lantern once it's lit and it blows its own candle out. The page goes dark for 6 seconds, a circle of light follows your cursor, and every spider's and bat's eyes glow until the wick sputters back to life.
Spoiler: Let sleeping bats lie
Hover or tap the bat hanging under the "r". It wakes up, grins, unfurls one wing and waves at you, then goes back to sleep.
Spoiler: The landlord
Swipe fast through the strands of the top-left web. Cut three and the spider living in it loses its footing and falls; leave the web alone for 7 seconds and it spins itself back.
Spoiler: The friendly one
One spider in five waves its front leg, once, while it hangs still at the bottom of its drop. Watch the ones that drop and wait.
Spoiler: Four is not enough
Add ?spiders=1 to the URL, as in joaovictord.dev/?spiders=1. Up to 24 spiders at once on a desktop, a new one every 0.7 seconds and a bat flock every 7. In Halloween week it works on any page. The rest of the year it works on this post, where it starts the swarm for that visit, no clicking needed.
Spoiler: The nocturnal courier
Send me a message through the contact form on the home page, October 25 to 31. Instead of the usual confetti, an envelope with a wax seal pops out above the check mark and a bat swoops in, grabs it and flies off the screen with it (it takes a real message, so make it a nice one).
Spoiler: A note for developers
Open the browser console on any page in Halloween week, or on this post whenever it's haunted. The spiders left a greeting there, with a tip on how to cut a thread. Out of season the note changes, and gives one of the riddles away.
Go find them. When your October 31 runs out, the date check wins everywhere but here. On this page, the rest of the year, you get the switch.