Generative Assets · Industry demo 393 · Wave 47

How the Wideboard Shearing Co. page was made

A shearing contractor's landing page built around one idea: a shed drawn in plan, with the run counted out beneath it day by day. Every pixel is procedural — SVG, CSS and about 700 lines of vanilla JavaScript in a single file. No libraries, no build step, no images.

← The site · The collection index

01The concept

Wideboard Shearing Co. is a fictional shearing and crutching contractor working out of Northam into the central and eastern wheatbelt. Its customer is a grower with a number in their head — 2,000 head, three stands — and a question the phone can't answer quickly: how many days, and what does it cost?

The page has one job: turn "have you got a team free" into a booked run, with the days, the tally and the cost already worked out before anyone picks up the phone. Everything else on the page — the trust strip, the reviews, the map — exists to make the number credible.

The hard part of that job is a piece of arithmetic growers already do in their heads and contractors are often vague about: a stand does roughly 140 head a day on a full shear, so the run length is ceil(head ÷ (stands × tally)) and the last day is nearly always a short one. Most quotes hide that. This page puts it in the largest type on the screen.

02The palette, and why

Argued from the shed itself: galvanised iron, jarrah boards worn dark, greasy wool gold, and the blue of the shed's own steel. A warm grey ground well below cream in value, a condensed grotesque, and a gold/steel-blue accent pair with no terracotta anywhere — deliberately clear of the three palettes AI design defaults to.

Every ratio below was computed with WCAG arithmetic from the shipped hex and measured again in Pass 1. The rule the collection enforces: the accent is for lines and marks, and body text gets its own ink token.

#E6E2D8

Shed light — page ground

The light inside a shed at nine in the morning. Warm, grey, and well below cream in value.

#221E19

Jarrah black — body ink

12.81:1 on the ground, 16.56:1 on white cards, 10.13:1 on the hairline tint. Also the primary CTA fill under white labels.

#B98A2E

Wool gold — marks only

2.41:1 as text on the ground, so it never carries copy. It is the fleece, the tally fill and the day strip.

#7D5C16

Gold ink — small gold copy

4.75:1 on the ground, 6.15:1 on white cards — and 3.76:1 on the hairline tint, so gold copy never sits on a tinted row. Gold buttons use this fill, never the raw gold (3.12:1 under white, fails).

#3A6E86

Shed-iron blue — marks only

4.32:1 on the ground, so it stays in the drawing: the stands, the pen rails, the map rings.

#2A5566

Blue ink — blue copy and blue fills

6.27:1 on the ground, 8.11:1 on cards; white on it is 8.11:1. The raw blue would pass as a button fill at 5.59:1, but every blue in the conversion path uses this one for consistency.

#57503F

Soft ink — secondary copy

6.19:1 on the ground, 8.00:1 on cards, 6.90:1 on the ledger tint. Derived during Pass 1 and measured before use.

#6E6455

Shed shadow — the one failing fill

2.85:1 against the body ink. It is the shadow, so it was not lightened to make the ink work; the back-wall band's label is set in the fleece #EFE9DA instead, which measures 4.79:1 on it.

#EFE9DA

Fleece

The wool on the table and on the board, 13.68:1 under the body ink — and the pinned label ink for anything crossing the shadow.

Scene fills, measured against the body ink

FillHexInk ratioWhere
Board timber#C9A9787.44:1The board and the wool table
Fleece#EFE9DA13.68:1Sheep on the board, wool on the table
Pen rail#B4AC9C7.35:1Catching pens behind the board
Shed iron#9FA8A86.82:1The press
Wool bale#DCD2BA11.02:1Pressed bales beside the press
Shed shadow#6E64552.85:1 — failsBack wall and pen doorways; labelled in fleece at 4.79:1

Service-area map labels are body-ink-class text, so they are set in #221E19 with a paint-order: stroke halo in the ground colour wherever they cross a ring or a fill. The "lines only" tokens never label the map.

03Type

The typographic moment is the hero stamp: the day count set enormous — 5 DAYS — with the tally string running beneath it in mono at wide tracking, and the money on the third line. It is the only place on the page where a number is allowed to be that big, and it is deliberately the day count rather than the dollar figure: days are what a grower is actually booking.

04The signature — the Board

An SVG plan of a shearing shed drawn across the page. The catching pens run along the back wall, one behind every stand; the board is the jarrah strip across the middle with a shearer and a sheep at each stand and a chute down to the counting-out pens; the wool table, the press and the pressed bales sit at the wool-room end; and the empty race runs out at the far end, which is where the run docket hangs.

