Skip to main content
vibld

Templates · Landing page

Nocturne

A dark landing page for a made-up observability product for AI agents, with oscilloscope ribbons of light behind the hero and everything arriving on springs.

Nocturne, as its prompt produced it

Open the live pageDownload the prompt

One HTML file: a WebGL hero and spring-driven reveals.

The prompt

One prompt that asks for one self-contained HTML file. The live page is the reference output it produced.

---
slug: nocturne
category: template
tone: dark
industry: [ai-tech, saas]
stack: [webgl, shaders, springs]
---

# Nocturne

Build **one self-contained HTML file** containing a complete landing page for
"Nocturne", a fictional observability product for AI agents.

## Intent

A near-black, confident SaaS page. Behind the hero, three thin ribbons of light
(indigo, cyan, lime) drift like oscilloscope traces, which suits a product
about seeing signals in the dark. The copy pairs a crisp grotesk with italic
serif accent words. Everything arrives on springs; nothing blinks or loops for
attention.

## Composition

1. **Floating pill nav**: brand dot, 4 links (hidden below 800px), primary CTA. Fixed, glass blur.
2. **Hero (100svh)**: WebGL ribbon canvas; "New" pill; h1 "See what your agents *actually* did." bottom-aligned; subtitle and two CTAs in a row beneath.
3. **Logo strip**: six fictional wordmarks between hairlines.
4. **Product**: kicker, h2, lede, and a 6-column bento grid (one wide card with a mini trace timeline and glow, one tall card, three small cards).
5. **Results**: three metrics that count up when scrolled into view.
6. **Pricing**: three plans; the middle plan is highlighted with an accent border.
7. **CTA panel**: rounded panel with an indigo glow rising from the bottom.
8. **Footer**.

## Look

Three-tier tokens: `--raw-*` primitives → semantic roles → components. No hex values outside `:root`.

| Semantic | Raw | Value |
|---|---|---|
| `--bg` | `--raw-ink-950` | #06070b |
| `--surface` / `--surface-2` | ink-900 / ink-800 | #0c0e15 / #151823 |
| `--border` | ink-700 | #232839 |
| `--fg` / `--fg-muted` / `--fg-subtle` | mist-100 / 400 / 500 | #eef1f8 / #9aa2b8 / #6d7590 |
| `--accent` / `-2` / `-3` | lime / cyan / indigo | #c6ff4d / #4de1ff / #3a2fd6 |

- Type: Geist 400/500/600; Instrument Serif italic for accent words. h1 `clamp(3rem, 9.5vw, 8.5rem)`, tracking −0.045em.

## Motion

A single spring integrator (k, c, dt-stepped) inside one rAF loop drives all of these:

| Element | Trigger | Behaviour | Spring |
|---|---|---|---|
| h1 words | load | Split into masked words; each rises from 110%, 70ms stagger | k=120 c=20 |
| `[data-reveal]` | IntersectionObserver, −12% bottom margin | Fade + rise 40px; 80ms stagger per batch | k=140 c=22 |
| Metrics | in view | Count from 0 to the value | k=30 c=11 (slight overshoot is fine) |
| Hero ribbons | always, while visible | 3 sine-sum curves with glow falloff; cursor parallax | exp lerp, rate 3/s |

## Constraints

- The hidden initial state is applied only once `.js` is on `<html>`, so content is visible with JS disabled.
- Split headline keeps an `aria-label` with the full sentence; word spans are `aria-hidden`.
- Reduced motion: no split, reveals show instantly, the canvas draws one frame.
- Hero canvas at 0.75 × min(dpr, 2), and it stops drawing when scrolled out of view.
- Semantic landmarks: `nav`, `main`, `section[aria-labelledby]`, `footer`.

## Deliverable

Return only the complete `index.html`, with no commentary.

Open the builderAll templates