---
name: web-weather-creator
description: Master of stylized atmospheric effects using SVG filters and CSS animations. Creates clouds, waves, lightning, rain, fog, aurora borealis, god rays, lens flares, twilight skies, and ocean spray—all
  with a premium aesthetic that's stylized but never cheap-looking.
metadata:
  category: Design
  tags:
  - svg
  - animations
  - weather-effects
  - atmospheric
  - css-animations
  pairs-with:
  - skill: web-cloud-designer
    reason: Cloud effects are a specific weather element sharing SVG filter and animation techniques
  - skill: web-wave-designer
    reason: Wave effects share the same SVG feTurbulence and CSS animation infrastructure
  - skill: dark-mode-design-expert
    reason: Atmospheric weather effects must adapt visual parameters for dark and light modes
---

# Web Weather Creator

Master of stylized atmospheric effects using SVG filters and CSS animations. Creates clouds, waves, lightning, rain, fog, aurora borealis, god rays, lens flares, twilight skies, and ocean spray—all with a premium aesthetic that's stylized but never cheap-looking.

## Activation Triggers

**Activate on:** "clouds", "waves", "weather effects", "atmospheric", "lightning", "rain", "fog", "mist", "aurora", "northern lights", "god rays", "crepuscular", "lens flare", "twilight", "sunset gradient", "golden hour", "ocean spray", "beach wash", "foam", "smoke", "parallax sky", "water ripples", "animated background"

**NOT for:**
- Photorealistic renders (use WebGL/Three.js)
- Static weather icons (use icon libraries)
- Weather data APIs (use backend services)
- 3D volumetric effects (use Babylon.js/Three.js)

---

## Philosophy: Stylized, Not Cheap

The goal is **premium stylization**—effects that feel intentional and artistic, not like stock footage or placeholder art.

### The Three Principles

1. **Layering Creates Depth** - Multiple semi-transparent layers with parallax motion
2. **Organic Motion** - Varied speeds, easing, and subtle randomization
3. **Restraint** - One hero effect, subtle supporting elements

### Quality Spectrum

```
CHEAP ──────────────────────── STYLIZED ──────────────────────── REALISTIC
CSS gradient blob         SVG filter + layered opacity        WebGL particles
Single div animation      3-5 layers with parallax            Fluid simulation
Linear easing             Cubic-bezier + varied timing        Physics engine
```

**Target Zone:** The middle—stylized enough to feel crafted, performant enough for production.

---

## Clouds Floating Through Content (Z-Index Strategy)

The most common question: *"How do I make clouds float through my content, not just behind it?"*

### The Split-Layer Solution

```html
<div class="atmosphere-container">
  <!-- BACK clouds (behind content) -->
  <div class="clouds clouds--back"></div>

  <!-- Content sits in the middle -->
  <main class="content">
    <div class="card">Your content here</div>
  </main>

  <!-- FRONT clouds (in front of content, but transparent) -->
  <div class="clouds clouds--front"></div>
</div>
```

```css
.atmosphere-container {
  position: relative;
  isolation: isolate; /* Creates stacking context */
}

.clouds {
  position: absolute;
  inset: 0;
  pointer-events: none; /* CRITICAL: Let clicks through */
  filter: url(#cloud-cumulus);
}

.clouds--back {
  z-index: -1;
  opacity: 0.3;
  transform: scale(1.5);
  animation: drift 120s linear infinite;
}

.content {
  position: relative;
  z-index: 1;
}

.clouds--front {
  z-index: 2;
  opacity: 0.12; /* LOW opacity so content is readable */
  transform: scale(0.8);
  animation: drift 50s linear infinite reverse;

  /* Optional: Mask to clear space around content */
  mask-image: linear-gradient(
    to bottom,
    black 0%,
    transparent 30%,
    transparent 70%,
    black 100%
  );
}
```

### Key Principles

1. **Split clouds into 2-3 layers** (back, mid, front)
2. **Front clouds use LOW opacity** (10-15%) so content remains visible
3. **Always use `pointer-events: none`** on cloud layers
4. **Use masks** to clear space around important content
5. **Vary animation speeds** for parallax depth (back = slow, front = fast)

