Whitaker & Hollis
A reference build for a Denver business-litigation firm.
Whitaker & Hollis is not a client. It is a fictional firm, and this is a reference build — a complete law firm website, made so that everything we say about law firm websites can be measured against a real one instead of described.
We did it this way because the alternative is worse. A portfolio of client work shows you sites we were paid to make, under constraints you cannot see, with content we did not choose. A reference build has no client to protect, so it can be scored in public, in full, against a standard published before it was built.
So it is. The site scores 22 passes, 0 failures and 2 not-applicable against our own 24-check standard — and the two that do not apply get named rather than quietly dropped. Call tracking: a static demo serves one number to everybody, so it cannot pass; on a site we deliver, that number is tracked and forwards to the firm's own line. Colorado's costs disclosure: it attaches to “no fee unless we win,” which a fixed-fee commercial firm never says. A page that only publishes its passes is not evidence of anything.
A cold load on a real phone, uncut
A cold load on a phone, on a throttled 4G connection, uncut. Then a scroll, then a tap on the call bar.
The clip opens on a second and a half of black. That is the page loading, at real speed, not an edit. It is the only clip on this page that has not been cut for pace, because the load is the thing being demonstrated and a load you do not have to sit through proves nothing.
Eight agency-built sites, scored before we built anything
Most law firm websites are not bad. They are unmeasured — built to a brief that never said what the site had to do, then handed over with nobody having checked whether it does it.
So we wrote down what a law firm website has to do, in 24 checks that can each be verified from outside the firm with no analytics access and no cooperation from anyone. Then we took eight websites built by agencies that specialise in law firms — the good end of the market, not the cheap end — and scored them.
Then we built one to the standard, and scored that too.
The two numbers that started it
The slowest of the eight to finish loading. Re-measured three times, alone, on a warm network, in case it was us. It was not.
Measured on eight agency-built law firm sites, 2026-08.Cannot tell you which phone calls came from their website. The site serves every visitor the same phone number, so no call it produces is attributable to it.
Measured on eight agency-built law firm sites, 2026-08.Neither of those firms knows. Both are paying for the site every month.
One job, and twenty-four ways to check it from outside
A law firm website has one job that matters more than the rest of them combined: get a person who already has a problem to pick up the phone. Nearly everything else serves that, and nearly all of it is checkable from outside the firm.
So we wrote twenty-four checks. A callable number in the first viewport that survives a scroll. Cold speed on a phone, not the desktop score. A page per attorney and per practice area — one firm in the sample, whose entire brand is its two partners' names, has no attorney pages at all. A form that qualifies rather than collects, carrying the attorney-client disclaimer. Structured data saying what the firm is: 2 of 8 manage it. And the one almost nobody passes — saying what happens after you send the form, which only 30% of Clio's secret shoppers could work out from a website.
All twenty-four are external, about ten minutes per site.
Three departures, one of them from our own standard
Three, all of them departures from something — including from our own standard.
The attorneys go high, against the pattern and against our own first draft
Eight out of eight sites in our sample put the attorney roster low, and our own standard said to do the same. We put it second. That pattern comes from personal-injury sites, which sell an outcome; a business-litigation firm sells named people. Proof still lands before the practice areas, so the check holds either way.
Every attorney and every practice area gets a real page
Six attorneys, six URLs. Five practice areas, five URLs. A referral is a person sent to a specific attorney by name; with no page to land on, they land on a homepage and start looking.
Every practice-area page runs the same three parts: what we handle, how a case runs, what it costs. That last one is what almost nobody ships.
The structured data corrects our own standard
Our standard said to type every attorney as schema.org/Attorney. We wrote that, then found it was wrong: Attorney descends from LocalBusiness, so it asserts a person is a business. What shipped: the firm is the Attorney, each bio a ProfilePage wrapping a Person — standard amended, build not bent. Check it in your own browser in five seconds; that is the only reason the claim is worth making.
Twenty-four routes, and not one page builder
Twenty-four routes. A WordPress theme written by hand — no page builder, no starter theme, no plugin stack holding the layout together.
Across 36 client sites from 11 agencies at the top of this market, zero use a page builder; of those agencies' own 52 marketing sites, 9 run Elementor. They do not ship what they run.
The intake form
Seven fields: first name, last name, email, phone, matter type, county, message. Matter type and county make it a qualifying form rather than a collecting one — one routes the enquiry, the other lets a firm decline a matter outside its jurisdiction before anyone's time is spent. The attorney-client disclaimer sits above the submit button, not in a footer link: a P0 check, and the one most of the sample gets wrong.
A note on the dropdown. Matter type is a native select, so you will see it change value but not open — an open native dropdown is drawn by the browser, not the page, and no screen recording can capture it. The options are the five practice areas plus Something else.
What happens after you send it
Check D5 — the widest gap on the sheet between how hard a thing is and how rarely it is done. The Clio figure above, answered in four sentences.
The rest of it
Three insight articles and an index, a who-we-are page, a disclaimer page, a privacy page, and a 404 that lists every route on the site instead of apologising.
One thing here is not real, and we would rather say so than have you find it: search returns a fixed set of results, because the demo is a static export with no server to query. On a delivered site it works normally.
Including the page that misses
Our agreement puts a number on this: largest content painted under 2.0 seconds on 4G, measured on the delivered site at handover. It is in the contract rather than the brochure, which means it is the kind of promise you can hold us to.
Here is that same test run against this build. Throttled to a 4G phone — 390×844, 150ms of latency, 1.6 Mbit/s, a quarter of the processor speed — with the cache cleared before every run, five runs per page, median reported.
| Route | Largest content painted | Against our own 2.0s |
|---|---|---|
| Homepage | 1,804ms | passes |
| Practice area | 1,992ms | passes, by eight milliseconds |
| Attorney bio | 2,000ms | exactly on the line |
| Contact | 2,540ms | misses |
The contact page misses, and it is the worst page on the site to miss on, because it is the one the whole thing converts on.
We can tell you exactly why. That page ships 399.8 KB. The stylesheet is 93.9 KB and the six font files are another 135 KB — 229 KB, fifty-seven per cent of the page, before a word of content arrives. On the interior pages nothing is waiting on an image at all; the page simply cannot finish until the last byte lands. The fix is font subsetting and splitting the render-blocking stylesheet. Neither is done. Both are known.
Why publish that. Because you can run this test yourself, on the live demo, in about ninety seconds, and finding a 2.5s page under a page that claimed 1.8s would tell you something much worse about us than a slow contact page does.
Two speed numbers appear on this page and they are different tests. Do not merge them.
34,671ms, in the teardown above, is a cold unthrottled desktop load measured to readyState: complete — everything the visitor waits through, including every chat widget and tracker. 1,804ms, here, is throttled mobile largest-contentful-paint. The first answers how long until this site stops loading; the second answers how long until the visitor sees something. Quoting one against the other's threshold would be overstating, in either direction.
Scope and performance, both in writing before anything starts
Scope is a page count, agreed up front. A firm site of this shape is one page per attorney and one per practice area, plus home, about, contact and the standard legal pages. With it: the intake form, click-to-call everywhere, the sticky mobile call bar, structured data, on-page SEO, SSL and analytics, Search Console connected, a 45-minute handover with a written guide, and 30 days of bug fixes.
A larger firm is the same build with a bigger count — more attorney bios, more practice areas, and a case results page with the disclaimers that requires. Extra bios, extra practice areas and call-tracking setup are settled against your real page count before anything starts, not assumed.
Three weeks from receipt of content. The clock starts when your content arrives, not when the agreement is signed — waiting on photographs and bios is the single most common reason a build of this size runs long.
Performance is in the agreement, not in the brochure: Lighthouse mobile 90+ and largest content painted under 2.0s on 4G, measured on the delivered site at handover, on the hosting named in the agreement.
Go and check it.
Every number on this page was measured on the demo, and the demo is live. Open it on your phone, run Lighthouse at it, read its source.