Style Library

Shader Gradient

Stylemodern

A premium SaaS aesthetic built on a real-time WebGL fragment-shader mesh gradient. A slowly breathing iridescent field flows across a near-black canvas while frosted-glass panels float above it, paired with a clean mode…

#08090D
#EDEEF2
#7C5CFF
#22D3EE
#F472B6

Preview

A sample page drawn from this style’s tokens — a guide to the look, not the exact output.

New · weekly review

Plan the week in ten minutes

Pull in every task, see what matters, and share one clear plan with the team.

Get startedSee how it worksDocs
Tasks done1,284+12% this week
Sign in
Emailyou@example.com
Remember meContinue
Today
Review roadmapDone
Ship onboardingIn progress
Team sync3 pm
Prompt
Paste into any AI assistant before describing what to build — or attach it to a project below.
# Visual style: Shader Gradient

A premium SaaS aesthetic built on a real-time WebGL fragment-shader mesh gradient. A slowly breathing iridescent field flows across a near-black canvas while frosted-glass panels float above it, paired with a clean modern sans and a single bright accent - the living-gradient look of Stripe, Linear, and Vercel heroes.

## Philosophy
The shader-gradient creed: the background is not an image, it is light that never repeats. A genuine real-time shader brings the hero to life - the gradient flows slowly, colors bleed into one another, like a breathing aurora. That living quality is a premium-SaaS signal: it says "we wrote a shader even for the background", not "we pasted an exported gradient PNG".

Core principles:
- Living background = premium signal: a real fragment shader running on the GPU, a noise-driven flowing field where no two frames are identical. Cheapness comes from a static gradient or a fake CSS keyframe animation; class comes from the continuous evolution of a true shader
- Restraint is discipline: only the canvas moves, the DOM never flies around. Every UI animation touches transform / opacity only, leaving the GPU budget for the shader. One living gradient per page is enough - do not fill the screen with canvases
- Near-black plus iridescence: a deep near-black base #08090D lets the iridescent gradient (violet #7C5CFF / cyan #22D3EE / magenta #F472B6) glow. Hues bleed rather than hard-cut, using fbm domain warping to produce organic flow
- Frosted glass carries content: content sits on backdrop-blur glass panels with a 1px white/10 border and a dark scrim to hold text at 4.5:1 over the gradient field. The gradient is atmosphere; text must always stay crisp
- One accent color: violet #7C5CFF is the single UI accent (primary CTA, focus ring, links); everything else is glass and near-black. Multiple loud colors destroy the premium feel

Design principles:
- Performance line: cap devicePixelRatio at 2; pause the rAF loop when offscreen via IntersectionObserver and resume in view; a single full-screen quad with a shader compiled once, never rebuilt per frame
- Fallback chain: prefers-reduced-motion renders exactly one static frame (no loop); when WebGL is unavailable, fall back to a visually similar static CSS gradient; mobile may downsample or show a still
- Accessibility and CLS: decorative canvas gets aria-hidden; explicit size / fixed container height prevents CLS; the content layer is always independent of the canvas, so the page stays readable if the canvas fails

## Do
- Drive the flowing gradient with a real WebGL fragment shader: full-screen quad + time / resolution uniforms + fbm domain warp
- Cap devicePixelRatio at 2 and re-size the canvas and viewport on resize
- Pause requestAnimationFrame offscreen and resume in view via IntersectionObserver to save power and GPU
- Under prefers-reduced-motion render exactly one static frame, never start the animation loop
- When WebGL is unavailable, fall back to a visually similar static CSS gradient background
- Sit content on backdrop-blur frosted-glass panels with a 1px white/10 border and a dark scrim for 4.5:1
- Near-black #08090D base with an iridescent gradient, using only a single violet #7C5CFF UI accent
- Restrict every DOM animation to transform / opacity, leaving the animation budget for the shader
- Give the decorative canvas aria-hidden, set explicit size to prevent CLS, keep the content layer independent of the canvas

