Style LibraryNew · weekly review
Shader Gradient
StylemodernA 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#F472B6Preview
A sample page drawn from this style’s tokens — a guide to the look, not the exact output.
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 meContinueToday
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 preventedExample 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