### Blend Modes for Natural Integration

```css
.clouds--front {
  mix-blend-mode: soft-light; /* Blends naturally with content */
  opacity: 0.25;
}

/* Or for white clouds on dark backgrounds */
.clouds--front {
  mix-blend-mode: screen;
  opacity: 0.15;
}
```

### Content Readability

```css
/* Add subtle backdrop to cards so text is always readable */
.card {
  background: rgba(255, 255, 255, 0.85);
  backdrop-filter: blur(4px); /* Blurs back clouds for extra depth */
}
```

→ **See `references/layering-strategies.md` for complete patterns including parallax, content-aware masking, and React components.**

---

## Core Technique: SVG Filter Chain

All atmospheric effects build on this filter architecture:

```svg
<svg width="0" height="0">
  <defs>
    <filter id="atmosphere" x="-50%" y="-50%" width="200%" height="200%">
      <!-- 1. Generate noise texture -->
      <feTurbulence
        type="fractalNoise"      <!-- or "turbulence" for water -->
        baseFrequency="0.01"     <!-- Lower = larger shapes -->
        numOctaves="4"           <!-- 3-5 for good detail -->
        seed="1"                 <!-- Change for variation -->
        result="noise"
      />

      <!-- 2. Distort the source -->
      <feDisplacementMap
        in="SourceGraphic"
        in2="noise"
        scale="30"               <!-- Distortion intensity -->
        xChannelSelector="R"
        yChannelSelector="G"
        result="displaced"
      />

      <!-- 3. Soften edges -->
      <feGaussianBlur
        in="displaced"
        stdDeviation="2"
        result="blurred"
      />

      <!-- 4. Add lighting (optional) -->
      <feDiffuseLighting
        in="noise"
        lighting-color="white"
        surfaceScale="2"
        result="lit"
      >
        <feDistantLight azimuth="45" elevation="60" />
      </feDiffuseLighting>

      <!-- 5. Composite layers -->
      <feComposite in="blurred" in2="lit" operator="multiply" />
    </filter>
  </defs>
</svg>
```

### Key Parameter Reference

| Parameter | Effect | Range | Notes |
|-----------|--------|-------|-------|
| `type="fractalNoise"` | Soft, cloudy | - | Clouds, smoke, fog |
| `type="turbulence"` | Wavy, liquid | - | Water, waves, ripples |
| `baseFrequency` | Shape size | 0.001-0.1 | Lower = larger shapes |
| `numOctaves` | Detail level | 1-8 | 3-5 optimal, &gt;5 diminishing returns |
| `scale` (displacement) | Distortion | 0-100 | Start at 20-30 |
| `stdDeviation` (blur) | Softness | 0-20 | 2-5 for clouds, 0-2 for water |

---

## SECTION A: CLOUD EFFECTS

### Cloud Type Recipes

| Cloud Type | baseFrequency | numOctaves | Blur | Character |
|------------|---------------|------------|------|-----------|
| **Cumulus** (fluffy) | 0.008 | 4 | 3-5 | Puffy, cotton-like |
| **Cirrus** (wispy) | 0.003 | 5 | 1-2 | Thin, streaky |
| **Stratus** (flat) | 0.015 | 2 | 5-8 | Low, uniform |
| **Storm** (dramatic) | 0.006 | 5 | 2-3 | Dense, textured |
| **Cartoon** | 0.02 | 2 | 8-12 | Soft, simple |

### Multi-Layer Cloud System

```css
.cloud-layer {
  position: absolute;
  inset: 0;
  background: radial-gradient(
    ellipse 200% 100% at 50% 100%,
    rgba(255, 255, 255, 0.9) 0%,
    transparent 70%
  );
  filter: url(#cloud-filter);
}

/* Layer hierarchy: back → front */
.cloud-back {
  opacity: 0.3;
  transform: scale(1.5);
  animation: drift 120s linear infinite;
}

.cloud-mid {
  opacity: 0.5;
  transform: scale(1.2);
  animation: drift 80s linear infinite;
}

.cloud-front {
  opacity: 0.7;
  transform: scale(1);
  animation: drift 50s linear infinite;
}

@keyframes drift {
  from { transform: translateX(-10%); }
  to { transform: translateX(10%); }
}
```

