fix(nav): the shared chrome shipped two defects no consumer could fix - #8
Merged
Conversation
A shared renderer is the one place where a mistake is not one bug in one repo but the same bug on every site that installs it — and unfixable downstream, because a consumer cannot patch markup it does not own. Two shipped: 1. Nav links were `px-2 py-1` on `text-xs`, roughly a 28px target. That is a fiddly thing to hit on a phone and below the 44px floor the rest of the fleet holds (fleetcrown enforces it centrally; kivvi and wild-spirit meet it explicitly). Now `inline-flex min-h-11 items-center`. 2. The package defined no focus style at all. A consumer's CSS reset can remove the user-agent ring, and nothing here replaced it, so keyboard users could lose their visible position in the nav on every site that installs this. Both the nav links and the wordmark now carry `focus-visible:outline-2 outline-offset-2 outline-accent` — a semantic class, so it stays the consumer's colour, per this package's no-tokens rule. The masthead does NOT get taller. Its own comment warns that wrapping the nav "makes a sticky masthead eat a third of a phone screen", so the row pays for the bigger targets out of its own padding: py-4 becomes py-2, and 44px items land the header at the height it already had. Five rendered tests, asserting markup rather than source and importing by package name so a broken exports map fails here rather than in a consumer. Four fail against the previous renderers; the fifth covers `aria-current`, which already worked and is guarded so a refactor of these classes cannot quietly drop it. Both live consumers inherit this: substrata (v0.1.1) and camille-boulangerie (v0.2.0) are also version-drifted from each other, so both move to v0.3.0. Found by a fleet-wide navigation audit across 20 repos, where this was the only defect that multiplies. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XeELB8b3N4JrT2asYL9WvE
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A shared renderer is the one place where a mistake is not one bug in one repo but the same bug on every site that installs it — and unfixable downstream, because a consumer cannot patch markup it does not own. Two shipped.
The defects
1. Nav links were ~28px targets.
px-2 py-1ontext-xsis a fiddly thing to hit on a phone, and below the 44px floor the rest of the fleet holds (fleetcrown enforces it centrally via a@media (pointer: coarse)block; kivvi and wild-spirit set it explicitly). Nowinline-flex min-h-11 items-center.2. The package defined no focus style at all. A consumer's CSS reset can remove the user-agent ring, and nothing here replaced it — so keyboard users could lose their visible position in the nav on every site that installs this. Both the nav links and the wordmark now carry
focus-visible:outline-2 outline-offset-2 outline-accent, a semantic class so the colour stays the consumer's, per this package's no-tokens rule.The masthead does not get taller
Its own comment warns that wrapping the nav "makes a sticky masthead eat a third of a phone screen." So the row pays for the bigger targets out of its own padding:
py-4→py-2, and 44px items land the header at the height it already had. There's a test asserting exactly that, so nobody re-inflates it later.Tests
Five rendered tests — asserting markup, not source, and importing by package name so a broken
exportsmap fails here rather than in a consumer. Four fail against the previous renderers. The fifth coversaria-current, which already worked; it's guarded so a refactor of these classes can't quietly drop it.npm run verifygreen: lint, typecheck, build, 33 tests.Release
Version bumped 0.2.0 → 0.3.0 (README install line updated to match). Both live consumers inherit these defects today and are also drifted from each other — substrata on v0.1.1, camille-boulangerie on v0.2.0 — so both should move to v0.3.0. I'll open those bumps once this lands.
One incidental note
.gitignorehasnode_modules/with a trailing slash, which matches a directory but not a symlink. Anyone working in a git worktree who symlinksnode_moduleswill find it staged bygit add -A. Not fixed here to keep this PR to one subject, but worth a one-character change.Found by a fleet-wide navigation audit across 20 repos, where this was the only defect that multiplies.
🤖 Generated with Claude Code
https://claude.ai/code/session_01XeELB8b3N4JrT2asYL9WvE