Files
workspace/docs/build-deck-commercialista.js
2026-04-15 11:26:46 +02:00

505 lines
18 KiB
JavaScript

// adiuvAI — Presentazione generica dell'applicazione
// Stile: Light canvas (app light mode)
const pptxgen = require("pptxgenjs");
const path = require("path");
const ASSETS = "C:/_temp/_adiuvai_workspace/adiuvAI/assets";
const LOGO_ICON = `${ASSETS}/logo/logo-icon.png`;
const SHOT_HOME = `${ASSETS}/screenshot/home.png`;
const SHOT_PROJECTS = `${ASSETS}/screenshot/projects.png`;
const SHOT_TASK = `${ASSETS}/screenshot/task.png`;
const SHOT_CHAT = `${ASSETS}/screenshot/home_chat.png`;
// Palette light mode (app)
const C = {
bg: "F4EDF3", // pinkish-white canvas
surface: "FFFFFF", // cards
surface2: "EDE5EC", // subtle header row
gold: "FBC881", // primary accent
goldDark: "C79A5B", // darker gold for contrast on light bg
ink: "0C0C0C", // near-black
ink2: "323232", // body text dark
muted: "8A8EA9", // slate blue-gray
border: "C8C3CD", // dusty lavender border
borderSoft: "E5DFE4",
};
const FONT_H = "Calibri";
const FONT_B = "Calibri";
const pres = new pptxgen();
pres.layout = "LAYOUT_WIDE"; // 13.333 x 7.5
pres.author = "adiuvAI";
pres.title = "adiuvAI";
const SW = 13.333;
const SH = 7.5;
const DARK = { bg: "0C0C0C", surface: "181818", surface2: "222222", text: "FBFBFB", muted: "8A8EA9", border: "2A2A2A" };
function bgLight(slide) { slide.background = { color: C.bg }; }
function bgDark(slide) { slide.background = { color: DARK.bg }; }
function footer(slide, pageNum, total, dark) {
slide.addImage({ path: LOGO_ICON, x: 0.5, y: 0.35, w: 0.35, h: 0.35 });
slide.addText(
[
{ text: "adiuv", options: { color: dark ? DARK.text : C.ink, fontFace: FONT_H, fontSize: 11 } },
{ text: "AI", options: { color: dark ? C.gold : C.goldDark, fontFace: FONT_H, fontSize: 11, bold: true } },
],
{ x: 0.9, y: 0.33, w: 2.5, h: 0.4, margin: 0, valign: "middle" }
);
slide.addText(`${pageNum} / ${total}`, {
x: SW - 1.5, y: 0.33, w: 1.0, h: 0.4,
color: dark ? DARK.muted : C.muted, fontFace: FONT_B, fontSize: 10, align: "right", valign: "middle", margin: 0,
});
}
function slideTitle(slide, eyebrow, title, dark) {
if (eyebrow) {
slide.addText(eyebrow.toUpperCase(), {
x: 0.8, y: 1.05, w: 10, h: 0.35,
color: dark ? C.gold : C.goldDark, fontFace: FONT_H, fontSize: 11, bold: true, charSpacing: 6, margin: 0,
});
}
slide.addText(title, {
x: 0.8, y: 1.4, w: 11.5, h: 1.0,
color: dark ? DARK.text : C.ink, fontFace: FONT_H, fontSize: 36, bold: true, margin: 0,
});
}
function goldDot(slide, x, y) {
slide.addShape(pres.shapes.OVAL, {
x, y, w: 0.12, h: 0.12, fill: { color: C.gold }, line: { color: C.gold },
});
}
const TOTAL = 9;
let page = 0;
// ============================================================
// 1 — COVER
// ============================================================
{
page++;
const s = pres.addSlide();
bgLight(s);
s.addImage({ path: LOGO_ICON, x: 1.1, y: 2.4, w: 2.6, h: 2.6 });
s.addText(
[
{ text: "adiuv", options: { color: C.ink, fontFace: FONT_H, fontSize: 72 } },
{ text: "AI", options: { color: C.goldDark, fontFace: FONT_H, fontSize: 72, bold: true } },
],
{ x: 4.0, y: 2.7, w: 7.5, h: 1.3, margin: 0, valign: "middle" }
);
s.addShape(pres.shapes.RECTANGLE, {
x: 4.1, y: 4.05, w: 0.6, h: 0.04, fill: { color: C.gold }, line: { color: C.gold },
});
s.addText("Meet your new chief of staff.", {
x: 4.0, y: 4.15, w: 8.5, h: 0.6,
color: C.ink, fontFace: FONT_H, fontSize: 24, italic: true, margin: 0,
});
s.addText("Una segretaria AI che legge la tua posta, organizza il tuo lavoro, e ogni mattina ti dice cosa conta — tutto sul tuo computer.", {
x: 4.0, y: 4.85, w: 8.5, h: 1.4,
color: C.ink2, fontFace: FONT_B, fontSize: 16, margin: 0,
});
}
// ============================================================
// 2 — L'IDEA: UNA SEGRETARIA
// ============================================================
{
page++;
const s = pres.addSlide();
bgLight(s);
footer(s, page, TOTAL);
slideTitle(s, "L'idea", "Non un altro tool. Una segretaria.");
s.addText(
[
{ text: "Gli strumenti di produttività si aspettano che tu li usi.\n", options: { color: C.muted, fontSize: 18 } },
{ text: "adiuvAI lavora per te.", options: { color: C.ink, fontSize: 26, bold: true } },
],
{ x: 0.8, y: 2.8, w: 11.8, h: 1.5, fontFace: FONT_H, margin: 0 }
);
// Metafora: cosa fa una segretaria reale
const duties = [
{ t: "Legge la tua posta", d: "Filtra, prioritizza, segnala solo ciò che richiede la tua attenzione." },
{ t: "Tiene in ordine l'agenda", d: "Scadenze, impegni, follow-up — tutto tracciato senza chiederti nulla." },
{ t: "Prepara il briefing", d: "Ogni mattina arriva con un piano chiaro: ecco cosa conta oggi." },
{ t: "Ti aiuta a eseguire", d: "Prepara bozze, organizza documenti, ti accompagna mentre lavori." },
];
const cardW = 5.85, gap = 0.2;
duties.forEach((d, i) => {
const col = i % 2, row = Math.floor(i / 2);
const x = 0.8 + col * (cardW + gap);
const y = 4.45 + row * 1.35;
s.addShape(pres.shapes.RECTANGLE, {
x, y, w: cardW, h: 1.2,
fill: { color: C.surface }, line: { color: C.borderSoft, width: 0.75 },
});
s.addShape(pres.shapes.RECTANGLE, {
x, y, w: 0.08, h: 1.2, fill: { color: C.gold }, line: { color: C.gold },
});
s.addText(d.t, {
x: x + 0.3, y: y + 0.15, w: cardW - 0.4, h: 0.4,
color: C.ink, fontFace: FONT_H, fontSize: 16, bold: true, margin: 0,
});
s.addText(d.d, {
x: x + 0.3, y: y + 0.55, w: cardW - 0.4, h: 0.65,
color: C.ink2, fontFace: FONT_B, fontSize: 12, margin: 0,
});
});
}
// ============================================================
// 3 — DAILY BRIEF + CAROUSEL (hero feature)
// ============================================================
{
page++;
const s = pres.addSlide();
bgDark(s);
footer(s, page, TOTAL, true);
slideTitle(s, "Il cuore dell'esperienza", "Il briefing del mattino, poi ti prende per mano.", true);
// Left: screenshot home (mostra il daily brief)
s.addImage({ path: SHOT_HOME, x: 0.8, y: 2.8, w: 6.4, h: 3.6 });
s.addShape(pres.shapes.RECTANGLE, {
x: 0.8, y: 2.8, w: 6.4, h: 3.6,
fill: { type: "solid", color: DARK.bg, transparency: 100 },
line: { color: DARK.border, width: 1 },
});
s.addText("Daily Brief", {
x: 0.8, y: 6.5, w: 6.4, h: 0.35,
color: DARK.muted, fontFace: FONT_H, fontSize: 11, bold: true, align: "center", charSpacing: 4, margin: 0,
});
// Right: caption + carousel feature
s.addText("Ogni mattina, un briefing personalizzato ti racconta cosa è cambiato, cosa scade e cosa conta di più.", {
x: 7.5, y: 2.75, w: 5.2, h: 1.4,
color: DARK.text, fontFace: FONT_H, fontSize: 16, margin: 0,
});
// Carousel card (feature)
s.addShape(pres.shapes.RECTANGLE, {
x: 7.5, y: 4.25, w: 5.2, h: 2.6,
fill: { color: DARK.surface }, line: { color: DARK.border, width: 0.75 },
});
s.addShape(pres.shapes.RECTANGLE, {
x: 7.5, y: 4.25, w: 0.08, h: 2.6,
fill: { color: C.gold }, line: { color: C.gold },
});
s.addText("CAROSELLO DELLE ATTIVITÀ", {
x: 7.75, y: 4.4, w: 5, h: 0.4,
color: C.gold, fontFace: FONT_H, fontSize: 10, bold: true, charSpacing: 4, margin: 0,
});
s.addText(
[
{ text: "Dalla home, avvii il carosello: ", options: { color: DARK.text, bold: true, breakLine: true } },
{ text: "ogni scheda è un'attività che l'AI ritiene prioritaria per la giornata. Ti guida passo passo con le indicazioni per completarla, e puoi chattare con lei mentre lavori — come se avessi la tua segretaria al fianco.",
options: { color: DARK.muted } },
],
{ x: 7.75, y: 4.8, w: 5, h: 1.95, fontFace: FONT_B, fontSize: 13, margin: 0 }
);
}
// ============================================================
// 4 — CHAT CONTESTUALE
// ============================================================
{
page++;
const s = pres.addSlide();
bgDark(s);
footer(s, page, TOTAL, true);
slideTitle(s, "Chat", "Parla con la tua segretaria. In italiano, in linguaggio naturale.", true);
// left: examples
const examples = [
"« Qual è la prossima attività su cui concentrarmi? »",
"« Riassumi le email arrivate stamattina. »",
"« Crea un'attività: richiamare Luca giovedì. »",
"« Cosa è cambiato sul progetto Patient Portal? »",
];
examples.forEach((e, i) => {
const y = 2.8 + i * 0.65;
s.addShape(pres.shapes.RECTANGLE, {
x: 0.8, y, w: 5.6, h: 0.55,
fill: { color: DARK.surface }, line: { color: DARK.border, width: 0.75 },
});
s.addShape(pres.shapes.RECTANGLE, {
x: 0.8, y, w: 0.06, h: 0.55, fill: { color: C.gold }, line: { color: C.gold },
});
s.addText(e, {
x: 1.0, y, w: 5.3, h: 0.55,
color: DARK.text, fontFace: FONT_B, fontSize: 12, italic: true, valign: "middle", margin: 0,
});
});
s.addText("Niente prompt engineering. Niente modelli da scegliere. L'AI giusta lavora in background e ti risponde con il contesto del tuo workspace.", {
x: 0.8, y: 5.65, w: 5.6, h: 1.0,
color: DARK.muted, fontFace: FONT_B, fontSize: 13, margin: 0,
});
// right: screenshot
s.addImage({ path: SHOT_CHAT, x: 6.8, y: 2.6, w: 6.0, h: 3.375 });
s.addShape(pres.shapes.RECTANGLE, {
x: 6.8, y: 2.6, w: 6.0, h: 3.375,
fill: { type: "solid", color: DARK.bg, transparency: 100 },
line: { color: DARK.border, width: 1 },
});
s.addText("Chat contestuale sul workspace", {
x: 6.8, y: 6.05, w: 6.0, h: 0.35,
color: DARK.muted, fontFace: FONT_H, fontSize: 11, bold: true, align: "center", charSpacing: 4, margin: 0,
});
}
// ============================================================
// 5 — FUNZIONALITÀ (compattate)
// ============================================================
{
page++;
const s = pres.addSlide();
bgLight(s);
footer(s, page, TOTAL);
slideTitle(s, "Cosa fa", "Tutto il lavoro quotidiano, in un unico posto.");
const items = [
{ t: "Email → Attività", d: "Legge Gmail, Outlook, cartelle locali ed estrae automaticamente task, promemoria e note." },
{ t: "Progetti e clienti", d: "Timeline, milestone, riepiloghi AI per ogni progetto. Tutto collegato." },
{ t: "Note con ricerca semantica", d: "Editor markdown e ricerca vettoriale su tutto ciò che scrivi." },
{ t: "Timeline e milestone", d: "Panoramica visiva delle scadenze e degli stati di avanzamento." },
{ t: "Agenti locali", d: "Sorveglianza file, monitor cartelle, integrazione Telegram." },
{ t: "Voce in riunione", d: "Prende note durante le call, estrae action item.", soon: true },
];
const cardW = 3.95, gap = 0.2;
const cols = 3;
items.forEach((it, i) => {
const col = i % cols, row = Math.floor(i / cols);
const x = 0.8 + col * (cardW + gap);
const y = 2.8 + row * 1.9;
s.addShape(pres.shapes.RECTANGLE, {
x, y, w: cardW, h: 1.7,
fill: { color: C.surface }, line: { color: C.borderSoft, width: 0.75 },
});
if (it.soon) {
s.addShape(pres.shapes.RECTANGLE, {
x: x + cardW - 1.1, y: y + 0.18, w: 0.95, h: 0.3,
fill: { color: C.bg }, line: { color: C.gold, width: 0.75 },
});
s.addText("COMING SOON", {
x: x + cardW - 1.1, y: y + 0.18, w: 0.95, h: 0.3,
color: C.goldDark, fontFace: FONT_H, fontSize: 8, bold: true, align: "center", valign: "middle", charSpacing: 2, margin: 0,
});
}
goldDot(s, x + 0.25, y + 0.3);
s.addText(it.t, {
x: x + 0.5, y: y + 0.2, w: cardW - 1.5, h: 0.4,
color: C.ink, fontFace: FONT_H, fontSize: 15, bold: true, margin: 0,
});
s.addText(it.d, {
x: x + 0.25, y: y + 0.7, w: cardW - 0.5, h: 0.95,
color: C.ink2, fontFace: FONT_B, fontSize: 11.5, margin: 0,
});
});
}
// ============================================================
// 5 — RISERVATEZZA
// ============================================================
{
page++;
const s = pres.addSlide();
bgLight(s);
footer(s, page, TOTAL);
slideTitle(s, "Riservatezza", "I tuoi dati non lasciano il tuo computer.");
s.addText("Local-first.", {
x: 0.8, y: 2.8, w: 6, h: 0.9,
color: C.goldDark, fontFace: FONT_H, fontSize: 48, bold: true, margin: 0,
});
s.addText("Tutto gira in locale. Il database è sul tuo disco, cifrato. Nessun server adiuvAI vede i contenuti di email, file o documenti.", {
x: 0.8, y: 3.9, w: 6, h: 2.0,
color: C.ink2, fontFace: FONT_B, fontSize: 15, margin: 0,
});
const comp = [
{ t: "GDPR", d: "I dati non vengono mai trasferiti a terzi. Conformità per architettura." },
{ t: "EU AI Act", d: "Progettato dall'inizio per il nuovo quadro normativo europeo." },
{ t: "Cifratura end-to-end", d: "Backup e sincronizzazione opzionali con cifratura client-side." },
{ t: "No training", d: "I tuoi dati non vengono mai usati per addestrare modelli AI." },
];
comp.forEach((c, i) => {
const col = i % 2, row = Math.floor(i / 2);
const x = 7.2 + col * 2.95;
const y = 2.8 + row * 1.85;
s.addShape(pres.shapes.RECTANGLE, {
x, y, w: 2.85, h: 1.65,
fill: { color: C.surface }, line: { color: C.borderSoft, width: 0.75 },
});
s.addShape(pres.shapes.RECTANGLE, {
x, y, w: 2.85, h: 0.05, fill: { color: C.gold }, line: { color: C.gold },
});
s.addText(c.t, {
x: x + 0.2, y: y + 0.15, w: 2.6, h: 0.4,
color: C.goldDark, fontFace: FONT_H, fontSize: 15, bold: true, margin: 0,
});
s.addText(c.d, {
x: x + 0.2, y: y + 0.6, w: 2.6, h: 1.0,
color: C.ink2, fontFace: FONT_B, fontSize: 11, margin: 0,
});
});
}
// ============================================================
// 6 — POSIZIONAMENTO
// ============================================================
{
page++;
const s = pres.addSlide();
bgLight(s);
footer(s, page, TOTAL);
slideTitle(s, "Posizionamento", "Perché non Motion, Notion AI o Microsoft Copilot?");
const rows = [
["", "adiuvAI", "Motion", "Notion AI", "Copilot"],
["Locale, dati sul tuo PC", "Sì", "No", "No", "No"],
["Conforme EU AI Act", "Sì", "n/d", "n/d", "Parziale"],
["Legge email + file + chat", "Sì", "Parziale", "No", "Sì"],
["Daily Brief proattivo", "Sì", "No", "No", "No"],
["AI invisibile (zero prompt)", "Sì", "No", "No", "No"],
];
const tableData = rows.map((r, ri) =>
r.map((cell, ci) => {
if (ri === 0) {
return {
text: cell,
options: {
bold: true, color: ci === 1 ? C.goldDark : C.ink,
fill: { color: C.surface2 },
align: "center", fontFace: FONT_H, fontSize: 13, valign: "middle",
},
};
}
if (ci === 0) {
return {
text: cell,
options: {
fontFace: FONT_B, fontSize: 12, color: C.ink, bold: true,
fill: { color: C.surface }, valign: "middle",
},
};
}
const isYes = cell === "Sì";
return {
text: cell,
options: {
fontFace: FONT_B, fontSize: 12, align: "center", valign: "middle",
color: ci === 1 ? (isYes ? C.goldDark : C.muted) : (isYes ? C.ink : C.muted),
bold: ci === 1,
fill: { color: ci === 1 ? C.surface2 : C.surface },
},
};
})
);
s.addTable(tableData, {
x: 0.8, y: 2.8, w: 11.7,
colW: [4.5, 1.8, 1.8, 1.8, 1.8],
rowH: 0.55,
border: { pt: 1, color: C.borderSoft },
fontFace: FONT_B,
});
s.addText("Gli altri sono cloud-first generalisti. adiuvAI è locale, proattivo, pensato per chi lavora con dati propri.", {
x: 0.8, y: 6.55, w: 12.0, h: 0.5,
color: C.goldDark, fontFace: FONT_B, fontSize: 13, italic: true, margin: 0,
});
}
// ============================================================
// 7 — ROADMAP
// ============================================================
{
page++;
const s = pres.addSlide();
bgLight(s);
footer(s, page, TOTAL);
slideTitle(s, "Roadmap", "Dove siamo, dove stiamo andando.");
const tlY = 4.2;
s.addShape(pres.shapes.RECTANGLE, {
x: 1.2, y: tlY, w: 11.0, h: 0.04,
fill: { color: C.border }, line: { color: C.border },
});
const milestones = [
{ x: 1.6, label: "Oggi — Beta privata", items: ["Daily Brief", "Carosello attività", "Email → Task", "Progetti & Note"] },
{ x: 5.6, label: "Giugno 2026 — Beta pubblica", items: ["Telegram bot", "Outlook / Teams", "App mobile companion"] },
{ x: 9.6, label: "Oltre", items: ["Assistente vocale in riunione", "Workspace di team", "SSO e ruoli"] },
];
milestones.forEach((m) => {
s.addShape(pres.shapes.OVAL, {
x: m.x - 0.12, y: tlY - 0.1, w: 0.25, h: 0.25,
fill: { color: C.gold }, line: { color: C.goldDark, width: 1 },
});
s.addText(m.label, {
x: m.x - 0.2, y: tlY - 0.9, w: 4.2, h: 0.5,
color: C.goldDark, fontFace: FONT_H, fontSize: 13, bold: true, margin: 0,
});
s.addText(
m.items.map((it, idx) => ({
text: it,
options: { bullet: { code: "25A0" }, color: C.ink2, breakLine: idx < m.items.length - 1, paraSpaceAfter: 4 },
})),
{ x: m.x - 0.2, y: tlY + 0.3, w: 4.0, h: 2.5, fontFace: FONT_B, fontSize: 12, margin: 0 }
);
});
}
// ============================================================
// 8 — CLOSING
// ============================================================
{
page++;
const s = pres.addSlide();
bgLight(s);
s.addImage({ path: LOGO_ICON, x: (SW - 1.5) / 2, y: 1.5, w: 1.5, h: 1.5 });
s.addText("Meet your new chief of staff.", {
x: 1.0, y: 3.3, w: SW - 2, h: 0.9,
color: C.ink, fontFace: FONT_H, fontSize: 32, bold: true, italic: true, align: "center", margin: 0,
});
s.addShape(pres.shapes.RECTANGLE, {
x: (SW - 0.6) / 2, y: 4.25, w: 0.6, h: 0.04, fill: { color: C.gold }, line: { color: C.gold },
});
s.addText("Beta in arrivo a Giugno 2026. Gli early adopter otterranno accesso prioritario e potranno guidare il roadmap.", {
x: 1.5, y: 4.45, w: SW - 3, h: 1.4,
color: C.ink2, fontFace: FONT_B, fontSize: 16, align: "center", margin: 0,
});
s.addShape(pres.shapes.RECTANGLE, {
x: (SW - 7) / 2, y: 6.0, w: 7, h: 1.1,
fill: { color: C.surface }, line: { color: C.gold, width: 1.5 },
});
s.addText(
[
{ text: "Iscriviti alla waitlist · ", options: { color: C.ink, bold: true } },
{ text: "adiuvai.com", options: { color: C.goldDark, bold: true } },
],
{ x: (SW - 7) / 2, y: 6.0, w: 7, h: 1.1,
fontFace: FONT_H, fontSize: 20, align: "center", valign: "middle", margin: 0 }
);
}
// ============================================================
const OUT = path.resolve("C:/_temp/_adiuvai_workspace/docs/adiuvAI.pptx");
pres.writeFile({ fileName: OUT }).then((f) => console.log("WROTE:", f));