One developer. Software that reads as a firm.

One person carries your project from architecture to production — so nothing is lost between the person who heard you and the person who builds it. You get software your clients take seriously, shipped, documented, and owned outright.

How I build.

A buyer can’t inspect code before hiring. You can inspect method. This is mine.

1.0

Every piece of data has an owner.

Before I write code, I decide who is allowed to see what, what runs on a schedule, and what each plan includes — and I put those rules in the system itself, not in a checklist someone has to remember. ConsultBase serves many consultancies from one database, and each one can only ever see its own clients, because the database enforces it, not the screen. Get that shape right first, and every feature after it stops fighting the system it lives in.

In the codePostgres · row-level security on all 60 tables · pg_cron · plan gating at the query layer

ClientVercel EdgePostgres60 tables · RLSpg_cronedgeproxy · auth · regionapiserver actions · validationdbpostgres · RLS · pg_cron

2.0

It looks like one company built it.

A visual system is a set of decisions made once, then kept. Modernizing ConsultBase meant an editorial typeface, a cool palette with gold used rarely enough to mean something, and hairline borders in place of shadows. The unglamorous half is what makes it hold: the same header rebuilt once instead of five times, and a stray value caught in production because the system existed to catch it. Consistency isn’t taste. It’s maintenance.

In the codedesign tokens · one type scale · 137 lines of duplicated header markup → one component

3.0

The data outlives the screen.

Screens get redesigned; the records underneath them have to be right for years. Parenting Plan Pro generates legal documents, where one silently changed sentence is a real-world harm — so the legal wording is stored once, in one place, and the site refuses to publish if a generated document differs from it by a single character. The same instinct runs everywhere at lower stakes: every table locked to its owner, changes that only move forward, and approval states kept in the database rather than in anyone’s memory.

In the codeschema-first · protected-text registry · source-fidelity CI gate · forward-only migrations

plansidpkmatter_idstatusreviewsidpkplan_idfkstateclausesidpkplan_idfkregistry_keyfkprotected_textkeypkstatutechecksum

4.0

Shipped means verified.

Shipping is a checklist, not a feeling. Nothing counts as live until my copy, the repository, and the running site all agree on the exact same version — checked by its fingerprint, not by refreshing and squinting. Database changes land together with the release that expects them, never before, never after. Nothing in the history is ever rewritten, so any past version can be put back. Boring, deliberately. The excitement in a release should be the feature, not the release.

In the codegit rev-parse HEAD = origin/main = vercel --prod · append-only history · migrations paired with the build that expects them

Selected work.

A short list, deliberately. Each of these is production software someone relies on. Read them for consistency of judgment, not variety of logos — and look for the seams: where booking meets calendar, where a document meets the statute it quotes.

The Accession board on the Ashcombe Bequest investigation: the case brief, a two-table schema, the Toolkit keyword panel, the query editor and the answer box.

Stack

Next.js Multi-Zone · DuckDB-Wasm · Monaco Editor · Vercel

Approach

DuckDB runs entirely in the browser, so there is no backend to keep alive and no data to leave the visitor's machine — schema, queries and answer checking all execute locally. Levels come in two kinds: drills check the result set, so the query is the lesson; investigations take a typed answer instead, which frees a hint to explain syntax without giving the finding away and makes a level that needs four queries possible at all. It is served as a Next.js Multi-Zone at vertexapps.dev/sql, so the pages inherit the domain rather than starting a new one, while the WebAssembly stays out of this site's bundle. A companion SQL reference publishes one indexable page per concept with the same live editor embedded.

Accession

A museum records puzzle that teaches SQL. Work the collection, one case at a time.

The True Colors salon home page on desktop: the wordmark over a deep red WebGL satin hero, the salon’s hours and phone number, and a stat band reading nineteen years, seventy-one Google reviews and a 4.5 average.

Stack

One self-contained HTML file · hand-written WebGL shader · JSON-LD · no dependencies · Vercel

Approach

The hero is a fragment shader written by hand rather than a stock video loop — no library, nothing to download but the page itself, and no licence to renew. The whole site is one self-contained HTML file with the photography inlined as data URIs, so it has no build step and no dependency that can break it a year from now. Open and closed are computed from the salon’s own timezone rather than the visitor’s, so a browser in Seattle is told the Bristol answer, and the hours live in one map that the week grid reads from so the two cannot drift apart. A second page recruits stylists for the open stations, which is the other half of a nine-chair business a brochure site would have missed.

