window.sketch = (p) => {
  let particles = [];
  let noiseScale = 0.02;
  let hueOffset = 0;

  p.setup = () => {
    p.createCanvas(p.windowWidth, p.windowHeight);
    p.colorMode(p.HSB, 360, 100, 100, 1);
    p.noStroke();

    for (let i = 0; i < 150; i++) {
      particles.push({
        x: p.random(p.width),
        y: p.random(p.height),
        size: p.random(5, 20),
        baseHue: p.random(0, 360),
        speed: p.random(0.5, 2),
        angle: p.random(p.TWO_PI),
        noiseOffsetX: p.random(1000),
        noiseOffsetY: p.random(1000),
        isStructured: p.random() > 0.5
      });
    }
  };

  p.draw = () => {
    p.background(0, 0, 10, 0.1);

    hueOffset = (hueOffset + 0.5) % 360;

    particles.forEach(particle => {
      if (particle.isStructured) {
        particle.angle += 0.01;
        particle.x = p.width / 2 + p.cos(particle.angle * particle.speed) * (p.width / 3 + p.sin(hueOffset * 0.01) * 50);
        particle.y = p.height / 2 + p.sin(particle.angle * particle.speed * 1.3) * (p.height / 3 + p.cos(hueOffset * 0.01) * 50);
      } else {
        particle.x = p.noise(particle.noiseOffsetX + p.frameCount * noiseScale) * p.width;
        particle.y = p.noise(particle.noiseOffsetY + p.frameCount * noiseScale) * p.height;
      }

      let hue = (particle.baseHue + hueOffset + p.sin(p.frameCount * 0.05) * 60) % 360;
      let saturation = particle.isStructured ? 80 : 60;
      let brightness = particle.isStructured ? 90 : 70;
      let alpha = particle.isStructured ? 0.8 : 0.5;

      p.fill(hue, saturation, brightness, alpha);

      if (particle.isStructured) {
        p.push();
        p.translate(particle.x, particle.y);
        p.rotate(particle.angle * 2);
        p.rectMode(p.CENTER);
        p.rect(0, 0, particle.size * 1.5, particle.size * 0.8);
        p.pop();
      } else {
        p.ellipse(particle.x, particle.y, particle.size);
      }
    });
  };

  p.windowResized = () => {
    p.resizeCanvas(p.windowWidth, p.windowHeight);
  };
};