### Cloud Color Palettes

```css
:root {
  /* Daylight clouds */
  --cloud-white: rgba(255, 255, 255, 0.9);
  --cloud-highlight: rgba(255, 250, 240, 1);
  --cloud-shadow: rgba(180, 190, 210, 0.6);

  /* Sunset clouds */
  --cloud-gold: rgba(255, 200, 100, 0.8);
  --cloud-pink: rgba(255, 150, 180, 0.7);
  --cloud-purple: rgba(180, 100, 200, 0.5);

  /* Storm clouds */
  --storm-dark: rgba(60, 70, 90, 0.9);
  --storm-purple: rgba(80, 60, 100, 0.7);
  --storm-highlight: rgba(200, 210, 230, 0.4);
}
```

---

## SECTION B: WAVE & WATER EFFECTS

### Critical Difference: Waves Use `turbulence`

```svg
<!-- WATER uses type="turbulence" NOT fractalNoise -->
<feTurbulence
  type="turbulence"
  baseFrequency="0.01 0.03"  <!-- X << Y for horizontal waves -->
  numOctaves="3"
  result="waves"
/>
```

### Wave Type Recipes

| Wave Type | baseFrequency | numOctaves | Scale | Character |
|-----------|---------------|------------|-------|-----------|
| **Ocean swell** | 0.005 0.015 | 3 | 40 | Broad, rolling |
| **Lake ripples** | 0.02 0.04 | 2 | 15 | Small, regular |
| **Beach shore** | 0.008 0.02 | 4 | 30 | Approaching, foam |
| **Pool reflection** | 0.03 0.03 | 2 | 10 | Subtle, uniform |

### Animated Wave SVG

```svg
<svg viewBox="0 0 1440 320" preserveAspectRatio="none">
  <defs>
    <filter id="wave-distort">
      <feTurbulence
        type="turbulence"
        baseFrequency="0.01 0.02"
        numOctaves="3"
        result="turbulence"
      >
        <animate
          attributeName="baseFrequency"
          dur="20s"
          values="0.01 0.02; 0.015 0.025; 0.01 0.02"
          repeatCount="indefinite"
        />
      </feTurbulence>
      <feDisplacementMap
        in="SourceGraphic"
        in2="turbulence"
        scale="20"
        xChannelSelector="R"
        yChannelSelector="G"
      />
    </filter>
  </defs>

  <path
    fill="var(--ocean-color)"
    filter="url(#wave-distort)"
    d="M0,160 C360,220 720,100 1080,180 C1260,220 1380,140 1440,160 L1440,320 L0,320 Z"
  >
    <animate
      attributeName="d"
      dur="10s"
      repeatCount="indefinite"
      values="
        M0,160 C360,220 720,100 1080,180 C1260,220 1380,140 1440,160 L1440,320 L0,320 Z;
        M0,180 C360,120 720,200 1080,140 C1260,100 1380,180 1440,140 L1440,320 L0,320 Z;
        M0,160 C360,220 720,100 1080,180 C1260,220 1380,140 1440,160 L1440,320 L0,320 Z
      "
    />
  </path>
</svg>
```

### Ocean Color Palettes

```css
:root {
  /* Deep ocean */
  --ocean-deep: #0c4a6e;
  --ocean-mid: #0369a1;
  --ocean-surface: #38bdf8;
  --ocean-foam: rgba(255, 255, 255, 0.8);

  /* Tropical */
  --tropical-deep: #047857;
  --tropical-mid: #10b981;
  --tropical-surface: #6ee7b7;

  /* Stormy */
  --stormy-deep: #1e3a5f;
  --stormy-mid: #334155;
  --stormy-surface: #64748b;

  /* Sunset reflection */
  --sunset-water: linear-gradient(
    180deg,
    rgba(251, 146, 60, 0.4) 0%,
    rgba(14, 165, 233, 0.6) 50%,
    #0c4a6e 100%
  );
}
```

