Results Stars Contact

Field notes

Notes from work that shipped.

Method, written down while it was still fresh. No dates on these — the problems they describe don’t expire, and neither do the answers.

Systems architecture · Hospitality

Fourteen booking channels, one message.

A guest books through one of fourteen channels. Each channel hands over a different shape of data, at a different moment, with a different idea of what a guest is called and which timezone anything happened in. The operator’s job is to send that guest the right message at four points in their stay. Done by hand, it is a few minutes per booking and a low, steady rate of misses — the ones that hurt, because a missed check-in message becomes a phone call at eleven at night.

The wrong fix is a template per channel. Fourteen templates become fifty-six the moment you have four lifecycle points, and every copy change becomes fifty-six edits, which means copy changes stop happening.

Separate what the message says from how the channel wants to receive it, and the fifty-six collapse back to four.

Two layers. The first holds the message itself, written once per lifecycle point, with variables for the things that differ — name, door code, checkout hour. The second holds channel-native delivery: what this particular channel permits, how it wants the payload shaped, whether it strips formatting, what it does with a link. Copy lives in layer one and is edited in one place. Channel quirks live in layer two and are never touched when the wording changes.

The part that quietly matters most is timezone resolution. A send offset defined as “the evening before arrival” has to resolve against the property’s local time, not the server’s and not the guest’s. Get that wrong and roughly one message in twelve arrives at an hour that makes the operator look careless — and because it is only one in twelve, nobody ever catches it as a pattern. They just think the system is unreliable.

Everything above is measurable before and after: minutes per booking, missed-send rate, and the count of guest-initiated “what time is check-in?” messages, which is the number that actually tells you whether the design worked.

Operations · Small business finance

A money path that closes.

Most small operations have the pieces — a payment processor, a bank, an accounting package — and no path between them. Money arrives somewhere, sits, and is moved by somebody remembering to move it. The books are then reconstructed monthly from memory and a bank statement.

A closed path has five links, and every one of them needs a test you can actually run: the customer can pay; the payment reaches the processor; the processor’s balance reaches the bank; the bank feed reaches the books; and the processor’s own transactions reach the books too. That last one is the link people miss, because the money already arrived — but if the processor doesn’t sync, the books show a deposit with no invoice against it, and reconciliation becomes archaeology.

The failure mode to design against is money sitting in the processor. Balances there are easy to forget, and nothing in a processor’s interface encourages you to move them. A daily automatic sweep of the entire balance to the operating account fixes it permanently and takes about four minutes to set up. Leave no cushion; a cushion is just a balance you have decided to forget more slowly.

Set aside tax where the money lands, not where you remember it.

Then the part that saves people from themselves. A redirect rule on the operating account — when funds arrive, a fixed percentage moves instantly to a separate savings account — turns the quarterly tax bill from an event into a non-event. It has to sit on the receiving account rather than on the processor, so that it catches every inbound path including internal transfers. Accounting software cannot do this; it tracks and estimates but does not move money. The bank does it, and it applies to money that has already arrived, which means it cannot be skipped in a bad month.

Total setup for the whole chain is under a day. The reason it is worth documenting is that every link has a silent failure, and a path that is only ninety percent wired is worse than no path at all — it produces books that look complete and aren’t.

Craft · Web

An icon that survives sixteen pixels.

A logo designed at poster size has detail in it. A favicon is sixteen pixels across. Somewhere between those two, detail stops reading as detail and starts reading as dirt — and the usual approach, exporting the real mark at 16px and shipping it, produces a grey smudge in the browser tab that undoes a lot of careful brand work.

The threshold in practice is around forty-eight pixels. Above it, a mark with concentric rings and fine tick marks holds together. Below it, the rings merge, the ticks alias into noise, and the whole thing turns to mud. So the small sizes get a different drawing: the outer ring only, strokes thickened to roughly twice their proportional weight, and the central figure fattened enough to stay legible when it is nine pixels tall. It is not the same mark scaled down. It is a mark designed for the size, which is what typefaces have always done with optical sizing and what icons mostly don’t.

Rendering matters too. Rasterising the simplified vector at each target size — sixteen, thirty-two, forty-eight, sixty-four — and packing all four into a single ICO gives every context the size it actually wants, instead of making the browser downsample and guess. A separate theme-aware SVG handles the modern path, and a 512-pixel PNG covers installed-app contexts.

The share image is the same problem, one order of magnitude larger.

An Open Graph image is 1200×630, and it is the first impression every link to the site makes — in messages, in Slack, in a post. Building it by hand in a design tool means it drifts from the site the moment the site changes. Rendering it from the site’s own markup, with the real typefaces embedded rather than fetched, means it cannot drift and it is correct by construction. Embedding the fonts rather than linking them is the whole trick: a renderer with no network access silently falls back, and the first you learn of it is a share card set in the wrong typeface, which is exactly the sort of small wrongness people notice without being able to name.

Working on something like this

Tell me what’s not working.

Scope and fee are agreed before any work starts.