My portfolio has a secret most visitors will never discover.
If you go to eamann.com right now, you’ll probably see a starfield. Stars drifting past like you’re in hyperspace. Move your mouse and the camera shifts. Shooting stars flicker through an overlay canvas.
That’s the default experience. The vast majority of visitors get it.
The other lucky few get something else entirely.
The Rebuild
My portfolio had been a static HTML resume for years. Job titles. Bullet points. The kind of page you put up because you’re supposed to have one, not because you’re proud of it. It listed what I’d done, but it didn’t represent who I actually am.
I’m not a resume. I’m a builder who ships security programs, writes books, plays with PHP and helps manage releases, speaks at conferences, and tells stories. The old site was accurate.
But it was lifeless.
So I rebuilt it from scratch.
No framework. A lightweight build step. Custom HTML, CSS, and vanilla JavaScript with Three.js pulled in as a vendor package. Hosted on GitHub Pages. Cloudflare in front.
The design language is sci-fi command terminal. Deep-space transmission aesthetic. Orbitron for display headings, Share Tech Mono for monospace, translucent panels with backdrop-filter blur over animated backgrounds. CRT scanlines overlay everything. The content reads as an identity piece, not a job application: a “Who I Am” narrative, a stats dashboard, case studies for projects I’ve actually shipped, a talks archive, publications, and social links.
Go look at it before you keep reading. The rest of this will make more sense.
The Atmosphere System
The background isn’t just a starfield. There are fifteen1And there will be more, depending on my level of boredom. different background animations. I call them “atmospheres.” Every visitor gets assigned one at random based on weighted probability tiers, and the assignment sticks. A 30-day cookie keeps your atmosphere consistent across visits.
Here are just a few of them, from common to impossibly rare:
Starfield — The default. Hyperspace flight through roughly 3,000 stars with nebula clouds and occasional shooting stars. Mouse parallax shifts the camera. Three.js.
Vaporwave — Outrun-style scrolling grid racing toward a neon sun, with layered wireframe mountain ridges and floating chevrons. The sun is a canvas-texture gradient from amber through magenta to deep purple, with horizontal scanline cutouts. Mouse movement drives world yaw. Three.js.

Möbius— A hand-rolled Möbius tube rendered as sparse cyan wireframe, with a smaller magenta inner tube counter-rotating inside it. Ambient rotation with cursor parallax. Three.js.
Tesseract — A true 4D hypercube. Sixteen vertices. Thirty-two edges. Rotating in the xw and yw planes. Two nested cubes (amber outer, cyan inner) counter-rotate with a breathing pulse. Mouse position accelerates the 4D rotation. Three.js.

Abyss — Pitch black until you move your cursor. Mouse movement spawns soft glowing particles along the cursor path that drift, grow as they fade, and stack additively into fluid-like trails. Hue cycles cyan to magenta with rare amber accents. Pure 2D canvas.
Dunes — A Mt. Hood silhouette rendered as a sand sculpture of roughly 1,800 spring-anchored particles. Each grain has ambient shimmer via per-grain sine phase and spring physics. Your cursor scatters nearby grains; the springs snap them back into the mountain shape. Pure 2D canvas. A Pacific Northwest easter egg.
With the current weighting of the possible views, fewer than 1 in 400 visitors will ever see Abyss or Dunes. Fewer still will see things like a fractal visualization or fireflies or an aurora.
How It Works
The implementation lives in js/atmosphere.js. On page load, the script checks for the eam_atmo cookie. If it’s not there, it rolls a weighted random choice using Math.random() against cumulative probability thresholds and sets the cookie with a 30-day expiry.
Each atmosphere is a self-contained init function targeting <canvas id="bg"> for the main scene (Three.js or raw 2D canvas, depending on the variant) and <canvas id="fx"> for a 2D overlay that handles effects like shooting stars. The overlay canvas is shared across all variants.
The Three.js atmospheres each create their own renderer, camera, and geometry, then run inside a requestAnimationFrame loop. The 2D canvas atmospheres use the raw Canvas API directly.
There’s a Cloudflare Worker that reads the eam_atmo cookie from incoming requests and sets an X-Atmosphere response header echoing the variant name. Check your response headers and you can see which one you got. I originally tried to do this with a Cloudflare Transform Rule, but Transform Rules can’t access cookies. That’s a Workers-only field. I learned this the hard way.
Folks who grew up gaming in the late 80s and 90s can also try a pretty common cheat code to clear the cookie and re-roll their chosen atmosphere.
The Collection Page
There’s a hidden page at eamann.com/atmosphere/ that shows all of the possible variants as a collector’s grid. Atmospheres you’ve personally encountered appear in full color; clicking on them will set your chosen atmosphere directly.
Ones you haven’t seen are grayed out and redacted: “??? — ?%”.
There’s no navigation link to this page anywhere on the site.
The only hint is a dim line in the browser console: // atmosphere index: /atmosphere/. If you open DevTools, you might notice it.
Most visitors won’t.
Other Easter Eggs
Opening DevTools shows an ASCII banner, a greeting, and a link to my LinkedIn profile. There’s a reroll() function you can call from the console if finding a cheat code feels like too much work.
The site has a humans.txt file, per the humanstxt.org convention, also alluding to the presence of additional atmospheres.
After discovering nownownow.com, I just had to add a /now page as well. It renders from a static Markdown file, compiled into the page template by a GitHub Action on push. Updating what I’m currently working on is just editing Markdown and pushing.
Why Any of This Matters
It doesn’t. Not in any measurable way.
Nobody will hire me because they got the tesseract background. The atmosphere system has zero business value. Cheat code Easter eggs won’t show up on a performance review. The collection page serves no strategic purpose.
But it turned a chore into something I’m genuinely proud of.
Every developer dreads rebuilding their portfolio. It’s a task that sits on your todo list for months, maybe years, because the gap between “what I should build” and “what I want to build” feels enormous. The old site was fine. It worked. Updating it felt like filling out paperwork.2I actually started down this path because someone pointed out I hadn’t updated my existing site since 2023 … That’s a lot of neglect for a website I refer to in the footer of literally every email I send.
The rarity mechanic changed the equation. Once I had the idea for weighted backgrounds, I wanted to build each one. The vaporwave grid led to the Möbius strip. The Möbius strip led to the tesseract. The tesseract led to Abyss, which led to Dunes, and suddenly the Mt. Hood silhouette felt like the most important thing I’d ever animated.
Some things you build because they serve a purpose. Some things you build because they make the work more yours.
One more thing: the site scores 100/100 on Mozilla Observatory. CSP header, X-Frame-Options, X-Content-Type-Options, Referrer-Policy, all configured through Cloudflare. Sometimes the simplest approach is also the most secure one.
The code is on GitHub. The site is live. Go visit, check your X-Atmosphere header, and if you got Starfield, try some old-school cheat codes.
You might get lucky.
- 1And there will be more, depending on my level of boredom.
- 2I actually started down this path because someone pointed out I hadn’t updated my existing site since 2023 … That’s a lot of neglect for a website I refer to in the footer of literally every email I send.