---

## SECTION C: LIGHTNING EFFECTS

### SVG Stroke-Dashoffset Lightning

The most effective technique for lightning uses animated stroke-dashoffset on SVG paths:

```svg
<svg viewBox="0 0 100 200" class="lightning">
  <defs>
    <filter id="lightning-glow" x="-50%" y="-50%" width="200%" height="200%">
      <feGaussianBlur stdDeviation="3" result="blur" />
      <feMerge>
        <feMergeNode in="blur" />
        <feMergeNode in="SourceGraphic" />
      </feMerge>
    </filter>
  </defs>

  <path
    class="bolt"
    d="M50,0 L45,40 L55,45 L40,90 L60,95 L35,150 L70,100 L50,95 L65,50 L45,45 L60,10 Z"
    fill="none"
    stroke="white"
    stroke-width="2"
    filter="url(#lightning-glow)"
  />
</svg>
```

```css
.lightning {
  position: absolute;
  pointer-events: none;
  opacity: 0;
}

.bolt {
  stroke-dasharray: 500;
  stroke-dashoffset: 500;
}

.lightning.flash {
  animation: lightning-flash 0.5s ease-out forwards;
}

.lightning.flash .bolt {
  animation: bolt-draw 0.15s ease-out forwards;
}

@keyframes lightning-flash {
  0% { opacity: 0; }
  10% { opacity: 1; }
  20% { opacity: 0.5; }
  30% { opacity: 1; }
  100% { opacity: 0; }
}

@keyframes bolt-draw {
  to { stroke-dashoffset: 0; }
}
```

### Lightning Flash Overlay

```css
.lightning-flash-overlay {
  position: fixed;
  inset: 0;
  background: rgba(255, 255, 255, 0);
  pointer-events: none;
  z-index: 1000;
}

.lightning-flash-overlay.active {
  animation: screen-flash 0.3s ease-out;
}

@keyframes screen-flash {
  0% { background: rgba(255, 255, 255, 0); }
  10% { background: rgba(200, 220, 255, 0.4); }
  20% { background: rgba(255, 255, 255, 0); }
  30% { background: rgba(200, 220, 255, 0.2); }
  100% { background: rgba(255, 255, 255, 0); }
}
```

### Branching Lightning Pattern

```javascript
function generateLightningPath(startX, startY, endY, segments = 8) {
  let path = `M${startX},${startY}`;
  let x = startX;
  let y = startY;
  const segmentHeight = (endY - startY) / segments;

  for (let i = 0; i < segments; i++) {
    const jitter = (Math.random() - 0.5) * 30;
    x += jitter;
    y += segmentHeight;
    path += ` L${x},${y}`;

    // Random branch (20% chance)
    if (Math.random() < 0.2) {
      const branchX = x + (Math.random() - 0.5) * 40;
      const branchY = y + segmentHeight * 0.5;
      path += ` M${x},${y} L${branchX},${branchY} M${x},${y}`;
    }
  }

  return path;
}
```

---

## SECTION D: RAIN EFFECTS

### CSS-Only Rain with Custom Properties

```css
.rain-container {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
}

.raindrop {
  position: absolute;
  width: 2px;
  background: linear-gradient(
    180deg,
    transparent 0%,
    rgba(174, 194, 224, 0.5) 50%,
    rgba(174, 194, 224, 0.8) 100%
  );
  border-radius: 0 0 2px 2px;
  animation: rain-fall var(--fall-duration) linear infinite;
  animation-delay: var(--delay);
  left: var(--x);
  height: var(--length);
  opacity: var(--opacity);
}

@keyframes rain-fall {
  0% {
    transform: translateY(-100vh);
  }
  100% {
    transform: translateY(100vh);
  }
}
```

### Rain Generator (JavaScript)

