Micro-Product Story
THIS SITE
How This Portfolio Was Built
At a Glance
| Role | Solo Designer + AI-Directed Developer |
|---|---|
| Timeline | July–August 2026 |
| Stack | HTML5 · CSS · Vanilla JavaScript · Git · Vercel |
| Tools | Claude · Claude Code |
| Key Outcomes | Full portfolio site designed and shipped in a single focused effort · Zero frameworks, zero build step, zero dependencies · Light/dark theme system with no flash · Accessible, responsive from day one · Live at myuxd.work |
Overview
This portfolio documents work that spans different eras and methods — enterprise UX leadership, early-stage product strategy, and more recent AI-directed development. The site itself belongs to that last category: every page was built using the same workflow described in the newer product stories, with Claude Code handling implementation while design decisions, architecture, and verification stayed with me.
The goal was a site that felt like a product, not a resume dressed up as a website.
Project Materials
Constraints
A portfolio is primarily a content-delivery product — it doesn't need application-scale state, routing, or framework abstraction. That made the stack choice straightforward before a single line of code was written.
- Vanilla only — no React, no Vue, no build step, no npm. If it couldn't be done in HTML, CSS, and vanilla JS, it wasn't done.
-
One stylesheet, one script —
css/styles.cssandjs/main.js. Design tokens and component styling are centralized in the stylesheet; shared interaction behavior lives in the script. -
No third-party image services — placeholder frames
are styled
divelements with descriptive labels. No Unsplash, no Picsum, no external dependencies that could break. - Content first — the design system exists to serve the writing, not compete with it. Every visual decision was evaluated against whether it helped or distracted from the work being presented.
Key Decisions
Design token architecture
Every color, type size, and spacing value lives as a CSS custom
property. Light and dark mode are two token sets —
[data-theme="light"] and [data-theme="dark"] —
toggled by a single attribute on the html element. A
pre-paint inline script reads localStorage before the first
render, eliminating theme flash entirely on reload.
Scroll animation without libraries
All scroll-triggered animations use the Intersection Observer API — no
GSAP, no AOS, no dependencies. Fade-up on entry, staggered delays on
card grids, hero content sequenced on load. A single
prefers-reduced-motion media query disables all of it for
users who need that. The entire animation system is approximately 40
lines of vanilla JS.
Placeholder system
Every image placeholder is a styled div with a specific
descriptive label — not a generic gray box. The labels document intent:
what image belongs there, what it should show, and why it's placed where
it is. This turned placeholder management from a liability into a
reference system for the image integration phase.
Deployment
GitHub to Vercel. Push to main, site deploys. No build step
means no framework configuration or dependency chain to maintain. The
deploy stays as simple as the stack.
Reflections
Building the portfolio this way made the positioning argument concrete rather than claimed. There's a meaningful difference between writing "I close the gap between design decisions and working software" and having a site at a custom domain that proves it.
The vanilla constraint also made certain decisions explicit rather than inherited from a framework. There's no state management library, so state is managed deliberately. There's no router, so navigation stays simple. There's no component library, so reusable patterns had to be defined intentionally rather than inherited.
Working within real constraints tends to produce clearer decisions than working without them. That held here as much as it did on any of the product stories on this site.