The Mobile Nav
Opened sorted3d.com on an iPhone and the nav was a wreck — "FIELD NOTES" split across two lines, "ABOUT" half off screen, the whole thing crammed into a bar that was not designed for a 390px viewport. Classic desktop-first mistake.
Built a hamburger menu. Three lines become an X, tapping any link closes the menu. Straightforward.
Except it wasn't. First deploy: hamburger worked fine at the top of the page. Scroll down, open the menu — partial overlay, menu items floating in the top quarter of the screen, page content visible behind it. Looked like a browser rendering glitch from 2009.
The actual cause: backdrop-filter: blur() on a position: fixed parent element creates a new stacking context. Child elements with position: fixed then position themselves relative to that stacking context instead of the viewport. So the "fullscreen" overlay was actually fullscreen relative to the nav bar — about 70px tall.
Fix: pull the mobile menu out of the <nav> entirely. Make it a sibling <div> at the body level with its own position: fixed and a higher z-index. No stacking context interference.
Then added an X button in the top right of the overlay, because opening a menu and having no obvious way to close it without picking a destination is annoying UX.
Security Headers
Did a security pass on the site. DNS and credentials were clean — no API tokens or real names in any deployed file. What was missing was HTTP security headers.
Added a _headers file to the site/ directory — Cloudflare Pages picks this up automatically:
- Content-Security-Policy — whitelists scripts, styles, Google Fonts. Nothing else loads.
- X-Frame-Options: DENY — can't be embedded in an iframe
- X-Content-Type-Options: nosniff — browser uses declared content types, doesn't guess
- Referrer-Policy — origin only when navigating away, not full URL
- Permissions-Policy — camera, mic, geolocation all blocked
- Access-Control-Allow-Origin — locked to sorted3d.com, not wildcard
Also added .wrangler/ to .gitignore — wrangler creates a local cache during deploys that doesn't belong in version control.
Contact Form
Added a contact section with name, email, and message. Static site means no backend, so used Formsubmit.co — point the form action at an email address, they handle delivery. Free, no account required, one-time verification on the first submission.
One gotcha: Formsubmit sends a verification email the first time the form is submitted. Click the link in that email before expecting submissions to arrive. One-time thing, then it's permanent.
What's Actually Live Now
sorted3d.com — real domain, real SSL, mobile nav that works at any scroll position, contact form, three blog posts, security headers. The site is done enough to not be embarrassing.
What it doesn't have: products to sell. That's next.
If you have a fixed nav with a blur effect and need a child element to cover the full viewport, it won't work. The blur creates a stacking context. Move the overlay to be a sibling of the nav at the body level instead.
Drop a file called _headers in your site root, write the headers under a /* block, deploy. No configuration UI, no Workers needed.
No backend, no account, just an email address in the form action. Verify once via a confirmation email, works forever after. Free tier is plenty for a small business site.