Trowel & Float

Generative Assets · Industry Demos XXV · site 336

Trowel & Float Rendering — how it was made

A conversion-first landing page for a fictional Balcatta rendering business, built as the pattern Sapience Analytics would ship for a real Perth renderer: price the elevation on the page, then book the site measure.

Concept

Trowel & Float Rendering does cement render, acrylic texture systems and bag-and-paint on Perth's 1980s–2000s face-brick homes. The audience is the owner about to sell (or stay) who wants the "rendered look", the builder's client choosing a texture system, and anyone whose old render is cracking. The page has one job: a site-measure booking with the elevation, finish and area already priced — so the first phone call is about dates, not "how much".

Art direction is a rendering site at 10am: limewash-white ground, Colorbond-monument ink, trowel-steel blue for the actions, sand-render linework. The whole page reads like a wall half-done — one side brick, one side smooth.

Palette — measured, not assumed

#F2F0EB limewashPage ground.
#26292E monumentBody ink. Measured 12.81:1 on limewash.
#2F6F8F trowel steelButtons and links. White labels 5.54:1; on limewash 4.86:1.
#255A75 deep steelButton hover. White labels 7.51:1.
#1F4D64 steel inkSmall accent copy and prices. 8.00:1 on limewash, 8.66:1 on paper.
#B8A98F sand renderBrick coursing, dimension lines, rules. 2.02:1 — lines only, never text.
#6E5F45 sand inkEyebrows, window labels, reviewer names. 5.45:1 on limewash.
#8FBFD9 light steelLedger notes and links on monument. 7.38:1.

The spec's contrast figures were hypotheses; every one was measured with WCAG relative-luminance arithmetic from the shipped hex values in Pass 1. Trowel steel cleared 4.5:1 on the ground (4.86:1), so it stays for links and button fills — but all small accent-coloured copy (chip prices, service prices, addon reasons) uses the pre-minted steel ink at 8:1, the ink/line token split. Sand render never carries text; sand ink does. Secondary body copy uses #4A4F57 at 7.24:1.

Type

Archivo Black (400) for the wordmark, headings, the display line and the money — a signwriter's grotesque with the weight of a trowel; the same face a real-estate board or a ute door would carry. Public Sans for everything else: a workhorse that stays legible at 13px inside the ledger and on the drawn board. Body is 17px on mobile. The typographic moment is the display line above the elevation — "ONE-EIGHTY SQUARE METRES, FLOATED SMOOTH" — set in caps at up to 34px, where the number is written in words from the live area (twenty … one-eighty … four hundred) and the second half follows the finish (floated smooth / texture-coated / bagged and painted).

The signature — the Render Elevation

A drawn SVG street elevation of a brick home, built from JavaScript on every state change so the scope chips genuinely redraw the house rather than toggling layers. The face brick is a 30×14 <pattern> of sand-render coursing over a warm clay fill. The rendered state is a second wall layer — flat fill plus a finish texture pattern (fine sand speckle for cement, a two-tone stipple for acrylic, a rotated wavy-line hessian drag for bag-and-paint) — clipped by a four-point <clipPath> polygon whose right edge is the trowel line, leaning 9 units so it reads as a wet edge, with a 52-unit gradient darkening behind the blade.

The trowel rides that edge on a requestAnimationFrame loop: edgeFrac = 0.45 + 0.13·sin(0.85t), so the rendered region always covers between 32% and 58% of the wall — the never-invisible floor is coverage rather than opacity: at any capture instant the wall is visibly half brick, half render, at full opacity. The blade tilts ±7° with the direction of travel. The delta is clamped both ways (dt = min(max(now − last, 0)/1000, 0.05)), the loop pauses on document.hidden, and reduced-motion skips the loop and paints the 0.45 frame once.

Scope chips redraw the geometry: front elevation ghosts the side return wing (dashed, 38% opacity — "not in scope"), single-storey draws it solid, double-storey lifts the eave, adds three upper windows, a floor course and a drawn scaffold (five standards, two lifts of planks with guard rails). Finish chips swap the fill and texture; the paint topcoat swaps raw grey cement for a painted off-white. Reveals & quoins draws alternating quoin blocks at both corners and 8-unit reveal frames around every opening — inside the clipped render layer, so they appear only where the trowel has been. The estimate board is drawn on the wall like a real-estate board (monument plate, light-steel screws): "SITE ESTIMATE / $13,140 / cement render · 180 m² + topcoat". Below 600px the board ships a tight variant (170×66, total only at 40 units) so it never covers the drawn windows at 375.

Every control handler bumps a token before touching state; the rebuild is synchronous and the loop reads scene references refreshed by each render, so a rapid-fire chip sequence never leaves a stale closure alive. First draw staggers the drawn groups at 90 ms (1.3 s cap); every later redraw runs at 26 ms (460 ms cap) via a firstDraw flag. window.__renderer exposes scope, finish, area, billed area, toggle states, lock flags, ledger lines, total, badge text, edge fraction, frame count and a settled flag.

Pricing model — pinned anchors, measured outputs

