Lucca Prada's personal portfolio site. Hand-written HTML, CSS, and JavaScript - no framework, no build step, no dependencies.
Live: https://luccahp1.github.io/portfolio/
The concept: a site that remembers you. Everything it knows lives in the visitor's own localStorage; there is no backend and no analytics.
- Adaptive memory - greets you differently by time of day, visit count, and how long you've been away. Footer keeps a running relationship ("you first showed up 3 weeks ago · visit #6").
- The ghost - the site records your cursor locally and replays it on your next visit as a translucent ghost labeled "you, 2 days ago". First-time visitors get Lucca's own recorded wander instead.
- Pencil mode (
d) - draw anywhere on the page. Doodles persist across visits, adapt to the theme,zundoes,xclears. - Terminal (
/) -help,whoami,cat secrets.txt,open outpace,sudo hire lucca, and a permanent record for anyone who triesrm -rf. Newer toys:race(a checkered-flag countdown that restarts the speedrun clock, then greets the finish with confetti, your time, and your saved highscore) andphysics(live sliders for the lamp cord's rope simulation - deliberately never persisted, so no slider session can outlive a reload). - Blueprint mode (Konami code) - exposes the site's construction lines and margin annotations. Every box confesses its pixel dimensions, and whatever you hover gets measured live.
- Print = résumé -
Ctrl+Pswaps the whole site for the real, professional one-page résumé (also atresume.html). - The lamp cord - dark mode is a pull-cord in the top right, with a tiny click. It's a simulated rope (Verlet chain under gravity, with spring constraints and damping): grab it and pull in any direction - it stretches, and past enough tension the switch gives. Swiping through it shoves whichever part you graze. The physics only runs while your mouse is near it. And if you ignore the warning and keep yanking, it snaps: sparks, a long and very visible lights-out flicker, a small glass-pop sound, and a taped-up repair nine seconds later. Snap it a second time and the repairs stop being nice: the cord gets duct-taped into scenery and a real wall switch gets drilled in beside it. The terminal's
rewirecommand earns the string back. - The tape - grab the tape holding any project card and pull. The card falls, and a very small "lucca" cursor arrives to pin it back with a real thumbtack (cropped from a vector pack) - a different pin, spot, and angle every time. The pinned note hangs crooked with a curled, shadowed corner. He is not thrilled.
- The vouch card - the guestbook, grown up. A popup form (name, email, optional company) that drafts the email in the visitor's own mail app; confirmed vouches get hand-typed into the HTML. The "role" question only exists if they type a company - friends and family never see it.
- Toasts happen at the scene - popups appear near whatever triggered them (the lamp's complaints at the lamp, the tape scolding on the note), as slanted handwriting on a translucent paper slip so they read over anything. Happy little mistakes, per Bob Ross.
- The spoilers - a footer button that reveals every secret and how to trigger it. Hand-maintained.
- It learns your name -
call me maplein the terminal; greetings use it from then on. - Small acknowledgments (each once, politely): copy/select-all/idle toasts, a speedrun footer ending with your official time, your saved best time, and paper-scrap confetti (trackpad scrollers get a fairer window), seasonal margin notes, an "eavestroughs" hover tooltip, a "prada" hover tooltip that has heard your handbag joke already, steam that rises off the coffee note when you hover it, escalating Konami snark, three pencil inks (
c), a favicon that naps when you leave the tab, and a birthday greeting on July 2. - Console API (
lucca.ghost(),lucca.secrets(),lucca.forget(), …), tab title that misses you, humans.txt, custom 404, a view-source banner.
It's static. Serve the folder with anything:
npx http-server . -p 4173
Or just open index.html.
Any static host works: nginx on luccaserver, GitHub Pages, Netlify. 404.html is self-contained for host-level error routing.
- Copy lives directly in
index.html(lowercase on purpose - printing swaps in the hidden.print-resumeblock, which has proper capitals). - Résumé: edit the
.print-resumeblock inindex.htmlandresume.htmltogether; the full version with phone number lives outside the repo inC:\Bin\Resume\2026\. - Guestbook entries: add
<li>items in the#guestbooksection, by hand. That's the system. - Site birthday / changelog:
BORNinjs/main.js,CHANGELOGinjs/terminal.js.