Skip to content

2 cases built from this template

Same prompt, different [VARIABLES]. Click one to preview it above.

About this template

Fathom is a long-scroll explainer in which every pixel of scrolling takes the reader deeper into the ocean. The page starts at the waterline with a pale sky and a moving surface, then the reader dives: the background shifts continuously from bright cyan through twilight blue and midnight navy to almost black, while a fixed depth gauge on the right counts metres, names the current zone and shows the light level, pressure and temperature. Each zone gets the same amount of scroll, so the thin sunlit layer and the deep abyss both have room to breathe. Short two-line chapters in a soft serif, with an italic second line and a small mono label, fade in and out on alternating sides. In the shallower zones, six real public-domain photographs from NOAA slide past as framed plates and lose their colour as the water darkens. Deeper down, everything is drawn in code on a canvas: drifting marine snow, light shafts that vanish after the first two hundred metres, pulsing jellyfish, a school of lanternfish that scatters from the cursor and an anglerfish whose lure brightens when you come close. At the bottom, a single glowing organism waits on the seafloor; press and hold to make it flare. It suits science centres, aquariums, museum exhibits, teachers and science writers, and any subject that comes in layers. The default case is a small ocean science centre with four zones down to 6,000 metres. To adapt it, change the brand, the dive title, the subject, the visit line and the list of zones with their depth ranges; the gauge, colour stops, chapters and creature positions are all computed from that list, and every line of copy lives in one content file.

The template prompt

The live demo was built from exactly this text — nothing added. The other cases only change the values of the [VARIABLES].

# Ocean Depth Scroll Explainer

Build this website exactly as described below. Replace the [VARIABLES] with your own values; keep everything else.

## Brief
A single-page interactive explainer for [BRAND] called [TITLE]: one very tall scroll is a dive through [SUBJECT], from 0 m at the surface down to the bottom of the last zone in [ZONES]. A full-screen intro shows the waterline. Then the dive section maps scroll to depth: every zone in [ZONES] gets an equal share of the scroll and depth runs linearly inside each share. A fixed depth gauge shows the live metre readout, the zone name, light, pressure and temperature. The page background color is interpolated by depth from sunlit cyan to near-black. Two short serif chapters per zone fade in and out on alternating sides. Six real public-domain NOAA photographs pass as framed plates in the first three zones and desaturate as the water darkens. A canvas draws marine snow, surface light shafts, jellyfish, a lanternfish school and an anglerfish that react to the cursor, and a seafloor at the bottom. The page ends on the seafloor with one glowing organism the visitor can press and hold to make it flare, followed by a visit line and a button back to the surface. Static site, no backend, no audio.

- Audience: Visitors of a small ocean science centre, school classes aged 9–14 and their teachers, and curious adults on phones or laptops. Also science centres, museums, teachers and science writers who want a layered subject (ocean, atmosphere, rock strata) to feel physical.
- Goal: Make the scale of the ocean felt rather than read: the reader should finish knowing the zone names, roughly how deep each goes, and one memorable fact per zone, and should want to visit [BRAND]'s Deep Room in person.
- Tone: Quiet, precise, slightly poetic. Short declarative sentences, real numbers, no exclamation marks, no hype. Headlines read like captions in a good museum; body lines are one or two sentences of plain science.

