Backgrounds
The two atmospheres that power the live site, lifted into the system as drop-in components. Move your cursor over the grid — it lights the cell beneath it.
Noir glow · live shader
NoirGlowBackground from @tollerud/ui — the packaged @paper-design/shaders-react grain atmosphere (corners shape, yellow ramp, animated). Requires @paper-design/shaders-react in the host app.
<div className="relative min-h-[280px]">
<NoirGlowBackground intensity="medium" speed="medium" className="absolute inset-0" />
<div className="relative z-20">{children}</div>
</div>Noir glow · CSS fallback
Pass forceCssFallback for static export, reduced-motion, or when WebGL is unavailable.
<NoirGlowBackground
intensity="medium"
preserveCenter
forceCssFallback={false}
className="absolute inset-0"
/>Grain gradient · CSS only
A pure-CSS approximation using the same yellow ramp and corner composition — zero WebGL cost. NoirGlowBackground uses a similar fallback when forceCssFallback is set.
Hero readability treatments
Four ways to keep copy readable over the live grain gradient: a local blur scrim, a full-hero blur, a broad left-side shadow, or a scaled/offset shader that keeps motion toward the edges.
Copy blur scrim
import { NoirGlowBackground } from '@tollerud/ui'
export function HeroWithCopyScrim({ children }) {
return (
<section className="relative min-h-[420px] overflow-hidden">
<NoirGlowBackground intensity="medium" className="absolute inset-0" />
<div className="relative z-20 flex min-h-full items-center p-9">
<div className="hero-copy-scrim max-w-[520px]">{children}</div>
</div>
</section>
)
}/* globals.css — local blur scrim behind copy only */
.hero-copy-scrim {
margin: -24px -26px;
padding: 24px 26px;
border-radius: 14px;
background: linear-gradient(90deg, rgba(0, 0, 0, 0.78), rgba(0, 0, 0, 0.54) 58%, rgba(0, 0, 0, 0.18));
box-shadow: 0 24px 70px rgba(0, 0, 0, 0.42);
backdrop-filter: blur(16px) saturate(0.9);
-webkit-backdrop-filter: blur(16px) saturate(0.9);
}Full hero blur
import { NoirGlowBackground } from '@tollerud/ui'
export function HeroWithFullBlur({ children }) {
return (
<section className="relative min-h-[420px] overflow-hidden">
<NoirGlowBackground intensity="medium" className="absolute inset-0" />
<div className="hero-readable-fullblur absolute inset-0 z-10 pointer-events-none" aria-hidden />
<div className="relative z-20 flex min-h-full items-center p-9">
<div className="max-w-[520px]">{children}</div>
</div>
</section>
)
}/* globals.css — soft glass across the whole hero */
.hero-readable-fullblur {
background:
radial-gradient(100% 100% at 50% 48%, rgba(0, 0, 0, 0.18), rgba(0, 0, 0, 0.46) 78%),
rgba(0, 0, 0, 0.34);
backdrop-filter: blur(14px) saturate(0.9);
-webkit-backdrop-filter: blur(14px) saturate(0.9);
}Left shadow gradient
import { NoirGlowBackground } from '@tollerud/ui'
export function HeroWithLeftShadow({ children }) {
return (
<section className="relative min-h-[420px] overflow-hidden">
<NoirGlowBackground intensity="medium" className="absolute inset-0" />
<div className="hero-readable-shadow absolute inset-0 z-10 pointer-events-none" aria-hidden />
<div className="relative z-20 flex min-h-full items-center p-9">
<div className="max-w-[520px]">{children}</div>
</div>
</section>
)
}/* globals.css — broad left-side shadow, shader stays visible on the right */
.hero-readable-shadow {
background:
radial-gradient(90% 120% at 0% 50%, rgba(0, 0, 0, 0.9) 0%, rgba(0, 0, 0, 0.68) 38%, rgba(0, 0, 0, 0.28) 64%, transparent 82%),
linear-gradient(90deg, rgba(0, 0, 0, 0.68), rgba(0, 0, 0, 0.18) 58%, transparent);
}Edge-biased shader
import { NoirGlowBackground } from '@tollerud/ui'
export function HeroWithEdgeShader({ children }) {
return (
<section className="relative min-h-[420px] overflow-hidden">
<NoirGlowBackground intensity="medium" scale={1.55} offsetX={0.38} className="absolute inset-0" />
<NoirGlowBackground intensity="subtle" speed="slow" scale={1.55} offsetX={-0.38} className="absolute inset-0" />
<div className="relative z-20 flex min-h-full items-center p-9">
<div className="max-w-[520px]">{children}</div>
</div>
</section>
)
}Animated grid
A scrolling canvas grid that fades to #060606 at the edges and fills the square under the cursor. Direction, speed, cell size and colors are all props.
<Squares
direction="diagonal" // right | left | up | down | diagonal
speed={0.5}
squareSize={40}
borderColor="#333"
hoverFillColor="#222"
base="#060606"
/>In use
The grain gradient backs the Overview hero; the grid suits full-bleed section dividers and empty states. Both sit behind content at a lower z-index — keep foreground on z-20+.