Side Project
Building This Site
A portfolio written as raw block markup, pasted into the WordPress code editor, with an AI doing the typing and me doing the deciding.
Overview
You are standing in this one. I wanted a portfolio that looked like something I made rather than something I picked off a menu, so I skipped the page builders and the premium themes and wrote the whole thing as raw Gutenberg block markup pasted straight into the WordPress code editor.
I also used AI heavily to do it, which I would rather say plainly than dance around. I am a mechanical engineering student, not a front end developer. What I brought was the direction: what the site should feel like, what belonged on each page, what was wrong when something came back wrong, and enough stubbornness to keep sending it back until it was right. That turned out to be most of the work.
The constraints
I set a few rules at the start and held to them.
- No page builder. Everything is block markup and one stylesheet. Nothing depends on a plugin that might stop being maintained.
- No Media Library. Every image on the site is embedded directly in the page as a base64 data URI. Nothing points at an uploads folder, so nothing breaks on a bad path or a migration.
- One design system. One dark background, one amber accent, one card treatment, one type pairing. Six project pages built on the same template so they read as a set instead of six separate attempts.
What actually went wrong
The interesting part of any build is the part that did not work the first time.
Images that were not there
The first pass filled the project cards with image URLs pointing at my own uploads folder, for files that had never been uploaded. Everything looked correct in the markup and every image was broken on the live page. That is what pushed the whole site to base64 embedding, which ended up being the better decision anyway.
Gutenberg strips inline styles
The PDM and ACE logos kept getting cropped, so the obvious fix was an inline style on the image tag setting object fit to contain. It worked in preview and vanished on save, every time. Gutenberg sanitizes inline style attributes out of block content. The fix was to stop fighting it and move the rules into the stylesheet as real classes.
/* logo images get contained, not cropped */ .nk-project.nk-project--logo .wp-block-media-text__media img{ object-fit:contain; max-height:220px; border:none; }
The escaping that invalidates a block
This one cost the most time for the smallest reason. Gutenberg stores block settings as JSON inside an HTML comment, and a double dash inside an HTML comment is illegal. So any class name containing one has to be escaped, and the escaped name in the comment has to match the plain name in the markup below it exactly. Get it wrong and the block turns up flagged as invalid with no useful explanation.
<!-- wp:button {"className":"nk-btn\u002d\u002dghost"} --> <div class="wp-block-button nk-btn--ghost">...</div> <!-- /wp:button -->
The pieces
The home page runs an infinite carousel of work experience built from a duplicated set of cards and a single keyframe animation that translates the track by half its width, so the loop is seamless with no JavaScript.
The posts page lists every project as an alternating media and text card. Photographs fill their frame, logos sit contained and centered in a well so they never get cropped, and the ACE logo gets a white plate behind it because it was drawn for light backgrounds.
Each project then gets its own article page on a shared template: a narrow reading column, a small back arrow at the top, a large one at the bottom, a metadata strip with an estimated reading time, and figures placed next to the text they belong to.
Working with AI
The part worth writing down is how the collaboration actually went, because it was not one prompt and a finished site.
Being specific beats being polite. Vague direction produced generic results. Naming the exact thing that was wrong, in the words I would use to describe it to a person, produced fixes.
You have to know what wrong looks like. Several times the markup was clean, plausible, and still not going to work in practice, like the invented image URLs. Nobody catches that except the person who knows what the finished thing is supposed to do.
Small requests, checked immediately. One change at a time, look at it, keep it or send it back. Same loop as any iterative design work.
The taste is still yours. Every decision about what belonged on the site, what the tone should be, which photos to use, and when something was good enough was mine. The AI was fast at execution and had no opinion about whether the result was any good.
Takeaway
I got a site I would not have been able to write by hand, in a fraction of the time it would have taken me to learn to. What I actually practiced was specifying clearly, reviewing critically, and iterating until the thing matched the intent. Those are the same habits that make the difference on an engineering project, and they were the whole job here.
