Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/apursley2012/dev-haunt/llms.txt

Use this file to discover all available pages before exploring further.

FogLayer renders a purely decorative, always-on atmospheric effect at the bottom of every page. It positions itself fixed to the viewport so it stays in place as the user scrolls, and it runs two independent CSS-animated fog waves that scroll horizontally in opposite directions. The staggered speeds and slight vertical offsets give the illusion of depth — a closer, faster bank of mist over a slower, more distant layer. Because the component is mounted inside Layout, the fog is always present regardless of which route is active.

Structure

The component itself is minimal — two <div> elements inside a container <div>:
function FogLayer() {
  return (
    <div className="fog-container">
      <div className="fog-layer" />
      <div className="fog-layer" />
    </div>
  );
}
All the animation work is done in CSS. The two .fog-layer divs are styled differently via the :nth-child(2) selector.

CSS animation

The fog effect is defined in main.css:
@keyframes fog-drift {
  0%   { transform: translate(0); }
  100% { transform: translate(-50%); }
}

.fog-container {
  position: fixed;
  bottom: 0;
  left: 0;
  width: 100%;
  height: 30vh;
  pointer-events: none;
  z-index: 40;
  overflow: hidden;
  mask-image: linear-gradient(to top, #000, transparent);
  -webkit-mask-image: linear-gradient(to top, rgba(0,0,0,1) 0%, rgba(0,0,0,0) 100%);
}

.fog-layer {
  position: absolute;
  bottom: 0;
  width: 200%;
  height: 100%;
  background: url('data:image/svg+xml;...') repeat-x;
  background-size: 50% 100%;
  animation: fog-drift 40s linear infinite;
}

.fog-layer:nth-child(2) {
  animation: fog-drift 30s linear infinite reverse;
  bottom: -20px;
}

How the drift works

Each .fog-layer is set to width: 200% and contains a repeating SVG wave tiled with background-size: 50% 100%. That means the background image repeats exactly twice across the element’s full width. The fog-drift keyframe slides the element from translate(0) to translate(-50%), which is exactly one full tile width — so at the 100% mark the pattern is in the same position it started, making the loop seamless.
LayerAnimation durationDirectionbottom offsetPerceived distance
First (:nth-child(1))40 sForward0Far / slow
Second (:nth-child(2))30 sReverse-20pxNear / fast

SVG fog waves

Each layer uses a different SVG path to vary the wave silhouette and create a more organic look: Layer 1 — gentle long waves, opacity: 0.15:
/* SVG path inside the data URI */
M0,100 Q100,50 200,100 T400,100 T600,100 T800,100 T1000,100 L1000,200 L0,200 Z
Layer 2 — slightly shorter peaks, opacity: 0.10:
M0,120 Q150,80 300,120 T600,120 T900,120 T1000,120 L1000,200 L0,200 Z
Both SVGs fill with the ghost colour (#f4f1ea) at a low opacity so the fog reads as a subtle light haze over the dark night background rather than an opaque white wall.

Masking

The .fog-container applies a mask-image gradient that fades from fully opaque at the very bottom to fully transparent at the top edge of the 30 vh container. This means the fog appears to rise naturally from the bottom of the screen and dissolve into the page rather than having a hard upper edge.
The -webkit-mask-image vendor-prefixed version is included alongside the standard mask-image for full Safari and older Chrome compatibility.

Z-index and pointer events

FogLayer sits at z-index: 40 — above page content (z-10) and the bat swarm (z-30), but below the navigation bar (z-50). The container has pointer-events: none set in CSS, so the fog overlay never interferes with clicks, links, or form inputs anywhere on the page.

Customisation

All visual parameters are in the .fog-layer and .fog-container rules in main.css, so you can tune the effect without touching the React component.
What to changeWhereHow
Wave shapeSVG d attribute in the background data URIEdit the Quadratic Bézier control points
Scroll speedanimation duration valueReduce for faster fog, increase for slower
Colourfill="%23f4f1ea" in the URIReplace the percent-encoded hex (%23 = #)
Fog densityopacity attribute in the SVGIncrease toward 1.0 for thicker fog
Container height.fog-container heightChange 30vh to any value

Build docs developers (and LLMs) love