One of those days that fans out instead of going deep on one thing. The surface got a new look and a header that finally behaves at every width; underneath, I spent most of the real thinking on data plumbing — how my edited photos should come down, why six of them weren't matching up, and where my project notes should live. Writing it all down so I remember what actually moved.
Built / shipped
A "liquid glass" redesign, shipped dark. I had a new visual treatment for the whole app — glassy chrome, a warm backlit light-table for the photo grids, cream-mounted slides. Rather than rip out the existing "darkroom" look, I appended the whole thing as a dormant layer that only switches on when a single class is set on the page. Look on, look off, instant A/B, no risk. I gave the marketing site the same treatment but left it committed-and-not-deployed: a public page has no hidden A/B toggle, so going live there is a separate, deliberate call.
The header, finally responsive at every width. This ate a lot of the day. The persistent top header — brand on the left, nav centered, a little stats box on the right — needed to hold one clean row when wide and degrade gracefully as the window narrows. I landed three layout bands: wide keeps the rigid one-row layout, a middle "fold zone" drops the stats into a flat strip under the nav, and mobile becomes a centered wrapping stack. Verified the whole thing headless across a 720→1920 sweep.
Polish on the single-photo view. Moved the viewing controls out into the photo corners so the bottom bar holds only the cull decisions, and quieted a score badge that had been loudly wearing the wrong styling.
Problems & fixes
- The stats box kept getting crushed at the in-between widths. Wide was fine, narrow was fine, but somewhere in the middle the box collapsed below its own text and the numbers spilled past the border. The fix was to give it a hard floor (never shrink below its widest stat) and a safety valve to drop to its own row instead of clipping. The real lesson: a flex item decides whether to wrap based on its natural size, not its squeezed size — so you can't get "shrink a bit, then wrap." It either shrinks or it wraps. Pick one and tune the threshold.
- My headless tests were lying to me for about ten iterations. The cache-busting token on the CSS file is computed once when the app boots, so after editing the stylesheet without redeploying, the browser kept serving the old cached copy. I was debugging a layout that no longer existed. Once I forced the headless browser to disable its cache, the real behavior showed up immediately.
- A score badge that wasn't unstyled — it was wrongly styled. A tiny generic class name was reused for two unrelated things, so the badge silently inherited a cream pill meant for something else entirely. And it was printing "23th" instead of "23rd" because the ordinal helper was out of scope. Both small, both the kind of thing that nags.
- The mobile brand was shoved off the right edge. One root cause behind two symptoms: a desktop no-wrap setting was leaking into the mobile nav. Let the nav wrap and both the clipping and the off-center brand fixed themselves.
Decisions
- The faithful-library principle. My photo library on disk is originals only — every edit I've ever made (crops, trims, portrait blur) still lives only in the cloud, so the app currently shows me pre-edit frames. Going forward the rule is: a faithful pull keeps both the original and the edited version, mirroring exactly what's stored upstream. Originals-only is allowed only as an explicit, labeled choice, never the silent default.
- Augment, don't re-pull. To get those edits, I'll pull only the edited renders and pair each to its existing original — not re-download the whole ~2TB library. Cheaper, and safer: my cull decisions are keyed to file paths, so leaving the originals exactly where they are keeps every keep/cut/vault decision intact. Hard rule: the augment must not rename or move anything that already exists.
- The download rides my Mac's already-signed-in session. Worked out the mechanism for pulling photos down through a Mac that already has the library, with no extra credential handling on my side. Validated it on a small test album and learned the hard way that one tempting shortcut silently wrote tiny broken stub files for videos while reporting success — a size check caught it.
Learned
- Apple stores an edit as a whole second rendered file, not a recipe. The little sidecar is just the edit instructions; the actual edited image is a complete separate asset living alongside the untouched original. The default download tool only grabs originals, which is exactly why my library came down edit-free.
- Six photos weren't pairing — and the cause was a filename suffix, not what I assumed. I went in convinced I needed to add date-awareness to the matcher to split recycled filenames. Wrong on two counts: the matcher already uses the date, and the six were just videos renamed on disk with a
-<filesize>suffix to dodge a name collision. The clean filename never matched the suffixed one. Strip the suffix (the digits are the size key) and five of six resolve instantly. The sixth is a genuine duplicate import — same bytes added twice — that no key can split, and I'm choosing to accept that. - You can do real layout measurement headless with zero dependencies — drive the browser you already have over its debug protocol and read element geometry directly, far more reliable than screenshotting one width at a time.
Housekeeping
- Moved my project notes vault to live alongside the app instead of the pipeline. The trick was doing it without triggering a full re-sync to my other machine — pause the sync, do a same-disk move that preserves the folder's identity, repoint it through the API, unpause. It re-indexed in place instead of re-downloading. Took a full backup first, of course.
- Compacted the decision and learning logs. They'd grown past the point where reading them whole was wasteful, so I built a snapshot-first compaction routine and ran it: collapsed ~30 sprawling entries into 10 tidy ones, dropped what was superseded, and promoted the durable principles up top. Snapshots taken and verified before anything got rewritten.
Still open / next
- The glass redesign is an unmerged A/B branch — whether it replaces the darkroom look or stays a toggle is a call for after I live with it in a real browser for a bit.
- The header needs my in-browser pass on an actual phone; headless says it's centered but I want to see it.
- The photo-pairing fix is root-caused but not yet built — strip the suffix, rebuild the bridge, re-run the cross-check, and only then wire up the edited-render augmentation itself.
- And there's a thread I ran a security review on and tightened up. Connecting to a personal photo library is exactly the kind of thing where I'd rather be quiet about the internals than clever about them in public — so that's all I'll say. It's only ever reachable on my home network, and I'm treating the whole area with extra care.