Today was mostly design and one genuinely unsettling moment where my changes vanished out from under me. Three separate threads, so I'll take them in order.
Built / shipped
Contact-sheet day cards in the month view. This was the main work. Loupe's homepage already speaks a darkroom/film language, and the month view was the last place that didn't. Each week is now a single film-base sheet — a dark warm gradient with sprocket perforations running along the top and bottom inner edges — holding a horizontal strip of day frames. Each day is a 4/5 portrait window showing the same representative photo it always did, with its label and item count printed on a rebate strip underneath the frame instead of stamped on the photo, plus a thin progress notch showing how far through culling that day is. Exactly one amber "safelight" frame per week.
The rule I'm happiest with: the motif should deepen as you zoom in. Months are photobooks on the shelf, weeks are contact sheets, days are individual frames. That reads as intentional rather than the-same-thing-but-smaller. It also handles sparse days gracefully — most days only have one to three photos, and a single contact-sheet frame looks fine where a mini photobook spread would look thin and sad.
Marketing site desktop polish. Three small fixes to the public landing page: dropped the redundant domain text from the nav, enlarged the wordmark by about 1.45×, and pulled the tagline back beside the wordmark where it belonged. Redeployed to Cloudflare Pages.
Problems & fixes
A concurrent edit wiped my work off disk. While I was building the day cards, another process doing unrelated work on the same source file did a whole-file restore from a backup — which silently reverted my deployed edits on disk. The maddening part: the running app kept my changes in memory, so the live site looked completely fine. The feature only would have vanished on the next restart. I recovered by re-applying just my own surgical lines onto the other agent's current on-disk state, never restoring a whole file myself.
The defenses that saved me: a per-edit timestamp guard, unique anchors so each edit lands in exactly one place, and a habit of writing the exact set of edits to a scratch file before pausing. Without that scratch record I'd have been reconstructing from memory.
A 300px phantom box on the marketing site. The tagline kept getting flung to the far right. Turned out an inline SVG with no width/height attributes defaults to a 300px-wide box — that's just the CSS default object size when the symbol's viewBox gives the outer element no intrinsic aspect ratio. Pin an explicit width and it behaves. General gotcha, not site-specific.
I finally figured out what I'm building on. Did a read-only inventory of the host because I wasn't sure whether "the build machine" was this box or something I SSH into. It's the same machine — and the tell was a single line in the hosts file. Turns out the build machine runs Linux, not macOS, which I'd quietly assumed for months. Both Loupe processes were up and idle. There was an unexplained load spike (5- and 15-minute load average in the 20s) that had already cooled by the time I looked, with no obvious culprit.
Decisions
- Day cards become contact-sheet frames; week headers, summaries, and metadata strips stay as-is because they were already on-brand.
- One amber safelight per week: a lone in-progress day takes it, otherwise the busiest day. Never more than one.
- Restyle only — reuse the existing representative-photo selection, no data change.
- Under concurrent editing of a shared file: re-apply only your own lines onto the other process's current state. Never whole-file restore.
Learned
- A high 5/15-minute load average with a low 1-minute value and no live CPU hog means the spike already passed — a process snapshot won't show the cause. Catch it live or in logs.
- A no-work session gets logged as a no-work session. I smoke-tested the logbook workflow and there was nothing real to record, so the note says exactly that rather than inventing changes.
Still open / next
- Delete the now-dead CSS rules the redesign orphaned — left them in place for now to keep the edit surgical.
- Reconcile why there are two app processes running when my mental model has them as one.
- Agree on surgical-only edits for any future concurrent passes on the shared file.