MARLOCKHYDRAULICS

Generative Assets · Industry demo 376

How the Hose Run was built

Marlock Hydraulics is a fictional Naval Base hydraulic hose service. The page has one job: get the phone ringing with the hose spec already priced — hose, both ends and the callout named before the customer rings. Everything on it is drawn in the browser; there is not a single raster image on either page.

The concept

A hydraulic hose is bought in the worst ten minutes of somebody’s day: a forklift dead in a doorway, an excavator boom hose let go at half three on a Friday. The prospect isn’t browsing — they want to know it can be matched, what it costs, and how fast someone can get there. So the page opens on a working drawing of the exact assembly they need, priced, with the phone number one thumb away.

The art direction is a spec sheet on the swage bench: a cool zinc drafting ground, graphite ink, and the two colours a hydraulic circuit diagram actually uses — red for the pressure line, blue for the return. Technical, dry, precise: the aesthetic of a workshop that measures things. It is held off the three AI-default palettes deliberately — a cool zinc grey rather than cream-and-terracotta, a light page rather than near-black-plus-an-acid-accent, and no column rules anywhere, because the structure here is the circuit, not a broadsheet grid.

Palette

Argued from a zinc bench top, graphite pencil and hydraulic-circuit colour convention. Every ratio below was measured with WCAG arithmetic from the shipped hex values against the ground it actually sits on.

Zinc drafting ground#EBEDEA

The page ground. Cards go pure white #FFFFFF; hairlines #D6D9D4. The drawing sheet itself is a half-step darker at #E3E6E2 so the instrument reads as a physical sheet laid on the page.

Graphite#1B2124

Body ink and the primary CTA fill. 13.83:1 on the ground, 16.28:1 on white cards, 12.94:1 on the drawing sheet. White labels on the graphite button measure 16.28:1; the hover #141A1C measures 17.58:1.

Return blue#2F6E8F