Beneath the shed a day strip counts the run out — one column per day, each filled in wool gold to that day's tally, with the last column part-filled to the honest remainder. Change the stands and the board redraws and the strip visibly shortens. Change the head count and the strip grows.

How it is built

The whole scene is one <svg> with seven groups — shed, pens, board, wool room, stands, day strip, labels — assembled synchronously in a single draw function. The entrance choreography is not a class toggle or a staggered DOM insertion; it is a progress value advanced inside the animation loop that owns the scene, because a group inserted after the loop starts can receive no paint invalidation in headless Chrome while every DOM assert stays green.

The geometry is solved, not guessed. The frame width is 2·pad + woolRoom + stands×standWidth + race, and the race is widened from the measured width of the docket so the docket always lands over empty floor rather than over a stand or the wool table. The binding contract is a rectangle-intersection assert — the docket's box never intersects the pens, the board, the wool room, the stands or the day strip — checked at 375, 1000 and 1200. Below 641px the docket drops out of the scene and docks directly beneath the artwork, and the race narrows to its minimum so the shed itself gets bigger on a phone.

Motion is deliberately small: the comb travels across each sheep on a staggered cycle, the fleece on the wool table breathes, and the final column of the strip pulses. Nothing ever drops below 0.55 opacity, so the signature is visibly alive at any capture instant rather than being phase-tuned to one. The frame delta is clamped at zero as well as capped, and the loop stops when the tab is hidden.

05The arithmetic

Rates are held as integer cents and divided by 100 exactly once, at display. This is not fastidiousness: 400 * 4.6 evaluates to 1839.9999999999998 in IEEE doubles, and a naive toFixed(0) hides that until a later comparison fails. The price function asserts Number.isInteger(cents) before it returns, and the verification harness re-checks it on every driven scenario.

QuantityRule
Rate460c / 140c / 515c a head (full shear / crutching / shear with classer)
Tally140 / 420 / 140 head a stand a day
Daysceil(head ÷ (stands × tally))
Last dayhead − (days − 1) × stands × tally
Keep$180 × days, in the 100–250 km zone only
Total(head × rateCents + keepCents) ÷ 100

Worked figures, measured from the running page

ScenarioDaysLast dayTotal
Rest — full shear, 2,000 head, 3 stands, within 100 km5320$9,200
The same job on 4 stands4320$9,200
The same job, 100–250 km, 3 stands5320$10,100
Crutching, 4,000 head, 4 stands, near3640$5,600
Shear with classer, 4,000 head, 4 stands, near880$20,600
400 head, full shear, 2 stands — the minimum engagement2120$1,840
Cheapest reachable output — 400 head crutching, near1400$560
Dearest reachable — 12,000 with a classer, 2 stands, 100–250 km43240$69,540

The estimator's cheapest output — $560 — is exactly the "from $560" floor printed in the services grid, so the page never argues with itself. Every figure above was re-derived by an oracle written separately from the page's own code: 1,156 checks over the full 3 × 30 × 4 × 3 grid, with zero non-integer cells and zero disagreements with the pinned spec.

Three designed behaviours worth naming

06Conversion decisions

07Local SEO we'd implement for the real business

This demonstration deliberately ships no LocalBusiness, Review or AggregateRating structured data. The business is fictional, and fictional structured data in a real search index is dishonest markup. The live page emits only WebPage, CreativeWork, WebSite, BreadcrumbList and ListItem, each naming the page as a demonstration.

