(function () {
  const canvas = document.getElementById("galaxy");
  if (!canvas) return;
  const ctx = canvas.getContext("2d");

  let W = 0, H = 0, DPR = 1;
  let stars = [];
  let shooters = [];

  function resize() {
    DPR = Math.min(window.devicePixelRatio || 1, 2);
    W = canvas.clientWidth = window.innerWidth;
    H = canvas.clientHeight = window.innerHeight;
    canvas.width = Math.floor(W * DPR);
    canvas.height = Math.floor(H * DPR);
    ctx.setTransform(DPR, 0, 0, DPR, 0, 0);
    buildStars();
  }

  function buildStars() {
    const area = W * H;
    const count = Math.min(280, Math.max(120, Math.floor(area / 6000)));
    stars = [];
    for (let i = 0; i < count; i++) {
      stars.push(makeStar());
    }
  }

  function makeStar() {
    const r = Math.random();
    // 30% colored (purple/pink), 70% white-ish
    let hue = null;
    if (r < 0.18) hue = 280 + Math.random() * 35;       // purple
    else if (r < 0.30) hue = 320 + Math.random() * 25;  // pink
    const size = Math.pow(Math.random(), 2.4) * 1.6 + 0.25;
    return {
      x: Math.random() * W,
      y: Math.random() * H,
      size,
      drift: (Math.random() * 0.04 + 0.005) * (size > 0.8 ? 1 : 0.5),
      phase: Math.random() * Math.PI * 2,
      twinkle: Math.random() * 0.015 + 0.004,
      baseAlpha: 0.35 + Math.random() * 0.55,
      hue,
    };
  }

  function maybeSpawnShooter() {
    // ~1 shooter every 6–12 seconds on average
    if (Math.random() < 0.0015 && shooters.length < 2) {
      const fromLeft = Math.random() < 0.5;
      const startX = fromLeft ? -40 : W + 40;
      const startY = Math.random() * H * 0.6;
      const angle = (fromLeft ? 1 : -1) * (Math.PI / 5 + Math.random() * Math.PI / 8);
      const speed = 7 + Math.random() * 5;
      shooters.push({
        x: startX,
        y: startY,
        vx: Math.cos(angle) * speed * (fromLeft ? 1 : -1),
        vy: Math.sin(angle) * speed,
        life: 1,
        trail: [],
      });
    }
  }

  function drawStar(s) {
    s.phase += s.twinkle;
    const flicker = 0.5 + 0.5 * Math.sin(s.phase);
    const a = s.baseAlpha * (0.55 + 0.45 * flicker);

    // Soft halo for larger stars
    if (s.size > 0.9) {
      const haloR = s.size * 5;
      const grad = ctx.createRadialGradient(s.x, s.y, 0, s.x, s.y, haloR);
      const haloColor = s.hue
        ? `hsla(${s.hue}, 90%, 70%, ${a * 0.35})`
        : `rgba(200, 180, 255, ${a * 0.25})`;
      grad.addColorStop(0, haloColor);
      grad.addColorStop(1, "rgba(0,0,0,0)");
      ctx.fillStyle = grad;
      ctx.beginPath();
      ctx.arc(s.x, s.y, haloR, 0, Math.PI * 2);
      ctx.fill();
    }

    // Core
    ctx.beginPath();
    ctx.arc(s.x, s.y, s.size, 0, Math.PI * 2);
    if (s.hue) {
      ctx.fillStyle = `hsla(${s.hue}, 95%, 78%, ${a})`;
    } else {
      ctx.fillStyle = `rgba(240, 232, 255, ${a})`;
    }
    ctx.fill();
  }

  function drawShooter(sh) {
    sh.trail.push({ x: sh.x, y: sh.y });
    if (sh.trail.length > 20) sh.trail.shift();

    // Draw fading trail
    for (let i = 0; i < sh.trail.length; i++) {
      const t = sh.trail[i];
      const a = (i / sh.trail.length) * 0.7 * sh.life;
      ctx.beginPath();
      ctx.arc(t.x, t.y, 1.2 + (i / sh.trail.length) * 1.5, 0, Math.PI * 2);
      ctx.fillStyle = `rgba(220, 180, 255, ${a})`;
      ctx.fill();
    }

    // Head
    const grad = ctx.createRadialGradient(sh.x, sh.y, 0, sh.x, sh.y, 8);
    grad.addColorStop(0, `rgba(255, 255, 255, ${sh.life})`);
    grad.addColorStop(0.4, `rgba(220, 180, 255, ${sh.life * 0.6})`);
    grad.addColorStop(1, "rgba(180, 120, 255, 0)");
    ctx.fillStyle = grad;
    ctx.beginPath();
    ctx.arc(sh.x, sh.y, 8, 0, Math.PI * 2);
    ctx.fill();

    sh.x += sh.vx;
    sh.y += sh.vy;
    sh.life -= 0.012;
  }

  function tick() {
    ctx.clearRect(0, 0, W, H);

    for (const s of stars) {
      s.y += s.drift;
      if (s.y > H + 4) {
        s.y = -4;
        s.x = Math.random() * W;
      }
      drawStar(s);
    }

    maybeSpawnShooter();
    for (let i = shooters.length - 1; i >= 0; i--) {
      const sh = shooters[i];
      drawShooter(sh);
      if (sh.life <= 0 || sh.x < -100 || sh.x > W + 100 || sh.y > H + 100) {
        shooters.splice(i, 1);
      }
    }

    requestAnimationFrame(tick);
  }

  resize();
  window.addEventListener("resize", resize);
  requestAnimationFrame(tick);
})();
