---
---

<canvas id="shader-canvas" class="hidden lg:block absolute inset-0 w-full h-full dark:opacity-90 z-10 pointer-events-none"></canvas>

<script>
  const canvas = document.getElementById('shader-canvas') as HTMLCanvasElement | null;
  if (!canvas) {
    console.error('Canvas element not found');
  } else {
    const gl = canvas.getContext('webgl', { alpha: true });

    if (!gl) {
      console.error('WebGL not supported!');
    } else {
      const vertexShaderSource = `
        attribute vec2 a_position;
        void main() {
          gl_Position = vec4(a_position, 0.0, 1.0);
        }
      `;

      const fragmentShaderSource = `
        precision mediump float;
        uniform vec2 iResolution;
        uniform float iTime;
        uniform vec3 u_color1;
        uniform vec3 u_color2;
        #define iterations 2

        void main() {
            vec2 uv = gl_FragCoord.xy / iResolution.xy;
            vec2 mirrored_uv = uv;

            if (mirrored_uv.x > 0.5) {
                mirrored_uv.x = 1.0 - mirrored_uv.x;
            }

            float res = 1.0;
            for (int i = 0; i < iterations; i++) {
                res += cos(mirrored_uv.y * 12.345 - iTime * 1.0 + cos(res * 12.234) * 0.2 + cos(mirrored_uv.x * 32.2345 + cos(mirrored_uv.y * 17.234))) + cos(mirrored_uv.x * 12.345);
            }

            vec3 c = mix(u_color1, u_color2, cos(res + cos(mirrored_uv.y * 24.3214) * 0.1 + cos(mirrored_uv.x * 6.324 + iTime * 1.0) + iTime) * 0.5 + 0.5);
            float vignette = clamp((length(mirrored_uv - 0.1 + cos(iTime * 0.9 + mirrored_uv.yx * 4.34 + mirrored_uv.xy * res) * 0.2) * 5.0 - 0.4), 0.0, 1.0);
            vec3 final_color = mix(c, vec3(0.0), vignette);
            gl_FragColor = vec4(final_color, length(final_color));
        }
      `;

      function createShader(context: WebGLRenderingContext, type: number, source: string): WebGLShader | null {
        const shader = context.createShader(type);
        if (!shader) return null;
        
        context.shaderSource(shader, source);
        context.compileShader(shader);
        
        if (!context.getShaderParameter(shader, context.COMPILE_STATUS)) {
          console.error('Shader compilation error:', context.getShaderInfoLog(shader));
          context.deleteShader(shader);
          return null;
        }
        return shader;
      }

      const vertexShader = createShader(gl, gl.VERTEX_SHADER, vertexShaderSource);
      const fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fragmentShaderSource);
      
      if (vertexShader && fragmentShader) {
        const program = gl.createProgram();
        if (program) {
          gl.attachShader(program, vertexShader);
          gl.attachShader(program, fragmentShader);
          gl.linkProgram(program);

          if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
            console.error('Program linking error:', gl.getProgramInfoLog(program));
          } else {
            gl.useProgram(program);

            const positionBuffer = gl.createBuffer();
            gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
            const positions = [-1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1];
            gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);

            const positionAttributeLocation = gl.getAttribLocation(program, "a_position");
            gl.enableVertexAttribArray(positionAttributeLocation);
            gl.vertexAttribPointer(positionAttributeLocation, 2, gl.FLOAT, false, 0, 0);

            const resolutionLocation = gl.getUniformLocation(program, "iResolution");
            const timeLocation = gl.getUniformLocation(program, "iTime");
            const color1Location = gl.getUniformLocation(program, "u_color1");
            const color2Location = gl.getUniformLocation(program, "u_color2");

            const color1 = [0.122, 0.502, 0.122]; // #1f801f
            const color2 = [0.059, 0.251, 0.059]; // #0f400f

            function render(time: number): void {
              if (!gl || !program || !canvas) return;
              
              time *= 0.001;

              const displayWidth = canvas.clientWidth;
              const displayHeight = canvas.clientHeight;
              
              if (canvas.width !== displayWidth || canvas.height !== displayHeight) {
                canvas.width = displayWidth;
                canvas.height = displayHeight;
                gl.viewport(0, 0, canvas.width, canvas.height);
              }

              gl.clearColor(0, 0, 0, 0);
              gl.clear(gl.COLOR_BUFFER_BIT);

              gl.useProgram(program);
              
              if (resolutionLocation !== null) {
                gl.uniform2f(resolutionLocation, canvas.width, canvas.height);
              }
              if (timeLocation !== null) {
                gl.uniform1f(timeLocation, time);
              }
              if (color1Location !== null) {
                gl.uniform3fv(color1Location, color1);
              }
              if (color2Location !== null) {
                gl.uniform3fv(color2Location, color2);
              }

              gl.drawArrays(gl.TRIANGLES, 0, 6);
              requestAnimationFrame(render);
            }
            
            requestAnimationFrame(render);
          }
        }
      }
    }
  }
</script>