```javascript
function createRain(container, dropCount = 100) {
  for (let i = 0; i < dropCount; i++) {
    const drop = document.createElement('div');
    drop.className = 'raindrop';
    drop.style.setProperty('--x', `${Math.random() * 100}%`);
    drop.style.setProperty('--delay', `${Math.random() * 2}s`);
    drop.style.setProperty('--fall-duration', `${0.5 + Math.random() * 0.5}s`);
    drop.style.setProperty('--length', `${15 + Math.random() * 20}px`);
    drop.style.setProperty('--opacity', `${0.3 + Math.random() * 0.5}`);
    container.appendChild(drop);
  }
}
```

### Rain Intensity Presets

```css
/* Light drizzle */
.rain-light {
  --drop-count: 50;
  --fall-duration-base: 1.2s;
  --drop-opacity: 0.3;
}

/* Moderate rain */
.rain-moderate {
  --drop-count: 150;
  --fall-duration-base: 0.8s;
  --drop-opacity: 0.5;
}

/* Heavy downpour */
.rain-heavy {
  --drop-count: 300;
  --fall-duration-base: 0.5s;
  --drop-opacity: 0.7;
}
```

### Rain + Wind Angle

```css
.raindrop.windy {
  animation: rain-fall-diagonal var(--fall-duration) linear infinite;
}

@keyframes rain-fall-diagonal {
  0% {
    transform: translate(-50vw, -100vh) rotate(15deg);
  }
  100% {
    transform: translate(50vw, 100vh) rotate(15deg);
  }
}
```

---

## SECTION E: FOG & MIST EFFECTS

### Multi-Layer Fog System

```css
.fog-container {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
}

.fog-layer {
  position: absolute;
  width: 200%;
  height: 100%;
  background: url("data:image/svg+xml,...") repeat-x;
  opacity: 0.3;
  filter: url(#fog-filter);
}

.fog-back {
  animation: fog-drift 60s linear infinite;
  opacity: 0.2;
  transform: scale(1.5);
}

.fog-mid {
  animation: fog-drift 40s linear infinite reverse;
  opacity: 0.3;
  transform: scale(1.2);
}

.fog-front {
  animation: fog-drift 25s linear infinite;
  opacity: 0.4;
}

@keyframes fog-drift {
  from { transform: translateX(-50%); }
  to { transform: translateX(0%); }
}
```

### SVG Fog Filter

```svg
<filter id="fog-filter" x="-50%" y="-50%" width="200%" height="200%">
  <feTurbulence
    type="fractalNoise"
    baseFrequency="0.003"
    numOctaves="4"
    seed="5"
    result="noise"
  />
  <feGaussianBlur in="noise" stdDeviation="20" result="blur" />
  <feColorMatrix
    type="matrix"
    values="1 0 0 0 0
            0 1 0 0 0
            0 0 1 0 0
            0 0 0 0.5 0"
    result="faded"
  />
</filter>
```

### Fog Density Variations

```css
:root {
  /* Light haze */
  --fog-light: rgba(255, 255, 255, 0.2);
  --fog-blur-light: 10px;

  /* Morning mist */
  --fog-mist: rgba(200, 210, 230, 0.4);
  --fog-blur-mist: 20px;

  /* Dense fog */
  --fog-dense: rgba(180, 190, 210, 0.6);
  --fog-blur-dense: 40px;

  /* Eerie fog (horror) */
  --fog-eerie: rgba(100, 120, 140, 0.5);
  --fog-blur-eerie: 30px;
}
```

### Ground-Hugging Mist

```css
.ground-mist {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  height: 30%;
  background: linear-gradient(
    to top,
    rgba(255, 255, 255, 0.6) 0%,
    rgba(255, 255, 255, 0.3) 40%,
    transparent 100%
  );
  filter: url(#fog-filter);
  animation: mist-breathe 8s ease-in-out infinite;
}

@keyframes mist-breathe {
  0%, 100% {
    opacity: 0.5;
    transform: scaleY(1);
  }
  50% {
    opacity: 0.7;
    transform: scaleY(1.1);
  }
}
```

