window.sketch = (p) => {
  let people = [];
  const maxPeople = 80;

  p.setup = () => {
    p.createCanvas(p.windowWidth, p.windowHeight);
    // Initialize crowd
    for (let i = 0; i < maxPeople; i++) {
      people.push(createPerson(true));
    }
  };

  p.draw = () => {
    p.background(30, 40, 50, 40); // slight trail for motion blur

    // Update and draw each person
    for (let i = people.length - 1; i >= 0; i--) {
      const person = people[i];
      person.x += person.speed;
      person.y += p.sin(p.frameCount * 0.02 + person.phase) * 0.3;

      // Draw person as a stylized figure
      drawPerson(person);

      // Wrap around when off screen (infinite loop)
      if (person.x > p.width + 30) {
        person.x = -30;
        person.y = p.random(p.height * 0.2, p.height * 0.8);
        person.speed = p.random(0.8, 2.2);
        person.phase = p.random(p.TWO_PI);
        person.color = p.color(
          p.random(100, 220),
          p.random(80, 180),
          p.random(60, 160)
        );
        person.bodyLength = p.random(12, 22);
        person.legPhase = p.random(p.TWO_PI);
      }
    }

    // Ensure we always have enough people (respawn if lost)
    while (people.length < maxPeople) {
      people.push(createPerson(false));
    }
  };

  function createPerson(randomX) {
    return {
      x: randomX ? p.random(-30, p.width + 30) : p.random(-30, 0),
      y: p.random(p.height * 0.2, p.height * 0.8),
      speed: p.random(0.8, 2.2),
      phase: p.random(p.TWO_PI),
      legPhase: p.random(p.TWO_PI),
      bodyLength: p.random(12, 22),
      color: p.color(
        p.random(100, 220),
        p.random(80, 180),
        p.random(60, 160)
      ),
      headSize: p.random(5, 9),
    };
  }

  function drawPerson(person) {
    const x = person.x;
    const y = person.y;
    const body = person.bodyLength;
    const headR = person.headSize;

    p.push();
    p.translate(x, y);

    // Body (torso)
    p.stroke(person.color);
    p.strokeWeight(3);
    p.line(0, 0, 0, body);

    // Head (circle with skin tone hint)
    p.fill(person.color);
    p.noStroke();
    p.circle(0, -headR - 2, headR * 2);

    // Arms (swinging with walk cycle)
    const armAngle = p.sin(p.frameCount * 0.08 + person.phase) * 0.4;
    p.stroke(person.color);
    p.strokeWeight(2);
    p.line(0, 2, 8 * p.cos(armAngle), 2 + 8 * p.sin(armAngle));
    p.line(0, 2, -8 * p.cos(armAngle), 2 - 8 * p.sin(armAngle));

    // Legs (moving with walk cycle)
    const legSwing = p.sin(p.frameCount * 0.08 + person.legPhase) * 0.3;
    p.strokeWeight(2.5);
    p.line(0, body, 6 * p.cos(legSwing), body + 10);
    p.line(0, body, -6 * p.cos(legSwing), body + 10);

    // Small detail: bag or briefcase for some people
    if (person.speed > 1.5) {
      p.fill(person.color);
      p.noStroke();
      p.rect(6, 3, 4, 6);
    }

    p.pop();
  }

  p.windowResized = () => {
    p.resizeCanvas(p.windowWidth, p.windowHeight);
    // Reposition people to fit new canvas
    for (let person of people) {
      person.y = p.constrain(person.y, p.height * 0.2, p.height * 0.8);
    }
  };
};
