Documentation Index
Fetch the complete documentation index at: https://mintlify.com/apursley2012/nightshade/llms.txt
Use this file to discover all available pages before exploring further.
SmokeLayer is the animated atmospheric background of Nightshade. It fills the entire viewport with three slowly drifting color blobs that bleed into one another, producing the impression of colored smoke or aurora light shifting behind the page content. It is always mounted as part of Layout and requires no props.
How it works
The component renders afixed inset-0 container at z-0 with opacity-30 and mix-blend-screen. Inside it, three motion.div blobs drift independently using Framer Motion’s animate prop with repeat: Infinity. A hidden SVG filter applies SVG fractal noise displacement to each blob, distorting their edges so they look organic rather than like smooth circles.
The three blobs
Each blob is a heavily blurred, large rounded div positioned in a different region of the screen. They drift alongx and y keyframe paths and scale up and down in a continuous loop.
| Blob | Color token | Size | Initial position | Loop duration |
|---|---|---|---|---|
| 1 | witch-teal/20 | 60% × 60% | Bottom-left (-bottom-[20%] -left-[10%]) | 25 s |
| 2 | witch-plum/20 | 50% × 50% | Top-right (-top-[10%] -right-[10%]) | 30 s |
| 3 | witch-turquoise/10 | 40% × 40% | Center-left (top-[30%] left-[20%]) | 35 s |
| Blob | x keyframes | y keyframes | scale keyframes |
|---|---|---|---|
| 1 | 0% → 20% → 0% | 0% → -10% → 0% | 1 → 1.2 → 1 |
| 2 | 0% → -30% → 0% | 0% → 20% → 0% | 1 → 1.5 → 1 |
| 3 | 0% → 40% → 0% | 0% → 10% → 0% | 1 → 1.1 → 1 |
ease: "easeInOut" and repeat: Infinity. Blobs 2 and 3 have delay: 5 and delay: 10 respectively, preventing them from starting in synchrony.
SVG fractal noise filter
A hidden<svg> element defines the smoke-filter filter using two SVG filter primitives: feTurbulence generates a fractal noise field, and feDisplacementMap uses that field to warp the blob’s pixel positions.
baseFrequency attribute is itself animated, cycling between 0.01 and 0.015 over 20 seconds. This causes the noise pattern to shift slowly over time, so the blob edges never settle into a static shape. Each blob references this filter via style={{ filter: "url(#smoke-filter)" }}.
The
<svg> element carrying the filter definition must be in the DOM for the url(#smoke-filter) reference to resolve. SmokeLayer renders it as a className="hidden" sibling inside the same fixed container.Blur levels
In addition to the SVG displacement, each blob is blurred with a Tailwindblur-* utility to soften it into a hazy cloud:
| Blob | Blur class |
|---|---|
| 1 | blur-[100px] |
| 2 | blur-[120px] |
| 3 | blur-[80px] |
Mix-blend-screen
The outer container usesmix-blend-screen, which makes the blobs brighten whatever is rendered beneath them rather than painting over it. On the very dark bg-witch-dark base, this means the blobs appear as faint luminous hazes — roughly analogous to how real colored light behaves against a dark background.
Customization
Blob colors — change the Tailwind color tokens (witch-teal/20, witch-plum/20, witch-turquoise/10) on each motion.div to shift the palette.
Animation speed — lower the duration values for a more restless, stormy feel; raise them for a slower, dreamlike drift.
Noise seed — changing seed="5" on feTurbulence to any other integer generates a completely different noise pattern, altering the overall shape language of the smoke without changing any other values.
Blob count — adding a fourth motion.div with its own color, position, duration, and delay is all that is needed to introduce another smoke layer.