Lossless Changelog
product

A Client Surface, a Header That Folds, and Two Hundred-Odd Tools Rescued From a Typo

A page for client toolkit recommendations, a quick-access rail so a client sees their own logo first, a header that collapses properly on a phone, and a repositories page built from four spellings of the same frontmatter key — one of them misspelt, and the only way seven tools were reachable at all. Also: a logo that returned HTTP 200 for a week without ever being an image.

Michael StatonMusic Editoraugmented with Claude Code on Claude Opus 5 (1M context)

Changelog — 2026-09-13 (#1)

Why Care?

A catalogue of 1,765 tools is not a recommendation. The work a client pays for is the narrowing — down to the stack they can actually adopt, in the order they can adopt it. This entry builds the first surface that says so out loud, and puts a client's own logo in front of them the moment they land.

It also collects three findings that have nothing to do with each other and one thing in common: a check that passed while the thing it checked was broken. An image that was never an image. A breakpoint that fired long after the layout had already fallen apart. A frontmatter key that seven tools depend on and that nothing was reading, because it is spelled wrong.

What's New?

  • /curious-clients/ — Custom Toolkit recommendations for Curious Clients. The client list, cards, glassmorphic nav and text CTA replicated from the lossless.group index page.

  • A Client Portals quick-access rail — a thin pill under the header, three icons at a time, toggles to walk all eleven. Laerdal leads.

  • The header collapses — below 52rem of header width the wordmark and nav links fold behind a hamburger on the right. The search bar stays.

  • /repositories/ — 155 tools with a public source-code home.

  • Two new hero filters — Open Source Alternatives (62) and GitHub Repositories (155).

The client cards wanted eleven logos. Eleven files were copied across. Every one returned 200. Eleven images rendered as broken glyphs.

$ file appIcon__Laerdal.png
appIcon__Laerdal.png: ASCII text

$ cat appIcon__Laerdal.png
version https://git-lfs.github.com/spec/v1
oid sha256:b69a97bd91b358677d94bed5a3b3a54e830766c55758493df1be97ce6ccba290
size 37508

Seven of the eleven are git-lfs pointer files — 130 bytes of ASCII naming an object that was never fetched. A web server returns them with a 200 and a Content-Type of image/png, because the extension says so and nothing checks. [[2026-09-12_01]] was written the previous day about precisely this — asserting on a status code instead of on a body — and the verification pass here walked straight into it and reported eleven working logos.

The recovery was not to fetch the LFS objects. git lfs is not installed for the source repo and its object cache is empty, so that would mean changing another repo's configuration. The real vectors were already on disk: trademark__Laerdal.svg, 24,651 bytes of actual SVG. It was rendered and looked at before being wired in — the only check in this whole entry that could not have produced a false pass.

A square app icon came out of the same file. The lockup is a roundel plus a wordmark in a 0 0 141 56 viewBox; cropping the viewBox to its leading 56×56 square yields the roundel alone. Same artwork, narrower window, nothing resampled:

viewBox="0 0 141 56"   ->   [◉ Laerdal helping save lives]
viewBox="0 0 56 56"    ->   [◉]

The rail now validates every icon on disk at build time — anything under 512 bytes is a pointer, and falls back to a monogram tile. When those LFS objects are eventually fetched the real icons appear with no code change. The fallback has a second virtue nobody planned: these are stealth cards, and BE is a good deal quieter than a client's trademark.

The header, and a breakpoint that measured the wrong thing

The pattern is mpstaton-site's, not twf_site's. TWF's is the better-known implementation but it is Tailwind (hidden md:flex / md:hidden) and this site has no Tailwind. What carried across was the reasoning, all of it load-bearing:

DecisionWhy
One nav, restyledA second copy per breakpoint is a second place to forget a link, and puts every href in the a11y tree twice
aria-expanded drives the icon swap in CSSThe attribute is already the source of truth for assistive tech; a second state would need syncing
Panel is position: absoluteAn in-flow panel shoves the page down as it opens — reads as the layout breaking, not as a menu appearing
display: none when shutLinks must leave the tab order. A hidden-but-focusable menu is worse than an unanimated one

Built on a container query rather than a media query — container-type: inline-size on .site-head__inner — so the rule travels with the component instead of with the viewport.

The first threshold was wrong, and the sweep that "verified" it did not look. 46rem was picked because it matches the house's 767px convention. It collapsed correctly at 430px and at 1280px, which is what got checked. In between, at ~800px, the nav had already wrapped to a second row and the header had grown to two lines — broken for a whole band of tablet widths that the two-point check flew straight over.

viewport   container   hamburger   state
  900        860px       no        fine, one row
  860        820px       no        tight, one row
  800        760px       no        WRAPPED — two rows, broken
  776        736px      yes        collapsed
  430        390px      yes        collapsed

The breakpoint is the width at which everything still fits on one row, not the width at which it becomes unreadable. Now 52rem, which collapses at ~860px viewport, before the wrap.

Two follow-ons fell out of fixing it:

The JS no longer knows the number. It used to hold 46 * rootFontSize as a second copy, which is a guaranteed drift — this codebase has a whole entry about a fact with four copies and nothing reconciling them. The observer now asks the CSS instead: if the toggle has computed display: none, the panel closes. No breakpoint in JavaScript at all.

The hamburger moved right. It was on the left, where the wordmark it replaces used to be. That is where the source order put it and it is not where anyone looks for it — a hamburger is a right-hand affordance by convention and by thumb reach. Flex order, not a second markup shape.

An older rule had to be reconciled on the way: Base.astro carried a @media (max-width: 860px) that set the search bar to order: 3 and a full-width second row. With the nav now folding there is room for one line — and the old rule was actively fighting it, re-sorting search behind the theme toggle so the mobile row read hamburger, moon, search.

Four spellings of one key, and the one that is wrong

The catalogue records where a tool's source lives. It does so in four different frontmatter keys:

github_repo_url      116   the project
github_url            15   the project, older spelling
github_profile_url    36   the org or user account
github_profle_url     10   <- the same key, misspelt
repo_url               1   Launchpad, not GitHub, still source

github_profle_url is not a variant. It is a typo. And seven tools carry no other spelling, so a resolver that reads only the three correct keys drops Inkscape, DoltHub, Crawlbase, Gemini, DeepReinforce, LM Studio and Zep on the floor without a word.

This is the tag-casing disease from [[2026-09-08_01]] (Check-It-Out 256 vs Check-it-Out 2) in a dimension nobody had checked. The lesson generalises one step further than it was written: assume any hand-maintained key in this corpus has a misspelt twin, not just any hand-maintained value.

pickRepo() reads all four in precedence order — the project beats the org that owns it — and files a Misspelled repo key anomaly when it falls through to the typo. The entry is served, and the vault gets told. Fix the key upstream and the note disappears on the next sync; nothing in the code needs to change either way.

Two filters, one of which is not a tag

Open-Source-Alternatives turned out to be clean — 62 tools, a single spelling, a working page already. The raw grep looks alarming (304 open-source, 147 Open Source, 93 open source) but that is body prose; the tag dimension itself is tidy. It needed nothing but a line in the hero.

GitHub Repositories is the interesting one, because "has a public repo" is not a tag and could never be one. It is true of 155 tools spread across every tag in the corpus, it is a property of the entry rather than a judgement someone applied to it, and no amount of tag hygiene would express it.

So the hero's featured row grew a second kind. Tag filters look themselves up by slug against live facets; route filters point at a page and count themselves the same way. Both stay honest for the same reason:

AI Toolkit                514   /tags/ai-toolkit/
Agentic AI                128   /tags/agentic-ai/
Open Source Alternatives   62   /tags/open-source-alternatives/
Founder Toolkit            81   /tags/founder-toolkit/
Must Have                  47   /tags/must-have/
Check It Out              258   /tags/check-it-out/
GitHub Repositories       155   /repositories/

Not one of those numbers is typed in. A content sync cannot make them stale, and a tag that leaves the corpus drops out of the row rather than rendering a dead link.

On client data

The replicated component is the stealth variant — the one that ships on the lossless.group index page, rendering codenames rather than client names. Since this site has a tested rule that client curation never reaches built output, the exclusion is enforced a layer earlier than the source does it: src/data/clients.json carries only the six fields the card reads. Real names, websites, descriptions and all eleven access passcodes were dropped at the copy, so they are not in this repo at all and cannot leak from a field someone renders by mistake.

Worth stating plainly, because it is inherited rather than introduced: the source pairs every codename with the client's real logo, so a card reading "Mission to Save Lives" carries an unmistakable Laerdal mark. If the codename is meant to withhold the client, the logo undoes it.

On verification, again

Every defect in this entry passed something:

  • the LFS pointers passed curl with a 200

  • the 46rem breakpoint passed a check at 430px and at 1280px

  • the misspelt key passed pnpm build — nothing errors on a field nobody reads

  • and twice, grep -c reported 2 occurrences of a string that appeared eight times, because it counts lines and this HTML is one long line. Both times a false negative was reported before being caught.

The browser drives that did the real work here were ad-hoc, written and deleted in place. They should not be. The click-paths are known and have earned a file.

What's next

  • Wire the remaining logos: Hypernova and Param have usable vectors on disk; Tonguc, Colearn, Reach and HUMAIN need git lfs install in the source repo.

  • /client/<id>/ does not exist — every portal link in the rail is a 404 today.

  • Promote the ad-hoc drives into tests/, resolving their target port from the server log rather than assuming it.

  • [[2026-09-12_01]] — the hero grid, and the status-code lesson this entry re-learned

  • [[2026-09-08_01]] — the full corpus, and the casing drift this extends to keys