window.sketch = (runtime) => {
  const { c2, canvas, startFrame } = runtime;
  const renderer = new c2.Renderer(canvas);

  const people = [];
  const NUM_PEOPLE = 22;

  const skinTones = ['#f4d3b3', '#e6bf94', '#d4a373', '#c68863', '#b07a52', '#8b5a3c', '#f0c9a0', '#dcb393'];
  const shirtColors = ['#c0392b', '#2980b9', '#27ae60', '#f39c12', '#8e44ad', '#16a085', '#d35400', '#2c3e50', '#a93226', '#1f618d', '#196f3d', '#b9770e', '#6c3483', '#117a65', '#922b21', '#7d6608', '#34495e', '#e74c3c', '#2874a6', '#239b56'];
  const pantsColors = ['#1a1a2e', '#16213e', '#0f3460', '#1b1b3a', '#2c2c54', '#3a3a5c', '#1f1f3d'];
  const hairColors = ['#0d0d0d', '#1a1a1a', '#2b1b17', '#3b2f2f', '#4a3728', '#241a14'];

  class Person {
    constructor() {
      this.x = Math.random() * canvas.width;
      this.y = canvas.height + Math.random() * canvas.height;
      this.speed = 0.3 + Math.random() * 0.5;
      this.walkPhase = Math.random() * Math.PI * 2;
      this.skin = skinTones[Math.floor(Math.random() * skinTones.length)];
      this.shirt = shirtColors[Math.floor(Math.random() * shirtColors.length)];
      this.pants = pantsColors[Math.floor(Math.random() * pantsColors.length)];
      this.hair = hairColors[Math.floor(Math.random() * hairColors.length)];
      this.height = 38 + Math.random() * 18;
      this.width = 14 + Math.random() * 6;
      this.hasBag = Math.random() > 0.55;
      this.bagSide = Math.random() > 0.5 ? 1 : -1;
      this.bagColor = shirtColors[Math.floor(Math.random() * shirtColors.length)];
      this.armSwing = 0.4 + Math.random() * 0.3;
      this.legSwing = 0.35 + Math.random() * 0.25;
      this.hairStyle = Math.floor(Math.random() * 4);
      this.headTilt = (Math.random() - 0.5) * 0.2;
    }

    update(frameCount) {
      this.y -= this.speed;
      this.walkPhase += 0.12;
      if (this.y < -this.height * 3) {
        this.y = canvas.height + 50 + Math.random() * 100;
        this.x = Math.random() * canvas.width;
      }
    }

    draw(frameCount) {
      const px = this.x;
      const py = this.y;
      const sw = this.walkPhase;
      const sinL = Math.sin(sw);
      const sinR = Math.sin(sw + Math.PI);
      const cosL = Math.cos(sw);
      const cosR = Math.cos(sw + Math.PI);

      // Shadow
      renderer.fill('rgba(0,0,0,0.25)');
      renderer.ellipse(px, py + 2, this.width * 0.9, 4);

      // Legs
      renderer.fill(this.pants);
      // Left leg
      renderer.rect(px - this.width * 0.35, py - this.height * 0.45, this.width * 0.3, this.height * 0.45 + sinL * this.legSwing * 3);
      // Right leg
      renderer.rect(px + this.width * 0.05, py - this.height * 0.45, this.width * 0.3, this.height * 0.45 + sinR * this.legSwing * 3);

      // Shoes
      renderer.fill('#1a1a1a');
      renderer.ellipse(px - this.width * 0.2, py + sinL * this.legSwing * 3, 4, 2);
      renderer.ellipse(px + this.width * 0.2, py + sinR * this.legSwing * 3, 4, 2);

      // Torso (shirt)
      renderer.fill(this.shirt);
      renderer.rect(px - this.width * 0.5, py - this.height * 0.95, this.width, this.height * 0.5);

      // Arms
      renderer.fill(this.shirt);
      // Left arm
      const lAx = px - this.width * 0.6 + sinL * this.armSwing * 4;
      const lAy = py - this.height * 0.85 + Math.abs(sinL) * this.armSwing * 2;
      renderer.rect(lAx, lAy, this.width * 0.2, this.height * 0.4);
      // Right arm
      const rAx = px + this.width * 0.4 + sinR * this.armSwing * 4;
      const rAy = py - this.height * 0.85 + Math.abs(sinR) * this.armSwing * 2;
      renderer.rect(rAx, rAy, this.width * 0.2, this.height * 0.4);

      // Hands
      renderer.fill(this.skin);
      renderer.circle(lAx + this.width * 0.1, lAy + this.height * 0.4, 2.2);
      renderer.circle(rAx + this.width * 0.1, rAy + this.height * 0.4, 2.2);

      // Bag
      if (this.hasBag) {
        const bagX = this.bagSide > 0 ? rAx - 2 : lAx + this.width * 0.1;
        const bagY = rAy + this.height * 0.1;
        renderer.fill(this.bagColor);
        renderer.rect(bagX, bagY, 5, 7);
        renderer.stroke(this.bagColor);
        renderer.lineWidth(0.5);
        renderer.line(bagX, bagY, bagX + 2.5, bagY - 3);
        renderer.line(bagX + 5, bagY, bagX + 2.5, bagY - 3);
      }

      // Neck
      renderer.fill(this.skin);
      renderer.rect(px - 2.5, py - this.height, 5, 5);

      // Head
      const headY = py - this.height - 5;
      renderer.fill(this.skin);
      renderer.ellipse(px, headY, 5.5, 6.5);

      // Hair
      renderer.fill(this.hair);
      if (this.hairStyle === 0) {
        // Short
        renderer.ellipse(px, headY - 3, 6, 4);
        renderer.rect(px - 5.5, headY - 4, 11, 3);
      } else if (this.hairStyle === 1) {
        // Bowl cut
        renderer.ellipse(px, headY - 2, 6.5, 5);
        renderer.rect(px - 6, headY - 5, 12, 5);
      } else if (this.hairStyle === 2) {
        // Slightly longer
        renderer.ellipse(px, headY - 2, 6.5, 5);
        renderer.rect(px - 6.5, headY - 5, 13, 5);
        renderer.rect(px - 6.5, headY, 2, 5);
        renderer.rect(px + 4.5, headY, 2, 5);
      } else {
        // Side parted
        renderer.ellipse(px, headY - 2, 6.5, 4.5);
        renderer.rect(px - 6, headY - 4, 12, 3);
      }

      // Eyes
      renderer.fill('#0a0a0a');
      renderer.circle(px - 1.8, headY + 0.5, 0.7);
      renderer.circle(px + 1.8, headY + 0.5, 0.7);

      // Subtle smile
      renderer.stroke('#3a1f1f');
      renderer.lineWidth(0.4);
      renderer.line(px - 1.5, headY + 3, px + 1.5, headY + 3);
    }
  }

  for (let i = 0; i < NUM_PEOPLE; i++) {
    const p = new Person();
    p.y = Math.random() * canvas.height;
    people.push(p);
  }

  // Background buildings
  const buildings = [];
  for (let i = 0; i < 12; i++) {
    buildings.push({
      x: i * (canvas.width / 8) + Math.random() * 30,
      y: 0,
      w: 40 + Math.random() * 60,
      h: 80 + Math.random() * 150,
      color: ['#3d2e2a', '#4a3a35', '#5c4540', '#3a2820', '#443532'][Math.floor(Math.random() * 5)],
      windows: Math.floor(Math.random() * 8) + 3
    });
  }

  // Lanterns
  const lanterns = [];
  for (let i = 0; i < 6; i++) {
    lanterns.push({
      x: (canvas.width / 6) * i + 30,
      y: 40 + Math.random() * 30,
      phase: Math.random() * Math.PI * 2
    });
  }

  // Signage
  const signs = [];
  const signTexts = ['茶', '麺', '寿司', '飯', '酒', '屋', '食', '店'];
  for (let i = 0; i < 5; i++) {
    signs.push({
      x: Math.random() * canvas.width,
      y: 60 + Math.random() * 80,
      text: signTexts[Math.floor(Math.random() * signTexts.length)],
      color: ['#ff6b35', '#ffd23f', '#ee4266', '#06aed5'][Math.floor(Math.random() * 4)]
    });
  }

  startFrame((frameCount) => {
    renderer.clear('#1a1410');

    // Sky gradient effect
    renderer.fill('#2a1f1a');
    renderer.rect(0, 0, canvas.width, canvas.height * 0.4);
    renderer.fill('#3a2820');
    renderer.rect(0, canvas.height * 0.4, canvas.width, canvas.height * 0.2);

    // Ground/street
    renderer.fill('#1f1812');
    renderer.rect(0, canvas.height * 0.6, canvas.width, canvas.height * 0.4);

    // Street lines
    renderer.fill('#3a2a1a');
    for (let i = 0; i < 8; i++) {
      const ly = canvas.height * 0.6 + i * (canvas.height * 0.4 / 8);
      renderer.rect(0, ly, canvas.width, 1);
    }

    // Buildings
    for (const b of buildings) {
      renderer.fill(b.color);
      renderer.rect(b.x, b.y, b.w, b.h);

      // Windows
      const lit = (b.x * 13 + frameCount * 0.01) % 100 < 50;
      for (let wy = 15; wy < b.h - 20; wy += 22) {
        for (let wx = 8; wx < b.w - 8; wx += 14) {
          const flicker = Math.sin(frameCount * 0.02 + wx + wy) > -0.3;
          if (flicker) {
            renderer.fill('rgba(255,200,120,0.6)');
            renderer.rect(b.x + wx, b.y + wy, 6, 8);
          } else {
            renderer.fill('rgba(40,30,20,0.8)');
            renderer.rect(b.x + wx, b.y + wy, 6, 8);
          }
        }
      }
    }

    // Lanterns
    for (const l of lanterns) {
      const swing = Math.sin(frameCount * 0.02 + l.phase) * 3;
      const glow = 0.7 + Math.sin(frameCount * 0.05 + l.phase) * 0.3;

      // String
      renderer.stroke('#2a1f1a');
      renderer.lineWidth(0.5);
      renderer.line(l.x, 0, l.x + swing, l.y);

      // Lantern body
      renderer.fill(`rgba(255,80,40,${glow})`);
      renderer.ellipse(l.x + swing, l.y, 8, 10);
      renderer.fill(`rgba(255,140,60,${glow * 0.8})`);
      renderer.ellipse(l.x + swing, l.y, 5, 6);

      // Top cap
      renderer.fill('#1a0f0a');
      renderer.rect(l.x + swing - 4, l.y - 11, 8, 2);
      // Tassel
      renderer.fill('#cc4422');
      renderer.rect(l.x + swing - 0.5, l.y + 9, 1, 4);
    }

    // Signs
    renderer.fontSize(18);
    for (const s of signs) {
      renderer.fill(s.color);
      renderer.text(s.text, s.x, s.y);
    }

    // Steam/fog wisps
    for (let i = 0; i < 4; i++) {
      const sx = (frameCount * 0.3 + i * 80) % (canvas.width + 40) - 20;
      const sy = canvas.height * 0.55 - Math.sin(frameCount * 0.02 + i) * 10;
      renderer.fill('rgba(200,180,170,0.06)');
      renderer.circle(sx, sy, 15 + Math.sin(frameCount * 0.03 + i) * 5);
    }

    // Sort people by y for depth
    people.sort((a, b) => a.y - b.y);

    // Update and draw people
    for (const p of people) {
      p.update(frameCount);
      p.draw(frameCount);
    }

    // Foreground silhouette figures (very close)
    renderer.fill('rgba(10,5,5,0.6)');
    for (let i = 0; i < 3; i++) {
      const fx = (frameCount * 0.8 + i * 200) % (canvas.width + 100) - 50;
      const fy = canvas.height - 40;
      renderer.rect(fx, fy, 20, 30);
      renderer.circle(fx + 10, fy - 8, 9);
    }
  });
};
