Maverick Frame is a 3D architectural visualisation studio: renders, animation and product CGI for developers, architects and manufacturers. It is also our own studio — the production arm the owners of Unreal Mango also own and run. That is the only reason this case study can exist in this form. On a client engagement we could publish a chart. Here we can open the analytics property, the dated change logs, the refreshes that made pages worse and the problems that are still open, because there is nobody to embarrass but ourselves.
It also answers the question every serious buyer asks and few agencies enjoy: do you run this playbook on your own money, or only on ours?
1. Five flat months, then the line moved
Here is the whole of 2026 to date, straight out of Search Console. No 28-day window chosen to flatter anything, no rolling average — calendar months, clicks and impressions as Google counts them.
| Month | Clicks | Impressions | CTR | Avg. position |
|---|---|---|---|---|
| January | 996 | 156,429 | 0.64% | 24.7 |
| February | 865 | 169,290 | 0.51% | 25.0 |
| March | 1,291 | 286,865 | 0.45% | 16.9 |
| April | 1,069 | 289,594 | 0.37% | 18.1 |
| May | 1,037 | 332,780 | 0.31% | 19.2 |
| June | 2,236 | 466,642 | 0.48% | 13.8 |
| July | 4,624 | 807,013 | 0.57% | 11.3 |
Search Console, property sc-domain:maverickframe.com, pulled 1 August 2026. July
covers 1–29 July, the last complete day available at the time of the pull. Work on the site
began on 27 May, so June and July are the first two full months of the programme.
The interesting part of that table is not the last two rows. It is the first five.
Between January and May, impressions more than doubled — 156,429 to 332,780 — and clicks did not move at all: 996 in January, 1,037 in May. Click-through rate halved over the same stretch, from 0.64% to 0.31%. Google was showing the site to twice as many people every month and a shrinking share of them were clicking.
That pattern has a specific meaning, and it is not "we need more content". A site collecting impressions and no clicks is a site that is visible on page two. The demand is already there, already being served, and it is landing one screen below where anyone looks. Publishing more articles into that situation produces more page-two pages.
June, the first full month of work, closed at 2,236 clicks. July closed at 4,624 — a factor of 3.6 against March, the strongest month before the engagement, and 4.6 against January. The best single day of the year so far, 29 July, produced 280 clicks: more than the first eight days of January added together.
2. What we inherited
Four findings shaped everything that followed. All four came out of data that had been sitting in the accounts for months.
410,729 US impressions at 0.09% click-through
Over the 90 days to 9 June, the United States alone sent 410,729 impressions and 372 clicks, at an average position of 19. The UAE, Canada and Australia told the same story at smaller scale. This is the finding that set the strategy: the job was not to create demand, it was to move existing demand from position 19 to position 9 and to write snippets worth clicking.
Twenty published pages were telling Google not to index them
An indexation audit on 14 June pushed all 268 canonical published URLs through the Search
Console inspection API and cross-referenced them against 90 days of impression data. Twenty
pages were sitting on noindex while being listed in the sitemap — seventeen of
them service pages, which is to say the pages that sell. Almost all had been crawled by Google
on the same day, 24 April: the signature of a single bulk event nobody had noticed.
The same audit worked in the other direction. Of 45 zero-impression URLs flagged as suspicious, fifteen turned out to be indexed and perfectly healthy — they simply had no demand behind them. Fixing those would have been work against a problem that did not exist.
The commercial layer was invisible and the blog was carrying everything
The blog's share of site clicks had gone from 41% in October 2025 to over 80% by mid-2026, with service pages under 1%. Around seventeen duplicate service-page slug pairs were live at once, two parallel navigation menus disagreed with each other, and the services sitemap exposed 10 of 28 URLs. Meanwhile AI Overviews for the studio's core commercial queries were citing competitors who published prices, turnaround times and FAQs — and Maverick Frame, which published none of the three, appeared nowhere in them.
Conversion tracking had been dead since April
In April the site had moved to a new form flow. Every tag-manager trigger was bound to the old
markup, so they silently stopped matching — the form_sent event went from 3 to 0
and stayed there. Two months of enquiries had been arriving and not being counted, and the
resulting flat line in the reports had been read as a performance problem. Underneath that, the
events were configured backwards: everything funnelled through one umbrella conversion, inside
which the cold catalogue download counted and the actual contact enquiries did not.
3. What we built first: a system, not a calendar
The instinct in this situation is to open a content calendar and start writing. We built the machinery first, and it is the part of this case we would defend hardest, because it is what makes month nine as disciplined as week one.
Five registries are the single source of truth. A topic-to-URL map that every new page and every refresh must clear a cannibalisation check against. A compact status index carrying, for every article, when it was last audited, when it was last refreshed and when it is next due. A full change log where each entry records the diagnosis, what changed, and a machine-readable baseline line so the effect can be measured later — 346 entries and 211 stored baselines today. An action queue that is the only "do this now" list. And a monitoring log where verdicts land.
Three jobs run every Monday, in a fixed order, over that shared database:
- The monitoring sweep takes every article whose review date has come due, pulls the Search Console delta against its stored baseline, issues a verdict — keep and re-check in 90 days, queue for rewrite in 28, or check whether it is indexed at all — and writes that verdict back into the registries. Losers go into the action queue.
- The quick-win pass picks up pages ranking 5–20 with a click-through shortfall and routes them to the refresh queue.
- The content-debt pass picks up the opposite tail — zero impressions, position beyond 20, or measurable decay — and routes those to rewrite or prune.
The boundary between the second and third job is deliberate and exclusive, so one URL can never enter both queues and get worked on twice.
That design came out of a failure worth naming. Before it, every refresh spawned its own one-off monitoring reminder. Those reminders fired into dead conversations, the verdicts were never recorded anywhere, and articles sat in "awaiting measurement" status indefinitely. The whole loop was cut and replaced with one weekly sweep reading a shared review date. Per-article reminders are now banned outright.
On top of that sits one hard rule: no edit without live data first. Query-level Search Console over 90 and 28 days, GA4 behaviour, keyword volume and difficulty, a live look at the top ten results, and a read of both registries — before a single word changes. Opinion-based edits are not discouraged, they are structurally impossible. Alongside it: one editorial internal link per target URL per article, because Google counts the first anchor and the rest just look spammy; no outbound links to competitors inside listicles; headings unique site-wide; and slugs that never change, because a slug change throws away everything the URL has earned.
4. What we shipped
384 logged content operations between 7 June and 30 July — nine weeks — counted from the change logs rather than estimated: 263 new pages and articles, 74 refreshes and targeted fixes, 10 monitoring write-backs, 9 format flips or revivals of dead pages, 6 consolidations, 3 prune batches. 274 of those operations were English, 110 German.
English content
- 160 new English article entries logged over the nine weeks.
- 40 new geographic listicles built as one coherent cluster rather than scattered posts — each with a researched roster of local studios, a comparison table, local cost bands and an FAQ, and each gated on a live demand check before it was written.
- 141 articles scheduled with fixed publish dates running to 31 December 2026. The calendar was full six months out.
- Sixteen service pages written from scratch from layouts, each with its own US and UK keyword research, plus 22 rewritten title and meta-description pairs put through 32 validator passes against both character and pixel limits.
- ~569 new questions and answers written from scratch for FAQ blocks and structured data, of which 65 were added during refreshes. Average FAQ depth per page went from 6.3 questions to 8.2.
- An internal-linking audit that parsed every post body on the site — 906 content links across 117 English blog posts and 28 service pages. It found 57 of those 117 posts sending 109 links into a dead-end section while the site's main pillar page had zero incoming links. After the fix, that section received none, the pillar received 39, and 88% of posts pointed at a page that sells something.
- ~190 duplicate H2 headings eliminated. The identical heading "Who They Are and What They Stand For" appeared on 64 separate case studies.
- Taxonomy rebuilt: 36 categories, 13 of them empty, and 9 unused tags became 7 categories with every post assigned to exactly one.
A German market built from zero in six weeks
117 German pages shipped between 21 June and 30 July: 78 case studies, 15 service pages, 14 blog articles, 10 hubs and utility pages. The language layer itself — slugs, menus, hreflang, legal pages — was planned, built and deployed in about three days, 21–23 June.
The scope was built on German keyword research, not a translation of the English site, and that changed the sitemap. The commercial-rendering page was dropped because every German phrase for it returned zero volume, while immobilien visualisierung (320/mo) and innenraumvisualisierung (110/mo, difficulty 7) each earned a page of their own. Under the hood, 214 German strings were added across 68 theme files in a single commit — bringing 409 interface strings to full trilingual coverage — with the existing English and Spanish output verified byte-identical afterwards. A multilingual refactor with zero regression on the two languages already live.
In July the German pages collected 12,410 impressions at average positions between 11 and 21 — a market that did not exist in search two months earlier. The Spanish section, live since 12 June, reached 54,171 impressions at average position 10.6.
Structured data
Four full site-wide audits ended at 242 of 242 URLs valid, zero parsing errors, confirmed by two independent passes. FAQ markup now covers every service page, every solution page, all 69 English case studies and 81 blog posts; breadcrumbs and organisation data are site-wide from a single global source rather than repeated per template.
Ten classes of defect were closed on the way, including 28 posts displaying a visible FAQ with no markup behind it, 53 with no FAQ at all, two posts dated in the future, four video thumbnails returning 404, and a generator bug that had quietly corrupted around 95 schema identifiers. One rule was adopted and enforced: the markup must be one-to-one with what the visitor can see. Review and rating markup was deliberately left at zero — the ban risk is not worth the stars, and a later test confirmed it would not have produced them anyway.
Speed and code
| Before | After | |
|---|---|---|
| Homepage Lighthouse, desktop | Performance 55 | 100 / 100 / 100 / 100 |
| Main JavaScript bundle | 935 KB (272 KB gzipped) | 20.5 KB gzipped |
| Case-study pages | PageSpeed 76, layout shift 1.0 | PageSpeed 100, layout shift 0 |
| Media library | 710 MB | 96 MB (−86%) |
| Contact form response | 7,228 ms | 176 ms |
| Server response, homepage | — | 31 ms |
Lighthouse and server-response figures are a desktop lab run against the live homepage on 1 August 2026. Real-user field data on the same day: largest contentful paint 2.0–2.2 s, interaction to next paint 90 ms, cumulative layout shift 0 — Core Web Vitals passing.
Almost all of that came from deleting things rather than adding them. A 551 KB 3D library was replaced by a purpose-built 4.6 KB canvas effect. The animation library was removed entirely and its work rewritten in about thirty lines of native browser code. The carousel library, the lazy-loading library and both web fonts went the same way — the fonts alone were 44 KB and two requests on the first screen of every page, and one of the two had no font-face rule anywhere in the codebase, meaning the site had been preloading files it never used.
The stylesheet got the same treatment, with proof attached: 1,120
!important declarations removed from a single file, verified as zero
declaration differences across 1,258 rules, and 3,080 unit-conversion calls replaced with plain
values across 76 files, verified as byte-identical compiled output. Refactors that cannot be
proven harmless do not get shipped to a site with no staging environment.
Plugins went from 23 to 7, and it is worth being precise about this because it is usually oversold: an audit run before the cleanup established that none of the 23 was loading front-end assets. This was not a speed win. It was a security, maintenance and licence-cost win — a paid performance plugin cancelled, sixteen pieces of attack surface removed, and the discovery that the paid plugin had never written a single cache file on that server, because caching had been happening at the CDN edge the entire time. Removed alongside it: the entire legacy service-page template system, which an audit showed was used by exactly zero of the 62 service-page records in the database; 558 lines of dead theme code; a 91-post legacy content type, deleted with all 91 URLs covered by redirects; and 1,784 accumulated post revisions, with a cap so they cannot come back.
What replaced them was built in-house and shipped with a kill switch — a URL parameter that disables the feature live, without a deploy, if it misbehaves in front of a real visitor. That list includes the deployment pipeline itself, built from scratch on 6 June and deliberately set to manual trigger so nothing reaches production by accident.
Analytics, CRM and email
The tracking rebuild produced three semantically distinct conversions — enquiry form, call booking, catalogue download — emitted by a single dynamic tag driven by attributes on the form itself. Adding a new form or lead magnet now requires no change to the tag manager and no change to the CRM. The old umbrella event went to zero hits from 20 June.
The CRM was migrated from amoCRM to HubSpot between 8 and 23 June and the old system fully retired on 15 July. Custom forms were kept and wired to the CRM server-side rather than embedding the vendor's own forms, a decision that avoided 100–300 KB of JavaScript on every page. Tag manager moved to a first-party domain on 13 July, recovering roughly 15% of desktop hits that ad blockers had been eating.
Email deliverability was repaired at the same time. The domain's SPF record had been broken by a single stray character — a trailing dot that made the whole mechanism invalid at strict receivers — and DMARC had no reporting address, so nobody had visibility into who was sending mail as the company. The standing advice had been to tighten the DMARC policy first, which with a broken SPF record would have started sending the company's own mail to junk.
5. Proof the loop closes
Anyone can publish a before-and-after. The harder question is whether the individual edits worked, and most agencies cannot answer it because nobody wrote down what they expected.
Four weekly sweeps between 6 and 27 July measured 65 articles against their stored baselines and wrote 65 verdicts back into the registries — 53 keep-and-recheck, 7 queued for rewrite, 5 still in measurement. Some of what that surfaced:
| Page | Position | CTR | Clicks |
|---|---|---|---|
| Architectural styles guide | 8.8 → 8.0 | 0.05% → 0.91% | 13 → 309 |
| Saudi Arabia studio listicle | 22–60 → 4.7 | 0 → 0.34% | 0 → 19 |
| Corona vs V-Ray comparison | 9.9 → 6.5 | ~0 → 0.31% | 0–1 → 23 |
| Brutalist architecture | 17 → 9.8 | 0 → 0.16% | 0 → 18 |
| 3ds Max plugins listicle | ~8.5 → 9.2 | → 3.42% | → 123 |
| What is a 3D floor plan | 5.8 → 6.3 | 0.56% → 1.00% | 7 → 29 |
Search Console, 28-day windows before and after each refresh.
The top row is the most instructive on the page. The architectural-styles guide barely moved in rank — 8.8 to 8.0 — and its clicks went from 13 to 309. That is not a ranking win, it is a snippet win: same position, an answer-first opening and a rewritten title, and eighteen times the click-through. Across the refresh set the two mechanisms show up cleanly separated rather than blended: some pages gained rank, others held rank and gained click-through, and knowing which is which is what tells you where to spend the next hour.
And the ones that failed, which are in the same log:
- A full refresh of the visualisation-portfolios listicle aimed at moving it from position 13 to 9–11. It went to 16.6 and dropped from 64 clicks to 46. Queued for rewrite.
- The outsourcing article holds page-one positions and produced 0 clicks on 11,900 impressions — the B2B intent behind that query is not what the page answers. Queued for rewrite, not for another twist of the title.
- The architectural-animation listicle had real winnable demand, and the click-through experiment on it failed while the position regressed. Queued.
Seven of 65 is a rate we are comfortable publishing, because the alternative — not measuring — produces a number that looks like zero.
6. What we chose not to do
This is where we would push back hardest on how agency case studies are usually written. A large share of the value here was in not producing content.
- US city landing pages were killed as a format. Cohort data settled it: in their first 30 days, the Chicago page produced 0 clicks, Los Angeles 0, New York 1, San Francisco 2. The format was removed from the plan instead of being scaled to twenty more cities.
- Eleven planned topics were cancelled outright after cannibalisation checks found an existing page already owned the query. One of them was already being cited in Google's AI Overview for the exact term — writing a second page would have split the signal and could only have made things worse.
- A geographic listicle that failed its demand gate was merged into a regional one, closing two calendar slots with one page rather than shipping two dead ones.
- A thin page was redirected rather than rewritten, because its entire head query set had already migrated to the service page — there was nothing left for a rewrite to aim at.
- We proved one of our own tactics did not work and stopped it. A post-test showed the pricing schema we had rolled out was not rich-result eligible. Rather than keep the effort going, we redirected it: the value of published prices turned out to live in AI Overviews, not in search-result stars.
- Output volume was tested before it was doubled. Before going from one article a day to two, we checked for diminishing returns — 54 of 55 recent articles indexed, none stuck in "crawled, not indexed", crawl freshness within three days, and no downward trend in median clicks per article by cohort. Google was not the constraint. Topics and click-through were.
- A structural risk was quantified before it became a problem. Listicles had grown to 32.1% of the blog. Rather than guess, we measured a site publicly known to have been penalised for that pattern and found its keyword profile had collapsed — and that it had not been ranking itself first, which was the assumption everyone was operating on. That reversed our own recommendation from a cosmetic fix to the real lever: grow the non-listicle share instead. It is still in progress and it is listed below as an open risk.
7. Six things that were quietly broken
Aggregate numbers are easy to publish and hard to verify. These are harder to publish and easier to verify, and for anyone technical they say more about how the work was done.
- Every page on the site had a live duplicate. Database collation is case-insensitive, so an uppercase variant of any URL returned a healthy 200 while the canonical was lowercase. The CMS's own canonical-redirect routine only rebuilds a URL when a query returns nothing — for a page that loads successfully it never compares case at all. No setting exists for this in the platform, the SEO plugin or the multilingual plugin. Ten were patched by hand in June; the systemic fix shipped on 30 July, validated against a 31-case test harness, with the redirect proven to happen in exactly one hop.
- The CRM was returning "200 OK" and throwing leads away. For three weeks every submission was accepted and routed to a spam queue as an unregistered domain, because the site was missing from one settings list. The code was correct the whole time. One checkbox took the spam queue from 65 to 0 and restored lead attribution.
- Form submissions took 7.2 seconds because of a function that does not exist on that host. The "send this to the CRM in the background" guard silently evaluated false — the server runs LiteSpeed, not PHP-FPM, and the function it checked for is a PHP-FPM feature. So the visitor sat through the entire background dispatch, including a six-second wait. Adding the LiteSpeed equivalent: 7,228 ms → 176 ms.
- A version query string was loading the JavaScript bundle twice. Module identity in the browser is the exact URL, and the CMS was appending a version parameter to the entry file while the code-splitting runtime referenced the clean one. Every top-level binding on the site was duplicated. The symptom that exposed it: one click on "load more" fired two requests and appended twelve cards instead of six.
- The animation library was not the performance problem. The optimisation started from a browser warning pointing straight at it. Measurement showed it accounted for about 5% of layout reads; the real culprit was an animation loop in the sticky call-to-action measuring element geometry on every single frame. Rewritten, per-frame layout reads went to zero — and a second, unrelated 47 ms read in the header init took a further 0.4 s off largest-contentful-paint on its own.
- Google Ads was crawling a broken URL from inside the ad account. Server logs showed 404s on a service page with a malformed tracking parameter, coming from Google's own conversion crawler — meaning a final URL in the ad account had lost a question mark. Three days had already gone into a custom logging trap that could never have caught it. The answer was one query against the host's access logs.
There is a seventh worth including because it is the least flattering. The project's own documentation instructed everyone to "test locally first". There was no local environment and no staging server — production was the only environment that had ever existed. That instruction was replaced with gates that actually exist: a build check, a syntax check, a merge-conflict check, a diff review, and an immediate anonymous verification of the live URL after every deploy.
8. How a team this size covers this much ground
The honest answer to "who did all this" is: one operator, working with modern tooling, on a live site.
We are careful about how we frame that, because the usual version of this claim is an argument about price, and it is the wrong argument. Efficiency here does not buy a discount. It buys depth — the second and third pass that normally gets cut, the audit run across all 4,055 URLs instead of a sample of forty, the refactor that ships with proof attached instead of a hope, and the weekly re-measurement that most programmes quietly drop by month three.
The project's own retrospective for the first twelve days put the volume at roughly 100–130 person-days of conventional work compressed into nine calendar days, with a line-by-line breakdown behind it. The line we find most telling is not about speed at all: 60–70% of this volume would never have been done at all. Not done slower — not done.
The mechanism that makes it safe is boring and matters more than the speed. Mass edits run through self-verifying pipelines rather than by hand. Every internal-link insertion carried its own guards — the phrase must appear exactly once, the link count must go from zero to one, the content length must change by the expected amount, no truncation marker may appear. Two of the stylesheet refactors were verified as byte-identical compiled output before they were allowed near production. That is what makes it responsible to do a month of work in a week on a site with no staging environment, and it is how we work on build and rebuild engagements generally, not just on our own property.
Maverick Frame is at maverickframe.com if you want to look at the site this was done to.
9. Where the numbers stand today
In GA4, organic sessions went from 2,046 in May to 7,941 in July. Engaged sessions went from 1,186 to 3,865, and the engagement rate on organic traffic held at 48.7% while traffic quadrupled — which is the number that tells you the growth is not junk.
On the lead side, organic-attributed lead events went from 13 in May to 42 in July, and all-channel from 36 to 97. In July specifically that breaks down as 38 enquiry forms and 21 call bookings, plus 28 catalogue downloads which we count separately because a download is not a lead. The comparison that matters: in May the tracking system was recording zero enquiry forms and zero call bookings, because it was broken.
One line in the July data deserves its own paragraph. A traffic source appeared that did not exist in the spring figures at all: AI assistants, 259 sessions and 3 lead events. Separately, Google's own translated-results feature delivered 15,262 impressions and 138 clicks from markets the site has never been localised for. Both are small. Both are new, and both are the direct result of the site being fast, cleanly structured and readable by something that is not a person.
10. What is still not solved
A case study that ends at the good news is a brochure. Five things are open, and they are the current priorities.
- The commercial pages have not moved. July: 33,678 impressions across the services section and 11 clicks — a 0.03% click-through. The blog carries roughly 86% of all site clicks. The commercial layer is built; it has not converted into rankings.
- Links are the structural ceiling. 117 referring domains against competitors sitting at 1,400–2,500. On-page work has taken the site about as far as on-page work takes anything. The next constraint is authority, which is slower and less comfortable.
- Conversion rate is flat; volume is not. Organic conversion sits around 0.53–0.64% against a 0.56% starting point. Leads tripled because traffic quadrupled, not because the funnel improved. That is the honest reading and it is the open KPI.
- Click-through is the biggest unexploited lever on the site. 807,000 impressions at average position 11.3 converting at 0.57%. Doubling that rate is worth roughly four thousand extra clicks a month with no new content — more than any content batch has delivered so far. The single clearest example is one Spanish page sitting at position 9.1 with 25,716 impressions and 5 clicks.
- Two risks we are watching rather than claiming to have solved: the Spanish section is not yet inside the weekly review loop, so nothing automatically picks up gaps like the one above; and listicles are 32.1% of the blog and trending upward as the scheduled geographic series publishes.
If the numbers in that last section look like an odd thing to publish, that is the point. They are the same list we work from on Monday mornings.
Frequently asked
Is Maverick Frame a client or your own company?
Our own. Maverick Frame is the CGI production studio the owners of Unreal Mango also own and run. That is exactly why this case can include the analytics account, the refreshes that failed and the things still unsolved — on a client site we could publish none of the three.
What period does the case cover?
Calendar year 2026 to date: 1 January to 1 August, seven months. Work on the site began on 27 May 2026, so June and July are the first two full months of the programme running. Search Console figures for July run to 29 July, the last complete day at the time of the pull.
Where do the numbers come from?
Google Search Console (property sc-domain:maverickframe.com) and GA4 property 486284340, both pulled on 1 August 2026, plus a Lighthouse run against the live homepage and a backlink pull on the same day. Counts of work done — pages shipped, links audited, verdicts written — are counted programmatically from the project’s own dated change logs.
How long before a programme like this shows up in Search Console?
On this site the first full month of work doubled clicks and the second doubled them again. That is unusually fast, and it is because the demand already existed: 410,729 US impressions in 90 days at 0.09% click-through. Unlocking impressions Google is already serving is much faster than creating demand that does not exist yet.
Did every change work?
No. Four weekly monitoring sweeps issued 65 article-level verdicts, of which 7 were "this refresh made it worse or did nothing, queue it for rewrite". One full refresh moved a page from position 13.1 to 16.6 and dropped it from 64 clicks to 46. Those verdicts are written back into the registries automatically, which is the only reason we can quote them.
What has not been solved yet?
The commercial pages. In July the service-page section collected 33,678 impressions and 11 clicks — a 0.03% click-through — while the blog carried roughly 86% of all site clicks. The diagnosis is link authority rather than on-page work: 117 referring domains against competitors sitting at 1,400–2,500. That is the next phase and it is slower than the first one.
Can you do this for our site?
The diagnostic half transfers to almost any site. The speed depends on what we find: a site with broken indexation and demand already visible in Search Console moves quickly, a site with neither needs demand built first, which takes longer. We will tell you which one you are on the first call, before anyone signs anything.
Method note. Page counts in this case study use these definitions: "blog posts" means English-language posts in the blog collection (117 at the time of the link audit); "service pages" means the 27–28 published English service pages, except where the 62 service-page records in the database are named explicitly; "case studies" means the 69 English ones. German and Spanish pages are always counted separately and labelled. Search Console figures are calendar months to 29 July 2026 unless a 28-day window is stated; GA4 figures are calendar months. Lighthouse figures are desktop lab runs — the mobile score has not been re-measured since the last round of optimisation, so no mobile number appears here.