Websites / Cloudflare
Pre-Cutover Visual Diff
SOP: Pre-Cutover Visual Diff
Section titled “SOP: Pre-Cutover Visual Diff”Last Updated: 2026-04-30 Version: 1.0 Tier: Pre-Cutover Quality Gate (mandatory before client review)
Purpose
Section titled “Purpose”Side-by-side compare every cloned site against its source URL before the client ever sees it. Catches missing widgets, drifted images, collapsed sections, and other “looks fine but isn’t faithful” issues that the basic build audit misses.
This step exists because the build pipeline confirms “does it render,” not “is it pixel-perfect against source.” Real fidelity needs human eyes on both versions at the same time.
If you skip this step, the client will spot the issues during review (embarrassing) or after cutover (worse).
Where this fits in the pipeline
Section titled “Where this fits in the pipeline”flowchart LR Clone["/clone-gate skill<br/>builds the clone"] --> Deploy["Deployed to<br/><slug>.pages.dev"] Deploy --> ThisSOP{"This SOP:<br/>Pre-cutover<br/>Visual Diff"} ThisSOP -->|findings| Fix["Branch → fix → PR → merge"] Fix --> ThisSOP ThisSOP -->|zero P0/P1| Client["Send test URL<br/>to client for review"] Client -->|approval| Cutover["/site-cutover skill<br/>flips DNS"]
style ThisSOP fill:#fbbf24,color:#000 style Cutover fill:#22c55e,color:#fffWhen to Use:
- After a clone is built and deployed to
<slug>.pages.dev - Before sending the test URL to the client
- After every round of fix-then-redeploy
Owner: Web Designer (runs the diff), Nick (signs off on findings before client sees URL) Timeline: 45–90 minutes per site for a thorough diff on a 20–30 page clone.
The 6-page sample
Section titled “The 6-page sample”You don’t audit every page. You audit a representative sample.
For most clients:
- Homepage — most-visited, all marquee elements
- About page — team photos, brand story, often unique layout
- One service page — pick the most central to the business
- One location / city page (if applicable) — checks dynamic content patterns
- Contact page — has the form (most common cutover-blocker)
- One blog post (if blog exists) — checks blog template
If site has unusual pages (gallery, portfolio, calculator, ecommerce), add those.
The 10-point check, per page
Section titled “The 10-point check, per page”Open source URL and clone URL side-by-side at 1440px width. Then check:
1. Hero / above-the-fold
Section titled “1. Hero / above-the-fold”- Same hero image / video?
- Same headline + subhead text (verbatim, not paraphrased)?
- Same CTA button text + position?
- If hero is a slideshow/carousel, do all slides match?
2. Navigation
Section titled “2. Navigation”- Same menu items, same order, same links?
- Do dropdowns/mega-menus open with same content?
- Logo same size?
- Sticky behavior (does nav stick to top when scrolling)?
3. Photos throughout
Section titled “3. Photos throughout”- Every photo on source: on the clone too?
- Same photo (not substitute or re-cropped)?
- Same position in layout?
- Lazy-loaded photos: scroll bottom, then back up — do they all load?
4. Third-party widgets (most common failure point)
Section titled “4. Third-party widgets (most common failure point)”- Google Reviews / TrustIndex — showing reviews or blank box?
- Instagram feed — showing posts or empty?
- Calendly / booking — opens flow?
- Live chat — chat icon appears?
- Google Maps — map loads (with overlay if applicable)?
- YouTube / Vimeo — video poster shows?
These are the things that broke on Atlas, Maine, Sorce in the first audit. Pay extra attention.
5. Forms
Section titled “5. Forms”- Form renders with same fields?
- Source’s form action will not work on the clone — that’s expected. We replace forms with GHL embeds during cutover. But fields and visual design should match.
- Document every form on the site (homepage, contact, service pages, popups). Each one needs a GHL embed routed somewhere.
6. Animations / interactions
Section titled “6. Animations / interactions”- Hover buttons — animate same way?
- Hover nav — dropdowns appear?
- Click “show more” / accordions — expand?
- Scroll-triggered animations — fire?
- Video backgrounds / parallax — motion happens?
7. Typography
Section titled “7. Typography”- Heading font matches?
- Body font matches?
- Font sizes look same (no drift to default sans-serif)?
8. Colors
Section titled “8. Colors”- Brand colors match? (button colors, link colors, accents, header backgrounds)
- Section background colors match?
- No grayscale washout (common Elementor failure)?
9. Mobile (resize browser to 390px width)
Section titled “9. Mobile (resize browser to 390px width)”- Layout reflows correctly?
- Hamburger menu works?
- Photos scale correctly?
- No horizontal scroll?
10. Internal links
Section titled “10. Internal links”- Click 5–10 random internal links throughout
- Right destination?
- Or bouncing to homepage / 404?
Logging findings
Section titled “Logging findings”For each issue:
- Page: which URL
- Section: which part (hero, services grid, footer)
- Issue: what’s wrong
- Severity: P0 / P1 / P2
- Source ref: link to source page (to copy from)
Save to ~/Projects/seo-ops-skills/logs/<client>-visual-diff-<date>.md.
Example:
## leons-landscaping — visual diff 2026-04-30
### P1 issues- [homepage / hero] — Hero background slideshow not cycling. Source has 4 slides rotating every 2.5s; clone shows only first slide.- [/contact / form] — Phone field missing from contact form. Source has 4 fields, clone has 3.
### P2 issues- [homepage / footer] — "Powered by Squarespace" tag still in footer. Should be stripped.
### Resolved- [/about / about photo] — Was missing on first audit. Fixed in PR #14.The triage decision tree
Section titled “The triage decision tree”For every issue you find, walk through this:
flowchart TD Issue[Found an issue] --> Type{What kind<br/>of issue?}
Type -->|Site is blank,<br/>logo missing,<br/>major page broken,<br/>placeholder visible| P0[P0 - BLOCK CUTOVER<br/>Do not flip DNS<br/>Fix immediately] Type -->|Wrong widget,<br/>wrong photo in hero,<br/>wrong brand color,<br/>major copy missing,<br/>significant layout drift| P1[P1 - FIX BEFORE CLIENT<br/>Open branch, fix, re-audit] Type -->|Minor formatting,<br/>tiny crop diff,<br/>footer credit,<br/>slight font weight| P2[P2 - DEFER<br/>Note in log<br/>fix post-cutover or skip]
P0 --> Log[Log to<br/><client>-visual-diff-<date>.md] P1 --> Log P2 --> Log
Log --> Decision{Total findings:<br/>any P0?<br/>more than 3 P1?} Decision -->|Yes| Hold[HOLD<br/>fix first<br/>do not send to client] Decision -->|No| Ship[SHIP<br/>send test URL<br/>with known-issues preface]
style P0 fill:#dc2626,color:#fff style P1 fill:#fbbf24,color:#000 style P2 fill:#94a3b8,color:#fff style Hold fill:#dc2626,color:#fff style Ship fill:#22c55e,color:#fffSeverity guide
Section titled “Severity guide”P0 — blocks cutover. Do not flip DNS.
- Site is blank on a major page
- Form completely missing (not just routing — actually missing)
- Logo broken or missing
- Half the homepage doesn’t render
- Mobile layout destroyed (overlapping, off-screen)
- Any “Powered by Cloudflare Pages” / placeholder visible
P1 — must fix before sending to client.
- Major widget broken (reviews, Instagram, maps, chat)
- Wrong photo in hero or featured spot
- Brand colors render wrong (grayscale, wrong primary)
- Major copy missing from a page
- Significant layout drift (extra blank sections, collapsed columns)
P2 — nice to fix, not a blocker.
- Minor copy formatting differences
- Font weight slightly different
- Footer credit line still present
- Tiny image cropping differences
- Hover state animations slightly different
Anything affecting public-facing brand impression is P1. When in doubt, treat as P1.
Common issues + fixes
Section titled “Common issues + fixes””Google Reviews / TrustIndex widget is blank”
Section titled “”Google Reviews / TrustIndex widget is blank””- Cause: Widget loader script loaded but div trigger ref is wrong, OR script needs source domain to authenticate
- Fix: Check
src/data/<page>.body.htmlfor the widget div. Confirmdata-srcpoints at original CDN URL (e.g.cdn.trustindex.io/loader.js?WIDGET_ID). If pointing at local path, restore the original CDN URL.
”Instagram feed missing”
Section titled “”Instagram feed missing””- Cause: Source used a Squarespace/Wix/WP Instagram block that doesn’t work cross-domain
- Fix: Replace with official Instagram oEmbed API or Embed.js. Get client’s Instagram handle and rebuild.
”Hero image is different from source”
Section titled “”Hero image is different from source””- Cause: Source uses JS-rendered slideshow that extractor only captured first frame of, OR uses CSS
background-imagenot rewritten - Fix: Inspect source CSS for background-image URL. Find image in
public/images/, confirm it downloaded. Check thatstyle="background-image: url(...)"was rewritten to local path.
”Maps embed shows ‘Oops!’ error”
Section titled “”Maps embed shows ‘Oops!’ error””- Cause: Google Maps API key domain-locked to source domain
- Fix during clone phase: Hide map with CSS (
#map { display: none !important; }in_clone-overrides.css) - Fix during cutover: Either ask client to add new domain to existing API key in Google Cloud Console, OR replace with Mapbox embed (no domain restriction)
“Brand colors are wrong / grayscale” (WP+Elementor)
Section titled ““Brand colors are wrong / grayscale” (WP+Elementor)”- Cause: Body class missing — Elementor scopes CSS variables to
.elementor-kit-NNNwhich has to be on<body> - Fix: Find source page’s
<body class="...">value. Copy intoLayout.astro’s<body>tag.
”Section is collapsed / missing”
Section titled “”Section is collapsed / missing””- Cause: Section was JS-injected by source CMS runtime, OR was hidden by source’s runtime and dedup picked the wrong copy
- Fix: Check
_clone-overrides.cssfordisplay: none !importantrules. Make sure they target rightdata-section-id.
”Forms aren’t submitting”
Section titled “”Forms aren’t submitting””- Expected. Forms always need GHL embed swap during cutover. Document the form, get GHL location from Nick, swap.
Ship vs hold
Section titled “Ship vs hold”Ship to client (send the test URL) when:
- Zero P0 issues
- Zero P1 issues OR all P1s noted in “Known issues — being fixed” preface in client email
- All forms documented
- Mobile layout works on homepage + at least one inner page
Hold and fix first when:
- Any P0 issue
- More than 3 P1 issues across the sample
- Site renders blank on any sample page
- Brand is unrecognizable (wrong colors, wrong fonts)
When unsure, ask Nick before sending to client. Better to hold a day than send something embarrassing.
After client review
Section titled “After client review”Client comes back with feedback. Most common:
- “Update phone number / hours / address”
- “Use this photo instead of that one”
- “Change this paragraph”
- “I don’t see [feature] from my old site”
For each: open a branch, fix, test locally, PR, merge. Re-run visual diff against changed pages only. Iterate until client GO.
Once GO → cutover (see web-designer-onboarding section 6).
Definition of done
Section titled “Definition of done”This SOP is complete for a given client when:
- All 6 sample pages diffed against source at 1440px and 390px
- All findings logged to
<client>-visual-diff-<date>.md - Zero P0 issues
- Zero P1 issues OR P1 list provided to Nick + acknowledged
- Forms inventoried with target GHL locations confirmed
- Test URL sent to client with cover note + known-issues preface
Quick reference card
Section titled “Quick reference card”SAMPLE 6 pages: home, about, 1 service, 1 location, contact, 1 blogTOOLS two browsers side-by-side at 1440pxPER PAGE 10-point check (hero, nav, photos, widgets, forms, animations, type, color, mobile, links)SEVERITY P0 = block | P1 = fix before client | P2 = nice to haveLOG ~/Projects/seo-ops-skills/logs/<client>-visual-diff-<date>.mdSHIP zero P0, zero P1 (or P1 noted in preface email)Version Control
Section titled “Version Control”- v1.0 (2026-04-30): Initial SOP. Built after Clawton’s first independent verification round flagged 3-of-4 sites with widget/photo drift not caught by the basic build audit.