How this site is built
From a blank page to a live site: what I rejected, what I chose and why. Astro, three languages, a local dashboard, SEO and motion written in code.
A recruiter has about a minute. So this site has one job: show who I am, what I build and how to reach me, then get out of the way. This note tells how I got there, from A to Z, with the decisions and above all the refusals.
What I wanted, before choosing any tool
I started by writing constraints, not code.
- A light page, because many people who write to me will open the site on a phone, on 4G.
- Three languages, French, English and German, because I live in Germany and I come from Cameroon.
- A site I can change without touching code.
- A site that does not look like what a generator produces: no purple gradient, no frosted glass, no grid of icon cards, no hollow sentences.
- A palette fixed from the start: six blues and a white, from midnight black to royal blue.
Choosing by looking, not by reading
I do not pick a design from a description. For every visual decision I asked for a rendered page with several options side by side, and decided in front of the screen.
That made me reject a lot. My first direction, an electronic component sheet with a pinout and a part number, was too clever and not modern at all, so I dropped it. A WebGL particle wave did not please me. Neither did an aurora. I kept a night sky with a blue glow on the horizon. For the logo I compared several routes, rejected the monograms that were too thin, and chose a solid Y with three points and a ring cut out of its centre. Every refusal tightened the style.
The stack: Astro, TypeScript, plain CSS
Astro produces static HTML and only ships JavaScript where something moves. That was exactly the need: no UI framework to load just to show text and images. TypeScript for the modules that have logic, hand-written CSS for the rest, and no styling framework.
The result is measurable. The home page loads about 9 KB of my own JavaScript. The only heavy piece is Three.js (137 KB compressed), used for the wall of technology logos. It is only downloaded when that wall nears the screen, and never for a visitor who asks for less motion, who is saving data or who is on 2G.
One typeface, hosted by me
Poppins carries everything, from the name in the hero to the form labels. I host it myself, in four weights only, and preload the two used above the fold. No request to a font service, so no external dependency and no layout jump.
Three languages, one source
The pages come from the same tree of components. The words live in one file per language, and what is shared (links, projects, technologies, colours) in one shared file. Every page declares its versions with hreflang and the sitemap links them, so Google treats the three languages as one translated page and not as duplicates. Adding a language or fixing a sentence never means touching a component.
A dashboard so I stop touching code
This is the decision I am happiest with. A small Node server, started with npm run admin, gives me an interface to edit everything: texts in three languages, projects, career, images, CVs, SEO settings.
It is written with no dependencies. It only listens on the local machine, never on the network. The password is hashed with scrypt, the session is protected, every change requires a CSRF token and an origin check, and every uploaded file is checked by its real signature and size, not by its name. Before saving, it checks that the data has the right shape: if I get a field wrong, it refuses instead of breaking the site.
Motion
The hero sky is a canvas of a few hundred stars on three depths, which twinkle, drift and follow the cursor a little. It pauses when off screen. On the first load of a session, a short intro of under four seconds flies the logo to its place in the navigation bar, then does not come back during the session.
All of this obeys one rule: if the visitor asks for less motion or saves data, they see a still image, and the site stays complete. Motion is a bonus, never a requirement.
Projects: show the real product
For every project I wanted real screenshots of the running application, not mock-ups. When an application was not running, I ran it on a copy, with a throwaway database and demo data I invented: fictional club names, randomly drawn scores. Personal details that appeared in documents were erased before publishing, including inside the pixels of an image.
When a project is an unrequested proposal, like the one for a Cameroonian chicken chain, the page says so. Every image also carries its origin in its metadata: real screenshot, freely licensed photo, or render. I do not publish anything I cannot trace.
SEO, treated as code
The site is complete HTML, readable by a search engine without running a script. Every page has its canonical address, its language alternates and its structured data (the person, the site, each project, the downloadable report, the video). The sitemap carries real last-modified dates, and an llms.txt file summarises the site for AI-based search tools. Share images are generated by a script.
Above all, an audit script (npm run seo) walks every built page and fails if anything is broken: title, description, internal link, link back between languages, image without alt text. I run it after every change.
Tools, honestly
I built this site with an AI programming assistant, which wrote a large part of the code and ran the checks. The decisions are mine: the brief, the constraints, the palette, what was rejected and what was kept. I read what gets published, and I ship nothing I do not understand.
What is not perfect
- On desktop, the home page is a little slower than on mobile because of the 3D wall. I measured about 98 out of 100 for performance on mobile and 85 on desktop, with 100 for accessibility, best practices and SEO. Fixing the 3D wall is on my list.
- The contact form sends an email and does not confirm an appointment.
- No tracking script runs here: I do not know how many people visit, and I prefer it that way.