
How we made this website faster, cleaner and easier to use
We hold our own site to the standard we set for clients. This page records every improvement: what we changed, why it matters, and the Google PageSpeed scores before and after.
Last updated September 29, 2026 · Benchmarked with Google PageSpeed Insights (Lighthouse)
The whole story in 7 minutes
We walk through our homepage audit and the five problems we see on most small business websites: oversized images, a slow main image, page builder bloat, heavy extras, and accessibility and layout shift. Then we show how we fixed each one.
Homepage scores
Google PageSpeed Insights tests every page twice: once as a mid-range phone on a slow mobile connection (the tougher test), and once as a desktop computer. Switch between the two below.
- 89
Performance
was 60
- 100
Accessibility
was 87
- 100
Best Practices
was 96
- 100
SEO
was 100
Mobile scores, measured September 29, 2026. The small print shows where each score started on September 18. Performance scores move a few points from run to run because Google's test conditions vary; runs since the new theme went live have landed between 81 and 89.
- 97
Performance
- 100
Accessibility
- 100
Best Practices
- 100
SEO
Desktop scores, measured September 29, 2026. We didn't record desktop scores before the work began, so there are no “before” figures here. Desktop Performance runs since the new theme went live have scored between 97 and 100.
What changed, in plain figures
805 KB27 KBStyling code per page
The page builder loaded 805 KB of styles on every page. The new theme loads one 27 KB file, about 97% less.
9.0 s3.8 sMain image on screen (mobile)
Largest Contentful Paint: how long until the biggest thing on the page appears. 9.0 seconds in the first audit, 3.8 seconds now.
280 px65 pxHeader height on phones
The old header took up a third of a phone screen. The new one is a single slim bar, so content starts right away.
20Page-builder plugins
Elementor and Royal Elementor Addons are switched off. Fewer plugins means less code, fewer updates and fewer things to break.
98.8 KB18 KBBridge photo on phones
The hero photo is now cropped and sized for the screen it's shown on: 18 KB on phones and 32 KB on desktops.
- 20
Blog posts rebuilt
Every article was moved out of the page builder into standard WordPress content, with messy pasted formatting cleaned up.
Mobile Performance over time
Every homepage test recorded in this log, in order.
- Sep 18 · first auditPage builder, original images60
- Sep 18 · afternoon re-checkContrast fixes, local fonts66
- Sep 19 · end of dayHero image and layout fixes83
- Sep 29 · before startingSite had grown since Sep 1959
- Sep 29 · images optimizedHero, featured project, lazy map74
- Sep 29 · new theme livePage builder removed87
- Sep 29 · final re-checkSame page, later run89
Between September 19 and 29 the services, about, portfolio and contact pages were rebuilt and the homepage changed, so we re-measured before starting new work rather than assuming the old score still held.
Every improvement, newest first
September 29, 2026
Replaced the page builder with a custom-built theme
The biggest remaining drag on speed was the page-builder stack itself, which loaded hundreds of kilobytes of code on every page whether it was used or not. We wrote a lightweight theme from scratch and rebuilt everything that still depended on the builder.
New header
One slim bar that stays at the top as you scroll, with the logo, a Services dropdown and a one-tap call button. On smaller screens it switches to a menu button instead of wrapping onto two lines.
Why it matters: 65 px tall on phones instead of about 280 px, and the dropdown works with a keyboard as well as a mouse.
New footer
A four-column footer with services, company links, social icons and a phone number. The Google map loads only when someone clicks "Show map".
Why it matters: the map used to load about 400 KB of Google code on every page, for every visitor.
20 blog posts rebuilt
All articles were converted from the builder into standard WordPress blocks. We cleaned out formatting pasted from other editors, and kept tables, quotes and the audio player.
Why it matters: posts are lighter, and they can now be edited in WordPress's normal editor.
New article layout
Each article now opens with its topic, date and reading time, then the featured image, followed by a free-mockup offer and three related articles.
Why it matters: readers can see what to read next, and they have a clear next step.
Articles page redesigned
A card grid with topic filters and page numbers, which becomes compact rows on phones. Topic pages, search results and the "page not found" screen use the same design.
Why it matters: it's easier to browse, and every page on the site looks consistent.
Images sized for the screen
The bridge photo now comes in a 32 KB desktop version and an 18 KB phone version, and it loads first. The featured project photo comes in two sizes, and the logo in two sizes.
Why it matters: phones stop downloading desktop-sized pictures.
Two plugins switched off
Elementor and Royal Elementor Addons are deactivated. Visitors now get one small stylesheet, and the page no longer loads the jQuery library.
Why it matters: less code to download, fewer security updates, and a faster first paint.
Checked on every page
We checked the pages at phone width for sideways scrolling and made wide tables scroll inside their box. We also fixed the contact form's loading spinner and the menu highlighting.
Why it matters: a faster site is only worth it if nothing else breaks.
September 19, 2026
Homepage loading and layout fixes
These fixes focused on how quickly the homepage's main image appears, plus page structure and consistent links. Several of them worked around page-builder limits and have since been replaced by the new theme.
Main image loads first
The bridge photo changed from a background style to a real image marked high priority, so the browser fetches it right away. It was also excluded from the host's delayed-loading script.
Phone-sized hero photo
We pre-cropped the phone version to the shape it's shown at, cutting it from 98.8 KB to 25.8 KB with no visible difference.
Main content landmark
The homepage got a proper "main" landmark so screen-reader users can jump straight to the content. Six layout side effects from the builder were fixed along the way.
Consistent contact links
All phone links now use the same international format, and every "Get a Free Consultation" button goes to the same contact page.
Result: mobile Performance 83 and Accessibility 95.
September 18, 2026
First audit: readability, trust and images
We ran the first full PageSpeed audit and fixed everything that made text hard to read or content hard to trust.
Readable text and stars
We darkened the light-gray review bylines, the pale gold star ratings and one low-contrast paragraph so all of them meet the WCAG AA contrast standard.
Verifiable reviews
Testimonials now link to our real Google Business Profile, and a new "Write a Review" button opens Google's review form directly.
Case-study section fixed
The E-Commerce case-study section got a solid fallback background, so its text stays readable while the photo loads. The photo now fits at every screen width.
404 KB image → 29 KB
We converted the food bank case-study image from PNG to WebP, 93% smaller. Fonts are now served from our own server, and the footer map got a title for screen readers.
Result: the afternoon re-check showed Performance up to 66, with the accessibility fixes counted in the next day's run.
What's next
We track what's left the same way we track what's done.
- Analytics script (about 170 KB). Google's tag, which powers our visitor statistics, is now the largest file on the page. We're keeping it on purpose, but it's the next thing to look at.
- Image lazy-loading script. The host's lazy-loading helper causes one small layout recalculation, about 70 ms. It's minor, but it's on the list.
- Main image timing on phones. The bridge photo downloads quickly, but it can take up to about 1.8 seconds on Google's slow-phone test before it's drawn. That delay is the main thing between us and a mobile score in the 90s.
- Final cleanup. After a short safety window, we'll delete the switched-off page-builder plugins completely.
Full technical notes from September 18–19 (original log)
The original, detailed engineering notes: exact colors, file sizes, root causes and the mistakes we caught along the way. They're kept unedited for the record.
This page tracks the SEO, performance, and accessibility audit and improvements made to tacomawebdesigners.com, using Google Lighthouse (via PageSpeed Insights, mobile) as the benchmark. Updated September 18, 2026.

