# Liquid Glass Voyage

> **Category:** Hero Section
> **Effect:** Liquid-glass morphism floating on a procedurally animated cinematic film backdrop
> **Platform:** Workbuddy proxy (`workbuddy`)
> **Model:** `hy4-preview-f` — Hy4 preview (hy4-preview-f)
> **License:** Free / MIT — copy, paste, ship.
> **Self-contained:** yes — one `index.html`, no build step, no external media.

---

## 🎬 Live demo

Open [`public/demos/liquid-glass-voyage/index.html`](../public/demos/liquid-glass-voyage/index.html) — generated by the model
above from the prompt below, with no human edits to the markup.

## ✅ Verification

<!-- VERIFICATION:START -->
_Pending — this block is written by `tools/verify.mjs` after the build run._
<!-- VERIFICATION:END -->

## 📋 Prompt

```text
DESIGN BRIEF — "Liquid Glass Voyage"

Build a full-viewport cinematic hero for a fictional deep-sea research studio called
"Abyssal". The feeling is expensive, quiet and slightly unreal: a slow-moving film of
light and water behind a single pane of liquid glass.

A. THE BACKDROP ("the film")
   - A fixed, full-bleed <canvas> layer that renders an endless, slowly drifting
     underwater light field. Do NOT draw literal water. Draw the *light*: 3-5 large,
     very soft radial gradients in deep teal (#031a1f), abyssal blue (#062b3a) and
     cyan (#1e6f8c) that drift on independent Lissajous paths, plus one warm
     highlight (#c8a45c) that passes across the frame every ~24 seconds.
   - Layer on top, in CSS: a fine animated grain (SVG feTurbulence as a repeating
     background-image, animated by shifting background-position), a 1.5px caustic
     band pattern at 4% opacity, and a bottom-to-top vignette so the centre stays
     legible.
   - The whole film must run at 60fps. Render at devicePixelRatio capped to 2, and
     downscale the canvas backing store to 0.6x for the soft gradients (they are
     blurry by nature) then CSS-scale it up — this is the performance trick.
   - A "film loop" behaviour, implemented in JS exactly like this: every 18 seconds the
     film performs a 900ms cross-fade to the next palette (teal → indigo → slate →
     teal), implemented with requestAnimationFrame interpolation of a palette weight
     array, NOT a CSS transition. Any fade in progress is cancelled and restarted
     from the current opacity rather than snapping.

B. THE GLASS
   - Implement a reusable `.liquid-glass` class with: background rgba(255,255,255,0.012)
     plus background-blend-mode: luminosity; backdrop-filter: blur(14px) saturate(1.4)
     with the -webkit- prefix; box-shadow: inset 0 1px 1px rgba(255,255,255,0.10);
     position: relative; overflow: hidden; isolation: isolate.
   - The signature 1.4px glass edge is drawn with a ::before pseudo-element:
     inset 0; border-radius: inherit; padding: 1.4px; background:
     linear-gradient(180deg, rgba(255,255,255,.55) 0%, rgba(255,255,255,.18) 18%,
     rgba(255,255,255,0) 42%, rgba(255,255,255,0) 58%, rgba(255,255,255,.18) 82%,
     rgba(255,255,255,.55) 100%); and the border-only mask trick
     (-webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
     -webkit-mask-composite: xor; mask-composite: exclude; pointer-events: none).
   - Add a slow specular sweep: a ::after with a 120deg white gradient at 6% opacity
     that translates across the pane over 9s, paused (animation-play-state: paused)
     until the hero has entered.

C. LAYOUT (single column, everything centred, all inside <main>)
   - <header> nav bar: a liquid-glass pill, max-width 1080px, centred, containing on the
     left a small inline-SVG mark (a stylised wave inside a circle) + the wordmark
     "ABYSSAL" in 600 weight with 0.18em letter-spacing; centre nav links "Vessel",
     "Research", "Expeditions" (hidden below 768px); right side a plain text "Sign in"
     link and a liquid-glass pill button "Request access".
   - Hero block, optically centred but translated up by 6vh:
       * Eyebrow: a liquid-glass pill containing a 6px pulsing dot and the text
         "EXPEDITION 14 · LIVE FROM 4,120 M" in 11px, 0.22em letter-spacing, uppercase.
       * <h1> in "Instrument Serif" (Google Fonts, italic available) at
         clamp(2.75rem, 8vw, 6.5rem), line-height 0.98, tracking -0.02em, colour #f4f7f8:
         "We chart the light / that never reaches shore." — the second line in italic
         and at 0.86em size, coloured #9fd8ea.
       * A max-width 560px paragraph, 17px/1.65, rgba(244,247,248,0.72): "Abyssal maps
         the twilight zone with autonomous gliders — 41 vehicles, 900 days of continuous
         observation, one open dataset."
       * A liquid-glass email capture bar: rounded-full, padding 8px 8px 8px 22px,
         containing a transparent email input (placeholder "you@institute.edu",
         aria-label "Email address") and a solid #eaf6fa circular submit button with a
         black arrow-right SVG. On submit, prevent default and morph the pill into a
         confirmation state reading "You're on the manifest." with a checkmark, then
         fade back after 3.2s.
   - A stat strip of three liquid-glass cards (grid: 3 cols → 1 col under 640px) showing
     animated counters: "4,120 m  max depth", "41  gliders", "900  days at sea". Counters
     animate from 0 with an easeOutExpo over 1.6s when the strip first enters the
     viewport (IntersectionObserver, fire once).
   - <footer> a single row: "© 2026 Abyssal Research" on the left, three liquid-glass
     circular social icon buttons (inline SVG: instagram, x, globe) on the right, each
     with aria-label.

D. TYPE + COLOUR SYSTEM
   - Display: 'Instrument Serif', ui-serif, Georgia, serif.
   - UI: system stack (-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif).
   - Palette: ink #f4f7f8, muted rgba(244,247,248,.72), cyan #9fd8ea, gold #c8a45c,
     base #031a1f.

E. MICRO-INTERACTION
   - Buttons lift 1px and gain a 1.04 specular boost on hover; the glass edge brightens
     to 0.75 alpha. Use transform + custom properties only.
   - On pointer move over the hero, the glass panes tilt at most 1.2deg toward the
     pointer (perspective 1200px), damped with a 0.08 lerp in the rAF loop.

---

TECHNICAL CONTRACT (non-negotiable):

1. Deliver ONE single file: a complete, valid `index.html`. No build step, no bundler,
   no framework, no package install. It must open correctly by double-clicking the file
   and also over http://.
2. Vanilla only. No React, no Tailwind CDN, no GSAP, no Three.js, no jQuery, no Lottie.
   Plain HTML + CSS + modern JavaScript in <style> and <script> tags.
3. NO external media. No .mp4, no .webm, no .gif, no remote images, no base64 blobs of
   photos. Every visual must be generated procedurally with CSS gradients, SVG, or
   <canvas>. This keeps the page free to host and impossible to break with a dead link.
4. Google Fonts is the ONLY permitted network request, and it must be declared with a
   <link rel="preconnect"> plus a system-font fallback stack so the page still looks
   intentional offline. If you prefer, skip it and use a pure system stack.
5. Responsive and correct at 390x844 (phone), 768x1024 (tablet) and 1440x900 (desktop).
   No horizontal scrollbar at any of those widths. Nothing may overflow its container.
6. Accessibility: exactly one <h1>; real <header>/<main>/<footer>/<nav> landmarks; every
   interactive element is a <button> or <a> with an accessible name; visible :focus-visible
   ring; body text contrast ratio >= 4.5:1 against its background.
7. Motion safety: wrap all continuous motion in
   `@media (prefers-reduced-motion: reduce)` rules that reduce it to a static or
   near-static state. The page must remain fully readable and usable with motion off.
8. Performance: no layout thrash. Cache DOM reads, batch writes inside a single
   requestAnimationFrame loop, use transform/opacity for animation, and never allocate
   inside the hot loop. Target 60fps on a 2019 laptop. Total file under 90 KB.
9. Runtime telemetry hook (used by the automated verifier — implement it exactly):
   at the top of your script define
     window.__DEMO__ = { name: '<slug>', ready: false, frames: 0, effects: [], errors: [] };
   then set `ready = true` after the first paint of your main effect, increment
   `frames` once per animation frame inside your rAF loop, and push the name of each
   implemented effect into `effects`. Add a `window.addEventListener('error', ...)`
   handler that pushes messages into `errors`. Do not rename these fields.
10. Zero console output in the happy path. No console.log left behind. No uncaught
    exceptions, no failed network requests.

RESPONSE FORMAT:
Return ONLY the raw HTML inside a single ```html fenced code block. No explanation, no
preamble, no commentary before or after the fence. The file must be complete and
immediately runnable — never truncate, never write "// rest of code here".
```

---

*LandingPagePrompts Prompt Library — free, verified, model-attributed.*
