
Asking Someone to Be Your Valentine, the Overengineered Way
12 February 2026
Not every project needs a business case. Sometimes you just want to ask someone a question, and instead of sending a text, you build a tiny website for it. That’s exactly what valentine-fun is. A small, interactive “will you be my Valentine?” page, built mostly because it was more fun than it had any right to be.
The idea
The premise is simple: a single page that asks the question, with a “yes” and a slightly-too-elusive “no” button that dodges the cursor, some AI-generated cat (or dog) illustrations, and just enough polish to feel like a real, deliberate gift rather than a rushed weekend hack, even though it absolutely was a rushed weekend hack.
I kept the stack as light as it could possibly be: Vite for the dev server and bundling, vanilla JavaScript for the interaction logic, and plain CSS3 for the gradients and animations. No framework, no state management library, no build complexity beyond what Vite gives you for free. For a page that exists to be looked at once and then forgotten, reaching for React would have been like renting a moving truck to bring home a bouquet of flowers.
Making it personal without rebuilding it
The part I actually enjoyed designing was the customization. Rather than hardcoding a name or hunting through source files every time I wanted to reuse this for someone else, everything personal is driven by environment variables:
services:
valentine-fun:
image: ghcr.io/maxpoe/valentine-fun:latest
ports:
- "8080:80"
environment:
- VALENTINE_NAME=Partner
- VALENTINE_PET=dog
restart: always
Change VALENTINE_NAME and the question addresses whoever you’re asking. Flip VALENTINE_PET from cat to dog and the whole illustrated theme swaps along with it. That’s the whole configuration surface — two variables, and the entire personality of the site changes. It’s a small thing, but it meant the project stopped being “a page I built once” and became “a page I can hand to a friend for their own Valentine.”
Shipping it like it mattered
Here’s where the overengineering crept back in: I still built and pushed a proper container image to GitHub Container Registry, with a Dockerfile and an entrypoint script that injects those environment variables into the static build at container start. Realistically, this project could have lived as a single HTML file emailed as an attachment. Instead it has a docker-compose.yml, a slim Nginx-based image, and a GitHub Actions workflow that builds and publishes it automatically.
Was that necessary for a page that gets visited once, hopefully says yes, and is never opened again? No. Was it satisfying to docker compose up a Valentine’s proposal like it was a production microservice? Also no — but I did it anyway, and that’s kind of the point of side projects like this one.
Why bother with a “real” project for something this small
Partly because it’s genuinely fun to apply the same discipline — clean structure, reproducible builds, sensible defaults — to something with zero stakes. And partly because these tiny projects are where I actually try new things without worrying about breaking anything important. Vite’s dev experience, a from-scratch CSS animation, a minimal Docker entrypoint pattern — none of it was new to me individually, but stitching it together for something this small and low-pressure is a nice way to keep the muscles warm between “real” work.
If you want to steal the idea for your own Valentine (or just want a lightweight interactive-page template to fork), the repo is right here — clone it, swap in your own name and pet theme, and you’ve got a proposal that took a weekend and somehow also has a Docker image.