2026 · Production · Financial consulting
Hanna Business
A bilingual production site for a financial consultant working between the DIFC and Turkey, with the whole contour in code.
- Next.js 16
- React 19
- CSS Modules
- Docker
- Nginx
- Cloudflare
- GitLab CI/CD
- Hetzner
- lines in the engineering log
- 1,052
- numbered decisions written down
- 40
- test inputs to bisect an iOS WebKit bug
- 10
- Compose profiles
- 3
What I walked into
A financial consultant working between the DIFC and Turkey needed a Russian and English site, with only one version ever indexed.
Then iOS WebKit showed an invisible caret and a jumping page on the form fields.
What I changed, and why
A language switch without Context
The switch is built on useSyncExternalStore over a module-level store, and getServerSnapshot always returns English, so only one version is indexed.
The whole contour is mine
Dockerfile, three Compose profiles, nginx, a Cloudflare Origin Certificate, a two-stage GitLab pipeline and a self-hosted runner on a Hetzner CCX13.
A log of the options that lost
A 1,052-line engineering log of 40 numbered decisions, including the false leads discarded while bisecting the iOS bug across 10 test inputs.
A system font for inputs only
next/font and font-display: swap were racing on form fields. A system font stack for inputs and textareas fixed the caret and the jump.
The engineering log records the options which lost.
Where it landed
The site is live in two languages with a single indexed version, self-hosted behind Cloudflare with its own runner on a Hetzner CCX13.
The iOS form bug is fixed with a system font stack for inputs and textareas, and forty decisions are written down with the options that lost.