const pptxgen = require("pptxgenjs"); const prs = new pptxgen(); // ─── Palette ──────────────────────────────────────────────────────────────── const BG_DARK = "0F1923"; // near-black navy — title / conclusion const BG_LIGHT = "F5F4F0"; // warm off-white — content slides const ACCENT = "1E7F8A"; // muted teal — a CRE/finance accent const ACCENT_LT = "BCE2E7"; // light teal highlight const TEXT_HVY = "0F1923"; // almost black const TEXT_MUT = "6B6E72"; // muted grey const WHITE = "FFFFFF"; const GOLD = "C49A1A"; // warm gold for key stats // ─── Slide size (16:9) ─────────────────────────────────────────────────────── prs.layout = "LAYOUT_WIDE"; // 10 x 5.625 inches // ─── Helper functions ──────────────────────────────────────────────────────── function darkSlide(prs) { const s = prs.addSlide(); s.background = { color: BG_DARK }; return s; } function lightSlide(prs) { const s = prs.addSlide(); s.background = { color: BG_LIGHT }; return s; } // Slide header bar (light slides only) function addHeader(slide, title, num) { // Left accent block slide.addShape(prs.ShapeType.rect, { x: 0, y: 0, w: 10, h: 0.65, fill: { color: BG_DARK } }); // Slide number chip if (num) { slide.addText(num, { x: 0.3, y: 0, w: 0.45, h: 0.65, fontSize: 9, bold: true, color: ACCENT_LT, fontFace: "Calibri", valign: "middle", align: "center" }); } // Title in header slide.addText(title, { x: 0.85, y: 0, w: 8.8, h: 0.65, fontSize: 15, bold: true, color: WHITE, fontFace: "Calibri", valign: "middle" }); } // Stat callout block function addStat(slide, value, label, x, y, w, h, valueSz, dark) { slide.addText(value, { x, y, w, h: h * 0.6, fontSize: valueSz || 48, bold: true, color: dark ? GOLD : ACCENT, fontFace: "Calibri", align: "center", valign: "bottom" }); slide.addText(label, { x, y: y + h * 0.6, w, h: h * 0.38, fontSize: 11, color: dark ? "AAAAAA" : TEXT_MUT, fontFace: "Calibri", align: "center", valign: "top" }); } // Bullet row function addBullets(slide, items, x, y, w, fontSize, color) { items.forEach((item, i) => { slide.addText([ { text: "— ", options: { color: ACCENT, bold: true } }, { text: item, options: { color: color || TEXT_HVY } } ], { x, y: y + i * 0.42, w, h: 0.38, fontSize: fontSize || 13.5, fontFace: "Calibri", valign: "middle" }); }); } // ════════════════════════════════════════════════════════════════════════════ // SLIDE 1 — Title (dark) // ════════════════════════════════════════════════════════════════════════════ { const s = darkSlide(prs); // Decorative teal bar left s.addShape(prs.ShapeType.rect, { x: 0, y: 0, w: 0.25, h: 5.625, fill: { color: ACCENT } }); // Main title s.addText("AI Investment Analyst", { x: 0.6, y: 1.2, w: 9.0, h: 1.3, fontSize: 52, bold: true, color: WHITE, fontFace: "Calibri", align: "left" }); // Subtitle s.addText("AI-аналитика для инвестиций\nв коммерческую недвижимость России", { x: 0.6, y: 2.65, w: 7.5, h: 1.0, fontSize: 20, color: "AAAAAA", fontFace: "Calibri", align: "left" }); // Tagline pill s.addShape(prs.ShapeType.rect, { x: 0.6, y: 3.85, w: 5.5, h: 0.48, fill: { color: ACCENT }, rectRadius: 0.04 }); s.addText("Self-service платформа оценки объектов, рисков и доходности", { x: 0.6, y: 3.85, w: 5.5, h: 0.48, fontSize: 11.5, color: WHITE, fontFace: "Calibri", align: "center", valign: "middle" }); // Bottom right watermark number s.addText("01", { x: 8.8, y: 4.9, w: 0.9, h: 0.5, fontSize: 28, bold: true, color: "1A2E38", fontFace: "Calibri", align: "right" }); } // ════════════════════════════════════════════════════════════════════════════ // SLIDE 2 — Рынок и масштаб // ════════════════════════════════════════════════════════════════════════════ { const s = lightSlide(prs); addHeader(s, "Рынок и масштаб", "01"); // 3 stat columns const stats = [ { val: "8–25 млрд ₽", lbl: "TAM — общий рынок" }, { val: "2.5–9 млрд ₽", lbl: "SAM — целевой сегмент" }, { val: "0.15–1.0 млрд ₽", lbl: "SOM — достижимый ARR" }, ]; stats.forEach((st, i) => { const x = 0.4 + i * 3.2; s.addShape(prs.ShapeType.rect, { x, y: 0.85, w: 3.0, h: 2.2, fill: { color: WHITE }, shadow: { type: "outer", blur: 6, offset: 2, color: "C0BDB8" } }); addStat(s, st.val, st.lbl, x, 0.85, 3.0, 2.2, 30, false); }); // User base s.addShape(prs.ShapeType.rect, { x: 0.4, y: 3.25, w: 9.2, h: 0.72, fill: { color: ACCENT }, rectRadius: 0.04 }); s.addText([ { text: "2 500 – 17 000 ", options: { bold: true, fontSize: 16 } }, { text: "потенциальных пользователей | ", options: { fontSize: 14 } }, { text: "рынок достаточен для масштабируемого AI-решения, а не только консалтинга", options: { fontSize: 14, italic: true } } ], { x: 0.4, y: 3.25, w: 9.2, h: 0.72, color: WHITE, fontFace: "Calibri", align: "center", valign: "middle" }); // Insight s.addText("Ключевой вывод", { x: 0.4, y: 4.15, w: 1.8, h: 0.3, fontSize: 9.5, bold: true, color: ACCENT, fontFace: "Calibri" }); s.addText("Коммерческая недвижимость — один из немногих классов активов, где AI-аналитика ещё не стала стандартом.", { x: 0.4, y: 4.42, w: 9.2, h: 0.55, fontSize: 12.5, color: TEXT_MUT, fontFace: "Calibri", italic: true }); } // ════════════════════════════════════════════════════════════════════════════ // SLIDE 3 — Конкурентный ландшафт // ════════════════════════════════════════════════════════════════════════════ { const s = lightSlide(prs); addHeader(s, "Конкурентный ландшафт", "02.1"); const tiers = [ { label: "Tier 1 — Данные есть, UX нет", names: "bnMAP.pro, Geointellect", desc: "Сильные данные, но узкий фокус и сложный интерфейс", col: ACCENT }, { label: "Tier 2 — Трафик без аналитики", names: "CIAN, Avito, Yandex RE", desc: "2.5+ млн CRE-пользователей в месяц — без инвестиционного скоринга", col: GOLD }, { label: "Tier 3 — Экспертиза без скорости", names: "CoStar, Argus, Core XP, Nikoliers", desc: "Глубокая экспертиза, но медленно и не масштабируется", col: "8B4A3A" } ]; tiers.forEach((t, i) => { const x = 0.35 + i * 3.15; s.addShape(prs.ShapeType.rect, { x, y: 0.85, w: 3.0, h: 3.6, fill: { color: WHITE }, shadow: { type: "outer", blur: 5, offset: 2, color: "C0BDB8" } }); // Color top bar s.addShape(prs.ShapeType.rect, { x, y: 0.85, w: 3.0, h: 0.38, fill: { color: t.col } }); s.addText(t.label, { x: x + 0.1, y: 0.85, w: 2.8, h: 0.38, fontSize: 10, bold: true, color: WHITE, fontFace: "Calibri", valign: "middle" }); s.addText(t.names, { x: x + 0.15, y: 1.32, w: 2.7, h: 0.38, fontSize: 13, bold: true, color: TEXT_HVY, fontFace: "Calibri" }); s.addText(t.desc, { x: x + 0.15, y: 1.78, w: 2.7, h: 1.0, fontSize: 12, color: TEXT_MUT, fontFace: "Calibri" }); }); // Bottom callout s.addShape(prs.ShapeType.rect, { x: 0.35, y: 4.6, w: 9.3, h: 0.5, fill: { color: "F0EDE8" } }); s.addText("Ни один игрок не закрывает инвестиционный анализ вторичного рынка с AI-скоростью", { x: 0.35, y: 4.6, w: 9.3, h: 0.5, fontSize: 12.5, bold: true, color: TEXT_HVY, fontFace: "Calibri", align: "center", valign: "middle" }); } // ════════════════════════════════════════════════════════════════════════════ // SLIDE 4 — Незанятая ниша // ════════════════════════════════════════════════════════════════════════════ { const s = lightSlide(prs); addHeader(s, "Незанятая ниша", "02.2"); // Left column: gap description s.addText("Что отсутствует на рынке", { x: 0.4, y: 0.9, w: 4.5, h: 0.38, fontSize: 13, bold: true, color: ACCENT, fontFace: "Calibri" }); addBullets(s, [ "Нет AI-движка для вторичного CRE-рынка", "Нет прозрачных данных по ставкам аренды", "Нет автоматического моделирования IRR/NPV", "Нет масштабируемого решения между листингами и консалтингом" ], 0.4, 1.38, 4.5, 12.5); // Right column: positioning visual s.addShape(prs.ShapeType.rect, { x: 5.3, y: 0.85, w: 4.3, h: 4.25, fill: { color: BG_DARK } }); s.addText("Окно\nвозможности", { x: 5.3, y: 0.85, w: 4.3, h: 1.0, fontSize: 22, bold: true, color: WHITE, fontFace: "Calibri", align: "center", valign: "middle" }); // Spectrum const items = [ { label: "Листинги (CIAN, Avito)", y: 1.95, bg: "2A3F4A", tc: "AAAAAA" }, { label: "→ AI Investment Analyst ←", y: 2.52, bg: ACCENT, tc: WHITE, bold: true }, { label: "Дорогой консалтинг", y: 3.09, bg: "2A3F4A", tc: "AAAAAA" } ]; items.forEach(it => { s.addShape(prs.ShapeType.rect, { x: 5.55, y: it.y, w: 3.8, h: 0.48, fill: { color: it.bg } }); s.addText(it.label, { x: 5.55, y: it.y, w: 3.8, h: 0.48, fontSize: 12.5, bold: !!it.bold, color: it.tc, fontFace: "Calibri", align: "center", valign: "middle" }); }); s.addText("Масштаб + скорость + доступность", { x: 5.3, y: 3.75, w: 4.3, h: 0.5, fontSize: 11, color: ACCENT_LT, fontFace: "Calibri", align: "center", italic: true }); // Bottom insight s.addText("Вывод: между «просто данными» и «дорогим советником» пусто. Это наш рынок.", { x: 0.4, y: 4.9, w: 9.2, h: 0.4, fontSize: 12, color: TEXT_MUT, fontFace: "Calibri", italic: true }); } // ════════════════════════════════════════════════════════════════════════════ // SLIDE 5 — Целевая аудитория // ════════════════════════════════════════════════════════════════════════════ { const s = lightSlide(prs); addHeader(s, "Целевая аудитория", "03"); // Two segments side by side const segs = [ { title: "Брокеры & Asset Managers", pts: [ "Профессиональный анализ объектов", "Командная работа и сравнения", "Branded reports для клиентов", "API-интеграция в экосистему" ] }, { title: "Semi-pro частные инвесторы", pts: [ "Билеты 10–50 млн руб.", "Непрозрачный прайсинг — боль №1", "Нет доступа к проверенным данным", "Хотят CRE, но без брокера" ] } ]; segs.forEach((seg, i) => { const x = 0.4 + i * 4.75; s.addShape(prs.ShapeType.rect, { x, y: 0.85, w: 4.4, h: 3.2, fill: { color: WHITE }, shadow: { type: "outer", blur: 5, offset: 2, color: "C0BDB8" } }); s.addShape(prs.ShapeType.rect, { x, y: 0.85, w: 4.4, h: 0.52, fill: { color: ACCENT } }); s.addText(seg.title, { x: x + 0.15, y: 0.85, w: 4.1, h: 0.52, fontSize: 13.5, bold: true, color: WHITE, fontFace: "Calibri", valign: "middle" }); addBullets(s, seg.pts, x + 0.15, 1.5, 4.1, 12.5); }); // Big stat s.addShape(prs.ShapeType.rect, { x: 0.4, y: 4.2, w: 4.4, h: 0.88, fill: { color: BG_DARK } }); s.addText([ { text: "1.5 млн ", options: { fontSize: 24, bold: true, color: GOLD } }, { text: "россиян войдут в CRE к 2030 году (прямые + коллективные инвестиции)", options: { fontSize: 12.5, color: "CCCCCC" } } ], { x: 0.4, y: 4.2, w: 4.4, h: 0.88, fontFace: "Calibri", valign: "middle", align: "center" }); s.addShape(prs.ShapeType.rect, { x: 5.15, y: 4.2, w: 4.45, h: 0.88, fill: { color: BG_DARK } }); s.addText([ { text: "Главный драйвер: ", options: { fontSize: 12, color: "AAAAAA" } }, { text: "демократизация класса активов,", options: { fontSize: 12.5, bold: true, color: WHITE } }, { text: " а не институционалы", options: { fontSize: 12, color: "AAAAAA" } } ], { x: 5.15, y: 4.2, w: 4.45, h: 0.88, fontFace: "Calibri", valign: "middle", align: "center" }); } // ════════════════════════════════════════════════════════════════════════════ // SLIDE 6 — Ценность продукта // ════════════════════════════════════════════════════════════════════════════ { const s = lightSlide(prs); addHeader(s, "Ценность продукта", "04"); // Two big stats left addStat(s, "×5", "быстрее принятие решений\n(AI-сводки вместо ручного анализа)", 0.4, 0.95, 3.0, 2.1, 64, false); addStat(s, "−70%", "ручной рутины\n(сбор данных и отчёты автоматизированы)", 0.4, 3.2, 3.0, 1.8, 52, false); // Right: 3 value cards const cards = [ { title: "Проверенные данные", body: "Верификация через ЕГРН, прайс-листы, secret shopper" }, { title: "Объективная оценка", body: "IRR, NPV, Cap Rate до сделки — без брокерского давления" }, { title: "Снижение риска", body: "Меньше риск «слепой» покупки — ключевой оффер продукта" } ]; cards.forEach((c, i) => { const y = 0.95 + i * 1.35; s.addShape(prs.ShapeType.rect, { x: 3.75, y, w: 5.85, h: 1.15, fill: { color: WHITE }, shadow: { type: "outer", blur: 4, offset: 2, color: "C0BDB8" } }); s.addText(c.title, { x: 4.05, y: y + 0.1, w: 5.45, h: 0.35, fontSize: 13.5, bold: true, color: ACCENT, fontFace: "Calibri" }); s.addText(c.body, { x: 4.05, y: y + 0.48, w: 5.45, h: 0.55, fontSize: 12.5, color: TEXT_HVY, fontFace: "Calibri" }); }); s.addText("Продукт продаёт не скорость — он продаёт снижение инвестиционного риска", { x: 0.4, y: 5.05, w: 9.2, h: 0.38, fontSize: 12, bold: true, color: TEXT_MUT, fontFace: "Calibri", italic: true, align: "center" }); } // ════════════════════════════════════════════════════════════════════════════ // SLIDE 7 — Продукт: что внутри // ════════════════════════════════════════════════════════════════════════════ { const s = lightSlide(prs); addHeader(s, "Продукт: что внутри", "05"); // Core modules s.addText("Обязательные модули", { x: 0.4, y: 0.85, w: 4.5, h: 0.35, fontSize: 13, bold: true, color: ACCENT, fontFace: "Calibri" }); const coreModules = ["IRR — внутренняя норма доходности", "NPV — чистая приведённая стоимость", "Cap Rate — капитализация объекта", "AI risk scoring — скоринг рисков"]; coreModules.forEach((m, i) => { s.addShape(prs.ShapeType.rect, { x: 0.4, y: 1.28 + i * 0.72, w: 4.5, h: 0.6, fill: { color: WHITE }, shadow: { type: "outer", blur: 3, offset: 1, color: "CCCCCC" } }); s.addText(m, { x: 0.65, y: 1.28 + i * 0.72, w: 4.2, h: 0.6, fontSize: 12.5, color: TEXT_HVY, fontFace: "Calibri", valign: "middle" }); }); // Data layers s.addText("Дополнительные слои данных", { x: 5.2, y: 0.85, w: 4.5, h: 0.35, fontSize: 13, bold: true, color: ACCENT, fontFace: "Calibri" }); const dataLayers = [ "Трафик мобильных операторов", "Huff models (пешеходная привлекательность)", "Исторические ставки аренды", "ЕГРН — правовая история объекта" ]; dataLayers.forEach((m, i) => { s.addShape(prs.ShapeType.rect, { x: 5.2, y: 1.28 + i * 0.72, w: 4.5, h: 0.6, fill: { color: "EDF7F8" }, shadow: { type: "outer", blur: 3, offset: 1, color: "CCCCCC" } }); s.addText(m, { x: 5.45, y: 1.28 + i * 0.72, w: 4.2, h: 0.6, fontSize: 12.5, color: TEXT_HVY, fontFace: "Calibri", valign: "middle" }); }); // Bottom s.addShape(prs.ShapeType.rect, { x: 0.4, y: 4.98, w: 9.2, h: 0.42, fill: { color: ACCENT } }); s.addText("Self-service альтернатива медленному консалтингу — данные + модели + AI в одном интерфейсе", { x: 0.4, y: 4.98, w: 9.2, h: 0.42, fontSize: 12, bold: true, color: WHITE, fontFace: "Calibri", align: "center", valign: "middle" }); } // ════════════════════════════════════════════════════════════════════════════ // SLIDE 8 — Два режима продукта // ════════════════════════════════════════════════════════════════════════════ { const s = lightSlide(prs); addHeader(s, "Два режима продукта", "05.1"); // Quick mode (left) s.addShape(prs.ShapeType.rect, { x: 0.35, y: 0.85, w: 4.5, h: 4.25, fill: { color: BG_DARK } }); s.addText("Quick Decision Mode", { x: 0.55, y: 1.0, w: 4.1, h: 0.52, fontSize: 17, bold: true, color: WHITE, fontFace: "Calibri" }); s.addText("< 60 секунд", { x: 0.55, y: 1.65, w: 4.1, h: 0.72, fontSize: 40, bold: true, color: GOLD, fontFace: "Calibri" }); s.addText("для оценки объекта", { x: 0.55, y: 2.42, w: 4.1, h: 0.35, fontSize: 13, color: "AAAAAA", fontFace: "Calibri" }); const quickPts = ["Скоринг объекта и risk meter", "Одним экраном — без настройки", "Для массового инвестора"]; quickPts.forEach((p, i) => { s.addText([ { text: "✓ ", options: { color: ACCENT_LT, bold: true } }, { text: p, options: { color: "DDDDDD" } } ], { x: 0.55, y: 2.92 + i * 0.42, w: 4.1, h: 0.38, fontSize: 12.5, fontFace: "Calibri" }); }); // Pro mode (right) s.addShape(prs.ShapeType.rect, { x: 5.15, y: 0.85, w: 4.5, h: 4.25, fill: { color: WHITE }, shadow: { type: "outer", blur: 6, offset: 2, color: "B0ADA8" } }); s.addShape(prs.ShapeType.rect, { x: 5.15, y: 0.85, w: 4.5, h: 0.52, fill: { color: ACCENT } }); s.addText("Professional Workspace", { x: 5.35, y: 0.85, w: 4.1, h: 0.52, fontSize: 16, bold: true, color: WHITE, fontFace: "Calibri", valign: "middle" }); const proPts = [ "Сценарное моделирование (bull / base / bear)", "Сравнение объектов в одном экране", "Командная работа и комментарии", "Экспорт branded reports для клиентов", "API-интеграция в CRM и BI" ]; proPts.forEach((p, i) => { s.addText([ { text: "— ", options: { color: ACCENT, bold: true } }, { text: p, options: { color: TEXT_HVY } } ], { x: 5.35, y: 1.5 + i * 0.52, w: 4.1, h: 0.45, fontSize: 12.5, fontFace: "Calibri" }); }); // Middle connector s.addText("Один продукт — два сегмента", { x: 0.35, y: 5.18, w: 9.3, h: 0.35, fontSize: 12, bold: true, color: TEXT_MUT, fontFace: "Calibri", align: "center" }); } // ════════════════════════════════════════════════════════════════════════════ // SLIDE 9 — GTM и монетизация // ════════════════════════════════════════════════════════════════════════════ { const s = lightSlide(prs); addHeader(s, "GTM и монетизация", "06"); // 3 pricing tiers const tiers = [ { name: "Freemium", price: "0 ₽", desc: "Базовый скоринг одного объекта\nБез регистрации карты" }, { name: "Pro Investor", price: "36k–120k ₽/год", desc: "Полный анализ, сценарии, история\nHeatmap и geo-слои" }, { name: "Team / Advisory", price: "Enterprise", desc: "API, командная работа\nBranded reports, white-label" } ]; tiers.forEach((t, i) => { const x = 0.35 + i * 3.18; const isMid = i === 1; s.addShape(prs.ShapeType.rect, { x, y: 0.85, w: 3.0, h: 2.45, fill: { color: isMid ? ACCENT : WHITE }, shadow: { type: "outer", blur: 5, offset: 2, color: "C0BDB8" } }); s.addText(t.name, { x: x + 0.1, y: 0.98, w: 2.8, h: 0.38, fontSize: 14, bold: true, color: isMid ? WHITE : TEXT_HVY, fontFace: "Calibri", align: "center" }); s.addText(t.price, { x: x + 0.1, y: 1.42, w: 2.8, h: 0.55, fontSize: 18, bold: true, color: isMid ? GOLD : ACCENT, fontFace: "Calibri", align: "center" }); s.addText(t.desc, { x: x + 0.15, y: 2.02, w: 2.7, h: 0.9, fontSize: 11.5, color: isMid ? "DDDDDD" : TEXT_MUT, fontFace: "Calibri", align: "center" }); }); // Channels s.addText("Каналы привлечения", { x: 0.35, y: 3.45, w: 3.5, h: 0.35, fontSize: 13, bold: true, color: ACCENT, fontFace: "Calibri" }); addBullets(s, [ "Интеграции с Avito и CIAN", "Контент: YouTube, Telegram-каналы", "Партнёрства с инвестклубами и УК" ], 0.35, 3.88, 4.3, 12.5); // Positioning s.addText("Позиционирование", { x: 5.15, y: 3.45, w: 4.5, h: 0.35, fontSize: 13, bold: true, color: ACCENT, fontFace: "Calibri" }); s.addShape(prs.ShapeType.rect, { x: 5.15, y: 3.88, w: 4.5, h: 0.82, fill: { color: BG_DARK } }); s.addText([ { text: "«AI Investment Analyst»", options: { bold: true, color: WHITE, fontSize: 15 } }, { text: "\nне просто агрегатор данных", options: { color: "AAAAAA", fontSize: 12 } } ], { x: 5.15, y: 3.88, w: 4.5, h: 0.82, fontFace: "Calibri", align: "center", valign: "middle" }); // CAC flag s.addShape(prs.ShapeType.rect, { x: 0.35, y: 4.92, w: 9.3, h: 0.45, fill: { color: "FFF3CD" } }); s.addText("⚠ CAC Red Flag: бюджет 2 млн руб. / 5 000 пользователей = 400 руб. CAC — требует верификации", { x: 0.35, y: 4.92, w: 9.3, h: 0.45, fontSize: 11.5, color: "7A5A00", fontFace: "Calibri", align: "center", valign: "middle" }); } // ════════════════════════════════════════════════════════════════════════════ // SLIDE 10 — Главный вывод (dark) // ════════════════════════════════════════════════════════════════════════════ { const s = darkSlide(prs); // Left accent bar s.addShape(prs.ShapeType.rect, { x: 0, y: 0, w: 0.25, h: 5.625, fill: { color: ACCENT } }); s.addText("Итог", { x: 0.6, y: 0.4, w: 2.0, h: 0.42, fontSize: 12, bold: true, color: ACCENT_LT, fontFace: "Calibri" }); s.addText("Занять пустую нишу\nAI-аналитики для CRE России", { x: 0.6, y: 0.9, w: 9.0, h: 1.3, fontSize: 36, bold: true, color: WHITE, fontFace: "Calibri" }); // 3 conclusion rows const rows = [ { label: "Главная ставка", body: "Незанятый вторичный CRE-рынок как точка входа для AI-платформы" }, { label: "Главная гипотеза", body: "Снижение риска продаётся лучше, чем скорость — это ключевое сообщение" }, { label: "Главный риск", body: "CAC 400 руб. при бюджете 2 млн / 5 000 пользователей — нужна валидация" } ]; rows.forEach((r, i) => { const y = 2.45 + i * 0.92; s.addShape(prs.ShapeType.rect, { x: 0.6, y, w: 9.0, h: 0.78, fill: { color: "1A2B35" } }); s.addText(r.label, { x: 0.8, y: y + 0.05, w: 2.2, h: 0.3, fontSize: 10, bold: true, color: ACCENT_LT, fontFace: "Calibri" }); s.addText(r.body, { x: 0.8, y: y + 0.35, w: 8.5, h: 0.38, fontSize: 13, color: "DDDDDD", fontFace: "Calibri" }); }); // Final tagline s.addShape(prs.ShapeType.rect, { x: 0.6, y: 5.18, w: 9.0, h: 0.28, fill: { color: ACCENT } }); s.addText("Strongest case: продукт продаёт не данные — он продаёт снижение инвестиционного риска", { x: 0.6, y: 5.18, w: 9.0, h: 0.28, fontSize: 11, bold: true, color: WHITE, fontFace: "Calibri", align: "center", valign: "middle" }); // Slide number s.addText("10", { x: 9.2, y: 0.15, w: 0.55, h: 0.35, fontSize: 10, color: "2A4450", fontFace: "Calibri", align: "right" }); } // ─── Write file ────────────────────────────────────────────────────────────── prs.writeFile({ fileName: "/home/user/workspace/ai_invest_pitch.pptx" }) .then(() => console.log("Done: ai_invest_pitch.pptx")) .catch(e => { console.error(e); process.exit(1); });