// Phase 6.5 T6c — `.canva-handoff.md` artifact builder. // // Emits a self-contained markdown file with three sections: // 1. Human-readable summary (artboard count, fidelity caveats) // 2. Drag-drop instructions for the universal Canva web path // 3. Fenced text-block prompt ready for the user's Canva MCP / agentic tool // // The prompt block is the load-bearing piece — anyone with a Canva MCP // configured in Claude Code / Cursor / equivalent can paste it and let the // MCP handle auth + import. Maude never touches credentials. export interface HandoffSummary { /** Filename of the .pptx that ships next to this markdown (e.g. `home.pptx`). */ pptxFilename: string; /** Absolute path to the .pptx after the user unzips. Resolved at render time. */ absolutePath: string; /** Canvas slug — used as the Canva design title and as the prompt's anchor. */ canvasSlug: string; /** Total artboard count (= PPTX slide count = expected Canva page count). */ artboardCount: number; /** Optional list of artboard titles, in render order. */ artboardTitles?: string[]; } const CAVEATS = ` - **Fonts:** if your Canva Brand Kit doesn't include the source fonts, Canva substitutes its defaults. Text remains editable. - **Gradients:** CSS gradients translate to native PPT gradients. Multi-stop fidelity is approximate. - **Shadows, blend modes:** advanced effects rasterize on import. - **Layouts:** flex / grid get flattened to absolute coordinates at export-time viewport (1440 × declared artboard height). `.trim(); export function buildHandoffMarkdown(s: HandoffSummary): string { const plural = s.artboardCount === 1 ? 'artboard' : 'artboards'; const titles = s.artboardTitles?.length ? s.artboardTitles.map((t, i) => `${i + 1}. ${t}`).join('\n') : `${s.artboardCount} ${plural}`; return `# Canva handoff — ${s.canvasSlug} Editable handoff bundle exported from Maude. The companion file \`${s.pptxFilename}\` is a native PowerPoint document — Canva imports it as editable text, shapes, and images, **not** a flat raster. ## What's inside - **${s.artboardCount}** artboard${s.artboardCount === 1 ? '' : 's'} → ${s.artboardCount} Canva page${s.artboardCount === 1 ? '' : 's'} on import. ${titles} ## Option A — drag-drop (works on any Canva tier) 1. Open https://www.canva.com in your browser. 2. Drag \`${s.pptxFilename}\` from this folder into the Canva home screen, or use **Create a design → Upload media → Import file**. 3. Canva opens the imported design. Text, shapes, and images are individually selectable and editable. ## Option B — automate via your Canva MCP If you have a Canva MCP server configured in Claude Code / Cursor / Goose / any agentic tool, paste the prompt below into a fresh chat: \`\`\`text Use my Canva MCP to import the PowerPoint file at the path below into a new Canva design titled "${s.canvasSlug}". Preserve text editability, shape fills and strokes, image swappability, and the artboard-to-page mapping (one PPTX slide = one Canva page). After the import job completes, return the Canva design URL. File path: ${s.absolutePath} Slides expected: ${s.artboardCount} \`\`\` Maude doesn't see your Canva credentials — your MCP handles auth and the import call itself. ## Fidelity caveats ${CAVEATS} --- Generated by [Maude](https://github.com/1aGh/maude). `; }