{"version":3,"sources":["../src/core/utils.ts","../src/core/engine.ts","../src/core/particle.ts","../src/core/imageLoader.ts","../src/core/effects/fairyDust.ts","../src/core/effects/sparkle.ts","../src/core/effects/confetti.ts","../src/core/effects/retroCRT.ts","../src/core/effects/snow.ts","../src/core/effects/bubble.ts"],"names":["DEFAULT_COLORS"],"mappings":"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","file":"chunk-5ZV2U5LA.mjs","sourcesContent":["export function randomColor(colors: string[]): string {\n  return colors[Math.floor(Math.random() * colors.length)];\n}\n\nexport function randomRange(min: number, max: number): number {\n  return Math.random() * (max - min) + min;\n}\n\nexport function createCanvas(container: HTMLElement): HTMLCanvasElement {\n  const canvas = document.createElement('canvas');\n  canvas.style.position = 'fixed';\n  canvas.style.top = '0';\n  canvas.style.left = '0';\n  canvas.style.pointerEvents = 'none';\n  canvas.style.zIndex = '9999';\n  canvas.width = window.innerWidth;\n  canvas.height = window.innerHeight;\n  container.appendChild(canvas);\n  return canvas;\n}\n\nexport function resizeCanvas(canvas: HTMLCanvasElement): void {\n  canvas.width = window.innerWidth;\n  canvas.height = window.innerHeight;\n}\n\nexport function drawStar(\n  ctx: CanvasRenderingContext2D,\n  x: number,\n  y: number,\n  size: number,\n  spikes: number = 5\n): void {\n  const outerRadius = size;\n  const innerRadius = size * 0.4;\n\n  ctx.beginPath();\n  for (let i = 0; i < spikes * 2; i++) {\n    const angle = (i * Math.PI) / spikes;\n    const radius = i % 2 === 0 ? outerRadius : innerRadius;\n    const dx = Math.cos(angle) * radius;\n    const dy = Math.sin(angle) * radius;\n\n    if (i === 0) {\n      ctx.moveTo(x + dx, y + dy);\n    } else {\n      ctx.lineTo(x + dx, y + dy);\n    }\n  }\n  ctx.closePath();\n  ctx.fill();\n}\n\nexport function drawRectangle(\n  ctx: CanvasRenderingContext2D,\n  x: number,\n  y: number,\n  width: number,\n  height: number\n): void {\n  ctx.fillRect(x - width / 2, y - height / 2, width, height);\n}\n\nexport function drawSnowflake(\n  ctx: CanvasRenderingContext2D,\n  x: number,\n  y: number,\n  size: number,\n  rotation: number = 0\n): void {\n  ctx.save();\n  ctx.translate(x, y);\n  ctx.rotate(rotation);\n\n  // Optimized glow - reduced blur for better performance\n  ctx.shadowBlur = 4;\n  ctx.shadowColor = '#FFFFFF';\n  ctx.lineWidth = 1.8; // Slightly thicker for better visibility\n\n  // Draw all 6 arms in a single path for better performance\n  ctx.beginPath();\n  for (let i = 0; i < 6; i++) {\n    const angle = (i * Math.PI) / 3;\n    ctx.moveTo(0, 0);\n    ctx.lineTo(Math.cos(angle) * size, Math.sin(angle) * size);\n  }\n  ctx.stroke();\n\n  ctx.restore();\n}\n\nexport function drawBubble(\n  ctx: CanvasRenderingContext2D,\n  x: number,\n  y: number,\n  size: number\n): void {\n  // Save the original fill color\n  const baseColor = ctx.fillStyle as string;\n\n  // Main bubble with multi-layer gradient for depth\n  const mainGradient = ctx.createRadialGradient(x - size * 0.25, y - size * 0.25, 0, x, y, size);\n  mainGradient.addColorStop(0, 'rgba(255, 255, 255, 0.3)');\n  mainGradient.addColorStop(0.3, baseColor);\n  mainGradient.addColorStop(0.7, baseColor);\n  mainGradient.addColorStop(1, 'rgba(255, 255, 255, 0.1)');\n\n  ctx.beginPath();\n  ctx.arc(x, y, size, 0, Math.PI * 2);\n  ctx.fillStyle = mainGradient;\n  ctx.fill();\n\n  // Subtle border/rim for definition\n  ctx.strokeStyle = 'rgba(255, 255, 255, 0.3)';\n  ctx.lineWidth = 1;\n  ctx.stroke();\n\n  // Primary highlight (large, soft)\n  ctx.fillStyle = 'rgba(255, 255, 255, 0.6)';\n  ctx.beginPath();\n  ctx.arc(x - size * 0.3, y - size * 0.3, size * 0.35, 0, Math.PI * 2);\n  ctx.fill();\n\n  // Secondary highlight (small, bright)\n  ctx.fillStyle = 'rgba(255, 255, 255, 0.9)';\n  ctx.beginPath();\n  ctx.arc(x - size * 0.4, y - size * 0.4, size * 0.15, 0, Math.PI * 2);\n  ctx.fill();\n\n  // Reflected light on opposite side\n  ctx.fillStyle = 'rgba(255, 255, 255, 0.2)';\n  ctx.beginPath();\n  ctx.arc(x + size * 0.4, y + size * 0.4, size * 0.2, 0, Math.PI * 2);\n  ctx.fill();\n}\n\nexport function drawCross(\n  ctx: CanvasRenderingContext2D,\n  x: number,\n  y: number,\n  size: number\n): void {\n  // Draw simple 4-pointed cross/plus shape\n  const halfSize = size / 2;\n  const thickness = size * 0.3;\n\n  // Vertical bar\n  ctx.fillRect(x - thickness / 2, y - halfSize, thickness, size);\n  // Horizontal bar\n  ctx.fillRect(x - halfSize, y - thickness / 2, size, thickness);\n}\n\nexport function drawOval(\n  ctx: CanvasRenderingContext2D,\n  x: number,\n  y: number,\n  width: number,\n  height: number\n): void {\n  ctx.save();\n  ctx.translate(x, y);\n  ctx.scale(width / height, 1);\n  ctx.beginPath();\n  ctx.arc(0, 0, height, 0, Math.PI * 2);\n  ctx.fill();\n  ctx.restore();\n}\n","import { Particle } from './particle';\nimport { createCanvas, resizeCanvas } from './utils';\nimport type { EngineOptions, Effect } from './types';\n\nexport class CursorFXEngine {\n  private canvas: HTMLCanvasElement;\n  private ctx: CanvasRenderingContext2D;\n  private particles: Particle[] = [];\n  private animationId: number | null = null;\n  private effect: Effect | null = null;\n  private maxParticles: number = 500; // Cap to prevent performance issues\n  private lastParticleTime: number = 0;\n  private particleThrottle: number = 16; // Create particles every 16ms (~60fps)\n  private lastMouseX: number = 0;\n  private lastMouseY: number = 0;\n  private minMoveDistance: number = 0; // Create particles on every valid move\n\n  constructor(options: EngineOptions = {}) {\n    if (options.canvas) {\n      this.canvas = options.canvas;\n    } else {\n      const container = options.container || document.body;\n      this.canvas = createCanvas(container);\n    }\n\n    const ctx = this.canvas.getContext('2d');\n    if (!ctx) {\n      throw new Error('Failed to get 2D context');\n    }\n    this.ctx = ctx;\n\n    // Bind methods once to prevent memory leaks\n    this.handleResize = this.handleResize.bind(this);\n    this.handleMouseMove = this.handleMouseMove.bind(this);\n    this.handleTouchMove = this.handleTouchMove.bind(this);\n    this.animate = this.animate.bind(this);\n\n    window.addEventListener('resize', this.handleResize);\n  }\n\n  private handleResize(): void {\n    resizeCanvas(this.canvas);\n  }\n\n  private handleMouseMove(e: MouseEvent): void {\n    if (!this.effect) return;\n\n    const now = Date.now();\n    const dx = e.clientX - this.lastMouseX;\n    const dy = e.clientY - this.lastMouseY;\n    const distance = Math.sqrt(dx * dx + dy * dy);\n\n    // Use effect-specific throttle and move distance if provided\n    const throttle = this.effect.throttle ?? this.particleThrottle;\n    const minDist = this.effect.minMoveDistance ?? this.minMoveDistance;\n\n    // Only create particles if enough time passed AND mouse moved enough\n    if (now - this.lastParticleTime >= throttle && distance >= minDist) {\n      this.lastParticleTime = now;\n      this.lastMouseX = e.clientX;\n      this.lastMouseY = e.clientY;\n      const particles = this.effect.onMouseMove(e.clientX, e.clientY);\n      this.addParticles(particles);\n    }\n  }\n\n  private handleTouchMove(e: TouchEvent): void {\n    if (!this.effect || e.touches.length === 0) return;\n\n    const now = Date.now();\n    const touch = e.touches[0];\n    const dx = touch.clientX - this.lastMouseX;\n    const dy = touch.clientY - this.lastMouseY;\n    const distance = Math.sqrt(dx * dx + dy * dy);\n\n    // Use effect-specific throttle and move distance if provided\n    const throttle = this.effect.throttle ?? this.particleThrottle;\n    const minDist = this.effect.minMoveDistance ?? this.minMoveDistance;\n\n    // Only create particles if enough time passed AND touch moved enough\n    if (now - this.lastParticleTime >= throttle && distance >= minDist) {\n      this.lastParticleTime = now;\n      this.lastMouseX = touch.clientX;\n      this.lastMouseY = touch.clientY;\n      const particles = this.effect.onMouseMove(touch.clientX, touch.clientY);\n      this.addParticles(particles);\n    }\n  }\n\n  addParticle(particle: Particle): void {\n    if (this.particles.length < this.maxParticles) {\n      this.particles.push(particle);\n    }\n  }\n\n  addParticles(particles: Particle[]): void {\n    const availableSlots = this.maxParticles - this.particles.length;\n    if (availableSlots > 0) {\n      this.particles.push(...particles.slice(0, availableSlots));\n    }\n  }\n\n  private update(): void {\n    // Update all particles\n    this.particles.forEach(particle => particle.update());\n    // Remove dead particles\n    this.particles = this.particles.filter(particle => !particle.isDead());\n  }\n\n  private draw(): void {\n    // Clear canvas\n    this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n    // Render all particles with shadow/glow effects\n    this.particles.forEach(particle => particle.draw(this.ctx));\n  }\n\n  private animate(): void {\n    this.update();\n    this.draw();\n    this.animationId = requestAnimationFrame(this.animate);\n  }\n\n  start(effect: Effect): void {\n    if (this.animationId === null) {\n      this.effect = effect;\n      this.animationId = requestAnimationFrame(this.animate);\n      document.addEventListener('mousemove', this.handleMouseMove);\n      document.addEventListener('touchmove', this.handleTouchMove, { passive: true });\n    }\n  }\n\n  stop(): void {\n    if (this.animationId !== null) {\n      cancelAnimationFrame(this.animationId);\n      this.animationId = null;\n      document.removeEventListener('mousemove', this.handleMouseMove);\n      document.removeEventListener('touchmove', this.handleTouchMove);\n    }\n  }\n\n  clear(): void {\n    this.particles = [];\n    this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n  }\n\n  destroy(): void {\n    this.stop();\n    this.clear();\n    window.removeEventListener('resize', this.handleResize);\n    if (this.canvas.parentElement) {\n      this.canvas.parentElement.removeChild(this.canvas);\n    }\n  }\n}\n","import type { ParticleConfig } from './types';\nimport { drawStar, drawRectangle, drawSnowflake, drawBubble, drawCross, drawOval } from './utils';\n\nexport class Particle {\n  x: number;\n  y: number;\n  vx: number;\n  vy: number;\n  size: number;\n  color: string;\n  life: number;\n  maxLife: number;\n  gravity: number;\n  opacity: number;\n  rotation: number;\n  rotationSpeed: number;\n  shape: 'star' | 'rectangle' | 'circle' | 'snowflake' | 'bubble' | 'cross' | 'oval';\n  wobbleAmplitude: number;\n  wobbleSpeed: number;\n  wobblePhase: number;\n  windDrift: number;\n  image?: HTMLImageElement;\n  scale: number;\n  initialScale: number;\n  scaleUpDuration: number;\n\n  constructor(config: ParticleConfig) {\n    this.x = config.x;\n    this.y = config.y;\n    this.vx = config.vx ?? (Math.random() - 0.5) * 4;\n    this.vy = config.vy ?? (Math.random() - 0.5) * 4;\n    this.size = config.size ?? 3;\n    this.color = config.color ?? '#ffffff';\n    this.maxLife = config.maxLife ?? 40; // Reduced for better performance\n    this.life = 0;\n    this.gravity = config.gravity ?? 0.1;\n    this.opacity = 1;\n    this.rotation = config.rotation ?? 0;\n    this.rotationSpeed = config.rotationSpeed ?? 0;\n    this.shape = config.shape ?? 'star';\n    this.wobbleAmplitude = config.wobbleAmplitude ?? 0;\n    this.wobbleSpeed = config.wobbleSpeed ?? 0;\n    this.wobblePhase = Math.random() * Math.PI * 2; // Random starting phase\n    this.windDrift = config.windDrift ?? 0;\n    this.image = config.image;\n    this.initialScale = config.initialScale ?? 1; // Default to full scale\n    this.scaleUpDuration = config.scaleUpDuration ?? 0; // Default no animation\n    this.scale = this.initialScale; // Start at initial scale\n  }\n\n  update(): void {\n    this.life++;\n    this.vy += this.gravity;\n\n    // Animate scale from initialScale to 1.0 over scaleUpDuration frames\n    if (this.scaleUpDuration > 0 && this.life < this.scaleUpDuration) {\n      const progress = this.life / this.scaleUpDuration;\n      // Ease-out cubic for smooth pop-up effect\n      const easedProgress = 1 - Math.pow(1 - progress, 3);\n      this.scale = this.initialScale + (1 - this.initialScale) * easedProgress;\n    } else {\n      this.scale = 1;\n    }\n\n    // Apply wobble (for bubbles)\n    if (this.wobbleAmplitude > 0) {\n      this.wobblePhase += this.wobbleSpeed;\n      this.x += this.vx + Math.sin(this.wobblePhase) * this.wobbleAmplitude;\n    } else {\n      this.x += this.vx;\n    }\n\n    // Apply wind drift (for snowflakes)\n    if (this.windDrift > 0) {\n      // Smooth Perlin-like drift using sine waves at different frequencies\n      const drift = Math.sin(this.life * 0.05) * this.windDrift * 0.3 +\n        Math.sin(this.life * 0.02) * this.windDrift * 0.7;\n      this.x += drift;\n    }\n\n    this.y += this.vy;\n    this.rotation += this.rotationSpeed;\n    this.opacity = 1 - this.life / this.maxLife;\n  }\n\n  isDead(): boolean {\n    return this.life >= this.maxLife;\n  }\n\n  draw(ctx: CanvasRenderingContext2D): void {\n    ctx.save();\n    ctx.globalAlpha = this.opacity;\n\n    // Apply scale transform (for pop-up animation)\n    ctx.translate(this.x, this.y);\n    ctx.scale(this.scale, this.scale);\n    ctx.translate(-this.x, -this.y);\n\n    // If image is available, render image instead of shape\n    if (this.image && this.image.complete) {\n      // Enable high-quality image smoothing for better rendering\n      ctx.imageSmoothingEnabled = true;\n      ctx.imageSmoothingQuality = 'high';\n\n      const imgSize = this.size * 2.5; // Larger multiplier for bigger images\n      ctx.translate(this.x, this.y);\n      if (this.rotation !== 0) {\n        ctx.rotate(this.rotation);\n      }\n\n      // Add simple glow for snowflake images (single pass)\n      // if (this.shape === 'snowflake') {\n      //   ctx.shadowBlur = 8;\n      //   ctx.shadowColor = '#FFFFFF';\n      // }\n\n      ctx.drawImage(\n        this.image,\n        -imgSize / 2,\n        -imgSize / 2,\n        imgSize,\n        imgSize\n      );\n      ctx.restore();\n      return;\n    }\n\n    // Fallback to shape rendering\n    ctx.fillStyle = this.color;\n\n    // Draw based on shape\n    switch (this.shape) {\n      case 'rectangle':\n        if (this.rotation !== 0) {\n          ctx.translate(this.x, this.y);\n          ctx.rotate(this.rotation);\n          ctx.translate(-this.x, -this.y);\n        }\n        drawRectangle(ctx, this.x, this.y, this.size, this.size * 1.5);\n        break;\n\n      case 'circle':\n        ctx.shadowBlur = 15; // Strong glow for circles\n        ctx.shadowColor = this.color;\n        ctx.beginPath();\n        ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);\n        ctx.fill();\n        break;\n\n      case 'snowflake':\n        ctx.strokeStyle = this.color;\n        ctx.lineWidth = 1.5;\n        drawSnowflake(ctx, this.x, this.y, this.size, this.rotation);\n        break;\n\n      case 'bubble':\n        drawBubble(ctx, this.x, this.y, this.size);\n        break;\n\n      case 'cross':\n        ctx.shadowBlur = 18; // Strong glow for fairy dust\n        ctx.shadowColor = this.color;\n        drawCross(ctx, this.x, this.y, this.size);\n        break;\n\n      case 'oval':\n        ctx.shadowBlur = 12; // Moderate glow for CRT phosphor\n        ctx.shadowColor = this.color;\n        drawOval(ctx, this.x, this.y, this.size * 2, this.size);\n        break;\n\n      default: // star\n        drawStar(ctx, this.x, this.y, this.size, 5);\n        break;\n    }\n\n    ctx.restore();\n  }\n}\n","// Image loader for bubble assets\nexport class ImageLoader {\n  private static images: Map<string, HTMLImageElement> = new Map();\n  private static loading: Map<string, Promise<HTMLImageElement>> = new Map();\n\n  static async loadImage(src: string): Promise<HTMLImageElement> {\n    // Return cached image if already loaded\n    if (this.images.has(src)) {\n      return this.images.get(src)!;\n    }\n\n    // Return existing promise if currently loading\n    if (this.loading.has(src)) {\n      return this.loading.get(src)!;\n    }\n\n    // Create new loading promise\n    const loadPromise = new Promise<HTMLImageElement>((resolve, reject) => {\n      const img = new Image();\n      img.onload = () => {\n        this.images.set(src, img);\n        this.loading.delete(src);\n        resolve(img);\n      };\n      img.onerror = () => {\n        this.loading.delete(src);\n        reject(new Error(`Failed to load image: ${src}`));\n      };\n      img.src = src;\n    });\n\n    this.loading.set(src, loadPromise);\n    return loadPromise;\n  }\n\n  static async loadBubbles(basePath: string = '/bubbles'): Promise<HTMLImageElement[]> {\n    const bubblePaths = [\n      `${basePath}/soap_bubbles_1.png`,\n      `${basePath}/soap_bubble_2.png`,\n      `${basePath}/soap_bubble_3.png`,\n    ];\n\n    try {\n      return await Promise.all(bubblePaths.map(path => this.loadImage(path)));\n    } catch (error) {\n      console.warn('Failed to load some bubble images, falling back to canvas rendering', error);\n      return [];\n    }\n  }\n\n  static async loadSnowflakes(basePath: string = '/snowflakes'): Promise<HTMLImageElement[]> {\n    const snowflakePaths = [\n      // `${basePath}/snowflake.png`,\n      `${basePath}/snow_flake_1.png`,\n      `${basePath}/snow_flake_2.png`,\n    ];\n\n    try {\n      return await Promise.all(snowflakePaths.map(path => this.loadImage(path)));\n    } catch (error) {\n      console.warn('Failed to load some snowflake images, falling back to canvas rendering', error);\n      return [];\n    }\n  }\n\n  static getRandomBubble(): HTMLImageElement | null {\n    const bubbleImages = Array.from(this.images.entries())\n      .filter(([key]) => key.includes('bubble'))\n      .map(([, img]) => img);\n    if (bubbleImages.length === 0) return null;\n    return bubbleImages[Math.floor(Math.random() * bubbleImages.length)];\n  }\n\n  static getRandomSnowflake(): HTMLImageElement | null {\n    const snowflakeImages = Array.from(this.images.entries())\n      .filter(([key]) => key.includes('snow'))\n      .map(([, img]) => img);\n    if (snowflakeImages.length === 0) return null;\n    return snowflakeImages[Math.floor(Math.random() * snowflakeImages.length)];\n  }\n\n  static isLoaded(): boolean {\n    return this.images.size > 0;\n  }\n\n  static clear(): void {\n    this.images.clear();\n    this.loading.clear();\n  }\n}\n","import { Particle } from '../particle';\nimport { randomColor } from '../utils';\nimport type { Effect, EffectOptions } from '../types';\n\nconst DEFAULT_COLORS = [\n  '#FFD700', // Gold\n  '#FFC700', // Golden Yellow\n  '#FFB700', // Amber\n  '#FFED4E', // Light Gold\n  '#F4E04D', // Pale Gold\n];\n\nexport function createFairyDustEffect(options: EffectOptions = {}): Effect {\n  const {\n    colors = DEFAULT_COLORS,\n    particleCount = 2,\n    particleSize = 6, // Increased from 4 for better visibility\n    gravity = -0.05, // Slight upward float for magical feel\n    maxLife = 40,\n    velocity = 3,\n  } = options;\n\n  return {\n    onMouseMove(x: number, y: number): Particle[] {\n      const particles: Particle[] = [];\n\n      for (let i = 0; i < particleCount; i++) {\n        particles.push(\n          new Particle({\n            x: x + (Math.random() - 0.5) * 15,\n            y: y + (Math.random() - 0.5) * 15,\n            vx: (Math.random() - 0.5) * velocity,\n            vy: (Math.random() - 0.5) * velocity - 1, // Slight upward bias\n            size: Math.random() * particleSize + 3, // Increased from 2 (now 3-9px)\n            color: randomColor(colors),\n            maxLife: maxLife + Math.random() * 20,\n            gravity,\n            shape: 'cross',\n          })\n        );\n      }\n\n      return particles;\n    },\n  };\n}\n","import { Particle } from '../particle';\nimport { randomColor } from '../utils';\nimport type { Effect, EffectOptions } from '../types';\n\nconst DEFAULT_COLORS = [\n  '#FFD700', // Gold\n  '#FF69B4', // Hot Pink\n  '#00CED1', // Dark Turquoise\n  '#9370DB', // Medium Purple\n];\n\nexport function createSparkleEffect(options: EffectOptions = {}): Effect {\n  const {\n    colors = DEFAULT_COLORS,\n    particleCount = 1, // Reduced for better performance\n    particleSize = 6, // Increased from 3 for better visibility\n    gravity = 0.1,\n    maxLife = 20, // Further reduced for faster cleanup\n    velocity = 4,\n  } = options;\n\n  return {\n    onMouseMove(x: number, y: number): Particle[] {\n      const particles: Particle[] = [];\n\n      for (let i = 0; i < particleCount; i++) {\n        particles.push(\n          new Particle({\n            x: x + (Math.random() - 0.5) * 10,\n            y: y + (Math.random() - 0.5) * 10,\n            vx: (Math.random() - 0.5) * velocity,\n            vy: (Math.random() - 0.5) * velocity,\n            size: Math.random() * particleSize + 3, // Increased from 2 (now 3-9px)\n            color: randomColor(colors),\n            maxLife: maxLife + Math.random() * 10, // Reduced random variation\n            gravity,\n          })\n        );\n      }\n\n      return particles;\n    },\n  };\n}\n","import { Particle } from '../particle';\nimport { randomColor } from '../utils';\nimport type { Effect, EffectOptions } from '../types';\n\nconst DEFAULT_COLORS = [\n  '#FF6B6B', // Red\n  '#4ECDC4', // Turquoise\n  '#FFE66D', // Yellow\n  '#95E1D3', // Mint\n  '#F38181', // Pink\n  '#AA96DA', // Purple\n  '#FCBAD3', // Light Pink\n  '#A8D8EA', // Sky Blue\n];\n\nexport function createConfettiEffect(options: EffectOptions = {}): Effect {\n  const {\n    colors = DEFAULT_COLORS,\n    particleCount = 3,\n    particleSize = 4,\n    gravity = 0.3, // Stronger gravity for falling effect\n    maxLife = 60, // Longer lifetime for confetti\n    velocity = 6,\n  } = options;\n\n  return {\n    onMouseMove(x: number, y: number): Particle[] {\n      const particles: Particle[] = [];\n\n      for (let i = 0; i < particleCount; i++) {\n        particles.push(\n          new Particle({\n            x: x + (Math.random() - 0.5) * 20,\n            y: y + (Math.random() - 0.5) * 20,\n            vx: (Math.random() - 0.5) * velocity,\n            vy: (Math.random() - 1) * velocity * 0.5, // Bias upward initially\n            size: Math.random() * particleSize + 3,\n            color: randomColor(colors),\n            maxLife: maxLife + Math.random() * 20,\n            gravity,\n            rotation: Math.random() * Math.PI * 2, // Random initial rotation\n            rotationSpeed: (Math.random() - 0.5) * 0.2, // Rotation speed\n            shape: 'rectangle',\n          })\n        );\n      }\n\n      return particles;\n    },\n  };\n}\n","import { Particle } from '../particle';\nimport { randomColor } from '../utils';\nimport type { Effect, EffectOptions } from '../types';\n\nconst DEFAULT_COLORS = [\n  '#00FF00', // Classic phosphor green\n  '#33FF33', // Bright phosphor green\n  '#00CC00', // Medium phosphor green\n  '#00DD00', // Light phosphor green\n];\n\nexport function createRetroCRTEffect(options: EffectOptions = {}): Effect {\n  const {\n    colors = DEFAULT_COLORS,\n    particleCount = 3,\n    particleSize = 4, // Slightly larger for better visibility\n    gravity = 0, // No gravity - phosphor glows in place\n    maxLife = 60, // Longer persistence like real phosphor\n    velocity = 1, // Very slow movement for authentic glow\n  } = options;\n\n  return {\n    onMouseMove(x: number, y: number): Particle[] {\n      const particles: Particle[] = [];\n\n      for (let i = 0; i < particleCount; i++) {\n        particles.push(\n          new Particle({\n            x: x + (Math.random() - 0.5) * 8,\n            y: y + (Math.random() - 0.5) * 8,\n            vx: (Math.random() - 0.5) * velocity,\n            vy: (Math.random() - 0.5) * velocity,\n            size: Math.random() * particleSize + 2,\n            color: randomColor(colors),\n            maxLife: maxLife + Math.random() * 15,\n            gravity,\n            shape: 'circle', // Back to circles with strong glow\n          })\n        );\n      }\n\n      return particles;\n    },\n  };\n}\n","import { Particle } from '../particle';\nimport { randomColor } from '../utils';\nimport { ImageLoader } from '../imageLoader';\nimport type { Effect, EffectOptions } from '../types';\n\nconst DEFAULT_COLORS = [\n  '#FFFFFF', // Pure white\n  '#F0F8FF', // Alice blue\n  '#E6F3FF', // Light blue white\n  '#F5F5F5', // White smoke\n];\n\n// ⚙️ CONFIGURATION FLAG: Switch between image-based and canvas-drawn snowflakes\nconst USE_SNOWFLAKE_IMAGES = true; // Set to true to use PNG images, false for canvas drawing\n\nexport function createSnowEffect(options: EffectOptions = {}): Effect {\n  const {\n    colors = DEFAULT_COLORS,\n    particleCount = 1, // One snowflake at a time\n    particleSize = 7, // Bigger for better visibility\n    gravity = 0.12, // Faster falling\n    maxLife = 150, // Shorter lifetime for faster fall\n    velocity = 0.4, // Slightly more drift\n    throttle = 120, // Spawn every 120ms - less frequent\n    minMoveDistance = 12, // Only spawn when cursor moves 12px\n  } = options;\n\n  return {\n    throttle,\n    minMoveDistance,\n    onMouseMove(x: number, y: number): Particle[] {\n      const particles: Particle[] = [];\n\n      for (let i = 0; i < particleCount; i++) {\n        // Conditionally get snowflake image based on flag\n        const snowflakeImage = USE_SNOWFLAKE_IMAGES ? ImageLoader.getRandomSnowflake() : null;\n\n        particles.push(\n          new Particle({\n            x: x + (Math.random() - 0.5) * 30,\n            y: y + (Math.random() - 0.5) * 15,\n            vx: (Math.random() - 0.5) * velocity,\n            vy: Math.random() * 0.2 + 0.1, // Slightly faster downward initial velocity\n            size: Math.random() * particleSize + 3, // Variable sizes (3-10px for canvas, base for images)\n            color: randomColor(colors),\n            maxLife: maxLife + Math.random() * 60,\n            gravity,\n            rotation: Math.random() * Math.PI * 2, // Random initial rotation\n            rotationSpeed: (Math.random() - 0.5) * 0.03, // More visible rotation\n            shape: 'snowflake',\n            windDrift: 0.8, // Gentle wind drift/sway\n            image: snowflakeImage || undefined, // Use image if flag is true and images loaded\n          })\n        );\n      }\n\n      return particles;\n    },\n  };\n}\n","import { Particle } from '../particle';\nimport { randomColor } from '../utils';\nimport { ImageLoader } from '../imageLoader';\nimport type { Effect, EffectOptions } from '../types';\n\nconst DEFAULT_COLORS = [\n  'rgba(173, 216, 230, 0.4)', // Light blue - transparent\n  'rgba(135, 206, 235, 0.4)', // Sky blue - transparent\n  'rgba(176, 224, 230, 0.4)', // Powder blue - transparent\n  'rgba(175, 238, 238, 0.4)', // Pale turquoise - transparent\n  'rgba(224, 255, 255, 0.4)', // Light cyan - transparent\n];\n\nexport function createBubbleEffect(options: EffectOptions = {}): Effect {\n  const {\n    colors = DEFAULT_COLORS,\n    particleCount = 1, // Spawn one bubble at a time\n    gravity = -0.02, // Gentle upward buoyancy\n    maxLife = 180, // Longer lifetime for slow rise\n    velocity = 0.2, // Minimal base horizontal drift\n    throttle = 150, // Spawn every 150ms - much less frequent\n    minMoveDistance = 15, // Only spawn when cursor moves 15px\n  } = options;\n\n  return {\n    throttle,\n    minMoveDistance,\n    onMouseMove(x: number, y: number): Particle[] {\n      const particles: Particle[] = [];\n\n      for (let i = 0; i < particleCount; i++) {\n        const bubbleImage = ImageLoader.getRandomBubble();\n\n        // Create more dramatic size variation (15-45 range for 2.5x multiplier = 37-112px actual)\n        const baseSize = 15 + Math.random() * 30;\n\n        particles.push(\n          new Particle({\n            x: x + (Math.random() - 0.5) * 10, // Spawn closer to pointer\n            y: y + (Math.random() - 0.5) * 10,\n            vx: (Math.random() - 0.5) * velocity,\n            vy: -Math.random() * 0.15 - 0.1, // Very slow, consistent upward\n            size: baseSize, // Wide size variation (15-45)\n            color: randomColor(colors),\n            maxLife: maxLife + Math.random() * 60,\n            gravity,\n            shape: 'bubble',\n            wobbleAmplitude: 0.3, // Gentle horizontal wobble\n            wobbleSpeed: 0.05, // Slow wobble oscillation\n            image: bubbleImage || undefined, // Use image if loaded, fallback to canvas\n            initialScale: 0.3, // Start at 30% size for pop-up effect\n            scaleUpDuration: 15, // Grow to full size over 15 frames (~250ms)\n          })\n        );\n      }\n\n      return particles;\n    },\n  };\n}\n"]}