Day 3: Shipping Craft
Craft is live. What started as a prompt about non-billable time and designer growth ended up as a fully functional, deployed web app – built in a single HTML file with no framework, no dependencies, and no backend.
What Was Built
Craft is a single-file HTML/CSS/JS application. Everything – structure, styles, and behavior – lives in one file. There’s no login required for end users browsing the learning buckets, but a password-protected admin panel is accessible via the ?admin route for anyone managing content. It’s the kind of architecture that’s easy to dismiss until you ship something with it, and then it makes a lot of sense.
The CMS is backed by localStorage – full CRUD on buckets and resources, plus JSON export and import for portability. If the browser goes away, the data can travel. The deploy pipeline runs through GitHub and Vercel: push to main, live in 20 seconds.
Key Decisions
Visual language first. The app was styled to match Midwestern’s internal brand from the start – light mode, DM Sans, lime accent color, hairline grid dividers. It doesn’t feel like a side project. It feels like it belongs.
No dependencies. Vanilla JS, no build step, no package manager. The constraint forced clarity. Every interaction had to be written deliberately rather than abstracted away by a library.
Admin without a backend. The ?admin route pattern is a clean solution for low-stakes content management. It keeps the file portable while still giving a non-technical user a surface to work with.
Iterations
The shipped version went through several meaningful passes before it felt right:
- Typography and spacing – swapped to DM Sans, ran a border radius audit, and opened up spacing throughout for more breathing room
- Light mode restyle – full visual overhaul from the initial dark treatment to a light mode that matches midwestern.com, including the lavender-gray background, white card surfaces, and lime highlight treatment
- Responsive stat row – used
clamp()to prevent overflow at narrow viewports without breaking the layout at wider sizes - Modal bug fix – the save callback was wired to the wrong slot, causing the modal to close without persisting changes; caught and fixed
- Ghost card – the placeholder for future team-defined buckets is preserved in the code but commented out and hidden from the UI, ready to surface when needed
- Logo integration – walked through the full GitHub → Vercel pipeline for swapping in a custom logo asset
- Nav layout – corrected to true
space-betweenwith the logo as a direct flex child, fixing an alignment issue at certain breakpoints
Stack
HTML · CSS · Vanilla JS · localStorage · GitHub · Vercel
What I Learned
Constraints are a feature. Deciding early that this would be a single file with no dependencies removed entire categories of decisions – no framework debates, no build configuration, no dependency management. The work stayed focused on the product. There’s a version of design tooling that lives entirely in that space, and it’s more capable than it looks.