← Back to Beaufort

[ Parable build guide ]

How Beaufort was built

A charter house, drawn as a chart. The signature is an inline-SVG sea chart — isobaths, soundings, a rhumb-line network and a real compass rose — whose needle rotates to track scroll progress, so your heading changes as you sail down the page. No canvas, no libraries, no image files.

static · no build stepinline SVG · zero depsSpectral / Karla / IBM Plex Monolight + darkreduced-motion aware

The idea

A boutique yacht charter sells one thing above the boats: trust in the people who navigate them. So the hero isn't a drone shot of a yacht — it's the thing the crew actually reads. A cartographic chart, rendered in vector so its lines stay hair-thin at any size, with the one flourish a photo can never give you: a compass that responds. Scroll down and the needle swings, as if the boat were slowly changing course. The romance of the brand is the navigation, so the navigation is the interface.

The stack

Deliberately plain. One index.html, one styles.css, one main.js. No framework, no bundler, no CDN — the chart is hand-authored SVG right in the markup, so there are zero runtime dependencies and nothing to build. Type is Spectral (a lyrical text serif for the display voice), Karla (a warm grotesque for body), and IBM Plex Mono for everything a navigator would set in a fixed pitch: soundings, bearings, distances, coordinates.

Signature technique — the scroll-driven compass

The compass rose is authored once in SVG — outer ring, an eight-point star, two-tone cardinal points, and a needle isolated in its own <g id="roseNeedle">. On scroll we map page progress to a bearing and rotate the needle group about the rose's centre. One fixed tell-tale badge, bottom-left, mirrors the same bearing in degrees so the heading is legible even after the chart scrolls away.

const START = 20, SWEEP = 300;          // sweep 20° → 320° over the page
const update = () => {
  const max = document.documentElement.scrollHeight - innerHeight;
  const p   = clamp(scrollY / max, 0, 1);
  const deg = START + p * SWEEP;
  needle.setAttribute('transform', `rotate(${deg} 468 158)`);   // rose centre
  ttDeg.textContent = String(Math.round(deg % 360)).padStart(3,'0') + '°';
};
addEventListener('scroll', () => requestAnimationFrame(update), { passive: true });

The charter route is a dashed <path> revealed on load by animating a clipPath rectangle from scaleX(0) to scaleX(1) — so the course appears to be laid down across the water — while a faint gradient band sweeps the sea as a slow shimmer. Both are pure CSS; only the needle needs JavaScript.

Details that matter

The enquiry form is a demo — it validates and confirms in-place but sends nothing. Wire it to your own endpoint (Formspree, a serverless function, an email service) before taking real bookings.

Ship it on GitHub Pages

Nothing to build. Push the folder and point Pages at the root.

gh repo create bswxyz/beaufort --public --source . --push
gh api --method POST /repos/bswxyz/beaufort/pages -f 'source[branch]=main' -f 'source[path]=/'

Relative paths and a .nojekyll file mean it serves from the project subpath without a single config change — the whole point of a static build.

← Back to Beaufort