My portfolio is the one project where I own every decision, so I treated it like client work: a design system first, a clean Elementor build, custom CSS and JavaScript where the builder stops, real SEO and schema, and a fast mobile score. This is how it came together.
Design, development, SEO
Oct 2026 · 3 days
WordPress · Elementor Free

Mobile PageSpeed
Largest Contentful Paint
Total Blocking Time
SEO & Best Practices
Schema errors
I explored three directions before writing any code: a refined black-and-white layout, a dark “Midnight & Lime” look, and a minimal device-style design. I picked the first one. It reads as calm and trustworthy, and it keeps the projects in focus. The first version used red as the accent, but red read like an error message, so I switched to cobalt.

The three directions. Left: Refined classic (chosen). Middle: Midnight & Lime. Right: System.
Everything uses 15 colors and 14 text styles, set up as Elementor global colors and fonts with the same names. Geist handles all text and Geist Mono the small labels. Headings scale with clamp(), while body text, buttons and labels use rem. Every text color passes the 4.5:1 contrast ratio.

15 named colors, from Ink #0B0B0C to Cobalt #2952E3.

14 text styles with desktop and mobile sizes.

The build spec: yellow tags name the global style, and striped bars give each section’s background and spacing.
Elementor handles the layout with containers and global styles. Everything else lives in a Hello Elementor child theme that I wrote and organized myself.
// functions.php · show self-hosted fonts in Elementor
add_filter( 'elementor/fonts/additional_fonts',
function ( $fonts ) {
$fonts['Geist'] = 'system';
$fonts['Geist Mono'] = 'system';
return $fonts;
} );// main.js · Work page filters
cards.forEach(function (card) {
var show = key === "all" ||
card.classList.contains("cat-" + key);
card.style.display = show ? "" : "none";
});
The homepage design (top section shown).

The Work page: 12 projects with platform filters. My NDA work is summarized, not linked.
A leftover initBackToTop() call from an older theme threw a ReferenceError, so the filters and everything after it never ran. I found it in the Console, removed it and moved every feature into one init block.
Contact Form 7 inserts the Cloudflare widget at the top of the form. I made the whole form the dark panel, set the inner wrapper to display: contents and used flex order to place it right above the button.
WordPress marks every /#section link as "current" on the homepage. A small CSS rule resets the active color for hash links only, so "Work" still highlights on the Work page.
Desktop menu rules started at 768px while the mobile menu ran up to 1024px, so tablets got both. Moving the desktop breakpoint to 1025px fixed it.
// Homepage schema (excerpt)
{
"@type": "ProfilePage",
"mainEntity": {
"@type": "Person",
"name": "HJ Miranda",
"jobTitle": "WordPress Developer",
"knowsAbout": [
"WordPress", "Elementor", "WooCommerce",
"Technical SEO", "Schema markup"
]
}
}
Schema.org validator result for the homepage.

Same page, same design. LCP went from 7.7 s to 2.1 s, and Total Blocking Time dropped to 0 ms.

Before: Performance 62.

After: Performance 98, Best Practices 100, SEO 100.