Latest PageSpeed Insights snapshot (mobile), captured September 18, 2026. Scores fluctuate slightly between runs due to Google's testing variance.
Homepage — Baseline Audit
Lighthouse mobile scores captured before changes:
| Category | Score |
|---|---|
| Performance | 60 / 100 |
| Accessibility | 87 / 100 |
| Best Practices | 96 / 100 |
| SEO | 100 / 100 |
Key issues found: Largest Contentful Paint (LCP) of 9.0s, render-blocking CSS/JS, unused CSS/JS, low-contrast text in two homepage sections, and a missing <main> landmark.
Fixes Applied & Verified
Click a category below to jump to its first fix. The bolded lead-in of each fix is color-coded by category; the rest of the description stays neutral for readability.
Accessibility Best Practices SEO / Trust
| Category | Fix |
|---|---|
| Accessibility | Fixed low-contrast text in the client testimonials section. "Google Review" byline text was light gray (#888) on white — a 3.54:1 contrast ratio, below the WCAG AA minimum of 4.5:1. Darkened to #595959 (now ~7:1). Verified live on the site. |
| Accessibility | Fixed skipped heading level in the site header. The "Tacoma Web Designers" site title in the header was marked up as an H3, appearing before the homepage's own H1 with no H2 in between — a heading-order violation. Edited directly in the Elementor Header template (accessible via the normal Elementor editor UI at wp-admin/post.php?post=32&action=elementor, even though it doesn't appear in the Templates list) and changed its HTML tag to H2. Verified live: heading order is now H2 → H1 → H2 → H3... |
| Accessibility | Fixed invisible hero paragraph text (corrected twice). A homepage paragraph sits in a column with a white/near-white CSS gradient background layered over the section's blue background. My first automated contrast scan only checked flat background-color and missed the gradient, so it misread the true background as solid blue and set the text to white — which actually made it invisible against the real (near-white) background. The user caught this live. Corrected to dark gray (#222) which reads clearly against the actual gradient. Verified live with a screenshot. |
| Accessibility | Fixed invisible heading/button in the E-Commerce & Brand Consolidation case study section (caught via user screenshot). The section background map image used background-size:contain, so on narrower widths the image shrank and left plain white space behind the white heading and Case Study button, making them unreadable. Added a dark blue fallback background-color plus background-size:cover so the image always fills the box. Verified live with a screenshot. |
| Accessibility | Fixed low-contrast gold star ratings. The 5-star review icons used #f5b400 gold — only 1.7–1.8:1 contrast against their white/light-blue backgrounds. Darkened to #7a5c00 (6.25:1 against white), keeping the gold look while passing WCAG AA. Verified live. |
| Best Practices | Fixed the E-Commerce & Brand Consolidation map at wide desktop sizes (1920×1080). The map graphic's natural ratio (1.45:1) was much taller than the section's wide desktop box (~3:1), so background-size: cover — which fixed the mobile white-gap bug — was cropping most of the map off at desktop widths. Switched to background-size: contain, which now shows the full map centered on the dark blue fallback background at every screen size. Verified at 1920×1080. |
| SEO / Trust | Added source links to the "What Our Clients Say" testimonials. Both review cards, the "Google Reviews" summary line, and the star rating now link out to the business's real Google Business Profile (g.page/r/CZUwWZ3aFgSGEBM) so visitors can verify the reviews are genuine. Confirmed the linked profile shows the same two reviewers (Jeannine Sigafoos, Kathryn Melin) with matching review text. |
| SEO / Trust | Added a "Write a Review" button. Links directly to the Google review-submission flow (g.page/r/CZUwWZ3aFgSGEBM/review) so visitors can leave a review in one click. |
All fixes were shipped through the site's Additional CSS (Customizer) or the homepage's Elementor content so they apply sitewide wherever those components repeat, and the host cache was purged immediately after publishing.
Still Open — Recommended Next Steps
- Performance (biggest opportunity): LCP is 9.0s on mobile, driven by render-blocking requests (~380ms), unused JavaScript (~405 KiB) and unused CSS (~99 KiB) from the large Elementor/plugin stack. Recommend enabling SiteGround Optimizer's CSS/JS minify + combine and deferring non-critical plugin scripts (chat widget, parallax libraries) below the fold.
- Accessibility: add a semantic <main> landmark wrapping the homepage content (the theme currently outputs three sibling top-level divs — header, content, footer — with no <main> wrapper). Correction: the header/footer templates are NOT actually REST-blocked as earlier noted here — they're editable directly through the normal Elementor editor UI (just not listed in wp-admin's Templates screen). The header's skipped heading level has already been fixed this way (see table above); the <main> landmark still needs a template-structure change rather than a simple widget edit, and the header logo's alt text was already correctly set (not blank as previously stated here) — no action needed there.
- Full-site audit: this pass covered the homepage in depth. Services, Portfolio, About, Contact, and the service sub-pages (Website Design, SEO, Social Media, Maintenance) still need the same Lighthouse pass and fixes.
Homepage — Interim Re-Check (Sep 18, 2026, 2:08 PM)
A live PageSpeed Insights re-run, screenshotted directly from pagespeed.web.dev (captured after the first two contrast fixes but before the E-Commerce section fix below). Performance fluctuates run-to-run with Google's live lab environment, which is expected and unrelated to the fixes tracked here:

