Build guide · Generative Assets
The concept. Trueline Glass & Glazing is a fictional Osborne Park glazier — cricket-ball windows, 7am break-in board-ups, shower screens and compliance-letter safety upgrades across Perth's inner north. The page has one job: book a same-day measure. The art direction is the glass rack in morning showroom light — clean panes leaning in the A-frame, the green glow float glass only shows on its edge — precise and unhurried, zero cracked-glass drama.
The spec's ink/line rule applied twice: glass-edge green fails 4.5:1 as small text on daylight (3.9:1), so body-scale green is set in the derived #256B5D and buttons in #2F7566; the bright #3E8E7E is reserved for lines, marks and the pane's edge glow. Silicone grey measures 2.75:1 and is confined to borders.
Job chips (window re-glaze / shower screen / splashback / sliding door), glass chips (4 mm float / toughened / laminated / obscure) and 300–2400 mm width/height steppers drive a procedural SVG pane drawn face-on and edge-on. Geometry is laid out in JS at 0.125 px/mm and eased to new dimensions with a 240 ms cubic-out requestAnimationFrame lerp (instant under reduced motion). The glass type renders procedurally: float's reflection streak lives in a clipPath that tracks the pane rect; toughened gains the etched corner stamp "T — AS 1288"; laminated thickens the edge-on bar and draws the interlayer seam; obscure overlays an SVG <pattern> frost. Scene swaps (shower screen, splashback) toggle SVG groups via the hidden attribute — with the [hidden]{display:none!important} guard, and never g.hidden=true, which silently no-ops on SVG. The live state (job, glass, dims, billed area, price, form status) is exposed at window.__glazier for QA.
Model: price = fit fee + glass rate × billed area, where billed area = max(actual m², 0.5 m² minimum billable pane). The minimum is the derivation that makes every pinned "from" anchor exact: $120 + rate × 0.5 reproduces $190 float, $280 toughened, $260 laminated, $220 obscure.
| Component | Value | Source |
|---|---|---|
| Fit & seal fee (window) | $120 | pinned |
| Fit fee (sliding door, incl. new rollers + track service) | $180 | derived — $180 + $320 × 0.5 = the pinned $340 floor |
| 4 mm float | $140/m² | pinned |
| Toughened 6 mm | $320/m² | pinned |
| Laminated 6.38 mm | $280/m² | pinned |
| Obscure 4 mm | $200/m² | pinned |
| Sliding-door floor | $340 | pinned — laminated sliders would otherwise undercut it, so the floor applies |
Rounding rule: the glass line rounds to the nearest dollar (Math.round(rate × billed)) and the total is fee + rounded glass line, so the card never argues with its own line items. The oracle in QA keeps exact arithmetic. Measured rest example: 1200 × 900 mm toughened window = 1.08 m² → $120 + round($345.60) = $466, matching the spec's cross-derived ≈$466. Cheapest reachable output — float window at minimum size — measures $190, equal to the services grid's re-glaze floor.
Honest disables (no control computes a dishonest figure): shower screens and splashbacks are quoted-on-measure scopes — selecting them disables the steppers and glass chips with the reason on-page ("screens are priced by configuration, not area — the measure is free") and the card shows only the pinned anchors ($680 / $1,250 semi-frameless / frameless; $420/m² splashbacks). Sliding doors disable float ("can't legally go in a door under AS 1288") and obscure ("comes as toughened obscure, quoted with the pattern in hand"), auto-switching to toughened with the switch announced. The pane-weight second read uses flat glass mass at 2.5 kg/m² per mm of thickness.
This demo deliberately ships only WebPage schema naming it a demonstration — fictional LocalBusiness/Review data in a real index is dishonest markup. For a real Trueline, we'd ship:
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "LocalBusiness",
"name": "Trueline Glass & Glazing",
"description": "Window re-glazing, shower screens, splashbacks
and emergency board-ups across Osborne Park and Perth's
inner north. Installs to AS 1288 & AS 2047.",
"telephone": "+61-8-XXXX-XXXX",
"address": { "@type": "PostalAddress",
"addressLocality": "Osborne Park", "addressRegion": "WA",
"postalCode": "6017", "addressCountry": "AU" },
"areaServed": ["Osborne Park","Tuart Hill","Yokine","Balcatta",
"Stirling","Innaloo","Karrinyup","Dianella","Mount Hawthorn",
"North Perth","Leederville","Wembley"],
"openingHours": ["Mo-Fr 07:00-17:00","Sa 08:00-12:00"],
"priceRange": "$$",
"review": { "@type": "Review",
"reviewRating": { "@type": "Rating", "ratingValue": "5" },
"author": { "@type": "Person", "name": "[verified customer]" },
"reviewBody": "[pulled from the live Google / Podium feed]" },
"aggregateRating": { "@type": "AggregateRating",
"ratingValue": "[live]", "reviewCount": "[live]" }
}
</script>
Plus suburb-level service pages (the FAQ answers above are each a query cluster: "safety glass requirements WA", "window cracked by itself", "shower screen cost Perth"), Google Business Profile with the board-up line as the primary category action, and review schema fed from a real review platform — never hand-typed.
Pass 1 — Craft. Drove the full page headlessly (46 asserts) and read the screenshots. The rendered image caught what the asserts couldn't: the wordmark's "LINE" was rendering at 0.56rem — the sub-brand rule .wordmark span also matched the two-tone span inside the <b>; scoped it to a direct child. The hero A-frame read as a giant letter "A" with panes floating beside it and four etch labels colliding at the base; rebuilt the composition — end-frame plus perspective rail, all panes on a consistent −10° lean with staggered feet, etch labels cut to two. The hero eyebrow orphan-wrapped "PARK" at 375px; shortened to "Glaziers · Osborne Park". Rest card verified at $466 against the independent oracle.
Pass 2 — Depth. Drove every scenario against a reimplemented oracle: float window at minimum size $190 (equals the services floor), slider auto-switching float→toughened at the $340 floor with the AS 1288 reason on-page, laminated slider floored ($320 raw → $340), obscure 2400×1200 at $696, stepper clamps at 2400. Added the price-tick micro-interaction (the total bumps 5.5% with a brief mint flash on change, killed under reduced motion) and kept the second reads: the pane-weight line ("≈ 16 kg — a careful two-hand carry"), and the front rack pane etched 1200 × 900 · 6 T — the estimator's own rest state. Chased a screenshot suspicion that the stepper labels rendered salmon; computed style measured the correct #59646B — an image-scaling artifact, logged rather than "fixed".
Pass 3 — Hardening. Masthead first at 375 per the W18 rule: wordmark and 44px call pill both inside the viewport, no overflow (scrollWidth 375). Empty submit on a fresh load raises all three validation errors with focus moved to the first invalid field; filled submit renders the "Thanks — request received" confirmation with the demo disclosure. Keyboard drive: Enter on a focused chip switches the job. Reduced-motion load settles instantly with the estimator readable at $466. External requests measured as Google Fonts only; every (08) 9xxx number on the page uses the reserved 9000 exchange; JSON-LD live blocks carry WebPage only. Chanel rule: removed the pane's second reflection streak — one is a reflection, two were decoration.