const initRainfallBackground = () => {
    // Get the canvas element
    const canvas = document.getElementById('bg-canvas');
    if (!canvas) return;
    
    // Create scene, camera, and renderer
    const scene = new THREE.Scene();
    const camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.1, 1000);
    const renderer = new THREE.WebGLRenderer({ canvas, antialias: true });
    
    // Set renderer size and pixel ratio
    renderer.setSize(window.innerWidth, window.innerHeight);
    renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
    
    // Create a dark cloudy background
    const vertexShader = `
        varying vec2 vUv;
        void main() {
            vUv = uv;
            gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
        }
    `;
    
    const fragmentShader = `
        uniform float time;
        varying vec2 vUv;
        
        // Simplex noise functions
        vec3 permute(vec3 x) { return mod(((x*34.0)+1.0)*x, 289.0); }

        float snoise(vec2 v) {
            const vec4 C = vec4(0.211324865405187, 0.366025403784439,
                -0.577350269189626, 0.024390243902439);
            vec2 i = floor(v + dot(v, C.yy));
            vec2 x0 = v - i + dot(i, C.xx);
            vec2 i1;
            i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0);
            vec4 x12 = x0.xyxy + C.xxzz;
            x12.xy -= i1;
            i = mod(i, 289.0);
            vec3 p = permute(permute(i.y + vec3(0.0, i1.y, 1.0))
                + i.x + vec3(0.0, i1.x, 1.0));
            vec3 m = max(0.5 - vec3(dot(x0, x0), dot(x12.xy, x12.xy),
                dot(x12.zw, x12.zw)), 0.0);
            m = m * m;
            m = m * m;
            vec3 x = 2.0 * fract(p * C.www) - 1.0;
            vec3 h = abs(x) - 0.5;
            vec3 ox = floor(x + 0.5);
            vec3 a0 = x - ox;
            m *= 1.79284291400159 - 0.85373472095314 * (a0 * a0 + h * h);
            vec3 g;
            g.x = a0.x * x0.x + h.x * x0.y;
            g.yz = a0.yz * x12.xz + h.yz * x12.yw;
            return 130.0 * dot(m, g);
        }
        
        // FBM function
        float fbm(vec2 p) {
            float sum = 0.0;
            float amp = 1.0;
            float freq = 1.0;
            // More octaves = more detail
            for(int i = 0; i < 6; i++) {
                sum += amp * snoise(p * freq);
                amp *= 0.5;
                freq *= 2.0;
                p += vec2(0.1, 0.2); // Domain warping
            }
            return sum;
        }
        
        void main() {
            // Base colors for sky
            vec3 cloudColor = vec3(0.02, 0.03, 0.05);  // Very dark blue-gray
            vec3 skyColor = vec3(0.05, 0.07, 0.1);     // Dark blue-gray
            
            // Create moving clouds with FBM noise
            float cloudCover = 0.5;
            vec2 cloudMovement = vec2(time * 0.01, time * 0.002);
            
            // Layered noise for cloud structure
            float clouds = fbm(vUv * 3.0 + cloudMovement);
            clouds += fbm(vUv * 6.0 - cloudMovement * 0.5) * 0.5;
            
            // Cloud density
            clouds = smoothstep(0.1, 0.6, clouds);
            
            // Occasional lightning flashes
            float lightning = 0.0;
            float lightningTime = mod(time, 20.0);  // Lightning every ~20s
            
            // Random lightning flashes
            if (lightningTime < 0.1) {
                lightning = sin(lightningTime * 60.0) * 0.5 + 0.5;
            } else if (lightningTime > 8.0 && lightningTime < 8.2) {
                lightning = sin(lightningTime * 80.0) * 0.3 + 0.3;
            }
            
            // Lightning illuminates clouds
            vec3 finalColor = mix(skyColor, cloudColor, clouds);
            
            // Add lightning effect
            finalColor += lightning * vec3(0.2, 0.3, 0.4) * clouds;
            
            // Add vignette effect
            vec2 center = vUv - 0.5;
            float vignette = 1.0 - dot(center, center) * 0.7;
            finalColor *= vignette;
            
            gl_FragColor = vec4(finalColor, 1.0);
        }
    `;
    
    // Create cloudy sky background
    const skyGeometry = new THREE.PlaneGeometry(2, 2);
    const skyMaterial = new THREE.ShaderMaterial({
        uniforms: {
            time: { value: 0 }
        },
        vertexShader: vertexShader,
        fragmentShader: fragmentShader,
        depthWrite: false
    });
    
    const sky = new THREE.Mesh(skyGeometry, skyMaterial);
    sky.renderOrder = -1000; // Render first (background)
    scene.add(sky);
    
    // Create raindrops
    const raindropCount = 10000;
    const raindropGeometry = new THREE.BufferGeometry();
    const raindropPositions = new Float32Array(raindropCount * 3);
    const raindropSizes = new Float32Array(raindropCount);
    const raindropVelocities = new Float32Array(raindropCount);
    const raindropRotations = new Float32Array(raindropCount);
    
    // Calculate camera frustum dimensions
    const getFrustumDimensions = () => {
        const fovRad = camera.fov * Math.PI / 180;
        const height = 2 * Math.tan(fovRad / 2) * Math.abs(camera.position.z);
        const width = height * camera.aspect;
        return { width, height };
    };
    
    // Initialize raindrops
    function initRaindrops() {
        const { width, height } = getFrustumDimensions();
        
        // Extra margin to ensure raindrops don't pop in/out at edges
        const margin = 5;
        const areaWidth = width + margin;
        const areaHeight = height + margin;
        const areaDepth = 20; // Depth of the rain volume
        
        for (let i = 0; i < raindropCount; i++) {
            const i3 = i * 3;
            
            // Random positions within a rectangular volume
            raindropPositions[i3] = (Math.random() - 0.5) * areaWidth;
            raindropPositions[i3 + 1] = (Math.random() - 0.5) * areaHeight;
            raindropPositions[i3 + 2] = (Math.random() - 0.5) * areaDepth;
            
            // Size varies by depth - closer raindrops are larger
            const depthFactor = (raindropPositions[i3 + 2] + areaDepth/2) / areaDepth;
            raindropSizes[i] = (0.03 + Math.random() * 0.05) * (0.3 + depthFactor * 0.7); // Increased size
            
            // Velocity varies by size - larger raindrops fall faster
            raindropVelocities[i] = (0.15 + Math.random() * 0.1) * (0.5 + raindropSizes[i] * 15); // Increased speed
            
            // Random rotation for varied raindrop angles
            raindropRotations[i] = Math.random() * Math.PI;
        }
    }
    
    initRaindrops();
    
    raindropGeometry.setAttribute('position', new THREE.BufferAttribute(raindropPositions, 3));
    raindropGeometry.setAttribute('size', new THREE.BufferAttribute(raindropSizes, 1));
    raindropGeometry.setAttribute('rotation', new THREE.BufferAttribute(raindropRotations, 1));
    
    // Create raindrop sprite texture
    const raindropCanvas = document.createElement('canvas');
    raindropCanvas.width = 128;
    raindropCanvas.height = 128;
    const ctx = raindropCanvas.getContext('2d');
    
    // Clear background
    ctx.clearRect(0, 0, 128, 128);
    
    // Draw elongated raindrop shape - make it much brighter and larger
    ctx.fillStyle = '#ffffff';
    ctx.beginPath();
    ctx.ellipse(64, 64, 8, 32, 0, 0, Math.PI * 2); // Wider and longer
    ctx.fill();
    
    // Add glow effect
    ctx.shadowColor = '#80A0FF';
    ctx.shadowBlur = 15;
    ctx.globalCompositeOperation = 'source-atop';
    ctx.fillStyle = '#FFFFFF';
    ctx.fillRect(0, 0, 128, 128);
    
    // Add additional brightness
    ctx.globalCompositeOperation = 'lighter';
    ctx.fillStyle = 'rgba(255, 255, 255, 0.5)';
    ctx.fillRect(0, 0, 128, 128);
    
    const raindropTexture = new THREE.Texture(raindropCanvas);
    raindropTexture.needsUpdate = true;
    
    // Custom shader for raindrops with proper rotation
    const raindropVertexShader = `
        attribute float size;
        attribute float rotation;
        uniform float time;
        
        varying float vRotation;
        
        void main() {
            vRotation = rotation;
            
            vec4 mvPosition = modelViewMatrix * vec4(position, 1.0);
            
            // Size attenuates with distance but remains visible
            gl_PointSize = size * (80.0 / -mvPosition.z); // Doubled the size factor
            gl_Position = projectionMatrix * mvPosition;
        }
    `;
    
    const raindropFragmentShader = `
        uniform sampler2D raindropTexture;
        uniform float time;
        
        varying float vRotation;
        
        void main() {
            // Center and rotate UV coordinates
            vec2 uv = gl_PointCoord - 0.5;
            float s = sin(vRotation);
            float c = cos(vRotation);
            uv = vec2(uv.x * c - uv.y * s, uv.x * s + uv.y * c) + 0.5;
            
            // Sample texture
            vec4 raindropColor = texture2D(raindropTexture, uv);
            
            // Apply stronger blue tint and increase brightness
            raindropColor.rgb *= vec3(0.8, 0.9, 1.2) * 1.5;
            
            // Add slight sparkle effect
            float sparkle = sin(time * 20.0 + gl_FragCoord.x * 0.1 + gl_FragCoord.y * 0.1) * 0.1 + 0.9;
            raindropColor.rgb *= sparkle;
            
            // Edge check
            if(uv.x < 0.0 || uv.x > 1.0 || uv.y < 0.0 || uv.y > 1.0) {
                discard;
            }
            
            gl_FragColor = raindropColor;
        }
    `;
    
    const raindropMaterial = new THREE.ShaderMaterial({
        uniforms: {
            raindropTexture: { value: raindropTexture },
            time: { value: 0 }
        },
        vertexShader: raindropVertexShader,
        fragmentShader: raindropFragmentShader,
        transparent: true,
        depthWrite: false,
        blending: THREE.AdditiveBlending // Changed to additive blending for brighter effect
    });
    
    const raindrops = new THREE.Points(raindropGeometry, raindropMaterial);
    scene.add(raindrops);
    
    // Create splash effects
    const maxSplashes = 200; // Maximum number of active splashes
    const splashGeometry = new THREE.BufferGeometry();
    const splashPositions = new Float32Array(maxSplashes * 3);
    const splashSizes = new Float32Array(maxSplashes);
    const splashOpacities = new Float32Array(maxSplashes);
    const splashAges = new Float32Array(maxSplashes);
    
    // Fill with initial values (all hidden)
    for (let i = 0; i < maxSplashes; i++) {
        splashAges[i] = 1.0; // Age of 1.0 means it's ready to be reused
    }
    
    splashGeometry.setAttribute('position', new THREE.BufferAttribute(splashPositions, 3));
    splashGeometry.setAttribute('size', new THREE.BufferAttribute(splashSizes, 1));
    splashGeometry.setAttribute('opacity', new THREE.BufferAttribute(splashOpacities, 1));
    
    // Create splash texture
    const splashCanvas = document.createElement('canvas');
    splashCanvas.width = 128;
    splashCanvas.height = 128;
    const splashCtx = splashCanvas.getContext('2d');
    
    // Draw a radial gradient for the splash
    const gradient = splashCtx.createRadialGradient(64, 64, 0, 64, 64, 64);
    gradient.addColorStop(0, 'rgba(255, 255, 255, 1)');
    gradient.addColorStop(0.3, 'rgba(200, 220, 255, 0.9)');
    gradient.addColorStop(0.7, 'rgba(150, 180, 220, 0.5)');
    gradient.addColorStop(1, 'rgba(100, 150, 200, 0)');
    
    splashCtx.fillStyle = gradient;
    splashCtx.fillRect(0, 0, 128, 128);
    
    // Add glow effect
    splashCtx.shadowColor = '#80A0FF';
    splashCtx.shadowBlur = 20;
    splashCtx.globalCompositeOperation = 'lighter';
    splashCtx.fillStyle = 'rgba(180, 200, 255, 0.5)';
    splashCtx.fillRect(0, 0, 128, 128);
    
    const splashTexture = new THREE.Texture(splashCanvas);
    splashTexture.needsUpdate = true;
    
    // Custom shader for splashes
    const splashVertexShader = `
        attribute float size;
        attribute float opacity;
        
        varying float vOpacity;
        
        void main() {
            vOpacity = opacity;
            
            vec4 mvPosition = modelViewMatrix * vec4(position, 1.0);
            gl_PointSize = size * (30.0 / -mvPosition.z);
            gl_Position = projectionMatrix * mvPosition;
        }
    `;
    
    const splashFragmentShader = `
        uniform sampler2D splashTexture;
        
        varying float vOpacity;
        
        void main() {
            vec4 texColor = texture2D(splashTexture, gl_PointCoord);
            gl_FragColor = vec4(texColor.rgb, texColor.a * vOpacity);
        }
    `;
    
    const splashMaterial = new THREE.ShaderMaterial({
        uniforms: {
            splashTexture: { value: splashTexture }
        },
        vertexShader: splashVertexShader,
        fragmentShader: splashFragmentShader,
        transparent: true,
        depthWrite: false,
        blending: THREE.AdditiveBlending
    });
    
    const splashes = new THREE.Points(splashGeometry, splashMaterial);
    scene.add(splashes);
    
    // Create a subtle fog/mist effect for atmosphere
    const mistCount = 300; // Reduced for better performance
    const mistGeometry = new THREE.BufferGeometry();
    const mistPositions = new Float32Array(mistCount * 3);
    const mistSizes = new Float32Array(mistCount);
    const mistOpacities = new Float32Array(mistCount);
    
    // Initialize mist particles
    function initMist() {
        const { width, height } = getFrustumDimensions();
        
        for (let i = 0; i < mistCount; i++) {
            const i3 = i * 3;
            
            // Position mist near the ground
            mistPositions[i3] = (Math.random() - 0.5) * width * 1.5;
            mistPositions[i3 + 1] = -height/2 + Math.random() * height * 0.3; // Near bottom 30% of screen
            mistPositions[i3 + 2] = (Math.random() - 0.5) * 10 - 5; // In front of other elements
            
            // Varied sizes
            mistSizes[i] = 0.3 + Math.random() * 1.2; // Larger mist particles
            
            // Low opacity
            mistOpacities[i] = 0.05 + Math.random() * 0.1;
        }
    }
    
    initMist();
    
    mistGeometry.setAttribute('position', new THREE.BufferAttribute(mistPositions, 3));
    mistGeometry.setAttribute('size', new THREE.BufferAttribute(mistSizes, 1));
    mistGeometry.setAttribute('opacity', new THREE.BufferAttribute(mistOpacities, 1));
    
    // Create mist texture
    const mistCanvas = document.createElement('canvas');
    mistCanvas.width = 64;
    mistCanvas.height = 64;
    const mistCtx = mistCanvas.getContext('2d');
    
    // Draw a soft gradient for mist
    const mistGradient = mistCtx.createRadialGradient(32, 32, 0, 32, 32, 32);
    mistGradient.addColorStop(0, 'rgba(255, 255, 255, 0.8)');
    mistGradient.addColorStop(0.5, 'rgba(220, 230, 255, 0.3)');
    mistGradient.addColorStop(1, 'rgba(200, 210, 230, 0)');
    
    mistCtx.fillStyle = mistGradient;
    mistCtx.fillRect(0, 0, 64, 64);
    
    const mistTexture = new THREE.Texture(mistCanvas);
    mistTexture.needsUpdate = true;
    
    // Custom shader for mist
    const mistVertexShader = `
        attribute float size;
        attribute float opacity;
        
        varying float vOpacity;
        
        void main() {
            vOpacity = opacity;
            
            vec4 mvPosition = modelViewMatrix * vec4(position, 1.0);
            gl_PointSize = size * (40.0 / -mvPosition.z);
            gl_Position = projectionMatrix * mvPosition;
        }
    `;
    
    const mistFragmentShader = `
        uniform sampler2D mistTexture;
        
        varying float vOpacity;
        
        void main() {
            vec4 texColor = texture2D(mistTexture, gl_PointCoord);
            gl_FragColor = vec4(texColor.rgb, texColor.a * vOpacity);
        }
    `;
    
    const mistMaterial = new THREE.ShaderMaterial({
        uniforms: {
            mistTexture: { value: mistTexture }
        },
        vertexShader: mistVertexShader,
        fragmentShader: mistFragmentShader,
        transparent: true,
        depthWrite: false,
        blending: THREE.AdditiveBlending
    });
    
    const mist = new THREE.Points(mistGeometry, mistMaterial);
    scene.add(mist);
    
    // Position camera
    camera.position.z = 10;
    
    // Handle window resize
    window.addEventListener('resize', () => {
        // Update camera
        camera.aspect = window.innerWidth / window.innerHeight;
        camera.updateProjectionMatrix();
        
        // Update renderer
        renderer.setSize(window.innerWidth, window.innerHeight);
        
        // Recalculate raindrop positions based on new dimensions
        const { width, height } = getFrustumDimensions();
        
        // Reset raindrops that are now out of bounds
        const positionsAttr = raindrops.geometry.getAttribute('position');
        for (let i = 0; i < raindropCount; i++) {
            const i3 = i * 3;
            
            if (Math.abs(positionsAttr.array[i3]) > width/2 ||
                Math.abs(positionsAttr.array[i3 + 1]) > height/2) {
                positionsAttr.array[i3] = (Math.random() - 0.5) * width;
                positionsAttr.array[i3 + 1] = height/2 + Math.random() * 2; // Start above screen
            }
        }
        
        positionsAttr.needsUpdate = true;
        
        // Reinitialize mist based on new dimensions
        initMist();
        mist.geometry.attributes.position.needsUpdate = true;
    });
    
    // Animation loop
    const clock = new THREE.Clock();
    
    const animate = () => {
        const elapsedTime = clock.getElapsedTime();
        const deltaTime = clock.getDelta();
        
        // Update time uniform for shaders
        skyMaterial.uniforms.time.value = elapsedTime;
        raindropMaterial.uniforms.time.value = elapsedTime;
        
        // Animate raindrops
        const { width, height } = getFrustumDimensions();
        const positionsAttr = raindrops.geometry.getAttribute('position');
        const sizesAttr = raindrops.geometry.getAttribute('size');
        
        let splashCreated = false; // Limit to one splash per frame for performance
        
        for (let i = 0; i < raindropCount; i++) {
            const i3 = i * 3;
            
            // Update position - move downward
            positionsAttr.array[i3 + 1] -= raindropVelocities[i] * deltaTime;
            
            // Add slight horizontal drift
            positionsAttr.array[i3] += Math.sin(elapsedTime + i) * 0.003;
            
            // Check if raindrop has hit the ground
            if (positionsAttr.array[i3 + 1] < -height/2) {
                // Create splash effect if we haven't already this frame
                if (!splashCreated && Math.random() < 0.2) { // Only create splash 20% of the time for performance
                    createSplash(positionsAttr.array[i3], -height/2, positionsAttr.array[i3 + 2], raindropSizes[i]);
                    splashCreated = true;
                }
                
                // Reset raindrop to the top
                positionsAttr.array[i3] = (Math.random() - 0.5) * width;
                positionsAttr.array[i3 + 1] = height/2 + Math.random() * 2;
                
                // Randomize z-position sometimes for more variety
                if (Math.random() < 0.1) {
                    positionsAttr.array[i3 + 2] = (Math.random() - 0.5) * 20;
                    
                    // Update size based on new depth
                    const depthFactor = (positionsAttr.array[i3 + 2] + 10) / 20;
                    sizesAttr.array[i] = (0.03 + Math.random() * 0.05) * (0.3 + depthFactor * 0.7);
                    
                    // Update velocity based on new size
                    raindropVelocities[i] = (0.15 + Math.random() * 0.1) * (0.5 + sizesAttr.array[i] * 15);
                }
            }
        }
        
        positionsAttr.needsUpdate = true;
        sizesAttr.needsUpdate = true;
        
        // Update splashes
        updateSplashes(deltaTime);
        
        // Animate mist
        const mistPositionsAttr = mist.geometry.getAttribute('position');
        
        for (let i = 0; i < mistCount; i++) {
            const i3 = i * 3;
            
            // Gentle drifting motion
            mistPositionsAttr.array[i3] += Math.sin(elapsedTime * 0.2 + i) * 0.001;
            mistPositionsAttr.array[i3 + 2] += Math.cos(elapsedTime * 0.2 + i * 0.7) * 0.001;
            
            // Subtle rise and fall
            mistPositionsAttr.array[i3 + 1] += Math.sin(elapsedTime * 0.1 + i * 0.5) * 0.001;
        }
        
        mistPositionsAttr.needsUpdate = true;
        
        // Render the scene
        renderer.render(scene, camera);
        
        // Call animate again on the next frame
        requestAnimationFrame(animate);
    };
    
    // Function to create a splash effect
    function createSplash(x, y, z, size) {
        // Find an available splash slot
        let index = -1;
        for (let i = 0; i < maxSplashes; i++) {
            if (splashAges[i] >= 1.0) {
                index = i;
                break;
            }
        }
        
        // If no slots available, just return
        if (index === -1) return;
        
        const i3 = index * 3;
        
        // Set position slightly above ground for better visibility
        splashPositions[i3] = x;
        splashPositions[i3 + 1] = y + 0.02;
        splashPositions[i3 + 2] = z;
        
        // Size based on raindrop size
        splashSizes[index] = size * 10;
        
        // Reset age
        splashAges[index] = 0;
        
        // Full opacity to start
        splashOpacities[index] = 0.7;
        
        // Update attributes
        const positionsAttr = splashes.geometry.getAttribute('position');
        const sizesAttr = splashes.geometry.getAttribute('size');
        const opacitiesAttr = splashes.geometry.getAttribute('opacity');
        
        positionsAttr.needsUpdate = true;
        sizesAttr.needsUpdate = true;
        opacitiesAttr.needsUpdate = true;
    }
    
    // Function to update all splash effects
    function updateSplashes(deltaTime) {
        const positionsAttr = splashes.geometry.getAttribute('position');
        const sizesAttr = splashes.geometry.getAttribute('size');
        const opacitiesAttr = splashes.geometry.getAttribute('opacity');
        
        for (let i = 0; i < maxSplashes; i++) {
            // Skip fully aged splashes
            if (splashAges[i] >= 1.0) continue;
            
            // Update age
            splashAges[i] += deltaTime * 3; // Splash lasts 1/3 of a second
            
            // Expand size as it ages
            sizesAttr.array[i] = splashSizes[i] * (0.7 + splashAges[i] * 0.3);
            
            // Fade out opacity
            opacitiesAttr.array[i] = splashOpacities[i] * (1.0 - splashAges[i]);
        }
        
        sizesAttr.needsUpdate = true;
        opacitiesAttr.needsUpdate = true;
    }
    
    // Start animation
    animate();
};

