How this page was made · site 384
A section drawn to scale, and a fee that refuses to move
Ridgeline Bushfire Planning is a fictional Mundaring bushfire planning consultancy. Its customers are people whose building permit is stuck: an owner-builder in Chidlow, a landowner subdividing four lots into twelve in Serpentine, a childcare manager in Roleystone. The page has one job — turn “do I even need this, and what does it cost” into a phone call, including for the people who don’t need it.
The signature: the Setback
The Setback is a cross-section through a lot, drawn on a survey sheet. The house pad sits on cleared ground at left; the classified vegetation at right; the separation between them is dimensioned in ember with real arrowheads, and a dashed 100 metre buffer is measured back from the vegetation edge. Five AS 3959 vegetation chips redraw the vegetation band; a distance stepper walks the separation from 10 to 120 metres and re-scales the whole frame.
The drawing is true 1:1 — the vertical scale equals the horizontal one, no exaggeration — because a section that stretches its own vertical axis is the visual equivalent of a rounded-up number. A 10 metre scale bar sits under the section and is always ten real metres, so it visibly shrinks as the frame grows from 70 to 180 metres. That shrinking bar is the honesty of the zoom in one mark.
Why the two most interesting controls change nothing
The vegetation chip and the distance stepper are deliberately price-neutral. They redraw the whole section, retitle the sheet and bump its revision letter — and the fee in the title strip does not move by a cent. That is not a missing feature. Vegetation class and separation set your construction standard under AS 3959; they do not set what it costs to have someone walk the block and write the report. A page that priced its fee off the class the visitor guessed at would be selling a number it cannot stand behind.
The same discipline runs one step further. The page carries a refusal on three surfaces — the sheet notes, the ledger and the plain-text mirror:
The section never prints a BAL rating, a construction requirement, or any figure a reader could act on for bushfire safety. It prints the class you selected, the separation you set, and the scale bar. Nothing else.
The state that sends the visitor away
Step the separation past 100 metres and the whole quote goes price-less. The pad draws clear of the buffer in eucalypt — not ember, because this is good news — the service chips disable with a reason, and the badge reads “likely nothing to pay — check the DFES map first”. The reason names the DFES Map of Bush Fire Prone Areas and says, in the business’s own words, before you pay anyone, including us. Losing the job on the page is the strongest thing this page does; the chosen service is remembered and restored the moment the separation comes back to 100 metres.
At exactly 100 metres the buffer line lands exactly on the pad edge — the pad is on the boundary, not outside it — so 100 m is priced and 110 m is not. Over the pinned 10–120 m grid in tens, only 110 and 120 trip the state. That reachability claim was enumerated over the grid in the verification oracle, not spot-checked.
Techniques
- Pure SVG, no canvas, no WebGL, no libraries. The section, the survey sheet, the service-area map and the icons are all generated in JavaScript against an SVG DOM. Nothing is fetched but three Google Fonts.
- Zoom-to-fit frame. The sheet frame is
separation + 60 min scene units — 70 m at the 10 m state, 180 m at the 120 m state. The pad apron (26 m) and the vegetation band (34 m) are constant in metres, so both shrink on screen as the frame grows and the geometry stays truthful. - The badge’s height drives the sheet. The title strip is a real HTML overlay (so the fee is a live text node, not painted glyphs). The sheet reserves a title band whose height is the strip’s measured
offsetHeightplus 24 px, and every drawn element is clipped below that rule. The badge cannot cover the drawing, at any width, because there is nothing drawn where it sits. - Dual-speed redraw. The first draw earns a 26 ms-per-element entrance capped at 1.5 s; every subsequent state change redraws at 11 ms capped at 520 ms, so a stepper tap reads as snap, not lag.
- Ambient motion with a token. The canopy sways a degree or so on two harmonics, the grass leans, and a pale air shimmer crosses the cleared ground. Any control that rebuilds the scene bumps a draw token in the handler, before the state swap, so a rapid-fire burst of clicks can never leave a stale animation closure indexing the previous scene.
- Reduced motion parks the clock at t = 1.9 s and renders one settled frame: the canopy sits mid-lean rather than bolt upright, so the still is a drawing rather than a freeze.
- Second read: the sheet is a survey drawing, so it carries a revision letter. Change the scenario and
DWG RBP-384 · REV Aticks to REV B, REV C, REV D… Nobody notices it first time.
The fee model
Every fee is a fixed professional fee, GST-inclusive, quoted against a written scope. All totals display to the whole dollar and every reachable cell in the model is a whole dollar by construction — the rates are whole dollars against whole-unit steppers, so there is no rounding decision to make.
| Line | Rate | What it multiplies |
|---|---|---|
| BAL assessment — single lot | $680 | flat |
| BMP — single dwelling | $1,850 | flat |
| BMP — subdivision or DA | $4,200 + $95 a lot | the actual lot count, 2–40 in twos |
| Emergency evacuation plan | $2,400 | flat |
| Bushfire Hazard Level — scheme amendment | scoped first | never priced on the page |
| Perth Hills & metro travel | $0 | added once |
| Peel & South West travel | $220 | added once |
| Beyond that | quoted | added once, price-less |
| Council & certifier lodgement fees | at cost | never marked up, never estimated |
| Vegetation class & separation | $0 | nothing — that is the point |
Worked examples, measured from the running page
| Scenario | Arithmetic | Badge |
|---|---|---|
| Rest state — BAL assessment, Class B at 40 m, Perth Hills | 680 | $680 |
| Subdivision BMP, 12 lots, Peel & South West | 4,200 + 12×95 + 220 | $5,560 |
| Subdivision BMP, 2 lots, Perth Hills (the subdivision floor) | 4,200 + 190 | $4,390 |
| Subdivision BMP, 40 lots, Perth Hills | 4,200 + 3,800 | $8,000 |
| Subdivision BMP, 20 lots, Perth Hills | 4,200 + 1,900 | $6,100 |
| Evacuation plan, Peel & South West | 2,400 + 220 | $2,620 |
| Single-dwelling BMP, beyond the travel zones | 1,850 computable | $1,850 + travel quoted |
| Scheme amendment, any zone | — | scoped with your council first — no charge to ask |
| Any service, separation 110 m or 120 m | — | likely nothing to pay — check the DFES map first |
The cheapest priced output anywhere in the model is $680, which is exactly the services grid’s lowest “from” figure. The rest state is the floor here, deliberately: the entry service is the cheapest one, so the first number a visitor sees is the smallest true number on the page.
Locks, holds and restores
- Lots is live only on the subdivision BMP. On every other service it disables with “single lot — nothing to count” and its value is held, not reset. Subdivision at 20 lots → BAL assessment (disabled, 20 held) → evacuation plan (still disabled, still 20) → subdivision again restores 20 and the badge returns to $6,100. On a partial unwind the forced value holds; the memory only comes back when it is valid again.
- Travel disables on the scheme amendment with “travel is inside the scoped fee”, and the included-work declaration is replaced (not merely supplemented) with “scope, travel and meetings are inside the quoted fee”. The verification asserts the standard line is absent, not just that the replacement is present.
- Service chips disable beyond the buffer, with the chosen service still visibly selected and greyed. Nothing is cleared; the visitor never loses their place while being told they may not need to be here.
- Restore memory is simply persistent state: a disabled control keeps its value, and any explicit change while it is free becomes the new memory. There is no separate memory to go stale.
Palette
Argued from ash, charred bark, eucalypt canopy and ember. Every ratio below was measured with WCAG arithmetic from the shipped tokens during Pass 1, not estimated.
The service-area map’s labels are body-ink class, not line-colour class: every town name is charred #22261F with a 4 px sheet-coloured halo via paint-order: stroke, so a label that crosses the ocean wash or the hills tint still reads at full contrast.
Type
Bricolage Grotesque (700) for display. A grotesque with slightly irregular, organic terminals — it carries the hand-annotated feel of a marked-up survey sheet without becoming a novelty face, and it holds up at the 1.72 rem fee figure in the title strip.
Instrument Sans for body. A quiet, well-fitted workhorse; body is 16 px on mobile and never smaller than 0.78 rem anywhere that carries a sentence.
DM Mono (500) in exactly one role: clause and dimension strings. Section numbers, drawing numbers, the class string, every metre figure, the scale bar, the eyebrows. Whenever the page is speaking as an instrument rather than as a person, it speaks in mono. The typographic moment is the title strip: the fee set large in Bricolage with CLASS B · 40 M in mono at wide tracking directly above it — the drawing’s fact and the business’s price sharing one box, and only one of them moves when you change the class.
Conversion decisions
- The fee lives inside the artwork. The title strip is drawn as the sheet’s title block, top-right inside the ruled border, so the 1200×750 preview of this page carries the price, not just a picture. Below 641 px it docks directly beneath the drawing rather than covering it.
- Two CTAs above the fold at 375 px — a fee request and a tap-to-call — plus the trust line, all visible without scrolling, and a fixed call/quote bar for the whole scroll.
- The Setback writes the enquiry. Service, lot count, travel zone, vegetation class and separation are composed into the message field, ending with the sentence “I understand this is not a rating.” If the visitor types in the field, the handoff stops overwriting them.
- Form fields are the ones this trade actually needs: name, phone, the lot’s suburb, a lot-or-street line, what the council or certifier asked for, and a permit deadline. The deadline is optional because a stuck permit is the strongest qualifying signal a lead can give and we do not want to gate the send on it.
- The confirmation is a designed panel, hidden on load and on an empty submit, shown only after a valid submit. It restates the callback promise and the refusal — because a lead that arrives expecting a rating is a bad lead.
- The FAQ answers the questions that lose work: whether you need an assessment at all, how to check the DFES map yourself, and what happens when the rating comes back higher than you hoped.
Iteration log
Pass 1 — Craft
Driven, not read: every chip, both steppers, an empty submit and a filled submit, at 375, 1000 and 1200, with native-resolution screenshots reviewed by eye.
- A ledger row helper silently ate its value.
row(dt, dd, cls)was being called with four pieces of information, so the money argument landed in the CSS class slot: the travel line rendered “Perth Hills & metro” with no figure and the lots line lost its subtotal entirely. Every state assert was green while the ledger argued with the badge. Rebuilt asrow(label, sub, value, cls). - The buffer measure struck through the “HOUSE PAD” label. Both sat in the same band under the ground line. Found only in a native-resolution screenshot; the label moved down a row, and a permanent assert was added that no measure line may cross any scene label without a knockout box.
- The sheet name ran under the title strip at 1000 px and was clipped mid-word. The sheet-name strings were shortened and split, and the drawing is now clipped to the border so nothing can escape the sheet.
- Vegetation ran past the right border — the last tree’s canopy overhung the ruled edge. A
clipPathon the border now clips the scene, which is also more truthful: the vegetation continues past the sheet. - Two SVG elements set an
opacitypresentation attribute while also carrying the CSS-animated entrance class, so the stylesheet silently discarded the attribute (the W16/W17 failure shape). The alpha was baked into the stroke colours instead. - Contrast measured from the shipped tokens. Twenty-three pairs computed with WCAG arithmetic. One failed: the Sapience band’s eyebrow at
#CBE0C6measured 4.40:1 on eucalypt. Re-minted#DAEAD6at 4.90:1. Charred on canopy measures 4.10:1, which is exactly why no small text sits there. - The hero’s value proposition was three lines of tracked mono caps and read as shouting. It was shortened to one clause; the service list moved into the deck, where it belongs.
Pass 2 — Depth
- A 1,400 px void. With the whole signature stacked in the hero’s right column, the left column was empty from the CTA down to the services grid. The controls, ledger and text mirror moved into a two-column desk beneath the hero, and the copy column gained the two things this business actually sells: a “why we say no” card, and the three-step process (look it up, walk it, sign it).
- The sheet grew a revision letter. A survey drawing gets a new revision every time it is redrawn, so this one does:
REV Aon load, ticking B, C, D… with each scenario change. It is the second-read detail — nobody sees it the first time. - The beyond-the-buffer wash changed colour. It was ember, which read as alarm; the message is you probably don’t need to pay anyone. It is now eucalypt, and the buffer tag reads “100 m — PAD CLEAR OF THE BUFFER”. Ember is reserved for the measure, never the verdict.
- The dimension was rehung. It used to float thirty pixels above the tallest tree, which put it in a different place for every class. It now hangs from the top of the section with long dashed extension lines running all the way down to each measurement point — how sections are actually dimensioned, and it gives the sky a structure.
- A verandah on the dwelling. Two strokes; the part of a house that catches embers.
- Press feedback on chips and steppers (a one-pixel push), and the class leader line now terminates in the canopy with a dot rather than in mid-air.
Pass 3 — Hardening
- The masthead at 375 first. The wordmark’s right edge is compared against the call button’s left edge explicitly, and the nav is dropped below 900 px so the row is wordmark plus a 44 px call target. Page
scrollWidthis exactly 375 and no element crosses the viewport box. - Scene short forms below 640 px. The class label loses its “classified on site” tail, the frame note shortens, the sheet name collapses to one line, and the title strip docks under the drawing with the pinned short declarations — while the ledger and the plain-text mirror keep the full templates at every width. Both surfaces are asserted at 375.
- The service-area map was over-scaled and colliding. At full shell width its labels rendered at 26 px and the zone tag ran off the right edge into the north arrow. The map is now capped at 790 px beside its copy, the zone tags are split onto two lines clear of the scarp, the ocean label is set vertically in the water, and the north arrow is parked in empty ground. A permanent assert checks that no two map labels overlap and that every one sits inside the frame.
- Reduced motion renders one settled frame with the canopy parked mid-lean; two screenshots 1.1 s apart are byte-identical, and the badge still reads $680.
- Every
patternproved by drivingcheckValidityon a deliberately invalid value, not by reading the attribute. The lot-or-street field escapes its/inside the character class, which Chrome’s v-flag regex engine would otherwise reject at validation time — leaving the field silently validating nothing. - Ornament removed (the Chanel rule): a fixed radial eucalypt gradient over the whole page. On an ash ground it did nothing but tint the sheet white. Gone.
- The shimmer was recoloured. A red wavy line beside a house on a bushfire page reads as flame. It is now a pale grey-green air distortion — the same motion, none of the alarm.
- Rapid-fire drive: forty-eight control clicks dispatched in one evaluate with no settle between. The draw token is bumped in the handler before the state swap, so the scene settles once, on 20 lots, at $6,100, with zero page errors.
The build was verified against an independently reimplemented oracle — the fee model rewritten from the pinned anchors in separate code, never calling the page’s own function — across all 18,000 reachable cells of the control grid plus every worked example, the lots-lock drive, the partial-unwind drive, the beyond-the-buffer drive, the price-neutral drive and the keyboard path. 329 assertions across both pages, all green. The price-neutral drive asserts something stronger than equality: it holds a reference to the fee’s DOM text node and proves that node is never replaced while the section redraws around it.
Local SEO we’d implement for the real business
The live page emits only WebPage and BreadcrumbList structured data, because marking up a fictional business as a real one would be dishonest markup in a real index. For an actual practice we would ship the block below. ProfessionalService is the right organization type for a consultancy — the specialty is carried by additionalType, knowsAbout and hasOfferCatalog rather than by inventing a type — and reviews would be wired to the real review source, never hand-written.
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "ProfessionalService",
"@id": "https://ridgelinebushfire.com.au/#practice",
"name": "Ridgeline Bushfire Planning",
"additionalType": "https://www.wikidata.org/wiki/Q2251597",
"description": "BAL assessments, bushfire management plans and emergency evacuation plans across the Perth Hills, the metro fringe, Peel and the South West.",
"url": "https://ridgelinebushfire.com.au/",
"telephone": "+61 8 XXXX XXXX",
"email": "hello@ridgelinebushfire.com.au",
"image": "https://ridgelinebushfire.com.au/img/team-on-site.jpg",
"priceRange": "$$",
"address": {
"@type": "PostalAddress",
"streetAddress": "Suite 2, 000 Great Eastern Highway",
"addressLocality": "Mundaring",
"addressRegion": "WA",
"postalCode": "6073",
"addressCountry": "AU"
},
"geo": { "@type": "GeoCoordinates", "latitude": -31.900, "longitude": 116.166 },
"openingHoursSpecification": [{
"@type": "OpeningHoursSpecification",
"dayOfWeek": ["Monday","Tuesday","Wednesday","Thursday","Friday"],
"opens": "07:30", "closes": "16:30"
}],
"areaServed": [
{ "@type": "AdministrativeArea", "name": "Shire of Mundaring" },
{ "@type": "AdministrativeArea", "name": "City of Kalamunda" },
{ "@type": "AdministrativeArea", "name": "City of Swan" },
{ "@type": "AdministrativeArea", "name": "Shire of Serpentine-Jarrahdale" },
{ "@type": "AdministrativeArea", "name": "City of Mandurah" }
],
"knowsAbout": [
"AS 3959 Construction of buildings in bushfire-prone areas",
"State Planning Policy 3.7",
"Bushfire Attack Level assessment",
"Bushfire Management Plans",
"Bushfire Emergency Evacuation Plans"
],
"hasCredential": {
"@type": "EducationalOccupationalCredential",
"credentialCategory": "BPAD Level 2 accreditation",
"recognizedBy": { "@type": "Organization", "name": "FPA Australia" }
},
"hasOfferCatalog": {
"@type": "OfferCatalog",
"name": "Bushfire planning services",
"itemListElement": [
{ "@type": "Offer",
"itemOffered": { "@type": "Service", "name": "BAL assessment for a building permit" },
"priceSpecification": { "@type": "PriceSpecification", "minPrice": 680, "priceCurrency": "AUD", "valueAddedTaxIncluded": true } },
{ "@type": "Offer",
"itemOffered": { "@type": "Service", "name": "Bushfire Management Plan, single dwelling" },
"priceSpecification": { "@type": "PriceSpecification", "minPrice": 1850, "priceCurrency": "AUD", "valueAddedTaxIncluded": true } },
{ "@type": "Offer",
"itemOffered": { "@type": "Service", "name": "Bushfire Emergency Evacuation Plan" },
"priceSpecification": { "@type": "PriceSpecification", "minPrice": 2400, "priceCurrency": "AUD", "valueAddedTaxIncluded": true } }
]
},
"review": [{
"@type": "Review",
"author": { "@type": "Person", "name": "Verified client, Chidlow" },
"datePublished": "2026-03-11",
"reviewBody": "Walked the block on the Thursday, signed report on the Monday, permit released that afternoon.",
"reviewRating": { "@type": "Rating", "ratingValue": 5, "bestRating": 5 }
}],
"aggregateRating": {
"@type": "AggregateRating", "ratingValue": 4.9, "reviewCount": 63
}
}
</script>
Alongside it: a Google Business Profile in the Mundaring service area with the service list mirrored from hasOfferCatalog, an FAQPage block built from the six questions on the page, and one location page per local government — Mundaring, Kalamunda, Swan, Serpentine–Jarrahdale, Mandurah — each naming that council’s own referral path rather than swapping a suburb token into boilerplate.
What would change for a real practice
- Their desktop assessment stack. QGIS or ArcGIS with Landgate SLIP imagery and the DFES Map of Bush Fire Prone Areas, so the enquiry can arrive with the map extract already attached to the lot.
- Their field record. Fulcrum for the plot-by-plot record, photographs and GPS — which means the section on this page could be drawn from the practitioner’s real plot data for an existing client instead of from a demo model.
- Their proposal and CRM. HubSpot or Freshsales, with the form posting straight to a deal and the fixed fee generated from the same anchors this page uses, so the website and the proposal can never disagree.
- Their accounts. Xero for the invoice and the at-cost council disbursements, kept as separate lines exactly as the page promises.
- Their reviews and photos. A Google Business Profile feed replacing the demo testimonials, and their own site photography — though the drawing stays procedural, because the drawing is the argument.