---

## SECTION F: TWILIGHT & SKY GRADIENTS

### Sky Time Progression

```css
:root {
  /* Pre-dawn (5:00-5:30) */
  --sky-predawn: linear-gradient(
    to top,
    #1a1a2e 0%,
    #16213e 30%,
    #0f3460 60%,
    #1a1a2e 100%
  );

  /* Dawn (5:30-6:30) */
  --sky-dawn: linear-gradient(
    to top,
    #ff6b6b 0%,
    #feca57 20%,
    #ff9ff3 40%,
    #54a0ff 70%,
    #1a1a2e 100%
  );

  /* Golden hour (6:30-7:30) */
  --sky-golden: linear-gradient(
    to top,
    #ff9a56 0%,
    #ffbe76 30%,
    #ffeaa7 50%,
    #74b9ff 80%,
    #0984e3 100%
  );

  /* Midday (10:00-14:00) */
  --sky-midday: linear-gradient(
    to top,
    #74b9ff 0%,
    #0984e3 50%,
    #0652dd 100%
  );

  /* Sunset (17:30-18:30) */
  --sky-sunset: linear-gradient(
    to top,
    #e17055 0%,
    #fdcb6e 20%,
    #f8a5c2 40%,
    #686de0 70%,
    #30336b 100%
  );

  /* Dusk (18:30-19:30) */
  --sky-dusk: linear-gradient(
    to top,
    #4a69bd 0%,
    #6a89cc 30%,
    #b8e994 10%,
    #e55039 5%,
    #1e3799 60%,
    #0c2461 100%
  );

  /* Night (20:00+) */
  --sky-night: linear-gradient(
    to top,
    #0c2461 0%,
    #1e3799 40%,
    #0a1931 100%
  );
}
```

### Animated Sky Transition

```css
.sky-canvas {
  background: var(--sky-midday);
  transition: background 3s ease-in-out;
}

.sky-canvas[data-time="dawn"] { background: var(--sky-dawn); }
.sky-canvas[data-time="golden"] { background: var(--sky-golden); }
.sky-canvas[data-time="midday"] { background: var(--sky-midday); }
.sky-canvas[data-time="sunset"] { background: var(--sky-sunset); }
.sky-canvas[data-time="dusk"] { background: var(--sky-dusk); }
.sky-canvas[data-time="night"] { background: var(--sky-night); }
```

### Sun/Moon Position System

```css
.celestial-body {
  position: absolute;
  width: 60px;
  height: 60px;
  border-radius: 50%;
  transition: all 2s cubic-bezier(0.4, 0, 0.2, 1);
}

.sun {
  background: radial-gradient(
    circle,
    #fff7e6 0%,
    #ffd93d 40%,
    #ff8c00 100%
  );
  box-shadow:
    0 0 40px 10px rgba(255, 200, 50, 0.6),
    0 0 80px 30px rgba(255, 150, 0, 0.3);
}

.moon {
  background: radial-gradient(
    circle at 30% 30%,
    #f5f5f5 0%,
    #e0e0e0 50%,
    #bdbdbd 100%
  );
  box-shadow:
    0 0 20px 5px rgba(255, 255, 255, 0.3),
    inset -10px -10px 20px rgba(0, 0, 0, 0.1);
}
```

---

## SECTION G: AURORA BOREALIS

### Stacked Gradient Aurora

```css
.aurora-container {
  position: absolute;
  inset: 0;
  overflow: hidden;
  background: linear-gradient(to top, #0a0a1a 0%, #1a1a3a 100%);
}

.aurora-band {
  position: absolute;
  top: 10%;
  left: -50%;
  width: 200%;
  height: 40%;
  opacity: 0.6;
  mix-blend-mode: screen;
  filter: blur(30px);
}

.aurora-green {
  background: linear-gradient(
    90deg,
    transparent 0%,
    rgba(0, 255, 128, 0.4) 20%,
    rgba(0, 255, 20