Live PageSpeed Insights snapshot (mobile) captured just now, reflecting all fixes applied today.
| Category | Before | Interim |
|---|---|---|
| Performance | 60 / 100 | 65 / 100 |
| Accessibility | 87 / 100 | 87 / 100 |
| Best Practices | 96 / 100 | 96 / 100 |
| SEO | 100 / 100 | 100 / 100 |
LCP improved from 9.0s to 5.3s and Speed Index from 5.8s to 3.8s between runs (some of this is normal test-to-test variance, not purely from the CSS fixes). Accessibility stayed at 87 because Lighthouse was still catching the E-Commerce section's invisible white-on-white heading/button at the time of this run — that was fixed immediately after, so the next full re-check should show a real accessibility gain.
Update: a follow-up PageSpeed Insights check at 2:19 PM (after the star-color fix but reflecting the earlier text-color mistake, see correction above) still showed Accessibility at 87 and a fresh contrast flag. Root cause: gold star ratings at #f5b400 (1.7–1.8:1 contrast) were still unfixed at that point. They were fixed immediately after and verified live at 6.25:1.
A live re-check run just now (screenshot above) confirms Performance at 66/100 and Accessibility holding at 87/100. The remaining accessibility gap is explained under "Still Open" below — mainly the missing <main> landmark and blank header logo alt text, neither of which has been fixed yet.
2026-09-18: Image delivery + iframe accessibility fixes
Following a PageSpeed Insights re-check (mobile), two more findings were fixed:
- Load Google Fonts Locally was disabled in Elementor's Performance settings; enabled it so fonts are served same-origin instead of blocking on a third-party Google Fonts request. Performance score moved from 57 to 69 on the next PSI run.
- Improve image delivery (59 KiB finding): the case-study image on the homepage ("families-unlimited-food-bank...") was a 404 KB PNG rendered at ~515×344px. Re-encoded it to WebP in-browser (canvas re-encode at the existing 768×513 size, quality 0.82) — new file is 29 KB, a 93% reduction. Uploaded as a new attachment and swapped it into the homepage's Elementor Image widget. Verified live: the page now serves the WebP file instead of the PNG.
- Iframe without title (accessibility): the Google Maps embed in the footer had an empty
title=""attribute. Addedtitle="Google Map showing Tacoma Web Designers location in Tacoma, WA"to the embed's raw HTML (footer template, Text Editor widget). Verified live viadocument.querySelector('iframe').title.
Note: a contrast "fix" was briefly applied and reverted during this session — a script misjudged the background behind a homepage paragraph as blue when it is actually white, and the text was mistakenly set to white before being caught and reverted back to the original #222222 (correct, matches the site's real white background). No lasting change was made there.
2026-09-19: Mobile-specific hero background image
Lighthouse's mobile PageSpeed run flagged the Tacoma Narrows Bridge hero background (155 KB AVIF) as one of the biggest remaining "Improve image delivery" opportunities (53.6 KiB estimated savings), even though the file was already AVIF. Testing confirmed re-encoding the whole image to WebP didn't help (AVIF was already more efficient at that resolution) — but a heavier-compressed WebP (quality 0.65) came in at 98.8 KB, under Lighthouse's target.
Rather than degrade the image for everyone, used Elementor's native per-breakpoint background control (background_image_mobile) to serve the 98.8 KB compressed WebP only below the mobile breakpoint, while desktop keeps the original 159 KB AVIF untouched. Verified separately at both viewport sizes after Elementor's compiled CSS file was regenerated (Elementor › Tools › Clear Files & Data) and the host cache purged.
Note: this site's Elementor-generated CSS files (wp-content/uploads/elementor/css/post-*.css) are served with a 1-year max-age and no cache-busting version query string. That means a repeat visitor who already has last week's CSS cached in their own browser won't see CSS-level changes (like this one) until that cache naturally expires or they hard-refresh — a real gap in the site's asset-versioning setup, not something fixable from a wp-admin browser session. New/first-time visitors are unaffected.
2026-09-19: Hero background converted to a real <img> for LCP priority
Lighthouse's LCP request discovery check flagged the homepage hero (the Tacoma Narrows Bridge section) because it was a CSS background-image, which can never get fetchpriority="high" or be discovered directly from the initial HTML — both attributes only apply to real <img> elements.
Fixed by adding a real, absolutely-positioned <picture>/<img> as the first child of the hero container (behind the heading/text via a negative z-index), and removing the container's CSS background entirely so the image isn't loaded twice. The <picture> element preserves the existing mobile/desktop responsive split (the 98.8 KB compressed WebP below 768px, the original AVIF above it) via a <source media="(max-width: 767px)">, matching what the old per-breakpoint background setting did. The image now carries fetchpriority="high" loading="eager" decoding="async".
Verified: compiled CSS for the hero container no longer contains a background-image rule, the live page renders the correct image at both mobile and desktop widths, and the heading/subtext/button still layer correctly on top with no visual change from before.
2026-09-19: Fixed regression — hero image invisible after the <img> conversion
Bug: right after converting the hero background to a real <img> (see previous entry), the user reported the bridge image not showing at all after clearing their browser cache.
Cause: SiteGround Speed Optimizer's "Lazy Load Media" feature automatically rewrites every <img> on the page — including ones inside a raw HTML widget — converting src to data-src and adding class="lazyload", deferring the load until a JS library detects it's in the viewport. This silently undid the whole point of the fix (immediate, high-priority discovery) and left the image dependent on that JS firing correctly.
Fix: the site already had a configured "skip-lazy" exclusion class under Speed Optimizer › Media › Exclude CSS Classes from Lazy Load. Added class="skip-lazy" to both the <picture> wrapper and the <img> itself. Verified via a direct no-cache fetch of the live HTML that the real src attribute now survives untouched (no more data-src/lazyload rewriting), and confirmed visually that the image renders immediately.
Lesson: any future real <img> added directly via HTML/code (bypassing Elementor's own Image widget, which is presumably already excluded from lazy-load by the optimizer) needs the "skip-lazy" class if it's meant to load immediately/eagerly — otherwise SiteGround's optimizer will lazy-load it regardless of loading="eager"/fetchpriority="high".
2026-09-19: Hero bridge image invisible on real browsers — Elementor auto-position/zero-height containing-block bug
After converting the hero background to a real <img> for LCP priority (see prior entry), the image silently stopped rendering for site visitors on 2 separate real browsers, even though every server-side check (raw HTML source, fetch of the AVIF file, response headers, Elementor CSS cache regeneration, SiteGround cache purge) came back correct. The image was fully downloaded and decoded (confirmed via canvas pixel sampling) but rendered at 0 pixels tall.
Root cause: Elementor automatically sets position: relative on every widget wrapper div (here, the HTML widget wrapping the <picture>/<img>). That wrapper — not the intended hero container two levels up — became the CSS containing block for the absolutely-positioned image. Since the wrapper's only child was itself out-of-flow (absolutely positioned), the wrapper had zero content contributing to its own height and collapsed to height: 0. With inset: 0 on the image, its height resolved against that zero-height containing block, so the image computed to 0px tall — fully loaded, fully decoded, completely invisible.
Two false leads before finding it: (1) Elementor's own "z-index" advanced control only writes a CSS custom property (--z-index) that isn't actually applied as a real z-index for this element/selector combination — setting it had zero visual effect and left the container's computed z-index at auto. (2) Adding isolation: isolate to the hero container to force a stacking context was a real improvement (prevents the negative z-index image from ever escaping to paint behind the whole page) but did not fix this bug, since the failure was a containing-block/height problem, not a stacking-context problem.
Fix: Added .elementor-element-21f187f{position:static !important;} via Additional CSS, forcing the containing block for the absolutely-positioned image to bubble up to the hero container itself (which has real, non-zero height), while leaving the image's own position:absolute untouched.
Why this was so hard to catch: the bug only reproduced reliably in a real Chrome browser under real load conditions; multiple headless/private-window checks from this session's own browser tooling rendered the image correctly despite the same underlying HTML/CSS, likely due to rendering-engine or timing differences. The lesson: when a visual bug is denied by "the HTML is correct" and "it works in my browser," check actual computed box dimensions (getBoundingClientRect, computed height) in the reporting browser itself, not just markup and file delivery.
2026-09-19: Mobile hero image re-cropped — 98.8 KiB → 25.8 KiB
Latest PageSpeed run flagged the mobile hero image for another 77.7 KiB of savings. The mobile <source> was serving the full 1458×429 wide desktop frame and relying on CSS object-fit:cover to crop it down to the mobile hero's narrow, tall display box at render time — meaning the browser downloaded and decoded the entire wide frame just to show a thin center slice of it, upscaled ~3x to fill the box.
Fixed by pre-cropping the image itself to the exact aspect ratio of the mobile display box (center 235×429 slice of the original), so no wasted width is downloaded and no client-side crop is needed. Result: 235×429 WebP at 25.8 KiB, down from 98.8 KiB — a 74% reduction, same visual result.
Investigated but skipped: the small header logo (TWD_Logo.avif, 149×86, 7.3 KiB) was flagged for both "low resolution" and "image delivery" savings. Re-encoding it at the higher resolution Lighthouse wants (224×129) produced an 18.7 KB file — 2.5x larger than the current one — because the source content is mostly fine detail (circuit-board lines) that doesn't compress well at that size. Fixing the resolution complaint would directly contradict the delivery-size goal, so left as-is; not worth it at this file size.
2026-09-19: Added missing <main> landmark to homepage
Lighthouse flagged "Document does not have a main landmark" — the homepage's 6 top-level Elementor sections sat directly under <body> with zero semantic wrapper. Fixed by creating a new Elementor Container set to render as a real <main> tag (via the free "HTML Tag" advanced control) and moving all 6 existing sections inside it, preserving their order.
Regression caught immediately: the new wrapper container defaulted to Elementor's "boxed" content width (1140px max), which clipped the full-bleed hero section that needs to span edge-to-edge — it visually disappeared for real site visitors even though every programmatic check (image decode, computed height, topmost element at point) looked correct. Fixed by explicitly setting the new wrapper's content width to "full". Verified afterward using Claude in Chrome on the actual browser tab, not just this session's own browser pane.
2026-09-19: Second regression from the <main> wrapper — default 10px padding on every section
After fixing the boxed-width regression, the new wrapper still had a 10px default padding on all sides — inherited from Elementor's global default container style, since every other hand-built section on this page already had its own explicit "padding: 0" override that a brand-new container doesn't get automatically. This showed up as a visible inset/border around every full-bleed section (hero image, blue background bands) instead of them reaching the true page edge. Fixed by explicitly setting the wrapper's padding to 0 on all sides.
Takeaway for next time a wrapping container gets added around existing full-bleed content: a brand-new Elementor container does not inherit "invisible" explicit resets (padding, content width) that existing sibling/sections have — it falls back to Elementor's global defaults instead. Any full-bleed page needs its wrapper explicitly zeroed (content_width: full, padding: 0) rather than assuming blank settings behave like the rest of the page.
2026-09-19: Third and fourth regressions from the <main> wrapper — rounded image corners and 20px gaps between every section
Same root cause as the previous two fixes, different defaults: the new wrapper's blank flex_gap setting fell back to Elementor's global default 20px flex gap, inserting a visible white gap between every one of the page's 6 sections. Separately, the hero image picked up a 20px border-radius from a theme/global image style that a structural change in ancestor nesting made newly applicable (most likely a specificity shift — an existing more-specific override no longer matched with the extra <main> wrapper layer in the ancestor chain). Fixed by explicitly setting flex_gap to 0 on the wrapper, and adding an explicit border-radius:0 to the hero image's own inline style (highest specificity, safest against future ancestor changes).
Running total: adding one <main> landmark wrapper around existing content surfaced four separate blank-default regressions (boxed width, padding, flex gap, and an image's border-radius via specificity shift) — all from the same pattern: a brand-new Elementor container does not inherit any of the "invisible" explicit resets or specific selector overrides that already-tuned content relies on. Every one of these was invisible in this session's own browser tooling on first glance and only surfaced clearly once checked against the user's real Chrome tab at full scroll depth.
Fifth and sixth regressions from the <main> wrapper — content width and leftover default padding
After the previous two regressions (default padding, default flex-gap) were fixed, two more surfaced from the same root cause: the new <main> wrapper container (id 44aa3b5) not inheriting the page's existing hand-tuned defaults.
Issue 5 — Hero text and food-bank section too wide. The hero heading/paragraph/button and the food-bank case-study section had lost their original constrained, readable width and were stretching edge-to-edge with the full-bleed background. Root cause: the hero container (b1baf0d) and food-bank container (c285ae4) both had "content_width" set to "full," meaning their normal in-flow child widgets (text, buttons) had no inner width-constrained wrapper — only the absolutely-positioned hero image bypassed this via the position:static trick. Fixed by setting content_width to "boxed" on both containers, which restores the standard pattern: the outer box still renders full-bleed for the background/image, while normal-flow content gets wrapped in a centered, ~1140px-max inner wrapper.
Issue 6 — Extra ~10px whitespace around the "What Our Clients Say" section. Three sections (ef31628, 57e529a, 336e87e) still had blank/unset padding, which falls back to Elementor's global default of 10px on all sides — the same default-padding issue caught earlier on the <main> wrapper itself, but this time on three of the individual sections it now contains. Fixed by explicitly setting padding to 0 on all four sides for each of the three sections.
Running total: six separate blank-default regressions traced back to the single <main> landmark addition, all caused by new/moved Elementor containers falling back to global defaults instead of matching the page's existing all-zero overrides. Verified in the user's real Chrome tab per the verification discipline noted above — confirmed resolved ("That's better").
Duplicate/inconsistent links — phone number href format
Resumed the accessibility "identical links" investigation paused earlier in this audit. The site has three phone-number links (header, mid-page footer CTA band, and page footer), all displaying "(253) 987-6029" but pointing to two different tel: href formats: tel:2539876029 (missing the country code) on the header and page-footer links, versus tel:+12539876029 (E.164 format) on the mid-page footer CTA. Normalized all three to tel:+12539876029 for consistency and correctness on international/VoIP dialers. Header link lives in the separate "Header" Elementor document (post ID 32, widget ccf18db); page footer lives in the separate "Footer" Elementor document (post ID 51, widget 9a24495) — both are outside the homepage's own Elementor document (ID 11) and had to be edited directly.
Also flagged, not changed: the "Get a Free Consultation" button appears with two different destinations depending on section — /contact-us/ (header nav + one CTA) and /contact/ (mid-page footer CTA). Both are live, separate 200-OK pages, not a redirect pair. This looks like a genuine duplicate-page issue rather than a link-text/accessibility issue, and changing which URL a button points to is a content decision — left as-is pending the site owner's input on which URL should be canonical.
Verified on the live site via the user's own Chrome tab after a cache purge, per the verification discipline established earlier in this log. The header, footer, and logo icon-link (which already had a proper alt text and needed no change) were all checked.
Consolidated "Get a Free Consultation" button to one destination
Per the site owner's direction, standardized on /contact-us/ as the canonical contact page. The mid-page footer CTA band (homepage document, widget 935bb31) previously pointed to /contact/; updated its href to /contact-us/, matching the header nav link and the other "Get a Free Consultation" button. Both buttons now point to the same page. Verified in the user's real Chrome tab after a cache purge.
Updated PageSpeed Insights results — Sep 19, 2026
Re-ran PageSpeed Insights (mobile) after all fixes above, including the <main> landmark regressions, content-width corrections, and the duplicate-links cleanup.

Performance climbed from the original baseline of 59 to 83, Accessibility from 87 to 95, with Best Practices (96) and SEO (100) holding steady.
Want your images fixed like ours?
Shrinking our images alone took the homepage from 59 to 74 on mobile, before any other speed work. We offer the same image cleanup for WordPress sites.
Want the same results for your website?
We'll audit your site, show you what's slowing it down, and fix it the same way we fixed ours.