/* Subtle UI backgrounds: paper, SVG feTurbulence noise, ruled and squared grids. Re-theme with the --bp-* properties. Each pattern is a utility; pass colours and sizes as arbitrary properties, e.g. [--bp-color:#0d9488]. */
/* Paper: warm ground, soft edge and a feTurbulence grain tinted by --bp-color */
@utility bp-paper{
position:relative;isolation:isolate;overflow:hidden;background:var(--bp-bg,radial-gradient(130% 100% at 50% 0%,#fdfaf3 50%,#efe4cf));--bp-svg:url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.8' numOctaves='3' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .6 0'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");
&::before{content:"";position:absolute;inset:0;z-index:-1;border-radius:inherit;pointer-events:none;opacity:var(--bp-opacity,.32);background-color:var(--bp-color,#6b4f1d);-webkit-mask:var(--bp-svg) 0 0/var(--bp-size,160px) repeat;mask:var(--bp-svg) 0 0/var(--bp-size,160px) repeat}
}
/* Noise: fine grain on a flat colour */
@utility bp-noise{
position:relative;isolation:isolate;overflow:hidden;background:var(--bp-bg,#f1f5f9);--bp-svg:url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='3' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .7 0'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");
&::before{content:"";position:absolute;inset:0;z-index:-1;border-radius:inherit;pointer-events:none;opacity:var(--bp-opacity,.22);background-color:var(--bp-color,#0f172a);-webkit-mask:var(--bp-svg) 0 0/var(--bp-size,140px) repeat;mask:var(--bp-svg) 0 0/var(--bp-size,140px) repeat}
}
/* Grain on gradient: noise breaks up gradient banding */
@utility bp-grain{
position:relative;isolation:isolate;overflow:hidden;background:var(--bp-bg,linear-gradient(135deg,#c7d2fe,#fbcfe8 55%,#fde68a));--bp-svg:url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.95' numOctaves='3' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .7 0'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");
&::before{content:"";position:absolute;inset:0;z-index:-1;border-radius:inherit;pointer-events:none;opacity:var(--bp-opacity,.3);background-color:var(--bp-color,#1e1b4b);-webkit-mask:var(--bp-svg) 0 0/var(--bp-size,120px) repeat;mask:var(--bp-svg) 0 0/var(--bp-size,120px) repeat}
}
/* Lined notebook: ruled lines plus a margin rule at --bp-margin */
@utility bp-notebook{
position:relative;isolation:isolate;overflow:hidden;background:var(--bp-bg,#fff);
&::before{content:"";position:absolute;inset:0;z-index:-1;border-radius:inherit;pointer-events:none;opacity:var(--bp-opacity,1);background-image:linear-gradient(90deg,transparent var(--bp-margin,44px),var(--bp-accent,#f87171) var(--bp-margin,44px) calc(var(--bp-margin,44px) + 1px),transparent 0),repeating-linear-gradient(transparent 0 calc(var(--bp-size,28px) - 1px),var(--bp-color,#93c5fd) 0 var(--bp-size,28px))}
}
/* Graph paper: minor squares of --bp-size with a major line every five */
@utility bp-graph{
position:relative;isolation:isolate;overflow:hidden;background:var(--bp-bg,#fff);
&::before{content:"";position:absolute;inset:0;z-index:-1;border-radius:inherit;pointer-events:none;opacity:var(--bp-opacity,1);background-image:linear-gradient(var(--bp-major,rgb(14 165 233 / .45)) 1px,transparent 1px),linear-gradient(90deg,var(--bp-major,rgb(14 165 233 / .45)) 1px,transparent 1px),linear-gradient(var(--bp-minor,rgb(14 165 233 / .16)) 1px,transparent 1px),linear-gradient(90deg,var(--bp-minor,rgb(14 165 233 / .16)) 1px,transparent 1px);background-size:calc(var(--bp-size,12px) * 5) calc(var(--bp-size,12px) * 5),calc(var(--bp-size,12px) * 5) calc(var(--bp-size,12px) * 5),var(--bp-size,12px) var(--bp-size,12px),var(--bp-size,12px) var(--bp-size,12px)}
}
/* Blueprint: the graph-paper grid in white on deep blue */
@utility bp-blueprint{
position:relative;isolation:isolate;overflow:hidden;background:var(--bp-bg,radial-gradient(120% 100% at 50% 0%,#1d4ed8,#1e3a8a));
&::before{content:"";position:absolute;inset:0;z-index:-1;border-radius:inherit;pointer-events:none;opacity:var(--bp-opacity,1);background-image:linear-gradient(var(--bp-major,rgb(255 255 255 / .32)) 1px,transparent 1px),linear-gradient(90deg,var(--bp-major,rgb(255 255 255 / .32)) 1px,transparent 1px),linear-gradient(var(--bp-minor,rgb(255 255 255 / .1)) 1px,transparent 1px),linear-gradient(90deg,var(--bp-minor,rgb(255 255 255 / .1)) 1px,transparent 1px);background-size:calc(var(--bp-size,16px) * 5) calc(var(--bp-size,16px) * 5),calc(var(--bp-size,16px) * 5) calc(var(--bp-size,16px) * 5),var(--bp-size,16px) var(--bp-size,16px),var(--bp-size,16px) var(--bp-size,16px)}
}
About this set
Six quiet textures for app shells, landing pages and editors. Paper puts a warm, slightly darker edge on a cream ground and adds a brown grain. Noise is a fine grey grain on a flat slate colour. Grain on gradient lays the same kind of noise over an indigo, pink and amber gradient, which also hides gradient banding. Lined notebook draws ruled blue lines and a red margin rule, Graph paper draws minor squares with a stronger line every five, and Blueprint is that grid in white on deep blue. The grain is an SVG feTurbulence filter inlined as a data URI. Instead of using it as a background image, the set uses it as a mask on a ::before layer filled with –bp-color, so the grain can be any colour and its strength is just –bp-opacity. The ruled and squared grids are layered linear-gradients sized from one –bp-size value, so the major lines always land on every fifth minor line. Use the grain textures behind hero sections and cards, and the grids behind note-taking, planning and technical pages.
What’s included
Paper, noise, grain on gradient, lined notebook, graph paper, blueprint
SVG feTurbulence noise inlined as a data URI, no image files
Grain colour comes from --bp-color because the noise is a mask
Graph and blueprint grids derive the major lines from one --bp-size
Plain CSS, Bootstrap 5 and Tailwind CSS 4 versions of the same design
Accessibility
The textures are decorative backgrounds, so they need no alt text and are not read by screen readers. Name labels are opaque chips with text above 4.5:1 on every texture. Nothing moves and there are no interactive controls.
Customise it
Change --bp-bg (which can be a gradient), --bp-color, --bp-size and --bp-opacity; the notebook adds --bp-accent and --bp-margin, and the grids use --bp-major and --bp-minor. In Tailwind pass the same properties as arbitrary properties on the bp-paper, bp-noise or bp-graph utilities.