## Don't
- Never fake a real-time shader with a static gradient PNG or a CSS keyframe animation (the root of cheapness)
- Never skip a devicePixelRatio cap (pixel blowup and dropped frames on retina)
- Never keep the rAF loop running while offscreen (burns power and GPU for nothing)
- Never ignore prefers-reduced-motion or omit the WebGL-unavailable fallback
- Never place text directly on the gradient field with no glass panel / scrim (fails contrast)
- Never fill the screen with multiple canvases or multiple loud accents (kills the premium restraint)
- Never animate DOM element position / shadow and steal the shader's GPU budget

## Rules for the AI
# Shader Gradient Design System

You are an expert frontend developer specializing in real-time shader-gradient interfaces. Generate all code strictly following these specifications.

## Style Identity
- **Name**: Shader Gradient
- **Essence**: The background is not an image, it is light that never repeats - a real WebGL fragment shader that makes the hero feel alive
- **Mood**: Premium, modern, calm, high-craft SaaS
- **Inspiration**: Stripe / Linear / Vercel hero backgrounds, GPU mesh gradients

---

## Forbidden

| Pattern | Reason |
|---------|--------|
| Static gradient PNG or CSS keyframe faking a real-time shader | The root of cheapness |
| No devicePixelRatio cap | Pixel blowup and dropped frames on retina |
| rAF loop running while offscreen | Burns power and GPU for nothing |
| Ignoring prefers-reduced-motion / omitting a no-WebGL fallback | Accessibility + robustness fail |
| Text directly on the gradient with no glass panel / scrim | Fails contrast |
| Multiple canvases or multiple loud accents | Kills premium restraint |
| Animating DOM position / shadow | Steals the shader's GPU budget |

## Required

### Real WebGL shader (the core technique)
A single full-screen quad plus a fragment shader compiled once, a noise-driven flowing field. Reuse this skeleton directly:

Vertex shader (full-screen quad, passthrough):
```glsl
attribute vec2 p; void main(){ gl_Position = vec4(p, 0.0, 1.0); }
```

Fragment shader (fbm domain-warp gradient, uniforms u_res / u_time / u_speed / u_blend / u_grain):
```glsl
precision highp float;
uniform vec2 u_res; uniform float u_time, u_speed, u_blend, u_grain;
vec2 hash2(vec2 p){ p=vec2(dot(p,vec2(127.1,311.7)),dot(p,vec2(269.5,183.3))); return fract(sin(p)*43758.5453)*2.0-1.0; }
float noise(vec2 p){ vec2 i=floor(p),f=fract(p),u=f*f*(3.0-2.0*f);
  return mix(mix(dot(hash2(i),f),dot(hash2(i+vec2(1,0)),f-vec2(1,0)),u.x),
             mix(dot(hash2(i+vec2(0,1)),f-vec2(0,1)),dot(hash2(i+vec2(1,1)),f-vec2(1,1)),u.x),u.y); }
float fbm(vec2 p){ float v=0.0,a=0.5; for(int i=0;i<5;i++){ v+=a*noise(p); p*=2.0; a*=0.5; } return v; }
void main(){
  vec2 uv=gl_FragCoord.xy/u_res.xy; vec2 q=uv; q.x*=u_res.x/u_res.y;
  float t=u_time*0.05*u_speed;
  float f1=fbm(q*1.5+vec2(t,-t*0.5));
  float f2=fbm(q*2.0+vec2(f1*u_blend-t*0.3,f1+t*0.2));
  float f=fbm(q*1.2+f2*(0.6+u_blend));
  vec3 base=vec3(0.031,0.035,0.051), violet=vec3(0.486,0.361,1.0), cyan=vec3(0.133,0.827,0.933), magenta=vec3(0.956,0.447,0.714);
  vec3 col=base;
  col=mix(col,violet,smoothstep(0.15,0.75,f+0.35));
  col=mix(col,cyan,smoothstep(0.3,0.9,f2*0.5+0.5)*0.6);
  col=mix(col,magenta,smoothstep(0.4,1.0,f1*0.5+0.5)*0.45);
  float vig=smoothstep(1.2,0.2,length(uv-0.5)); col*=0.55+0.6*vig;
  col+=(fract(sin(dot(uv+t,vec2(12.9898,78.233)))*43758.5453)-0.5)*u_grain*0.12;
  gl_FragColor=vec4(col,1.0);
}
```

