Generative Assets · Wave 20 — Industry Demos IX · Site 260

How Closegrain Cabinetmakers was made

A conversion-first landing page for a fictional Bassendean custom cabinetmaker — couples on a forever-home kitchen, robe planners, owners whose 90s laminate has delaminated at the kettle. The page has one job: book a design consult. The signature, a Cabinet Configurator that draws a maker's plan live and prices it honestly, exists to make that consult request warmer.

Palette — workshop-afternoon oak

Every colour is argued from the bench at 4pm. This ground-plus-red-brown pairing deliberately lives near the most common AI-default palette (cream + terracotta + high-contrast serif), so the spec drew three hold-the-line rules: the accent is jarrah heartwood — deeper and browner than terracotta, argued from WA's own timber; the display face is a slab, never a high-contrast serif; and the ground carries a visible warm grain texture (a tiled data-URI SVG of faint plane strokes and knots), not gallery cream.

Shaving pale#F5EFE6 ground — fresh-planed pine and dust in low sun, grain-textured
Walnut dark#33291F structure and primary ink — oiled walnut, wrought hinges
Jarrah heart#8A3A28 LINE/MARK — dimension lines, plan marks, CTA; never body text
Gauge brass#8C6D1F marks — chips, focus rings, stars
Brass ink#6E5518 derived — link text; raw brass measured 4.27:1 on shaving pale, under the 4.5:1 floor, so a darker ink was minted (7.0:1 at #6E5518)
Jarrah deep#6E2C1E derived — price figures and hover states, 9.1:1 on white card stock

Type

Bitter — the solid-timber edge

A slab serif for display: the letterform equivalent of a square-planed edge. Deliberately not a high-contrast serif — that's banned default #1's face, and a cabinetmaker's brand should read workshop, not gallery.

Source Sans 3 — the workhorse

Body and UI. Legible at 16px+ on a phone in one hand, which is where most of this traffic lives.

Fragment Mono — 7.0 lm × $1,700/lm

Linear metres, finishes and prices. Everything measured or costed renders in mono — the marking-gauge voice of the page.

The signature — Cabinet Configurator

Project chips (kitchen / robe / laundry / vanity), kitchen layout chips (galley / L / U / island), a 4–12 lm slider and finish chips (melamine / 2-pac / veneer) drive a procedural SVG maker's plan: plan view plus an elevation strip. Carcasses hatch in (a 45° SVG pattern), 600 mm module lines divide each run, the door-face line sits on the working edge, and jarrah dimension lines with architectural tick ends annotate each segment. The elevation strip draws one door per 600 mm module in the chosen finish — melamine flat, 2-pac with a sheen gradient and highlight line, veneer with a drawn-grain pattern overlay — under a grey benchtop bar labelled "stone — separate trade".

Implementation notes: run geometry is computed in metres per layout, converted at 36 px/m, bounding-boxed and centred, and the dynamic <g> is rebuilt as an SVG string on every input. Positioning lives on outer <g transform> attributes; the hatch-in and dim fades are CSS opacity animations on separate inner elements that set no competing presentation attribute (the W16/W17 rule). No stroke-dash draw-ins are used anywhere, which sidesteps the round-cap dot artefact class entirely. The rest state is mid-demonstration: L-shape, 7 lm, 2-pac, plan drawn, $11,900 showing — and a live price readout sits in the configurator header so the figure shares the 1200×750 thumbnail with the plan. State is exposed at window.__cabinetmaker.

Pricing model — shape and derivations

ScenarioModelMeasured
Kitchen (any layout)lm × rate — melamine $1,150, 2-pac $1,700, veneer $2,100; min 4 lmrest 7 × $1,700 = $11,900
Melamine, same run7 × $1,150$8,050
Walk-in robefrom $2,400, quoted on drawingslider disabled, reason shown ✓
Laundryfrom $3,200, quoted on drawingslider disabled, reason shown ✓
Vanityfrom $1,400, quoted on drawing= services-grid floor ✓

Conversion decisions

Local SEO we'd implement for the real business

