Sites & landing pages
Self-contained pages with no build step and nothing to break: they open from a folder, load on a bad connection, and survive JavaScript failing with everything still readable.
PartsHTML · CSS · JS · Cloudflare
Services Web & App Design
A website is not a picture of a business. It is the thing somebody uses at a bus stop, on three bars of signal, on a mid-range Android phone — and that is the machine it has to be good on. So it gets built static-first, measured at a true 390 px, and handed over in plain files you could move to another host by copying them. No framework you will be left maintaining, no tracking, no build step nobody but us can run.
PartsHTML · CSS · JS · SvelteKit · WordPress · Cloudflare
§01 What gets built
A brochure site, a store, a platform somebody else edits, and an app that installs on a phone are four different machines. Choosing between them is the first real decision, and it is made before anything is drawn — because each one costs a different amount to keep alive.
Self-contained pages with no build step and nothing to break: they open from a folder, load on a bad connection, and survive JavaScript failing with everything still readable.
PartsHTML · CSS · JS · Cloudflare
A static build behind an edge cache, and a checkout that has been used on a 390 px phone before it was called finished — because that is where the basket is abandoned, not on a desktop.
Partsstatic build · edge cache · payments
For when somebody on your side will genuinely edit the site. Themes written as templates rather than page builders, and plugin work built like a product: licensing that fails politely, a private update channel, and a compatibility matrix.
PartsPHP · REST · semantic versioning · licensing
A booking screen, a tool, an internal system — installed to the home screen straight from the browser, working offline, with no app store, no review queue and nobody taking thirty per cent.
PartsSvelteKit · service worker · Supabase · PostGIS
§02 How the work goes
Nothing here gets approved as a flat picture. From the first round you are looking at an actual page in an actual browser, at the width your visitors use, because that is the only version that tells the truth about a long headline, a slow connection or a thumb.
01 · Map
Not a page list. A list of the people who will arrive, what each of them came to do, and the one thing each page has to make possible.
Most sites are organised the way the organisation is organised, which is of no use to anyone outside it. One recent build had three completely different readers arriving at the same domain — people wanting to give, partner organisations, and certified contractors — and the structure came out of that rather than out of a departmental chart.
This is also where we decide what is not being built. A page nobody has a reason to open is a page somebody has to maintain forever.
02 · Draw
The design round is a real page you can open on your own phone — not an image of a website that behaves perfectly because it cannot behave at all.
Type, colour and spacing are set as a small number of tokens rather than decided per page, so the site stays consistent as it grows and a change to the heading size is one edit rather than forty. Where a site carries two themes — a dark one and a light one, say — both are drawn at the same time, because retrofitting the second is where the contrast bugs come from.
You review it at 390 px and on a desktop, on your own hardware, in the round it was made. A flat mock-up cannot show you what a headline twice as long does to a layout, and that headline will exist by month two.
03 · Build
The page works as HTML. JavaScript makes it nicer; it is never what makes it work at all.
No framework unless the job genuinely needs one — a shop window does not. That decision is worth money for years: every dependency is a maintenance bill, and a site built out of HTML, CSS and a little JavaScript is still readable by any developer in a decade. Where an application really does need state, accounts and live data, that is what SvelteKit and a proper database are for, and then the reasoning is written down.
Content that repeats — products, articles, episodes, staff — is driven from data files, so adding one means adding an entry to a list rather than copying a page and editing it by hand until it drifts. Accessibility is part of the build rather than an audit afterwards: a skip link, visible focus, real 44 px targets, motion that honours the system setting, and forms that still submit when the JavaScript does not load.
04 · Measure
Every page measured at a true 390 px, every internal link crawled, every tap target checked — by a harness, not by scrolling and hoping.
This studio wrote its own measurement tool for a reason: headless browsers silently enforce a window minimum of around 500 px, so a "mobile check" run the obvious way reports a layout that no phone will ever render. Ours drives the browser through its debugging protocol instead, which makes 390 px genuinely 390 px.
What it checks on every page: horizontal overflow, scroll height, tap targets under 44 px, contrast, elements still hidden by an animation that failed, JavaScript exceptions, and whether the fonts actually loaded. On one recent site it crawled 723 internal references and found zero broken — which is a sentence worth being able to say before launch rather than after.
05 · Launch
Uploading is not publishing. The last stage is the one where most of the avoidable damage happens.
Assets are stamped with a content hash, so a returning visitor downloads only what actually changed and a new version can never be half-cached. Cache headers are set deliberately — long and immutable for hashed assets, short for pages — and where a CDN sits in front of the site, the cache is purged and then verified with a plain request, because a cache-busting query string proves the origin is right and nothing about what the public sees.
Then the keys: hosting, DNS, repository, and a written note of which lever does what. Every review round along the way arrives as a dated package — a start-here page, the site itself, documents as PDF and Word rendered from the same source, and a zip — so there is always one obvious thing to open.
§03 The toolkit
The list is short on purpose. Everything here is either plain enough that any developer can maintain it, or present because a specific job genuinely needed it.
| Part | Why it is there |
|---|---|
| HTML, CSS, JS | The default. No build step, no framework to upgrade, no folder of dependencies quietly rotting. A page written this way opens from a folder and will still open in ten years. |
| Data manifests | Repeating content — products, articles, people, episodes — driven from a list that a router turns into pages. Adding one is an entry, not a copied file that drifts out of step by the fourth one. |
| SvelteKit | When the thing is genuinely an application: accounts, live data, state that has to survive a refresh. Chosen for small output and plain components rather than for the name. |
| Supabase / PostgreSQL | A real database with row-level security, so who may read which row is enforced by the database rather than by remembering to check in the code. PostGIS where location matters. |
| Service workers | What makes a web app installable to a home screen and usable without a connection — no app store, no review queue, no percentage of your revenue. |
| WordPress (PHP) | When somebody on your side will really edit the site. Written as templates with one scoped stylesheet each, not assembled in a page builder that only its author can operate. |
| Plugin discipline | Custom behaviour built like a product: semantic versioning, a private update channel, a compatibility matrix across platform versions, and licensing that fails politely rather than destructively. |
| Cloudflare | DNS, TLS, an edge cache and a firewall in front of ordinary hosting you own. Cheap, fast, and reversible — nothing here is a platform you cannot leave. |
| Self-hosted fonts | Faster than a font CDN, and nobody's request log gets a copy of your visitors. Only the weights actually used are shipped. |
| The 390 px harness | Homemade, because headless Chrome enforces a window minimum near 500 px and will report a mobile layout that does not exist. Ours drives the browser over its debugging protocol, so the number is real. |
| git | Every change recorded, every deploy traceable to a commit. A site that cannot be rolled back is a site you are afraid to touch. |
NoteThe reason for each choice goes in writing at the time it is made, so the next person inherits the reasoning, not just the result.
§04 Which machine
This is the decision that costs or saves the most, and it is made in the first week. Three questions settle it:
Plenty of projects end up with two of the three: a static front of house for speed, WordPress behind it for the part somebody updates weekly, one domain over both. That is a design decision, and it gets written down with everything else.
§05 Not a sales page
Six ways web projects fail. We have made most of them at some point, which is why they are on the list.
§06 Straight answers
Only if somebody on your side will genuinely edit the site. WordPress buys you an editor and costs you a database, a login page, an update schedule and a security surface. If the content changes twice a year, a static site is faster, safer and cheaper to keep — and we can still hand you the parts you want to change as plain text files.
Yes, and how you edit it is decided before anything is built rather than after. That might be WordPress, or a set of data files where adding a product or an article means adding an entry to a list rather than copying a page and hoping. Whichever it is, you get written instructions for the parts you will actually touch.
Ordinary hosting you own, usually with Cloudflare in front of it. Everything is plain files in a git repository, so the site can be moved to another host by copying it. There is no platform here that only we can log into, and no monthly fee that exists to keep the lights on.
The parts that are engineering get done as a matter of course: server-rendered HTML rather than an empty page that fills itself in later, one canonical URL, real titles and descriptions per page, structured data, a generated sitemap, sensible headings, and fast loading on a phone. The part that is not engineering — having something worth reading — is what actually decides rankings, and no build technique substitutes for it.
The target is that the page is readable before a visitor decides to leave, on a mid-range Android phone on mobile data — not a perfect score on a test run from a laptop on fibre. In practice that means no framework, self-hosted fonts, images sized for the screen that asked for them, and assets stamped with a content hash so a returning visitor downloads nothing they already have.
Yes. A web app can install to a phone's home screen straight from the browser and keep working without a connection — no app store, no review queue, nobody taking thirty per cent. It is the right answer for booking screens, tools and internal systems. It is the wrong answer if you need deep hardware access, or a store listing because that is where your customers look.
You have the source, the hosting and the documentation, and the site is built out of the plainest parts available — HTML, CSS, JavaScript, and PHP where the platform is WordPress. Any competent developer can pick it up. Building on something exotic is how a studio makes itself hard to replace, and that is a bad reason to choose a tool.
Send the address and what it is failing to do. You will get an honest read on whether it needs rebuilding or just fixing — those are very different bills.
Alsoa community hub and its WordPress twin · a plugin built like a product · AI integration