The navigation bar speaks the language of the page it sits on, and a phone gets one button - #392
Merged
Conversation
…phone gets one button Two buyer reviews, a phone and a laptop, named the shared bar as the biggest remaining distraction. On 390px it held five elements: logo, HELP, SIGN IN, CREATE ACCOUNT and the hamburger, with the button and the hamburger both starting at x=330 and no air between them. And all of it in mono capitals with letter-spacing, over a homepage set in paper, ink, sentences and one cobalt button. Typography. PRODUCT SECURITY PRICING DOCS is the voice of a terminal. Same four destinations, same order, now in the reading face at 14px, sentence case, no letter-spacing: Product, Security, Pricing, Docs, and Help, Sign in, Create account beside them. The phone bar. One primary action next to the menu button. Sign in and Help move to a strip under the drawer, 48px tall, where a thumb reaches them, and they come back into the bar at 700px, so a tablet keeps what it had room for. The bar has a 12px floor between every pair of elements now, set with a gap instead of hoping space-between leaves some: 98px and 12px where it used to be 0. Every target in it is at least 44px tall. The button. The one filled button was lime, which is the punctuation colour of this brand and not the colour of its primary action; next to the cobalt hero button it read as a second, competing offer. It is cobalt with white text (6.3:1), the same .hp-btn-fill the homepage uses. app-2026.css forced #0A1626 on lime with !important for the app screens and now follows, at the same weight. One home for the bar. .nav-auth, .nav-signin, .nav-cta, .nav-user and .nav-help lived in design-system.css while the rest of the bar lived in nav.css, and the half in design-system.css answered a narrow phone by shrinking: 9px type, 5px padding, the Help border dropped. Small is not roomy. It all sits in nav.css now. No page loads one without the other. The drawer keeps mirroring the four destinations exactly, because js/nav-auth.js rewrites its contents after the session check and tests/navigation-shell pins them; that is why the tail is a sibling and not a child, and why apply-nav.py had to learn to strip an old tail before stamping a new one, or the second run would leave two. Signed in is the same bar: the email control in the reading face, the drawer carrying Documents, Send, Sign, Verify, Settings, and no tail, since the user menu already holds Help and Sign out. tests/navigation-shell: support on a phone was pinned to a visible /help link in the closed bar, which is why Help was the fifth element up there at 9px. The requirement is that a visitor looking for support finds a working route, not which surface it lives on, so the check now opens the menu and demands a 48px target. It gained three checks that measure what the reviews saw by eye: what is in the phone bar, how far apart, and how big. 29 checks, all green. Versions: design-system.css v25, nav.css v20, nav.js v15, nav-auth.js v6, app-2026.css v3, stamped by frontend/apply-nav.py over 51 pages and by hand on the pages the generator does not own. Gates: first-screen, ui-truthfulness, site-claims, seo-contract, links, navigation-shell, frontend-loading-contract, pricing-fold, cache-bust, csp-inline, static-sanity, check-test-declarations, eslint, theme-contrast, motion-safety, app-contrast, app-theme, access-log-visitors, apply-nav-idempotent, apply_seo_head --check. All green.
…e bar is measured on three pages Review of #392 found the hole in the first round. developer.html keeps its own navigation (KEEP_OWN_NAV in frontend/apply-nav.py), is stamped by hand, and carries a hamburger. The round moved Sign in and Help out of the bar below 700px and into a strip under the drawer, and that page never got a strip. So on a 390px screen both links measured 0x0 there, where main still had them in the bar. A page the generator does not own is a page a generated fix does not reach. Three things, because one of them alone would leave the same gap open. The markup. developer.html carries the strip now, like every stamped page. The script. nav.js builds the strip when a page has a menu button and no strip. A page can forget the markup; this cannot forget to build it. That is a floor under the live site, not a substitute for the markup, which is why it comes with the check below rather than instead of it. The check. tests/navigation-shell reads every .html in frontend/, not only the 51 the generator writes, and fails on any page that has id="nav-hamburger" without id="nav-mobile-tail". 52 pages carry the button. Taking the strip back out of developer.html turns it red and names the file. And the measurement moved. The three phone-bar checks ran on the homepage alone, which is exactly why they were green while /developer was broken. They run on /, /pricing and /developer now, each with a fourth check that the strip really holds /auth/login and /help at 44px or more. /developer measures logo x16-95, Create account x181-318, menu x330-374, gaps 86 and 12, all heights 44. 39 checks, all green. Rebased on main with #379, #390 and #391.
Apolloccrypt
force-pushed
the
fe/nav-rustig
branch
from
September 3, 2026 04:11
40948a1 to
fa0030b
Compare
Apolloccrypt
pushed a commit
that referenced
this pull request
Sep 3, 2026
…jurybesluit Het oude document beschreef een richting die op drie punten is teruggedraaid en op een vierde nooit is uitgevoerd. Het wees naar een tokenbestand dat door niets geladen wordt en naar elf screenshots van prototypepagina's die niet bestaan. Elke regel is nu getraceerd naar de PR die hem heeft besloten. De richting leeft in vier lagen en niet in een. design-system.css v4.1 op alle 58 paginas, licht only; nav.css; app-2026.css op elf app-schermen, met donker als keuze op /account onder paramant.theme.v1; en een eigen --hp-palet in de kritieke CSS van de homepage. Het document zei dat er een globale tokenlaag zou komen. Die is er niet en het bestand dat hem zou dragen is hier weg. Drie dingen zijn verworpen en staan nu met hun reden in het document. De STIL-balk in mono hoofdletters (#392: de stem van een terminal boven een pagina in papier, inkt en zinnen, en Help stond daardoor op 9px). Lime als primaire knop (#392: lime is de leestekenkleur van dit merk en las naast de kobalt-heroknop als een tweede aanbod). En donker op marketing (#380: onbereikbaar achter [data-theme] zonder schakelaar, onleesbaar wit op lime op 1.07:1, en 31 KB op elke pagina zonder gzip). frontend/design-tokens-2026.css is weg. Geen pagina, build, test of nginx-conf laadde hem, en hij was in tegenspraak met wat wel draait: hij schreef donker als :root:not([data-theme="light"]), precies de sprong van creme naar zwart die #381 heeft weggehaald en die docs/site-claims.md rij 28 en tests/app-theme.test.mjs bewaken. Zijn aliaslaag verschoof --space-8/9/10 en liet --space-10 en --space-11 ongedefinieerd, en --navy: var(--ink) zou elke navy op 58 paginas in een keer verzetten. De levende bron is app-2026.css. De elf prototypebeelden zijn vervangen door twee van de echte homepage, met scripts/brand-shots-direction.mjs. Dat script volgt de regel uit #393: een tempmap standaard, docs/brand/assets alleen met PARAMANT_WRITE_BRAND_SHOTS=1, en het hergebruikt de vlag en de docs-check uit scripts/brand-shots-dir.mjs in plaats van er een tweede kopie van te houden. Twee merkbesluiten staan open in sectie 8. Een gevuld accent per scherm, want /pricing draagt sinds de balkwissel zeven btn-primary plus de knop in de balk, en op het eerste scherm staan er twee naast elkaar. En de koele naad: de balk op rgb(248,250,252) tegen homepagepapier #FAF8F3, nu verborgen achter een gradient over de eerste 160px, met de balkkleur gepind door tests/navigation-shell.test.mjs. Poorten groen: tests/static-sanity.sh (twaalf checks), scripts/check-test-declarations.sh (134 suites), node --test tests/links.test.mjs, npx eslint@9 . (exit 0). Extra: tests/brand-shots-optin.test.mjs 10/10, scripts/check-cache-bust.sh 363 links, tests/frontend-loading-contract.test.mjs 7/7.
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.
Two buyer reviews, a phone and a laptop, named the shared navigation bar as the biggest remaining distraction. On 390px it held five elements: logo, HELP, SIGN IN, CREATE ACCOUNT and the hamburger, with the button and the hamburger both starting at x=330 and no air between them. All of it in mono capitals with letter-spacing, over a homepage set in paper, ink, sentences and one cobalt button.
What changed
Typography. PRODUCT SECURITY PRICING DOCS is the voice of a terminal. Same four destinations, same order, now in the reading face at 14px, sentence case, no letter-spacing: Product, Security, Pricing, Docs, and Help, Sign in, Create account beside them. Same in the drawer, at 16px.
The phone bar. One primary action next to the menu button. Sign in and Help move to a strip under the drawer, 48px tall, where a thumb reaches them, and they come back into the bar at 700px so a tablet keeps what it had room for. A
gapon the bar sets a 12px floor between every pair of elements instead of hopingspace-betweenleaves some: measured 98px and 12px where it used to be 0 and 0. Every target in the bar is at least 44px tall.The button. The one filled button was lime, which is the punctuation colour of this brand and not the colour of its primary action; next to the cobalt hero button it read as a second, competing offer. It is cobalt with white text (6.3:1), the same
.hp-btn-fillthe homepage uses.app-2026.cssforced#0A1626on lime with!importantfor the app screens and now follows, at the same weight. The drawer's current row loses its lime wash for the same cobalt the desktop bar uses.One home for the bar.
.nav-auth,.nav-signin,.nav-cta,.nav-userand.nav-helplived indesign-system.csswhile the rest of the bar lived innav.css, and the half indesign-system.cssanswered a narrow phone by shrinking: 9px type, 5px padding, the Help border dropped. Small is not roomy. It all sits innav.cssnow. No page loads one without the other (vault.html,billing/checkout.htmlandclaim.htmlloaddesign-system.csswithoutnav.cssand carry none of these classes).Signed in is the same bar: the email control in the reading face, the drawer carrying Documents, Send, Sign, Verify, Settings, and no tail, since the user menu already holds Help and Sign out.
The test
tests/navigation-shellpinned support on a phone to a visible/helplink in the closed bar. That pin is why Help was the fifth element up there, shrunk to 9px type to fit. The requirement is that a visitor looking for support finds a working route, not which of the two surfaces it lives on, so the check now opens the menu and demands a 48px target instead of "not display:none". The static contract below it still demands the/helplink in the stamped markup of all 51 pages, so it cannot quietly disappear.Three checks were added that measure what the reviews saw by eye:
the phone bar carries one action beside the menu button(at most 3 elements)nothing in the phone bar touches its neighbour(every gap >= 12px)every target in the phone bar is finger-sized(every height >= 44px)29 checks, all green. The drawer contract is untouched:
#nav-mobilestill mirrors the four desktop links exactly, which is why the tail is a sibling and not a child, and whyapply-nav.pyhad to learn to strip an old tail before stamping a new one or the second run would leave two.Versions
design-system.cssv25,nav.cssv20,nav.jsv15,nav-auth.jsv6,app-2026.cssv3. Stamped byfrontend/apply-nav.pyover 51 pages, and by hand on the pages the generator does not own (developer.html,co-sign.html,vault.html,claim.html,billing/checkout.html,setup.html,request-key.html,all-systems-go.html,changelog.html) plus the fixture intests/access-log-visitors.test.mjs.Gates
All green locally: first-screen, ui-truthfulness, site-claims, seo-contract, links, navigation-shell, frontend-loading-contract, pricing-fold, cache-bust, csp-inline, static-sanity, check-test-declarations, eslint, theme-contrast, motion-safety, app-contrast, app-theme, access-log-visitors, apply-nav-idempotent,
apply_seo_head --check.Screenshots
Taken with
deviceScaleFactor: 2, session mocked at/api/user/session/verify. Paths on the NUC, under/tmp/claude-1000/-home-mick-vault/aaa93ca4-46a3-4e08-bb7e-b16bfb35e53c/scratchpad/navbar2026/shots/:before/390-out-closed.pngafter/390-out-closed.pngbefore/390-out-open.pngafter/390-out-open.pngbefore/390-in-closed.pngafter/390-in-closed.pngbefore/390-in-open.pngafter/390-in-open.pngbefore/1440-out-closed.pngafter/1440-out-closed.pngbefore/1440-in-closed.pngafter/1440-in-closed.pngThe measured bar at 390, signed out, from the test output:
ParaMANTx16-83,HELPx95-134,SIGN INx150-203,CREATE ACCOUNTx219-356,Open menux368-412ParaMANTx16-83,Create accountx181-318,Open menux330-374, gaps 98 and 12, all heights 44Round 2: the page the generator does not own
Review found the hole.
developer.htmlkeeps its own navigation (KEEP_OWN_NAVinfrontend/apply-nav.py), is stamped by hand, and carries a hamburger. This round moves Sign in and Help out of the bar below 700px and into the strip under the drawer, and that page never got a strip: on 390px both links measured 0x0 there, where main still had them in the bar.Three things, because any one of them alone leaves the same gap open:
developer.htmlcarries the strip now, like every stamped page.nav.jsbuilds the strip when a page has a menu button and no strip. A page can forget the markup; this cannot forget to build it. A floor under the live site, not a substitute for the markup.tests/navigation-shellnow reads every.htmlinfrontend/, not only the 51 the generator writes, and fails on any page withid="nav-hamburger"and noid="nav-mobile-tail". 52 pages carry the button. Sabotage run: taking the strip back out ofdeveloper.htmlturns the suite red and names the file, while the runtime check stays green on thenav.jsfallback, which is the pair working as intended.The measurement moved too. The three phone-bar checks ran on the homepage alone, which is exactly why they were green while
/developerwas broken. They run on/,/pricingand/developernow, each with a fourth check that the strip really holds/auth/loginand/helpat 44px or more./developermeasures logo x16-95, Create account x181-318, menu x330-374, gaps 86 and 12, all heights 44. 39 checks, all green, and the 20 gates re-run clean after the rebase (now on main with #379, #390, #391).Extra screenshots:
after/390-developer-out-closed.png,after/390-developer-out-open.png.Follow-up, not in this PR
Two observations from the review that are real and out of scope here:
rgb(248, 250, 252)while the homepage paper is#FAF8F3. Identical to main, and pinned bynavigation-shell("mobile navigation is opaque before opening the menu"), so changing it is its own round with its own contrast measurement./pricing. Create account in the bar plus the CTA in the copy now read as two primary actions on one screen. That is the cost of moving the bar button from lime to cobalt, and the fix belongs with the page, not with the bar: either the page CTA becomes an outline button, or the bar drops to outline on pages that carry their own primary action.