## Stack
- Framework: Vite 5 + vanilla TypeScript
- Styling: Plain CSS, custom properties
- Libraries: gsap 3 (core + ScrollTrigger) (GSAP Standard 'no charge' license), lenis (MIT), vite (MIT), typescript (Apache-2.0), @fontsource-variable/fraunces (OFL-1.1), @fontsource-variable/manrope (OFL-1.1), @fontsource/dm-mono (OFL-1.1)
- Build: `npm run build` → static files in `dist/`. No backend, no server code, no external APIs.
- Setup:
  - Scaffold with npm create vite@latest using the vanilla-ts template. No UI framework. One page: index.html plus src/main.ts.
  - vite.config.ts: base './', build { outDir: 'dist', sourcemap: false, assetsInlineLimit: 0 }. Do not copy src/ into dist/.
  - File layout: src/content.ts (every string, the ZONES list, chapters, plates, credits), src/depth.ts (scroll→depth mapping, color stops, light/pressure/temperature functions), src/scene/ (Ocean.ts canvas loop, Snow.ts, Shafts.ts, Jelly.ts, Lanternfish.ts, Angler.ts, Seafloor.ts, Glow.ts), src/ui/ (Intro.ts, Gauge.ts, Chapters.ts, Plates.ts, Finale.ts, Cursor.ts), src/styles.css.
  - Fonts: in src/main.ts import '@fontsource-variable/fraunces', '@fontsource-variable/fraunces/wght-italic.css', '@fontsource-variable/manrope', '@fontsource/dm-mono/400.css' and '@fontsource/dm-mono/500.css'. CSS families: 'Fraunces Variable', 'Manrope Variable', 'DM Mono', each with a serif / sans-serif / monospace fallback.
  - Smooth scroll: new Lenis({ lerp: 0.085, wheelMultiplier: 0.9, smoothWheel: true }); lenis.on('scroll', ScrollTrigger.update); gsap.ticker.add(t => lenis.raf(t * 1000)); gsap.ticker.lagSmoothing(0). gsap.registerPlugin(ScrollTrigger). Under prefers-reduced-motion do not create Lenis (native scroll).
  - ZONES parsing in src/content.ts: split [ZONES] on ', ', each item 'Name start–end' (en dash or hyphen) gives { name, start, end } in metres. Validate that zones are contiguous and start at 0; MAX = last zone end. The page supports 3 to 6 zones.
  - Section heights are set in px from window.innerHeight on load and recomputed only when the viewport width changes (so mobile toolbars do not jump the page): #intro = 1 × vh, #dive = N × 3.6 × vh (N = number of zones), #finale = 1.8 × vh.
  - Photos live in public/images/ under the exact file names in Assets and are referenced with relative paths ('./images/plate-1-kelp-canopy.jpg'). Write ASSETS.md at the project root before building.
  - All colors are CSS custom properties on :root in src/styles.css and mirrored in src/depth.ts for the canvas and the interpolation.
  - dist/ contains index.html, hashed JS/CSS, woff2 files, favicon.svg and the six photos (about 3 MB). Keep it under 20 MB.

## Variables
- [BRAND] — Organisation or project name (default: "Tidewell Ocean Lab"). Shown top-left, in the intro eyebrow, the finale and the <title>.
- [TITLE] — Title of the dive (default: "Six Thousand Metres"). Two to four words. The last word is set in italic on its own line in the intro.
- [SUBJECT] — What the reader descends through (default: "the open ocean"). Lower-case phrase used inside sentences, e.g. 'a deep ocean trench'.
- [ZONES] — Zones with depth ranges in metres, top to bottom (default: "Sunlight 0–200, Twilight 200–1000, Midnight 1000–4000, Abyss 4000–6000"). 3–6 zones, contiguous, first starts at 0. The last end is the maximum depth. Two chapters are written per zone.
- [VISIT_LINE] — Practical line: place, hours, price (default: "Deep Room, 14 Brinewater Quay, Port Halden · Tue–Sun 10:00–17:30 · Adults $14, under-16s free")
- [CREDIT] — keep a small "Template by VibeFather" link to https://vibefather.ai/t/ocean-depth-scroll-explainer in the footer (default: yes; delete this line to remove it)

The copy under Pages & Sections is written for the default values. If your values differ, rewrite every headline, paragraph, label and image for them — same length, tone and structure. Layout, colors, type and motion stay as described.
Keep all copy, image paths and links in one content file (for example `src/content.ts`), keyed by section, so the content can be swapped later without touching components.

