Hermes-built • SVG + GSAP demo • self-hosted on your VPS
GPT Bloom
I switched to a flat-logo-first approach because the real mark is a designed 2D symbol, not something that naturally falls out of stacked circles.
This version now uses a real flat ChatGPT symbol reference as the source shape, draws it on as you scroll, and then lets you tilt the whole mark gently with your pointer.
What you're seeing: a flatter, more logo-first interpretation built from an actual symbol reference,
with a scroll-triggered path draw first, then gentle tilt and shadow response so the mark stays readable instead of turning into a noisy 3D object.
Interaction
Scroll to draw the mark and let it settle into place, then move the pointer to tilt it. The symbol stays readable and mostly still, then responds as one piece when you interact.
Reference shape first, then motion — not circles pretending to be the logo.
How it was built
Under the hood
The hero no longer tries to fake the logo out of torus loops or repeated petal approximations. Instead, it uses a real flat symbol path with one shared transform layer. The interaction starts with a scroll-driven stroke draw and settle-in scale, then hands off to tilt, parallax, and shadow response.
The key trick is to separate symbol fidelity from motion design: start with a flat mark that already reads correctly, reveal it with a lightweight stroke animation, let it settle into the frame, and only then animate the whole mark lightly instead of inventing the geometry from scratch.
That way it still feels responsive, but it reads more clearly as an intentional symbol. And because it is just HTML, inline SVG, local GSAP, CSS, and a little JavaScript, it stays easy to keep tweaking without a build chain.
// Scroll reveals the path, settles the mark, then pointer tilt takes over
const progress = clamp(window.scrollY / maxScroll, 0, 1);
stroke.style.strokeDashoffset = totalLength * (1 - progress);
gsap.to(mark, { scale: 0.88 + progress * 0.12, y: 28 - progress * 28, duration: 0.18 });
gsap.to(mark, { rotateX: pointerY * -8, rotateY: pointerX * 10, rotateZ: pointerX * 2.5, duration: 0.45 });
I also kept the camera and particle count modest so the page should perform comfortably on ordinary devices while still looking polished on a desktop screen.
Why this hosting setup works
Built for your VPS instead of an expiring agent host
This page is the durable version of the idea you mentioned earlier. Rather than publishing to a temporary agent-hosted site, the files live on your own VPS and are served by your existing Caddy stack under demo.ourhomelab.site.
Static files
The site content lives in /srv/pages/demo, which fits the static site pattern you're already using for other pages on this server.
Caddy routing
A dedicated vhost block points the hostname at that directory and serves the page with normal file_server behavior.
So yes — this is absolutely doable here, and it is a better long-lived fit than a one-day showcase platform when you want a real URL you can keep around.