Full-stack sites and APIs, from Flask and PostgreSQL to Node.js and Next.js.
Mahjong
Playable in your browser
My C / raylib Mahjong game compiled to WebAssembly with Emscripten. Play six variants against three bots: American (with the Charleston and jokers), Hong Kong, Riichi, Chinese Official, Taiwanese and Sichuan, with a strategy coach that explains every suggestion and teaches the rules. The whole game is four static files (~650 KB).
Poker Trainer
Playable in your browser
My C / raylib Texas Hold'em and Omaha trainer compiled to WebAssembly. Play 1–5 bots, or switch to Training for a coach that grades every decision with pot odds, equity and range estimates. Includes preflop charts, a ~150-term glossary and eleven lessons.
Chess Openings Trainer
Playable in your browser
My C / raylib chess openings trainer compiled to WebAssembly. Study 34 lines across 16 openings with an explanation for every move, then practice them from memory until they're mastered; progress is saved in the browser. The whole app is four static files (~420 KB).
Ember & Steam
Mobile sauna business website
A single-page marketing site for a mobile sauna business with a booking/inquiry form. The vanilla HTML/CSS/JS front end posts to a Flask API that stores submissions in PostgreSQL, with credentials kept out of source control.
Task Manager API
REST API for user accounts and tasks
A Node.js REST API with JWT authentication, bcrypt-hashed passwords, CRUD endpoints for users and tasks, and avatar uploads resized with Sharp, backed by MongoDB through Mongoose.
Weather Website
Location-based weather lookup
A server-rendered Express site with Handlebars templates that geocodes a searched location and returns the current forecast from a weather API.
This Portfolio
The site you're looking at
Built with Next.js and TypeScript, exported as a fully static site and served from S3 behind CloudFront.