Circuit return lines, rule ticks, chip outlines and the secondary CTA fill (white labels, 5.60:1; hover #255A76, 7.49:1). As text on the ground it measures only 4.76:1, so it is a line-and-fill token, never small copy.

Blue ink#1F5573

The pre-minted text twin for the return blue: 6.85:1 on the ground, 8.06:1 on white, 6.40:1 on the drawing sheet. Every small blue word on both pages — eyebrows, the 300 mm rule label, the DETAIL A caption — uses this and not the line colour.

Pressure red#B4342B

The pressure line, the travelling pulse, the crimp bands on each ferrule and the map’s Naval Base star. Scene and marks only (5.14:1 on the ground) — it is the colour of the fluid under load, so it never labels anything.

Red ink#96271F

The text twin for pressure red: 6.84:1 on the ground, 8.06:1 on white, 6.40:1 on the drawing sheet, 7.09:1 on the map ground. Carries the brand eyebrow, the lock reasons and the quoted-travel line.

Graphite muted#4C5458

Secondary copy: 6.57:1 on the ground, 7.73:1 on white, 5.81:1 on the hose tag’s zinc plate, 6.45:1 in the drawing’s title block. Disabled chip labels use #5A6367 (5.22:1) plus a dashed border, so a locked control is still legible and still explains itself.

Bench shadow#232A2E

The single dark band on the page, under the trust strip. White on it measures 14.56:1, the zinc body copy #C9CFCB 9.20:1, the pale blue fine print #A8C6D6 8.12:1.

Type

Archivo 700/800 is the display face — an industrial grotesque with square counters, argued from stencilled plant labelling and machine data plates. It sets the h1, the section heads and the price on the hose tag, where its tight negative tracking makes $410 land like a stamped number rather than a marketing figure.

IBM Plex Sans is the workhorse: 16.5px body, 15px in cards, never below 13px anywhere a customer has to read. IBM Plex Mono 500 appears in exactly one role — spec strings. The hose tag’s 3/4" R13 · 3.0 m · JIC×JIC, every label inside the drawing, the price columns in the ledger and the pre-filled hose spec in the enquiry form. Restricting the mono to real specification data is what makes the page read like a workshop document instead of a website wearing a costume.

The typographic moment is the hose tag: the rest-state total set huge in Archivo 800 with the spec string running beneath it in tracked mono, hung on a wire loop over the drawing. That pairing — a big soft-edged number over a hard technical string — is the whole proposition in one object.

Techniques

No libraries, no build step, no images. Both pages are single self-contained HTML files. The drawing is SVG generated as a string on every state change; the motion is one requestAnimationFrame loop updating two attributes, plus one CSS keyframe for the oil sheen. That is the entire runtime.

The signature: the Hose Run

An SVG swage bench in elevation with the selected assembly drawn along it. The hose body carries its real braid construction — two-wire hose draws a crosshatch weave, four-spiral draws four straight-wound bands — and a crimped ferrule with three red crimp bands sits at each end, with the fitting drawn to type outboard of it: a hex nut and 37° seat cone for JIC, a longer nut with a threaded male end for BSP, a four-bolt plate for the SAE Code 62 flange.

The frame is zoom-to-fit: its width in scene units is always length + 0.6 m, so a 1 m assembly draws in a 1,600 mm frame and a 6 m assembly in a 6,600 mm frame. Because the frame grows with the hose, the honest constant reference is drawn beneath the assembly: a 300 mm steel rule, always exactly 300 mm in scene units, which visibly shrinks as the run gets longer. Everything in the drawing is at that one frame scale, including the outside diameters — 13, 18, 22, 34 and 42 mm for the five bores. At true frame scale a 34 mm hose in a 3,600 mm frame is a hairline, which is correct and also useless, so the sheet carries a drafting convention instead of a cheat: DETAIL A, a clipped circle showing a 220 mm window on the crimped end at whatever magnification the frame implies, with the drawn OD called out beneath it. The main assembly stays honest; the detail is where you can see the weave.

A slow pressure pulse travels the red line end to end on a 3.4-second cycle. Its delta is clamped at both ends (dt = min(max(now − last, 0)/1000, 0.05)) so a vsync timestamp that precedes the scheduling clock can never drive a negative length; the loop idles while the tab is hidden. The pulse is never invisible — it is always somewhere on the line and the base pressure line never drops below 55% alpha — so the drawing is visibly alive at any capture instant without any phase arithmetic against a screenshot schedule.

Redraws run at two speeds. The first draw earns the full entrance stagger (26 ms per element); every subsequent state change redraws snappy at 11 ms per element, so tapping through the hose chips reads as an instrument responding rather than a page reloading. Each redraw bumps a token in the event handler, before the state swap, so a control clicked mid-transition can never leave an animation closed over the previous scene’s geometry.

The scene’s height is computed, not fixed: the tag’s measured pixel height sets a minimum so the assembly, its labels and the steel rule can never end up underneath the badge at any viewport width. Below 641 px the tag docks directly beneath the drawing and switches to the short forms of its service line and both declarations; the ledger and the screen-reader mirror keep the full strings at every width.

Everything else that’s drawn

The pricing model

GST-inclusive, whole dollars, and internally consistent by construction — every rate is a whole dollar and every stepper grid is whole units, so no total can ever land on a fraction. Hose is priced per whole metre and multiplies only the hose line; fittings are a flat pair price and never multiply by length; the callout is flat; travel is added once, not per hour.

Pinned rates for hose, fittings, service and travel
ControlOptionPriceDrawn
Hose (per metre)1/4" 2-wire (SAE 100R2AT)$18/m13 mm OD
3/8" 2-wire (R2AT)$22/m18 mm OD
1/2" 2-wire (R2AT)$28/m22 mm OD
3/4" 4-spiral (R13)$62/m34 mm OD
1" 4-spiral (R13)$84/m42 mm OD
Fittings (both ends)JIC 37° both ends$44 (2 × $22)hex nut + 37° cone
BSP both ends$52 (2 × $26)hex nut + male thread
JIC one end, BSP the other$48 ($22 + $26)one of each
SAE Code 62 flange + JIC$118 ($96 + $22)four-bolt plate + cone
Service (callout)Bench, Naval Base$0vice + swage press
Mobile callout — first 30 min on site in$180van door + hose reel
After-hours breakdown — first hour in$340van door + work lamp
Travel zoneKwinana · Henderson · Rockingham+$0
Perth metro+$60
Beyond metroquoted

Length steps in whole metres from 1 to 6. There is no empty state: one chip in every set is always selected and the length floor is 1 m, so the estimator always shows a real number.

Measured outputs

Every figure below was read off the running page and cross-checked against a pricing model reimplemented independently in the verification harness.

Worked examples measured from the running page
ScenarioArithmeticMeasured
Rest state — 3/4" R13, 3 m, JIC both ends, mobile, Kwinana62×3 + 44 + 180 + 0$410
Cheapest output — bench, 1/4" 2-wire, 1 m, JIC both18 + 44 + 0$62
After-hours, 1" 4-spiral, 6 m, SAE flange + JIC, Perth metro84×6 + 118 + 340 + 60$1,022
Bench, 3/8" 2-wire, 4 m, JIC/BSP mixed22×4 + 48 + 0$136
Mobile, 3/4" 4-spiral, 6 m, SAE flange + JIC, Perth metro62×6 + 118 + 180 + 60$730
After-hours, 1/4" 2-wire, 1 m, BSP both, Kwinana18 + 52 + 340$410
Mobile, 1/2" 2-wire, 2 m, BSP both, beyond metro28×2 + 52 + 180, travel quoted$288 + travel quoted

The sixth and first rows land on the same number by coincidence. The harness asserts that the badge’s second line differs — “after-hours breakdown — first hour on site included” against “mobile callout — first thirty minutes on site included” — rather than only checking the total, because a price that matches by accident is exactly where a state bug hides.

The cheapest output the estimator can produce is $62, and that is precisely the “from $62” floor printed on the services grid’s bench-built assembly card. The grid’s other floors — $18/m, $62/m, $22 an end, $96, $180, $340, $60 — are the same pinned anchors the estimator uses, so the page cannot argue with itself.

Locks, forces and memory

Two controls constrain each other, and both are declared on the page rather than silently computed.

What the page refuses to put a number on

Beyond the metro, travel is genuinely unknowable until we know the gate and the induction, so the badge prints the part it can compute plus the declaration — $288 + travel quoted — wherever the total would normally print, on the tag, in the ledger total, in the screen-reader mirror and in the pre-filled form. A bare “quoted” would throw away information the customer already has. Two more declarations ride along with every scenario on all three surfaces: crimping, the pressure test and the tag are in the price and never charged per end; and re-usable fittings salvaged off the old assembly are credited on the invoice, not in this estimate. The hose register is priced “per fleet, after we walk the yard” and carries no figure at all, because the size of the yard decides it and a rate card would be a guess.

Conversion decisions

Local SEO we’d implement for the real business

The live page emits only WebPage, CreativeWork, WebSite, BreadcrumbList and ListItem schema, naming itself a demonstration. Putting a LocalBusiness block with fictional reviews and a fictional rating into a real search index would be dishonest markup, so it lives here as a code sample instead. This is what would ship on the real operator’s site, with their real address, real hours and a review feed wired to their Google Business Profile:

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "LocalBusiness",
  "@id": "https://marlockhydraulics.com.au/#business",
  "name": "Marlock Hydraulics",
  "additionalType": "https://www.wikidata.org/wiki/Q1128564",
  "description": "Mobile hydraulic hose service and on-site assembly across Kwinana, Henderson, Rockingham and the Perth metropolitan industrial belt.",
  "url": "https://marlockhydraulics.com.au/",
  "telephone": "+61-8-XXXX-XXXX",
  "email": "bench@marlockhydraulics.com.au",
  "image": "https://marlockhydraulics.com.au/img/swage-bench.jpg",
  "logo": "https://marlockhydraulics.com.au/img/logo.png",
  "priceRange": "$$",
  "currenciesAccepted": "AUD",
  "address": {
    "@type": "PostalAddress",
    "streetAddress": "Unit N, Example Road",
    "addressLocality": "Naval Base",
    "addressRegion": "WA",
    "postalCode": "6165",
    "addressCountry": "AU"
  },
  "geo": { "@type": "GeoCoordinates", "latitude": -32.19, "longitude": 115.78 },
  "openingHoursSpecification": [
    { "@type": "OpeningHoursSpecification",
      "dayOfWeek": ["Monday","Tuesday","Wednesday","Thursday","Friday"],
      "opens": "06:30", "closes": "16:30" },
    { "@type": "OpeningHoursSpecification",
      "dayOfWeek": "Saturday", "opens": "07:00", "closes": "12:00" }
  ],
  "areaServed": [
    { "@type": "City", "name": "Kwinana" },
    { "@type": "City", "name": "Rockingham" },
    { "@type": "Place", "name": "Henderson" },
    { "@type": "Place", "name": "Bibra Lake" },
    { "@type": "Place", "name": "Welshpool" },
    { "@type": "Place", "name": "Canning Vale" },
    { "@type": "Place", "name": "Malaga" }
  ],
  "knowsAbout": [
    "SAE 100R2AT two-wire hose assemblies",
    "SAE 100R13 four-spiral hose assemblies",
    "JIC 37 degree flare fittings",
    "BSP fittings",
    "SAE Code 62 flange fittings",
    "hydraulic hose registers and scheduled changeout"
  ],
  "hasOfferCatalog": {
    "@type": "OfferCatalog",
    "name": "Hydraulic hose services",
    "itemListElement": [
      { "@type": "Offer",
        "itemOffered": { "@type": "Service", "name": "Bench-built hose assembly" },
        "priceSpecification": { "@type": "PriceSpecification",
          "minPrice": 62, "priceCurrency": "AUD", "valueAddedTaxIncluded": true } },
      { "@type": "Offer",
        "itemOffered": { "@type": "Service", "name": "Mobile hose replacement" },
        "priceSpecification": { "@type": "PriceSpecification",
          "minPrice": 180, "priceCurrency": "AUD", "valueAddedTaxIncluded": true } },
      { "@type": "Offer",
        "itemOffered": { "@type": "Service", "name": "After-hours breakdown callout" },
        "priceSpecification": { "@type": "PriceSpecification",
          "minPrice": 340, "priceCurrency": "AUD", "valueAddedTaxIncluded": true } }
    ]
  },
  "aggregateRating": {
    "@type": "AggregateRating",
    "ratingValue": "4.9", "reviewCount": "87",
    "bestRating": "5", "worstRating": "1"
  },
  "review": [
    { "@type": "Review",
      "author": { "@type": "Person", "name": "REAL CUSTOMER NAME" },
      "datePublished": "2026-07-18",
      "reviewRating": { "@type": "Rating", "ratingValue": "5", "bestRating": "5" },
      "reviewBody": "Forklift died in the roller door at 10:20. Van was in the yard by 11:05
                     and the mast hose was swaged on the tailgate." }
  ]
}
</script>

Note the @type: schema.org has no hydraulic-service subtype and the trade sits outside AutoRepair, so the honest choice is the LocalBusiness parent with the specialty carried by additionalType, knowsAbout and hasOfferCatalog. Reaching for a more specific-sounding token that isn’t actually an organization subtype would be worse markup, not better.

Alongside the schema we would ship: a Google Business Profile with the service area drawn as the real van radius rather than a postcode list, service-page URLs for the three callout types and the two hose constructions, an emergency hydraulic hose Kwinana-shaped page targeting the breakdown query, and review requests fired by SMS the afternoon a job closes — the only reliable way a hose business gets reviews from people who were, by definition, having a bad day.

What would change for the real client

Iteration log

Pass 1 — Craft

The first render passed 213 of 218 assertions, and every one of the five failures was a composition defect that no state assertion could have seen.

  • At 1000 px the hose tag was covering the right-hand fitting label and the 3.0 m dimension label. The root cause was that the scene’s height was a fixed fraction of its width while the tag’s height was fixed in pixels, so at mid widths the badge occupied 63% of the drawing. Fixed properly rather than cosmetically: the whole vertical layout was rebuilt with the assembly at 57.5% of the sheet height, its labels and dimension line moved below it, and the sheet’s height now computed as max(base aspect, (tag height + margins) ÷ 0.575) so the badge can never reach the drawn subject at any width.
  • The title block’s three text lines were overlapping each other at 375 and 1000 px, because line spacing was a fraction of the sheet height while the type was sized in pixels. It became a two-line block laid out from its own font metrics, with a short form at phone widths and the pressure/return legend moved out beside it.
  • The 300 mm rule label was colliding with the title block; the rule now sits on the bench surface with its label to the right of it, which is also how a rule actually lies on a bench.
  • Two labels were overflowing the drawing frame at 375 px. All centred scene labels now clamp their own half-width inside the sheet margins, and the DETAIL A caption carries a short form at phone widths.
  • The hero trust line was breaking mid-sentence: its list items were flex containers, so the bold clause and the text after it became separate flex items and wrapped into two columns. Rebuilt as a grid of block items with the marker absolutely positioned.
  • Contrast was measured from the shipped tokens rather than trusted: everything cleared 4.5:1 except the disabled chip label at 3.32:1, which was re-inked to #5A6367 (5.22:1) and given a dashed border so “locked” is signalled by shape as well as tone.
  • Copy read: the lede lost a clause, and the h1 dropped to 39px at desktop and 29px at phone widths so the value proposition, both CTAs and a trust signal clear the fold at 375×667 with room rather than by a pixel.

Pass 2 — Depth

  • DETAIL A earned a dimension. The magnified crimp detail now carries an OD 13 mmOD 42 mm callout that tracks the hose chip — the one number a fitter would actually write on a drawing, and the number that explains why the main assembly is drawn as thin as it is.
  • The steel rule grew minor graduations. Ten-millimetre ticks across its first 100 mm, alongside the 50 mm marks. At a 1 m frame they are crisp; at a 6 m frame they collapse into a grey smear — which is exactly what happens to a real rule as you back away from it, and makes the zoom-to-fit argument visible instead of merely stated. This is the second-read detail.
  • Every scene label got a halo. Ground-coloured paint-order: stroke on every piece of type in the drawing, so a roller-door slat or a grid line can never strike through a label.
  • Micro-interaction: the tag’s total lifts and fades in over 400 ms whenever the price actually changes — not on every redraw, only on a genuine change — so the badge acknowledges the tap. Suppressed entirely under reduced motion.
  • Keyboard control of every radio group with arrow keys, Home and End, skipping disabled chips, focus following selection. Driven and asserted in the harness rather than assumed.
  • The pressure pulse’s glow was rebuilt to hug the hose — its vertical radius is now derived from the drawn OD instead of the sheet height, so it reads as fluid in the bore rather than a smudge on the sheet.

Pass 3 — Hardening

  • The desktop layout had a void. With the whole instrument in the hero’s right column, the control deck and ledger ran 600 px down the page beside an empty left column. The hero grid was re-cut: copy and drawing share row one, and the control deck spans both columns on row two, with chips and ledger side by side. The drawing keeps its exact width, so the thumbnail composition is untouched.
  • The FAQ ran 1,180 px wide — unreadable measure. It became a two-column section with the heading and an invitation to ring on the left and the accordion on the right.
  • The map’s zone circles were floating into the Indian Ocean. Both are now clipped to a land path, so a service boundary stops at the coast.
  • Chanel rule. Two ornaments removed: the 01–08 numbering on the services grid, since a service catalogue is not a sequence and the numbers were structure pretending to be meaning; and an unlabelled red dashed route line across the top of the map that carried no information at all.
  • 375 px re-checked at native resolution end to end: no horizontal overflow, no element escaping the viewport box, the masthead wordmark clearing the call button, every tap target at or above 44 px, the sticky bar inside the bottom 140 px, the tag docked beneath the drawing with the short forms while the ledger and screen-reader mirror keep the full ones.
  • Reduced motion asserted, not assumed: the pulse parks mid-run, the sheen stops, the badge stops flashing, and every element of the scene renders at full opacity — a settled frame, never a blank one.
  • An explicit label-collision sweep at 375, 1000 and 1200 px compares every pair of scene label bounding boxes and every label against the tag. It is part of the harness now, because assertions prove state and only pixels prove composition.

Verification

The final harness drives the real page in headless Chrome and asserts 228 times: the pinned rest state and every worked example against an independently reimplemented pricing oracle; all four lock, force, partial-unwind and memory-invalidation sequences; every hose, fittings, service and travel chip; both stepper bounds; two rapid-fire drives that fire several controls in a single evaluation with no settle between, to catch an animation closed over stale scene data; a fresh-navigation empty submit and a filled submit; the estimator-to-form handoff; the live JSON-LD type allowlist; the reserved phone pattern; the colophon on both pages; the reduced-motion settled frame; the 375 px layout; and screenshots at 375, 1000 and 1200 px at native resolution with the label-collision sweep. Zero console errors, zero page errors, zero failed requests.