\n
\n \n
\n

Utopía Ingenua

\n

Toca el vacíoy haz florecer la perfección own-defined

\n
Sincronizando sueños...
\n
\n
\n
", "css": ".body { margin: 0; padding: 0; overflow: hidden; background: #000; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; color: #fff; }\n#app { width: 100vw; height: 100vh; position: relative; overflow: hidden; }\n#canvas-container { position: relative; width: 100%; height: 100%; }\n#main-canvas { position: absolute; top: 0; left: 0; width: 100%; height: 100%; cursor: crosshair; }\n#ui { position: absolute; top: 30px; left: 30px; pointer-events: none; z-index: 10; text-shadow: 0 2px 10px rgba(0,0,0,0.5); }\n#ui h1 { margin: 0; font-size: 2.5rem; font-weight: 300; letter-spacing: 3px; color: #e0f7fa; }\n#ui p { margin: 0 0 10px 0; font-size: 1rem; font-weight: 300; opacity: 0.7; }\n#ui #status { font-family: monospace; font-size: 0.8rem; color: #4db6ac; letter-spacing: 1px; }\n\n@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }\n#ui { animation: fadeIn 2s ease-out; }", "js": "const canvas = document.getElementById('main-canvas');\nconst ctx = canvas.getContext('2d');\n\nlet width, height;\nlet particles = [];\nconst MAX_PARTICLES = 150;\nconst COLORS = ['#FFB7C5', '#B2EBF2', '#E1F5FE', '#F8BBD0', '#C8E6C9', '#DCEDC1'];\n\nfunction resize() {\n width = canvas.width = window.innerWidth;\n height = canvas.height = window.innerHeight;\n}\n\nwindow.addEventListener('resize', resize);\nresize();\n\nclass Particle {\n constructor(x, y, color) {\n this.x = x;\n this.y = y;\n this.vx = (Math.random() - 0.5) * 2;\n this.vy = (Math.random() - 0.5) * 2;\n this.radius = Math.random() * 3 + 1;\n this.color = color;\n this.life = 1.0;\n this.decay = Math.random() * 0.01 + 0.005;\n }\n\n update() {\n this.vx += (Math.random() - 0.5) * 0.1;\n this.vy += (Math.random() - 0.5) * 0.1;\n this.x += this.vx;\n this.y += this.vy;\n this.life -= this.decay;\n }\n\n draw() {\n ctx.beginPath();\n ctx.arc(this.x, this.y, this.radius * this.life, 0, Math.PI * 2);\n ctx.fillStyle = `rgba(${this.hexToRgb(this.color)}, ${this.life})`;\n ctx.fill();\n }\n\n hexToRgb(hex) {\n const result = { r: 0, g: 0, b: 0 };\n const r = parseInt(hex.slice(1, 3), 16);\n const g = parseInt(hex.slice(3, 5), 16);\n const result.r = r; // Simplified for logic, actually needing to return a string\n return `${r}, ${parseInt(hex.slice(3, 5), 16)}, ${parseInt(hex.slice(5, 7), 16)}`;\n }\n}\n\nfunction createParticles(x, y) {\n const color = COLORS[Math.floor(Math.random() * COLORS.length)];\n for (let i = 0; i < 20; i++) {\n particles.push(new Particle(x, y, color));\n }\n}\n\nfunction animate() {\n ctx.fillStyle = 'rgba(0, 0, 0, 0.1)';\n ctx.fillRect(0, 0, width, height);\n\n particles = particles.filter(p => p.life > 0);\n particles.forEach(p => {\n p.update();\n p.draw();\n });\n\n // Draw connection lines based on proximity\n ctx.lineWidth = 0.5;\n for (let i = 0; i < particles.length; i++) {\n for (let j = i + 1; j < particles.length; j++) {\n const dx = particles[i].x - particles[j].x;\n const dy = particles[i].y - particles[j].y;\n const dist = Math.sqrt(dx * dx + dy * dy);\n if (dist < 80) {\n ctx.beginPath();n ctx.strokeStyle = `rgba(255, 255, 255, ${0.2 * (1 - dist / 80)})`;\n ctx.stroke();\n }\n }\n }\n \n requestAnimationFrame(animate);\n}\n\ncanvas.addEventListener('mousedown', (e) => {\n createParticles(e.clientX, e.clientY);\n});\n\ncanvas.addEventListener('touchstart', (e) =>