Portfolio demo ยท Landing page build and analytics

A landing page built to be measured, not just looked at.

Northfold is a fictional brand strategy studio. I wrote a brief for it, then planned, built and instrumented a single landing page whose only job is to get qualified founders to book a 20-minute call. This page explains the decisions behind it.

  • GoalBooked fit calls from qualified founders
  • BuildHand-written HTML, CSS and vanilla JS. No framework, no template
  • TrackingGTM-ready dataLayer, optional GA4, 7 event types
  • SizeAbout 43 KB compressed, fonts included

1. The brief I set

The visitor is a founder of a 2โ€“50 person business who suspects their brand is muddled, usually because something forces the issue: a website rebuild, a raise or a new offer. They arrive from a referral or a LinkedIn post, mostly on a phone, and they are deciding one thing: is this worth 20 minutes of my time?

So the page has one conversion: a fit-call request. Everything else either moves the visitor toward it or helps them rule themselves out.

2. Page logic: one question per section

Each section answers the question a visitor would have at that point in the scroll. If a section can't name its question, it gets cut.

SectionVisitor's questionWhat the design does
HeroWhat is this, and is it for me?Outcome headline, price and duration in the first screen, one primary button. The sample deliverable shows the product instead of describing it.
Sound familiar?Do they understand my problem?Three symptoms written in the founder's language, not the studio's.
How it worksWhat actually happens, and how much of my time?A day-by-day timeline where each stage ends in a named deliverable.
Is this for you?Am I the right fit?An explicit "not for you if" column. It trades a few clicks for better-qualified calls.
PricingWhat does it cost, and what's the risk?One published price, a list of what's included and a stop-at-day-five guarantee.
FAQWhat's left that stops me?Five objections from the brief, each answered in two sentences.
BookHow do I start?Four fields, one optional. The copy says what happens next and how fast.

3. Conversion decisions

  • One goal, repeated where intent peaks. The same action appears in the header, the hero, after the process, on the price card and at the end, so a convinced visitor never has to scroll back.
  • A sticky button on phones only. It appears once the hero has scrolled away and hides again when the form is on screen, so it never covers the form.
  • The price is shown. A strategy studio that hides its price gets calls from people who can't afford it. Publishing it moves that filter onto the page.
  • Inline validation that doesn't scold. Errors appear on submit, clear as soon as the field is fixed and move focus to the first problem. Every failure is tracked, so a confusing field shows up in the data.
  • No fake social proof. The studio is fictional, so instead of invented testimonials the hero shows a sample of the work. On a real build this is where client logos or a named quote would go.

4. Tracking plan

Every event is pushed to window.dataLayer, so it works with Google Tag Manager as-is. Add a GA4 measurement ID to the page and the same events go to GA4 directly. Event names follow GA4's recommended naming where one exists (generate_lead).

EventFires whenParametersAnswers
cta_clickAny "Book" button is clickedlocation, cta_textWhich placement actually drives people to the form?
section_viewA section is at least half visible, once per visitsectionWhere do people stop reading?
scroll_depth25, 50, 75 and 90% of the pagepercentIs the page too long for the people who arrive?
faq_openA question is expandedquestionWhich objections need to move higher up the page?
form_startFirst focus inside the formformHow many start the form but don't finish?
form_errorA field fails validation on submitform, fieldWhich field is costing us leads?
generate_leadThe form is submitted successfullyform, reasonThe conversion, broken down by why they came

How to check it yourself

  1. Open the page with ?debug=1. An inspector lists each event the moment it fires.
  2. Scroll, open a FAQ, click a button, then submit the form empty and filled in. You should see form_error for each missing field, then one generate_lead.
  3. On a live client build, the same check is done in GA4 DebugView or GTM Preview, and the conversion is marked as a key event before handover.

5. Speed and accessibility

  • Small by default. One stylesheet, two small scripts loaded with defer, no images in the critical path, and one display font with font-display: swap.
  • Mobile first. Styles start at phone width and add columns at 720 px and 1000 px. Tap targets are at least 40 px tall and form fields 50 px.
  • Accessible by structure. Real headings and landmarks, a skip link, labelled fields, errors tied to their inputs, visible focus rings and reduced motion respected.
  • 43 KBfor the page's own files, compressed, fonts included
  • 6requests for the page itself
  • 0cookies set
  • 0.00cumulative layout shift

Measured in Chromium at phone width. Fonts are self-hosted (SIL Open Font License), so there's no Google Fonts request. The host adds Cloudflare Web Analytics, a cookie-free page-view counter of about 10 KB. Event tracking stays in the page's own dataLayer until GA4 is switched on.

6. On a real project

This demo is hand-coded so every decision is visible. For a client I build on whichever platform their team will maintain, such as Webflow, Framer, WordPress or plain static hosting, and keep the same structure and tracking plan.

Before quoting I'd confirm:

  • how many pages, and whether copy and designs are final
  • which platform you build on and who maintains the site afterwards
  • the one action each page should drive, and where leads should go (inbox, CRM, booking tool)
  • which analytics stack you use, and any consent or privacy requirements

I use AI tools to speed up drafting and testing. I review every section by hand and check behaviour on phone and desktop before handover.