Generative Assets — Wave 17 · Industry Demos VI · site 243

How Stillwater Pool Care was made

A fictional Duncraig pool-servicing business, built as a single conversion-focused landing page: one honest pricing model, one signature interaction — the Pool Volume & Service Planner — and every pixel procedural.

Concept

Stillwater Pool Care serves busy families across Perth's northern corridor whose pool is one job too many — plus new owners who inherited a mystery, and anyone staring at a green pool a week before a February birthday party. The page has a single job: book a first service. The direction is a backyard at noon in February — pebble glare, frangipani shade, water so clear the tiles wobble — premium quiet competence, zero tropical-resort kitsch.

Palette — argued from the water line

#F6F8F7 pebble whiteGround — the bullnose paving in full sun.
#1B4A52 deep-end inkStructure and primary ink — the shadow under the diving line.
#2E9BA6 pool aquaLine/mark only — the water itself: volume fills, caustics, marks. Never body text on pebble.
#DCA93F frangipani goldSecondary — the fallen flower on the step: focus rings, active accents, the primary CTA.
#0F5C66 aqua-ink (derived)The readable sibling of pool aqua, minted for mono figures and eyebrows (≥4.5:1 on pebble).
#7C5A10 gold-ink (derived)The readable sibling of frangipani gold, minted for text links per the ink/line token split.

The spec names pool aqua and frangipani gold as line/mark tokens; neither clears 4.5:1 as small text on pebble white, so two darker ink siblings were derived for anything that reads — the collection's standard ink/line split.

Type

Outfit (display) — clean geometry with a soft edge, like good pool coping; it carries the masthead, headings and buttons. Nunito Sans (body/UI) — a warm workhorse that stays legible at 16px+ on a phone by the pool. IBM Plex Mono — litres, dosing figures and visit prices, so every number on the page reads like an instrument, not a slogan.

The signature — Pool Volume & Service Planner

Shape chips (rectangle / freeform kidney / plunge), length and width sliders (plunge clamps them to 3–5 m × 2–3 m) and an average-depth slider (1.2–2.0 m) drive a procedural SVG top-down pool that reshapes live. The rectangle is a rounded-rect path; the kidney is a closed Catmull-Rom spline through twelve control points in a unit box, scaled to the slider dimensions so the bean stays organic at any aspect ratio. Water depth recolours the fill gradient toward deep-end ink; caustic lines are dash-drifted CSS animations clipped to the live pool path, with SVG layout kept on attribute transforms and CSS animation on separate nested groups. A frangipani petal drifts across the water as the second-read detail.

The volume & pricing model (source of truth)

QuantityModelAt rest (8 × 4 m, 1.5 m)
Rectangle / plunge volumeL × W × depth × 100048,000 L (exact)
Freeform volume× 0.85 of bounding rectangle40,800 L
Visit priceweekly $62 · fortnightly $78 · catch-up from $140 · recovery from $320$62 / visit
Recovery chemicals (indicative)litres × $0.002 – litres × $0.0045, rounded to $5$95–$215
1 ppm chlorine liftlitres ÷ 650 g cal-hypo at 65% available chlorine74 g
Monthly comparisonweekly 52/12 × $62 ≈ $269 · fortnightly 26/12 × $78 ≈ $169shown on plan card

The ×0.85 freeform factor: a surveyed kidney outline typically encloses 80–90% of its bounding rectangle, so the planner uses 0.85 and always presents litres with a "≈". The spec's worked example (8 × 4 × 1.5 ≈ 48,000 L) is what the model computes exactly, so the rest state ships the measured figure.

A deliberately flat dimension: the visit price does not change with litres. That is a pricing statement, not a missing gradient — the visit is priced on the work of the round (weekly $62, fortnightly $78, dearer per visit because a fortnight lets more drift), and it's chemistry that scales with volume: correction doses are billed at cost and itemised. The page says this in the plan card, the services grid and the FAQ, so all three surfaces agree. The planner's cheapest output ($62 weekly) equals the services grid's floor by construction.

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 Stillwater we'd ship LocalBusiness + Review schema fed by a live review source:

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "LocalBusiness",
  "name": "Stillwater Pool Care",
  "telephone": "+61-8-XXXX-XXXX",
  "url": "https://stillwaterpoolcare.com.au",
  "address": {
    "@type": "PostalAddress",
    "addressLocality": "Duncraig",
    "addressRegion": "WA",
    "postalCode": "6023",
    "addressCountry": "AU"
  },
  "geo": { "@type": "GeoCoordinates", "latitude": -31.83, "longitude": 115.77 },
  "areaServed": ["Duncraig","Sorrento","Hillarys","Padbury","Kingsley",
                 "Greenwood","Warwick","Carine","Karrinyup","Joondalup"],
  "openingHours": ["Mo-Fr 07:00-17:00","Sa 08:00-12:00"],
  "priceRange": "$$",
  "aggregateRating": { "@type": "AggregateRating",
    "ratingValue": "4.9", "reviewCount": "187" },
  "review": [{
    "@type": "Review",
    "author": { "@type": "Person", "name": "…from Google Business Profile…" },
    "reviewRating": { "@type": "Rating", "ratingValue": "5" },
    "reviewBody": "…live review text, never hand-written copy…"
  }]
}
</script>

Plus suburb-level service pages for the corridor, Google Business Profile with service categories, and review velocity via post-visit SMS.

What would change for the real client

Techniques

Iteration log

Pass 1 — Craft

Drove the full conversion path headlessly (36 asserts): fresh-load empty submit raised all three validation errors; filled submit rendered the "Thanks — request received / we'd call you back" confirmation; planner litres and prices verified against an independently reimplemented oracle for three scenarios (rect 8×4×1.5 → 48,000 L weekly $62; freeform 10×5×2.0 → 85,000 L green $320 + $170–$380 chems; plunge 4×2.5×1.2 → 12,000 L catch-up $140). Screenshot review caught what asserts couldn't: at 375px the header's phone link collapsed to an empty focusable target (its text span was hidden) and the header CTA wrapped to two lines — fixed by hiding the tel link under 560px (the sticky bar owns "call" there) and tightening the CTA. Also fixed the hero's "no lock-in" chip reusing the clock icon (now an open padlock, hero + trust strip), removed a stray white skimmer pill that read as an artifact, and moved the frangipani from a clipped corner onto the water.

Pass 2 — Depth

Added the second-read detail — a frangipani petal drifting slowly across the planner's water, clipped to the live pool path and repositioned per shape (asserted inside the pool's bbox for all three shapes) — and a price-pop micro-interaction on plan changes. Drove everything by keyboard as well as dispatched clicks: Enter on service and shape chips, arrow keys on the depth slider (1.5 → 1.6 m), Enter on FAQ items; all state-probe transitions verified. Confirmed the 375px header fixes from Pass 1 (CTA single-line inside the bar, tel hidden, no overflow).

Pass 3 — Hardening

Chanel rule: removed the hero's outer paving grid lines — the surround reads cleaner without them. Hid the "deep end" water label on pools narrower than 230px of drawn water (plunge), where it crowded the shape. Re-ran the full Pass 1 suite on the final code: 375px (no overflow, sticky call bar fixed within the bottom 140px, 56px tap targets, h1 + CTA + trust above the fold), reduced-motion (hero visible, caustics and petal stopped, planner settled at the rest demonstration), focus-visible outlines on chips and fields, zero console errors on both pages, exactly one h1 per page, the (08) 9000-exchange positive phone sweep, and WebPage-only JSON-LD. Guide numbers re-read against final code before commit.