This demo page ships only a WebPage schema naming it a demonstration — fictional structured data in a real index is dishonest markup. For a real client we would ship LocalBusiness + Review schema fed by their actual details and review stream:

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "LocalBusiness",
  "@id": "https://example.com.au/#business",
  "name": "Real Cabinetmaker Pty Ltd",
  "description": "Custom kitchens, robes, laundries and vanities made in Perth.",
  "url": "https://example.com.au",
  "telephone": "+61 8 XXXX XXXX",
  "address": {
    "@type": "PostalAddress",
    "streetAddress": "Unit X / XX Example St",
    "addressLocality": "Bassendean",
    "addressRegion": "WA",
    "postalCode": "6054",
    "addressCountry": "AU"
  },
  "geo": { "@type": "GeoCoordinates", "latitude": -31.9, "longitude": 115.94 },
  "openingHoursSpecification": [{
    "@type": "OpeningHoursSpecification",
    "dayOfWeek": ["Monday","Tuesday","Wednesday","Thursday","Friday"],
    "opens": "07:00", "closes": "16:00"
  }],
  "priceRange": "$$$",
  "areaServed": "Perth metropolitan area",
  "aggregateRating": {
    "@type": "AggregateRating",
    "ratingValue": "4.9", "reviewCount": "87"
  },
  "review": [{
    "@type": "Review",
    "author": { "@type": "Person", "name": "Real Customer" },
    "reviewRating": { "@type": "Rating", "ratingValue": "5" },
    "reviewBody": "Pulled from the client's live Google review feed."
  }]
}
</script>

Plus: Google Business Profile with workshop photos and the service-area set, suburb-level service pages (kitchens Bassendean / Morley / Bayswater…), review schema fed from the live Podium/Google stream — never hand-typed — and a real NAP consistent across the site, GBP and directories.

What would change for the real client

Iteration log

Pass 1 — Craft

DRIVEN: rest state · finish chips · slider · layout chips · oracle cross-check · screenshots 1200×750 + full-page

Every displayed figure verified against an independently reimplemented oracle (rates re-derived from the spec in separate harness code): rest L-shape 7 lm 2-pac measured $11,900 (= 7 × $1,700), melamine on the same run $8,050, veneer at 9.5 lm $19,950. Layout chip to U-shape redrew the plan (dynamic markup changed) with the price honestly unmoved. Found in code re-read: vertical dimension labels rendered start-anchored on left-side dims, overlapping the carcass — split the label side by face (text-anchor:end on left dims); removed a leftover empty rotated text node in the elevation. Screenshot review at 1200×750 confirmed plan, jarrah dims and elevation strip all render — and revealed that the price figure sat below the 750px line, queued for Pass 2.

Pass 2 — Depth

DRIVEN: vanity/robe/laundry chips · slider-disable behaviour · handoff button · screenshots of each state

Added the live price readout to the configurator header — the $11,900 now shares the 1200×750 thumbnail with the drawn plan (measured top at 154px). Drove all three quoted-on-drawing projects: vanity $1,400 (= services-grid floor), robe $2,400, laundry $3,200, each with the metre slider and layout chips disabled and the honest reason visible on-page. Benchtop row correctly hides for non-kitchen projects. The handoff button pre-filled project + details ("…estimate $4,600 cabinetry (stone benchtop from $600/lm, quoted separately)"). Screenshot review caught the workshop illustration reading as a window frame in a dark room — rebuilt it: pale carcass open on the bench in two jarrah F-clamps, a leaning 2-pac door, sun shaft through the roller door slats, shavings on the floor. Second-read detail: the elevation strip labels the benchtop bar "stone — separate trade", echoing the card's honesty in the drawing itself.

Pass 3 — Hardening

DRIVEN: 375px masthead first · fresh-load empty submit · filled submit · sticky bar · FAQ · reduced-motion · drive-then-diff · honesty sweeps

Masthead screenshot at 375px FIRST: wordmark and the collapsed 44px phone button sit inside the viewport, no wrap, scrollWidth 375. Above the fold at 375: h1, value prop, 46px CTA and the flat-pack trust line. Empty submit on a fresh load raised validation on all 5 fields (5/5 aria-invalid, probe formStatus:'invalid'); filled submit swapped to the local confirmation ("Thanks, Tessa — request received… we'd call you back within one business day"), probe 'confirmed'. Sticky call bar measured 48px tall in the bottom band. FAQ accordion toggled via dispatched MouseEvent. Reduced-motion emulation: hero at opacity 1, plan fully settled — entry animations are opacity/transform-only CSS, killed by the media query. Drive-then-diff: galley at 10 lm measured $17,000 with state probe confirming. Honesty sweeps: the only (08) 9xxx number on the page is (08) 9000 0260; live JSON-LD contains only the WebPage demonstration schema. No stroke-dash draw-ins exist (all reveals are opacity fades), so the round-cap dot artefact class doesn't apply. Chanel rule: removed a redundant rotated side-label from the elevation rather than adding anything. Final: 42/42 harness asserts, zero console errors across 1200×750, 375×720 and full-page loads.

Techniques