A professional site for a combat sports photographer.
Geoff shoots MMA and Muay Thai across the UK and EU. He needed a site that showed his work at full quality, sold prints at checkout, and let him update everything himself between events — without any SaaS subscription, any CMS to learn, and without waiting on me. The whole project became about making the admin feel easier than email.
From kickoff to live site, including Stripe + Supabase wiring.
CMS subscriptions. Geoff owns the whole stack.
Photographer. Everything from upload to payout runs off his dashboard.



From client call to live site, step by step.
- 01Kickoff call + brief
One call, one page of notes. Pinned down what he sells, how often he updates, what he never wants to touch again.
- 02Sketched the site on paper
Home, services, shop, contact. Four pages, no nav tricks. Got to v1 layout before opening Figma.
- 03Set the visual tone in Figma
Dark background, gold accent, warm cream highlight — tuned around the way his photography actually looks on screen.
- 04Built directly in HTML + CSS
No framework. Every page is a static file — loads instantly, survives any hosting, editable by him.
- 05Wired Supabase + Stripe for the shop
Products in Supabase, checkout via Stripe. Zero dashboard I had to build from scratch.
- 06Purchase notifications + orders dashboard
Stripe webhook flags new orders the moment payment clears — Geoff gets an email, the sidebar shows a badge, and orders filter by status with a mark-as-delivered action.
- 07Automatic photo delivery to buyers
Geoff bulk-uploads the clean web + hi-res files, filenames auto-match to each order line, and the buyer gets an email with a download button. No manual send.
- 08Taught Geoff the admin, then left
15-minute walkthrough. He uploads new prints, fulfils orders, and pulls payout reports without me.
Geoff edits every page, price, and photo himself.
The real deliverable wasn't the public site — it was this admin. Seven sections, one for each thing Geoff actually changes: events he's covering, the home page, about, contact, pricing tiers, orders from the shop, and site settings. Every form writes straight to Supabase; every save is live within seconds. No CMS to subscribe to, nothing for him to install.
Upcoming coverage
Sections Geoff owns: events, home, about, contact, pricing, orders, settings.
Email + password. Everything behind Supabase auth — no admin URL to hide.
Copy changes go live without redeploying the site.
One Stripe webhook, both sides done.
When Stripe confirms payment, two things happen at once: the order lands in Geoff's dashboard with a pending badge, and the buyer gets an email with a download button for the photos they just bought. No copy, no paste, no forwarding files.
1 new pending
Thanks for your order — your photos are ready to download.
Links are gated by your order ID. Keep this email to redownload.
From Stripe’s webhook firing to Geoff’s inbox and the buyer’s receipt.
Clean files are matched to orders by filename — download links generate themselves.
Receipt, line items, and hi-res + web downloads all live in one message.
The right stack is the smallest stack.
Shopify would have given him a dashboard to pay for monthly and a theme to fight with. Next.js would have added a build step I had to debug every time his copy changed. Static HTML + Supabase + Stripe gave us the opposite: no subscription fees, no framework fights, no cold starts — a site he owns, deployed via Vercel, charged per transaction rather than per month.
Client work taught me to remove things.
When the person using the admin isn't an engineer, every extra option is friction. I cut Geoff's admin down to the three tasks he actually does — upload a print, edit a service, pull a payout — and hid everything else.
No framework is sometimes the right framework. Four pages of HTML rendered faster, stayed simpler, and cost him nothing in runtime fees. The job wasn't to build a product — it was to give one person a tool.
The handover is the deliverable. I shipped the site, then spent as much time writing the 15-minute walkthrough as I did on any single page. The walkthrough is what keeps the site shipped.