Build notes · Industry demonstration
A borehole log that prices the job while it draws it
Datum Ground Testing is a fictional two-rig geotechnical outfit out of Malaga doing residential site classification across the Perth metro. The page has one job: turn "how much is a soil test" into a booking, with the log, the class and the price already on the screen before anybody picks up the phone.
The Log — a section that zooms to the drilled depth around a figure that never changes size
The signature is a single SVG borehole section drawn straight down the page. Depths tick down the left in a monospaced face; the strata fill the hole as banded, hatched blocks; the water table strikes across as a dashed line where it is actually struck within the drilled depth; olive sample tags hang off the side at the sampled depths; and at the surface a laterite double-headed arrow carries the characteristic surface movement — the AS 2870 ys — with the class stamped beneath it.
Everything is drawn in one coordinate system where one metre is one hundred user units, so vertical scale is real and comparable across states. The section frame is the drilled depth plus one metre of rock below and half a metre of air above: 4.5 m at the 3.0 m chip, 6.0 m at 4.5 m, 7.5 m at 6.0 m. A 1.7 m surveyor figure stands on the surface beside the hole at the same vertical scale — the honest constant reference mark. He is 37.8 % of the frame at the shallowest state and 22.7 % at the deepest, which is as small as he gets and still legible. There is no drawn cap: 6.0 m is the enumerated maximum.
Above the section a lot strip draws the lots on the visit with the logged one marked, and below the drilled depth a hatched grey band says out loud that nothing under the hole was investigated. Only two things move on their own: the water line drifts its dash offset, and the ys arrow breathes. Both hold a never-invisible floor — the arrow's opacity never drops below 0.72 — so the seven-second thumbnail catches the signature alive at any instant, with no phase arithmetic.
The badge, measured rather than assumed
The price badge sits on the sheet, upper right, over empty air above the surface. Its clearance is not a fixed aspect ratio: every redraw measures the badge's real box, converts it to scene units through the current render scale, and grows the headroom (max(130, badgeHeight + 26 − lotStrip)) and the sheet width (max(840, subjectRight + 18 + badgeWidth + 12)) so it always lands over blank paper. The harness asserts the contract directly rather than the formula: the badge's rectangle must not intersect the rectangle of any drawn element, tested at 375, 1000 and 1200, and again at the tallest state (6.0 m, four lots). At 640 px and below the badge docks directly beneath the drawing instead — still inside the signature's container, never over the subject.
The second read
A dotted olive line crosses the hole at 1.8 m, tagged Hs 1.8 m. That is Perth's design suction change depth under AS 2870-2011 — the depth below which seasonal moisture movement stops mattering to the footing. It is the whole reason the depth chip prices rig time and never the class, and drawing it is better than only asserting it in copy. Change the profile and the class box presses down like a rubber stamp; the animation is driven from the render loop rather than by a class toggle on a scene the loop already owns.
Field paper, peat black, laterite and olive
The palette is argued from a Perth bore: bleached surface sand, peaty topsoil, Guildford clay, Darling laterite, and the water that comes up grey-green. It is held off the cream-and-terracotta default by a paper with zero warm cream and a red paired with an olive rather than left alone; off the near-black default by being a light site with two argued mid-tone accents; and off the broadsheet default by having no column rules at all — the vertical structure is the depth scale. Every ratio below was measured with WCAG arithmetic from the shipped tokens.
#ECEDE7
Field paper — the ground
A cool grey-green sheet, not cream. Cards sit on it in white (#FFFFFF) with #D5D8CE hairlines.
#1D211B
Peat black — body ink & primary CTA
13.87:1 on the paper, 16.33:1 on white cards, 11.31:1 on the hairline tint. White labels on it measure 16.33:1; hover #0F120E takes that to 18.86:1.
#A24030
Laterite — the ys arrow, the class stamp, section rules
Clears body copy unminted: 5.38:1 as text on the paper, 6.34:1 on white. As a button fill under white labels also 6.34:1; hover #8A3325 gives 8.14:1. No separate ink was needed.
#4F6B34
Peat olive — topsoil, sample tags, secondary rules
Also unminted: 5.12:1 as text on the paper, 6.03:1 on white; white on it 6.03:1, hover #3F5629 gives 8.16:1.
#565E4F
Muted ink — secondary prose
Minted during Pass 1, which the spec left to the builder: 5.74:1 on the paper and 6.75:1 on white, so every hint, note and caption clears the body-copy bar rather than the large-text one.
#7FA8B8
Groundwater — the struck line
The one colour on the page that is a measurement rather than a material. 6.37:1 against the body ink, so the level label sits on it in ink.
Scene fills, measured against the body ink
| Fill | Hex | Ink ratio | Label set in |
|---|---|---|---|
| Bleached sand | #E2D8BE | 11.51:1 | Body ink |
| Silty sand | #CFC5A6 | 9.48:1 | Body ink |
| Guildford clay | #A9A183 | 6.31:1 | Body ink |
| Laterite gravel | #C4885E | 5.47:1 | Body ink (lightened at spec time from #B8734F, which measured 4.36:1 and failed) |
| Weathered rock | #8C8B84 | 4.78:1 | Body ink |
| Uncontrolled fill rubble | #9E8F7A | 5.18:1 | Body ink |
| Groundwater | #7FA8B8 | 6.37:1 | Body ink |
| Peat olive topsoil | #4F6B34 | 2.71:1 — fails | White (6.03:1). The fill is not lightened to make the ink work; the label changes instead. |
Service-area map labels are body-ink-class text and carry a ground-coloured halo through paint-order: stroke. Ink measures 12.97:1 on the land fill, 10.21:1 on the ocean and 9.49:1 on the Darling Scarp band. The "lines only" tokens never label the map.
Manrope, Hanken Grotesk, and Red Hat Mono in exactly one role
Manrope 800 — display
A geometric grotesque with tight, engineered joins. A site classification is a measurement, not an opinion, and the face had to read that way. Set at −0.02 em tracking with a 1.02–1.08 line height.
Hanken Grotesk — workhorse
Every piece of prose on both pages. 17 px body, 16 px minimum on mobile, 1.62 line height. It sits under Manrope without arguing with it.
Red Hat Mono 500 — log strings only
One face, one job: depths and log strings. 0.0 · 1.2 · 2.4 · 3.0 m, ys 32 mm, Hs 1.8 m, the eyebrows, the badge lines and the ledger figures. It never sets a sentence.
The typographic moment
The rest-state class set enormous in the hero — M in Manrope 800 at up to 6.1 rem with an 0.82 line height — with $620 stamped beside it and YS 32 MM · 2 HOLES TO 3.0 M beneath in mono at 0.2 em tracking. Both figures are measured from the running model, not typed in, and both re-derive when the state changes.
Holes, depth, lots and travel — and nothing the ground can do about it
The commercial argument of this page is that the fee is a function of what we do, not what we find. The profile chip changes the strata, the movement figure and the class letter and leaves the price exactly where it was; the depth chip changes the rig time and the frame and leaves the class exactly where it was. Both neutralities are asserted, not just claimed — the harness drives all four profiles across the depth, lot, zone and toggle grid and compares totals.
One exception exists and the page shows it as a locked line rather than a surprise: selecting uncontrolled fill forces the fill-depth investigation on at $240 a lot, because a P classification has to prove how deep the fill goes.
| Line | Rate | Multiplies |
|---|---|---|
| Site classification, 2 holes to 3.0 m — first lot | $620 | Once per visit |
| Additional lot on the same visit | $410 | lots − 1 |
| Deeper holes — 4.5 m / 6.0 m | +$120 / +$240 | Actual lot count, including the first |
| Fill-depth investigation | +$240 | Actual lot count, including the first |
| Outer-metro travel | $180 | One flat charge per visit, outside the per-lot arithmetic |
| Regional WA travel | at cost | Quoted on the run — prints no number anywhere |
Money is held in cents
Every rate runs through integer arithmetic and is divided by one hundred once, at display; the price function throws if the cent total is ever non-integer. Nothing in this model has a decimal component, so this is belt-and-braces rather than a fix — but it is the construction the wave asked for, and it means a later rate of $x.50 cannot quietly introduce a float artefact. All totals display to the whole dollar; the enumeration found 0 non-integer cells in 576.
Worked examples, measured from the running page
| Scenario | Total | Class |
|---|---|---|
| Guildford clay, 1 lot, 3.0 m, metro (rest state) | $620 | M · ys 32 mm |
| Coastal sand, 1 lot, 3.0 m, metro | $620 | A · ys 0 mm |
| Hills laterite, 1 lot, 3.0 m, metro | $620 | S · ys 15 mm |
| Uncontrolled fill, 1 lot, 3.0 m, metro (forced investigation) | $860 | P · not classified |
| Guildford clay, 3 lots, 4.5 m, metro | $1,800 | M |
| The same job, outer metro | $1,980 | M |
| Guildford clay, 2 lots, 6.0 m, metro | $1,510 | M |
| Uncontrolled fill, 4 lots, 4.5 m, metro | $3,290 | P |
| Cheapest reachable output — equals the services grid floor | $620 | — |
| Dearest reachable — 8 lots, 6.0 m, fill, outer metro | $7,510 | P |
Force, restore memory and the partial unwind
The fill-depth investigation is a free toggle on any profile — some builders want it on a clay site next to an old cut — and a locked, checked line on uncontrolled fill. Two different controls can impose the lock: the profile, and five or more lots on a fill site. The unwind semantics are pinned and shipped exactly:
- The toggle's pre-force value is remembered when the lock engages, and restored when it lifts.
- An explicit user change to the toggle while it is free clears the memory.
- Partial unwind: going 6 lots → 4 lots while still on uncontrolled fill relaxes the lot constraint but not the profile constraint, so the forced value is held. Leaving uncontrolled fill at 6 lots releases both, because the lot rule only bites on fill — and the memory is then restored.
Both halves are driven in the harness, along with a "click the locked toggle" no-op assert and a rapid-fire burst that fires a dozen control clicks in a single evaluate with no settle between them.
Four things the spec left open, and what shipped
- The view-fit frame. The spec pins "a 4.0 m frame at the 3.0 m chip" alongside the rule "always drawn depth + 1.0 m of rock below and 0.5 m of air above", which gives 4.5 m. The rule reproduces the pinned 7.5 m frame at 6.0 m and the pinned 22.7 % surveyor fraction; the 4.0 m figure reproduces neither. The rule shipped, and the frames are 4.5 / 6.0 / 7.5 m.
- The "no water struck" note. Pinned to the Hills laterite chip. It is attached to the condition instead: it appears wherever no groundwater is struck within the drilled depth. That covers every Hills laterite state and also coastal sand at the 3.0 m chip, where the water table sits at 3.4 m — saying nothing there would have been the dishonest reading.
- The hole count on badge line 2. The pinned rest string is 2 holes to 3.0 m · 1 lot, which is ambiguous between per-lot and total at one lot. The badge prints the total — two holes a lot — so it reproduces the pinned string exactly at rest and stays true at every other lot count (6 holes to 3.0 m · 3 lots).
- The investigation surcharge. The price line reads "when the profile is uncontrolled fill"; the force section makes the same line a free toggle on any profile. Shipped toggle-driven with the force on fill, which reproduces every pinned worked figure and is the only reading in which the free toggle can charge anything.
Why the page is laid out this way
The number is the hero, not a reward for scrolling. The rest-state class and total are set enormous in the hero column and printed again on the scene badge, so the thumbnail's commercial argument is satisfied with margin rather than by luck. Somebody who reads nothing else leaves knowing a soil test costs $620.
The signature answers the question the phone call would have started with. "How much is a soil test" is really four questions — what is it, how many holes, how deep, and does my dirt make it more expensive. The Log answers all four visually and then puts a "Book this test" button under the ledger.
The form asks what a booking actually needs. Name, mobile, suburb, lot count and where you're up to — that last field is the one that sets urgency, because "my slab designer is waiting on it" and "still deciding whether to buy" are different jobs for the same rig. The date is optional. The consent tick is required, and the confirmation panel is hidden on load and after an empty submit, and appears only after a valid filled submit. Nothing is sent anywhere; the callback promise beside the form says so twice.
The honest exclusions are a conversion asset. The last FAQ says what Datum does not do — no footing design, no contamination assessment, no CBR testing, and no "your block is fine" over the phone. Naming the boundary is what makes the rest of the page credible to a builder who has been burnt.
Three passes, and what each one actually found
Pass 1 — Craft
- The class stamp was clipped at every width. The reactivity descriptor sat beside the letter and ran past the sheet's right edge, so "moderately reactive" and "problem site" were cut off. Restacked the stamp — label, letter, descriptor — and widened the sheet from 760 to 840 units.
- The surveyor struck through the borehole caption. The figure at x = 352 crossed "BOREHOLE 1 · UNCONTROLLED FILL". The caption is now the fixed BOREHOLE 1 · AS 1726 (the profile is already named on the chip, the strata bands and the ledger) and the figure moved to 470.
- The lot-strip caption ran under the badge. "lot 1 logged below · 3 more on the same visit" grew past the badge's left edge from four lots up. Trimmed to a fixed "lot 1 logged below"; the lot count lives on badge line 2.
- Two sample tags collided. The fixed extra-sample list for the fill profile put tags 0.2 m apart, which touch at the 7.5 m frame. Replaced it with a midpoint split of every gap of 0.6 m or more, which guarantees at least 0.3 m between tags in every reachable state.
- Scene type measured about 7 px rendered at 375. A 840-unit sheet in a 340 px container is a 0.4 scale. Added the pinned phone-width viewBox crop: a 440-unit sheet with short strata names, short tag strings and a compact class stamp, so the smallest string renders at about 11.5 px.
- The ground line ran under the movement label. Pulled it back to just past the ys arrow.
- Four separate map collisions, all screenshot-only: the Malaga yard mark sat on top of the Swan; Mandurah's dot sat on the metro band's dashed edge, which struck straight through its label; the outer-metro caption overprinted that label; and "Mundaring" crossed the rotated DARLING SCARP label. Moved the yard north of the river, dropped Mandurah clear of the band, moved the scarp label down, and lifted the outer-metro caption out of the SVG into HTML beneath the legend — where it also reads at 375 and now carries the at-cost declaration too. Map labels were also ~7 px at 375; added a phone-width font bump on the label classes.
- Contrast measured from the shipped tokens reproduced every spec figure exactly. Minted the one token the spec left open: the muted ink #565E4F at 5.74:1 on paper and 6.75:1 on card.
Pass 2 — Depth
- Drew the design suction change depth. A dotted olive line at 1.8 m tagged Hs 1.8 m — the AS 2870 depth below which seasonal movement stops mattering. It is the reason the depth chip can't move the class, and it is now on the drawing instead of only in the copy. Every reachable state drills past it, which is exactly the point.
- The class box now presses like a rubber stamp when the class changes: 0.42 s, cubic ease-out, 1.07 → 1.00, driven from the animation loop rather than by a CSS class toggle on a scene the loop already owns.
- The fill-depth investigation buys something you can see. The midpoint split adds real sample tags between the pinned ones, so switching the $240-a-lot line on visibly densifies the log rather than only moving a number.
- Motion floor. The water line's dash drift and the arrow's breathing both hold an opacity floor of 0.72, so the signature is visibly alive at any capture instant — no phase arithmetic against the seven-second settle.
- Ledger notes now argue in the state's own numbers — "Guildford clay logs as a Class M block with ys 32 mm, and costs exactly the same as any other profile at this depth and lot count" — rather than restating a generic claim.
Pass 3 — Hardening
- Chanel rule. Removed the ground-hatch ticks under the surface line — twenty-five decorative strokes that carried no information and were what collided with the movement label in Pass 1. The 2.2 px surface line and the depth axis say "natural ground level" perfectly well.
- The "On every job" strip repeated the hero trust line verbatim. The fourth slot now carries new information: refusal depth and water level recorded with the date.
- Trimmed a sentence from the hero lede so the trust signal clears the sticky bar at 375 without scrolling; the audience line moved to the services heading, where it earns its place.
- Stepper unit reads "Lot" at one and "Lots" above it.
- 375 sweep: scrollWidth exactly 375, no element outside the viewport box (SVG descendants and off-canvas skip links excluded, scrolling ancestors respected), the masthead wordmark clears the call button, the call target is 44 px tall, the badge docks beneath the drawing and stays inside the signature's container, and all eight lot boxes draw inside the sheet.
- Reduced motion: the rAF loop never starts, a settled frame is drawn with every stratum and tick present, the probe reports settled, and no reveal is left at opacity 0.
- Form patterns proved by driving checkValidity on deliberately invalid values rather than by reading the attribute — every literal special inside a character class is escaped, and the zero-console-error assert is what would surface a dead regex.
Two independent implementations back the numbers on this page: a spec-time oracle that re-derives the whole model, enumerates all 576 grid cells, checks integer safety, verifies every AS 2870 band and computes every contrast ratio (541 assertions), and a headless harness that drives the running page at 1200, 1000 and 375 plus reduced motion and asserts its output against a third reimplementation of the model (221 assertions). Both are green. The page's own figures were never trusted against the page's own function.
Local SEO we'd implement for the real business
None of this ships on the demonstration. The live page carries only WebPage, CreativeWork, WebSite and BreadcrumbList schema that names it a demonstration — marking a fictional business up as a real one would pollute the index with a business that does not exist. For a real client the block below is what we would ship, with their registration, their coordinates and their own review feed.
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "ProfessionalService",
"@id": "https://datumground.com.au/#business",
"name": "Datum Ground Testing",
"description": "Residential site classification to AS 2870 and geotechnical site investigation to AS 1726 across the Perth metropolitan area.",
"url": "https://datumground.com.au/",
"telephone": "+61 8 XXXX XXXX",
"email": "bookings@datumground.com.au",
"image": "https://datumground.com.au/img/rig-malaga.jpg",
"logo": "https://datumground.com.au/img/logo.png",
"priceRange": "$$",
"currenciesAccepted": "AUD",
"paymentAccepted": "EFT, Card",
"address": {
"@type": "PostalAddress",
"streetAddress": "Unit N, XX Example Road",
"addressLocality": "Malaga",
"addressRegion": "WA",
"postalCode": "6090",
"addressCountry": "AU"
},
"geo": { "@type": "GeoCoordinates", "latitude": -31.85, "longitude": 115.89 },
"areaServed": [
{ "@type": "City", "name": "Perth" },
{ "@type": "AdministrativeArea", "name": "Perth metropolitan area, Western Australia" }
],
"openingHoursSpecification": [{
"@type": "OpeningHoursSpecification",
"dayOfWeek": ["Monday","Tuesday","Wednesday","Thursday","Friday"],
"opens": "06:30", "closes": "15:30"
}],
"hasOfferCatalog": {
"@type": "OfferCatalog",
"name": "Site classification and geotechnical services",
"itemListElement": [
{
"@type": "Offer",
"itemOffered": { "@type": "Service", "name": "Residential site classification — 2 holes to 3.0 m, AS 2870-2011" },
"priceSpecification": {
"@type": "PriceSpecification",
"price": "620", "priceCurrency": "AUD", "valueAddedTaxIncluded": true
}
},
{
"@type": "Offer",
"itemOffered": { "@type": "Service", "name": "Additional lot on the same visit" },
"priceSpecification": {
"@type": "PriceSpecification",
"price": "410", "priceCurrency": "AUD", "valueAddedTaxIncluded": true
}
},
{
"@type": "Offer",
"itemOffered": { "@type": "Service", "name": "Fill-depth investigation for a Class P site" },
"priceSpecification": {
"@type": "PriceSpecification",
"price": "240", "priceCurrency": "AUD", "valueAddedTaxIncluded": true
}
}
]
},
"aggregateRating": {
"@type": "AggregateRating",
"ratingValue": "4.9", "reviewCount": "137", "bestRating": "5"
},
"review": [
{
"@type": "Review",
"author": { "@type": "Person", "name": "Nathan R." },
"datePublished": "2026-07-14",
"reviewRating": { "@type": "Rating", "ratingValue": "5", "bestRating": "5" },
"reviewBody": "Booked Tuesday, bored Thursday, Class A report with my slab designer the following Monday. Somebody actually explained what the letter meant."
},
{
"@type": "Review",
"author": { "@type": "Person", "name": "Costa V." },
"datePublished": "2026-06-02",
"reviewRating": { "@type": "Rating", "ratingValue": "5", "bestRating": "5" },
"reviewBody": "Eleven lots, one morning, one invoice, and the reports came back numbered to match my lot plan."
}
]
}
</script>
The aggregateRating and review nodes only go live once they are pulled from the client's real Google Business Profile feed — never hand-written. The hasOfferCatalog prices must match what the page actually says, or the markup becomes a liability rather than an asset.
What would change for the real client
Everything on this page that is procedural would become theirs: rig photos on the truck at a real Baldivis block, a real NATA-endorsed scope reference in place of the placeholder, their engineer's name against the classification, and their actual report template as the download.
- Job and scheduling system. The booking form posts into whatever runs the yard — simPRO, AroFlo, Tradify or ServiceM8 for the job card, the rig allocation and the site address. The lot count and the depth chip map straight onto line items, so the quote the customer saw is the quote that opens in the system.
- Bore logs and lab data. Field logs from gINT or HoleBASE SI, sample results from the lab's LIMS, and the classification letter written back into the job record — so the page's log drawing could eventually render the client's actual logged strata for a completed job rather than an illustrative profile.
- Accounting. Xero or MYOB for the invoice, with the same line structure the ledger shows on screen — first lot, additional lots, depth, investigation, travel — so nothing on the invoice is a line the customer has not already seen.
- CRM and follow-up. HubSpot or Freshsales for the builder relationships that actually drive volume; a builder who sends eleven lots is a different pipeline from an owner-builder with one.
- Reviews and local presence. A live Google Business Profile feed replacing the demonstration testimonials, which is also what unlocks the review schema above. Suburb landing pages for the areas that convert, built from the same service-area data the map already carries.
- Report delivery. A link the builder can open without an account, with the log sheet, the classification and the sampling record attached — plus a webhook into the builder's own document system where they have one.