Generative Assets · Wave 17 · Industry Demos VI

How the Ridgecap Roofing Co. demo was made

A conversion-focused landing page for a fictional Tuart Hill roof-restoration outfit — built to show Perth roofers exactly what Sapience Analytics would build for them. Back to the site or the collection.

Concept


Ridgecap Roofing Co. is a fictional restoration-first roofer for owners of 1960s–90s tile-roofed homes across Perth's north — the family watching a ceiling stain spread, the seller pre-sale, the owner quoted a $24k reroof who suspects a $7k restoration would do. The page has one job: book the free 20-point inspection. The art direction is a storm-season roofline — the terracotta roofscape of the northern suburbs against a building June front — respectful of weather, contemptuous of nothing. The single signature is the Roof Health Estimator: an honest ballpark before anyone climbs a ladder.

Palette — a Perth June sky


#EDF0F2 storm-lightground — the sky before the front arrives
#31363C ironstonestructure & primary ink — wet Colorbond
#B65C38 terracotta tileLINE/MARK — roof fills, defect markers, CTA
#8C3E1F tile-inkderived — terracotta as small text (6.5:1 on storm-light)
#4C7490 rain slatesecondary — focus rings, active-chip borders, glass
#33536B slate-inkderived — slate as link text (7.1:1 on storm-light)

The spec's bright terracotta and rain slate are line/mark tokens only — both fail 4.5:1 as small text on storm-light, so the build derives an ink twin for each (the W2/W5 ink/line split). Active chips sit on a deepened slate #3E617A so white chip text clears 6.5:1 on the dark estimator band.

Type


Bricolage Grotesque (display) — a sturdy grotesque with enough character to be a masthead on a van door; set tight (-.02em) at 800 for the h1 and section heads. Public Sans (body/UI) — plain-spoken and legible at 16px+ on a phone in one hand, which is where trade traffic lives. IBM Plex Mono — every per-metre rate, roof area and dollar figure renders in mono, so the numbers read like a measured quote rather than marketing.

The signature: Roof Health Estimator


A procedural SVG house elevation under a storm front: layered gradient sky, drifting cloud groups, dashed rain off the leading edge. Three <pattern> defs paint the roof plane per material — scalloped terracotta courses, flat concrete tiles with course lines, ribbed Colorbond — and the ridge-cap strip recolours to match. Changing roof type redraws the plane through a clipPath rect whose CSS width transitions (SVG geometry properties animate in CSS; the rect has no layout box, so QA probes read getComputedStyle, not getBoundingClientRect). The area slider rescales the whole house via the transform attribute anchored at the slab line — attribute for layout, CSS animation only on separate inner nodes (the W16 rule), which is why the pulsing defect markers animate a child circle inside an attribute-positioned group. Each job chip lights its own marker set: weathered surface, cracked pointing and lichen for restoration; slipped tile and water entry for repairs; ridge faults; rusted gutter runs. Everything the estimator knows is mirrored to window.__roofer on every interaction, and choosing a scenario pre-fills the inspection form — the demo interaction becomes a warmer lead. A second-read detail: once every 14 seconds, distant lightning flickers off the front (phased so the 7-second thumbnail lands in its dark half; killed under reduced motion).

Pricing model — anchors and derivation


The spec pins the rates; the build derives the geometry. This table is the single source of truth the page, the FAQ and the QA oracle are all checked against.

ItemModelAt 190 m² (rest state)
Full restorationarea × rate — $35/m² concrete (clean, rebed where needed, repoint, recoat), $30/m² terracotta (no coating — the colour is fired in), $28/m² Colorbond (clean, screws, seal, repaint)190 × $35 = $6,650
Leak & tile repairsDeliberately flat at from $330 — callout + first hour + photo report is area-independent, so the estimator ships the flatness as a pricing statement, not an invented gradientfrom $330
Ridge repoint & rebedridge/hip length ≈ round(2.9 × √area) lm — linear dimensions scale with √area; lands 32–54 lm across the 120–350 m² slider, inside the 30–80 lm band typical of Perth hip roofs. Repoint $12/lm, rebed & repoint $28/lm, shown as an honest range40 lm → $480–$1,120
Ridge on ColorbondSpecial-cased honestly: Colorbond ridges are screw-fixed, not bedded — the card re-routes to a re-screw & seal visit from $330 instead of quoting pointing that doesn't existfrom $330
Gutters & downpipesgutter run ≈ round(4.6 × √area) lm (eave perimeter, same √ scaling), × $45/lm supplied + fitted63 lm → $2,835