Pro template. The design, sections, motion and assets parts of this prompt are for Pro members. The live demo and DESIGN.md stay free.

Join Pro early access →

DESIGN.md

The design system on its own — colors, type, spacing and motion. Apply this look to a project you already have.

---
name: "Ocean Depth Scroll Explainer"
colors:
  surface: "#9fe0e8"
  sky: "#e8f6f3"
  shallows: "#3fa9c6"
  lagoon: "#1b6e9a"
  dusk: "#0f3e6b"
  indigo: "#0a2546"
  midnight: "#04132a"
  abyssal: "#020914"
  floor: "#010407"
  ink: "#07293b"
  foam: "#e9f5f4"
  mist: "rgba(233,245,244,0.62)"
  hairline: "rgba(233,245,244,0.18)"
  lume: "#79f2d0"
  lure: "#ffcf7a"
typography:
  display_intro_title_chapter_headlines_zone_name_in_gauge_wordmark: { family: "Fraunces", weights: [300, 400] }
  text_lead_chapter_body_lines_buttons_finale_copy: { family: "Manrope", weights: [400, 500, 600] }
  mono_hud_eyebrows_depth_readout_gauge_labels_plate_captions_hints: { family: "DM Mono", weights: [400, 500] }
spacing: "Fixed HUD inset 32px from the edges at ≥ 900px wide, 18px below. Chapters sit inside a 6vw side margin; left and right chapters max-width 560px, centered chapters max-width 760px. Eyebrow → headline gap 20px, headline → body 22px. Mono labels 11px uppercase with 0.18em letter-spacing. Plates: width clamp(260px, 30vw, 460px), 10px inner padding, caption 12px below. Vertical rhythm in multiples of 8px."
radius: "0 on plates, frames and panels. Pill buttons 999px. Cursor ring, gauge marker and glows are circles."
---

# Ocean Depth Scroll Explainer — Design System

Apply this design system to an existing project. It describes the look and feel only; for the full site, use prompt.md.

## Colors
- **Surface** `#9fe0e8` — Depth color stop at 0 m; intro water near the waterline
- **Sky** `#e8f6f3` — Intro sky above the waterline (gradient top)
- **Shallows** `#3fa9c6` — Depth stop at 60 m
- **Lagoon** `#1b6e9a` — Depth stop at 200 m
- **Dusk** `#0f3e6b` — Depth stop at 600 m
- **Indigo** `#0a2546` — Depth stop at 1000 m
- **Midnight** `#04132a` — Depth stop at 0.4 × MAX
- **Abyssal** `#020914` — Depth stop at 0.7 × MAX
- **Floor** `#010407` — Depth stop at MAX and the finale background; seabed fill #03090e
- **Ink** `#07293b` — Text on the bright surface (intro and 0–20 m)
- **Foam** `#e9f5f4` — Text from 80 m down, marine snow, cursor ring; between 20 m and 80 m --fg is interpolated Ink→Foam
- **Mist** `rgba(233,245,244,0.62)` — Secondary text, body lines, plate captions, gauge labels (Ink at 70% while --fg is Ink)
- **Hairline** `rgba(233,245,244,0.18)` — Gauge track, plate frames, dividers
- **Lume** `#79f2d0` — The bioluminescent accent: gauge marker, jellyfish and photophore glow, finale organism, focus rings, button dot. Never for text blocks or large fills.
- **Lure** `#ffcf7a` — Only the anglerfish lure bulb and its glow

## Typography
- **Display (intro title, chapter headlines, zone name in gauge, wordmark)** — Fraunces (OFL), weights 300/400. Self-host the font files.
- **Text (lead, chapter body lines, buttons, finale copy)** — Manrope (OFL), weights 400/500/600. Self-host the font files.
- **Mono HUD (eyebrows, depth readout, gauge labels, plate captions, hints)** — DM Mono (OFL), weights 400/500. Self-host the font files.