// Function to setup the background canvas for the entire page
const setupPageBackground = () => {
    // Check if we already have a canvas
    let canvas = document.getElementById('bg-canvas');
    
    // If no canvas exists, create one
    if (!canvas) {
        canvas = document.createElement('canvas');
        canvas.id = 'bg-canvas';
        
        // Set canvas styles for fullscreen background
        canvas.style.position = 'fixed';
        canvas.style.top = '0';
        canvas.style.left = '0';
        canvas.style.width = '100%';
        canvas.style.height = '100%';
        canvas.style.zIndex = '-1';
        canvas.style.pointerEvents = 'none'; // Allow clicks to pass through
    }
    
    // Add the canvas to the body as a fixed background
    if (canvas.parentElement !== document.body) {
        document.body.appendChild(canvas);
    }
    
    return canvas;
};

// Add CSS to make content readable over the rainy background
const addBackgroundCSS = () => {
    // Create a style element if it doesn't exist
    let style = document.getElementById('background-styles');
    if (!style) {
        style = document.createElement('style');
        style.id = 'background-styles';
        document.head.appendChild(style);
        
        // Add CSS rules
        style.textContent = `
            body {
                background-color: #050a10 !important;
                position: relative;
                z-index: 1;
                color: #fff;
            }
            
            main, article, section, .content, .container {
                position: relative;
                z-index: 1;
                background-color: rgba(10, 20, 30, 0.7);
                padding: 20px;
                border-radius: 5px;
                box-shadow: 0 4px 15px rgba(0, 0, 0, 0.5);
            }
            
            h1, h2, h3, h4, h5, h6 {
                color: #ffffff;
                text-shadow: 0 0 10px rgba(100, 150, 255, 0.5);
            }
            
            a {
                color: #7FDBFF;
                text-shadow: 0 0 5px rgba(127, 219, 255, 0.5);
            }
            
            /* Style adjustments for text contrast */
            p, li, span, div {
                text-shadow: 0 0 5px rgba(0, 0, 0, 0.9);
            }
            
            /* Add a subtle background to text containers */
            article, .content, .container, .card, .post {
                
                -webkit-backdrop-filter: blur(5px);
                margin-bottom: 20px;
                border: 1px solid rgba(100, 150, 255, 0.2);
            }
            
            /* Water drop effect on hovering over containers */
            article:hover, .content:hover, .container:hover, .card:hover, .post:hover {
                box-shadow: 0 0 20px rgba(100, 150, 255, 0.3);
                border: 1px solid rgba(100, 150, 255, 0.4);
                transition: box-shadow 0.3s ease, border 0.3s ease;
            }
            
            /* Style form elements */
            input, textarea, select, button {
                background-color: rgba(20, 30, 40, 0.8);
                border: 1px solid rgba(100, 150, 255, 0.5);
                color: #fff;
            }
            
            button, .button, input[type="submit"] {
                background-color: rgba(40, 80, 120, 0.7);
                color: white;
                border: 1px solid rgba(100, 150, 255, 0.7);
                text-shadow: 0 0 3px rgba(0, 0, 0, 0.5);
            }
            
            /* Style scrollbars to match theme */
            ::-webkit-scrollbar {
                width: 12px;
                background-color: rgba(10, 20, 30, 0.6);
            }
            
            ::-webkit-scrollbar-thumb {
                background-color: rgba(100, 150, 255, 0.4);
                border-radius: 6px;
            }
            
            ::-webkit-scrollbar-thumb:hover {
                background-color: rgba(100, 150, 255, 0.6);
            }
        `;
    }
};

// Initialize on DOM load
document.addEventListener('DOMContentLoaded', () => {
    setupPageBackground();
    addBackgroundCSS();
    initRainfallBackground();
    
    // Add a mutation observer to ensure the background works on dynamically loaded pages
    const observer = new MutationObserver((mutations) => {
        let needsReattach = false;
        
        mutations.forEach(mutation => {
            if (mutation.type === 'childList') {
                // Check if our canvas was removed
                const canvas = document.getElementById('bg-canvas');
                if (!canvas || !document.body.contains(canvas)) {
                    needsReattach = true;
                }
            }
        });
        
        if (needsReattach) {
            setupPageBackground();
            initRainfallBackground();
        }
    });
    
    // Start observing the document body for changes
    observer.observe(document.body, {
        childList: true,
        subtree: true
    });
});