How this was built
Counterweight Garage Doors
A fictional Malaga garage door company — supply, install and repair, Perth metro-wide. The page has one job: turn a homeowner replacing a tired door (or trapped behind a broken one) into a measure-and-quote booking. The Door Studio makes the price honest and the facade visible before anyone picks up the phone.
Palette — steel on render
Argued from the product: a powder-coated steel door hung in a rendered Perth elevation. Grey-white ground, charcoal ink, one confident powder-coat blue, and the torsion spring's brass as the marks-only accent. The brass never sets small text — the ink/line split keeps body copy at 13.8:1 and reserves the warm tone for springs, dimension ticks and eyebrow rules.
Type — the shop drawing
Chakra Petch for display: squared, engineered, reads like a laser-cut nameplate — headings, buttons and the configurator's price all set in it, so the price card lands like a shop-drawing title block. IBM Plex Sans carries body copy (16.5px, professional and legible one-handed), with IBM Plex Mono for phone numbers, drawing numbers, field labels and dimension text. The typographic moment is the title block itself: DRG CW-288, a revision letter that bumps on every configuration change, and the installed price at 2rem Chakra Petch.
Signature — the Door Studio
A configurator driving an animated SVG house elevation. The house — hip roof, entry door, window, ground line — is hand-authored SVG; the door zone (opening, interior with car silhouette, cutaway, mechanism, door, dimension line) is rebuilt by JS on every configuration change. Two door mechanisms are drawn honestly:
- Sectional: four panels clipped to the opening, each translated up the track per frame; as a panel's top passes the header it foreshortens (its clip height follows cos θ, anchored at the panel's bottom edge) and a ghost bar fades in inside the dashed cutaway zone above the lintel — panels visibly "tilt and track up". The torsion spring is a brass zigzag whose dash offset winds as the door moves, with lift cables that shorten to the door's bottom edge.
- Roller: a slat-pattern curtain whose height shrinks as the drum above it thickens (10px → 26px), the curl read as a growing rounded bar in the cutaway.
Animation is a tiny sequenced engine: first draw earns the entrance (door opens 0 → 0.5 over 1.45s), every later change closes-then-reopens in 460ms total (the W21 dual-speed rule), and between transitions the door breathes between 0.35 and 0.62 open on a 6.5s sine — a never-invisible floor, so the 7-second thumbnail always catches it mid-open and visibly alive. Every change handler bumps an animation token before touching state (the W25 demolition-race rule): a rapid-fire burst of clicks abandons in-flight frames cleanly instead of letting a stale closure index a rebuilt scene. window.__garagedoors exposes config, price, the open fraction and a settled flag; reduced motion renders the settled f=0.5 frame with no loop.
Honest numbers — pinned anchors
Every figure on the page derives from the spec's pinned anchors, and the QA harness re-implements the price model independently and asserts the displayed figures match at rest and across every driven combination.
| Item | Anchor | Worked example (measured) |
|---|---|---|
| Sectional, ribbed (opener incl.) | single $2,150 · double $2,890 | Rest state: double ribbed Charcoal = $2,890 |
| Flatline profile | +$260 (sectional only) | Double flatline timber-look: 2,890 + 260 + 680 = $3,830 |
| Timber-look laminate | +$680 (sectional only) | |
| Roller, manual | single $1,450 · double $2,050 | Single roller motorised: 1,450 + 390 = $1,840 |
| Motorised roller drive | +$390 | |
| Powder-coat colours | no change | On-card: "colour changes the door, not the price" |
| Width > 5.4 m | price-less by design | "Custom — quoted on measure"; the drawing still updates |
| Repairs | spring from $290 · service $160 · opener from $520 | Panel replacement quoted on inspection (price-less by design) |
The services grid floors equal the configurator minimums — "sectional from $2,150" is a single ribbed powder-coat door, "roller from $1,450" is a single manual — so the page never argues with itself. Controls that can't price honestly say why on the card: timber-look is disabled on rollers ("laminate faces are a sectional-panel product"), profile chips lock for the slat curtain, and switching to a roller with timber selected falls back to Charcoal with the reason printed on the title block.
Conversion decisions
- Two CTAs, two jobs. The measure-and-quote booking is primary everywhere; the 7am–7pm breakdown line is the secondary path, styled in brass because a jammed door traps the car — it gets the header slot, a hero line, and the larger half of the mobile sticky bar with the number printed on it.
- The studio pre-fills the form. Every configuration writes its spec and measured price into the enquiry notes and flips the job-type chip, so the demo interaction arrives as a warm, specific lead.
- The "it's broken now" checkbox surfaces the breakdown copy immediately — the honest safety line about loaded springs plus the phone number — and switches the confirmation to a 20-minute callback promise, instead of making a stuck customer wait for a form round-trip.
- Form fields: name, phone, suburb (dispatch is suburb-based from Malaga), job-type chips, notes. Nothing a phone-in-one-hand user doesn't need. Validation is front-end only with a designed local confirmation that says plainly nothing was sent.
- Torsion-spring FAQ gives the genuinely correct advice — don't touch the winding cones, keep the door down, call — because the honest answer is also the strongest conversion argument for a repair business.
Local SEO we'd implement for the real business
This demo page ships only WebPage/CreativeWork schema naming it a demonstration — fictional structured data in a real index would be dishonest markup. For the real client we'd ship the full local-business graph, wired to their true NAP, licence and live review feed:
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "HomeAndConstructionBusiness",
"name": "Counterweight Garage Doors",
"description": "Garage door supply, installation and repair across Perth.",
"telephone": "+61-8-XXXX-XXXX",
"address": {
"@type": "PostalAddress",
"addressLocality": "Malaga",
"addressRegion": "WA",
"postalCode": "6090",
"addressCountry": "AU"
},
"geo": { "@type": "GeoCoordinates", "latitude": -31.86, "longitude": 115.90 },
"areaServed": { "@type": "City", "name": "Perth" },
"openingHoursSpecification": [{
"@type": "OpeningHoursSpecification",
"dayOfWeek": ["Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"],
"opens": "07:00", "closes": "19:00"
}],
"priceRange": "$$",
"aggregateRating": {
"@type": "AggregateRating",
"ratingValue": "4.9", "reviewCount": "187"
},
"review": [{
"@type": "Review",
"author": { "@type": "Person", "name": "Real Customer" },
"reviewRating": { "@type": "Rating", "ratingValue": "5" },
"reviewBody": "Pulled from the live Google reviews feed."
}]
}
</script>
Techniques
- Everything procedural: the elevation, the metro map (coastline, Swan River, the 45-minute ring around Malaga), the favicon — all inline SVG; zero raster assets, no libraries.
- SVG discipline per the playbook: all door animation writes transform/geometry attributes from JS (never CSS-animating a property an element also sets as a presentation attribute), toggles use the hidden attribute with the [hidden]{display:none !important} guard, and a no-JS fallback door sits in the markup until the script replaces it.
- Entrance choreography is class-gated on document.fonts.ready with a 900ms fallback timer, defaults visible without JS, and collapses to nothing under prefers-reduced-motion.
- The phone pattern attribute is v-flag-valid (escaped parens/plus); the form's validity is asserted headlessly with an empty submit after a hard reload.
Iteration log
- Drove the full harness (67 asserts): every chip/swatch/size against an independently reimplemented price oracle, empty and filled submits after a hard reload, the rapid-fire nine-click burst, reduced motion, both pages at 375 — all green, zero console errors.
- The screenshot look then caught what the state asserts couldn't: at rest, the Charcoal door read as one murky mass against the near-black interior. Lightened the interior gradient, gave the car a visible windscreen and lighter body, and added a weather-seal highlight along the door's moving bottom edge — the mid-open gap now reads as a lit room behind a steel door.
- At 375 the eyebrow broke mid-word ("METRO-/WIDE"); wrapped the phrase in a nowrap span. Gave the cutaway annotation a ground-colour paint-order halo so it holds against the roof plane, and put a highlight lip on the roller's bottom rail, which had vanished into the interior.
- Enriched the mechanism: lift cables shorten visibly to the door's bottom edge and the torsion spring's dash offset winds against door travel — the counterweight idea is drawn, not just named. Added a soft shadow the mid-open door casts down into the room, moving with the bottom edge on both mechanisms.
- Second-read detail: the drawing's revision letter (REV A → B → C…) bumps with every configuration change, like a real drawing register; the confirmation panel echoes the exact configured spec back in mono.
- Micro-interactions: the title-block price fades in on every recalculation; chips lift their border on hover; the close-then-reopen change animation (150ms + 310ms) reads as the door being re-hung rather than the SVG being swapped.
- 375 masthead first (the W18 offender): wordmark and tel measured for collision at 375 and 360; under 400px the number collapses to a solid "Call" button. Sticky bar verified fixed, tel target ≥44px, inside the bottom 140px. Keyboard drive added: Enter on a focused swatch changes the finish, FAQ toggles, focus-visible outline confirmed.
- Reduced-motion run: settled f=0.5 frame, no loop, config changes render instantly settled. The rapid-fire drive (nine clicks in one evaluate, no settle between) left a consistent oracle-matched state — the animation token is bumped in the handler before the state swap, so no stale closure ever touches a rebuilt scene.
- One harness artifact ruled out before calling a defect: a footer screenshot displayed light in review while canvas pixel-sampling of the same capture read the correct #24272B — the rendered pixels, not the preview, are ground truth. Chanel rule: dropped the planned door-height dimension line — the width figure carries the shop-drawing idea alone. Final copy read at 375; guide tables in .table-scroll. Final suite: 72 asserts, 0 failures.
What changes for the real client
Their photography replaces nothing — the procedural elevation stays as the configurator — but their finished-job photos join the reviews, the review strip wires to their Google profile, and the enquiry form posts to their job-management system: for a door and trades operation that's ServiceM8, Simpro, Tradify or AroFlo, with the breakdown path opening a priority job and SMS-ing the on-call installer. The configurator's anchors become their real price book, maintained in one JSON block.
Prices, licence numbers, reviews and the business itself are fictional demonstration content. The torsion-spring safety advice is real: springs are under load — don't undo them yourself.