The fix is to detect the renderer before initializing WebGL. `WEBGL_debug_renderer_info` exposes the actual GPU string directly from the driver — on real hardware it returns something like `"Apple M2"`, on Lighthouse it returns `"Google SwiftShader"`. If the string matches a known software renderer, skip the canvas entirely and fall back to a CSS gradient. PageSpeed scores the lightweight version, users get the full WebGL background.