True Colors

Nineteen years of word of mouth and no website. A whole salon presence, built from one owner interview.

The Parenting Plan Pro landing page rendered on desktop.

Stack

Next.js · Supabase · react-pdf · Stripe · source-fidelity CI gate

Approach

The plan's legal language lives in a protected-text registry, and the build fails if rendered output drifts from its source by a character. One codebase renders jurisdiction-aware plans across US/Canada, UK, and Australia school-calendar systems. Contested arrangements — supervised visitation, step-up schedules — are gated behind professional mediation, so self-authored legal language never reaches a branded, court-ready PDF.

Parenting Plan Pro

Legal document generation where the text is the product, and protected accordingly.

The Villa L’Estagne booking site rendered on desktop.

Stack

Next.js · Supabase RLS · Resend · no cookies

Approach

Row-level security lets an anonymous visitor write a booking request and read nothing back, so one guest's dates and contact details are never visible to another. Overlapping requests are allowed by design — two parties can hold the same week as on_request and the owner arbitrates from the admin panel. Bilingual FR/EN with French primary. No cookies, no analytics, no payment processing — a direct-booking site without a platform in the middle.

Villa L’Estagne

A booking site for a Mediterranean villa, built to the property’s standard rather than a template’s.

The Civic Strategy Partners site rendered on desktop.

Stack

Next.js App Router · Tailwind · server-side form API · Vercel

Approach

A credibility site for a practice that sells judgment, so the detail work went where a federal buyer actually looks — the footer carries live UEI, CAGE, and NAICS identifiers beside the SDVOSB certification, because that audience verifies before it inquires. Motion is engineered rather than avoided: the gradient wave animates on background-position across an oversized canvas, so it never jumps at the seam. This is the second generation of the site for the same client, staged behind a passphrase gate for review before it took the root domain.

Civic Strategy Partners

Site for a fractional GSA MAS advisory practice, built for an audience that checks your CAGE code.

The Revoix product site rendered on desktop.

Stack

Next.js · prerendered on Vercel · no analytics · no cookies

Approach

Static-feel front-end for a language platform. Backend-free — the served HTML has zero third-party requests, no analytics, no cookies, not even Vercel Insights. Locale routes carry independently linkable metadata (title, description, OG) even though the body copy renders client-side.

Revoix

Product site for an on-device speech and situational-awareness tool used by police and emergency responders. Four languages, zero tracking by design.

The FM24 public site rendered on desktop.

Stack

Next.js · static export · dropped onto legacy Apache

Approach

Static export shipped into infrastructure with no Node runtime — the client hosts on a legacy Apache stack, so the entire built site is prerendered files. Backend-free. Four languages — German, English, Spanish, French — with build-time i18n and browser-language detection. GDPR-conformant cookie consent gate, so reCAPTCHA and embedded video load only after opt-in.

FM24

Multilingual public site for a German security and facility-management software platform, shipped as a static build into the client’s existing server environment.

Lab.

Not client work — demonstrations. Built quickly to answer a specific question: what does capability look like before a contract exists?

The NC Housing Terminal choropleth map zoomed into North Carolina with a ZIP-code tooltip visible.

NC Housing Terminal

A Bloomberg-style housing map of North Carolina: every ZIP code rendered as a live choropleth of Zillow home-value change.

Stack

Mapbox GL · Next.js · static data pipeline · Vercel

Approach

The colour scale is clamped and diverging, so a given red means the same thing in Asheville as it does in Charlotte — unclamped, a single outlier county flattens the rest of the state into noise. Zillow’s raw series is reshaped into ZIP-indexed data by a build-time pipeline, so the map ships static and the browser never waits on an API. Labels are zoom-gated and detail resolves on hover, which keeps several hundred polygons legible rather than crowded.

Designed, built, and deployed in one evening.

More in Labs

Contact.

The best fit is bounded work built with care — portals, internal tools, AI systems, and the businesses that need them done properly. Email is fastest; I reply within one business day.