Generative Assets · site 269 · industry demo

How Wagtail Dog Grooming was made

Build notes for a fictional Bayswater dog-grooming salon: a Saturday-morning-hydrobath landing page whose signature is a procedural SVG dog that re-renders as you price the groom.

The concept

Wagtail Dog Grooming is a fictional grooming & hydrobath salon in Bayswater, named for the bird that never stops moving — like every dog at bath time. The audience is oodle owners six weeks past due, double-coat owners shedding through a Perth summer, and new puppy owners who want the first groom to go well. The page has one job: book a groom — and it earns that booking with honesty (the matting promise, the double-coat promise, prices that are the price) rather than gloss.

Palette — argued from the salon

#F8F3ED towel creamThe ground — warm folded towels, not gallery white.
#453730 cocoaStructure and primary ink — a chocolate lab's coat. 10.3:1 on cream.
#2E9BA6 hydrobath aquaLINE/MARK only — suds arcs, tiles, progress. Never body text.
#17727C aqua-deepDerived CTA ground: white on it reads 5.6:1. The aqua's working ink.
#D97E4A collar apricotLeads and bandanas — active chips, focus rings, the home marker.
#9C4A1E apricot-inkDerived text-safe apricot for links: 5.6:1 on cream.

The spec's bright accents (#2E9BA6, #D97E4A) both fail 4.5:1 as small text on towel cream, so each got a derived ink twin — the line/ink split the collection's learnings mandate. The aqua is deliberately a warm-bathroom aqua on cream, distinct from tinting's dark-site ceramic cyan and poolcare's pool water.

Type

Baloo 2 for display — round, wagging, friendly weight; the masthead moment and every heading. Nunito Sans for body and UI — a workhorse that stays warm at 16.5px. Azeret Mono for kilograms and dollars — prices in mono read as ledger, not marketing, which is the whole honesty argument in one typeface choice.

The signature — the Groom Planner

Size, coat and service chips plus a deshed toggle drive a procedural SVG dog on the grooming table. The silhouette rescales per size chip (an outer <g> positions the dog with its paws anchored to the table; a nested <g> carries only the scale, so every size stands on the same mat). The coat re-renders procedurally per chip from a seeded PRNG — fine hatch lines for short coats, layered light-under/dark-over strokes with a saddle for double coats, looped coils for curly & wool — roughly 350 stroke elements per render, staggered in on first draw only (a firstDraw flag keeps every later redraw under 600 ms, so chip taps feel snappy, not ceremonial).

The before/after reveal is the comb line: two rect-clipped coat layers (scruffy strokes plus edge-fuzz spikes left of the line, neat strokes plus a sheen gradient right of it) share the dog's silhouette clip, and the line itself is a scene-space overlay recomputed from the dog-local comb position each frame. At rest it eases to ~60% groomed, then drifts gently between 52% and 68%. Suds and the hydrobath arc loop behind the dog with a CSS opacity floor of 0.45 — never invisible at any capture instant. Every SVG element keeps attribute state and CSS animation on separate nested nodes (the W16/W17 rule), and the whole scene renders settled at 60%/$145 under prefers-reduced-motion.

Second reads: a willie wagtail perched on the tile rail flicks its tail every seven seconds, the dog blinks, a dryer blows animated air lines at the finished side, and switching the deshed toggle on releases a drift of loose undercoat off the rump — so the toggle changes the rendering, not just the number.

The pricing model — shape and derivation

Every figure the planner shows is computed from the pinned anchors below; the card's cheapest possible output ($65, small wash & tidy) equals the services grid's "grooms from $65" floor.

Servicesmallmediumlargegiant
Wash & tidy$65$80$100$125
Full groom$95$120$150$185
Curly & wool clip+$25 on full grooms only
Deshed treatment+$25, any size, any coat
Puppy intro (<6 mo)$60 flat
Walk-in nail trim$20 — outside the planner, walk-in only

Three dimensions are deliberately flat, and the page says so rather than inventing gradients:

Worked examples, cross-checked against the spec's anchor arithmetic and measured from the running page by the QA harness's independently reimplemented oracle: the rest state (medium · curly & wool · full groom) shows $120 + $25 = $145; with deshed toggled, $170; a giant double-coat full groom with deshed, $185 + $25 = $210. All matched with zero corrections. The services grid's derived cards say their arithmetic out loud: oodle grooms "from $120" is the small full groom $95 + $25; deshed treatments "from $90" is the small tidy $65 + $25.

Conversion decisions

Local SEO we'd implement for the real business

This demo page carries only WebPage schema naming it a demonstration — fictional structured data in a real index would be dishonest markup. For a real salon we'd ship LocalBusiness + Review schema like this:

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "LocalBusiness",
  "name": "Wagtail Dog Grooming",
  "description": "Dog grooming and hydrobath salon in Bayswater, WA.",
  "telephone": "+61 8 XXXX XXXX",
  "address": {
    "@type": "PostalAddress",
    "streetAddress": "…", "addressLocality": "Bayswater",
    "addressRegion": "WA", "postalCode": "6053", "addressCountry": "AU"
  },
  "geo": { "@type": "GeoCoordinates", "latitude": -31.917, "longitude": 115.917 },
  "openingHoursSpecification": [{
    "@type": "OpeningHoursSpecification",
    "dayOfWeek": ["Tuesday","Wednesday","Thursday","Friday","Saturday"],
    "opens": "08:00", "closes": "16:00"
  }],
  "priceRange": "$65–$235",
  "aggregateRating": { "@type": "AggregateRating", "ratingValue": "4.9", "reviewCount": "182" },
  "review": [{
    "@type": "Review",
    "author": { "@type": "Person", "name": "…" },
    "reviewRating": { "@type": "Rating", "ratingValue": "5" },
    "reviewBody": "…"
  }]
}
</script>

Plus: suburb-level service pages only if genuinely distinct, Google Business Profile with groom-category photos, and review markup fed by a real review flow — never hand-typed.

What would change for the real client

Techniques

Iteration log

Pass 1 — Craft

Pass 2 — Depth

Pass 3 — Hardening

Honesty rules, applied

The business is fictional and the page says so plainly in the colophon. The phone number uses the reserved (08) 9000 0269 pattern; the address stays suburb-level; ABN and certificate numbers are visibly placeholder-patterned (ABN 00 000 000 000, Cert III 0000). Reviews are demo copy on a page declared fictional, never structured data. The two trade-honesty promises — humane clip-off for matted coats, never shaving double coats — are real grooming practice, quoted because being right about the trade is the demo's credibility.