Native first.
WebGL second.

Accessible-by-default WebGL effects for native HTML elements. The element keeps its state, its keyboard and its place in the accessibility tree; WebGL only paints the surface.

This list is the demo

Each row is a native <details>. Press Enter or Space on a title: the cover recedes like ink soaking into paper, and the content moves from transparent and blurred to sharp.

The attribute open changes the instant you press; only the surface is animated.

What stays native

State, events, focus, Esc, the top layer, light dismiss and the accessibility tree. Nothing is reimplemented: the library wraps the native calls and lets the browser do the work.

What WebGL paints

One canvas, one WebGL context, shared by every element on the page. It is aria-hidden, takes no pointer events and exists only while an animation runs.

Opacity and blur come from CSS, which follows the same progress as the shader through --p.

Without WebGL

With prefers-reduced-motion, without WebGL2 or after a lost context, every element behaves exactly like the native one.

Playground

A native dialog

Focus is trapped, Esc closes it and the rest of the page is inert: all of it comes from the browser. Behind it, a pane of liquid glass drawn with WebGPU: the frosting is CSS, the surface, its highlights and their colour split are the shader.

A native popover

Esc or a click outside closes it, natively. The button closes it with the animation.