teste
const {
Document, Packer, Paragraph, TextRun, Table, TableRow, TableCell,
AlignmentType, HeadingLevel, BorderStyle, WidthType, ShadingType,
LevelFormat, PageBreak, PageNumber, Header, Footer
} = require('docx');
const fs = require('fs');
// ── Colors ──
const C = {
brand: 'AED3D9',
brandDd: '1E4D54',
brandD: '3A7A85',
lilas: '8A70C8',
lilasCl: 'EDE8F8',
ok: '2A7A50',
okCl: 'E6F7EE',
av: 'C08020',
avCl: 'FDF5E0',
er: '7A2A2A',
erCl: 'FDE8E8',
white: 'FFFFFF',
gray1: 'F4FBFC',
gray2: 'E8F0F2',
text: '1A3A40',
};
const border1 = { style: BorderStyle.SINGLE, size: 1, color: 'CCCCCC' };
const borders = { top: border1, bottom: border1, left: border1, right: border1 };
const borderNone = { style: BorderStyle.NONE, size: 0, color: 'FFFFFF' };
const bordersNone = { top: borderNone, bottom: borderNone, left: borderNone, right: borderNone };
const W = 9360; // content width DXA (US Letter 1" margins)
// ── Helpers ──
function h(text, level, color = C.brandDd) {
return new Paragraph({
heading: level,
children: [new TextRun({ text, color, bold: true })],
spacing: { before: 280, after: 120 },
});
}
function p(runs, spacing = { before: 80, after: 100 }, align = AlignmentType.JUSTIFIED) {
const children = Array.isArray(runs)
? runs.map(r => new TextRun(r))
: [new TextRun(typeof runs === 'string' ? { text: runs, size: 22, color: C.text } : runs)];
return new Paragraph({ children, spacing, alignment: align });
}
function bold(text, color = C.brandDd) {
return { text, bold: true, color, size: 22 };
}
function normal(text, color = C.text) {
return { text, size: 22, color };
}
function bullet(text, bold_ = false, color = C.text) {
return new Paragraph({
numbering: { reference: 'bullets', level: 0 },
children: [new TextRun({ text, size: 22, color, bold: bold_ })],
spacing: { before: 40, after: 40 },
});
}
function sub(text) {
return new Paragraph({
numbering: { reference: 'bullets2', level: 0 },
children: [new TextRun({ text, size: 20, color: C.text })],
spacing: { before: 20, after: 20 },
});
}
function divider(color = C.brand) {
return new Paragraph({
border: { bottom: { style: BorderStyle.SINGLE, size: 8, color, space: 4 } },
spacing: { before: 180, after: 180 },
children: [],
});
}
function space(before = 160) {
return new Paragraph({ children: [], spacing: { before } });
}
function cell(children, options = {}) {
return new TableCell({
borders,
margins: { top: 100, bottom: 100, left: 120, right: 120 },
shading: options.bg ? { fill: options.bg, type: ShadingType.CLEAR } : undefined,
verticalAlign: options.vAlign || 'center',
width: options.width ? { size: options.width, type: WidthType.DXA } : undefined,
children: Array.isArray(children) ? children : [children],
});
}
function headerCell(text, width, bg = C.brandDd) {
return new TableCell({
borders,
margins: { top: 100, bottom: 100, left: 120, right: 120 },
shading: { fill: bg, type: ShadingType.CLEAR },
width: { size: width, type: WidthType.DXA },
children: [new Paragraph({
alignment: AlignmentType.CENTER,
children: [new TextRun({ text, bold: true, color: C.white, size: 20 })],
})],
});
}
function tableRow(cells) {
return new TableRow({ children: cells });
}
// Highlight box
function box(title, lines, bgColor = C.okCl, titleColor = C.ok) {
const rows = [];
// title row
rows.push(tableRow([cell(
new Paragraph({ children: [new TextRun({ text: title, bold: true, size: 22, color: titleColor })] }),
{ bg: bgColor, width: W }
)]));
// content rows
lines.forEach(line => rows.push(tableRow([cell(
new Paragraph({ children: [new TextRun({ text: line, size: 21, color: C.text })], spacing: { before: 30, after: 30 } }),
{ bg: bgColor, width: W }
)])));
return new Table({ width: { size: W, type: WidthType.DXA }, columnWidths: [W], rows, borders: bordersNone });
}
// Phase card
function phaseCard(num, title, months, bg, titleBg) {
return new Table({
width: { size: W, type: WidthType.DXA },
columnWidths: [900, W - 900],
rows: [tableRow([
cell(
new Paragraph({ alignment: AlignmentType.CENTER, children: [
new TextRun({ text: num, bold: true, size: 36, color: C.white }),
new TextRun({ text: '\n' + months, size: 18, color: C.white, break: 1 }),
]}),
{ bg: titleBg, width: 900 }
),
cell(
new Paragraph({ children: [new TextRun({ text: title, bold: true, size: 26, color: C.brandDd })], spacing: { before: 60 } }),
{ bg, width: W - 900 }
),
])],
borders: bordersNone,
});
}
// ─────────────────────────────────────────────
// DOCUMENT
// ─────────────────────────────────────────────
const doc = new Document({
numbering: {
config: [
{
reference: 'bullets',
levels: [{
level: 0, format: LevelFormat.BULLET, text: '\u2022',
alignment: AlignmentType.LEFT,
style: { paragraph: { indent: { left: 560, hanging: 280 } } },
}],
},
{
reference: 'bullets2',
levels: [{
level: 0, format: LevelFormat.BULLET, text: '\u25E6',
alignment: AlignmentType.LEFT,
style: { paragraph: { indent: { left: 900, hanging: 280 } } },
}],
},
{
reference: 'numbers',
levels: [{
level: 0, format: LevelFormat.DECIMAL, text: '%1.',
alignment: AlignmentType.LEFT,
style: { paragraph: { indent: { left: 560, hanging: 280 } } },
}],
},
],
},
styles: {
default: {
document: { run: { font: 'Arial', size: 22, color: C.text } },
},
paragraphStyles: [
{
id: 'Heading1', name: 'Heading 1', basedOn: 'Normal', next: 'Normal', quickFormat: true,
run: { size: 36, bold: true, font: 'Arial', color: C.brandDd },
paragraph: { spacing: { before: 320, after: 160 }, outlineLevel: 0 },
},
{
id: 'Heading2', name: 'Heading 2', basedOn: 'Normal', next: 'Normal', quickFormat: true,
run: { size: 28, bold: true, font: 'Arial', color: C.brandD },
paragraph: { spacing: { before: 260, after: 120 }, outlineLevel: 1 },
},
{
id: 'Heading3', name: 'Heading 3', basedOn: 'Normal', next: 'Normal', quickFormat: true,
run: { size: 24, bold: true, font: 'Arial', color: C.lilas },
paragraph: { spacing: { before: 200, after: 80 }, outlineLevel: 2 },
},
],
},
sections: [{
properties: {
page: {
size: { width: 12240, height: 15840 },
margin: { top: 1080, right: 1080, bottom: 1080, left: 1080 },
},
},
headers: {
default: new Header({
children: [
new Table({
width: { size: W + 360, type: WidthType.DXA },
columnWidths: [W + 360],
rows: [tableRow([cell(
new Paragraph({
alignment: AlignmentType.RIGHT,
border: { bottom: { style: BorderStyle.SINGLE, size: 4, color: C.brand, space: 4 } },
children: [
new TextRun({ text: 'Tudo Controlado | Plano de Vendas 2025–2026', size: 18, color: C.brandD }),
],
}),
{ bg: C.white, width: W + 360 }
)])],
borders: bordersNone,
}),
],
}),
},
children: [
// ══════════════════ CAPA ══════════════════
new Paragraph({
alignment: AlignmentType.CENTER,
spacing: { before: 600, after: 80 },
children: [new TextRun({ text: 'TUDO CONTROLADO', bold: true, size: 56, color: C.brandDd })],
}),
new Paragraph({
alignment: AlignmentType.CENTER,
spacing: { before: 0, after: 60 },
children: [new TextRun({ text: 'Gestao de Cosmeticos Artesanais', size: 28, color: C.brandD })],
}),
divider(C.brand),
new Paragraph({
alignment: AlignmentType.CENTER,
spacing: { before: 0, after: 600 },
children: [new TextRun({ text: 'PLANO ESTRATEGICO DE VENDAS | 2025 - 2026', bold: true, size: 26, color: C.lilas })],
}),
// ─ Resumo executivo ─
new Table({
width: { size: W, type: WidthType.DXA },
columnWidths: [W],
rows: [
tableRow([cell(
new Paragraph({ alignment: AlignmentType.CENTER, children: [new TextRun({ text: 'RESUMO EXECUTIVO', bold: true, size: 24, color: C.white })] }),
{ bg: C.brandDd, width: W }
)]),
tableRow([cell([
p([normal('O ', C.text), bold('Tudo Controlado'), normal(' e o primeiro sistema de gestao completo desenhado especificamente para produtores artesanais de cosmeticos no Brasil. Nao e uma planilha. Nao e um sistema de estoque generico. E uma ferramenta construida para quem produz com as maos e quer crescer com a cabeca.', C.text)]),
p(normal('Este plano cobre os primeiros 12 meses de comercializacao, com foco principal em parcerias estrategicas com fornecedores de ingredientes e instrutores de cursos — os dois maiores canais de confianca do nosso publico.')),
], { bg: C.gray1, width: W })]),
],
borders: bordersNone,
}),
space(400),
// ══════════════════ 1. POSICIONAMENTO ══════════════════
h('1. POSICIONAMENTO E PROPOSTA DE VALOR', HeadingLevel.HEADING_1),
divider(),
h('1.1 Para quem e o sistema', HeadingLevel.HEADING_2),
p(normal('Pessoas fisicas e microempresas que produzem cosmeticos artesanais para venda — shampoos, hidratantes, seruns, sabonetes, perfumes — sem serem industria. Esse publico:')),
space(40),
bullet('Trabalha de casa, em atelie proprio ou em espaco compartilhado'),
bullet('Vende por WhatsApp, Instagram, feiras e lojas locais'),
bullet('Quer ser levado a serio pelos clientes e pela lei (ANVISA)'),
bullet('Tem dificuldade para precificar corretamente e controlar estoque'),
bullet('Perde dinheiro porque nao sabe exatamente quanto custa cada frasco'),
bullet('Precisa de agilidade, nao de complexidade'),
space(120),
h('1.2 Por que o Tudo Controlado e diferente', HeadingLevel.HEADING_2),
new Table({
width: { size: W, type: WidthType.DXA },
columnWidths: [Math.round(W * 0.38), Math.round(W * 0.31), Math.round(W * 0.31)],
rows: [
tableRow([
headerCell('Funcionalidade', Math.round(W * 0.38)),
headerCell('Planilha / Solucao Generica', Math.round(W * 0.31), C.er),
headerCell('Tudo Controlado', Math.round(W * 0.31), C.ok),
]),
...([
['Formulas com % por ingrediente', 'Manual e propenso a erro', '✔ Automatico com validacao'],
['Calculo de custo por frasco', 'Formula manual complexa', '✔ Calculado na producao'],
['Controle de validade e INCI', 'Nao tem', '✔ Campos dedicados'],
['Checklist BPF / ANVISA', 'Nao tem', '✔ 13 itens com PDF'],
['Geracao de etiqueta legal', 'Nao tem', '✔ RDC 907/2024 + 898/2024'],
['Cosmetovigilancia', 'Nao tem', '✔ Registro conforme RDC 894/2024'],
['Producao em lote (planejador)', 'Nao tem', '✔ Multi-formulas simultaneas'],
['Funciona offline, sem internet', 'Precisa de conexao (cloud)', '✔ Arquivo local no dispositivo'],
['Foto do produto', 'Nao tem', '✔ Upload direto da camera'],
].map(([feat, old, novo], i) => tableRow([
cell(new Paragraph({ children: [new TextRun({ text: feat, size: 21, color: C.text, bold: true })] }), { bg: i % 2 === 0 ? C.white : C.gray1, width: Math.round(W * 0.38) }),
cell(new Paragraph({ children: [new TextRun({ text: old, size: 20, color: C.er })] }), { bg: i % 2 === 0 ? C.white : C.gray1, width: Math.round(W * 0.31) }),
cell(new Paragraph({ children: [new TextRun({ text: novo, size: 20, color: C.ok })] }), { bg: i % 2 === 0 ? C.white : C.gray1, width: Math.round(W * 0.31) }),
]))),
],
}),
space(300),
// ══════════════════ 2. MODELO DE NEGOCIO ══════════════════
h('2. MODELO DE NEGOCIO E PRECIFICACAO', HeadingLevel.HEADING_1),
divider(),
h('2.1 Planos sugeridos (a definir)', HeadingLevel.HEADING_2),
new Table({
width: { size: W, type: WidthType.DXA },
columnWidths: [Math.round(W * 0.25), Math.round(W * 0.25), Math.round(W * 0.25), Math.round(W * 0.25)],
rows: [
tableRow([
headerCell('', Math.round(W * 0.25), C.gray2),
headerCell('ESSENCIAL', Math.round(W * 0.25), C.brandD),
headerCell('PROFISSIONAL', Math.round(W * 0.25), C.lilas),
headerCell('PARCEIRO', Math.round(W * 0.25), C.brandDd),
]),
...([
['Preco mensal', 'R$ 39,90', 'R$ 79,90', 'Negociado'],
['Preco anual (desconto)', 'R$ 349/ano', 'R$ 699/ano', 'Negociado'],
['Formulas', 'Ate 15', 'Ilimitado', 'Ilimitado'],
['Ingredientes', 'Ate 50', 'Ilimitado', 'Ilimitado'],
['Usuarios', '1', '1 + 1 colaborador', 'Multi-usuario'],
['PDF / Etiquetas', 'Ilimitado', 'Ilimitado', 'Personalizado com logo'],
['ANVISA / BPF', 'Basico', 'Completo', 'Completo + suporte'],
['Suporte', 'Email', 'Email + Chat', 'Prioritario'],
].map(([feat, e, pro, par], i) => tableRow([
cell(new Paragraph({ children: [new TextRun({ text: feat, size: 20, bold: true, color: C.text })] }), { bg: i % 2 === 0 ? C.gray1 : C.white, width: Math.round(W * 0.25) }),
cell(new Paragraph({ children: [new TextRun({ text: e, size: 20, color: C.text })] }), { bg: i % 2 === 0 ? C.gray1 : C.white, width: Math.round(W * 0.25) }),
cell(new Paragraph({ children: [new TextRun({ text: pro, size: 20, color: C.text })] }), { bg: i % 2 === 0 ? C.gray1 : C.white, width: Math.round(W * 0.25) }),
cell(new Paragraph({ children: [new TextRun({ text: par, size: 20, color: C.text })] }), { bg: i % 2 === 0 ? C.gray1 : C.white, width: Math.round(W * 0.25) }),
]))),
],
}),
space(80),
p([bold('Nota: ', C.av), normal('Os precos acima sao sugestoes de referencia. O valor final deve ser validado com pesquisa de disposicao a pagar junto ao publico-alvo antes do lancamento oficial.')]),
space(200),
h('2.2 Modelo de comissao para parceiros', HeadingLevel.HEADING_2),
p(normal('A parceria com fornecedores e instrutores funciona por indicacao rastreada. O parceiro indica o sistema com um link ou cupom exclusivo. A cada adesao:')),
space(40),
new Table({
width: { size: W, type: WidthType.DXA },
columnWidths: [Math.round(W * 0.4), Math.round(W * 0.3), Math.round(W * 0.3)],
rows: [
tableRow([
headerCell('Evento', Math.round(W * 0.4)),
headerCell('Comissao sugerida', Math.round(W * 0.3)),
headerCell('Observacao', Math.round(W * 0.3)),
]),
...([
['Adesao anual (plano Essencial)', '20% do valor pago', 'Pago uma vez na adesao'],
['Adesao anual (plano Profissional)', '25% do valor pago', 'Pago uma vez na adesao'],
['Mensalidade recorrente', '15% por mes ativo', 'Enquanto o cliente pagar'],
['Parceiro Premium (volume > 20/mes)', 'Negociado caso a caso', 'Pode incluir co-marketing'],
].map(([e, c, o], i) => tableRow([
cell(new Paragraph({ children: [new TextRun({ text: e, size: 20, bold: true, color: C.text })] }), { bg: i % 2 === 0 ? C.white : C.gray1, width: Math.round(W * 0.4) }),
cell(new Paragraph({ children: [new TextRun({ text: c, size: 20, color: C.ok, bold: true })] }), { bg: i % 2 === 0 ? C.white : C.gray1, width: Math.round(W * 0.3) }),
cell(new Paragraph({ children: [new TextRun({ text: o, size: 20, color: C.text })] }), { bg: i % 2 === 0 ? C.white : C.gray1, width: Math.round(W * 0.3) }),
]))),
],
}),
space(80),
box('Por que isso funciona para o parceiro?', [
'• Renda passiva real: um curso com 100 alunos que convertem 30% gera comissao recorrente todos os meses',
'• Zero esforco operacional: o parceiro so indica; o sistema, pagamento e suporte sao nossos',
'• Agrega valor ao proprio negocio: quem vende ingrediente passa a oferecer solucao completa ao cliente',
'• Dashboard de acompanhamento: o parceiro ve em tempo real quantas indicacoes converteram e quanto recebera',
], C.okCl, C.ok),
space(300),
// ══════════════════ 3. PUBLICO ALVO ══════════════════
h('3. PUBLICO-ALVO E PERSONAS', HeadingLevel.HEADING_1),
divider(),
h('3.1 Usuario final (quem usa o sistema)', HeadingLevel.HEADING_2),
new Table({
width: { size: W, type: WidthType.DXA },
columnWidths: [Math.round(W / 3), Math.round(W / 3), Math.round(W / 3)],
rows: [
tableRow([
headerCell('Iniciante', Math.round(W / 3), C.brandD),
headerCell('Em crescimento', Math.round(W / 3), C.lilas),
headerCell('Estabelecida', Math.round(W / 3), C.brandDd),
]),
tableRow([
cell([
p(normal('Acabou de fazer o primeiro curso. Produz para amigos e familia. Quer comecar a cobrar.')),
p(normal('Dor: nao sabe quanto cobrar e tem medo de errar na ANVISA.')),
], { bg: C.brand + '33', width: Math.round(W / 3) }),
cell([
p(normal('Ja vende regularmente. Faz feiras e atende via WhatsApp. Cresceu rapido e perdeu o controle.')),
p(normal('Dor: nao sabe o lucro real, esquece de comprar ingrediente.')),
], { bg: C.lilasCl, width: Math.round(W / 3) }),
cell([
p(normal('Tem linha de produtos, clientes fixos, CNPJ. Contrata ajuda. Pensa em escalar.')),
p(normal('Dor: precisa de rastreabilidade para fornecedores e clientes exigentes.')),
], { bg: C.gray1, width: Math.round(W / 3) }),
]),
],
}),
space(200),
h('3.2 Parceiros distribuidores (quem indica o sistema)', HeadingLevel.HEADING_2),
new Table({
width: { size: W, type: WidthType.DXA },
columnWidths: [Math.round(W * 0.28), Math.round(W * 0.38), Math.round(W * 0.34)],
rows: [
tableRow([
headerCell('Tipo de Parceiro', Math.round(W * 0.28)),
headerCell('Por que e um bom canal', Math.round(W * 0.38)),
headerCell('O que oferecer', Math.round(W * 0.34)),
]),
...([
[
'Fornecedores de ingredientes cosmeticos',
'Acesso direto ao publico exato. O cliente ja comprou ingredientes — proximo passo natural e organizar a producao.',
'Comissao recorrente + link/cupom exclusivo + banner na loja + mencao no newsletter',
],
[
'Instrutores de cursos de cosmetica artesanal',
'Autoridade maxima para o aluno. Recomendacao do professor converte muito mais que anuncio.',
'Comissao de adesao alta + material exclusivo para alunos + co-criacao de conteudo',
],
[
'Grupos e comunidades do setor (Facebook, WhatsApp, Telegram)',
'Alta concentracao do publico. Admins tem influencia real sobre membros.',
'Comissao por indicacao + acesso gratuito ao sistema + selo de parceiro oficial',
],
[
'Consultores de regularizacao ANVISA',
'Cliente em momento critico: precisa se regularizar. Sistema resolve parte do problema.',
'Comissao + co-divulgacao + possibilidade de white-label futuro',
],
[
'Influenciadores do nicho (YouTube, Instagram, TikTok)',
'Alcance organico grande com publico engajado que ja consome conteudo do setor.',
'Comissao por link + acesso vitalicio gratuito + mencao em video/post patrocinado',
],
].map(([tipo, por, o], i) => tableRow([
cell(new Paragraph({ children: [new TextRun({ text: tipo, size: 20, bold: true, color: C.brandDd })] }), { bg: i % 2 === 0 ? C.white : C.gray1, width: Math.round(W * 0.28) }),
cell(new Paragraph({ children: [new TextRun({ text: por, size: 20, color: C.text })] }), { bg: i % 2 === 0 ? C.white : C.gray1, width: Math.round(W * 0.38) }),
cell(new Paragraph({ children: [new TextRun({ text: o, size: 20, color: C.text })] }), { bg: i % 2 === 0 ? C.white : C.gray1, width: Math.round(W * 0.34) }),
]))),
],
}),
space(300),
// ══════════════════ 4. ESTRATEGIA PARCEIROS ══════════════════
h('4. ESTRATEGIA DE PARCERIAS — COMO ABORDAR', HeadingLevel.HEADING_1),
divider(),
h('4.1 Abordagem para fornecedores de ingredientes', HeadingLevel.HEADING_2),
p(normal('O argumento central nao e "divulgue nosso sistema". E: "oferea um beneficio que seus clientes ja precisam, e ganhe renda passiva com isso".')),
space(60),
h('Passo a passo para prospectar um fornecedor:', HeadingLevel.HEADING_3),
new Paragraph({ numbering: { reference: 'numbers', level: 0 }, children: [new TextRun({ text: 'Pesquise no Google e Instagram: "fornecedor ingredientes cosmeticos artesanais [estado]"', size: 22 })], spacing: { before: 50, after: 50 } }),
new Paragraph({ numbering: { reference: 'numbers', level: 0 }, children: [new TextRun({ text: 'Identifique se tem newsletter, Instagram ativo ou grupo de clientes', size: 22 })], spacing: { before: 50, after: 50 } }),
new Paragraph({ numbering: { reference: 'numbers', level: 0 }, children: [new TextRun({ text: 'Aborde pelo canal mais ativo (Instagram DM, e-mail comercial ou WhatsApp)', size: 22 })], spacing: { before: 50, after: 50 } }),
new Paragraph({ numbering: { reference: 'numbers', level: 0 }, children: [new TextRun({ text: 'Use o roteiro de abordagem abaixo', size: 22 })], spacing: { before: 50, after: 50 } }),
new Paragraph({ numbering: { reference: 'numbers', level: 0 }, children: [new TextRun({ text: 'Envie acesso gratuito para o responsavel testar por 14 dias', size: 22 })], spacing: { before: 50, after: 50 } }),
new Paragraph({ numbering: { reference: 'numbers', level: 0 }, children: [new TextRun({ text: 'Reuniao de 30 min por video para tirar duvidas e fechar parceria', size: 22 })], spacing: { before: 50, after: 50 } }),
space(80),
box('Roteiro de Abordagem — Mensagem Inicial (WhatsApp / Instagram)', [
'"Ola, [Nome]! Admiro muito o trabalho da [Empresa]. Desenvolvi um sistema de gestao especifico para produtores de cosmeticos artesanais — controle de formulas, ingredientes, producao em lote, etiquetas ANVISA e muito mais.',
'',
'Estou buscando parceiros que queiram oferecer esse recurso para sua base de clientes e ganhar comissao recorrente por cada adesao. Sem esforco operacional da sua parte.',
'',
'Posso te mandar um acesso gratuito para voce testar? Tenho certeza que seus clientes vao adorar. E seria uma conversa de 20 minutinhos para mostrar como funciona."',
], C.avCl, C.av),
space(80),
h('4.2 Abordagem para instrutores de cursos', HeadingLevel.HEADING_2),
p(normal('Instrutores vendem transformacao. Seu aluno quer aprender para vender. Mostrar que voce oferece a ferramenta que fecha o ciclo — da receita a venda — e um diferencial real para o curso.')),
space(60),
box('Proposta de valor para o instrutor', [
'• "Seus alunos aprendem a formula. Com o Tudo Controlado, eles aprendem a gerir o negocio."',
'• Inclua o sistema como bonus do curso (acesso de 3 meses gratis ao plano Profissional)',
'• Comissao alta na conversao de alunos para assinatura paga apos o periodo de bonus',
'• O instrutor pode usar o sistema ao vivo nas aulas para demonstracao — marketing organico',
'• Material exclusivo: tutorial em video com a marca do instrutor para os alunos',
], C.lilasCl, C.lilas),
space(80),
h('4.3 Mecanica de rastreamento das indicacoes', HeadingLevel.HEADING_2),
p(normal('Cada parceiro recebe um identificador unico. As conversoes sao rastreadas automaticamente e o parceiro ve tudo em tempo real:')),
space(40),
bullet('Link exclusivo com UTM: tudocontrolado.com.br/?ref=NOMEPARCEIRO'),
bullet('Cupom de desconto unico: ex. COSMETIC20 (20% no primeiro mes)'),
bullet('Dashboard do parceiro: conversoes, receita gerada, comissao acumulada'),
bullet('Pagamento automatico mensal via PIX ou transferencia'),
space(300),
// ══════════════════ 5. CRONOGRAMA ══════════════════
h('5. CRONOGRAMA DE EXECUCAO — 12 MESES', HeadingLevel.HEADING_1),
divider(),
// Phase 1
phaseCard('FASE 1', 'PREPARACAO E LANCAMENTO (Meses 1-2)', 'Meses 1-2', C.brand + '44', C.brandD),
space(60),
h('Mes 1 — Preparar o terreno', HeadingLevel.HEADING_3),
bullet('Finalizar pagina de vendas com demo interativa do sistema', true),
bullet('Criar kit do parceiro: apresentacao em PDF, video de 3 min, FAQ, contrato-padrao'),
bullet('Configurar rastreamento de indicacoes (link + cupom por parceiro)'),
bullet('Gravar video de demonstracao completo (20 min) para usar em abordagens'),
bullet('Montar lista dos primeiros 50 fornecedores e instrutores para prospectar'),
bullet('Criar perfis no Instagram e YouTube do produto'),
space(60),
h('Mes 2 — Primeiras parcerias', HeadingLevel.HEADING_3),
bullet('Prospectar ativamente: 10 fornecedores + 10 instrutores por semana', true),
bullet('Meta: fechar 5 parcerias ativas ate o final do mes'),
bullet('Dar acesso gratuito de 30 dias para todos os parceiros testarem'),
bullet('Coletar depoimentos de primeiros usuarios reais para usar como prova social'),
bullet('Lancamento publico do sistema com evento ao vivo (Instagram/YouTube)'),
bullet('Meta de assinantes pagos: 20 ao final do mes 2'),
space(80),
box('Entregaveis da Fase 1', [
'✔ Kit parceiro pronto (PDF, video, contrato)',
'✔ Minimo 5 parcerias ativas assinadas',
'✔ 20 assinantes pagos',
'✔ Pagina de vendas ao ar',
'✔ Perfis de redes sociais ativos',
], C.okCl, C.ok),
space(160),
// Phase 2
phaseCard('FASE 2', 'ESCALA DE PARCERIAS (Meses 3-6)', 'Meses 3-6', C.lilasCl, C.lilas),
space(60),
h('Mes 3 — Aceleracao', HeadingLevel.HEADING_3),
bullet('Intensificar prospectar: foco em parceiros de maior audiencia (> 5k seguidores/alunos)', true),
bullet('Criar programa de ranking: parceiros com mais indicacoes ganham beneficios extras'),
bullet('Participar de ao menos 1 evento do setor (presencial ou online) como expositor'),
bullet('Publicar primeiros 4 videos no YouTube (tutoriais do sistema)'),
bullet('Meta: 15 parcerias ativas, 80 assinantes pagos'),
space(60),
h('Meses 4-5 — Consolidacao', HeadingLevel.HEADING_3),
bullet('Lan car programa de afiliados aberto (qualquer usuario pode indicar e ganhar comissao)'),
bullet('Criar conteudo SEO para Google: "como precificar cosmetico artesanal", "ANVISA cosmetico caseiro"'),
bullet('Webinar mensal gratuito: "Como organizar sua producao artesanal" — captacao de leads'),
bullet('Parcerias com 2-3 instrutores para incluir o sistema como bonus dos cursos'),
bullet('Meta: 30 parcerias ativas, 200 assinantes pagos'),
space(60),
h('Mes 6 — Revisao e ajuste', HeadingLevel.HEADING_3),
bullet('Analise completa: quais parceiros convertem mais? Por que?', true),
bullet('Cortar parcerias que nao geraram resultado; dobrar investimento nas que funcionam'),
bullet('Pesquisa de satisfacao com assinantes: NPS e pedido de depoimento em video'),
bullet('Iniciar contatos com associacoes do setor (ABIHPEC, grupos estaduais)'),
bullet('Meta: 300 assinantes pagos, taxa de cancelamento < 5% ao mes'),
space(80),
box('Entregaveis da Fase 2', [
'✔ 30 parcerias ativas',
'✔ 300 assinantes pagos',
'✔ MRR (receita recorrente mensal) superior a R$ 15.000',
'✔ Canal YouTube com 8+ videos publicados',
'✔ NPS superior a 70',
], C.lilasCl, C.lilas),
space(160),
// Phase 3
phaseCard('FASE 3', 'AUTORIDADE E DIVERSIFICACAO (Meses 7-12)', 'Meses 7-12', C.gray1, C.brandDd),
space(60),
h('Meses 7-9 — Tornar-se referencia', HeadingLevel.HEADING_3),
bullet('Lancar certificado gratuito de "Produtor Organizado" para usuarios que completam o perfil', true),
bullet('Publicar ebook gratuito: "Guia ANVISA para Cosmeticos Artesanais 2025" (captacao de e-mail)'),
bullet('Criar comunidade fechada para assinantes (grupo WhatsApp/Discord com suporte peer-to-peer)'),
bullet('Abrir canal de revendedores: pessoas que vendem o sistema para outros pequenos produtores'),
bullet('Meta: 600 assinantes, 50 parcerias ativas'),
space(60),
h('Meses 10-12 — Produto e expansao', HeadingLevel.HEADING_3),
bullet('Lancar versao mobile progressiva (PWA) baseada no sistema atual', true),
bullet('Plano Parceiro: white-label do sistema com logo do fornecedor/instrutor (preco diferenciado)'),
bullet('Iniciar desenvolvimento de backend com banco de dados em nuvem (versao SaaS completa)'),
bullet('Participar de pelo menos 2 feiras do setor (Beleza e Cosmetica, Indie Beauty etc.)'),
bullet('Meta ao fim do mes 12: 1.000 assinantes pagos, MRR > R$ 50.000'),
space(80),
box('Entregaveis da Fase 3', [
'✔ 1.000 assinantes pagos',
'✔ MRR superior a R$ 50.000',
'✔ 50 parcerias ativas',
'✔ Versao PWA mobile publicada',
'✔ Plano white-label disponivel para parceiros premium',
'✔ Pipeline do SaaS em nuvem iniciado',
], C.okCl, C.ok),
space(300),
// ══════════════════ 6. METAS ══════════════════
h('6. METAS E INDICADORES (KPIs)', HeadingLevel.HEADING_1),
divider(),
new Table({
width: { size: W, type: WidthType.DXA },
columnWidths: [Math.round(W * 0.3), Math.round(W * 0.18), Math.round(W * 0.18), Math.round(W * 0.18), Math.round(W * 0.16)],
rows: [
tableRow([
headerCell('Indicador', Math.round(W * 0.3)),
headerCell('Mes 2', Math.round(W * 0.18)),
headerCell('Mes 6', Math.round(W * 0.18)),
headerCell('Mes 12', Math.round(W * 0.18)),
headerCell('Responsavel', Math.round(W * 0.16)),
]),
...([
['Assinantes pagos', '20', '300', '1.000', 'Vendas'],
['Parcerias ativas', '5', '30', '50', 'Parcerias'],
['MRR (R$)', 'R$ 1.000', 'R$ 15.000', 'R$ 50.000', 'Financeiro'],
['Taxa de cancelamento (churn)', '< 10%', '< 7%', '< 5%', 'Produto'],
['NPS (satisfacao)', '> 50', '> 65', '> 75', 'Produto'],
['Novos assinantes/mes', '10', '60', '100', 'Marketing'],
['Conversao indicacao → pago', '15%', '25%', '35%', 'Parcerias'],
['Videos YouTube publicados', '0', '8', '24', 'Marketing'],
['Leads capturados (email)', '200', '2.000', '8.000', 'Marketing'],
].map(([ind, m2, m6, m12, resp], i) => tableRow([
cell(new Paragraph({ children: [new TextRun({ text: ind, size: 20, bold: true, color: C.text })] }), { bg: i % 2 === 0 ? C.white : C.gray1, width: Math.round(W * 0.3) }),
cell(new Paragraph({ alignment: AlignmentType.CENTER, children: [new TextRun({ text: m2, size: 20, color: C.text })] }), { bg: i % 2 === 0 ? C.white : C.gray1, width: Math.round(W * 0.18) }),
cell(new Paragraph({ alignment: AlignmentType.CENTER, children: [new TextRun({ text: m6, size: 20, color: C.text })] }), { bg: i % 2 === 0 ? C.white : C.gray1, width: Math.round(W * 0.18) }),
cell(new Paragraph({ alignment: AlignmentType.CENTER, children: [new TextRun({ text: m12, size: 20, color: C.lilas, bold: true })] }), { bg: i % 2 === 0 ? C.white : C.gray1, width: Math.round(W * 0.18) }),
cell(new Paragraph({ alignment: AlignmentType.CENTER, children: [new TextRun({ text: resp, size: 19, color: C.text })] }), { bg: i % 2 === 0 ? C.white : C.gray1, width: Math.round(W * 0.16) }),
]))),
],
}),
space(300),
// ══════════════════ 7. ORCAMENTO ══════════════════
h('7. ORCAMENTO DE MARKETING SUGERIDO (Mes 1-6)', HeadingLevel.HEADING_1),
divider(),
p(normal('Este plano e deliberadamente enxuto — o foco e parcerias organicas antes de trafego pago. Os custos abaixo sao estimativas mensais iniciais:')),
space(60),
new Table({
width: { size: W, type: WidthType.DXA },
columnWidths: [Math.round(W * 0.45), Math.round(W * 0.2), Math.round(W * 0.35)],
rows: [
tableRow([
headerCell('Item', Math.round(W * 0.45)),
headerCell('Custo mensal estimado', Math.round(W * 0.2)),
headerCell('Observacao', Math.round(W * 0.35)),
]),
...([
['Infraestrutura (hospedagem, dominio, email mkt)', 'R$ 150–250', 'Vercel/Railway + Brevo/Mailchimp'],
['Producao de conteudo (design, edicao de video)', 'R$ 300–500', 'Canva Pro + editor freelance'],
['Trafego pago (meta / google ads)', 'R$ 500–1.000', 'Apenas apos mes 3, quando tiver prova social'],
['Participacao em eventos do setor', 'R$ 200–500', 'Media de custo anual dividida por mes'],
['Ferramentas de prospectar parceiros', 'R$ 100–200', 'LinkedIn Sales Navigator ou similar'],
['Comissoes de parceiros', '15–25% da receita', 'Variavel — nao e custo fixo, e proporcional'],
].map(([item, custo, obs], i) => tableRow([
cell(new Paragraph({ children: [new TextRun({ text: item, size: 20, bold: true, color: C.text })] }), { bg: i % 2 === 0 ? C.white : C.gray1, width: Math.round(W * 0.45) }),
cell(new Paragraph({ alignment: AlignmentType.CENTER, children: [new TextRun({ text: custo, size: 20, color: C.ok, bold: true })] }), { bg: i % 2 === 0 ? C.white : C.gray1, width: Math.round(W * 0.2) }),
cell(new Paragraph({ children: [new TextRun({ text: obs, size: 19, color: C.text })] }), { bg: i % 2 === 0 ? C.white : C.gray1, width: Math.round(W * 0.35) }),
]))),
],
}),
space(80),
box('Custo total fixo estimado: R$ 1.250 a R$ 2.450/mes nos primeiros 6 meses', [
'O modelo de parcerias e o canal com melhor ROI: custo quase zero, conversao alta (recomendacao de confianca).',
'Invista em trafego pago so depois de ter depoimentos, NPS positivo e pelo menos 100 clientes pagos.',
], C.avCl, C.av),
space(300),
// ══════════════════ 8. DIFERENCIAIS ══════════════════
h('8. ARGUMENTOS DE VENDA — OBJECOES COMUNS', HeadingLevel.HEADING_1),
divider(),
new Table({
width: { size: W, type: WidthType.DXA },
columnWidths: [Math.round(W * 0.38), Math.round(W * 0.62)],
rows: [
tableRow([
headerCell('Objecao do potencial cliente', Math.round(W * 0.38)),
headerCell('Como responder', Math.round(W * 0.62)),
]),
...([
['"Eu uso planilha, funciona"', '"Planilha nao calcula o custo por frasco automaticamente quando voce muda a embalagem. Nao gera etiqueta com INCI conforme a ANVISA. Nao avisa quando o ingrediente vai vencer. Experimente por 30 dias — se achar que a planilha ainda e melhor, cancela."'],
['"E muito caro pra mim"', '"Voce perde quanto por mes por nao saber o preco certo dos seus produtos? Um erro de precificacao em 50 frascos pode custar mais que um ano de assinatura. Temos o plano Essencial por menos de R$1,30 por dia."'],
['"Nao tenho tempo para aprender"', '"O sistema funciona sem treinamento. Voce comeca a usar em 10 minutos. O guia de inicio rapido dentro do sistema mostra exatamente por onde comecar. Oferecemos onboarding ao vivo de 30 min."'],
['"Tenho medo de perder meus dados"', '"Seus dados ficam salvos no seu dispositivo. A qualquer momento voce exporta tudo em PDF. Estamos migrando para nuvem — quando chegar la, seus dados vao junto, automaticamente."'],
['"Nao sei se a lei se aplica a mim"', '"A Lei 15.154/2025 se aplica a quem produz e vende cosmeticos, mesmo em pequena escala. Ter o controle documentado e o que te protege em caso de fiscalizacao. O Tudo Controlado ja tem os checklists BPF e os campos de rastreabilidade que a ANVISA exige."'],
].map(([obj, resp], i) => tableRow([
cell(new Paragraph({ children: [new TextRun({ text: obj, size: 20, bold: true, color: C.er })] }), { bg: i % 2 === 0 ? C.erCl : C.white, width: Math.round(W * 0.38) }),
cell(new Paragraph({ children: [new TextRun({ text: resp, size: 20, color: C.text })] }), { bg: i % 2 === 0 ? C.white : C.gray1, width: Math.round(W * 0.62) }),
]))),
],
}),
space(300),
// ══════════════════ 9. PROXIMOS PASSOS ══════════════════
h('9. PROXIMOS PASSOS — ACOES IMEDIATAS', HeadingLevel.HEADING_1),
divider(),
p([bold('Essa semana (antes de qualquer outra coisa):', C.brandDd)]),
space(40),
new Paragraph({ numbering: { reference: 'numbers', level: 0 }, children: [new TextRun({ text: 'Definir o preco dos planos — fazer uma pesquisa rapida com 10 produtoras conhecidas', size: 22, bold: true })], spacing: { before: 60, after: 40 } }),
sub('Pergunta: "Voce pagaria R$X por mes por um sistema que controla sua producao, ingredientes e gera etiqueta ANVISA?"'),
new Paragraph({ numbering: { reference: 'numbers', level: 0 }, children: [new TextRun({ text: 'Gravar um video de demonstracao de 3 minutos do sistema funcionando', size: 22, bold: true })], spacing: { before: 60, after: 40 } }),
sub('Use o proprio sistema — mostre: cadastrar ingrediente → criar formula → registrar producao → gerar etiqueta'),
new Paragraph({ numbering: { reference: 'numbers', level: 0 }, children: [new TextRun({ text: 'Montar uma lista de 20 fornecedores e 20 instrutores para prospectar', size: 22, bold: true })], spacing: { before: 60, after: 40 } }),
sub('Google: "fornecedor ingredientes cosmetica artesanal" + Instagram: #cosmeticaartesanal #formulacaocosmetica'),
new Paragraph({ numbering: { reference: 'numbers', level: 0 }, children: [new TextRun({ text: 'Criar um perfil simples no Instagram do Tudo Controlado', size: 22, bold: true })], spacing: { before: 60, after: 40 } }),
sub('Bio clara, link para o sistema, primeiro post: "Para quem produz cosmeticos artesanais"'),
new Paragraph({ numbering: { reference: 'numbers', level: 0 }, children: [new TextRun({ text: 'Enviar a primeira mensagem de abordagem para 5 fornecedores', size: 22, bold: true })], spacing: { before: 60, after: 40 } }),
sub('Use o roteiro da secao 4.1. Nao espere a pagina estar perfeita. Comece com o video de demo.'),
space(80),
box('Lembre-se: o maior risco nao e lancar cedo demais. E perder tempo esperando estar perfeito.', [
'O sistema ja esta funcionando e resolve problemas reais. O mercado vai indicar o que ajustar.',
'Cada semana sem vender e uma semana de receita perdida e de feedback que voce nao teve.',
], C.avCl, C.av),
space(200),
divider(C.brand),
new Paragraph({
alignment: AlignmentType.CENTER,
spacing: { before: 120, after: 40 },
children: [new TextRun({ text: 'Tudo Controlado — Gestao de Cosmeticos Artesanais', bold: true, size: 22, color: C.brandDd })],
}),
new Paragraph({
alignment: AlignmentType.CENTER,
spacing: { before: 0, after: 0 },
children: [new TextRun({ text: 'Plano Estrategico de Vendas | 2025–2026 | Versao 1.0', size: 19, color: C.brandD })],
}),
],
}],
});
Packer.toBuffer(doc).then(buffer => {
fs.writeFileSync('/home/claude/plano_vendas_tudo_controlado.docx', buffer);
console.log('✅ Done!');
}).catch(e => {
console.error('❌ Error:', e.message);
process.exit(1);
});