What we would ship for a real shearing contractor

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "LocalBusiness",
  "@id": "https://wideboardshearing.com.au/#business",
  "name": "Wideboard Shearing Co.",
  "description": "Shearing, crutching and lamb marking contractor based at Northam, working the central and eastern wheatbelt of Western Australia.",
  "url": "https://wideboardshearing.com.au/",
  "telephone": "+61 8 9XXX XXXX",
  "email": "office@wideboardshearing.com.au",
  "image": "https://wideboardshearing.com.au/img/board-northam.jpg",
  "logo": "https://wideboardshearing.com.au/img/logo.png",
  "priceRange": "$$",
  "currenciesAccepted": "AUD",
  "paymentAccepted": "Bank transfer, EFT",
  "foundingDate": "2004",
  "address": {
    "@type": "PostalAddress",
    "streetAddress": "Lot 00 Example Road",
    "addressLocality": "Northam",
    "addressRegion": "WA",
    "postalCode": "6401",
    "addressCountry": "AU"
  },
  "geo": { "@type": "GeoCoordinates", "latitude": -31.653, "longitude": 116.667 },
  "areaServed": [
    { "@type": "City", "name": "Northam" },
    { "@type": "City", "name": "York" },
    { "@type": "City", "name": "Cunderdin" },
    { "@type": "City", "name": "Wongan Hills" },
    { "@type": "City", "name": "Corrigin" },
    { "@type": "City", "name": "Merredin" },
    { "@type": "City", "name": "Kojonup" }
  ],
  "openingHoursSpecification": [{
    "@type": "OpeningHoursSpecification",
    "dayOfWeek": ["Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],
    "opens": "06:00", "closes": "19:00"
  }],
  "hasOfferCatalog": {
    "@type": "OfferCatalog",
    "name": "Shearing services",
    "itemListElement": [
      { "@type": "Offer",
        "itemOffered": { "@type": "Service", "name": "Full shear" },
        "priceSpecification": {
          "@type": "UnitPriceSpecification",
          "price": "4.60", "priceCurrency": "AUD",
          "unitText": "per head", "valueAddedTaxIncluded": true } },
      { "@type": "Offer",
        "itemOffered": { "@type": "Service", "name": "Crutching" },
        "priceSpecification": {
          "@type": "UnitPriceSpecification",
          "price": "1.40", "priceCurrency": "AUD",
          "unitText": "per head", "valueAddedTaxIncluded": true } },
      { "@type": "Offer",
        "itemOffered": { "@type": "Service", "name": "Shear with an AWEX-registered classer" },
        "priceSpecification": {
          "@type": "UnitPriceSpecification",
          "price": "5.15", "priceCurrency": "AUD",
          "unitText": "per head", "valueAddedTaxIncluded": true } }
    ]
  },
  "aggregateRating": {
    "@type": "AggregateRating",
    "ratingValue": "4.9", "reviewCount": "38",
    "bestRating": "5", "worstRating": "1"
  },
  "review": [{
    "@type": "Review",
    "author": { "@type": "Person", "name": "R. Trethewey" },
    "datePublished": "2026-10-14",
    "reviewRating": { "@type": "Rating", "ratingValue": "5", "bestRating": "5" },
    "reviewBody": "Two thousand through a three-stand shed in five days, exactly as booked. Tally sheet in my inbox every evening."
  }]
}
</script>

Alongside it: a verified Google Business Profile with the Northam service area and the two travel rings, the six town names in real page copy rather than a footer keyword list, and a review feed the client actually owns. The ratings and the review above are illustrative — on a live build they would be generated from the client's real review data, never authored.

08What would change for a real client

09The three iteration passes

Each pass drove the interactive elements and asserted the output — not just loaded the page. Empty submit and filled submit, every chip and stepper, the signature driven to known values, a rapid-fire drive with no settle between clicks, both halves of the partial unwind, and native-resolution screenshots at 375, 1000 and 1200.

Pass 1 — Craft

Three collisions and a wrapping rule

  • The stand labels were struck through by the chutes. "STAND 1" sat at boardY + boardHeight + 20, which is exactly the band the chutes down to the counting-out pens occupy. Every DOM assert was green; only the screenshot showed it. The labels moved below the counting-out pens onto a shared baseline with "RACE OUT", the shed's bottom wall came up from 418 to 406 units, and the now-redundant "COUNTING-OUT PENS" caption was deleted rather than relocated.
  • The docket sat over the shed's back-wall band. Anchored at top: 14px it covered the top-right corner of the shadow band and read like a sticker rather than a docket hung on the race wall. Moved to top: 46px, and the layout's badge-clearance arithmetic updated to match — the offset is a variable in the same expression, not a duplicated constant.
  • A wrapping eyebrow centred its rule against two lines. align-items: center put the gold dash halfway down a two-line eyebrow. Changed to flex-start with a margin-top: .62em on the rule so it sits on the first line's baseline whatever the wrap.
  • Contrast measured from the shipped tokens. All 26 pinned ratios re-computed from the hexes actually in the stylesheet and matched to the spec within 0.02. The one token the spec left to the builder — the secondary ink — was derived and measured before use: #57503F at 6.19:1 on the ground, 8.00:1 on cards, 6.90:1 on the ledger tint.
  • Trust strip built as normal inline flow. A marker-plus-prose strip is never a flex container: the dot is an inline-block ::before with a right margin, because display:inline-flex with a gap renders "AWEX , registered" with a space before the comma while the source markup and every text assert stay perfectly correct.