## Spacing & shape
- Spacing: Fixed HUD inset 32px from the edges at ≥ 900px wide, 18px below. Chapters sit inside a 6vw side margin; left and right chapters max-width 560px, centered chapters max-width 760px. Eyebrow → headline gap 20px, headline → body 22px. Mono labels 11px uppercase with 0.18em letter-spacing. Plates: width clamp(260px, 30vw, 460px), 10px inner padding, caption 12px below. Vertical rhythm in multiples of 8px.
- Radius: 0 on plates, frames and panels. Pill buttons 999px. Cursor ring, gauge marker and glows are circles.

## Motion
- Global easing: entrances cubic-bezier(.2,.8,.2,1); everything tied to scroll is scrubbed directly from depth, never time-based. Damping helper damp(a, b, λ, dt) = a + (b − a)(1 − e^(−λ·dt)) for cursor, creature reactions and glow.
- Depth mapping: ScrollTrigger on #dive, start 'top top', end 'bottom top', gives p ∈ [0, 1]. zone i = min(floor(p·N), N−1), u = p·N − i, depth = start_i + u·(end_i − start_i). Before #dive depth = 0; in #finale depth = MAX. All visuals read this one depth value each frame.
- Background color: body background is set every frame by interpolating the stops (0 m Surface, 60 m Shallows, 200 m Lagoon, 600 m Dusk, 1000 m Indigo, 0.4·MAX Midnight, 0.7·MAX Abyssal, MAX Floor) in linear RGB. Stops that are not strictly increasing for a given ZONES list are dropped.
- Chapters fade by zone-local position u: opacity = smoothstep(c−0.16, c−0.08, u) × (1 − smoothstep(c+0.08, c+0.16, u)); translateY = (c − u) × 180px; the headline's second line lags the first by 0.025 in u.
- Plates reveal with clip-path inset(100% 0 0 0) → inset(0) while their top travels from 100% to 60% of the viewport (scrub), the image inside scales 1.12 → 1 and moves −6% → 6% in y across the plate's pass (parallax). Plate filter: t = clamp(depth / 1200, 0, 1); saturate(1 − 0.7t) brightness(1 − 0.5t).
- Canvas loop (requestAnimationFrame, paused when the tab is hidden): marine snow streams upward with scroll velocity, light shafts sway and fade out by 220 m, creatures pulse and react to the cursor, finale glow charges while the pointer is held.
- Readout numbers update every frame with tabular figures; zone name changes slide up through a 1-line mask in 0.45s.
- prefers-reduced-motion: native scroll (no Lenis), chapters crossfade with opacity only (no translate), no plate parallax or clip reveal (plates simply fade in), snow drawn static at 40 particles, no shaft sway, creatures drawn in a still pose with glow on, finale copy shown without needing to hold, custom cursor off.

## Imagery
Six real public-domain photographs from NOAA (via Wikimedia Commons) in the first three zones: kelp from below, kelp and a fish school, bigeye jacks, a deep coral mound, a siphonophore and an Arctic comb jelly. They keep their natural aspect and are only darkened and desaturated by depth through the CSS filter. Everything else is drawn in code: the waterline, sun, light shafts, marine snow, jellyfish, lanternfish, anglerfish, seafloor, finale organism, grain, vignette, cursor and favicon. No people, no divers' faces, no logos.

## Tone
Quiet, precise, slightly poetic. Short declarative sentences, real numbers, no exclamation marks, no hype. Headlines read like captions in a good museum; body lines are one or two sentences of plain science.

---
Inspired by Descent — an interactive scroll journey from the ocean surface to the abyss by @ohmiler — https://ohmiler.github.io/opus-5.5/underwater-journey/
— Prompt by VibeFather · https://vibefather.ai/t/ocean-depth-scroll-explainer · CC BY-NC 4.0 (non-commercial; commercial use needs a VibeFather Pro license) · Request removal: https://vibefather.ai/takedown