The spec's worked example (190 m² concrete restoration ≈ $6,650) was a hypothesis to verify; the implemented model computes exactly $6,650, so it ships unchanged. The estimator's cheapest possible output is the flat $330 repairs figure, which equals the services grid's "from $330" floor — the page never argues with itself. The review quoting a $7,000 restoration is a 200 m² concrete roof at $35/m².

Conversion decisions


Local SEO we'd implement for the real business


The demo page carries only WebPage schema naming it a demonstration — fictional structured data in a real index is dishonest markup. For a real Ridgecap, we'd ship LocalBusiness + Review schema wired to their actual details and review feed:

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "RoofingContractor",
  "name": "Ridgecap Roofing Co.",
  "telephone": "+61 8 XXXX XXXX",
  "address": { "@type": "PostalAddress",
    "addressLocality": "Tuart Hill", "addressRegion": "WA",
    "postalCode": "6060", "addressCountry": "AU" },
  "areaServed": ["Tuart Hill","Yokine","Dianella","Balcatta",
    "Stirling","Osborne Park","Karrinyup","Morley"],
  "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": "…" },
    "reviewRating": { "@type": "Rating", "ratingValue": "5" },
    "reviewBody": "…" }]
}
</script>

Plus: suburb-level service pages, Google Business Profile with the photo reports as posts, and review capture in the job-completion flow.

What would change for the real client


Iteration log


Pass 1 — Craft

  • Full headless drive (44 asserts): estimator verified against an independently re-implemented oracle across five scenarios — rest state concrete/restoration/190 → ≈ $6,650, terracotta 250 m² → $7,500, ridge 190 m² → $480–$1,120, gutters 350 m² → $3,870, and the Colorbond-ridge special case → from $330. Empty submit on a fresh load raised all three validation errors; filled submit rendered the confirmation lexicon.
  • Found & fixed: header wordmark + mono phone number overflowed 375px (scrollWidth 389) — the tel link becomes a 44px icon-only button under 600px, number preserved for screen readers and in the sticky bar.
  • Two harness artifacts (not site bugs): a clipPath rect has no layout box, so "roof drawn" probes moved from getBoundingClientRect to getComputedStyle; fixed the probe, not the page.
  • Screenshot review: 375px fold clean (h1, CTA, trust chips, sticky call bar all present), estimator scene rendering all three materials correctly.

Pass 2 — Depth

  • Added the estimate-figure tick — a 280ms scale-and-ink pulse whenever the number changes, so the card visibly answers every chip and slider move (asserted in the drive).
  • Added the second-read detail: distant lightning off the storm front once per 14s, phased so the 7-second thumbnail settle lands at 50% of the cycle — inside the dark 0–71% window, opacity 0. Killed under reduced motion (asserted).
  • Choreography discipline: removed the hero art's cloud drift so the only continuously-moving pixels belong to the signature scene.
  • Screenshot review of the revealed full page: services grid, reviews and map all correct; moved the Morley label next to its dot.

Pass 3 — Hardening

  • Found & fixed on screenshot review: the "weathered surface" and "cracked pointing" marker labels collided at rest — weathered surface now sits below-right of its marker on the roof plane, halo stroke keeping it legible on the tile pattern.
  • Chanel rule: removed the hero art's second cloud — one front, more negative space.
  • Re-ran the full suite: 375px overflow/fold/sticky-bar/tap-targets, reduced-motion (content immediate, roof pre-drawn, flash and pulses dead), keyboard drive of chips and FAQ, skip link, focus-visible outlines, zero console errors across all runs.
  • Final copy read against the code: every figure on the page ($35/$30/$28 per m², $330, $12/$28 per lm, $45/lm, $220, $6,650, $7,000 review) traced back to the model table above.