# Reverse Lab

*Nearly every engagement is under NDA. The twenty-three case studies prove the method and name no client.*

**Category:** WEB PLATFORM / ENGINEERING SERVICES
**Status:** live
**Period:** May – June 2026
**Live:** https://reverselab.tech
**Built by:** HM Ammar, Digital Architect & Head of IT, Kuala Lumpur

**Stack:** Next.js 15 (App Router), React 19, TypeScript (strict), Tailwind CSS v4, MDX + Contentlayer, Framer Motion, Zod, pnpm

## The challenge

Reverse Lab sells reverse engineering and custom device development to enterprise buyers. Almost every engagement runs under NDA, which removes what an agency site normally leans on: named clients, product screenshots, hard numbers. The firm's own material reached me as folders of project photography, video and Russian-language write-ups. I had to earn trust from method and evidence instead.

## What I built

I built a Next.js 15 App Router site where the content is data rather than JSX. One config file defines the three-tier portfolio — six reverse-engineering specialisms, six engineering and development services, one advisory line — and drives the tier hub pages, the case-study filter chips, the sitemap and every page's metadata. Twenty-three case studies live as MDX parsed by Contentlayer, each with its own photo gallery and a small frontmatter markup I added so long narrative sections stay in content instead of leaking into components. I kept navigation deliberately one surface at a time.

## The detail

### Single nav surface

Past a shared scroll threshold the header retracts and a vertical rail slides in from the left, both reading one exported constant so the two can never both be on screen. I reserve only a 76px gutter through a --rail-offset variable on the body; the rail is 56px collapsed and expands to 260px over the page rather than reflowing it under the cursor. A 180 ms cancellable close timer keeps the services sub-panel alive while the pointer crosses the 12px gap to reach it.

### Services as config

config/services.ts is my source of truth for 13 services in three categories, each entry carrying its slug, accent colour, primary keyword, supporting keywords and a 60-character meta title. Tier hub pages, the homepage pillar grids, the case-study filter chips, sitemap.ts and every generateMetadata read from it; the header mega-menu and side rail read a parallel nav list in config/site.ts that mirrors the same slugs by hand. Reordering the reverse-engineering cards on the homepage cost me four order values rather than a template edit.

### Documents as changelog

Four rounds of client feedback arrived as one PDF and three Word files with annotated screenshots. Three of them became a single commit carrying the document's item numbers in the message; the first round fanned out across four commits. The history reads back to the source document, which is what made the last round cheap.

### Confidentiality as constraint

When the client decided team presence could not be shown for sensitive engagements, I stripped every portrait band, lead chip, team grid and headcount line across 17 files in one commit and reflowed the sections that had been built around them. No engineer had ever been named — I used initials and role aliases from the start. I rewrote a hard CVE count to "multiple publicly documented CVEs — details available after NDA".

### Rules for the agent

I wrote CLAUDE.md and five guides in .ai/ defining where each kind of change belongs: a decision tree routing copy edits to MDX or config and explicitly forbidding component edits for copy, a forbidden-dependency list (no CSS-in-JS, no Redux, no alternative UI kits), and a performance budget with hard limits. It is why months of copy-driven change rounds never turned into JSX churn.

## The outcome

It is live at reverselab.tech, serving 55 URLs: 13 service pages across three tiers, 23 case studies, six industry pages, a ten-phase process page and the legal set. It absorbed four rounds of corrections delivered as documents, including a brand rename from EA Engineering to Reverse Lab and a site-wide removal of every team-presence disclosure, without my having to change the content model.

---

[All work](https://hmammar.world/) · [HTML version](https://hmammar.world/work/reverse-lab.html)
