const pptxgen = require("pptxgenjs"); const React = require("react"); const ReactDOMServer = require("react-dom/server"); const sharp = require("sharp"); const { FiCheck, FiX } = require("react-icons/fi"); const { MdCalculate, MdSentimentSatisfied, MdPublic, MdDirectionsWalk } = require("react-icons/md"); const pres = new pptxgen(); pres.layout = "LAYOUT_16x9"; pres.title = "Cómo perdí 25 kg en 4 meses"; // === PALETTE === const C = { darkGreen: "04342C", midGreen: "0F6E56", green: "1D9E75", lightGreen: "5DCAA5", paleGreen: "9FE1CB", palest: "E1F5EE", white: "FFFFFF", offWhite: "F7F9F8", darkText: "1A2E28", mutedText: "5A7A70", errorBg: "FAECE7", errorText: "993C1D", errorBorder: "F0997B", }; async function iconToPng(IconComponent, color = "#ffffff", size = 256) { const svg = ReactDOMServer.renderToStaticMarkup( React.createElement(IconComponent, { color, size: String(size) }) ); const buf = await sharp(Buffer.from(svg)).png().toBuffer(); return "image/png;base64," + buf.toString("base64"); } async function main() { // ───────────────────────────────────────────────────────────────────── // SLIDE 0 — ANTES DE EMPEZAR (banner intro) // ───────────────────────────────────────────────────────────────────── { const s = pres.addSlide(); s.background = { color: "F7F9F8" }; s.addShape(pres.shapes.ROUNDED_RECTANGLE, { x: 0.4, y: 0.4, w: 9.2, h: 4.8, fill: { color: C.white }, line: { color: "D8EDE6", width: 1 }, rectRadius: 0.12, shadow: { type: "outer", color: "000000", blur: 10, offset: 3, angle: 90, opacity: 0.06 }, }); s.addShape(pres.shapes.ROUNDED_RECTANGLE, { x: 0.4, y: 0.4, w: 9.2, h: 0.55, fill: { color: C.green }, rectRadius: 0.12, }); s.addText("ANTES DE EMPEZAR", { x: 0.4, y: 0.47, w: 9.2, h: 0.4, fontSize: 10, bold: true, color: C.white, align: "center", valign: "middle", charSpacing: 3, }); s.addText("Si mientras ves este vídeo te das cuenta de que quieres ayuda para aplicar este sistema\na tu situación concreta, debajo de este vídeo encontrarás un enlace para solicitar una\nllamada gratuita.", { x: 1, y: 1.2, w: 8, h: 1.5, fontSize: 15, color: C.darkText, align: "center", valign: "top", lineSpacingMultiple: 1.3, }); s.addText("En esa llamada analizaremos tu situación actual, veremos cuántos kilos necesitas\nperder y si puedo ayudarte a conseguirlo de forma sostenible.", { x: 1, y: 2.7, w: 8, h: 1.1, fontSize: 14, color: C.mutedText, align: "center", lineSpacingMultiple: 1.3, }); s.addText("Ahora sí, vamos al vídeo.", { x: 1, y: 3.9, w: 8, h: 0.5, fontSize: 13, italic: true, color: C.green, align: "center", }); } // ───────────────────────────────────────────────────────────────────── // SLIDE 1 — HERO (dark bg) // ───────────────────────────────────────────────────────────────────── { const s = pres.addSlide(); s.background = { color: C.darkGreen }; // Big title s.addText("Cómo perdí", { x: 0.6, y: 0.5, w: 6, h: 0.8, fontSize: 34, color: C.palest, bold: false, }); s.addText("25 kg", { x: 0.6, y: 1.15, w: 6, h: 1.1, fontSize: 72, bold: true, color: C.lightGreen, }); s.addText("en 4 meses", { x: 0.6, y: 2.15, w: 6, h: 0.65, fontSize: 30, color: C.palest, }); s.addText("y lo que aprendí para no volver a recuperarlos", { x: 0.6, y: 2.85, w: 7, h: 0.6, fontSize: 15, color: C.paleGreen, italic: true, }); // Stats row const stats = [ { num: "25 kg", label: "perdidos" }, { num: "4 meses", label: "de proceso" }, { num: "100%", label: "sostenible" }, ]; stats.forEach((st, i) => { const x = 0.6 + i * 3.1; if (i > 0) { s.addShape(pres.shapes.LINE, { x: x - 0.15, y: 4.0, w: 0, h: 0.9, line: { color: "1D9E75", width: 1 }, }); } s.addText(st.num, { x, y: 3.85, w: 2.8, h: 0.6, fontSize: 22, bold: true, color: C.lightGreen, }); s.addText(st.label, { x, y: 4.42, w: 2.8, h: 0.35, fontSize: 11, color: C.paleGreen, }); }); // Bottom note s.addText("Si has perdido peso alguna vez y después lo has recuperado: probablemente el problema no sea tu fuerza de voluntad.", { x: 0.6, y: 5.05, w: 8.8, h: 0.45, fontSize: 11, color: "4D9980", italic: true, }); } // ───────────────────────────────────────────────────────────────────── // SLIDE 2 — MI HISTORIA (timeline) // ───────────────────────────────────────────────────────────────────── { const s = pres.addSlide(); s.background = { color: C.white }; s.addText("MI HISTORIA", { x: 0.6, y: 0.3, w: 4, h: 0.35, fontSize: 9, bold: true, color: C.green, charSpacing: 3, }); s.addText("Lo intenté muchas veces.\nY siempre volvía al punto de partida.", { x: 0.6, y: 0.6, w: 8, h: 1.0, fontSize: 24, bold: true, color: C.darkText, lineSpacingMultiple: 1.2, }); const items = [ { label: "El problema", text: "Me sentía incómodo, sin energía y no me gustaba lo que veía. Como mucha gente, intenté adelgazar varias veces." }, { label: "El patrón", text: "Algunas estrategias funcionaban unas semanas. Conseguía perder kilos. Pero tarde o temprano volvía al punto de partida." }, { label: "La pregunta", text: '"Si ya sé lo que tengo que hacer, ¿por qué no soy capaz de mantenerlo?" Hasta que descubrí lo que realmente estaba pasando.' }, ]; items.forEach((item, i) => { const y = 1.75 + i * 1.15; s.addShape(pres.shapes.OVAL, { x: 0.6, y: y + 0.05, w: 0.22, h: 0.22, fill: { color: C.green }, line: { color: C.green, width: 0 }, }); if (i < items.length - 1) { s.addShape(pres.shapes.LINE, { x: 0.705, y: y + 0.28, w: 0, h: 0.88, line: { color: C.paleGreen, width: 1.5 }, }); } s.addText(item.label.toUpperCase(), { x: 1.0, y: y, w: 2.5, h: 0.28, fontSize: 9, bold: true, color: C.green, charSpacing: 2, }); s.addText(item.text, { x: 1.0, y: y + 0.28, w: 8.2, h: 0.72, fontSize: 13, color: C.mutedText, lineSpacingMultiple: 1.3, }); }); } // ───────────────────────────────────────────────────────────────────── // SLIDE 3 — EL ERROR MÁS COMÚN // ───────────────────────────────────────────────────────────────────── { const checkIcon = await iconToPng(FiCheck, "#0F6E56", 256); const xIcon = await iconToPng(FiX, "#993C1D", 256); const s = pres.addSlide(); s.background = { color: C.white }; s.addText("EL ERROR MÁS COMÚN", { x: 0.6, y: 0.3, w: 6, h: 0.35, fontSize: 9, bold: true, color: C.green, charSpacing: 3, }); s.addText("El problema no es que no sepas adelgazar.", { x: 0.6, y: 0.62, w: 8.8, h: 0.7, fontSize: 26, bold: true, color: C.darkText, }); s.addText("Todo el mundo sabe que para perder peso necesita comer mejor, moverse más y controlar las calorías. Eso no es el problema.", { x: 0.6, y: 1.35, w: 8.8, h: 0.6, fontSize: 14, color: C.mutedText, lineSpacingMultiple: 1.3, }); // Wrong column s.addShape(pres.shapes.ROUNDED_RECTANGLE, { x: 0.6, y: 2.1, w: 4.2, h: 1.5, fill: { color: C.errorBg }, line: { color: C.errorBorder, width: 1 }, rectRadius: 0.1, }); s.addImage({ data: xIcon, x: 0.85, y: 2.22, w: 0.28, h: 0.28 }); s.addText("El error", { x: 1.22, y: 2.18, w: 3.3, h: 0.32, fontSize: 9, bold: true, color: C.errorText, charSpacing: 2, }); s.addText("Perder peso de una forma que no podrías mantener durante años.", { x: 0.85, y: 2.52, w: 3.7, h: 0.9, fontSize: 13, color: "712B13", lineSpacingMultiple: 1.3, }); // vs s.addText("vs", { x: 4.85, y: 2.55, w: 0.4, h: 0.4, fontSize: 13, color: C.mutedText, align: "center", }); // Right column s.addShape(pres.shapes.ROUNDED_RECTANGLE, { x: 5.2, y: 2.1, w: 4.2, h: 1.5, fill: { color: C.palest }, line: { color: C.lightGreen, width: 1 }, rectRadius: 0.1, }); s.addImage({ data: checkIcon, x: 5.45, y: 2.22, w: 0.28, h: 0.28 }); s.addText("La clave", { x: 5.82, y: 2.18, w: 3.3, h: 0.32, fontSize: 9, bold: true, color: C.midGreen, charSpacing: 2, }); s.addText("Construir un sistema que puedas mantener el resto de tu vida.", { x: 5.45, y: 2.52, w: 3.7, h: 0.9, fontSize: 13, color: "085041", lineSpacingMultiple: 1.3, }); // Big question s.addShape(pres.shapes.ROUNDED_RECTANGLE, { x: 0.6, y: 3.8, w: 8.8, h: 1.4, fill: { color: "F0FAF6" }, line: { color: C.lightGreen, width: 1 }, rectRadius: 0.12, }); s.addText("¿Podrías seguir haciendo tu dieta actual dentro de tres años?", { x: 0.9, y: 3.9, w: 8.2, h: 1.2, fontSize: 18, bold: true, color: C.darkGreen, align: "center", valign: "middle", }); } // ───────────────────────────────────────────────────────────────────── // SLIDE 4 — LOS 4 PILARES // ───────────────────────────────────────────────────────────────────── { const calcIcon = await iconToPng(MdCalculate, "#1D9E75", 256); const smileIcon = await iconToPng(MdSentimentSatisfied, "#1D9E75", 256); const worldIcon = await iconToPng(MdPublic, "#1D9E75", 256); const walkIcon = await iconToPng(MdDirectionsWalk, "#1D9E75", 256); const icons = [calcIcon, smileIcon, worldIcon, walkIcon]; const s = pres.addSlide(); s.background = { color: C.white }; s.addText("EL SISTEMA", { x: 0.6, y: 0.3, w: 4, h: 0.35, fontSize: 9, bold: true, color: C.green, charSpacing: 3, }); s.addText("Dejé de buscar la dieta perfecta.\nEmpecé a construir un sistema.", { x: 0.6, y: 0.62, w: 8.8, h: 0.9, fontSize: 24, bold: true, color: C.darkText, lineSpacingMultiple: 1.2, }); s.addText("No para una vida ideal. Para mi vida real, con cenas fuera, antojos y días imperfectos.", { x: 0.6, y: 1.55, w: 8.8, h: 0.4, fontSize: 13, color: C.mutedText, }); const pillars = [ { title: "Control de calorías", desc: "Entender cuánto necesitas comer para perder peso de forma progresiva, sin pasar hambre ni eliminar grupos de alimentos." }, { title: "Saciedad", desc: "Comidas que te permiten comer suficiente, disfrutar, y seguir perdiendo peso. Sin depender de fuerza de voluntad." }, { title: "Vida real", desc: "Cumpleaños, cenas fuera, viajes. Hábitos que funcionan cuando la vida ocurre." }, { title: "Movimiento diario", desc: "Aumenta el gasto energético de forma natural, sin vivir en el gimnasio." }, ]; pillars.forEach((p, i) => { const col = i % 2; const row = Math.floor(i / 2); const x = 0.5 + col * 4.75; const y = 2.15 + row * 1.55; s.addShape(pres.shapes.ROUNDED_RECTANGLE, { x, y, w: 4.45, h: 1.4, fill: { color: C.offWhite }, line: { color: "D8EDE6", width: 0.75 }, rectRadius: 0.1, shadow: { type: "outer", color: "000000", blur: 5, offset: 1, angle: 90, opacity: 0.05 }, }); s.addShape(pres.shapes.ROUNDED_RECTANGLE, { x: x + 0.15, y: y + 0.2, w: 0.42, h: 0.42, fill: { color: C.palest }, line: { color: C.palest, width: 0 }, rectRadius: 0.06, }); s.addImage({ data: icons[i], x: x + 0.18, y: y + 0.23, w: 0.35, h: 0.35 }); s.addText(p.title, { x: x + 0.7, y: y + 0.2, w: 3.5, h: 0.38, fontSize: 13, bold: true, color: C.darkText, }); s.addText(p.desc, { x: x + 0.15, y: y + 0.62, w: 4.1, h: 0.72, fontSize: 11, color: C.mutedText, lineSpacingMultiple: 1.25, }); }); } // ───────────────────────────────────────────────────────────────────── // SLIDE 5 — PILAR 1: CALORÍAS // ───────────────────────────────────────────────────────────────────── { const checkIcon = await iconToPng(FiCheck, "#FFFFFF", 256); const s = pres.addSlide(); s.background = { color: C.white }; s.addText("PILAR 1", { x: 0.6, y: 0.3, w: 3, h: 0.35, fontSize: 9, bold: true, color: C.green, charSpacing: 3, }); s.addText("Control de calorías", { x: 0.6, y: 0.62, w: 8.8, h: 0.7, fontSize: 30, bold: true, color: C.darkText, }); s.addText("No importa qué dieta hagas: para perder grasa necesitas consumir menos energía de la que gastas. Esto no significa pasar hambre, ni eliminar alimentos, ni comer pollo y brócoli todo el día.", { x: 0.6, y: 1.42, w: 8.8, h: 0.85, fontSize: 14, color: C.mutedText, lineSpacingMultiple: 1.4, }); s.addShape(pres.shapes.ROUNDED_RECTANGLE, { x: 0.6, y: 2.45, w: 8.8, h: 0.9, fill: { color: C.palest }, line: { color: C.lightGreen, width: 1 }, rectRadius: 0.1, }); s.addText("Significa entender cómo funciona realmente la pérdida de grasa y dejar de depender de reglas absurdas.", { x: 0.9, y: 2.5, w: 8.2, h: 0.8, fontSize: 14, bold: true, color: C.darkGreen, valign: "middle", lineSpacingMultiple: 1.3, }); const checks = ["Déficit progresivo, no agresivo", "Sin eliminar grupos de alimentos", "Pérdida sostenida en el tiempo"]; checks.forEach((txt, i) => { const y = 3.55 + i * 0.52; s.addShape(pres.shapes.OVAL, { x: 0.6, y: y + 0.03, w: 0.3, h: 0.3, fill: { color: C.green }, line: { color: C.green, width: 0 }, }); s.addImage({ data: checkIcon, x: 0.66, y: y + 0.06, w: 0.18, h: 0.18 }); s.addText(txt, { x: 1.05, y, w: 8, h: 0.38, fontSize: 14, color: C.darkText, }); }); } // ───────────────────────────────────────────────────────────────────── // SLIDE 6 — PILAR 2: SACIEDAD // ───────────────────────────────────────────────────────────────────── { const checkIcon = await iconToPng(FiCheck, "#FFFFFF", 256); const s = pres.addSlide(); s.background = { color: C.white }; s.addText("PILAR 2", { x: 0.6, y: 0.3, w: 3, h: 0.35, fontSize: 9, bold: true, color: C.green, charSpacing: 3, }); s.addText("Saciedad: el arma secreta", { x: 0.6, y: 0.62, w: 8.8, h: 0.7, fontSize: 30, bold: true, color: C.darkText, }); s.addText("El problema de muchas dietas es que te dejan con hambre. Cuando tienes hambre constantemente, dependes de fuerza de voluntad. Y la fuerza de voluntad siempre acaba agotándose.", { x: 0.6, y: 1.42, w: 8.8, h: 0.85, fontSize: 14, color: C.mutedText, lineSpacingMultiple: 1.4, }); s.addShape(pres.shapes.ROUNDED_RECTANGLE, { x: 0.6, y: 2.45, w: 8.8, h: 0.9, fill: { color: C.palest }, line: { color: C.lightGreen, width: 1 }, rectRadius: 0.1, }); s.addText("Cuando controlas el hambre, todo se vuelve mucho más fácil. El autocontrol deja de ser necesario.", { x: 0.9, y: 2.5, w: 8.2, h: 0.8, fontSize: 14, bold: true, color: C.darkGreen, valign: "middle", lineSpacingMultiple: 1.3, }); const checks = ["Comidas que sacian de verdad", "Disfrutar sin sentir culpa", "Sin depender de motivación diaria"]; checks.forEach((txt, i) => { const y = 3.55 + i * 0.52; s.addShape(pres.shapes.OVAL, { x: 0.6, y: y + 0.03, w: 0.3, h: 0.3, fill: { color: C.green }, line: { color: C.green, width: 0 }, }); s.addImage({ data: checkIcon, x: 0.66, y: y + 0.06, w: 0.18, h: 0.18 }); s.addText(txt, { x: 1.05, y, w: 8, h: 0.38, fontSize: 14, color: C.darkText, }); }); } // ───────────────────────────────────────────────────────────────────── // SLIDE 7 — PILAR 3: VIDA REAL // ───────────────────────────────────────────────────────────────────── { const checkIcon = await iconToPng(FiCheck, "#FFFFFF", 256); const s = pres.addSlide(); s.background = { color: C.white }; s.addText("PILAR 3", { x: 0.6, y: 0.3, w: 3, h: 0.35, fontSize: 9, bold: true, color: C.green, charSpacing: 3, }); s.addText("Adaptación a la vida real", { x: 0.6, y: 0.62, w: 8.8, h: 0.7, fontSize: 30, bold: true, color: C.darkText, }); s.addText("Aquí es donde fracasa la mayoría. Adelgazar un martes es fácil. Lo difícil es seguir cuando la vida ocurre.", { x: 0.6, y: 1.42, w: 8.8, h: 0.6, fontSize: 14, color: C.mutedText, lineSpacingMultiple: 1.4, }); const situations = ["Un cumpleaños", "Una cena fuera", "Un viaje o fin de semana diferente"]; situations.forEach((txt, i) => { const y = 2.2 + i * 0.52; s.addShape(pres.shapes.OVAL, { x: 0.6, y: y + 0.03, w: 0.3, h: 0.3, fill: { color: C.green }, line: { color: C.green, width: 0 }, }); s.addImage({ data: checkIcon, x: 0.66, y: y + 0.06, w: 0.18, h: 0.18 }); s.addText(txt, { x: 1.05, y, w: 8, h: 0.38, fontSize: 14, color: C.darkText, }); }); s.addShape(pres.shapes.ROUNDED_RECTANGLE, { x: 0.6, y: 3.75, w: 8.8, h: 1.45, fill: { color: "F0FAF6" }, line: { color: C.lightGreen, width: 1 }, rectRadius: 0.12, }); s.addText("La pregunta no es "¿puedo perder peso?"", { x: 0.9, y: 3.88, w: 8.2, h: 0.42, fontSize: 15, bold: true, color: C.darkGreen, }); s.addText("La pregunta es "¿puedo seguir perdiéndolo cuando la vida ocurre?"", { x: 0.9, y: 4.3, w: 8.2, h: 0.6, fontSize: 14, color: C.midGreen, lineSpacingMultiple: 1.3, }); } // ───────────────────────────────────────────────────────────────────── // SLIDE 8 — PILAR 4: MOVIMIENTO // ───────────────────────────────────────────────────────────────────── { const checkIcon = await iconToPng(FiCheck, "#FFFFFF", 256); const s = pres.addSlide(); s.background = { color: C.white }; s.addText("PILAR 4", { x: 0.6, y: 0.3, w: 3, h: 0.35, fontSize: 9, bold: true, color: C.green, charSpacing: 3, }); s.addText("Movimiento diario", { x: 0.6, y: 0.62, w: 8.8, h: 0.7, fontSize: 30, bold: true, color: C.darkText, }); s.addText("Mucha gente cree que necesita vivir en el gimnasio. Yo también lo pensaba. Pero para la mayoría de personas con poco tiempo existe una herramienta mucho más sencilla.", { x: 0.6, y: 1.42, w: 8.8, h: 0.85, fontSize: 14, color: C.mutedText, lineSpacingMultiple: 1.4, }); s.addShape(pres.shapes.ROUNDED_RECTANGLE, { x: 0.6, y: 2.45, w: 8.8, h: 0.9, fill: { color: C.palest }, line: { color: C.lightGreen, width: 1 }, rectRadius: 0.1, }); s.addText("Moverse más durante el día. Caminar más. Sin convertir tu vida en un plan de entrenamiento imposible de mantener.", { x: 0.9, y: 2.5, w: 8.2, h: 0.8, fontSize: 14, bold: true, color: C.darkGreen, valign: "middle", lineSpacingMultiple: 1.3, }); const checks = [ "Aumenta el gasto energético de forma natural", "Sin necesitar horas en el gimnasio", "Integrable en cualquier rutina", ]; checks.forEach((txt, i) => { const y = 3.55 + i * 0.52; s.addShape(pres.shapes.OVAL, { x: 0.6, y: y + 0.03, w: 0.3, h: 0.3, fill: { color: C.green }, line: { color: C.green, width: 0 }, }); s.addImage({ data: checkIcon, x: 0.66, y: y + 0.06, w: 0.18, h: 0.18 }); s.addText(txt, { x: 1.05, y, w: 8, h: 0.38, fontSize: 14, color: C.darkText, }); }); } // ───────────────────────────────────────────────────────────────────── // SLIDE 9 — LA GRAN LECCIÓN // ───────────────────────────────────────────────────────────────────── { const xIcon = await iconToPng(FiX, "#993C1D", 256); const checkIcon = await iconToPng(FiCheck, "#0F6E56", 256); const s = pres.addSlide(); s.background = { color: C.white }; s.addText("LA GRAN LECCIÓN", { x: 0.6, y: 0.3, w: 6, h: 0.35, fontSize: 9, bold: true, color: C.green, charSpacing: 3, }); s.addText("Si solo recuerdas una cosa de este vídeo, que sea esta.", { x: 0.6, y: 0.62, w: 8.8, h: 0.65, fontSize: 22, bold: true, color: C.darkText, }); // Wrong s.addShape(pres.shapes.ROUNDED_RECTANGLE, { x: 0.6, y: 1.45, w: 8.8, h: 0.8, fill: { color: C.errorBg }, line: { color: C.errorBorder, width: 1 }, rectRadius: 0.1, }); s.addImage({ data: xIcon, x: 0.82, y: 1.63, w: 0.3, h: 0.3 }); s.addText("El problema NO es perder peso.", { x: 1.25, y: 1.58, w: 7.8, h: 0.55, fontSize: 15, bold: true, color: "712B13", valign: "middle", }); // Right s.addShape(pres.shapes.ROUNDED_RECTANGLE, { x: 0.6, y: 2.38, w: 8.8, h: 1.05, fill: { color: C.palest }, line: { color: C.lightGreen, width: 1 }, rectRadius: 0.1, }); s.addImage({ data: checkIcon, x: 0.82, y: 2.55, w: 0.3, h: 0.3 }); s.addText("El problema es perder peso de una forma que no puedes mantener.\nSi no puedes mantener el proceso, tampoco podrás mantener el resultado.", { x: 1.25, y: 2.45, w: 7.9, h: 0.9, fontSize: 14, color: "085041", lineSpacingMultiple: 1.35, }); s.addText("La razón por la que muchas personas recuperan el peso no es porque sean débiles. Es porque nunca aprendieron a adaptar la pérdida de peso a su vida real.", { x: 0.6, y: 3.58, w: 8.8, h: 0.85, fontSize: 14, color: C.mutedText, lineSpacingMultiple: 1.4, }); } // ───────────────────────────────────────────────────────────────────── // SLIDE 10 — CTA (dark bg) // ───────────────────────────────────────────────────────────────────── { const checkIcon = await iconToPng(FiCheck, "#5DCAA5", 256); const s = pres.addSlide(); s.background = { color: C.darkGreen }; s.addText("QUÉ HACER AHORA", { x: 0.6, y: 0.3, w: 6, h: 0.35, fontSize: 9, bold: true, color: C.lightGreen, charSpacing: 3, }); s.addText("¿Quieres ayuda para aplicar esto\na tu situación?", { x: 0.6, y: 0.62, w: 8.8, h: 1.1, fontSize: 28, bold: true, color: C.palest, lineSpacingMultiple: 1.2, }); s.addText("Si has llegado hasta aquí, te invito a solicitar una llamada gratuita donde veremos:", { x: 0.6, y: 1.82, w: 8.8, h: 0.42, fontSize: 13, color: C.paleGreen, }); const items = [ "Cuántos kilos necesitas perder", "Qué te ha impedido conseguirlo hasta ahora", "Qué estrategia sería la más adecuada para tu situación", "Si tiene sentido que trabajemos juntos", ]; items.forEach((txt, i) => { const y = 2.35 + i * 0.47; s.addImage({ data: checkIcon, x: 0.6, y: y + 0.06, w: 0.22, h: 0.22 }); s.addText(txt, { x: 0.98, y, w: 8.2, h: 0.38, fontSize: 13, color: C.palest, }); }); // CTA button (rectangle) s.addShape(pres.shapes.ROUNDED_RECTANGLE, { x: 0.6, y: 4.42, w: 3.8, h: 0.65, fill: { color: C.lightGreen }, line: { color: C.lightGreen, width: 0 }, rectRadius: 0.08, }); s.addText("Solicitar llamada gratuita →", { x: 0.6, y: 4.42, w: 3.8, h: 0.65, fontSize: 13, bold: true, color: C.darkGreen, align: "center", valign: "middle", }); s.addText("⚠ Plazas limitadas — solo trabajo con un número reducido de personas al mismo tiempo", { x: 0.6, y: 5.18, w: 8.8, h: 0.3, fontSize: 10, color: "4D9980", italic: true, }); } await pres.writeFile({ fileName: "/home/claude/presentacion_25kg.pptx" }); console.log("✅ Presentación generada."); } main().catch(console.error);
Made on
Tilda