Aprende. Construye. Vende.
Una app tipo Duolingo que no te enseña sobre emprender: te lleva de una idea a un negocio real, una misión al día.
Al terminar la ruta no te llevas un certificado. Te llevas una idea validada, un cliente ideal definido, una oferta escrita, tus precios calculados, una identidad básica, una estrategia de ventas y tus primeros clientes.
Opción 1 — instalarla como app (la mejor en móvil)
Abre la app y instálala:
- Android / Chrome / Edge: aparece "Instalar", o entra a Perfil › Ajustes › Instalar la app.
- iPhone: botón Compartir → Añadir a pantalla de inicio.
Queda con icono propio, a pantalla completa y funciona sin conexión: la tipografía, el código y las 50 lecciones se guardan en el dispositivo la primera vez que la abres.
Opción 2 — doble clic
Abre index.html en Chrome, Edge o Firefox. No necesita instalación, ni internet, ni cuenta.
Dos avisos sobre
file://: algunos navegadores restringen ahí el guardado local (si tu progreso no se conserva, usa la opción 3), y los service workers no funcionan, así que por esta vía no se puede instalar.
Opción 3 — servidor local
node serve.jsY abre http://localhost:4321. Por aquí sí se puede instalar.
El modo sin conexión no se puede probar en local: el service worker se registra y precarga todo, pero en
localhostno intercepta ninguna petición a propósito (si lo hiciera, editar un archivo te seguiría enseñando la copia guardada). Para comprobar que la app abre sin red hay que hacerlo sobre la versión publicada.
Opción 4 — publicarla
Es un sitio estático puro. Sube la carpeta completa a Netlify, Vercel, GitHub Pages o cualquier hosting y funciona igual.
Si la publicas en una subcarpeta (como hace GitHub Pages), no hay nada que tocar: el manifest, el service worker y todas las rutas son relativas a propósito.
| 50 microlecciones | de 5 a 10 minutos cada una |
| 248 ejercicios | 9 tipos distintos de interacción |
| 8 niveles | Descubre → Valida → Construye → Vende → Administra → Crece → Sistematiza → Escala |
| 8 retos reales | los "jefes finales": se hacen fuera de la app |
| 58 paradas en la ruta | las 50 lecciones + los 8 retos reales |
| 50 misiones aplicadas | una por lección, cada una a tu negocio de verdad |
| Simulador de empresa | 12 semanas, 22 eventos, modelo de demanda real |
| Chispa Engine | reglas, fórmulas y 77 entradas de conocimiento. Calcula tu precio preguntándote solo lo que falta, y recuerda lo que decidiste |
| Perfil del emprendimiento | tu idea registrada al entrar: personaliza lecciones, desafíos, planes y recomendaciones |
| Se contesta hablando o tocando | 8 formas de responder — nota de voz, tarjetas, botones, escalas, deslizar, completar frases, ejemplos y escribir. Escribir es una opción, no la única |
| Captura progresiva | 21 preguntas que Chispa hace de una en una, al terminar una lección. Nunca dos veces lo mismo, y «todavía no lo sé» no penaliza |
| La app se adapta a tu negocio | color secundario, ejemplos del oficio, orden del panel y Chispa con delantal, herramienta y su espacio de trabajo |
| Expediente Mi Negocio | 12 secciones que se llenan solas y se exportan |
| Lectura en voz alta | escucha las lecciones y las respuestas con la voz del dispositivo |
| La Plaza | Tu puesto, con lo que ya contaste. Sale solo lo que apruebes, y nunca tus números |
| Decora tu puesto | 33 piezas en 5 ranuras: el toldo, su color, el letrero, lo que hay alrededor y sobre qué está montado. Gratis desde el primer día |
| Iconos propios | 60 piezas dibujadas a mano en el mismo lenguaje que Chispa. Nada de emoji del sistema: se ven igual en cualquier teléfono y se mueven |
| Emprendo Impulso | La suscripción, 99 pesos al mes: energía sin límite y sin anuncios. Ninguna lección y ningún reto se esconden detrás del pago, y hay un verificador que lo comprueba |
Cómo se cuentan: el mapa tiene 58 paradas = 50 lecciones + 8 retos reales. Cada lección cierra con una misión aplicada a tu propio negocio (50 en total), y cada nivel termina con un reto real que haces fuera de la app y luego reportas.
| Nivel | Resultado |
|---|---|
| 1. 🔎 Descubre | Encuentras problemas y oportunidades reales |
| 2. 🧪 Valida | Compruebas si alguien de verdad compraría |
| 3. 🔧 Construye | Creas tu producto mínimo viable y le pones precio |
| 4. 🤝 Vende | Consigues tus primeros clientes |
| 5. 📊 Administra | Controlas costos, ingresos e inventario |
| 6. 📈 Crece | Haces marketing y aumentas ventas |
| 7. ⚙️ Sistematiza | Automatizas, delegas y documentas |
| 8. 🚀 Escala | Contratas, reinviertes y expandes |
No son exámenes. Son cosas que haces en el mundo real y luego reportas:
- Consigue tu primera entrevista con un cliente
- Publica tu primera oferta y consigue 3 respuestas
- Calcula tu costo unitario y define tu precio
- Envía 10 mensajes y manda una cotización
- Cierra tu primer mes con números reales
- Consigue 3 clientes nuevos en una semana
- Documenta tu proceso clave
- Recupera tu inversión inicial y define tu plan de 90 días
Cada sesión dura entre 5 y 10 minutos y siempre tiene la misma forma:
- Concepto corto — la idea, en dos párrafos y tres claves
- Caso empresarial — una historia real de negocio pequeño
- Ejercicios — decisiones, no memorización
- Simulación de consecuencias — eliges y ves qué le pasa a tu negocio
- Misión aplicada — algo que haces con tu negocio de verdad
- Evaluación del mentor — revisa lo que escribiste y te dice qué falta
quiz una respuesta · multi varias respuestas · tf verdadero o falso · order ordenar pasos · match emparejar · fill completar la frase · slider elegir un número con consecuencias · sim decisión con impacto animado · write escribir —o dictar— y que el mentor lo revise
Además de construir tu proyecto, administras una empresa virtual durante 12 semanas. Cada semana decides precio, cuánto material compras y cuánto inviertes en publicidad, y enfrentas un evento: un proveedor que sube precios, un cliente molesto, un pedido mayorista con pago a 60 días, una máquina descompuesta, alguien que te copia…
El modelo calcula demanda a partir de tu precio (elasticidad), tu reputación y tu publicidad, y la limita por tu inventario y tu capacidad. Distingue utilidad de flujo de efectivo: puedes ser rentable en papel y quedarte sin dinero. Es el error que más negocios pequeños mata, y aquí lo cometes gratis.
Chispa no busca respuestas: decide con qué responderte. Cada mensaje recorre siete niveles y se detiene en el primero que resuelva de verdad.
| Nivel | Qué hace | |
|---|---|---|
| 1 | Intención | Qué quieres hacer |
| 2 | Perfil | Qué sabe ya de tu negocio |
| 3 | Huecos | Qué dato falta → pregunta uno, no seis |
| 4 | Fórmula | Precio, margen, punto de equilibrio: se calculan, no se opinan |
| 5 | Conocimiento | Los fragmentos aplicables de la base, filtrados por tu sector |
| 6 | Plantilla | Compone la respuesta con tus datos reales |
| 7 | Generativo | Solo si aporta lo que una plantilla no puede |
Los seis primeros niveles no gastan un byte de red y responden en menos de un milisegundo.
Un ejemplo real: a "¿en cuánto debo vender mi producto?" detecta la intención, mira qué números ya conoce, pregunta uno a uno los que faltan, calcula, te explica el resultado con tus cifras y guarda el precio como decisión. La segunda vez no pregunta nada.
El modelo generativo nunca es la fuente de la verdad. Cuando se llega al nivel 7, Chispa le entrega los hechos ya resueltos y el modelo solo redacta.
Ninguna es obligatoria. Si no hay ninguna, Chispa responde igual con los niveles 1 a 6.
1 · IA gratuita de Emprendo — un Worker de Cloudflare con Workers AI. No necesitas cuenta ni clave: solo que el dueño de la instancia lo haya desplegado. Es gratis para todos y no puede generar cobros: al agotarse la cuota diaria corta en vez de facturar. Instrucciones en worker/README.md.
2 · IA local de Chispa — un modelo abierto que corre dentro de tu navegador: sin conexión, sin costo y sin que nada salga del dispositivo. Es una descarga voluntaria de entre 879 MB y 2,5 GB, nunca automática, y la app comprueba antes si tu equipo puede. En iPhone y iPad no se ofrece: iOS limita la memoria de una página muy por debajo de lo que pide el modelo más pequeño.
3 · Tu clave personal — en Perfil › Mentor con IA puedes conectar una clave de Anthropic. Tiene prioridad sobre las demás: si la configuraste, es porque quieres ese modelo.
4 · Las respuestas escritas — 26 temas con respuesta desarrollada a mano, que se usan cuando no hay ninguna IA disponible.
Las calculadoras, las rúbricas de las misiones y las prácticas guiadas son deterministas a propósito. Un precio calculado se puede comprobar con una calculadora; uno redactado por un modelo es una opinión con formato de número.
Puntos de entrada:
Chispa.responder()enjs/core/chispa.js, la base enjs/data/kb.js, y el enrutado de proveedores enAI.ask()dentro dejs/core/ai.js.
La app necesita conocer el negocio para poder hablar de él. Lo que cambió no es qué pregunta, sino cómo se contesta.
| Forma | Para qué |
|---|---|
| 🎤 Nota de voz | La idea, el problema que resuelve, la competencia: lo que cuesta escribir |
| 🃏 Tarjetas | El sector, la etapa, el objetivo: respuestas cerradas, con dibujo y ejemplo |
| ⚡ Botones rápidos | Presupuesto, tiempo, frecuencia: rangos que se tocan sin teclado |
| 📊 Escalas | Experiencia y avance, sin pedir un número |
| 👉 Deslizar | Listas largas —dónde vendes— de una tarjeta en una: sí · tal vez · no |
| 🧩 Completar la frase | La propuesta de valor, armada eligiendo piezas |
| 🖼️ Ejemplos parecidos | Reconocer el negocio en un ejemplo cuando no sale describirlo |
| ✍️ Escribir | Siempre disponible, para quien lo prefiera |
Y en todas, salvo la idea: «Todavía no lo sé». No penaliza, no bloquea y no vuelve a preguntarse en una semana.
Idea, sector, cliente y etapa. Nada más. Lo demás —la oferta, el objetivo, el presupuesto, el tiempo, la experiencia— lo aprende Chispa después, una pregunta al terminar cada lección, con un tope de tres al día. Cada respuesta sale de la cola para siempre.
Al acabar el registro, Chispa devuelve en dos frases lo que armó, con lo deducido subrayado, y espera:
Sí, así es · Quiero corregir algo · Todavía no lo tengo claro
Tocar cualquier trozo subrayado abre justo la pregunta que lo escribió, en el mismo modo en el que se contestó. Nada se guarda sin pasar por aquí: lo dictado se enseña escrito antes de guardarlo, y lo deducido se enseña marcado antes de darlo por bueno.
En Mi emprendimiento está todo lo capturado, con cómo se contó cada cosa (voz, tarjeta, escala, deslizar). Cualquier línea se toca para cambiarla, y dentro está «Que Chispa lo olvide»: borra el dato del perfil y deja que se pueda volver a preguntar desde cero.
Puntos de entrada: el catálogo en
js/data/preguntas.js, el motor enCaptura.bloque()yCaptura.siguiente()dentro dejs/core/captura.js, y el reconocimiento de voz enjs/core/dictado.js. Se verifica connode tools/check-captura.js.
El audio no se guarda en ningún sitio y no llega a ningún servidor de Emprendo: quien convierte la voz en texto es el reconocimiento del propio navegador, igual que cuando dictas un mensaje en el teclado del teléfono. Algunos navegadores hacen esa transcripción en sus servidores, y eso está escrito tal cual en privacidad.html: la app no promete lo que no puede cumplir. Donde no se puede dictar —Firefox de escritorio, sin permiso de micrófono— el botón sencillamente no aparece y se escribe.
Al registrar tu idea eliges tu sector, y a partir de ahí la app deja de ser genérica: no cambia de forma, cambia de tema.
| Qué se adapta | Qué NO se toca |
|---|---|
| El color secundario y los acentos | El naranja de marca, la tipografía, la estructura y la navegación |
| Los ejemplos de cada lección | Las 50 lecciones, que son las mismas para todos |
| El orden de las tarjetas del panel y de los 7 análisis | El mapa de la ruta |
| Lo que Chispa lleva puesto y su espacio de trabajo | Su cuerpo, su cara y su chispa de ocho puntas |
Una pastelería lee "pesa los ingredientes de un solo pedido y súmale gas, empaque y tu hora de trabajo"; un taller de impresión 3D, "súmale las horas de máquina, la luz, las piezas falladas y tu tiempo de acabado". No es la misma frase con otra palabra: son dos oficios distintos.
Chispa es una sola. Se le añaden capas —delantal, lentes, herramienta, un banco de trabajo detrás— pero nunca se le cambia el cuerpo ni la cara. Los accesorios están dibujados para rodear su chispa, no para taparla: es lo que la hace reconocible.
Cuando cambias la descripción de tu negocio, la app pregunta antes de tocar nada. Y si eliges un color a mano, deja de proponerte otro.
En Mi emprendimiento › Personalizar mi experiencia decides el color, los accesorios, cuánto quieres que se note —sutil, media o visible— o lo apagas del todo y la app vuelve a verse igual para todo el mundo.
La IA puede leer tu descripción y proponer una clasificación, pero no genera CSS, ni rutas, ni colores. Devuelve un JSON que se valida clave por clave contra listas cerradas; si algo no está en la lista, la propuesta entera se descarta y manda el clasificador por palabras clave, que funciona sin conexión y sin costo. Y ninguna propuesta se aplica sin que la aceptes.
Los colores viven solo en css/temas.css. js/core/persona.js no escribe ni un color: escribe atributos en <html> y deja que la cascada decida. Eso es lo que hace que el modo oscuro siga funcionando y que un valor inventado simplemente no pinte nada. Las 7 paletas están medidas: texto sobre fondo por encima de 4.5:1 en claro y en oscuro, y ningún tema toca el azul del foco de teclado.
Puntos de entrada:
Persona.actual()enjs/core/persona.js, las listas blancas enjs/data/config.js(TEMAS,PERSONALIDADES), los accesorios enjs/data/mascota-capas.jsy los ejemplos por oficio enEXAMPLE_BY_SECTORdentro dejs/data/venture-templates.js.
La Plaza es el único sitio de la app donde hay alguien más. Tu emprendimiento se enseña como un puesto de mercado: un toldo con tu oficio y, debajo, el nombre y una frase.
La vitrina se arma sola con lo que ya le contaste a Chispa. Antes de abrir el puesto se ve entera, línea por línea, y cada línea se puede corregir a mano. Lo que nunca sale está escrito y verificado a máquina: tus precios y costos, tu plan y tus decisiones, tu ciudad y tus contactos, tu presupuesto y tu experiencia, y tu progreso.
tools/check-vitrina.js arma un perfil de mentira lleno de datos privados, construye la
vitrina y comprueba que ninguno sale. Si alguien amplía la lista de lo publicable sin
declararlo, el verificador falla antes de que llegue a publicarse.
Detrás del puesto hay una plaza de verdad: cielo, horizonte con más puestos al fondo, faroles, una guirnalda cruzando, empedrado que se aleja y motas de luz. Todo se mueve a distinta velocidad al hacer scroll, así que se lee como profundidad. De noche no cierra: se enciende.
Está hecho sin librerías, sin perspective y sin una sola imagen: gradientes, máscaras
y una variable —--pz-scroll— que la pantalla escribe al desplazarse y de la que salen
los diez planos. Quien pidió menos movimiento ve el mundo entero, quieto.
No hay vecinos inventados, y no los va a haber. La Liga puede permitirse rivales simulados porque ahí lo que está en juego son puntos; aquí el botón dice "Veo valor" y un vecino que nunca contesta sería una mentira. Lo que sí hay son sitios libres: la plaza tiene espacio, y eso es verdad. Tocar uno invita a alguien que conoces.
Mi negocio › La Plaza › Decorar mi puesto. Cinco ranuras y 33 piezas, todas disponibles desde el primer día:
| Ranura | Piezas |
|---|---|
| El toldo | Festón, rayas, picos, ondas, cuadros, lona |
| De qué color | El de tu oficio y 9 colores más |
| El letrero | Sin marco, tabla de madera, pizarra, placa esmaltada, cinta pintada |
| Lo que hay alrededor | Nada, macetas, farol, banderines, cajas, pizarrón, girasoles |
| Sobre qué está | Nada, tarima, tapete, adoquín, pasto |
La vista previa de arriba es el puesto de verdad, con los mismos componentes y las mismas piezas que la Plaza. No hay maquetas: si algo se ve mal ahí, se ve mal allí.
Cada toque se guarda solo y, si tu puesto ya está abierto, sale hacia la Plaza sin preguntar nada. El texto sí pasa por «Así está bien», porque lo escribió la app y hay que revisarlo; la decoración no, porque la elegiste tú mirando el puesto entero mientras la elegías.
Es la misma idea que las capas de Chispa, un escalón más arriba. js/data/puesto-piezas.js
es un catálogo cerrado: los colores no viven ahí, viven en css/puesto.css, así que
una clave que no exista simplemente no pinta. js/core/puesto.js tiene una sola puerta
—limpio()— por la que pasa todo: lo que elige el usuario, lo que se guarda, lo que se
publica y lo que llega de otra persona.
La lista blanca está escrita tres veces a propósito: en el teléfono, en el Worker y en
el CHECK de la base. El Worker no puede fiarse del cliente, porque un cliente modificado
existe en cuanto la app es pública. Que las tres no se separen lo comprueba
tools/check-puesto.js, que además mide cada dibujo para que ninguna pieza se salga de su
franja ni acabe encima del texto del puesto.
El interruptor de Personalizar mi experiencia manda también aquí: apagado, tu puesto se ve —y se publica— tal y como venía. Lo que elegiste no se borra; solo deja de enseñarse.
Puntos de entrada:
js/data/puesto-piezas.js(el catálogo),js/core/puesto.js(validación y estado),js/screens/puesto.js(la pantalla),css/puesto.css(las piezas) ycss/plaza.css(el lugar). La maqueta viva está enlab/plaza-mundo.html.
La suscripción. 99 pesos al mes (MXN), y lo primero que hay que decir es lo que NO hace:
No esconde ni una lección ni un reto. Las 50 lecciones, los 8 retos reales, el simulador, Chispa, el expediente y la Plaza siguen siendo gratis, y van a seguir siéndolo. Impulso quita las pausas y añade acompañamiento.
Eso no es una promesa de marketing: hay un verificador que lo comprueba.
tools/check-gratis.js recorre la ruta entera con un usuario sin pagar y falla si
alguna parada queda cerrada. El día que alguien quiera cerrar el último nivel detrás
del pago, tendrá que borrar ese script a propósito, y eso se ve en el diff.
| Estado | |
|---|---|
| ⚡ Energía sin límite | Listo |
| 🧘 Sin anuncios | Listo |
| 🗓️ Tu plan de la semana — qué hacer primero, y por qué | Listo |
| ✍️ Material listo para usar — 8 plantillas con sus datos dentro | Listo |
| 💬 Chispa más cerca — un modelo de pago, 40 al día y memoria de lo que hablaron | Listo |
Lo que todavía no está hecho sale apagado y con la palabra «pronto» en la propia
pantalla de cobro, no con un candado: un candado dice «existe y no te lo doy». Quien
paga hoy ve exactamente lo que se lleva hoy. Vive en CONFIG.IMPULSO.BENEFICIOS, y
encender uno es cambiar su listo a true.
Tres cosas y el porqué de cada una. El porqué no es adorno: es lo único que separa esto de una lista de pendientes, que se pospone igual de fácil.
Las 25 tareas viven en js/data/plan-semanal.js, cada una con cuando —si aplica
ahora—, un peso y una familia. El motor se queda con las que aplican, reparte por
familia para que la semana no sea tres veces lo mismo, y toma tres. Nada es
aleatorio: dos personas en la misma situación ven lo mismo, y eso es una propiedad —
el día que alguien pregunte «¿por qué me salió esto?», hay respuesta.
Dos decisiones que lo sostienen:
- La elección se congela, el estado no. Si el plan se recalculara en cada pintado, cambiaría bajo los pies: terminas una lección, vuelves a la Ruta y tu semana ya es otra. Se guardan solo los tres ids; si están hechos o no se calcula en vivo.
- Nadie marca nada a mano. Cada tarea tiene un
hecho()que mira el estado real. Una lista que se puede tachar sin hacer nada es una lista que miente. Las seis que pasan fuera de la app y no dejan rastro están declaradas a propósito entools/check-plan.js.
El quinto beneficio, y el único que cuesta dinero cada vez que se usa. Entra en
la cascada de ai.js por delante del modelo local y de la IA gratuita, y
por detrás de la clave personal — configurarla es decir «quiero ESE modelo», y
usar otro por detrás sería tomar por alguien una decisión que ya tomó.
| Gratis | Con Impulso | |
|---|---|---|
| Niveles 1–6 de Chispa | Ilimitados, sin red | Ilimitados, sin red |
| Modelo | Workers AI, cuota compartida de Cloudflare | Un modelo de pago, suyo |
| Consultas | 25/día por dispositivo | 40/día y 600/mes por cuenta |
| Largo de la respuesta | 400 tokens | 900 |
| Memoria de la conversación | 4 turnos | 12 |
| Revisión de decisiones | — | Sí |
Lo que de verdad cambia no es el número: es que la cuota gratuita es compartida y se agota a media tarde para todos a la vez. La de Impulso no compite con nadie.
La operación vive en worker-plaza/ y no en worker/ por una razón concreta:
para contar por persona hace falta una sesión y una base, y el Worker de la IA
gratuita no declara ningún almacenamiento ni recibe ninguna identidad. El
contador es el mismo INSERT … ON CONFLICT … RETURNING de la tabla pedido:
contar y decidir en una sentencia, porque con un SELECT y luego un UPDATE
treinta peticiones simultáneas convierten un tope de 40 en 70.
Al llegar al tope no se corta nada. La cascada cae al escalón de abajo y, si tampoco puede, se enseña el motivo de arriba —«llegaste a tus 40 de hoy»— y no un genérico: la razón por la que cambió la respuesta es justo lo que esa persona necesita saber.
De cada persona se guarda un número: cuántas van hoy y cuántas van este mes. Ni la pregunta, ni la respuesta, ni el contexto del negocio.
La revisión de decisiones es lo único de esta pantalla que una plantilla no puede hacer: mirar todo lo que alguien ha decidido —precio, costo, cliente, oferta, etapa, progreso— y decir qué no cuadra entre sí. Los hechos los escribe la app y van con orden de no inventar ninguno; el modelo solo los cruza. El modelo nunca es la fuente de la verdad, aquí tampoco.
Ocho plantillas —publicación, mensaje de venta, pitch, cotización, guion de llamada,
respuesta a «está caro», seguimiento y el de después de vender— rellenadas con
Venture.terms(), la misma fuente de la que salen los ejemplos de las lecciones.
Y la regla que lo hace sentir caro: si falta un dato, no se abre un formulario. Un formulario aquí sería confesar que la app no se acordaba de nada, justo en la pantalla que existe para demostrar lo contrario. El material sale apagado, dice exactamente qué le falta a Chispa y lleva al sitio donde se cuenta.
Son deterministas porque tienen que funcionar sin conexión, en el mismo teléfono desde
el que se va a mandar el mensaje. Si hay IA, reescribe la redacción encima; nunca
decide el contenido. Los corchetes [así] son huecos deliberados —el nombre, la
fecha, el plazo—: poner ahí un invento sería peor, porque se mandaría sin revisar.
Durante meses el modal de cero vidas decía «…o seguir practicando sin vidas (no ganarás XP)» y ningún código lo aplicaba: los puntos se daban enteros. O sea, la energía no regulaba nada y el beneficio de pago ya existía gratis detrás de un botón.
Ahora sin energía la lección cuenta igual y los puntos valen la mitad. Se avanza por la ruta exactamente igual —nadie se queda encerrado, ni dentro de una lección ni desde el mapa— y solo se sube más despacio de rango y de liga. Es lo único que deja las tres cosas ciertas a la vez: nadie bloqueado, la energía significa algo, y el texto de la app no miente.
El factor vive en Engine.xpMultiplier(), junto al de XP doble y multiplicándose con
él: quien compró XP doble y se quedó sin energía va a x1.
El estado de la app es un JSON de localStorage, y su propio importador lo bendice: un
respaldo editado a mano con "plan":"impulso" entraría tal cual. Así que lo que se
guarda no es un valor, es una firma.
worker-pago/ devuelve un pase —cuenta, plan y hasta cuándo— firmado con ECDSA
P-256. La app lo verifica con la mitad pública, sin red y en un milisegundo, y se
renueva solo cada vez que hay conexión. Un pase editado no verifica; escribirse uno
hace falta la mitad privada, que vive como secreto del Worker.
Lo que esto no resuelve, y está aceptado: la app es JavaScript que se descarga entero, así que quien sepa parchearla se lo salta siempre. Lo que se cierra es el fraude que puede hacer cualquiera en dos minutos.
Tres consecuencias que están escritas en pantalla, no en la letra pequeña:
- Para pagar hace falta un correo. Es la misma cuenta de la Plaza: no hay dos.
- El respaldo
.jsonno lleva Impulso. Vive fuera del estado a propósito, porque ese archivo se manda por WhatsApp. En un teléfono nuevo se recupera entrando con el correo. - Borrar la cuenta cancela el cobro primero, y si eso falla no se borra nada: una cuenta borrada con una suscripción viva es un cobro fantasma que ya no se puede relacionar con nadie.
Son el primer tercero de este proyecto, y por eso tienen una sola puerta:
js/core/anuncios.js. Las reglas están escritas ahí dentro y no repartidas por las
pantallas:
- Solo en dos huecos: al terminar una lección y en la Ruta. Nunca dentro de una lección, de un reto ni de una conversación con Chispa.
- Nunca antes de que alguien haya terminado su primera lección.
- Nunca a pantalla completa ni con algo que haya que cerrar para seguir.
- Con Impulso no se carga ni el script. Comprobado: cero peticiones a Google.
- Nunca sin haber preguntado, y la respuesta se puede cambiar en Perfil.
- A la red no se le manda ni un dato del negocio. Ni el sector, ni la etapa, ni el texto de ninguna pantalla, ni el correo.
Esa última regla es la que permitió cambiar la tercera promesa de promesa.js por
algo que sigue siendo verdad: «Tu idea no se la doy a nadie. Nunca.» La anterior
—«Emprendo no vive de tus datos»— dejó de serlo el día que entró una red publicitaria,
y se cambió en vez de dejarla.
En la cuenta de AdSense hay que dejar los Auto ads APAGADOS. Con ellos encendidos, Google coloca anuncios donde quiere —incluidos anclajes y pantallas completas— y se salta las seis reglas de arriba sin que el código pueda impedirlo.
Todo esto está apagado mientras CONFIG.ANUNCIOS.editor esté vacío, que es el estado
de serie: sin identificador no se carga script, no se pregunta nada y no se pinta
ningún hueco.
Puntos de entrada:
js/core/impulso.js(el pase),js/screens/impulso.js(la pantalla),js/core/anuncios.js(la puerta de la publicidad),js/core/plan.jsyjs/data/plan-semanal.js(el plan),js/data/materiales.jsyjs/screens/materiales.js(el material),css/impulso.cssyworker-pago/(Stripe). La maqueta viva está enlab/impulso.html, el plan completo endocs/plan-impulso.md, y se verifica connode tools/check-gratis.js,node tools/check-impulso.jsynode tools/check-plan.js.
Racha diaria con congeladores · XP y 10 rangos · 5 vidas que se regeneran cada 30 min · monedas y tienda · 26 insignias · 7 ligas semanales · 5 retos semanales · mapa visual de progreso · meta diaria ajustable · modo oscuro · sonido sintetizado (sin archivos) · vibración háptica.
La tienda (5 artículos, todos con efecto real):
| ❤️ Recarga de vidas | Rellena las 5 al instante |
| 🧊 Congelador de racha | Salva la racha un día que falles |
| ⚡ XP doble | 30 minutos, con indicador en la barra superior |
| 💡 Pistas | Descartan una opción incorrecta dentro de la lección |
| 🔬 Auditoría del negocio | Evalúa las 12 secciones de Mi Negocio y te da las 3 prioridades |
EMPRENDO/
├── index.html
├── manifest.webmanifest nombre, iconos y accesos directos de la app
├── sw.js service worker: instalable y sin conexión
├── serve.js servidor local opcional
├── assets/
│ ├── fonts/ Nunito (variable, woff2) — no se pide a Google
│ ├── icons/ 192, 512, maskable y apple-touch
│ └── og-image.png portada al compartir el enlace (1200×630)
├── css/
│ ├── fonts.css @font-face de la tipografía local
│ ├── tokens.css colores, tipografía, sombras, temas
│ ├── base.css reset y layout
│ ├── components.css botones, tarjetas, opciones, fichas…
│ ├── captura.css las 8 formas de contestar
│ ├── screens.css cada pantalla
│ ├── animations.css todos los keyframes
│ ├── iconos.css el alfabeto visual dibujado a mano
│ ├── plaza.css el lugar: cielo, horizonte, faroles y puestos
│ ├── puesto.css lo que el usuario le pone encima a su puesto
│ ├── impulso.css la pantalla de cobro y sus dos apariciones
│ ├── temas.css el color secundario por tipo de negocio
│ └── splash.css la pantalla de arranque
├── worker/ IA gratuita: Worker de Cloudflare (se despliega aparte)
├── worker-plaza/ la Plaza: cuentas, vitrinas y conversaciones (aparte también)
├── worker-pago/ Emprendo Impulso: Stripe y el pase firmado (aparte también)
├── docs/ investigación de proveedores y de Chispa Engine
├── lab/ laboratorio aislado: modelos locales, captura y la Plaza
├── tools/
│ ├── check-precache.js cuadra index.html con el precache del sw
│ ├── check-captura.js ejecuta el motor de la captura y lo verifica
│ ├── check-catalogo.js que todos los logros compartibles sean alcanzables
│ ├── check-motor.js las razones para acercarse a un vecino
│ ├── check-vitrina.js que de la vitrina no salga nada que no se dijo
│ ├── check-puesto.js que las tres listas de piezas no se separen
│ ├── check-plaza-worker.js ejecuta el Worker de la Plaza contra sus reglas
│ ├── check-gratis.js que sin pagar se llegue del primer nodo al último
│ ├── check-impulso.js firma pases de verdad y comprueba que no se falsifican
│ ├── check-plan.js ejecuta las 25 tareas y los 8 materiales contra 7 perfiles
│ └── nueva-llave-pase.js genera el par de llaves del pase (no es un verificador)
└── js/
├── core/
│ ├── store.js estado + persistencia + rachas
│ ├── venture.js perfil del emprendimiento: los 3 niveles de contexto
│ ├── chispa.js el motor: intención, huecos, fórmulas, plantillas
│ ├── personalize.js reescribe lecciones y desafíos sobre tu idea
│ ├── persona.js la apariencia: tema, accesorios y orden del panel
│ ├── engine.js ruta, XP, vidas, insignias, ligas
│ ├── mentor.js rúbricas, análisis de texto, calculadoras
│ ├── ai.js elige proveedor de IA y arma el contexto
│ ├── ai-worker.js cliente de la IA gratuita de Emprendo
│ ├── local-ai.js diagnóstico del equipo y descarga opcional
│ ├── speech.js lectura en voz alta con la voz del dispositivo
│ ├── dictado.js la nota de voz: reconocimiento del aparato → texto
│ ├── captura.js las 8 formas de contestar y qué preguntar después
│ ├── ui.js DOM, router, modales, toasts
│ ├── fx.js confeti, partículas, contadores
│ ├── audio.js sonido sintetizado con WebAudio
│ ├── plaza.js la vitrina: qué se puede enseñar y qué nunca
│ ├── plaza-motor.js por qué te conviene acercarte a un vecino
│ ├── plaza-nube.js lo único que habla con un servidor sobre personas
│ ├── impulso.js el pase firmado: quién pagó, comprobado sin conexión
│ ├── ia-impulso.js la vía de IA de pago, contra el Worker de la Plaza
│ ├── anuncios.js la única puerta por la que puede entrar publicidad
│ ├── plan.js elige las tres tareas de la semana y las congela
│ ├── puesto.js cómo decoró su puesto, y la lista blanca que lo guarda
│ └── mascot.js Chispa (SVG animable, 7 estados de ánimo)
├── data/
│ ├── config.js niveles, jefes, insignias, ligas, tienda
│ ├── preguntas.js lo que Chispa quiere saber y cómo se contesta
│ ├── lessons-1..8.js las 50 microlecciones
│ ├── kb.js base de conocimiento de Chispa (77 entradas)
│ ├── venture-templates.js plantillas de desafío por tema y por oficio
│ ├── mascota-capas.js accesorios de Chispa, por capas
│ ├── puesto-piezas.js las 33 piezas con las que se decora un puesto
│ ├── plan-semanal.js las 25 tareas que puede tocar en una semana
│ ├── materiales.js las 8 plantillas de material listo para usar
│ ├── sim.js simulador: modelo y 22 eventos
│ └── mentor-kb.js las 26 respuestas escritas del mentor
├── local/ motor de la IA local — NO va en el precache
├── screens/ una pantalla por archivo
│ ├── personaliza.js "Personalizar mi experiencia": vista previa y controles
│ ├── plaza.js la Plaza, la vitrina y las conversaciones
│ ├── impulso.js la pantalla donde se cobra
│ ├── materiales.js las ocho plantillas, con los datos del negocio dentro
│ └── puesto.js "Decorar mi puesto": vista previa y las 5 ranuras
└── app.js arranque y navegación
Sin dependencias, sin build, sin framework. Scripts clásicos para que funcione incluso abriendo el archivo directamente.
Al publicar una versión nueva, sube
VERSIONensw.js. Ese cambio es lo que hace que quien ya tenga la app instalada reciba los archivos nuevos en vez de seguir viendo la copia guardada. Si no lo subes, a quien ya la instaló le llega el HTML nuevo con el JavaScript viejo.
Antes de publicar, comprueba que el precache siga cuadrando:
node tools/check-precache.jsY que lo demás siga cuadrando:
node tools/check-captura.jsnode tools/check-vitrina.jsnode tools/check-puesto.jsnode tools/check-plaza-worker.jsnode tools/check-gratis.jsnode tools/check-impulso.jsnode tools/check-plan.jsEse carga el catálogo y el motor de verdad, y comprueba lo que no da error cuando se rompe: que ninguna pregunta guarde en un sitio que no existe, que contestarla la saque de la cola para siempre, que saltarla no la traiga de vuelta al día siguiente, que las respuestas cerradas no acepten texto inventado y que el «esto entendí» no diga nada que no esté en el perfil.
Compara los archivos que carga index.html con la lista PRECACHE de sw.js. Las dos se escriben a mano y el service worker precarga uno por uno con su propio catch: una ruta que falte solo deja un aviso en la consola y la app deja de abrir sin conexión sin que nadie se entere.
Una lección nueva es un objeto en cualquier js/data/lessons-N.js:
{
id: 'n1-08', level: 1, icon: '🎯', title: 'Título', xp: 25, min: 6,
concept: { tag: 'Concepto', title: '…', body: ['…'], keys: ['…','…','…'] },
cas: { emoji: '🧁', title: '…', text: '…' },
steps: [
{ type: 'quiz', q: '…', opts: [{ t:'…', ok:true, why:'…' }], explain: '…' }
],
mission: {
id: 'm1-08', title: '…', brief: '…', dossier: 'cliente',
fields: [{ key:'x', label:'…', type:'text', ph:'…' }],
rubric: [{ id:'a', label:'…', check:'audience' }],
reward: { xp: 40, coins: 25 }
}
}Los check disponibles están en CHECKS dentro de js/core/mentor.js (29 comprobaciones: audience, problem, margin, steps, verbs, measurable…). El campo dossier decide qué sección de Mi Negocio se llena al entregarla.
Todo se guarda en localStorage, solo en tu dispositivo. No hay servidor, no hay cuentas, no hay telemetría. La tipografía viaja dentro del proyecto, así que la app no hace ni una sola petición a terceros mientras no actives la IA. Desde Perfil puedes exportar tu progreso a un .json y volver a importarlo en otro dispositivo.
Las excepciones son las vías de IA, y solo si tú las enciendes:
| Vía | A dónde van tus datos |
|---|---|
| IA local de Chispa | A ningún sitio. El modelo corre en tu dispositivo |
| IA gratuita de Emprendo | Al Worker de quien publicó la app, que los pasa a Workers AI. Cloudflare declara que no entrena con ellos |
| Tu clave personal | A api.anthropic.com, con tu propia clave |
Ni la clave de API ni la dirección del Worker se incluyen en el .json de respaldo: viven en otras entradas de localStorage justamente para que puedas compartir o subir ese archivo sin filtrarlas.
Como no hay servidor, ese archivo es el único respaldo posible, así que la app te lo recuerda sola: si pasan más de 7 días sin una copia y ya tienes progreso real, aparece un aviso con los botones para descargarla o copiarla al portapapeles. En Perfil › Ajustes se ve la fecha del último respaldo y el recordatorio se puede desactivar.
Los rivales de la liga son simulados: existen para dar ritmo, no para compararte con nadie real.
El contenido es formación empresarial general. Las secciones de impuestos y formalización varían por país y por nivel de ingresos: confirma siempre con la autoridad fiscal local o un contador antes de decidir.