LineRateRule
Cement render, sand finish$55/m²Supply and apply per m² of wall, GST included
Acrylic texture system$85/m²Base coat + texture, colour through
Bag-and-paint$48/m²Bagged finish + two coats exterior paint, included
Area stepper20–400 m² ×10Scope chips SET it (front 60 · single 180 · double 320); it stays live afterwards and never changes the scope chip
Minimum40 m²Billed at the selected finish; multiplies the topcoat line too. 30 m² → note "billed at the 40 m² minimum"; 40 m² → no note
Paint topcoat+$18/m² × billedLive on cement only. Disabled on acrylic: "the texture coat IS the finish — no paint needed". Disabled on bag-and-paint: "bag-and-paint already includes two coats". The owner's choice is remembered and restored when cement is re-selected
Reveals & quoins+$450 flatLive at every scope × finish
Scaffold+$1,200 flatForced ON and locked for double-storey ("two storeys need a scaffold — WorkSafe's rule and our knees'"); OFF and disabled for front and single ("ground-level work runs off trestles"). Scope fully owns it — nothing to restore
Crack repair & re-coatsno number"Quoted on inspection" — a designed price-less line in the grid and under the ledger, never in the estimate

Toggle matrix

ToggleFront · cementFront · acrylicFront · bagSingle (same as front)Double · cementDouble · acrylicDouble · bag
Paint topcoatlivedisableddisabledlive / disabled / disabledlivedisableddisabled
Reveals & quoinslivelivelivelivelivelivelive
Scaffoldoff, disabledoff, disabledoff, disabledoff, disabledlocked ONlocked ONlocked ON

Worked examples — all measured from the running page and cross-checked against an independent oracle

ScenarioArithmeticMeasured
Rest: single, 180 m², cement, topcoat ON, reveals OFF180×55 + 180×18$13,140
Front, 60 m², acrylic, no toggles (topcoat disabled)60×85$5,100
Double, 320 m², acrylic, reveals ON, scaffold forced27,200 + 450 + 1,200$28,850
Single, 180 m², bag-and-paint (topcoat disabled)180×48$8,640
Bag-and-paint, stepper 30 m² → billed 40, note shown40×48$1,920
Bag-and-paint, 40 m², no note40×48$1,920
Cement, 20 m² + topcoat → billed 40 on both lines40×55 + 40×18$2,920
Grid floors: bag $1,920 · cement $2,200 · acrylic $3,40040 × ratematch

Zero spec corrections: every pinned figure landed exactly. Totals are integer by construction (integer rates × integer areas ×10, flat add-ons), so no rounding rule was needed.

Conversion decisions

Local SEO we'd implement for the real business

The live page carries only WebPage, WebSite, CreativeWork and a BreadcrumbList — a fictional business must not put business-shaped structured data into a real index. For the real client we would ship HomeAndConstructionBusiness (the schema.org organisation subtype for building trades — more precise than bare LocalBusiness, and rendering has no narrower type of its own), with the real ABN, address, hours, service area and a live review feed:

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "HomeAndConstructionBusiness",
  "name": "Trowel & Float Rendering",
  "url": "https://example.com.au/",
  "telephone": "+61 8 9000 0336",
  "address": { "@type": "PostalAddress", "addressLocality": "Balcatta", "addressRegion": "WA", "postalCode": "6021", "addressCountry": "AU" },
  "areaServed": ["Balcatta", "Karrinyup", "Dianella", "Morley", "Joondalup", "Wanneroo", "Perth"],
  "openingHoursSpecification": [{ "@type": "OpeningHoursSpecification", "dayOfWeek": ["Monday","Tuesday","Wednesday","Thursday","Friday"], "opens": "07:00", "closes": "16:00" }],
  "priceRange": "$$",
  "hasOfferCatalog": { "@type": "OfferCatalog", "name": "Rendering services", "itemListElement": [
    { "@type": "Offer", "itemOffered": { "@type": "Service", "name": "Cement render, sand finish" } },
    { "@type": "Offer", "itemOffered": { "@type": "Service", "name": "Acrylic texture systems" } },
    { "@type": "Offer", "itemOffered": { "@type": "Service", "name": "Bag-and-paint" } }
  ]},
  "aggregateRating": { "@type": "AggregateRating", "ratingValue": "4.9", "reviewCount": "63" },
  "review": [{
    "@type": "Review",
    "author": { "@type": "Person", "name": "Real customer name" },
    "reviewRating": { "@type": "Rating", "ratingValue": "5" },
    "reviewBody": "Pulled from the Google Business Profile feed, never hand-typed."
  }]
}
</script>

Plus: a Google Business Profile with the service area set to the metro, suburb landing sections for the brick belt (Karrinyup, Dianella, Morley, Joondalup), before/after galleries with the suburb in the alt text, and the FAQ marked up as FAQPage once the answers are the client's own.

What would change for the real client

Iteration log

Pass 1 — Craft

Pass 2 — Depth

Pass 3 — Hardening

Rest-state price measured from the running page: $13,140 (single-storey full exterior, 180 m² cement render with paint topcoat). Zero console errors, one <h1> per page, live JSON-LD limited to WebPage / WebSite / CreativeWork / BreadcrumbList / ListItem.