My homepage hero used to be plain: name, a typewriter role line, a small mascot illustration, three buttons. It worked fine. Then I saw a tutorial by Metics Media on building "cinematic" scroll-scrubbed hero videos — the kind where a short clip plays frame by frame as you scroll, instead of autoplaying — and wanted to try it on something real instead of a throwaway demo. My own site was the obvious target.
Deciding the scope before touching anything
The tempting version of this project is "redesign the whole site." I didn't do that. Three decisions up front kept it from turning into a rebuild:
- Homepage hero only. About, Experience, Work, and Notes stayed exactly as they were.
- Keep the existing host. The tutorial's workflow assumed Hostinger; my site already runs on Vercel with a working deploy pipeline. No reason to migrate hosting just to match a tutorial.
- Branch and preview before touching the live site. Every change went through a feature branch and a Vercel preview URL first.
Getting the robot wrong, then wrong again
The first generated frame was a generic glowing robot — fine on its own, but it wasn't my mascot. My actual site icon has a specific face: a rectangular head, a circle-eye on one side and an X-eye on the other, a zigzag antenna. The AI had no way to know that from a vague prompt, so I had to go pull the real SVG, look at it properly, and describe it back with the exact details — round bumps, the red accent stripe, the antenna shape. The second attempt matched.
The video itself took three tries. The first pass had the robot assemble from drifting particles, which looked fine but boring. I asked for something more dramatic — panels slamming into place with impact flashes — and changed the story order too: start from a bare wireframe skeleton, then have the casing snap on, instead of particles vaguely gathering. That version nailed the motion but the ending didn't resolve: the head sat tilted, slightly detached from the body, like the assembly froze at 90%. A hero's last frame becomes part of the page's permanent layout, so an unfinished ending isn't a small thing. The fix was a third generation with the prompt explicitly forcing a level, centered, fully-solid final frame — which is also where the eyes drifted into two matching ovals instead of the circle-and-X shape. Small tradeoff, left in; three generations was enough iteration for a decorative hero.
The bug that almost shipped silently
After merging the hero to a branch and pushing it, I noticed the video was never
actually in the repository. My .gitignore had a blanket
*.mp4 rule from some old template, so every commit quietly dropped the
hero video while reporting success. The fix was a one-line force-add, but it's the kind
of failure that's invisible until someone opens the deployed page and the hero is just...
missing.
Making it feel like mine, not the tutorial's
Once the video worked, I kept finding small things that read as "generic AI build" instead of "my site." The nav still showed my old cartoon avatar icon right next to the new robot — two different mascots competing for attention in the same five seconds. I swapped it for a plain text wordmark, "JS.", and matched the favicon to it so the whole identity agreed with itself.
The audit that caught what my eyes didn't
I eyeballed the hero text over the video twice and it looked readable both times. Then I ran an actual contrast measurement — hide the text, screenshot the composited frame, sample the brightest pixel under where each line sits, compute the contrast ratio against the text color. Two lines failed outright: the accent-blue role text and the muted subtext scored 1.5–1.6:1 against a required 3.5:1. They were colors tuned for the site's plain dark background, not for sitting on top of a brighter video frame. "Looks fine" and "measurably passes" turned out to be different claims.
name : worst-pixel contrast = 4.42:1 [PASS]
role : worst-pixel contrast = 1.54:1 [FAIL]
sub : worst-pixel contrast = 1.60:1 [FAIL]
btn : worst-pixel contrast = 5.58:1 [PASS]
The fix was a darker, full-coverage backdrop panel behind the text instead of a radial fade that thinned out toward the edges where the text actually sat. Re-measured after: 4.1–4.3:1 on the lines that failed.
Cutting the parts that only looked impressive
The hero was originally four screen-heights of scroll (400vh) — the tutorial's default for a dedicated landing page. I simulated a normal scroll session: wheel steps of 120px, counted how many it took to clear the hero. Fourteen. For a portfolio where a recruiter wants to reach the actual content fast, that's too slow. I cut it to 230vh — about six flicks — and kept the same video, same motion, just a tighter scroll-to-video mapping.
Mobile never sees the video at all, by design: phones, portrait tablets, short landscape screens, and anyone with "reduce motion" turned on get a static composed image instead — no video request is ever made for them. That's not a fallback apology, it's the plan: most visitors to a portfolio site are on a phone, and a six-second robot animation isn't worth their data.
The unglamorous pass after the fun part was done
The hero itself took maybe a third of the actual work. The rest was boring, necessary housekeeping that doesn't show up in a before/after screenshot:
- Re-encoded the video at a slightly harder compression setting — 4.3MB down to 2.8MB, visually identical, because busy particle footage hides compression artifacts well.
- Deleted three image files nobody referenced anymore, after actually grepping the whole repo first to be sure nothing linked to them.
- Recompressed a 181KB avatar photo that was only ever displayed at 96px down to 13.5KB with no visible quality loss.
- Added a
robots.txtandsitemap.xml— the site had never had either. - Added canonical tags, a Person schema block, an apple-touch-icon, and basic security headers (X-Frame-Options, nosniff, a referrer policy) that also hadn't existed before.
What I'd tell myself starting over
- Feed the AI the real asset, not a description of it. "A robot mascot" and "this exact SVG, here are its five distinguishing features" produce very different results.
- An ending frame is a design decision, not a detail — it becomes part of the page's permanent layout the moment scrolling stops.
- Measure legibility; don't eyeball it. I was wrong twice in a row about text being readable, by a wide margin, until I actually measured it.
- The flashy generation step is maybe a third of a real redesign. The rest is scope discipline, compression, cleanup, and the SEO basics nobody notices until they're missing.
PS: the old mascot icon didn't disappear — it still shows up normally further down the page, in the About section. The hero just isn't the place for two different characters at once anymore.