Poopy Poochy – A Service Business That Runs Itself
A custom WordPress theme for a dog waste removal company in St. Clair County: nine city landing pages generated from one template, a five-step quote calculator that files every lead as a record, and an editing surface the owner can use without calling me.
Project Details
Tags
Challenge
A dog waste removal service is a local business in the most literal sense. Nobody searches for it nationally; they search for it by the town they live in. The company covers St. Clair County and northern Macomb, which is nine separate towns, each of which needs its own page that ranks, prices correctly, and does not read as a copy of the other eight.
The second constraint mattered more. The owner runs a route, not a CMS. Anything that required a developer to change a price, add a town, or swap a photo would quietly rot the moment the invoice was paid — I have inherited enough of those sites to know how the story ends.
The obvious route was a page builder on a purchased theme. That solves the first week and then bills you for the next three years: nine near-duplicate pages maintained by hand, a DOM heavy enough to drag Core Web Vitals down on the mobile connections the actual customers use, and an editing experience where the owner is one misplaced drag away from breaking the layout.
Solution
I built a classic WordPress theme from scratch, with Advanced Custom Fields driving the content. No page builder anywhere in the stack. Every editable thing is a labelled field in the admin, and every layout decision stays in code where it cannot be dragged loose.
375px
768px
1366px
- One city template, nine towns. Service areas are a custom post type at
/cities/{slug}/, each carrying its own pricing, testimonials, and list of neighbourhoods served. Adding Richmond is filling in a form, not copying a page. The town-specific detail is what keeps nine pages from reading as one page nine times. - A quote calculator, not a contact form. Five steps — dog count, frequency, yard size, surface type, contact details — because those are the four variables that actually set the price. The visitor gets a real number instead of a promise that someone will call.
- Leads are records, not emails. The form posts through
admin-ajax, creates a Lead post type, then sends the notification. Email is the alert; the database is the source of truth. A missed notification costs an alert, not a customer. - An accessible before/after slider. The single most persuasive thing this business can show is a yard before and after. The drag handle works with touch, mouse, and arrow keys, because a control that only responds to a confident drag excludes a real slice of the audience.
- Brand colors in the Customizer. Palette changes flow through the WordPress Customizer as inline CSS overrides — the owner can repaint the site without touching a stylesheet or asking me.
- Layout controls where they earn their keep. The home page exposes per-section show/hide, spacing, and width, plus per-card toggles on the trust and what's-included blocks. Enough control to reorganise a sales page; not enough to break it.
/cities/port-huron/
/cities/marysville/
Designing the Mascot
The business had a name doing a lot of comedic work and nothing to hang it on. I drew the mascot in several poses before committing, because the pose is not decoration — it decides what the character is for. Waving belongs in a hero. Thumbs-up belongs at the end of a completed booking. The clipboard pose belongs anywhere the site is asking the visitor for information, which turned out to be most of the quote flow.

Waving — hero

Clipboard — forms

Thumbs-up — confirmation

Running — service speed
Decisions Worth Defending
Three of these came out of the hero video system, which sounds like a small feature and was where most of the interesting problems lived.
- The headline card fades only once the video is actually playing. Not on a timer, not on load. Browsers block autoplay unpredictably, and a card that fades on a timer over a poster image that never became a video leaves the hero empty. Tying the fade to real playback means the failure case degrades into the static hero rather than into nothing.
- The H1 stays in the DOM when the card is hidden. Hiding the headline is a visual choice the owner makes per page. Removing the heading would be an SEO consequence he never agreed to. It is hidden, not deleted.
- Every hero has an image poster and a reduced-motion fallback. Video is the enhancement; the still is the design.
prefers-reduced-motionand mobile both get the poster, and the layout was composed for the poster first. - The site renders without ACF. Every template falls back to sensible defaults if the plugin is inactive. A licensed dependency should never be the thing standing between a client and a working website.
- Email got its own infrastructure. Quote notifications go out through a verified sender domain over authenticated SMTP rather than PHP
mail(). On shared hosting, the default path lands quotes in spam, and a lead nobody sees is indistinguishable from a lead that never arrived.
The whole build is organised around one question: what happens the day I stop answering the phone? Every answer — leads in the database, prices in fields, colors in the Customizer, towns as a post type, a written owner guide and an admin launchpad pointing at all of it — is a version of "the owner keeps working."
Outcome
The site is live at poopypoochy.com and the business is running on it.
- Custom classic theme, ACF-driven, with a City post type covering St. Clair County and northern Macomb
- Quote calculator feeding a Lead record store, with authenticated email notification on top
- Keyboard- and touch-accessible before/after slider, hero video system with poster and reduced-motion fallbacks
- Owner-facing admin launchpad and a written guide, so routine changes never route through me
The lesson I took from this one was about where to spend adjustability. My instinct was to expose everything; what worked was exposing the four or five things the owner would actually want to change on a Tuesday — price, phone number, a photo, a town — and hard-coding the rest. Control the client never uses is not a feature, it is a surface area for breaking things.