{"id":8,"date":"2026-04-09T17:21:59","date_gmt":"2026-04-09T17:21:59","guid":{"rendered":"https:\/\/dialelo.io\/?page_id=8"},"modified":"2026-04-11T21:11:18","modified_gmt":"2026-04-11T21:11:18","slug":"inicio","status":"publish","type":"page","link":"https:\/\/dialelo.io\/","title":{"rendered":"Dialelo"},"content":{"rendered":"\n<!DOCTYPE html>\n<html lang=\"es\">\n<head>\n<meta charset=\"UTF-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n<meta name=\"description\" content=\"Dialelo \u2014 Conecta con la siguiente generaci\u00f3n de inteligencia creativa.\">\n<title>Dialelo<\/title>\n<link rel=\"preconnect\" href=\"https:\/\/fonts.googleapis.com\">\n<link href=\"https:\/\/fonts.googleapis.com\/css2?family=DM+Sans:ital,wght@0,300;0,400;0,500;1,300&#038;family=DM+Mono:wght@300;400&#038;display=swap\" rel=\"stylesheet\">\n\n<style>\n\/* \u2500\u2500 Reset \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\n*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }\n\n:root {\n  --gold:         rgba(255, 175, 50, 0.92);\n  --gold-dim:     rgba(255, 185, 70, 0.55);\n  --text:         rgba(255, 245, 220, 0.90);\n  --muted:        rgba(255, 215, 140, 0.38);\n  --glass-bg:     rgba(10, 6, 0, 0.45);\n  --glass-border: rgba(255, 255, 255, 0.11);\n  --f: 'DM Sans', system-ui, sans-serif;\n  --m: 'DM Mono', monospace;\n}\n\nhtml, body {\n  width: 100%; height: 100%;\n  background: #000;\n  font-family: var(--f);\n  color: var(--text);\n  overflow-x: hidden;\n}\n\n\/* \u2500\u2500 Canvas fixed background \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\n#bh-canvas {\n  position: fixed;\n  inset: 0; width: 100%; height: 100%;\n  z-index: 0;\n}\n\n\/* \u2500\u2500 Dark vignette overlay \u2014 makes text legible over the glow \u2500\u2500 *\/\n#vignette {\n  position: fixed;\n  inset: 0;\n  z-index: 1;\n  pointer-events: none;\n  \/* Radial dark center + edge darken *\/\n  background:\n    radial-gradient(ellipse 70% 60% at 50% 50%,\n      rgba(0,0,0,0.55) 0%,\n      rgba(0,0,0,0.0) 100%),\n    radial-gradient(ellipse 120% 100% at 50% 50%,\n      transparent 40%,\n      rgba(0,0,0,0.5) 100%);\n}\n\n\/* \u2500\u2500 Page layout \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\n#page {\n  position: relative;\n  z-index: 10;\n  min-height: 100vh;\n  display: flex;\n  flex-direction: column;\n}\n\n\/* \u2500\u2500 Nav \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\nnav {\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  padding: 28px 48px;\n  flex-shrink: 0;\n}\n\n.hero-logo {\n  display: block;\n  height: 38px;\n  width: auto;\n  opacity: 0;\n  transform: translateY(10px);\n  animation: fadeUp 1.2s cubic-bezier(0.22,1,0.36,1) 0.1s forwards;\n}\n\n.nav-dot {\n  width: 7px; height: 7px;\n  border-radius: 50%;\n  background: var(--gold);\n  box-shadow: 0 0 10px rgba(255,160,40,0.9);\n  animation: pulse 2.8s ease-in-out infinite;\n}\n@keyframes pulse {\n  0%,100% { opacity: 1; transform: scale(1); }\n  50%      { opacity: 0.45; transform: scale(1.6); }\n}\n\n\/* \u2500\u2500 Hero \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\n#hero {\n  flex: 1;\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n  justify-content: center;\n  text-align: center;\n  padding: 40px 24px 60px;\n  gap: 20px;\n}\n\n.hero-eyebrow {\n  font-family: var(--m);\n  font-size: 10px;\n  letter-spacing: 0.32em;\n  text-transform: uppercase;\n  color: rgba(255, 185, 70, 0.5);\n  \/* text-shadow for extra legibility *\/\n  text-shadow: 0 0 20px rgba(0,0,0,0.8), 0 2px 8px rgba(0,0,0,1);\n  opacity: 0;\n  transform: translateY(10px);\n  animation: fadeUp 1.2s cubic-bezier(0.22,1,0.36,1) 0.3s forwards;\n}\n\n.hero-title {\n  font-size: clamp(34px, 5.5vw, 72px);\n  font-weight: 300;\n  line-height: 1.08;\n  letter-spacing: -0.028em;\n  color: rgba(255, 250, 235, 0.96);\n  \/* Strong shadow to cut through the glow *\/\n  text-shadow:\n    0 0 40px rgba(0,0,0,0.95),\n    0 4px 24px rgba(0,0,0,1),\n    0 8px 40px rgba(0,0,0,0.8);\n  max-width: 800px;\n  opacity: 0;\n  transform: translateY(14px);\n  animation: fadeUp 1.2s cubic-bezier(0.22,1,0.36,1) 0.6s forwards;\n}\n.hero-title em {\n  font-style: italic;\n  color: rgba(255, 210, 100, 0.95);\n  text-shadow:\n    0 0 40px rgba(0,0,0,0.95),\n    0 4px 24px rgba(0,0,0,1),\n    0 0 80px rgba(255,160,40,0.3);\n}\n\n.hero-sub {\n  font-size: clamp(13px, 1.4vw, 16px);\n  font-weight: 300;\n  line-height: 1.75;\n  color: rgba(255, 220, 160, 0.55);\n  max-width: 480px;\n  text-shadow: 0 2px 12px rgba(0,0,0,1), 0 0 30px rgba(0,0,0,0.9);\n  opacity: 0;\n  transform: translateY(14px);\n  animation: fadeUp 1.2s cubic-bezier(0.22,1,0.36,1) 0.9s forwards;\n}\n\n@keyframes fadeUp {\n  to { opacity: 1; transform: translateY(0); }\n}\n\n\/* \u2500\u2500 Liquid Glass Form \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\n.form-wrap {\n  opacity: 0;\n  transform: translateY(18px);\n  animation: fadeUp 1.4s cubic-bezier(0.22,1,0.36,1) 1.2s forwards;\n  width: 100%;\n  display: flex;\n  justify-content: center;\n  margin-top: 12px;\n}\n\n.form-card {\n  width: 100%;\n  max-width: 400px;\n  \/* Darker glass \u2014 much more opaque to ensure legibility *\/\n  background: rgba(8, 4, 0, 0.72);\n  backdrop-filter: blur(40px) saturate(160%);\n  -webkit-backdrop-filter: blur(40px) saturate(160%);\n  border: 1px solid rgba(255, 200, 80, 0.14);\n  border-radius: 22px;\n  padding: 36px 32px 30px;\n  box-shadow:\n    0 32px 80px rgba(0,0,0,0.7),\n    0 0 0 0.5px rgba(255,220,100,0.06) inset,\n    0 1px 0 rgba(255,200,80,0.10) inset;\n  position: relative;\n  overflow: hidden;\n}\n\n\/* Top shimmer line *\/\n.form-card::before {\n  content: '';\n  position: absolute;\n  top: 0; left: 20%; right: 20%;\n  height: 1px;\n  background: linear-gradient(90deg, transparent, rgba(255,200,80,0.25), transparent);\n  pointer-events: none;\n}\n\n.form-header {\n  text-align: center;\n  margin-bottom: 28px;\n}\n.form-logo {\n  font-family: var(--m);\n  font-size: 11px;\n  letter-spacing: 0.28em;\n  text-transform: uppercase;\n  color: rgba(255, 210, 120, 0.6);\n  margin-bottom: 5px;\n}\n.form-tagline {\n  font-size: 12px;\n  color: rgba(255, 185, 60, 0.35);\n  font-style: italic;\n  font-weight: 300;\n}\n\n\/* Fields *\/\n.field { margin-bottom: 16px; }\n.field label {\n  display: block;\n  font-family: var(--m);\n  font-size: 9px;\n  letter-spacing: 0.16em;\n  text-transform: uppercase;\n  color: rgba(255, 195, 90, 0.45);\n  margin-bottom: 7px;\n}\n.field input {\n  width: 100%;\n  background: rgba(255, 255, 255, 0.05);\n  border: 1px solid rgba(255, 255, 255, 0.08);\n  border-radius: 9px;\n  padding: 12px 14px;\n  font-family: var(--f);\n  font-size: 14px;\n  font-weight: 300;\n  color: rgba(255, 245, 220, 0.92);\n  outline: none;\n  transition: border-color 0.2s, background 0.2s, box-shadow 0.2s;\n  -webkit-appearance: none;\n}\n.field input::placeholder { color: rgba(255,255,255,0.16); }\n.field input:focus {\n  border-color: rgba(255, 165, 40, 0.42);\n  background: rgba(255, 255, 255, 0.07);\n  box-shadow: 0 0 0 3px rgba(255,148,28,0.08);\n}\n\n\/* Submit *\/\n.submit-btn {\n  width: 100%;\n  margin-top: 6px;\n  padding: 14px;\n  background: rgba(255, 158, 40, 0.88);\n  border: none;\n  border-radius: 9px;\n  font-family: var(--f);\n  font-size: 14px;\n  font-weight: 500;\n  letter-spacing: 0.03em;\n  color: #060200;\n  cursor: pointer;\n  box-shadow: 0 8px 28px rgba(255,138,24,0.32), 0 1px 0 rgba(255,220,100,0.25) inset;\n  transition: all 0.22s ease;\n  position: relative;\n  overflow: hidden;\n}\n.submit-btn::after {\n  content: '';\n  position: absolute; inset: 0;\n  background: linear-gradient(to bottom, rgba(255,255,255,0.08), transparent);\n  pointer-events: none;\n}\n.submit-btn:hover {\n  background: rgba(255, 175, 58, 1);\n  box-shadow: 0 12px 36px rgba(255,145,20,0.48);\n  transform: translateY(-1px);\n}\n.submit-btn:active { transform: translateY(0); }\n.submit-btn:disabled { opacity: 0.55; cursor: not-allowed; transform: none; }\n\n\/* Success *\/\n.form-success {\n  display: none;\n  text-align: center;\n  padding: 24px 0 8px;\n}\n.form-success .icon { font-size: 32px; display: block; margin-bottom: 12px; }\n.form-success h3 { font-size: 17px; font-weight: 400; color: rgba(255,245,215,0.9); margin-bottom: 6px; }\n.form-success p { font-size: 13px; color: rgba(255,200,100,0.4); }\n\n.form-legal {\n  text-align: center;\n  font-size: 11px;\n  color: rgba(255,255,255,0.16);\n  margin-top: 16px;\n  line-height: 1.5;\n}\n\n\/* \u2500\u2500 Controls panel \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\n#bh-controls {\n  position: fixed;\n  bottom: 22px; right: 22px;\n  z-index: 100;\n  background: rgba(8, 4, 0, 0.88);\n  backdrop-filter: blur(24px);\n  -webkit-backdrop-filter: blur(24px);\n  border: 1px solid rgba(255, 175, 50, 0.18);\n  border-radius: 16px;\n  padding: 18px 20px 16px;\n  display: flex;\n  flex-direction: column;\n  gap: 0;\n  width: 220px;\n  opacity: 0;\n  animation: fadeUp 0.8s cubic-bezier(0.22,1,0.36,1) 2s forwards;\n}\n\n.ctrl-title {\n  font-family: var(--m);\n  font-size: 9px;\n  font-weight: 400;\n  letter-spacing: 0.22em;\n  text-transform: uppercase;\n  color: rgba(255, 175, 50, 0.45);\n  margin-bottom: 14px;\n}\n\n\/* Each control row *\/\n.ctrl-row {\n  display: flex;\n  flex-direction: column;\n  gap: 6px;\n  margin-bottom: 14px;\n}\n\n\/* Toggle row *\/\n.ctrl-toggle {\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  margin-bottom: 14px;\n}\n.ctrl-toggle .ctrl-lbl {\n  font-size: 14px;\n  font-weight: 400;\n  color: rgba(255, 235, 190, 0.85);\n}\n\n\/* Label + value row *\/\n.ctrl-header {\n  display: flex;\n  align-items: baseline;\n  justify-content: space-between;\n  gap: 8px;\n}\n.ctrl-lbl {\n  font-size: 14px;\n  font-weight: 400;\n  color: rgba(255, 235, 190, 0.85);\n}\n.ctrl-val {\n  font-family: var(--m);\n  font-size: 13px;\n  font-style: italic;\n  font-weight: 300;\n  color: rgba(255, 190, 70, 0.65);\n  min-width: 36px;\n  text-align: right;\n}\n\n\/* Range slider *\/\ninput[type=range] {\n  width: 100%;\n  height: 4px;\n  appearance: none;\n  -webkit-appearance: none;\n  background: rgba(255, 255, 255, 0.08);\n  border-radius: 2px;\n  outline: none;\n  cursor: pointer;\n  margin: 0;\n}\ninput[type=range]::-webkit-slider-thumb {\n  -webkit-appearance: none;\n  width: 16px; height: 16px;\n  border-radius: 50%;\n  background: #ff9a1e;\n  cursor: pointer;\n  box-shadow: 0 0 10px rgba(255,148,24,0.7);\n  border: none;\n}\ninput[type=range]::-moz-range-thumb {\n  width: 16px; height: 16px;\n  border-radius: 50%;\n  background: #ff9a1e;\n  cursor: pointer;\n  box-shadow: 0 0 10px rgba(255,148,24,0.7);\n  border: none;\n}\n\n\/* Toggle switch *\/\n.tog {\n  width: 42px; height: 24px;\n  border-radius: 12px;\n  background: rgba(255,255,255,0.1);\n  cursor: pointer;\n  position: relative;\n  transition: background 0.22s;\n  border: none;\n  flex-shrink: 0;\n}\n.tog.on { background: #ff9a1e; }\n.tog::after {\n  content: '';\n  position: absolute;\n  top: 3px; left: 3px;\n  width: 18px; height: 18px;\n  border-radius: 50%;\n  background: #fff;\n  transition: transform 0.2s ease;\n  box-shadow: 0 1px 4px rgba(0,0,0,0.3);\n}\n.tog.on::after { transform: translateX(18px); }\n\n\/* Divider *\/\n.ctrl-divider {\n  height: 1px;\n  background: rgba(255,255,255,0.06);\n  margin: 2px 0 14px;\n}\n\n\/* Reset button *\/\n.ctrl-reset {\n  width: 100%;\n  padding: 10px;\n  margin-top: 2px;\n  background: transparent;\n  border: 1px solid rgba(255, 175, 50, 0.2);\n  border-radius: 9px;\n  color: rgba(255, 200, 100, 0.6);\n  font-family: var(--m);\n  font-size: 11px;\n  font-weight: 400;\n  letter-spacing: 0.1em;\n  cursor: pointer;\n  transition: all 0.2s;\n}\n.ctrl-reset:hover {\n  border-color: rgba(255, 175, 50, 0.42);\n  color: rgba(255, 210, 120, 0.85);\n  background: rgba(255, 150, 24, 0.07);\n}\n\n\/* \u2500\u2500 Footer \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\nfooter {\n  position: relative; z-index: 10;\n  padding: 22px 48px;\n  display: flex; align-items: center; justify-content: space-between;\n  border-top: 1px solid rgba(255,255,255,0.04);\n  flex-shrink: 0;\n}\nfooter p, footer a { font-size: 11px; color: rgba(255,255,255,0.16); font-family: var(--m); }\nfooter a { text-decoration: none; transition: color 0.2s; }\nfooter a:hover { color: rgba(255,190,60,0.5); }\n\n\/* \u2500\u2500 Responsive \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\n@media (max-width: 600px) {\n  nav { padding: 20px 22px; }\n  .nav-logo svg { height: 22px; }\n  #hero { padding: 30px 18px 50px; }\n  .form-card { padding: 28px 20px 24px; border-radius: 18px; }\n  #bh-controls { display: none; }\n  footer { padding: 18px 22px; flex-direction: column; gap: 6px; text-align: center; }\n}\n<\/style>\n<\/head>\n<body>\n\n<canvas id=\"bh-canvas\"><\/canvas>\n<div id=\"vignette\"><\/div>\n\n<div id=\"page\">\n\n  <nav>\n    <div class=\"nav-dot\"><\/div>\n  <\/nav>\n\n  <section id=\"hero\">\n    <img id=\"hero-logo-img\" alt=\"Dialelo\" class=\"hero-logo\">\n<script>\n(function() {\n  var src = \"data:image\/png;base64,\/9j\/4AAQSkZJRgABAQAAAQABAAD\/4gHYSUNDX1BST0ZJTEUAAQEAAAHIAAAAAAQwAABtbnRyUkdCIFhZWiAH4AABAAEAAAAAAABhY3NwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAA9tYAAQAAAADTLQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlkZXNjAAAA8AAAACRyWFlaAAABFAAAABRnWFlaAAABKAAAABRiWFlaAAABPAAAABR3dHB0AAABUAAAABRyVFJDAAABZAAAAChnVFJDAAABZAAAAChiVFJDAAABZAAAAChjcHJ0AAABjAAAADxtbHVjAAAAAAAAAAEAAAAMZW5VUwAAAAgAAAAcAHMAUgBHAEJYWVogAAAAAAAAb6IAADj1AAADkFhZWiAAAAAAAABimQAAt4UAABjaWFlaIAAAAAAAACSgAAAPhAAAts9YWVogAAAAAAAA9tYAAQAAAADTLXBhcmEAAAAAAAQAAAACZmYAAPKnAAANWQAAE9AAAApbAAAAAAAAAABtbHVjAAAAAAAAAAEAAAAMZW5VUwAAACAAAAAcAEcAbwBvAGcAbABlACAASQBuAGMALgAgADIAMAAxADb\/2wBDAAUDBAQEAwUEBAQFBQUGBwwIBwcHBw8LCwkMEQ8SEhEPERETFhwXExQaFRERGCEYGh0dHx8fExciJCIeJBweHx7\/2wBDAQUFBQcGBw4ICA4eFBEUHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh7\/wAARCABgAR4DASIAAhEBAxEB\/8QAHQABAAIDAQEBAQAAAAAAAAAAAAcIBQYJBAMCAf\/EAE0QAAEDAwIDBAQICwUFCQAAAAECAwQABQYHEQgSITFBUWETFCJxFTJCUmJ1gbMJFiM2OHKCkZKhshczdKLSGCQ1Y7E3Q1VWc4WVwdH\/xAAUAQEAAAAAAAAAAAAAAAAAAAAA\/8QAFBEBAAAAAAAAAAAAAAAAAAAAAP\/aAAwDAQACEQMRAD8AplSlKBSt+0a0lzDVS9qg45DCYjJHrdwkbpjxgfnK71HuSNyfIbkTvdrXw7aCAwrrGVqTmjPR1hfKY7Cx3LT1bb6jsPpFjwG9BVi1We73ZZRarVOnqHamNHW6f8oNZR7BM4YZU89huRNtJ7VrtjwSPtKalfLOKnUy4tmHjXwViNtT0aj2yIjmSnwK1g9fNIT7qj2VqvqpOeK3NQssWtR7EXV9I+wJUBQaW62404pt1tTa0nZSVDYj3ivxWSvt6vd6fS7e7lNuDyNwHJTqnFjx6q60s1gvt6eDFmstxuLqugRFirdJ+xINBjaAb1O+nvCrqrlDrbtztzOMwVbFT1xXs5t5NJ3Vv5K5ffVstGOG7ANOHGbmthV\/vrWykz5yBytK8Wmvio8ieZQ+dQVb0L4Wsvzj0F3yj02M2BeywXW\/97kJ\/wCW2fiAj5S\/EEJUKlHX\/JtNNDdPLjpZgdkgv328wyxcC5+VUy0tJHpH1nqpwgkoR0Cd+bYDlCt64reIKHprAcxnGXWZWXyW+u+y0W5Ch0ccHYXCOqUHyUrpsFc97jNl3KfIuFwlPSpclxTr77yytbi1HcqUT1JJ670HnpSlApSlApSlApSlApSlApSlApSlApSlApSlApSlApSlApSlAqQdA9MLpqtn0fH4SlR4LQ9PcZnLuI7AOxI8VnsSO8nfsBIj6rb\/AAj\/AGAcJsBNvV6tm2eD0xeHRyOwU7hQPaORtSQPBbpI7KD4cQutFtwSz\/2OaM8lrt9vSY9xuUZX5RTnYtttY682+\/O52k7gbbbmN9AOHvLdVlpuzqzZcbCyFXF9sqU+QfaSyjpznfoVEhIO\/UkbV9OEvRw6q5suVeG3BjNpKXJ6gSkyFnqhhKu0c2xKiOoSO0FQNdHWWrfZrSlppEaBb4THKlKQlpphpCezuCUpA9wAoIx084d9KMMYbMfGI92mIA5pl1AkuKPiEqHIn9lIqT4tvgRG0tRYMZhCfipbaSkD3ACqoaycY0O2T37TptamLoWiUKuk7mDCj\/y2wQpQ+kSPcR1qFneK7Wtcv06cihNo339Cm2Mcnu6pKv50HRh6BBdILsKM4fFTST\/9V9m20NpCW0JQkdgSNhVNNKOM2Sqczb9SbLHEZZCTc7YhQLX0lsknmHeSkg+CTVwLJdbbe7RGu9omsToEpsOsSGVhSHEnvBFB7ar7xW8QUTTWA5jOMusysvkt+S0W5Ch0cWOwuEdUoPkpXTYKcVvEFE01gOYzjLrMrL5LfgFotyFDo4sdhcI6pQfJSumwVQEJuuR3WZJdfenXB0Oy33HXCpx4gFbiiT1UrYKUfcaDy3GbLuU+RcLhKelS5LinX33lla3FqO5UonqST13rz0pQKUpQKVtGkjDErVXEo0php9h29Q0ONOJCkLSXkApIPQgjuNdTDhGFk7nEMfJ+rWf9NByLpV7dNsZxx7jc1GtzuPWlyDHtDK2YyobZabUpEXdSUkbAnc7kDvPjU35thOGowy+KbxGwhYt0gpKbc0Dv6NX0aDlHSlKBSlKBSldBuCPF8ZufD\/bZdyx20TZK5krmekQm3Fq2cIG6lAk9AB9lBz5pXQDjjxjGrXoJLl23HbRCkpuEYJejwm21jdRB2KQD2Vz\/AKBSlKBSlT\/wGWy2XbXB2NdbdDnsCzyFhuSwl1IVztjcBQI32JG\/maCAKV1z\/EfC\/wDyhj\/\/AMaz\/prlLnDLMfNb7HjtIaZauMhDbaBslCQ4oAAdwAoMNSlKBSlKDM4LaBf82sdiO+1wuLEU7eC3EpP\/AFqVuNjKPh\/XSfbI6gIGPst2yM2k+ykpHM5sPHnUU\/sitG0EcQ1rfg63FcqRf4QJ976BXxzdxd71mvTj4UpU7IH+Yd\/tyFdP50HRfhgwtnBdFMftfoQ3MlR0z5x22Kn3gFEHzSOVHuSKgr8INqfMhJhaZWeSplMpkTLutCtitskhtnfwJSVKHf7HdvvcBtCW20toASlICUgdwFczOMp+Q9xI5Z6wVEtuR0IB7kCO3tt\/1+2giClK2PTjCsh1AyyLjWNQjJmyDupR6Nstj4zjivkoG\/U+4DckAg04wrIc\/wAsi41jUIyZsg7lR6Nstj4zjivkoG\/U+4DckA27zXN7Zw3abQtJcEmu37N5PtuOFPpBFde23c9H1AUrp6Nnr3KVvv7eNzXKMT4XMEXguCrYumoNwaSu5XJaATHJHRxY67bA\/k2ewA8yt9\/brdo5c7lL15xG6SJT8qfIyKI48+6orW6pb6eZSiepJ3O5oLRaZcLomYFfbzqOXLhmd+iPKZDzxWYDqwVJWpW\/tvFexUTuB1HXqTUbTi6HHNR7DdH0EphXJlUhs\/LbCwHEHyKeZJ99dbtq5HZs0kakXtiOkcvwxIQ2E+HplAbUH31axoYdqbkeMJSoNW64ussc3aWuYlsn3oKT9tavU1cbMUReIi9qAAU9GhuLH0vV2wf6a8fCbpizqdqqxCubal2S2N+u3FIO3pUggIa37udRG\/fyhW3Wg92hXDhmup0Zu8LU3YceWfYnymypT47\/AETfQrH0iUp7diSCKsXbeC3TlqKlE\/IcllP\/ACnG3WWkn3J9Gdv3mrMRmGY0duPHabZZaQENttpCUoSBsEgDoAB02qF9XuJjTvTu9u2F0zr3dmFcsli3pSUx1fNWtSgObxA3I79qCPP9j5jHs1sOR4flTrzVuukaU9DubY5lNtupUrlcbG3NsDsCnr4irX1Fuimu2DarOPQ7G9KhXVhHpHLfOQEOlHetBBKVpBPXY7jvA3FSlQU4uGBP6gcaWoNtj5ZesaVGtzD5kWt0tuuD0UZPISCPZ9rfbxArcco4crjDxm6yzrPnz4ZhPOFpyaooXsgnlUObqk9hHhX10x\/Tt1M+pWP6IlTxnX5kX76tkfdKoORcONJmy2YkOO7IkPuBtplpBWtxajsEpSOpJPQAVafSrg1v13gs3LPb38AocAULfFQHZAH01k8iD5Dm89j0ravwf2lcNqzO6o3eMl2Y+45Gs4WncMtp3S46PpKPMgHuCVfOq2d0nwrVbZFxuUpmJDjNqdffeWEIbQkblSiegAFBXB7gv0yVHKGr5lLbu2wcMhk7Hx29FWoW\/glbTkshFwzVxyxFjeO4xHCJId5h7K0ndPLy7+0DuT3CtzvXGXpnCvKocK15Bc4iF8qprLCEIUPnJStYUR7wk+VTnp5muOZ9jDGRYvcUToDpKCdilbSx8ZC0nqlQ3HQ9xBG4INBWPJeDPFbXjlzubWZXpbkSG6+hKmGuUlCCoA7d3SpH4EP0dLX\/AI2X96alvP8A8xMg+rJP3SqiTgQ\/R0tf+Nl\/emg+PHt+jzN+sYv9ZqguC4jkWb5Gxj+L2t643B7qG2+gQkdq1qPRKRuN1EgdR41frj1BPD1MAG5Nxi9P2zWw8LOlcLTLTWG27FQMgubSJN1fKfb5yN0s7\/NQDtt2b8x76CGcE4KIIhtv5vl0hclQBXGtLaUoQfD0jgJV\/CK2C9cFeAvxFJtGTZDBk7eyt8tPo380hCSf4hUla\/a6YtpDHjsXFl653mWguR7dHUEq5N9vSOKPRCNwQDsSSDsDsSIkwnjUsVwvbUPKcSkWaE6sJ9djy\/WQ0Ce1aORJ5R3lO58AaCuuuWg2baUrEy5NNXOxrXyN3SICWwT2JcSeraj57g9xNbn+D3\/7envqWR\/W1V+bhDtGS4+7DmMxrlarjH5VoVstp9pY8R2gg7gj31UXh50+c0y4zb3i6VLchJsz8i3ur7Vx1raKNz3kdUk95SaC5VciM\/BOe5AB\/wCKSfvVV13ql\/CLpXCyTVrLNQb7FRIhWa9Ps25pxO6Vy\/SFRcI7\/RpKSPpKB7U0Go6OcI+XZZBYvGXzvxXt7yQtuOpn0kxxJ7ygkBvf6R5vFNTMjgu0yEYIXfMpU7tsXPWGR18dvRVY67XCBaLZIudzmMQ4UVsuvvvrCENoA3KlE9AKgiRxe6PtXowEv3t2OF8pnIgfkf1tioObfsb+VBCOrXB3ktggvXTBrr+MbDQKlQXWw1L5R8zY8rh8vZJ7gTVXn2XY77jD7a2nW1FC0LSUqSoHYgg9hB7q6\/43fLRklji3uxXCPcLdLRzsSGFcyVjs+wg7gg9QQQdjVTuOnRhU6fAz3EraVz5j\/qt0jsJ\/vVcpUh\/bx2SUqPf7PfvuFOLPPftd2h3OKrlkRH0PtHwUhQUP5gVkFXVUzOPhsIKFP3L1rl36pKnefbf7awtbBptal33UPHbM2grVNukZjYDuU4kH+VB1y3qi34QzApVvzaBqBFYUqBdWUxJawOjclsbJ3\/WbA2\/9NVXqrEZljVly7Gp2O5BBbm22a36N5pf7wQe0KBAII6ggEUHKbTjCshz\/ACyLjWNQjJmyDupR6Nstj4zjivkoG\/U+4DckA2pzXKMT4XMEXguCrYumoNwaSu5XJaATHJHRxY67bA\/k2eoAPMrff2\/ZqBkuF8M+Nv4DpYwu5ZzdlAvyn+V9+OFf3Zc2SAV7H8m0Bt15lA7+3U+7YpqBNvEh66Y1k0i5SHS4+p+A+p5xxR3JVunckk70Gv3GbMuU+RcLhKelS5LinX33lla3FqO5UonqST13qduBnApWVaxxsgdZV8FY4PW3nCPZU+QQygHx5t1+5B8RXl0o4XtSszmsu3e3OYtaSQXZVxbKXSn6DPRRP63KPOr76X4HjunOIRsZxqKWYjO63HFkKdkOnbmdcVt7SjsPIAAAAACg9+c3+LiuG3jJJqgli2wnZKtz8bkSSE+8nYDzNcwdEbHJzbW7G7Y4C8qZdUPyj4tpV6V0\/wAKVVY3j61djPMJ0rsEpLqg4l69utq3CSk7tx9+877LV4bJHiBgeD2xxcBwDKdeclZCY0OG5FtCHOnplbgKUn9ZfI0D489BFvF9d2rzxFZZIZUFNsSG4gIPe00htX+ZKqnr8GqzHFqzaQNvWC\/EQrp1COV0j+ZP7qptdp8q6XWXc5zpdlS31vvLPapa1FSj+8mp74EtQYmHarO2O6PpYt+RtJihxR2SiSlRLO58DzLR71poL75tKnwcMvc21oK58e3SHYqQN93UtqKBt7wK5DyHnpEhyRIdW686orcWtW6lKJ3JJPaSa7H9oqo2s\/B4m9ZFJvent4g2tuW4XXbbNSoMtLJ3PoloBIST8gp6dx22ACsHD3OuNu1wwyRa1LEk3mO1sjtUhawhafcUKUD5GurFVw4beGGLpvkCMsye6R7xfGElMNqOgiPFKgQpe6uq17EgEgAbnoTsRY+grdpj+nbqZ9Ssf0RKnfPSRgt\/I7fgyT90qoI0x\/Tt1M+pWP6IlTxnX5kX76tkfdKoNU4aGWGNAcJRGACDaGVnb5yhzK\/zE1Gf4Qu4XSHonCiwlOIiTbw01NKexSAhxaUnyK0pPvSK\/PAPqFEyDS84XJkJF2x9SuRtR9pyKtRUlY8eVSig+HseIqdNQMRsmc4lPxfIYxkW+ajlWEnZaFA7pWg9ykkAg+XXcbig5FVbj8G1OuIyjLbalSzbVQmX3E\/JS8FlKT5EpK\/fyjwrzXrgmytF6UizZhZnrWV+y7LbcbfSnwKEhSSf2hv5VZ7QLSSx6R4mu0W15c2dKWHbhPcQEqkLA2ACevKhIJ2Tudtyd9yaDa8\/\/MTIPqyT90qok4EP0dLX\/jZf3pqW8\/8AzEyD6sk\/dKqJOBD9HS1\/42X96aDMcWTLEjTq0R5SUqYdya1odCuwpMhIIP2VL1QPx3POx9AZEhlZQ61c4i0KHalQXuDUi6K53b9R9N7TlEJ1BcfaDcxpJ6sSUgBxsju2PUeKSk99BmL9h+JZBMRMvuMWW6yUI9Gl6ZBbeWlG5PKFKSTtuSdvM1jjplpwQQcBxYg9o+CWP9NRzxIaI3vUKU1fsPzCdYb020GXGFynUxZKBvy78h3QobnqAQe8d9RlplwwakG\/sydQtQZSLSysKciW66SFuyQPkFZ5QhJ7yNztuBseoC3kdlqOw2ww0hpptIQhCEhKUpA2AAHYAO6okvbMdPF5jshAHrDmHy0OdOvKmSgp\/mpVfDIOHPCJ7avUL3mNj7x6nfnlJT9jpX0qBuFEwEcXV8h2jI7jkdrh2uTHh3Cc5zuOoStrcg7kFPNzbEbAjY7Degu9US8KDTLelb7jaUhb1+ua3iO9Xrbiev7KU1LVVa4LdQYhyrNdN576W5SbzLuFtCjt6VBcIdQnzSUhW3aQpR7jQej8ItcbrF0os0GIpxECbdQmaU77L5G1KbQryJBVt4oHhVCa646jYZYc\/wAQm4vkcYvwJaRuUHlcaWOqXEK7lJPUHs7iCCRVT5HBDPN6Ij59GFrKtwty3qL4T4coXyk+e491Bl\/wbNxujtiy+1PLcVa40iM9HCt+VDq0rDm3vCEbjy86tlcWWX2UofQlaQrcBQ367Gta0k08x7TLD2caxxlYYSouvvukF2S6QAXFkbDfYAbDoAAKiXjM1md07t9mslgfaXfpb3rLrZP91GSlSd1Du5lkbfqKoOelWD4DMOXkWtbd9daKoWPR1SlqI9n0ywUNJ9\/VSh+pVfUgqUEpBJPQAV0y4SdM1aa6TxmLgx6O+XUidcgR7TaiPYaP6idgR84roJgqvvFdxBQ9NYDmM4y6zKy+S34BaLchQ6OLHYXCOqUHyUrpsFOK7iCiaawHMZxl1mVl8lvt6LRbkKHRxY7C4R1Sg+SldNgqgTDN3yi+uq9MufdJjinVqffHpJDijuTzLPtKJO\/buaC7nBhpXY1QUaq369Q8mym47yEKEgPmAV9VFZ3J9YO55ieqdyB3k2krkLJiZViFyBkRrzYJw7CtDkZzbyPQ1l06pamBr0I1Byrk222+Fn+z+Kg6oZFf7HjluXcb\/d4NriIHtPS30tJ\/eojc+VVN4geLiL6nIx7SsuOPOAtu3x1soDY7\/QIV1KvpqA27gehFZbJh2puotwS7AsmRZA8vp6y6hxxA97q\/ZH2mpyw\/hmseHwG8p14yy32W2t+0LWxJ\/KPEdeRTg6k\/RaCie5QoI44dtGr\/AKw5YqZMVKYx5h\/nul0WSVOKJ5lNtqPxnVb9T1CQeY9wVtHF5qtaL6uBplgRZZw\/HuVvmjH8lJeQOUcp+U2gbgH5SipXX2TX7104i27tj39n2ldt\/FrD2mywtbaA09Kb70gD+7bV137VL39ojdSTXSgV\/QSDuK\/lKC2+gXFy7Z7dGx7UxiVcGGUhtm8RxzvhI6APIPx9vng83TqFHc1ZC2a+6OXCKJLOoFmbTy78shamVj9lYB3+yuXFKDo7mfFbpJYHWWYNzlX91bqUOfB8dXI0kn2lla+UHYbnZO5PZ07a\/J4tdGASPhe5nzFtc6\/yrnJSgtrhGumntq4p82z+ZNnIsN3tzcaI6IiitS0pYB3QOoH5NW2\/l2VKmUcVWj1wxm6wY91uZekQnmmwbc4N1KQQB+81z2pQZvB8qv2FZPEyPG57kG4xFbocT1Cge1KgeikkdCDV4dKeL7Br5BZjZw07jV0AAcdQ2t6I4fFJSCpG\/godPnGqB0oOpb+vGjzMT1leoViKNt9kP86\/4ACr+VaI5xeaSIyF63h+7KgNs8ybimGr0bi9wORKPj9nXcgDpXO+lB0Hy3ip0fuGK3eBGul0W\/JgvMtJ+DnBzKU2QBueg6nvrQOFjX\/TbT7R2BjWSXCezcmZMhxxDUJbiQFrKkkKHQ9DVN6UFxOKzX3TfULSCTjeNT5z9xcmMOpQ7CW2nlSolRKj0qAtCtYMn0lyBc6zFEu3SSkTra8ohqQB2EEfEWOuyh9oI6VHFKDpFgfFNpJksNtU+8uY7NI9uNcWlJAPfs4kFBHvIPkK2G98QWjloiqkP57apGw3CIZVIWryAbBrl5Sgs7xF8VM\/NLZJxbBo0mz2SQkty5jxAlSkHoUAJJDaD39SVDp0G4OicIufY3pxqq7kOUyH48BVsejhbLBdPOpSCBsOu2yT191Q7Sg6Nji10YJ\/4vdB\/wC2uf8A5VBJ+Ry4moMvKcemyIUgXJ2ZDkIPK43u4VJPv2PUdR2itfpQXm0b4w8enwGLdqVGctNxQkJVcYrJcjPfSUhO6m1HwAUO09OypmRrto+uJ6yNQ7CEbb7GRsv+Ajm\/lXLOlBfXVrjAw2zQXoeAsOZDdCCluS80pmI0fnHm2WvbwAAPzqo\/l2RXnLMimZBkE92fcprnpH33O0nsAAHQJA2ASOgAAHSsVSgsbwNaUfjlnZzK8Ruex4+6lbaVj2ZEztQnzCOiz58g7CasJxW8QUPTW3uYzjLrMrL5LfktFuQodHFjsLhB3Sg+SldNgrUNStWcW0C0ntWnGm8yFdMh9TBMtopcaYKxuqS5tuFOLJJSjqANifZCUqpLcpsy5T5FwuEp6VLkuKdffeWVrcWo7lSiepJPfQLjNmXKfIuFwlPSpclxTr77yytbi1HcqUT1JJ67156UoN7xDWDUvFIqYdmy+4phJASmJJKZLCR4Bt0KSke4Ct0t3E9qLC2Um3Yk46P+9VZW0r38fY5ahClBNF\/4odZ7swphOTt25pQ2Igw2mj9iuUqH2Gomvt6vF+uC7he7rNucxfxn5b6nVn9pRJrwUoFKUoFKUoFKUoFKUoFKUoFKUoFKUoFKUoFKUoFKUoFKUoFKUoFKUoFKUoP\/2Q==\";\n  var img = new Image();\n  img.onload = function() {\n    var cv = document.createElement('canvas');\n    cv.width = img.naturalWidth;\n    cv.height = img.naturalHeight;\n    var ctx = cv.getContext('2d');\n    ctx.drawImage(img, 0, 0);\n    var d = ctx.getImageData(0, 0, cv.width, cv.height);\n    var px = d.data;\n    for (var i = 0; i < px.length; i += 4) {\n      \/\/ Brightness of pixel\n      var brightness = (px[i] * 0.299 + px[i+1] * 0.587 + px[i+2] * 0.114);\n      \/\/ Make dark pixels transparent, keep light ones\n      \/\/ Smooth transition: fully transparent below 40, fully opaque above 180\n      var alpha = Math.min(255, Math.max(0, (brightness - 40) * (255 \/ 140)));\n      px[i+3] = Math.round(alpha);\n    }\n    ctx.putImageData(d, 0, 0);\n    document.getElementById('hero-logo-img').src = cv.toDataURL('image\/png');\n  };\n  img.src = src;\n})();\n<\/script>\n    <p class=\"hero-eyebrow\">Creative Intelligence Platform<\/p>\n    <h1 class=\"hero-title\">\n      Where ideas <em>collapse<\/em><br>into clarity\n    <\/h1>\n    <p class=\"hero-sub\">\n      Dialelo conecta equipos creativos con el poder de la inteligencia artificial.\n      Un horizonte de eventos para tus ideas m\u00e1s ambiciosas.\n    <\/p>\n\n    <div class=\"form-wrap\">\n      <div class=\"form-card\">\n        <div class=\"form-header\">\n          <div class=\"form-logo\">Dialelo.io<\/div>\n          <div class=\"form-tagline\">Solicita acceso anticipado<\/div>\n        <\/div>\n\n        <form id=\"contact-form\">\n          <div class=\"field\">\n            <label for=\"nombre\">Nombre<\/label>\n            <input type=\"text\" id=\"nombre\" name=\"nombre\" placeholder=\"Tu nombre\" required autocomplete=\"given-name\">\n          <\/div>\n          <div class=\"field\">\n            <label for=\"email\">Email<\/label>\n            <input type=\"email\" id=\"email\" name=\"email\" placeholder=\"tu@email.com\" required autocomplete=\"email\">\n          <\/div>\n          <button type=\"submit\" class=\"submit-btn\" id=\"submit-btn\">\n            Solicitar acceso\n          <\/button>\n        <\/form>\n\n        <div class=\"form-success\" id=\"form-success\">\n          <span class=\"icon\">\u2726<\/span>\n          <h3>Recibido, gracias.<\/h3>\n          <p>Te avisaremos en cuanto abramos el acceso.<\/p>\n        <\/div>\n\n        <p class=\"form-legal\">Sin spam. Cancelaci\u00f3n inmediata.<\/p>\n      <\/div>\n    <\/div>\n  <\/section>\n\n  <footer>\n    <p>\u00a9 2025 Dialelo. Todos los derechos reservados.<\/p>\n    <p><a href=\"#\">Privacidad<\/a> &nbsp;\u00b7&nbsp; <a href=\"#\">T\u00e9rminos<\/a><\/p>\n  <\/footer>\n<\/div>\n\n<!-- Controls panel -->\n<div id=\"bh-controls\">\n  <div class=\"ctrl-title\">Agujero Negro<\/div>\n\n  <div class=\"ctrl-toggle\">\n    <span class=\"ctrl-lbl\">Auto-rotaci\u00f3n<\/span>\n    <button class=\"tog on\" id=\"tog-rot\"><\/button>\n  <\/div>\n\n  <div class=\"ctrl-divider\"><\/div>\n\n  <div class=\"ctrl-row\">\n    <div class=\"ctrl-header\">\n      <span class=\"ctrl-lbl\">Bloom<\/span>\n      <span class=\"ctrl-val\" id=\"val-bloom\">0.00<\/span>\n    <\/div>\n    <input type=\"range\" id=\"sl-bloom\" min=\"0\" max=\"2\" step=\"0.05\" value=\"0\">\n  <\/div>\n\n  <div class=\"ctrl-row\">\n    <div class=\"ctrl-header\">\n      <span class=\"ctrl-lbl\">Velocidad<\/span>\n      <span class=\"ctrl-val\" id=\"val-speed\">0.08<\/span>\n    <\/div>\n    <input type=\"range\" id=\"sl-speed\" min=\"0.01\" max=\"0.5\" step=\"0.01\" value=\"0.08\">\n  <\/div>\n\n  <div class=\"ctrl-row\">\n    <div class=\"ctrl-header\">\n      <span class=\"ctrl-lbl\">Lensing<\/span>\n      <span class=\"ctrl-val\" id=\"val-lens\">0.100<\/span>\n    <\/div>\n    <input type=\"range\" id=\"sl-lens\" min=\"0\" max=\"0.25\" step=\"0.005\" value=\"0.10\">\n  <\/div>\n\n  <button class=\"ctrl-reset\" id=\"btn-reset\">Reset c\u00e1mara<\/button>\n<\/div>\n\n<!-- \u2500\u2500 Form handler \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n<script>\ndocument.getElementById('contact-form').addEventListener('submit', async function(e) {\n  e.preventDefault();\n  const btn = document.getElementById('submit-btn');\n  btn.disabled = true;\n  btn.textContent = 'Enviando\u2026';\n\n  const data = {\n    nombre:    this.nombre.value,\n    apellidos: this.apellidos.value,\n    email:     this.email.value,\n  };\n\n  \/* \u2500\u2500 Conecta aqu\u00ed tu backend \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n   *\n   * Opci\u00f3n A \u2014 Formspree (recomendado, gratis):\n   *   const res = await fetch('https:\/\/formspree.io\/f\/TU_ID', {\n   *     method: 'POST',\n   *     headers: { 'Content-Type': 'application\/json' },\n   *     body: JSON.stringify(data)\n   *   });\n   *   if (res.ok) { ... mostrar \u00e9xito }\n   *\n   * Opci\u00f3n B \u2014 Tu propio API endpoint:\n   *   await fetch('\/api\/leads', { method:'POST', body: JSON.stringify(data), headers:{'Content-Type':'application\/json'} });\n   *\n   * \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\n\n  \/\/ Demo: simula env\u00edo\n  await new Promise(r => setTimeout(r, 900));\n  document.getElementById('contact-form').style.display = 'none';\n  document.getElementById('form-success').style.display = 'block';\n});\n\n\/\/ \u2500\u2500 Controls \u2014 cola de comandos mientras Three.js carga \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\/\/ Todas las acciones se encolan si DIBH a\u00fan no est\u00e1 disponible\nconst _queue = [];\nlet _ready = false;\n\nwindow._dibhReady = function(api) {\n  _ready = true;\n  _queue.forEach(fn => fn(api));\n};\n\nfunction ctrl(fn) {\n  if (_ready && window.DIBH) fn(window.DIBH);\n  else _queue.push(fn);\n}\n\n\/\/ Toggle autorotaci\u00f3n\ndocument.getElementById('tog-rot').addEventListener('click', function() {\n  this.classList.toggle('on');\n  const on = this.classList.contains('on');\n  ctrl(api => api.setAutoRotate(on));\n});\n\n\/\/ Bloom\ndocument.getElementById('sl-bloom').addEventListener('input', function() {\n  const v = parseFloat(this.value);\n  document.getElementById('val-bloom').textContent = v.toFixed(2);\n  ctrl(api => api.setBloom(v));\n});\n\n\/\/ Velocidad\ndocument.getElementById('sl-speed').addEventListener('input', function() {\n  const v = parseFloat(this.value);\n  document.getElementById('val-speed').textContent = v.toFixed(2);\n  ctrl(api => api.setRotateSpeed(v));\n});\n\n\/\/ Lensing\ndocument.getElementById('sl-lens').addEventListener('input', function() {\n  const v = parseFloat(this.value);\n  document.getElementById('val-lens').textContent = v.toFixed(3);\n  ctrl(api => api.setLensing(v));\n});\n\n\/\/ Reset c\u00e1mara\ndocument.getElementById('btn-reset').addEventListener('click', function() {\n  ctrl(api => api.resetCamera());\n});\n<\/script>\n\n<!-- \u2500\u2500 Three.js UMD \u2014 sin importmap, compatible con WordPress \u2500\u2500\u2500\u2500 -->\n<script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/three.js\/r128\/three.min.js\"><\/script>\n<script src=\"https:\/\/cdn.jsdelivr.net\/npm\/three@0.128.0\/examples\/js\/controls\/OrbitControls.js\"><\/script>\n<script src=\"https:\/\/cdn.jsdelivr.net\/npm\/three@0.128.0\/examples\/js\/shaders\/CopyShader.js\"><\/script>\n<script src=\"https:\/\/cdn.jsdelivr.net\/npm\/three@0.128.0\/examples\/js\/shaders\/LuminosityHighPassShader.js\"><\/script>\n<script src=\"https:\/\/cdn.jsdelivr.net\/npm\/three@0.128.0\/examples\/js\/postprocessing\/EffectComposer.js\"><\/script>\n<script src=\"https:\/\/cdn.jsdelivr.net\/npm\/three@0.128.0\/examples\/js\/postprocessing\/RenderPass.js\"><\/script>\n<script src=\"https:\/\/cdn.jsdelivr.net\/npm\/three@0.128.0\/examples\/js\/postprocessing\/ShaderPass.js\"><\/script>\n<script src=\"https:\/\/cdn.jsdelivr.net\/npm\/three@0.128.0\/examples\/js\/postprocessing\/UnrealBloomPass.js\"><\/script>\n\n<script>\n(function() {\nvar OrbitControls   = THREE.OrbitControls;\nvar EffectComposer  = THREE.EffectComposer;\nvar RenderPass      = THREE.RenderPass;\nvar UnrealBloomPass = THREE.UnrealBloomPass;\nvar ShaderPass      = THREE.ShaderPass;\n\nconst canvas    = document.getElementById('bh-canvas');\nconst BH_RADIUS = 1.3;\nconst DISK_INNER = BH_RADIUS + 0.15;\nconst DISK_OUTER = 8.0;\nconst DISK_TILT  = Math.PI \/ 3.2;\n\n\/\/ \u2500\u2500 Renderer \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nconst renderer = new THREE.WebGLRenderer({ canvas, antialias: true, powerPreference: 'high-performance' });\nrenderer.setSize(innerWidth, innerHeight);\nrenderer.setPixelRatio(Math.min(devicePixelRatio, 1.5));\nrenderer.outputEncoding = THREE.sRGBEncoding;\nrenderer.toneMapping        = THREE.ACESFilmicToneMapping;\nrenderer.toneMappingExposure = 1.35;\n\n\/\/ \u2500\u2500 Scene \/ Camera \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nconst scene  = new THREE.Scene();\nscene.fog    = new THREE.FogExp2(0x020100, 0.022);\nconst camera = new THREE.PerspectiveCamera(58, innerWidth \/ innerHeight, 0.1, 4000);\ncamera.position.set(-6.0, 4.5, 6.5);\nconst CAM_DEFAULT = camera.position.clone();\n\n\/\/ \u2500\u2500 OrbitControls \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nconst controls = new OrbitControls(camera, renderer.domElement);\ncontrols.enableDamping   = true;\ncontrols.dampingFactor   = 0.035;\ncontrols.rotateSpeed     = 0.4;\ncontrols.autoRotate      = true;\ncontrols.autoRotateSpeed = 0.08;\ncontrols.minDistance     = 2.5;\ncontrols.maxDistance     = 80;\ncontrols.enablePan       = false;\ncontrols.target.set(0, 0, 0);\ncontrols.update();\n\n\/\/ \u2500\u2500 Post-processing \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nconst composer  = new EffectComposer(renderer);\ncomposer.addPass(new RenderPass(scene, camera));\nconst bloomPass = new UnrealBloomPass(new THREE.Vector2(innerWidth, innerHeight), 0.0, 0.65, 0.78);\ncomposer.addPass(bloomPass);\n\nconst lensingPass = new ShaderPass({\n  uniforms: {\n    tDiffuse:        { value: null },\n    bhScreenPos:     { value: new THREE.Vector2(0.5, 0.5) },\n    lensingStrength: { value: 0.10 },\n    lensingRadius:   { value: 0.28 },\n    aspectRatio:     { value: innerWidth \/ innerHeight },\n    chromaticAb:     { value: 0.004 },\n  },\n  vertexShader: `varying vec2 vUv; void main(){ vUv=uv; gl_Position=projectionMatrix*modelViewMatrix*vec4(position,1.0); }`,\n  fragmentShader: `\n    uniform sampler2D tDiffuse;\n    uniform vec2 bhScreenPos;\n    uniform float lensingStrength,lensingRadius,aspectRatio,chromaticAb;\n    varying vec2 vUv;\n    void main(){\n      vec2 tc=vUv-bhScreenPos; tc.x*=aspectRatio;\n      float dist=length(tc);\n      float amt=clamp(lensingStrength\/(dist*dist+0.004),0.0,0.65);\n      amt*=smoothstep(lensingRadius,lensingRadius*0.3,dist);\n      vec2 dir=normalize(tc); dir.x\/=aspectRatio;\n      gl_FragColor=vec4(\n        texture2D(tDiffuse,vUv-dir*amt*(1.0+chromaticAb)).r,\n        texture2D(tDiffuse,vUv-dir*amt).g,\n        texture2D(tDiffuse,vUv-dir*amt*(1.0-chromaticAb)).b,\n        1.0\n      );\n    }\n  `\n});\ncomposer.addPass(lensingPass);\n\n\/\/ \u2500\u2500 Stars \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nconst STAR_COUNT = 120000;\nconst sGeo = new THREE.BufferGeometry();\nconst sPos=new Float32Array(STAR_COUNT*3), sCol=new Float32Array(STAR_COUNT*3);\nconst sSiz=new Float32Array(STAR_COUNT),   sTwk=new Float32Array(STAR_COUNT);\nconst sPal=[\n  new THREE.Color(0xffe8c0),new THREE.Color(0xfff0dd),new THREE.Color(0xffffff),\n  new THREE.Color(0xffeebb),new THREE.Color(0xffd090),new THREE.Color(0xffccaa),\n  new THREE.Color(0xaaccff),new THREE.Color(0xffffff),\n];\nfor(let i=0;i<STAR_COUNT;i++){\n  const phi=Math.acos(-1+(2*i)\/STAR_COUNT),theta=Math.sqrt(STAR_COUNT*Math.PI)*phi;\n  const r=Math.cbrt(Math.random())*2000+100;\n  sPos[i*3]=r*Math.sin(phi)*Math.cos(theta); sPos[i*3+1]=r*Math.sin(phi)*Math.sin(theta); sPos[i*3+2]=r*Math.cos(phi);\n  const sc=sPal[Math.floor(Math.random()*sPal.length)].clone(); sc.multiplyScalar(Math.random()*0.6+0.4);\n  sCol[i*3]=sc.r; sCol[i*3+1]=sc.g; sCol[i*3+2]=sc.b;\n  sSiz[i]=THREE.MathUtils.randFloat(0.4,2.5); sTwk[i]=Math.random()*Math.PI*2;\n}\nsGeo.setAttribute('position',new THREE.BufferAttribute(sPos,3));\nsGeo.setAttribute('color',   new THREE.BufferAttribute(sCol,3));\nsGeo.setAttribute('size',    new THREE.BufferAttribute(sSiz,1));\nsGeo.setAttribute('twinkle', new THREE.BufferAttribute(sTwk,1));\nconst starMat=new THREE.ShaderMaterial({\n  uniforms:{uTime:{value:0},uPixelRatio:{value:renderer.getPixelRatio()}},\n  vertexShader:`uniform float uTime,uPixelRatio;attribute float size,twinkle;varying vec3 vColor;varying float vTwk;\n    void main(){vColor=color;vTwk=sin(uTime*2.2+twinkle)*0.5+0.5;vec4 mv=modelViewMatrix*vec4(position,1.);gl_PointSize=size*uPixelRatio*(280.\/-mv.z);gl_Position=projectionMatrix*mv;}`,\n  fragmentShader:`varying vec3 vColor;varying float vTwk;\n    void main(){float d=distance(gl_PointCoord,vec2(0.5));if(d>0.5)discard;float a=(1.-smoothstep(0.,0.5,d))*(0.25+vTwk*0.75);gl_FragColor=vec4(vColor,a);}`,\n  transparent:true,vertexColors:true,blending:THREE.AdditiveBlending,depthWrite:false,\n});\nconst stars=new THREE.Points(sGeo,starMat);\nscene.add(stars);\n\n\/\/ \u2500\u2500 Black hole \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nconst bhMesh=new THREE.Mesh(new THREE.SphereGeometry(BH_RADIUS,96,64),new THREE.MeshBasicMaterial({color:0}));\nbhMesh.renderOrder=0; scene.add(bhMesh);\n\nconst photonMat=new THREE.ShaderMaterial({\n  uniforms:{uTime:{value:0},uCamPos:{value:camera.position}},\n  vertexShader:`varying vec3 vN,vP;void main(){vN=normalize(normalMatrix*normal);vP=position;gl_Position=projectionMatrix*modelViewMatrix*vec4(position,1.);}`,\n  fragmentShader:`uniform float uTime;uniform vec3 uCamPos;varying vec3 vN,vP;\n    void main(){vec3 vd=normalize(uCamPos-vP);float f=pow(1.-abs(dot(vN,vd)),2.2);float p=sin(uTime*2.2)*0.12+0.88;\n    vec3 c=mix(vec3(2.,1.3,.3),vec3(3.,2.6,1.8),pow(f,.4));gl_FragColor=vec4(c*p,f*0.45);}`,\n  transparent:true,blending:THREE.AdditiveBlending,side:THREE.BackSide,depthWrite:false,\n});\nscene.add(new THREE.Mesh(new THREE.SphereGeometry(BH_RADIUS*1.08,96,64),photonMat));\nscene.add(new THREE.Mesh(new THREE.SphereGeometry(BH_RADIUS*4.5,32,32),new THREE.ShaderMaterial({\n  transparent:true,blending:THREE.AdditiveBlending,side:THREE.BackSide,depthWrite:false,\n  vertexShader:`varying vec3 vN;void main(){vN=normalize(normalMatrix*normal);gl_Position=projectionMatrix*modelViewMatrix*vec4(position,1.);}`,\n  fragmentShader:`varying vec3 vN;void main(){float r=pow(1.-abs(dot(vN,vec3(0,0,1))),5.);gl_FragColor=vec4(.35,.12,0.,r*.25);}`,\n})));\n\n\/\/ \u2500\u2500 Accretion disk \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nconst diskGeo=new THREE.RingGeometry(DISK_INNER,DISK_OUTER,320,160);\nconst diskMat=new THREE.ShaderMaterial({\n  uniforms:{\n    uTime:{value:0},\n    uColorHot:{value:new THREE.Color(1.0,0.98,0.92)},\n    uColorA:{value:new THREE.Color(1.0,0.85,0.50)},\n    uColorB:{value:new THREE.Color(1.0,0.60,0.15)},\n    uColorC:{value:new THREE.Color(0.85,0.28,0.04)},\n    uColorOuter:{value:new THREE.Color(0.30,0.06,0.01)},\n    uNoiseScale:{value:2.2},uFlowSpeed:{value:0.20},uDensity:{value:1.25},\n  },\n  vertexShader:`varying vec2 vUv;varying float vRadius,vAngle;\n    void main(){vUv=uv;vRadius=length(position.xy);vAngle=atan(position.y,position.x);gl_Position=projectionMatrix*modelViewMatrix*vec4(position,1.);}`,\n  fragmentShader:`\n    uniform float uTime,uNoiseScale,uFlowSpeed,uDensity;\n    uniform vec3 uColorHot,uColorA,uColorB,uColorC,uColorOuter;\n    varying vec2 vUv;varying float vRadius,vAngle;\n    vec3 mod289(vec3 x){return x-floor(x*(1.\/289.))*289.;}\n    vec4 mod289(vec4 x){return x-floor(x*(1.\/289.))*289.;}\n    vec4 permute(vec4 x){return mod289(((x*34.)+1.)*x);}\n    vec4 taylorInvSqrt(vec4 r){return 1.79284291400159-0.85373472095314*r;}\n    float snoise(vec3 v){\n      const vec2 C=vec2(1.\/6.,1.\/3.);const vec4 D=vec4(0.,.5,1.,2.);\n      vec3 i=floor(v+dot(v,C.yyy));vec3 x0=v-i+dot(i,C.xxx);\n      vec3 g=step(x0.yzx,x0.xyz);vec3 l=1.-g;\n      vec3 i1=min(g.xyz,l.zxy);vec3 i2=max(g.xyz,l.zxy);\n      vec3 x1=x0-i1+C.xxx;vec3 x2=x0-i2+C.yyy;vec3 x3=x0-D.yyy;\n      i=mod289(i);\n      vec4 p=permute(permute(permute(i.z+vec4(0.,i1.z,i2.z,1.))+i.y+vec4(0.,i1.y,i2.y,1.))+i.x+vec4(0.,i1.x,i2.x,1.));\n      float n_=0.142857142857;vec3 ns=n_*D.wyz-D.xzx;\n      vec4 j=p-49.*floor(p*ns.z*ns.z);vec4 x_=floor(j*ns.z);vec4 y_=floor(j-7.*x_);\n      vec4 x=x_*ns.x+ns.yyyy;vec4 y=y_*ns.x+ns.yyyy;vec4 h=1.-abs(x)-abs(y);\n      vec4 b0=vec4(x.xy,y.xy);vec4 b1=vec4(x.zw,y.zw);\n      vec4 s0=floor(b0)*2.+1.;vec4 s1=floor(b1)*2.+1.;vec4 sh=-step(h,vec4(0.));\n      vec4 a0=b0.xzyw+s0.xzyw*sh.xxyy;vec4 a1=b1.xzyw+s1.xzyw*sh.zzww;\n      vec3 p0=vec3(a0.xy,h.x);vec3 p1=vec3(a0.zw,h.y);vec3 p2=vec3(a1.xy,h.z);vec3 p3=vec3(a1.zw,h.w);\n      vec4 norm=taylorInvSqrt(vec4(dot(p0,p0),dot(p1,p1),dot(p2,p2),dot(p3,p3)));\n      p0*=norm.x;p1*=norm.y;p2*=norm.z;p3*=norm.w;\n      vec4 m=max(0.6-vec4(dot(x0,x0),dot(x1,x1),dot(x2,x2),dot(x3,x3)),0.);m=m*m;\n      return 42.*dot(m*m,vec4(dot(p0,x0),dot(p1,x1),dot(p2,x2),dot(p3,x3)));\n    }\n    void main(){\n      float normR=smoothstep(${DISK_INNER.toFixed(3)},${DISK_OUTER.toFixed(3)},vRadius);\n      float spiral=vAngle*3.-(1.\/(normR+0.1))*2.;\n      vec2 flowUv=vec2(vUv.x+uTime*uFlowSpeed*(2.\/(vRadius*0.3+1.))+sin(spiral)*0.1,vUv.y*0.8+cos(spiral)*0.1);\n      float n1=snoise(vec3(flowUv*uNoiseScale,uTime*0.14));\n      float n2=snoise(vec3(flowUv*uNoiseScale*3.2+0.8,uTime*0.21));\n      float n3=snoise(vec3(flowUv*uNoiseScale*6.5+1.5,uTime*0.30));\n      float n=(n1*0.45+n2*0.35+n3*0.20);n=(n+1.)*0.5;\n      vec3 col=uColorOuter;\n      col=mix(col,uColorC,smoothstep(0.00,0.22,normR));\n      col=mix(col,uColorB,smoothstep(0.18,0.52,normR));\n      col=mix(col,uColorA,smoothstep(0.48,0.76,normR));\n      col=mix(col,uColorHot,smoothstep(0.72,0.96,normR));\n      col*=(0.45+n*1.1);\n      float brightness=pow(1.-normR,1.1)*3.8+0.4;brightness*=(0.25+n*2.4);\n      float pulse=sin(uTime*1.6+normR*11.+vAngle*2.)*0.12+0.88;brightness*=pulse;\n      float alpha=uDensity*(0.18+n*0.92);\n      alpha*=smoothstep(0.00,0.12,normR);alpha*=(1.-smoothstep(0.88,1.00,normR));alpha=clamp(alpha,0.,1.);\n      gl_FragColor=vec4(col*brightness,alpha);\n    }\n  `,\n  transparent:true,side:THREE.DoubleSide,depthWrite:false,blending:THREE.AdditiveBlending,\n});\nconst disk=new THREE.Mesh(diskGeo,diskMat);\ndisk.rotation.x=DISK_TILT; disk.renderOrder=1; scene.add(disk);\n\n\/\/ \u2500\u2500 Lensed arc \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nconst ARC_N=6000;\nconst aPos=new Float32Array(ARC_N*3),aCol=new Float32Array(ARC_N*3),aSiz=new Float32Array(ARC_N);\nconst tc=document.createElement('canvas');tc.width=tc.height=64;\nconst tctx=tc.getContext('2d'),tcx=32,tg=tctx.createRadialGradient(tcx,tcx,0,tcx,tcx,tcx);\ntg.addColorStop(0,'rgba(255,255,255,1)');tg.addColorStop(0.2,'rgba(255,230,160,.7)');\ntg.addColorStop(0.6,'rgba(255,180,60,.15)');tg.addColorStop(1,'rgba(0,0,0,0)');\ntctx.fillStyle=tg;tctx.fillRect(0,0,64,64);\nconst spriteTex=new THREE.CanvasTexture(tc);spriteTex.needsUpdate=true;\nfor(let i=0;i<ARC_N;i++){\n  const t=(Math.random()-0.5)*Math.PI*1.75,r=BH_RADIUS*1.1+Math.random()*3.5,c=1-Math.abs(t)\/Math.PI;\n  const ah=BH_RADIUS*1.05*Math.sin(Math.PI*c);\n  aPos[i*3]=r*Math.cos(t);aPos[i*3+1]=ah+(Math.random()-0.5)*0.35;aPos[i*3+2]=r*Math.sin(t)*0.25;\n  const br=0.5+c*2.0+Math.random()*0.4;aCol[i*3]=br*2.6;aCol[i*3+1]=br*2.0;aCol[i*3+2]=br*0.8;\n  aSiz[i]=0.2+c*1.0+Math.random()*0.4;\n}\nconst aGeo=new THREE.BufferGeometry();\naGeo.setAttribute('position',new THREE.BufferAttribute(aPos,3));\naGeo.setAttribute('color',new THREE.BufferAttribute(aCol,3));\naGeo.setAttribute('size',new THREE.BufferAttribute(aSiz,1));\nscene.add(new THREE.Points(aGeo,new THREE.PointsMaterial({\n  size:0.08,map:spriteTex,vertexColors:true,transparent:true,opacity:0.7,\n  blending:THREE.AdditiveBlending,depthWrite:false,sizeAttenuation:true,\n})));\n\n\/\/ \u2500\u2500 Loop \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nconst clock=new THREE.Clock(),bhProj=new THREE.Vector3();\nfunction animate(){\n  requestAnimationFrame(animate);\n  const t=clock.getElapsedTime(),dt=clock.getDelta();\n  diskMat.uniforms.uTime.value=t;\n  starMat.uniforms.uTime.value=t;\n  photonMat.uniforms.uTime.value=t;\n  photonMat.uniforms.uCamPos.value.copy(camera.position);\n  bhProj.copy(bhMesh.position).project(camera);\n  lensingPass.uniforms.bhScreenPos.value.set((bhProj.x+1)\/2,(bhProj.y+1)\/2);\n  stars.rotation.y+=dt*0.002;\n  disk.rotation.z+=dt*0.004;\n  controls.update();\n  composer.render(dt);\n}\nanimate();\n\n\/\/ \u2500\u2500 Resize \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nlet rTimer;\nwindow.addEventListener('resize',()=>{\n  clearTimeout(rTimer);\n  rTimer=setTimeout(()=>{\n    camera.aspect=innerWidth\/innerHeight; camera.updateProjectionMatrix();\n    renderer.setSize(innerWidth,innerHeight); composer.setSize(innerWidth,innerHeight);\n    bloomPass.resolution.set(innerWidth,innerHeight);\n    lensingPass.uniforms.aspectRatio.value=innerWidth\/innerHeight;\n    renderer.setPixelRatio(Math.min(devicePixelRatio,1.5));\n  },150);\n});\n\n\/\/ \u2500\u2500 API p\u00fablica + notificar que est\u00e1 lista \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nwindow.DIBH = {\n  setAutoRotate:  v => { controls.autoRotate = v; },\n  setRotateSpeed: v => { controls.autoRotateSpeed = v; },\n  setBloom:       v => { bloomPass.strength = v; },\n  setLensing:     v => { lensingPass.uniforms.lensingStrength.value = v; },\n  resetCamera:    () => { camera.position.copy(CAM_DEFAULT); controls.target.set(0,0,0); controls.update(); },\n};\n\n\/\/ Desencolar comandos pendientes del panel de controles\nwindow._dibhReady(window.DIBH);\n})();\n<\/script>\n\n<\/body>\n<\/html>\n","protected":false},"excerpt":{"rendered":"<p>Dialelo Creative Intelligence Platform Where ideas collapseinto clarity Dialelo conecta equipos creativos con el poder de la inteligencia artificial. Un horizonte de eventos para tus ideas m\u00e1s ambiciosas. Dialelo.io Solicita acceso anticipado Nombre Email Solicitar acceso \u2726 Recibido, gracias. Te avisaremos en cuanto abramos el acceso. Sin spam. Cancelaci\u00f3n inmediata. \u00a9 2025 Dialelo. Todos los [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"page-template-blank.php","meta":{"_et_pb_use_builder":"off","_et_pb_old_content":"<!-- wp:html -->\n<!DOCTYPE html>\n<html lang=\"es\">\n<head>\n<meta charset=\"UTF-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n<meta name=\"description\" content=\"Dialelo \u2014 Conecta con la siguiente generaci\u00f3n de inteligencia creativa.\">\n<title>Dialelo<\/title>\n<link rel=\"preconnect\" href=\"https:\/\/fonts.googleapis.com\">\n<link href=\"https:\/\/fonts.googleapis.com\/css2?family=DM+Sans:ital,wght@0,300;0,400;0,500;1,300&family=DM+Mono:wght@300;400&display=swap\" rel=\"stylesheet\">\n\n<style>\n\/* \u2500\u2500 Reset \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\n*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }\n\n:root {\n  --gold:         rgba(255, 175, 50, 0.92);\n  --gold-dim:     rgba(255, 185, 70, 0.55);\n  --text:         rgba(255, 245, 220, 0.90);\n  --muted:        rgba(255, 215, 140, 0.38);\n  --glass-bg:     rgba(10, 6, 0, 0.45);\n  --glass-border: rgba(255, 255, 255, 0.11);\n  --f: 'DM Sans', system-ui, sans-serif;\n  --m: 'DM Mono', monospace;\n}\n\nhtml, body {\n  width: 100%; height: 100%;\n  background: #000;\n  font-family: var(--f);\n  color: var(--text);\n  overflow-x: hidden;\n}\n\n\/* \u2500\u2500 Canvas fixed background \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\n#bh-canvas {\n  position: fixed;\n  inset: 0; width: 100%; height: 100%;\n  z-index: 0;\n}\n\n\/* \u2500\u2500 Dark vignette overlay \u2014 makes text legible over the glow \u2500\u2500 *\/\n#vignette {\n  position: fixed;\n  inset: 0;\n  z-index: 1;\n  pointer-events: none;\n  \/* Radial dark center + edge darken *\/\n  background:\n    radial-gradient(ellipse 70% 60% at 50% 50%,\n      rgba(0,0,0,0.55) 0%,\n      rgba(0,0,0,0.0) 100%),\n    radial-gradient(ellipse 120% 100% at 50% 50%,\n      transparent 40%,\n      rgba(0,0,0,0.5) 100%);\n}\n\n\/* \u2500\u2500 Page layout \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\n#page {\n  position: relative;\n  z-index: 10;\n  min-height: 100vh;\n  display: flex;\n  flex-direction: column;\n}\n\n\/* \u2500\u2500 Nav \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\nnav {\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  padding: 28px 48px;\n  flex-shrink: 0;\n}\n\n.nav-logo img {\n  height: 28px;\n  width: auto;\n  display: block;\n  \/* Logo is white on black \u2014 make background transparent *\/\n  mix-blend-mode: screen;\n  filter: brightness(0) invert(1);\n  opacity: 0.85;\n}\n\n.nav-dot {\n  width: 7px; height: 7px;\n  border-radius: 50%;\n  background: var(--gold);\n  box-shadow: 0 0 10px rgba(255,160,40,0.9);\n  animation: pulse 2.8s ease-in-out infinite;\n}\n@keyframes pulse {\n  0%,100% { opacity: 1; transform: scale(1); }\n  50%      { opacity: 0.45; transform: scale(1.6); }\n}\n\n\/* \u2500\u2500 Hero \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\n#hero {\n  flex: 1;\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n  justify-content: center;\n  text-align: center;\n  padding: 40px 24px 60px;\n  gap: 20px;\n}\n\n.hero-eyebrow {\n  font-family: var(--m);\n  font-size: 10px;\n  letter-spacing: 0.32em;\n  text-transform: uppercase;\n  color: rgba(255, 185, 70, 0.5);\n  \/* text-shadow for extra legibility *\/\n  text-shadow: 0 0 20px rgba(0,0,0,0.8), 0 2px 8px rgba(0,0,0,1);\n  opacity: 0;\n  transform: translateY(10px);\n  animation: fadeUp 1.2s cubic-bezier(0.22,1,0.36,1) 0.3s forwards;\n}\n\n.hero-title {\n  font-size: clamp(34px, 5.5vw, 72px);\n  font-weight: 300;\n  line-height: 1.08;\n  letter-spacing: -0.028em;\n  color: rgba(255, 250, 235, 0.96);\n  \/* Strong shadow to cut through the glow *\/\n  text-shadow:\n    0 0 40px rgba(0,0,0,0.95),\n    0 4px 24px rgba(0,0,0,1),\n    0 8px 40px rgba(0,0,0,0.8);\n  max-width: 800px;\n  opacity: 0;\n  transform: translateY(14px);\n  animation: fadeUp 1.2s cubic-bezier(0.22,1,0.36,1) 0.6s forwards;\n}\n.hero-title em {\n  font-style: italic;\n  color: rgba(255, 210, 100, 0.95);\n  text-shadow:\n    0 0 40px rgba(0,0,0,0.95),\n    0 4px 24px rgba(0,0,0,1),\n    0 0 80px rgba(255,160,40,0.3);\n}\n\n.hero-sub {\n  font-size: clamp(13px, 1.4vw, 16px);\n  font-weight: 300;\n  line-height: 1.75;\n  color: rgba(255, 220, 160, 0.55);\n  max-width: 480px;\n  text-shadow: 0 2px 12px rgba(0,0,0,1), 0 0 30px rgba(0,0,0,0.9);\n  opacity: 0;\n  transform: translateY(14px);\n  animation: fadeUp 1.2s cubic-bezier(0.22,1,0.36,1) 0.9s forwards;\n}\n\n@keyframes fadeUp {\n  to { opacity: 1; transform: translateY(0); }\n}\n\n\/* \u2500\u2500 Liquid Glass Form \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\n.form-wrap {\n  opacity: 0;\n  transform: translateY(18px);\n  animation: fadeUp 1.4s cubic-bezier(0.22,1,0.36,1) 1.2s forwards;\n  width: 100%;\n  display: flex;\n  justify-content: center;\n  margin-top: 12px;\n}\n\n.form-card {\n  width: 100%;\n  max-width: 400px;\n  \/* Darker glass \u2014 much more opaque to ensure legibility *\/\n  background: rgba(8, 4, 0, 0.72);\n  backdrop-filter: blur(40px) saturate(160%);\n  -webkit-backdrop-filter: blur(40px) saturate(160%);\n  border: 1px solid rgba(255, 200, 80, 0.14);\n  border-radius: 22px;\n  padding: 36px 32px 30px;\n  box-shadow:\n    0 32px 80px rgba(0,0,0,0.7),\n    0 0 0 0.5px rgba(255,220,100,0.06) inset,\n    0 1px 0 rgba(255,200,80,0.10) inset;\n  position: relative;\n  overflow: hidden;\n}\n\n\/* Top shimmer line *\/\n.form-card::before {\n  content: '';\n  position: absolute;\n  top: 0; left: 20%; right: 20%;\n  height: 1px;\n  background: linear-gradient(90deg, transparent, rgba(255,200,80,0.25), transparent);\n  pointer-events: none;\n}\n\n.form-header {\n  text-align: center;\n  margin-bottom: 28px;\n}\n.form-logo {\n  font-family: var(--m);\n  font-size: 11px;\n  letter-spacing: 0.28em;\n  text-transform: uppercase;\n  color: rgba(255, 210, 120, 0.6);\n  margin-bottom: 5px;\n}\n.form-tagline {\n  font-size: 12px;\n  color: rgba(255, 185, 60, 0.35);\n  font-style: italic;\n  font-weight: 300;\n}\n\n\/* Fields *\/\n.field { margin-bottom: 16px; }\n.field label {\n  display: block;\n  font-family: var(--m);\n  font-size: 9px;\n  letter-spacing: 0.16em;\n  text-transform: uppercase;\n  color: rgba(255, 195, 90, 0.45);\n  margin-bottom: 7px;\n}\n.field input {\n  width: 100%;\n  background: rgba(255, 255, 255, 0.05);\n  border: 1px solid rgba(255, 255, 255, 0.08);\n  border-radius: 9px;\n  padding: 12px 14px;\n  font-family: var(--f);\n  font-size: 14px;\n  font-weight: 300;\n  color: rgba(255, 245, 220, 0.92);\n  outline: none;\n  transition: border-color 0.2s, background 0.2s, box-shadow 0.2s;\n  -webkit-appearance: none;\n}\n.field input::placeholder { color: rgba(255,255,255,0.16); }\n.field input:focus {\n  border-color: rgba(255, 165, 40, 0.42);\n  background: rgba(255, 255, 255, 0.07);\n  box-shadow: 0 0 0 3px rgba(255,148,28,0.08);\n}\n\n\/* Submit *\/\n.submit-btn {\n  width: 100%;\n  margin-top: 6px;\n  padding: 14px;\n  background: rgba(255, 158, 40, 0.88);\n  border: none;\n  border-radius: 9px;\n  font-family: var(--f);\n  font-size: 14px;\n  font-weight: 500;\n  letter-spacing: 0.03em;\n  color: #060200;\n  cursor: pointer;\n  box-shadow: 0 8px 28px rgba(255,138,24,0.32), 0 1px 0 rgba(255,220,100,0.25) inset;\n  transition: all 0.22s ease;\n  position: relative;\n  overflow: hidden;\n}\n.submit-btn::after {\n  content: '';\n  position: absolute; inset: 0;\n  background: linear-gradient(to bottom, rgba(255,255,255,0.08), transparent);\n  pointer-events: none;\n}\n.submit-btn:hover {\n  background: rgba(255, 175, 58, 1);\n  box-shadow: 0 12px 36px rgba(255,145,20,0.48);\n  transform: translateY(-1px);\n}\n.submit-btn:active { transform: translateY(0); }\n.submit-btn:disabled { opacity: 0.55; cursor: not-allowed; transform: none; }\n\n\/* Success *\/\n.form-success {\n  display: none;\n  text-align: center;\n  padding: 24px 0 8px;\n}\n.form-success .icon { font-size: 32px; display: block; margin-bottom: 12px; }\n.form-success h3 { font-size: 17px; font-weight: 400; color: rgba(255,245,215,0.9); margin-bottom: 6px; }\n.form-success p { font-size: 13px; color: rgba(255,200,100,0.4); }\n\n.form-legal {\n  text-align: center;\n  font-size: 11px;\n  color: rgba(255,255,255,0.16);\n  margin-top: 16px;\n  line-height: 1.5;\n}\n\n\/* \u2500\u2500 Controls panel \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\n#bh-controls {\n  position: fixed;\n  bottom: 22px; right: 22px;\n  z-index: 100;\n  background: rgba(6, 3, 0, 0.85);\n  backdrop-filter: blur(20px);\n  -webkit-backdrop-filter: blur(20px);\n  border: 1px solid rgba(255, 175, 50, 0.13);\n  border-radius: 14px;\n  padding: 15px 17px;\n  display: flex;\n  flex-direction: column;\n  gap: 12px;\n  min-width: 168px;\n  opacity: 0;\n  animation: fadeUp 0.8s cubic-bezier(0.22,1,0.36,1) 2s forwards;\n}\n.ctrl-title {\n  font-family: var(--m);\n  font-size: 9px;\n  letter-spacing: 0.2em;\n  text-transform: uppercase;\n  color: rgba(255,175,50,0.38);\n}\n.ctrl-row { display: flex; flex-direction: column; gap: 5px; }\n.ctrl-label {\n  display: flex;\n  justify-content: space-between;\n  align-items: center;\n}\n.ctrl-label span:first-child { font-size: 11px; color: rgba(255,200,100,0.52); }\n.ctrl-val {\n  font-family: var(--m);\n  font-size: 10px;\n  color: rgba(255,200,100,0.38);\n  min-width: 30px;\n  text-align: right;\n}\ninput[type=range] {\n  width: 100%; height: 3px;\n  appearance: none; -webkit-appearance: none;\n  background: rgba(255,255,255,0.1);\n  border-radius: 2px; outline: none; cursor: pointer;\n}\ninput[type=range]::-webkit-slider-thumb {\n  -webkit-appearance: none;\n  width: 13px; height: 13px;\n  border-radius: 50%;\n  background: rgba(255,165,38,0.92);\n  cursor: pointer;\n  box-shadow: 0 0 8px rgba(255,140,18,0.65);\n}\n\n.ctrl-toggle {\n  display: flex; align-items: center; justify-content: space-between;\n}\n.ctrl-toggle span { font-size: 11px; color: rgba(255,200,100,0.52); }\n.tog {\n  width: 32px; height: 17px;\n  border-radius: 10px;\n  background: rgba(255,255,255,0.1);\n  cursor: pointer; position: relative;\n  transition: background 0.2s; border: none; flex-shrink: 0;\n}\n.tog.on { background: rgba(255,150,28,0.75); }\n.tog::after {\n  content: '';\n  position: absolute;\n  top: 2.5px; left: 2.5px;\n  width: 12px; height: 12px;\n  border-radius: 50%; background: #fff;\n  transition: transform 0.18s ease;\n}\n.tog.on::after { transform: translateX(15px); }\n\n.ctrl-reset {\n  width: 100%; padding: 7px;\n  background: transparent;\n  border: 1px solid rgba(255,175,50,0.16);\n  border-radius: 7px;\n  color: rgba(255,185,65,0.45);\n  font-family: var(--m);\n  font-size: 10px; letter-spacing: 0.08em;\n  cursor: pointer; transition: all 0.2s;\n}\n.ctrl-reset:hover {\n  border-color: rgba(255,175,50,0.38);\n  color: rgba(255,200,95,0.75);\n  background: rgba(255,148,24,0.06);\n}\n\n\/* \u2500\u2500 Footer \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\nfooter {\n  position: relative; z-index: 10;\n  padding: 22px 48px;\n  display: flex; align-items: center; justify-content: space-between;\n  border-top: 1px solid rgba(255,255,255,0.04);\n  flex-shrink: 0;\n}\nfooter p, footer a { font-size: 11px; color: rgba(255,255,255,0.16); font-family: var(--m); }\nfooter a { text-decoration: none; transition: color 0.2s; }\nfooter a:hover { color: rgba(255,190,60,0.5); }\n\n\/* \u2500\u2500 Responsive \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\n@media (max-width: 600px) {\n  nav { padding: 20px 22px; }\n  .nav-logo img { height: 22px; }\n  #hero { padding: 30px 18px 50px; }\n  .form-card { padding: 28px 20px 24px; border-radius: 18px; }\n  #bh-controls { display: none; }\n  footer { padding: 18px 22px; flex-direction: column; gap: 6px; text-align: center; }\n}\n<\/style>\n<\/head>\n<body>\n\n<canvas id=\"bh-canvas\"><\/canvas>\n<div id=\"vignette\"><\/div>\n\n<div id=\"page\">\n\n  <nav>\n    <div class=\"nav-logo\">\n      <img src=\"data:image\/png;base64,\/9j\/4AAQSkZJRgABAQAAAQABAAD\/4gHYSUNDX1BST0ZJTEUAAQEAAAHIAAAAAAQwAABtbnRyUkdCIFhZWiAH4AABAAEAAAAAAABhY3NwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAA9tYAAQAAAADTLQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlkZXNjAAAA8AAAACRyWFlaAAABFAAAABRnWFlaAAABKAAAABRiWFlaAAABPAAAABR3dHB0AAABUAAAABRyVFJDAAABZAAAAChnVFJDAAABZAAAAChiVFJDAAABZAAAAChjcHJ0AAABjAAAADxtbHVjAAAAAAAAAAEAAAAMZW5VUwAAAAgAAAAcAHMAUgBHAEJYWVogAAAAAAAAb6IAADj1AAADkFhZWiAAAAAAAABimQAAt4UAABjaWFlaIAAAAAAAACSgAAAPhAAAts9YWVogAAAAAAAA9tYAAQAAAADTLXBhcmEAAAAAAAQAAAACZmYAAPKnAAANWQAAE9AAAApbAAAAAAAAAABtbHVjAAAAAAAAAAEAAAAMZW5VUwAAACAAAAAcAEcAbwBvAGcAbABlACAASQBuAGMALgAgADIAMAAxADb\/2wBDAAUDBAQEAwUEBAQFBQUGBwwIBwcHBw8LCwkMEQ8SEhEPERETFhwXExQaFRERGCEYGh0dHx8fExciJCIeJBweHx7\/2wBDAQUFBQcGBw4ICA4eFBEUHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh7\/wAARCABgAR4DASIAAhEBAxEB\/8QAHQABAAIDAQEBAQAAAAAAAAAAAAcIBQYJBAMCAf\/EAE0QAAEDAwIDBAQICwUFCQAAAAECAwQABQYHEQgSITFBUWETFCJxFTJCUmJ1gbMJFiM2OHKCkZKhshczdKLSGCQ1Y7E3Q1VWc4WVwdH\/xAAUAQEAAAAAAAAAAAAAAAAAAAAA\/8QAFBEBAAAAAAAAAAAAAAAAAAAAAP\/aAAwDAQACEQMRAD8AplSlKBSt+0a0lzDVS9qg45DCYjJHrdwkbpjxgfnK71HuSNyfIbkTvdrXw7aCAwrrGVqTmjPR1hfKY7Cx3LT1bb6jsPpFjwG9BVi1We73ZZRarVOnqHamNHW6f8oNZR7BM4YZU89huRNtJ7VrtjwSPtKalfLOKnUy4tmHjXwViNtT0aj2yIjmSnwK1g9fNIT7qj2VqvqpOeK3NQssWtR7EXV9I+wJUBQaW62404pt1tTa0nZSVDYj3ivxWSvt6vd6fS7e7lNuDyNwHJTqnFjx6q60s1gvt6eDFmstxuLqugRFirdJ+xINBjaAb1O+nvCrqrlDrbtztzOMwVbFT1xXs5t5NJ3Vv5K5ffVstGOG7ANOHGbmthV\/vrWykz5yBytK8Wmvio8ieZQ+dQVb0L4Wsvzj0F3yj02M2BeywXW\/97kJ\/wCW2fiAj5S\/EEJUKlHX\/JtNNDdPLjpZgdkgv328wyxcC5+VUy0tJHpH1nqpwgkoR0Cd+bYDlCt64reIKHprAcxnGXWZWXyW+u+y0W5Ch0ccHYXCOqUHyUrpsFc97jNl3KfIuFwlPSpclxTr77yytbi1HcqUT1JJ67156UoN7xDWDUvFIqYdmy+4phJASmJJKZLCR4Bt0KSke4Ct0t3E9qLC2Um3Yk46P+9VZW0r38fY5ahClBNF\/4odZ7swphOTt25pQ2Igw2mj9iuUqH2Gomvt6vF+uC7he7rNucxfxn5b6nVn9pRJrwUoFKUoFKUoFKUoFKUoFKUoFKUoFKUoFKUoFKUoFKUoFKUoFKUoFKUoFKUoP\/2Q==\" alt=\"Dialelo\">\n    <\/div>\n    <div class=\"nav-dot\"><\/div>\n  <\/nav>\n\n  <section id=\"hero\">\n    <p class=\"hero-eyebrow\">Creative Intelligence Platform<\/p>\n    <h1 class=\"hero-title\">\n      Where ideas <em>collapse<\/em><br>into clarity\n    <\/h1>\n    <p class=\"hero-sub\">\n      Dialelo conecta equipos creativos con el poder de la inteligencia artificial.\n      Un horizonte de eventos para tus ideas m\u00e1s ambiciosas.\n    <\/p>\n\n    <div class=\"form-wrap\">\n      <div class=\"form-card\">\n        <div class=\"form-header\">\n          <div class=\"form-logo\">Dialelo.io<\/div>\n          <div class=\"form-tagline\">Solicita acceso anticipado<\/div>\n        <\/div>\n\n        <form id=\"contact-form\">\n          <div class=\"field\">\n            <label for=\"nombre\">Nombre<\/label>\n            <input type=\"text\" id=\"nombre\" name=\"nombre\" placeholder=\"Tu nombre\" required autocomplete=\"given-name\">\n          <\/div>\n          <div class=\"field\">\n            <label for=\"apellidos\">Apellidos<\/label>\n            <input type=\"text\" id=\"apellidos\" name=\"apellidos\" placeholder=\"Tus apellidos\" required autocomplete=\"family-name\">\n          <\/div>\n          <div class=\"field\">\n            <label for=\"email\">Email<\/label>\n            <input type=\"email\" id=\"email\" name=\"email\" placeholder=\"tu@email.com\" required autocomplete=\"email\">\n          <\/div>\n          <button type=\"submit\" class=\"submit-btn\" id=\"submit-btn\">\n            Solicitar acceso\n          <\/button>\n        <\/form>\n\n        <div class=\"form-success\" id=\"form-success\">\n          <span class=\"icon\">\u2726<\/span>\n          <h3>Recibido, gracias.<\/h3>\n          <p>Te avisaremos en cuanto abramos el acceso.<\/p>\n        <\/div>\n\n        <p class=\"form-legal\">Sin spam. Cancelaci\u00f3n inmediata.<\/p>\n      <\/div>\n    <\/div>\n  <\/section>\n\n  <footer>\n    <p>\u00a9 2025 Dialelo. Todos los derechos reservados.<\/p>\n    <p><a href=\"#\">Privacidad<\/a> &nbsp;\u00b7&nbsp; <a href=\"#\">T\u00e9rminos<\/a><\/p>\n  <\/footer>\n<\/div>\n\n<!-- Controls panel -->\n<div id=\"bh-controls\">\n  <div class=\"ctrl-title\">Agujero negro<\/div>\n\n  <div class=\"ctrl-toggle\">\n    <span>Auto-rotaci\u00f3n<\/span>\n    <button class=\"tog on\" id=\"tog-rot\"><\/button>\n  <\/div>\n\n  <div class=\"ctrl-row\">\n    <div class=\"ctrl-label\">\n      <span>Bloom<\/span>\n      <span class=\"ctrl-val\" id=\"val-bloom\">0.75<\/span>\n    <\/div>\n    <input type=\"range\" id=\"sl-bloom\" min=\"0\" max=\"2\" step=\"0.05\" value=\"0.75\">\n  <\/div>\n\n  <div class=\"ctrl-row\">\n    <div class=\"ctrl-label\">\n      <span>Velocidad<\/span>\n      <span class=\"ctrl-val\" id=\"val-speed\">0.08<\/span>\n    <\/div>\n    <input type=\"range\" id=\"sl-speed\" min=\"0.01\" max=\"0.5\" step=\"0.01\" value=\"0.08\">\n  <\/div>\n\n  <div class=\"ctrl-row\">\n    <div class=\"ctrl-label\">\n      <span>Lensing<\/span>\n      <span class=\"ctrl-val\" id=\"val-lens\">0.10<\/span>\n    <\/div>\n    <input type=\"range\" id=\"sl-lens\" min=\"0\" max=\"0.25\" step=\"0.005\" value=\"0.10\">\n  <\/div>\n\n  <button class=\"ctrl-reset\" id=\"btn-reset\">Reset c\u00e1mara<\/button>\n<\/div>\n\n<!-- \u2500\u2500 Form handler \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n<script>\ndocument.getElementById('contact-form').addEventListener('submit', async function(e) {\n  e.preventDefault();\n  const btn = document.getElementById('submit-btn');\n  btn.disabled = true;\n  btn.textContent = 'Enviando\u2026';\n\n  const data = {\n    nombre:    this.nombre.value,\n    apellidos: this.apellidos.value,\n    email:     this.email.value,\n  };\n\n  \/* \u2500\u2500 Conecta aqu\u00ed tu backend \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n   *\n   * Opci\u00f3n A \u2014 Formspree (recomendado, gratis):\n   *   const res = await fetch('https:\/\/formspree.io\/f\/TU_ID', {\n   *     method: 'POST',\n   *     headers: { 'Content-Type': 'application\/json' },\n   *     body: JSON.stringify(data)\n   *   });\n   *   if (res.ok) { ... mostrar \u00e9xito }\n   *\n   * Opci\u00f3n B \u2014 Tu propio API endpoint:\n   *   await fetch('\/api\/leads', { method:'POST', body: JSON.stringify(data), headers:{'Content-Type':'application\/json'} });\n   *\n   * \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\n\n  \/\/ Demo: simula env\u00edo\n  await new Promise(r => setTimeout(r, 900));\n  document.getElementById('contact-form').style.display = 'none';\n  document.getElementById('form-success').style.display = 'block';\n});\n\n\/\/ \u2500\u2500 Controls \u2014 cola de comandos mientras Three.js carga \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\/\/ Todas las acciones se encolan si DIBH a\u00fan no est\u00e1 disponible\nconst _queue = [];\nlet _ready = false;\n\nwindow._dibhReady = function(api) {\n  _ready = true;\n  _queue.forEach(fn => fn(api));\n};\n\nfunction ctrl(fn) {\n  if (_ready && window.DIBH) fn(window.DIBH);\n  else _queue.push(fn);\n}\n\n\/\/ Toggle autorotaci\u00f3n\ndocument.getElementById('tog-rot').addEventListener('click', function() {\n  this.classList.toggle('on');\n  const on = this.classList.contains('on');\n  ctrl(api => api.setAutoRotate(on));\n});\n\n\/\/ Bloom\ndocument.getElementById('sl-bloom').addEventListener('input', function() {\n  const v = parseFloat(this.value);\n  document.getElementById('val-bloom').textContent = v.toFixed(2);\n  ctrl(api => api.setBloom(v));\n});\n\n\/\/ Velocidad\ndocument.getElementById('sl-speed').addEventListener('input', function() {\n  const v = parseFloat(this.value);\n  document.getElementById('val-speed').textContent = v.toFixed(2);\n  ctrl(api => api.setRotateSpeed(v));\n});\n\n\/\/ Lensing\ndocument.getElementById('sl-lens').addEventListener('input', function() {\n  const v = parseFloat(this.value);\n  document.getElementById('val-lens').textContent = v.toFixed(3);\n  ctrl(api => api.setLensing(v));\n});\n\n\/\/ Reset c\u00e1mara\ndocument.getElementById('btn-reset').addEventListener('click', function() {\n  ctrl(api => api.resetCamera());\n});\n<\/script>\n\n<!-- \u2500\u2500 Three.js + motor agujero negro \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n<script type=\"importmap\">\n{\n  \"imports\": {\n    \"three\":         \"https:\/\/cdn.jsdelivr.net\/npm\/three@0.163.0\/build\/three.module.js\",\n    \"three\/addons\/\": \"https:\/\/cdn.jsdelivr.net\/npm\/three@0.163.0\/examples\/jsm\/\"\n  }\n}\n<\/script>\n\n<script type=\"module\">\nimport * as THREE from 'three';\nimport { OrbitControls }   from 'three\/addons\/controls\/OrbitControls.js';\nimport { EffectComposer }  from 'three\/addons\/postprocessing\/EffectComposer.js';\nimport { RenderPass }      from 'three\/addons\/postprocessing\/RenderPass.js';\nimport { UnrealBloomPass } from 'three\/addons\/postprocessing\/UnrealBloomPass.js';\nimport { ShaderPass }      from 'three\/addons\/postprocessing\/ShaderPass.js';\n\nconst canvas    = document.getElementById('bh-canvas');\nconst BH_RADIUS = 1.3;\nconst DISK_INNER = BH_RADIUS + 0.15;\nconst DISK_OUTER = 8.0;\nconst DISK_TILT  = Math.PI \/ 3.2;\n\n\/\/ \u2500\u2500 Renderer \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nconst renderer = new THREE.WebGLRenderer({ canvas, antialias: true, powerPreference: 'high-performance' });\nrenderer.setSize(innerWidth, innerHeight);\nrenderer.setPixelRatio(Math.min(devicePixelRatio, 1.5));\nrenderer.outputColorSpace   = THREE.SRGBColorSpace;\nrenderer.toneMapping        = THREE.ACESFilmicToneMapping;\nrenderer.toneMappingExposure = 1.35;\n\n\/\/ \u2500\u2500 Scene \/ Camera \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nconst scene  = new THREE.Scene();\nscene.fog    = new THREE.FogExp2(0x020100, 0.022);\nconst camera = new THREE.PerspectiveCamera(58, innerWidth \/ innerHeight, 0.1, 4000);\ncamera.position.set(-6.0, 4.5, 6.5);\nconst CAM_DEFAULT = camera.position.clone();\n\n\/\/ \u2500\u2500 OrbitControls \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nconst controls = new OrbitControls(camera, renderer.domElement);\ncontrols.enableDamping   = true;\ncontrols.dampingFactor   = 0.035;\ncontrols.rotateSpeed     = 0.4;\ncontrols.autoRotate      = true;\ncontrols.autoRotateSpeed = 0.08;\ncontrols.minDistance     = 2.5;\ncontrols.maxDistance     = 80;\ncontrols.enablePan       = false;\ncontrols.target.set(0, 0, 0);\ncontrols.update();\n\n\/\/ \u2500\u2500 Post-processing \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nconst composer  = new EffectComposer(renderer);\ncomposer.addPass(new RenderPass(scene, camera));\nconst bloomPass = new UnrealBloomPass(new THREE.Vector2(innerWidth, innerHeight), 0.75, 0.65, 0.78);\ncomposer.addPass(bloomPass);\n\nconst lensingPass = new ShaderPass({\n  uniforms: {\n    tDiffuse:        { value: null },\n    bhScreenPos:     { value: new THREE.Vector2(0.5, 0.5) },\n    lensingStrength: { value: 0.10 },\n    lensingRadius:   { value: 0.28 },\n    aspectRatio:     { value: innerWidth \/ innerHeight },\n    chromaticAb:     { value: 0.004 },\n  },\n  vertexShader: `varying vec2 vUv; void main(){ vUv=uv; gl_Position=projectionMatrix*modelViewMatrix*vec4(position,1.0); }`,\n  fragmentShader: `\n    uniform sampler2D tDiffuse;\n    uniform vec2 bhScreenPos;\n    uniform float lensingStrength,lensingRadius,aspectRatio,chromaticAb;\n    varying vec2 vUv;\n    void main(){\n      vec2 tc=vUv-bhScreenPos; tc.x*=aspectRatio;\n      float dist=length(tc);\n      float amt=clamp(lensingStrength\/(dist*dist+0.004),0.0,0.65);\n      amt*=smoothstep(lensingRadius,lensingRadius*0.3,dist);\n      vec2 dir=normalize(tc); dir.x\/=aspectRatio;\n      gl_FragColor=vec4(\n        texture2D(tDiffuse,vUv-dir*amt*(1.0+chromaticAb)).r,\n        texture2D(tDiffuse,vUv-dir*amt).g,\n        texture2D(tDiffuse,vUv-dir*amt*(1.0-chromaticAb)).b,\n        1.0\n      );\n    }\n  `\n});\ncomposer.addPass(lensingPass);\n\n\/\/ \u2500\u2500 Stars \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nconst STAR_COUNT = 120000;\nconst sGeo = new THREE.BufferGeometry();\nconst sPos=new Float32Array(STAR_COUNT*3), sCol=new Float32Array(STAR_COUNT*3);\nconst sSiz=new Float32Array(STAR_COUNT),   sTwk=new Float32Array(STAR_COUNT);\nconst sPal=[\n  new THREE.Color(0xffe8c0),new THREE.Color(0xfff0dd),new THREE.Color(0xffffff),\n  new THREE.Color(0xffeebb),new THREE.Color(0xffd090),new THREE.Color(0xffccaa),\n  new THREE.Color(0xaaccff),new THREE.Color(0xffffff),\n];\nfor(let i=0;i<STAR_COUNT;i++){\n  const phi=Math.acos(-1+(2*i)\/STAR_COUNT),theta=Math.sqrt(STAR_COUNT*Math.PI)*phi;\n  const r=Math.cbrt(Math.random())*2000+100;\n  sPos[i*3]=r*Math.sin(phi)*Math.cos(theta); sPos[i*3+1]=r*Math.sin(phi)*Math.sin(theta); sPos[i*3+2]=r*Math.cos(phi);\n  const sc=sPal[Math.floor(Math.random()*sPal.length)].clone(); sc.multiplyScalar(Math.random()*0.6+0.4);\n  sCol[i*3]=sc.r; sCol[i*3+1]=sc.g; sCol[i*3+2]=sc.b;\n  sSiz[i]=THREE.MathUtils.randFloat(0.4,2.5); sTwk[i]=Math.random()*Math.PI*2;\n}\nsGeo.setAttribute('position',new THREE.BufferAttribute(sPos,3));\nsGeo.setAttribute('color',   new THREE.BufferAttribute(sCol,3));\nsGeo.setAttribute('size',    new THREE.BufferAttribute(sSiz,1));\nsGeo.setAttribute('twinkle', new THREE.BufferAttribute(sTwk,1));\nconst starMat=new THREE.ShaderMaterial({\n  uniforms:{uTime:{value:0},uPixelRatio:{value:renderer.getPixelRatio()}},\n  vertexShader:`uniform float uTime,uPixelRatio;attribute float size,twinkle;varying vec3 vColor;varying float vTwk;\n    void main(){vColor=color;vTwk=sin(uTime*2.2+twinkle)*0.5+0.5;vec4 mv=modelViewMatrix*vec4(position,1.);gl_PointSize=size*uPixelRatio*(280.\/-mv.z);gl_Position=projectionMatrix*mv;}`,\n  fragmentShader:`varying vec3 vColor;varying float vTwk;\n    void main(){float d=distance(gl_PointCoord,vec2(0.5));if(d>0.5)discard;float a=(1.-smoothstep(0.,0.5,d))*(0.25+vTwk*0.75);gl_FragColor=vec4(vColor,a);}`,\n  transparent:true,vertexColors:true,blending:THREE.AdditiveBlending,depthWrite:false,\n});\nconst stars=new THREE.Points(sGeo,starMat);\nscene.add(stars);\n\n\/\/ \u2500\u2500 Black hole \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nconst bhMesh=new THREE.Mesh(new THREE.SphereGeometry(BH_RADIUS,96,64),new THREE.MeshBasicMaterial({color:0}));\nbhMesh.renderOrder=0; scene.add(bhMesh);\n\nconst photonMat=new THREE.ShaderMaterial({\n  uniforms:{uTime:{value:0},uCamPos:{value:camera.position}},\n  vertexShader:`varying vec3 vN,vP;void main(){vN=normalize(normalMatrix*normal);vP=position;gl_Position=projectionMatrix*modelViewMatrix*vec4(position,1.);}`,\n  fragmentShader:`uniform float uTime;uniform vec3 uCamPos;varying vec3 vN,vP;\n    void main(){vec3 vd=normalize(uCamPos-vP);float f=pow(1.-abs(dot(vN,vd)),2.2);float p=sin(uTime*2.2)*0.12+0.88;\n    vec3 c=mix(vec3(2.,1.3,.3),vec3(3.,2.6,1.8),pow(f,.4));gl_FragColor=vec4(c*p,f*0.45);}`,\n  transparent:true,blending:THREE.AdditiveBlending,side:THREE.BackSide,depthWrite:false,\n});\nscene.add(new THREE.Mesh(new THREE.SphereGeometry(BH_RADIUS*1.08,96,64),photonMat));\nscene.add(new THREE.Mesh(new THREE.SphereGeometry(BH_RADIUS*4.5,32,32),new THREE.ShaderMaterial({\n  transparent:true,blending:THREE.AdditiveBlending,side:THREE.BackSide,depthWrite:false,\n  vertexShader:`varying vec3 vN;void main(){vN=normalize(normalMatrix*normal);gl_Position=projectionMatrix*modelViewMatrix*vec4(position,1.);}`,\n  fragmentShader:`varying vec3 vN;void main(){float r=pow(1.-abs(dot(vN,vec3(0,0,1))),5.);gl_FragColor=vec4(.35,.12,0.,r*.25);}`,\n})));\n\n\/\/ \u2500\u2500 Accretion disk \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nconst diskGeo=new THREE.RingGeometry(DISK_INNER,DISK_OUTER,320,160);\nconst diskMat=new THREE.ShaderMaterial({\n  uniforms:{\n    uTime:{value:0},\n    uColorHot:{value:new THREE.Color(1.0,0.98,0.92)},\n    uColorA:{value:new THREE.Color(1.0,0.85,0.50)},\n    uColorB:{value:new THREE.Color(1.0,0.60,0.15)},\n    uColorC:{value:new THREE.Color(0.85,0.28,0.04)},\n    uColorOuter:{value:new THREE.Color(0.30,0.06,0.01)},\n    uNoiseScale:{value:2.2},uFlowSpeed:{value:0.20},uDensity:{value:1.25},\n  },\n  vertexShader:`varying vec2 vUv;varying float vRadius,vAngle;\n    void main(){vUv=uv;vRadius=length(position.xy);vAngle=atan(position.y,position.x);gl_Position=projectionMatrix*modelViewMatrix*vec4(position,1.);}`,\n  fragmentShader:`\n    uniform float uTime,uNoiseScale,uFlowSpeed,uDensity;\n    uniform vec3 uColorHot,uColorA,uColorB,uColorC,uColorOuter;\n    varying vec2 vUv;varying float vRadius,vAngle;\n    vec3 mod289(vec3 x){return x-floor(x*(1.\/289.))*289.;}\n    vec4 mod289(vec4 x){return x-floor(x*(1.\/289.))*289.;}\n    vec4 permute(vec4 x){return mod289(((x*34.)+1.)*x);}\n    vec4 taylorInvSqrt(vec4 r){return 1.79284291400159-0.85373472095314*r;}\n    float snoise(vec3 v){\n      const vec2 C=vec2(1.\/6.,1.\/3.);const vec4 D=vec4(0.,.5,1.,2.);\n      vec3 i=floor(v+dot(v,C.yyy));vec3 x0=v-i+dot(i,C.xxx);\n      vec3 g=step(x0.yzx,x0.xyz);vec3 l=1.-g;\n      vec3 i1=min(g.xyz,l.zxy);vec3 i2=max(g.xyz,l.zxy);\n      vec3 x1=x0-i1+C.xxx;vec3 x2=x0-i2+C.yyy;vec3 x3=x0-D.yyy;\n      i=mod289(i);\n      vec4 p=permute(permute(permute(i.z+vec4(0.,i1.z,i2.z,1.))+i.y+vec4(0.,i1.y,i2.y,1.))+i.x+vec4(0.,i1.x,i2.x,1.));\n      float n_=0.142857142857;vec3 ns=n_*D.wyz-D.xzx;\n      vec4 j=p-49.*floor(p*ns.z*ns.z);vec4 x_=floor(j*ns.z);vec4 y_=floor(j-7.*x_);\n      vec4 x=x_*ns.x+ns.yyyy;vec4 y=y_*ns.x+ns.yyyy;vec4 h=1.-abs(x)-abs(y);\n      vec4 b0=vec4(x.xy,y.xy);vec4 b1=vec4(x.zw,y.zw);\n      vec4 s0=floor(b0)*2.+1.;vec4 s1=floor(b1)*2.+1.;vec4 sh=-step(h,vec4(0.));\n      vec4 a0=b0.xzyw+s0.xzyw*sh.xxyy;vec4 a1=b1.xzyw+s1.xzyw*sh.zzww;\n      vec3 p0=vec3(a0.xy,h.x);vec3 p1=vec3(a0.zw,h.y);vec3 p2=vec3(a1.xy,h.z);vec3 p3=vec3(a1.zw,h.w);\n      vec4 norm=taylorInvSqrt(vec4(dot(p0,p0),dot(p1,p1),dot(p2,p2),dot(p3,p3)));\n      p0*=norm.x;p1*=norm.y;p2*=norm.z;p3*=norm.w;\n      vec4 m=max(0.6-vec4(dot(x0,x0),dot(x1,x1),dot(x2,x2),dot(x3,x3)),0.);m=m*m;\n      return 42.*dot(m*m,vec4(dot(p0,x0),dot(p1,x1),dot(p2,x2),dot(p3,x3)));\n    }\n    void main(){\n      float normR=smoothstep(${DISK_INNER.toFixed(3)},${DISK_OUTER.toFixed(3)},vRadius);\n      float spiral=vAngle*3.-(1.\/(normR+0.1))*2.;\n      vec2 flowUv=vec2(vUv.x+uTime*uFlowSpeed*(2.\/(vRadius*0.3+1.))+sin(spiral)*0.1,vUv.y*0.8+cos(spiral)*0.1);\n      float n1=snoise(vec3(flowUv*uNoiseScale,uTime*0.14));\n      float n2=snoise(vec3(flowUv*uNoiseScale*3.2+0.8,uTime*0.21));\n      float n3=snoise(vec3(flowUv*uNoiseScale*6.5+1.5,uTime*0.30));\n      float n=(n1*0.45+n2*0.35+n3*0.20);n=(n+1.)*0.5;\n      vec3 col=uColorOuter;\n      col=mix(col,uColorC,smoothstep(0.00,0.22,normR));\n      col=mix(col,uColorB,smoothstep(0.18,0.52,normR));\n      col=mix(col,uColorA,smoothstep(0.48,0.76,normR));\n      col=mix(col,uColorHot,smoothstep(0.72,0.96,normR));\n      col*=(0.45+n*1.1);\n      float brightness=pow(1.-normR,1.1)*3.8+0.4;brightness*=(0.25+n*2.4);\n      float pulse=sin(uTime*1.6+normR*11.+vAngle*2.)*0.12+0.88;brightness*=pulse;\n      float alpha=uDensity*(0.18+n*0.92);\n      alpha*=smoothstep(0.00,0.12,normR);alpha*=(1.-smoothstep(0.88,1.00,normR));alpha=clamp(alpha,0.,1.);\n      gl_FragColor=vec4(col*brightness,alpha);\n    }\n  `,\n  transparent:true,side:THREE.DoubleSide,depthWrite:false,blending:THREE.AdditiveBlending,\n});\nconst disk=new THREE.Mesh(diskGeo,diskMat);\ndisk.rotation.x=DISK_TILT; disk.renderOrder=1; scene.add(disk);\n\n\/\/ \u2500\u2500 Lensed arc \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nconst ARC_N=6000;\nconst aPos=new Float32Array(ARC_N*3),aCol=new Float32Array(ARC_N*3),aSiz=new Float32Array(ARC_N);\nconst tc=document.createElement('canvas');tc.width=tc.height=64;\nconst tctx=tc.getContext('2d'),tcx=32,tg=tctx.createRadialGradient(tcx,tcx,0,tcx,tcx,tcx);\ntg.addColorStop(0,'rgba(255,255,255,1)');tg.addColorStop(0.2,'rgba(255,230,160,.7)');\ntg.addColorStop(0.6,'rgba(255,180,60,.15)');tg.addColorStop(1,'rgba(0,0,0,0)');\ntctx.fillStyle=tg;tctx.fillRect(0,0,64,64);\nconst spriteTex=new THREE.CanvasTexture(tc);spriteTex.needsUpdate=true;\nfor(let i=0;i<ARC_N;i++){\n  const t=(Math.random()-0.5)*Math.PI*1.75,r=BH_RADIUS*1.1+Math.random()*3.5,c=1-Math.abs(t)\/Math.PI;\n  const ah=BH_RADIUS*1.05*Math.sin(Math.PI*c);\n  aPos[i*3]=r*Math.cos(t);aPos[i*3+1]=ah+(Math.random()-0.5)*0.35;aPos[i*3+2]=r*Math.sin(t)*0.25;\n  const br=0.5+c*2.0+Math.random()*0.4;aCol[i*3]=br*2.6;aCol[i*3+1]=br*2.0;aCol[i*3+2]=br*0.8;\n  aSiz[i]=0.2+c*1.0+Math.random()*0.4;\n}\nconst aGeo=new THREE.BufferGeometry();\naGeo.setAttribute('position',new THREE.BufferAttribute(aPos,3));\naGeo.setAttribute('color',new THREE.BufferAttribute(aCol,3));\naGeo.setAttribute('size',new THREE.BufferAttribute(aSiz,1));\nscene.add(new THREE.Points(aGeo,new THREE.PointsMaterial({\n  size:0.08,map:spriteTex,vertexColors:true,transparent:true,opacity:0.7,\n  blending:THREE.AdditiveBlending,depthWrite:false,sizeAttenuation:true,\n})));\n\n\/\/ \u2500\u2500 Loop \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nconst clock=new THREE.Clock(),bhProj=new THREE.Vector3();\nfunction animate(){\n  requestAnimationFrame(animate);\n  const t=clock.getElapsedTime(),dt=clock.getDelta();\n  diskMat.uniforms.uTime.value=t;\n  starMat.uniforms.uTime.value=t;\n  photonMat.uniforms.uTime.value=t;\n  photonMat.uniforms.uCamPos.value.copy(camera.position);\n  bhProj.copy(bhMesh.position).project(camera);\n  lensingPass.uniforms.bhScreenPos.value.set((bhProj.x+1)\/2,(bhProj.y+1)\/2);\n  stars.rotation.y+=dt*0.002;\n  disk.rotation.z+=dt*0.004;\n  controls.update();\n  composer.render(dt);\n}\nanimate();\n\n\/\/ \u2500\u2500 Resize \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nlet rTimer;\nwindow.addEventListener('resize',()=>{\n  clearTimeout(rTimer);\n  rTimer=setTimeout(()=>{\n    camera.aspect=innerWidth\/innerHeight; camera.updateProjectionMatrix();\n    renderer.setSize(innerWidth,innerHeight); composer.setSize(innerWidth,innerHeight);\n    bloomPass.resolution.set(innerWidth,innerHeight);\n    lensingPass.uniforms.aspectRatio.value=innerWidth\/innerHeight;\n    renderer.setPixelRatio(Math.min(devicePixelRatio,1.5));\n  },150);\n});\n\n\/\/ \u2500\u2500 API p\u00fablica + notificar que est\u00e1 lista \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nwindow.DIBH = {\n  setAutoRotate:  v => { controls.autoRotate = v; },\n  setRotateSpeed: v => { controls.autoRotateSpeed = v; },\n  setBloom:       v => { bloomPass.strength = v; },\n  setLensing:     v => { lensingPass.uniforms.lensingStrength.value = v; },\n  resetCamera:    () => { camera.position.copy(CAM_DEFAULT); controls.target.set(0,0,0); controls.update(); },\n};\n\n\/\/ Desencolar comandos pendientes del panel de controles\nwindow._dibhReady(window.DIBH);\n<\/script>\n\n<\/body>\n<\/html>\n<!-- \/wp:html -->","_et_gb_content_width":"1080","footnotes":""},"class_list":["post-8","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/dialelo.io\/index.php?rest_route=\/wp\/v2\/pages\/8","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/dialelo.io\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/dialelo.io\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/dialelo.io\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/dialelo.io\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=8"}],"version-history":[{"count":16,"href":"https:\/\/dialelo.io\/index.php?rest_route=\/wp\/v2\/pages\/8\/revisions"}],"predecessor-version":[{"id":47,"href":"https:\/\/dialelo.io\/index.php?rest_route=\/wp\/v2\/pages\/8\/revisions\/47"}],"wp:attachment":[{"href":"https:\/\/dialelo.io\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=8"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}