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

View Repository
Download Style Guide

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 scriptcss/styles.css and js/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 div elements 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.