Pass 2 — Depth

Giving the empty end of the shed a job, and making the short day legible

  • The race became a race. The right-hand third of the plan existed only so the docket had somewhere to hang, and it read as dead space. It is now a drawn counting-out race — two rails, posts, a doorway at the far end — with shorn sheep walking out along it on a slow loop. It answers a real question a plan should answer (where do they go after the board), it gives the region a reason to be that wide, and it is now part of the rectangle-intersection assert, so the docket is tested against it too.
  • A full-day rule across the day strip. The page's central insight is that the last day is nearly always a short one, but until this pass you had to compare column heights to see it. A dashed line now runs across the top of the strip labelled "A full day — 420 head", drawn last so the gold columns cannot paint over it. The shortfall on the final column is now a distance you can see rather than a number you have to read.
  • A "SHORT DAY" tag on the final column, drawn only when the run is longer than a day and the last day genuinely falls short. It sits in the white above the gold when there is room and inside the gold when there is not — the body ink measures 5.31:1 on the wool gold, so it stays readable either way.
  • Second-read details. The AWEX classer chip puts a classer at the wool table and brands the bales on the press; the comb strokes are staggered by stand so the board never pulses in unison; the docket pegs itself with a short stamp animation on every state change, which is the state-change feedback that lets the scene itself stay still.
  • A never-invisible motion floor. Nothing in the scene animates below 0.55 opacity, so the signature is alive at any capture instant rather than being phase-tuned to the 7-second thumbnail settle.

Pass 3 — Hardening

One defect that would have shipped a blank thumbnail, and type that follows the frame

  • The entrance choreography replayed on every redraw. This is the one that mattered. The scene faded up from opacity 0 on first draw — correct — but every subsequent draw restarted it, so a chip click, a stepper tap, or a window resize blanked the shed and faded it back. Worse: a screenshot with a clip changes the device metrics, which fires the resize handler, which restarted the entrance — so the capture photographed a nearly empty shed. The state asserts were all green throughout; only the pixels showed it. The entrance is now scoped to the cold load, every later draw lands opaque, and the settle timer force-completes the entrance as a backstop if no further frame ever arrives. There is now a harness assert that drives the controls, waits with nothing poking the page, and requires every group to be fully painted.
  • Scene type was sized in scene units, so it shrank with the frame. A 13-unit label is 9px at 1200 on three stands and 3.7px at 375 on six — illegible, and no assert can see it. Every string in the drawing is now specified in CSS pixels and converted into scene units at draw time, and so is the day strip's whole vertical rhythm, so a six-stand frame on a phone no longer squeezes 12px of type into an 8px band. The harness now measures every scene label's rendered height at 375, 1000 and 1200 and fails anything under 8px.
  • Labels that cannot fit their compartment stand down rather than overprint. "Race out — counted" shortens to "Race out" and then disappears; "Stand 1" becomes "1"; the wool-room sub-labels drop out below 118px of room; the whole set of fine plan labels stands down when the back wall band is too shallow in real pixels to hold them. The drawing stays a drawing; the words live in the SVG description and the plain-text mirror.
  • Tally legibility was gated in the wrong unit. The per-column head counts were suppressed by a scene-unit threshold that hid them at the 14-column cap on a 1200px desktop, where a 40px column carries "280" comfortably. Both that threshold and the short-day tag's are now measured in pixels.
  • 375px. The trust signals sat under the sticky call bar. The hero's type scale, stamp and spacing were tightened below 430px until all three clear it, and the eyebrow — which wrapped to two lines at every width — moved its region detail into the lede. The masthead was checked first, wordmark right edge against call-button left edge, as it is the collision that keeps shipping.
  • One ornament removed. The chute arrows on the board read as stray glyphs at every width and said nothing the chute rectangle did not already say.
  • The rest. Reduced motion renders a settled frame at full opacity with no loop; the frame delta is clamped at zero as well as capped; the loop stops on visibilitychange; focus states are visible on every control and every field; the form's patterns were proven by driving checkValidity on deliberately invalid values rather than by reading the attributes; and a rapid-fire drive fires ten control clicks in one evaluate with no settle between them.

Final harness: 387 assertions green against an independently reimplemented oracle, plus 1,156 spec-level checks over the full 3 × 30 × 4 × 3 price grid.