Guide · Site 221 · Wave 13 — Industry Demos II
How Datum & Chain was made
A fictional Perth land-surveying business built as a conversion demonstration: one landing page whose only job is to turn "where is my boundary, actually?" into a fixed-fee quote request. Audience: homeowners subdividing a block, builders needing setout, buyers staring doubtfully at a fence. Every pixel is procedural — no photography, no raster assets.
Palette — argued from the plan sheet
The whole page behaves like a deposited plan on a drafting table: white ground, fine ink linework, everything dimensioned. Survey orange is the hi-vis field DNA — pegs, traverse lines, dimension marks — and is never used as body text on white (it measures ~3.05:1; the derived slate inks carry all copy at 4.5:1+).
Derived inks: body #3A4652 (≈9:1 on drafting white), muted #5A6672 (≈5.4:1) — the W2/W5 ink/line split applied before QA could flag it.
Type
Instrument Sans carries the display and body — engineered, slightly instrument-panel, set tight at 650 weight for the headline. Spline Sans Mono does what a plan's annotation lettering does: every number on the page — bearings, distances, fees, hours, ABN — is set in the mono, so figures read as measurements rather than marketing. The typographic moment is the h1: the word "boundary" carries a real dimension bar with end ticks and a ±15 mm annotation — the page's promise drawn as a dimension.
Signature — the Plan-Your-Survey estimator
Choose one of four survey types and a lot size (200–2,000 m²) and an SVG plan sheet drafts the job live: the boundary traverse strokes in side by side (stroke-dashoffset on a deterministic rAF timeline with a clamped delta accumulator, so tab-switches don't jump the plotter), pegs pop at each corner as its side completes, and bearings and distances annotate each line. The annotations are honest: lot corners are generated in metres (east/north), the quoted bearings and distances are computed from that geometry with atan2 and formatted as DD°MM'SS", and a one-step shoelace correction makes the drawn polygon's area match the slider. Each type re-draws its own overlay — found-peg notes for a re-peg, clipped contour splines with RL labels, a dashed subdivision split with per-lot areas that sum to the slider value, a slab footprint with setback dimensions for setout.
The fee range updates with the drawing: low = round₁₀(base + rate × max(0, area − 450)), high = low + spread. At rest the sheet is mid-example — a boundary re-peg on a 728 m² Leederville lot, half-drawn at the 7-second mark (a 13s first draw; 2.6s on every interaction after). Reduced motion renders the finished plan instantly. A drafting in-joke for the second visit: the title block's REV letter increments every time you re-configure the job.
| Scenario | Displayed range | Hand-computed |
|---|---|---|
| Boundary re-peg · 728 m² (rest state) | $750 – $1,000 | 750 / 1,000 ✓ |
| Boundary re-peg · 200 m² | $650 – $900 | 650 ✓ = services grid floor |
| Feature & contour · 450 m² | $1,100 – $1,500 | 1,100 ✓ = grid floor |
| 2-lot subdivision · 1,000 m² | $5,270 – $7,070 | 5,270 / 7,070 ✓ |
| Site setout · 2,000 m² | $1,630 – $1,930 | 1,630 / 1,930 ✓ |
The estimator's cheapest re-peg output equals the services grid's "from $650", and the subdivision span (max $8,470 at 2,000 m²) sits inside the grid's stated $4,500–$8,500 — the page never argues with itself.
Conversion decisions
- Above the fold at 375px: name, "know exactly where your boundary is", two CTAs (estimator + tel:) and the licence/insurance trust line — all before the first scroll.
- Estimator → form handoff: configuring a scenario pre-fills the quote form's survey type and job description with the live fee range, and "Use this in my quote" scrolls to the form and focuses the name field — the demo interaction becomes a warmer lead.
- Form fields: name, phone, suburb, survey type, job description — suburb is load-bearing for a surveyor (it determines which survey records get searched), and the confirmation copy says so.
- Local confirmation, no fake network: submit validates in-page, then swaps to a personalised "we'd call you back within one business hour" panel that plainly declares the demo. Nothing pretends to send.
- Mobile sticky bar: call + quote, 56px targets, present only under 768px.
- Honest anchors: WA-plausible 2026 figures throughout — re-pegs from $650, contour from $1,100, subdivision $4,500–$8,500 incl. lodgement, and the FAQ tells the truth about WAPC timelines (3–6 months) rather than promising speed nobody controls.
Local SEO we'd implement for the real business
This demo ships only WebPage schema naming it a demonstration — fictional structured data in a real index is dishonest markup. For a real surveying client, we'd ship LocalBusiness + Review markup fed by their actual Google profile:
{
"@context": "https://schema.org",
"@type": "LocalBusiness",
"additionalType": "https://schema.org/ProfessionalService",
"name": "— client's registered business name —",
"telephone": "+61-8-XXXX-XXXX",
"address": { "@type": "PostalAddress", "streetAddress": "…",
"addressLocality": "Osborne Park", "addressRegion": "WA", "postalCode": "6017" },
"geo": { "@type": "GeoCoordinates", "latitude": …, "longitude": … },
"areaServed": ["Perth", "Joondalup", "Fremantle", "Midland"],
"openingHoursSpecification": [{ "@type": "OpeningHoursSpecification",
"dayOfWeek": ["Monday","Tuesday","Wednesday","Thursday","Friday"],
"opens": "07:00", "closes": "16:30" }],
"aggregateRating": { "@type": "AggregateRating",
"ratingValue": "— from their live reviews feed —", "reviewCount": "—" },
"review": [{ "@type": "Review", "author": { "@type": "Person", "name": "—" },
"reviewRating": { "@type": "Rating", "ratingValue": 5 }, "reviewBody": "—" }]
}Plus: suburb + service landing pages ("boundary survey Dianella"), a Google Business Profile wired to the quote form, and FAQ schema on the real questions above.
What would change for the real client
- Their field-to-office pipeline: quote requests routed into the practice's job system, with lot/plan details pulled at intake — integrating with 12d Model and MAGNET / Trimble Access workflows so the records search starts from the enquiry, and Landgate lodgement status (plan in examination → in order for dealings) surfaced back to the client automatically.
- Live title context: a real estimator could pre-fill lot dimensions from a Landgate/SLIP title search on the entered address, so the plan sheet draws their block, not a parametric example.
- Their proof: real reviews via their Google profile feed, real licence number, real PI certificate, photos of pegs in actual verge sand if they want them — the procedural art here proves the layout carries without stock photography.
- Booking: call-back scheduling against the field calendar (north-of-river runs), SMS confirmations, and quote PDFs generated from the estimator's own fee model.
Iteration log
Pass 1 — Craft drive everything, then look
All 45 harness checks driven: empty submit flagged all four fields with visible errors and aria-invalid; a bad phone flagged exactly one; filled submit rendered the personalised confirmation; five known estimator inputs matched hand-computed fees to the dollar; FAQ opened; sticky bar scrolled to the form. The screenshots then caught what the DOM asserts couldn't: the h1's dimension annotation was drawn as a stretched SVG (preserveAspectRatio="none" distorted the ±15 mm label into a scribble) and collided with the second text line — rebuilt as CSS pseudo-elements under the last line. Also fixed in review: a duplicate x attribute on the map's Leederville label (first-wins parsing had parked it 100px off its dot) and a header tel link that went empty below 560px.
Pass 2 — Depth enrich the signature
The plan sheet's centre was dead space on the screenshot — added the centroid "LOT 47 / area" label, VINCENT STREET lettered along the frontage, and moved contour RL labels off the centreline so nothing collides. Second-read detail: the title block's REV letter increments on every re-draw, and DRAWN carries today's date. Micro-interaction: the fee figure blinks like a re-computed field, and chip selection strokes an orange traverse underline. This pass also caught its own regression: white-space:nowrap on buttons pushed 375px scrollWidth to 399 — the mobile header was rebuilt (icon-only tel:, tighter brand) and the probe re-confirmed 375 exactly.
Pass 3 — Hardening 375 / reduced motion / focus
Reduced-motion path verified by emulation: the plan renders complete on load (drawProgress = 1, no rAF loop), reveals and pulses are killed in CSS and JS. The [hidden]{display:none !important} guard covers the form/confirmation swap. Focus-visible outlines on chips, slider, summary rows and every field; sticky-bar targets 56px; the rAF timeline pauses accumulation while document.hidden. Chanel rule: removed the fifth grid cross from the hero's decorative sheet. Final copy read tightened the FAQ answers and confirmed the reserved phone pattern (08) 9000 0221 everywhere, licence and ABN visibly placeholdered.
Techniques
- Single-file vanilla page: inline CSS/JS, Google Fonts only, no libraries.
- Procedural SVG built in the DOM: cadastral plan (geometry in metres → screen transform), Perth service-area map, trust icons, hero plan sheet.
- Deterministic rAF animation timeline over per-element windows (stroke-dashoffset draws, peg pops, label fades) with clamped deltas and a state probe (window.__surveyor) for QA to gate on state, never wall-clock.
- CSS-only load choreography gated on an .anim class so content is never hidden if JS fails; IntersectionObserver reveals with the same guarantee.