Skip to main content
MAJ Atlas

Proof

Nothing reaches this domain without passing six stages in order. They run as one command, they run before every deploy, and any one of them failing stops the deploy rather than raising a warning. What follows is the gate itself, the last run it produced, and the instrument behind every score on this site.

The gate

  1. 1. Types

    npm run typecheck

    TypeScript in strict mode across every file, with no emit. A content field that changes shape, a prop that no longer exists, or a value that could be null and is read as though it cannot, stops here rather than in a browser.

  2. 2. Lint

    npm run lint

    ESLint on the Next.js config. It catches the patterns that degrade a page quietly: a raw img element in place of next/image, an unused import left behind by an edit, the accessibility rules that can be seen in the source.

  3. 3. Tests

    npm run test

    Vitest with React Testing Library, rendering the server trees themselves. Each page is asserted on its single h1, on its structured data parsing, and, for the studies whose clients are not named, on the absence of any naming string in the rendered text. The measurement snapshot's own age is asserted here too: once it passes fourteen days, this stage fails.

  4. 4. Build

    npm run build

    next build. Every static route is generated, so a page that only fails when rendered fails here, and the two stages after this one have real output to inspect.

  5. 5. Credential guard

    node scripts/assert-no-fabricated-credentials.mjs

    Reads the built HTML of every page. Inside each structured-data block it rejects the machine-readable credential keys, and across the visible text, with scripts stripped first, it rejects placeholder licence, tax-registration and to-be-decided strings. A credential this business does not yet hold cannot reach a visitor by accident.

  6. 6. Bundle budget

    node scripts/assert-bundle-budget.mjs

    Adds up the JavaScript the homepage loads before it can hydrate, from the build manifests, and fails over 420 kB uncompressed, which is the conservative stand-in for a 180 kB gzipped budget. It also fails if a WebGL renderer has entered that initial set, which is the single change most likely to undo the paint.

The last run

Tests passing
314
Pages built
22
Homepage first-load JS, uncompressed
374 kB
Commit
4c8900e

Written by the gate summary, checked 13 Sep 2026.

This site measured

Mobile

Performance
98
Accessibility
100
Best practices
100
SEO
100
Largest Contentful Paint
2.3 s
Cumulative Layout Shift
0
Total Blocking Time
11 ms

Lighthouse 12.8.2.

Desktop

Performance
100
Accessibility
100
Best practices
100
SEO
100
Largest Contentful Paint
0.5 s
Cumulative Layout Shift
0
Total Blocking Time
0 ms

Lighthouse 12.8.2.

Lighthouse CLI 12, simulated throttling; mobile = slow 4G emulation. checked 13 Sep 2026.

The builds we ship

The four live builds behind the case studies are measured on mobile in the same run as this site. A client we do not have permission to name is measured and reported by its sector, never by its address.

Their current scores are shared with each client directly rather than published here. What this page publishes is our own site, measured the same way.

How the numbers are produced

Every score on this page comes from the Lighthouse command-line tool, run against the live public URL, not against a local development server. The mobile figures use Lighthouse’s simulated throttling on its emulated handset, which is the same method behind the mobile score in PageSpeed Insights; the desktop figures use its desktop preset. Simulated throttling is a model of a slow connection, so the numbers are comparable between runs and between sites rather than a record of one visitor’s actual morning.

The run is one script, scripts/measure.mjs. It measures this site in both form factors and the four client builds on mobile, and writes the results, each with the timestamp of its own run, into a file committed to the repository. That committed snapshot is what this page renders, which is why every figure here carries the day it was read.

When a PageSpeed Insights key is configured, the per-site scores refresh from Google’s own run once a day and the snapshot becomes the fallback. No key is required for this page to be accurate: the snapshot is the measurement, and a test in the gate above fails the build once it passes fourteen days old, so the dates here cannot quietly drift.

The build facts come from scripts/gate-summary.mjs, which reads the test count from the test runner, the page count and the homepage’s first-load JavaScript from the build manifests, and the commit from git, at the end of a gate run.