How this demo
was built
Design and build notes for Wandoo Earthmoving — a fictional Maddington wet-hire operator, and the sixth-wave earthmoving entry in the Industry Demos series.
Concept
The pad at knock-off
Wandoo Earthmoving is a fictional bobcat, excavator and tipper wet-hire business working Perth's south-east out of Maddington — named for the WA wandoo: hard wood, straight grain. The audience is owner-builders needing a sand pad, pool families, landscapers and builders; the page has one job — get a machine booked or a site-works quote requested. The art direction is the pad at 5:30pm: cut sand glowing under a low sun, the machine parked square, the site string-lined. Machine pride without machinery porn, and a price honesty streak (minimums, tip fees, tight-access hours) as the differentiator.
Palette
Iron dusk, argued from 5:30pm
The wave's second dark site, deliberately a different dark from the locksmith's night navy: warm iron instead of cool night. Limestone body copy sits on iron dusk at ≈12:1. Machine yellow is strictly a line-and-mark token — excavator outlines, the cut line, the primary CTA — never body text. Cut sand measures ≈4.4:1 on iron dusk, just under the 4.5:1 floor, so a lighter #D69E66 sand-ink was derived for link and annotation text (6.3:1) per the LEARNINGS ink/line split; raw cut sand is kept for fills, chips and marks only.
Type
Signage on a machine door
Big Shoulders Display (500–800) carries the mastheads — tall industrial caps that read like the sign-written door of a well-kept machine. Figtree does body and UI work: plain, legible, no affect. JetBrains Mono prints everything that must read as measured — rates, hours, machine plates, the job card — so every number on the page looks like it came off an invoice, not a brochure. The typographic bravery moment is the full-bleed WANDOO EARTHMOVING hero stack at up to 148px, with the trade name knocked into machine yellow.
Signature
The Machine Match Estimator
Five job chips × three access chips drive a procedural SVG site cross-section: the block profile with soil strata, a string line hung at the working level, and the cut rendered in cut-sand gradient — a raised compacted pad, a −1.6 m pool box, a −150 mm driveway strip, a surface scrape, or three soakwell pits with dashed drums. The matched machine (1.8t mini / bobcat + tipper combo / 5t excavator + truck, drawn as yellow-outline silhouettes) rolls in with a one-shot dust puff, and a mono job card prints the same numbers the operator would read out on the phone: machine, hours on site, machine time, and what's billed at cost.
Implementation notes: machine positioning lives on outer <g transform> attribute groups while the roll-in animation runs on nested inner groups — CSS transforms silently discard SVG transform attributes (LEARNINGS W16), so the two never share an element. SVG groups are toggled via the hidden attribute (never the non-existent SVG .hidden IDL, LEARNINGS W13) backed by a [hidden]{display:none !important} guard. The cut draw-in is a one-shot dash reveal with butt caps (no W15 round-cap dot) that holds its drawn state — nothing loops, so the 7-second thumbnail always captures the rest demonstration: sand pad, standard access, combo matched, cut drawn, $850–$1,190 card showing. Every interaction updates window.__earthmoving, and the card's scenario pre-fills the quote form.
Honest numbers
The pricing model, documented
The spec pins three wet-hire rates (operator + fuel included) and six service floors. Everything else below is this build's derived model — QA re-implemented it as an independent oracle and asserted the displayed card against it for all fifteen job × access combinations.
| Job | Machine | Rate | Hours | Machine time | At cost, on top |
|---|---|---|---|---|---|
| Site clean | Combo | $170/hr | 3–5 | $510–$850 | green waste & tip fees |
| Sand pad | Combo | $170/hr | 5–7 | $850–$1,190 | pad sand, geotech cert |
| Pool dig | 5t + truck | $195/hr | 11–15 | $2,145–$2,925 | cart-off + tip ≈$655–$1,275 → all-in $2,800–$4,200 |
| Driveway prep | Combo | $170/hr | 4–6 | $680–$1,020 | road base |
| Soakwells | Mini | $140/hr | 3–4 | $420–$560 | 4 units × ≈$275 → typical home $1,520–$1,660, from $380 each |
- Access rules. Tight (≤1.1 m gate) forces the 1.8t mini and multiplies base hours by 1.7 (rounded up) for jobs whose standard machine is bigger — a smaller bucket moves the same sand in more trips; soakwells (already mini work) add one hour for positioning. Rural-acreage upgrades surface jobs (clean/pad/driveway) to the 5t + truck at $195/hr with hours held flat — a deliberate, documented flatness: the bigger bucket offsets the longer carries. Pool digs stay on the 5t; soakwells stay on the mini.
- Floors, derived. $420 minimum call = 3 hrs × $140 mini (the model's cheapest output: soakwells, standard access). Site cleans from $510 = 3 × $170. Sand pads from $850 = 5 × $170. Driveway prep from $680 = 4 × $170. Pool digs from $2,800 = 11 × $195 + $655 low disposal. Soakwells from $380 each = ($420 + 4 × $275) ÷ 4. Every services-grid anchor is a model output, so the estimator can never argue with the grid.
- Spec corrections, measured. The wave spec's illustrative rest-state card ("sand pad ≈ 4 hrs ≈ $680, verify") conflicts with its own pinned "from $850" pad floor — $680 is 4 hrs of combo, which this model assigns to the driveway-prep floor. The shipped rest card is the measured 5–7 hrs / $850–$1,190. The spec's "site clean ≈ $510–$850" hypothesis was confirmed exactly (3–5 hrs × $170).
Conversion
Decisions on the page
- Above the fold at 375px: name, trade + area promise, call CTA, quote CTA and the ticketed/insured/since-2010 trust line — measured in QA, not eyeballed.
- Two CTAs, one priority. Earthmoving is a phone trade: call leads (yellow), quote follows (ghost). The mobile sticky bar repeats both at ≥48px tap height.
- The estimator is the qualifier. It answers the two questions that decide the phone call — "which machine?" and "what will it roughly cost?" — then hands its scenario to the form, so the enquiry lands pre-qualified (job, access, hours band).
- Form fields: name, phone, suburb (the suburb sets the float — asking for it is itself an honesty signal), job type, access, timing, free text. Front-end validation with per-field messages; a local confirmation state that plainly says nothing was sent — never a faked network round-trip.
- Honesty as positioning: the 3-hour minimum, capped-float promise, at-cost tip fees and the tight-access hours rise are stated in the estimator, the services grid, the FAQ and the footer — the same numbers everywhere, greppable against one model.
Local SEO
What we'd ship for the real business
This demo page carries only WebPage schema naming it a demonstration — fictional structured data in a real index is dishonest markup. A live Wandoo would ship LocalBusiness + Review schema fed by its actual Google Business Profile:
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "LocalBusiness",
"@id": "https://wandooearthmoving.com.au/#business",
"name": "Wandoo Earthmoving",
"description": "Bobcat, excavator and tipper wet hire across
Maddington and Perth's south-east.",
"telephone": "+61-8-XXXX-XXXX",
"address": {
"@type": "PostalAddress",
"addressLocality": "Maddington",
"addressRegion": "WA",
"postalCode": "6109",
"addressCountry": "AU"
},
"geo": { "@type": "GeoCoordinates", "latitude": -32.05, "longitude": 115.99 },
"areaServed": ["Maddington","Gosnells","Thornlie","Canning Vale",
"Southern River","Kelmscott","Armadale","Byford"],
"openingHours": "Mo-Sa 06:30-16:30",
"priceRange": "$$",
"aggregateRating": {
"@type": "AggregateRating",
"ratingValue": "4.9",
"reviewCount": "87"
},
"review": [{
"@type": "Review",
"author": { "@type": "Person", "name": "Real customer" },
"reviewRating": { "@type": "Rating", "ratingValue": "5" },
"reviewBody": "Pulled from the live Google review feed."
}]
}
</script>
Plus suburb-level service pages (sand pads Maddington / pool digs Canning Vale), GBP posts fed from completed job photos, and review-flow automation.
What would change for the real client
Their photos and live review feed replace the procedural scene and demo copy; the quote form posts into AroFlo or Tradify job cards with SMS acknowledgment; Xero or MYOB handles invoicing with the at-cost tip-fee lines itemised; Geotab plant tracking feeds honest ETA and utilisation data; Assignar schedules larger crews; BYDA (Dial Before You Dig) referrals lodge from the job record; and a Power BI utilisation dashboard shows which machine earns its float.
Process
Three passes, driven not loaded
Every pass drove the page headlessly (puppeteer, isolated port): all fifteen estimator combinations asserted against an independently re-implemented pricing oracle, the form submitted empty on a fresh load then filled, the sticky bar measured at 375px, every chip and FAQ item exercised, and at least one real screenshot reviewed by eye per pass.
Pass 1 — Craft
Screenshot review found a dead dark column under the cross-section beside the tall job card at desktop — filled it with a three-card fleet rate strip, which then earned its keep by live-highlighting the matched machine. SVG annotation type read too small at 375px, so the cut label was raised (the HTML caption bar always carries the state at readable size). One harness artifact fixed on the harness side, not the page: FAQ toggle events are queued tasks, so the probe read had to wait a tick. All 45 oracle asserts (15 combos × cost/hours/rate) green; empty submit raised 4 validation signals on a fresh load; filled submit confirmed inside the required lexicon.
Pass 2 — Depth
Took the exact 7-second-settle screenshot the thumbnail pipeline will take and reviewed the rest frame: the low sun sat directly behind the machine silhouettes and their yellows blended — moved it over the cut; the compacted pad read as a sliver — deepened it, hung the string line just above pad level and stood the pegs on the ground per job. Added the one-shot roll-in dust puff (motion-gated) and the fleet-strip MATCHED state as the tie between card and scene. Keyboard drive: Tab reaches the chips with a visible outline, Enter activates (probe asserts the job change). Tight access verified to visibly raise hours (pad 5–7 → 9–12) with the smaller-bucket explanation printed on the card.
Pass 3 — Hardening
375px: scrollWidth 375, wordmark and nav inside the viewport, h1 + 56px call CTA + trust line above the fold, sticky bar in the bottom 140px at 48px tap height. Reduced motion: entrance, draw-in, dust and beacon all gated; the page loads settled and fully drawn. Positive phone sweep: every (08) 9xxx number on both pages uses the reserved 9000 exchange; DBYD 1100 kept as the genuinely correct institutional number. JSON-LD audit: index carries WebPage only; this page's LocalBusiness sample lives in an escaped code panel. Chanel rule: removed the hero's redundant "STRING LINE +0.00" horizon label — the estimator owns the string line. Final copy read against the model: every price on the page traces to a model output.