← Basalt vault

Refract

Think in liquid light.

Fig. 1 — Refract, live capture10 s loop · recorded frame by frame on GPU

Field notes

An aurora of violet, cyan, and pink light flows behind frosted glass cards whose rims bend it like a lens. One raw WebGL2 shader, no three.js, and the glass follows whatever the DOM lays out.

Refract is a hero for an AI product that wants to feel alive. A domain-warped aurora flows behind the page, and three glass cards float over it: a prompt that types itself and walks through its build steps, a live render metric, and a status chip. Each card's rim acts like a lens, pulling the light inward with a faint color split, while the face stays frosted so the text reads cleanly.

It is a single raw WebGL2 canvas with two small shaders and no 3D library. Every frame it measures each card in the DOM and draws the glass exactly underneath, so any layout, breakpoint, or new card just works. The pointer stirs the fluid and tilts the cards in parallax, and visitors who prefer reduced motion get one still, fully typed frame.

How it's built

  • CSS can’t bend light: backdrop-filter only blurs. So the glass lives in the shader. Every frame it measures each card with getBoundingClientRect() and draws a lens under it, refraction on the rim and frost on the face. Move a card in the DOM and the glass follows.
  • Seamless loop: time reaches the shader only as the cosine and sine of the loop angle, so the last frame flows back into the first.
  • Frost for free: generateMipmap on the half-resolution fluid, then textureLod(…, 3.0). No blur pass.

Inside the prompt

Every file below is written out in full, so your agent creates the project exactly — no guessing, no missing pieces.

refract-glass/
├─ .gitignore
├─ index.html
├─ package.json
├─ tsconfig.json
├─ vite.config.ts
└─ src/
   ├─ App.tsx
   ├─ index.css
   ├─ main.tsx
   ├─ vite-env.d.ts
   ├─ components/
   │  ├─ GlassCard.tsx
   │  ├─ HeroOverlay.tsx
   │  └─ LiquidCanvas.tsx
   ├─ lib/
   │  ├─ cards.ts
   │  └─ loop.ts
   └─ shaders/
      └─ liquidGlass.ts

Recut it

  • Rename the product and rewrite the pitchsrc/components/HeroOverlay.tsx → HeroOverlay
  • Edit the prompt, build steps, metric, and status textsrc/lib/cards.ts → PROMPT, STEPS, METRIC, STATUS
  • Swap the three aurora colors and the basesrc/shaders/liquidGlass.ts → PALETTE
  • Tune corner radius, rim width, refraction, and frostsrc/shaders/liquidGlass.ts → GLASS
  • Add a glass card (up to four)src/components/GlassCard.tsx → GlassCard
  • Move or restack the cardssrc/components/HeroOverlay.tsx → the cards column in <main>

Also in the vault