The base layer uses a regular 2D canvas. It draws soft moving light fields behind the interface, then lets CSS glass layers do the depth work.
This keeps the public site lighter than a WebGL scene while leaving room for special pages later.
const gradient = ctx.createRadialGradient(x, y, 0, x, y, radius);
gradient.addColorStop(0, "hsla(var(--page-hue), 95%, 68%, 0.16)");
gradient.addColorStop(1, "transparent");
The key constraints are simple:
- respect reduced motion
- cap device pixel ratio
- keep the particle count low
- use CSS variables for page hue
That is enough to make the page feel alive without turning every route into an effects demo.