Build guide · Generative Assets №238

How Southerly Marine was made

Southerly Marine Services is a fictional boat-servicing and antifouling yard in O'Connor, five minutes from Fremantle Fishing Boat Harbour — a marine services industry demonstration designed & built by Sapience Analytics. The page has one job: turn a boat owner who is due for antifoul into a quote request, with the Slipway Estimator doing the persuading.

Concept

The audience is Swan River and Rockingham boat owners: due for antifoul, needing an outboard service before the season, or buying a boat and wanting the truth about it. The direction is the slipway at 7am — salt white, hull shadow, honest yard work — premium shipwright pride rather than a chandlery catalogue. Every visual is procedural: the hardstand scene, the service-area map and all ornament are inline SVG drawn in the site's palette; there is not a single raster image on the page.

Conversion decisions

Palette — the hardstand at 7am

#F4F6F4 · salt whiteGround — gelcoat in morning light.
#16323C · deep-seaStructure and primary ink — the water under the jetty.
#B0413E · antifoul redLine/mark accent — the colour every hull wears below the waterline. CTAs, waterline rules, markers. Never body text.
#3E7D5C · channel greenSecondary — the starboard channel marker. Ticks and marks; text uses the darker #2C5C43 ink.
#4A5D64 · derived body-inkSmall text on salt white (6.3:1). The line/mark accents were never asked to carry copy.

Ink/line split (LEARNINGS W2/W5): antifoul red measures ~5.2:1 on salt white — fine for 40px display and thick rules, marginal for small text — so captions use #933431 (5.7:1+) or the derived inks. Dark panels carry their own light body-ink #C9D6DA (9.0:1).

Type

The Slipway Estimator — technique

The hardstand scene is a single inline SVG rebuilt from parameters on every interaction. A hull-path generator takes the slider length (16–45 ft mapped at 15px/ft) and the hull type and produces the sheer, stem and run as cubic Béziers; monos get a keel subpath and poppet stands with keel blocks, catamarans get a second hull drawn offset (+16px x, −7px y) behind the first so a twin bow reads in side view, and trailer boats sit on a procedural trailer — frame, guards, two wheels, drawbar and jockey wheel — with an outboard on the transom.

The antifoul band is the same hull path duplicated, filled antifoul red and clipped by a rect starting at the hull's waterline height, so the "paint" always follows the hull exactly (keel and second hull included). The waterline itself is a stroke-dash draw-in with butt caps, kept visibility:hidden until its dash length is set — the LEARNINGS W15 round-cap dot never gets a frame to render. A dimension line above the boat mirrors the slider ("26 ft"), the estimate figure counts up over 320ms with a cubic ease-out, and everything settles instantly under prefers-reduced-motion. State probe: window.__marine, updated on every interaction.

Pricing model — source of truth

The spec pins these anchors; the harness's independent oracle re-implements exactly this table and asserts the page's displayed figures against it.

ServiceRateModel shape
Haul-out & antifoul — mono$95/ft Linear in length. 26 ft rest state = 26 × 95 = $2,470.
Antifoul — catamaran$152/ft Mono rate + 60% (95 × 1.6). 32 ft = 32 × 152 = $4,864.
Antifoul — trailer boat$85/ft On the owner's trailer, no haul-out — this is the services grid's "from $85/ft" floor. 20 ft = $1,700.
Outboard 100-hr servicefrom $440 Deliberately flat in hull length — service cost scales with the engine, not the boat, so the line is shown as "from" and never multiplied by feet.
Shaft-drive diesel servicefrom $590 Flat, as above; twins and larger engines are quoted per engine.
Pre-purchase inspection$30/ft Linear in length. 26 ft = $780; the review's "best $900" buyer is a 30-footer — 30 × 30, cross-surface consistent.

Services are additive: multiple chips sum their lines on the job card (26 ft mono, antifoul + outboard + inspection = 2,470 + 440 + 780 = $3,690), and the total is labelled "from" whenever any flat-rate line is included. The card, the services grid, the hero lede and the reviews all quote from this one table.

Local SEO we'd implement for the real business

This demo page ships only WebPage schema naming it a demonstration — fictional structured data in a real index would be dishonest markup. For a real yard we would ship:

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "LocalBusiness",
  "name": "Southerly Marine Services",
  "description": "Boat servicing, antifouling and pre-purchase
    inspections on the O'Connor hardstand, Fremantle.",
  "telephone": "+61-8-XXXX-XXXX",
  "address": {
    "@type": "PostalAddress",
    "streetAddress": "[real street address]",
    "addressLocality": "O'Connor",
    "addressRegion": "WA", "postalCode": "6163",
    "addressCountry": "AU"
  },
  "geo": { "@type": "GeoCoordinates",
    "latitude": -32.06, "longitude": 115.79 },
  "openingHoursSpecification": [
    { "@type": "OpeningHoursSpecification",
      "dayOfWeek": ["Monday","Tuesday","Wednesday","Thursday","Friday"],
      "opens": "07:00", "closes": "16:00" },
    { "@type": "OpeningHoursSpecification",
      "dayOfWeek": "Saturday", "opens": "07:00", "closes": "12:00" }
  ],
  "priceRange": "$$",
  "areaServed": ["Fremantle","East Fremantle","Bicton","Applecross",
    "Mosman Park","Coogee","Henderson","Rockingham"],
  "aggregateRating": { "@type": "AggregateRating",
    "ratingValue": "[from live review feed]",
    "reviewCount": "[from live review feed]" },
  "review": [ /* synced from Google Business Profile —
    never hand-written */ ]
}
</script>

What would change for the real client

Iteration log

Pass 1 — Craft

Built a 43-assert puppeteer harness (headless Chrome, port 6203) with an independently re-implemented pricing oracle, then read the real screenshots. Found and fixed:

Pass 2 — Depth

Pass 3 — Hardening

Techniques: inline SVG (parametric hull generator, clip-path paint band, dash draw-in, procedural map), CSS grid/flex layout, vanilla JS. No libraries, no build step, no raster images — Google Fonts is the only external resource.