The maker's guide

How the water got into the website.

Everything on this site — the transparent turquoise sea, the glass calendar, the type, the textures — was designed and built by Claude (Fable 5). Here is exactly how, so you can do it too.

1 · The idea: the water is the interface

The brief was a booking site where a turquoise, see-through Caribbean sea sits behind everything — including the live Guesty calendar. So the home page is built as a water column: a sunlit sand seafloor at the very back, a real-time WebGL water surface in front of it, and the content floating between them in panels of glass. Scrolling doesn’t move past the ocean; it descends through it, until the page finally washes ashore onto sand.

2 · A transparent Gerstner ocean

The sea is a Three.js ShaderMaterial on a 340×340 plane. Five Gerstner waves are composited in the vertex shader — the classic trochoidal wave model, where each point moves in a circle, so crests sharpen the way real water does:

void gerstner(vec2 dir, float steep, float len, vec3 p0, …){
  float k = 6.28318 / len;
  float c = sqrt(9.8 / k);          // deep-water wave speed
  float f = k * (dot(d, p0.xz) - c * uTime);
  float a = steep / k;
  disp += vec3(d.x * a * cos(f), a * sin(f), d.y * a * cos(f));
  …
}

The trick that makes it Mexican-Caribbean and transparent is all in the fragment shader. Color mixes from a deep petrol teal into bright turquoise by crest height, then toward a pale-aqua sky by fresnel. Alpha is lowest looking straight down into troughs — so the seafloor glows through the clear water — and rises at grazing angles, on crests, and with foam:

vec3 col = mix(uDeep, uShal, crest);       // #0b7c96 → #3fd6d9
col = mix(col, uSky, fresnel * 0.6);       // horizon goes pale
float alpha = 0.34 + fresnel * 0.5
            + crest * 0.18 + foam * 0.5;   // clear in the troughs
gl_FragColor = vec4(col, alpha);

The renderer is created with alpha: true and clears to nothing, so whatever the DOM puts behind the canvas — here, an AI-generated sunlit seafloor with caustic light webs — reads through the surface. Scroll position feeds a uDepth uniform that darkens the water and lowers the camera: the descent.

3 · The calendar beneath the surface

The Guesty search widget and full booking calendar sit in a glass panel (backdrop-filter: blur(20px) saturate(1.5)) over the living water. Both are lazy: an IntersectionObserver injects Guesty’s script only when the panel approaches the viewport, and the calendar iframe gets its src the same way. If either fails, a plain link to the booking page remains — availability and pricing always belong to Guesty, never to this site.

new IntersectionObserver((entries) => {
  if (entries.some((e) => e.isIntersecting)) loadGuesty();
}, { rootMargin: "600px 0px" }).observe(panel);

4 · Palette & type

Eight tokens run the whole site — a water column from abyss to foam, warm sand for the shore, and one coral accent used sparingly:

  • Abyss
    #032f3d
  • Deep
    #0b7c96
  • Turquoise
    #1fc4cc
  • Aqua
    #a9f0e9
  • Foam
    #f2fffb
  • Sand
    #f6eedd
  • Ink
    #06323c
  • Coral
    #ff6a52

Display type is Fraunces, self-hosted as a variable font with its WONK axis switched on — the slightly drunken letterforms give the serifs a hand-set, salt-warped character. UI text is Manrope. Both load as single variable woff2 files.

h1 { font-family: "Fraunces";
     font-variation-settings: "SOFT" 0, "WONK" 1; }

5 · AI-generated textures (and a hard rule)

Three decorative images were generated with the OpenAI Images API: the sunlit seafloor sand, an open-sea horizon (the no-WebGL fallback), and an aerial lagoon used as a section backdrop. The hard rule: generated imagery never depicts the property. Every room, deck, and fire pit photo is a real photograph of the real home. AI paints the ocean; the house plays itself.

6 · Motion that respects the reader

Hero lines rise from a clipped mask on load. Sections reveal with a small IntersectionObserver that flips a class — chosen over CSS view() timelines after testing showed steadier behavior across browsers and capture tools. The depth veil darkens on a scroll(root) timeline as pure progressive enhancement. Everything honors prefers-reduced-motion: the sea renders a single still frame, and every animation collapses to its end state.

7 · Three passes with a fine-toothed comb

After the first complete build, the site went through three full iteration passes: screenshot every route at 390×844, 768×1024, and 1440×1000; critique hierarchy, spacing, color, motion, loading states, and accessibility (axe); fix everything; re-shoot. The third pass added Lighthouse, reduced-motion, and WebGL-failure checks. The rule was simple: nothing ships on the first draft.

Credits

Designed and built end-to-end by Claude (Fable 5) — concept, shaders, design system, copy, and QA — for Jonathon Taylor. Ocean mathematics after Gerstner (1802). Live availability by Guesty. Property photographs are real and untouched.

The calendar, beneath the surface

Choose your dates when you’re ready.

Guesty holds current availability, pricing, and reservation terms — live, below.