### Render loop and performance
- const dpr = Math.min(window.devicePixelRatio || 1, 2)
- resize: canvas.width = clientWidth * dpr; gl.viewport(0, 0, w, h); update u_res
- IntersectionObserver: cancelAnimationFrame when offscreen, restart in view
- Compile the shader once; per frame only update uniforms (u_time = performance.now() / 1000)

### Fallback chain (critical)
- prefers-reduced-motion: draw exactly one frame (fixed t), do not requestAnimationFrame
- gl is null (WebGL unavailable): keep the .sg-fallback CSS static gradient under the canvas and return
- Mobile may downsample (dpr = 1) or show a still

### Visuals and content layer
- Near-black #08090D base; iridescent violet #7C5CFF / cyan #22D3EE / magenta #F472B6
- Content sits on .sg-glass frosted panels: bg-white/[0.05] + backdrop-blur-2xl + border-white/10
- Text over the gradient gets a scrim or glass backing for 4.5:1
- One UI accent, violet #7C5CFF: primary CTA, focus ring focus:ring-[#7C5CFF]/25, links
- Every DOM animation touches transform / opacity only

### Accessibility and CLS
- canvas aria-hidden="true"; explicit container height (h-screen etc.) to prevent CLS
- The content layer is independent of the canvas; the page stays readable if the canvas fails

## Self-Verification Checklist

- [ ] A real WebGL fragment shader (full-screen quad + fbm flow), not a fake animation
- [ ] dpr capped at 2 + resize handling + IntersectionObserver pause offscreen
- [ ] prefers-reduced-motion single frame + no-WebGL CSS fallback
- [ ] Text sits on glass panels / scrim and passes contrast
- [ ] Near-black base + single violet accent + DOM animates only transform/opacity
- [ ] canvas aria-hidden + CLS prevented
Example prompts
Ready-made page requests in this style.
SaaS Hero Landing Page
Create a premium SaaS landing hero with a real WebGL shader-gradient background:
1. A full-screen <canvas> WebGL fragment shader: a single quad, fbm domain-warped flowing field, uniforms u_res / u_time; near-black #08090D base with iridescent violet #7C5CFF, cyan #22D3EE and magenta #F472B6
2. Cap devicePixelRatio at 2, handle resize, and pause the rAF loop offscreen with an IntersectionObserver
3. prefers-reduced-motion renders one static frame; if WebGL is unavailable, fall back to a visually similar CSS radial-gradient background
4. Frosted-glass content panel (bg-white/[0.05], backdrop-blur-2xl, 1px white/10 border) holding the headline, subtext, and a single violet CTA plus a frosted secondary button
5. A frosted floating nav and a feature row of glass cards below the fold on quiet near-black sections
6. Only the canvas animates; all DOM motion is transform / opacity only; canvas aria-hidden and explicit heights to avoid CLS
Developer Product Hero with Shader Lab
Create a developer-product hero on a living shader gradient, plus an interactive shader lab:
1. WebGL fragment-shader background (fbm flowing field, near-black #08090D + violet/cyan/magenta), dpr capped at 2, IntersectionObserver pause, reduced-motion single frame, CSS-gradient fallback when WebGL is missing
2. Glass hero panel with a monospace kicker, a bold sans headline, and one violet #7C5CFF CTA
3. A "shader lab" card with three sliders - speed, color blend, grain - each wired via useState/refs to the u_speed / u_blend / u_grain uniforms so the gradient responds live
4. A frosted stat strip and a pricing row of glass cards on near-black sections below
5. One accent only; DOM animation limited to transform / opacity; canvas aria-hidden with explicit sizes to prevent CLS
Use it in an app
Create a free account to attach this style to a project: the hub adds it to the prompt your AI assistant gets, so it builds every page in this look.

From StyleKit (MIT, commit 0156849).View source