--- name: helloprint-presentation-creator description: > Helloprint Presentation Creator — generates on-brand Helloprint .pptx files by copying slide templates from a curated baseline and swapping text content. Use whenever someone asks to "make a presentation", "create slides", "build a deck", "make a pptx", or any variation involving a Helloprint internal or external presentation. Also trigger for: "quarterly review", "team update", "strategy deck", "board presentation", "pitch deck", "section update slides", or "present this as slides". --- # Helloprint Presentation Creator ## HOW IT WORKS This skill uses a **template-copy engine**. The baseline PPTX (`HP_MainTemplate_baseline.pptx`) contains 15 perfectly designed slide templates. The generator copies selected slides from that file, swaps placeholder text, and outputs a new `.pptx` — preserving all fonts, colors, shapes, and layouts exactly as designed. **Do NOT use python-pptx or pptxgenjs.** The generator is a raw ZIP/XML engine. --- ## SETUP (run once per session) Before generating, ensure the generator and baseline are available: ```python import os, shutil SKILL_DIR = os.path.dirname(os.path.abspath(__file__)) # adapt to actual skill path BASELINE_SRC = os.path.join(SKILL_DIR, "HP_MainTemplate_baseline.pptx") GENERATOR_SRC = os.path.join(SKILL_DIR, "generate_presentation.py") # Copy to working session directory shutil.copy(BASELINE_SRC, "/sessions/brave-bold-cerf/hp_baseline.pptx") shutil.copy(GENERATOR_SRC, "/sessions/brave-bold-cerf/generate_presentation.py") ``` Then run the generator: ```python import sys sys.path.insert(0, "/sessions/brave-bold-cerf") from generate_presentation import generate ``` --- ## THE API ```python generate(slide_plan, output_path) ``` `slide_plan` is a list of `(template_name, replacements)` tuples, in the order you want slides to appear in the final deck. `replacements` is a list of `(old_text, new_text)` pairs. Pass raw characters — the engine handles XML escaping. **Never pass `&` in your strings — pass `&` directly.** Example: ```python generate([ ("title-dark", [ ("Q1 2025 Business Review", "My Presentation Title"), ("Kwartaalresultaten, strategische prioriteiten en roadmap H2", "Subtitle goes here"), ("Team Strategy & Leadership", "Author Name / Team"), ]), ("closing", []), ], "/Users/derkdissselhof/Library/Application Support/Claude/local-agent-mode-sessions/a2d0567c-5a2d-4037-a100-87a5e74b9a55/3f471e31-d031-4ffe-bb3a-282799a05800/local_0cbc5cf3-74a0-4400-80d7-33c648a960dc/outputs/MyPresentation.pptx") ``` --- ## AVAILABLE SLIDE TEMPLATES 15 templates are available. Below is each template's name, purpose, and **exact placeholder text strings** that can be replaced. Always copy the exact string shown — these are the literal XML text values in the baseline. --- ### `title-dark` Dark background title slide. Always first. | Placeholder text | What it is | |---|---| | `Q1 2025 Business Review` | Main title | | `Kwartaalresultaten, strategische prioriteiten en roadmap H2` | Subtitle / tagline | | `Team Strategy & Leadership` | Author / team (bottom right) | > Note: The date (`15 april 2025`) is auto-filled from the slide and can optionally be replaced. > `Making print easier, for everyone, everywhere.` is the permanent brand tagline — leave it. --- ### `hero-split-photo` Left-side dark photo panel with headline overlay. For bold opening statements. | Placeholder text | What it is | |---|---| | `ANNUAL REPORT 2024` | Section label (top) | | `Building Europe's` | Display headline line 1 | | `largest print` | Display headline line 2 | | ` platform.` | Display headline line 3 (note leading space) | | `300+ suppliers · 14 markets · millions of products` | Sub-caption | --- ### `content-bullets-kpis` White content slide with 3 bullet rows on the left and 4 KPI cards on the right. | Placeholder text | What it is | |---|---| | `STRATEGIE` | Section label | | `Drie strategische prioriteiten voor Q2` | Slide title | | `Revenue Growth` | Bullet 1 title (appears 3× — first occurrence is replaced) | | ` — target €18M voor FY2025, nu tracking op €16.2M (+12% YoY)` | Bullet 1 body (note leading space) | | `€16.2M` | KPI 1 number | | `Q1 Revenue` | KPI 1 label | | `4.6/5` | KPI 2 number | | `Supplier NPS` | KPI 2 label | | `12` | KPI 3 number | | `AI Skills live` | KPI 3 label | | `3` | KPI 4 number | | `New markets H1` | KPI 4 label | > **3 distinct bullets** are supported via nth-occurrence tuples `(old, new, n)`. > Because all 3 bullet rows share identical placeholder text in the baseline, use n=1, 2, 3 > to target each row individually. The engine automatically adjusts for already-replaced > occurrences, so n=2 always means "the 2nd bullet", not "the 2nd remaining one". ```python ("content-bullets-kpis", [ ("STRATEGIE", "STRATEGIE Q2"), ("Drie strategische prioriteiten voor Q2", "Drie prioriteiten voor Q2"), # Bullet 1 ("Revenue Growth", "Marketplace Expansie", 1), (" — target €18M voor FY2025, nu tracking op €16.2M (+12% YoY)", " — uitrol naar IT en ES gepland voor juni, pipeline 40+ leveranciers", 1), # Bullet 2 ("Revenue Growth", "AI-First Operations", 2), (" — target €18M voor FY2025, nu tracking op €16.2M (+12% YoY)", " — 20 Skills in productie, doel is 35 actieve Skills voor einde Q2", 2), # Bullet 3 ("Revenue Growth", "Supplier Kwaliteit", 3), (" — target €18M voor FY2025, nu tracking op €16.2M (+12% YoY)", " — NPS van 4.6 naar 4.8 via geautomatiseerde kwaliteitscontrole", 3), # KPI cards ("€16.2M", "€14.2M"), ("Q1 Revenue", "Q1 Omzet"), ... ]), ``` > **Character limit:** Bullet title: max **25 chars**. Bullet body (after the dash): max **100 chars**. --- ### `impact-statement` Full dark-green impact slide. For key takeaways. Max 1 per 5 slides. | Placeholder text | What it is | |---|---| | `€1B` | Hero number / stat | | `Disrupting` | Bold word in headline | | ` the print industry by building Earth's ` | Normal weight headline text | | `largest infrastructure` | Bold word in headline | | ` for customised products.` | Normal weight headline ending | > Note: `Making print easier, for everyone, everywhere.` is the permanent tagline — leave it. --- ### `chart-kpi-cards` White slide with chart area on the left and 4 KPI cards on the right. | Placeholder text | What it is | |---|---| | `FINANCIALS` | Section label | | `Revenue & Margin — Q1 2025` | Slide title | | `€12.4M` | KPI 1 number | | `▲ +18% YoY` | KPI 1 delta (use ▲ for positive, ▼ for negative) | | `Total Revenue Q1` | KPI 1 label | | `34.2%` | KPI 2 number | | `▲ +2.1pp` | KPI 2 delta | | `Gross Margin` | KPI 2 label | | `1.2M` | KPI 3 number | | `▼ -3.1%` | KPI 3 delta | | `Orders Processed` | KPI 3 label | | `€10.33` | KPI 4 number | | `▲ +22%` | KPI 4 delta | | `Revenue per Order` | KPI 4 label | --- ### `two-column-product` White slide with text on the left and product image placeholder on the right. Good for product spotlights or feature introductions. | Placeholder text | What it is | |---|---| | `PRODUCT LAUNCH` | Section label | | `Premium Hardcover Boekjes` | Slide title | | `Professionele uitstraling voor elk merk` | Left column headline | | `Ons nieuwe hardcover-programma biedt premium kwaliteit...` | Left column body text | | `Vanaf 1 stuk bestelbaar` | USP bullet 1 | | `Gratis ontwerpcheck` | USP bullet 2 | | `FSC-gecertificeerd papier` | USP bullet 3 | --- ### `usp-4-cards` Light gray background with 4 equal feature/USP cards. | Placeholder text | What it is | |---|---| | `WAAROM HELLOPRINT` | Section label | | `Vier redenen om voor ons te kiezen` | Slide title | | `Laagste prijs` | Card title line 1 (all 4 cards identical in baseline) | | `garantie` | Card title line 2 (all 4 cards identical in baseline) | | `All-inclusive prijzen zonder verborgen kosten...` | Card body (all 4 identical in baseline) | | `30%` | Card stat (all 4 identical in baseline) | | `goedkoper dan traditioneel` | Card stat label (all 4 identical in baseline) | **Per-card content** is supported via nth-occurrence tuples `(old, new, n)`. Because all 4 cards share identical placeholder text, pass `n=1..4` to target each card individually: ```python ("usp-4-cards", [ ("WAAROM HELLOPRINT", "COMMUNITY MOMENTS"), ("Vier redenen om voor ons te kiezen", "Wat er deze maand gebeurde"), # Card 1 ("Laagste prijs", "Armeense lunch", 1), ("garantie", "Tolma & Ghapama", 1), ("All-inclusive prijzen zonder verborgen kosten...", "Sona nodigde iedereen uit voor een Armeense lunch op 10 april.", 1), # Card 2 ("Laagste prijs", "Paas taart", 2), ("garantie", "van Marte", 2), ("All-inclusive prijzen zonder verborgen kosten...", "Marte verraste het team met een zelfgemaakte paastaart.", 2), # Card 3 ("Laagste prijs", "Chinese snacks", 3), ("garantie", "van Irene", 3), ("All-inclusive prijzen zonder verborgen kosten...", "Irene bracht authentieke Chinese snacks mee voor het hele kantoor.", 3), # Card 4 ("Laagste prijs", "Boek tip", 4), ("garantie", "van Dennis", 4), ("All-inclusive prijzen zonder verborgen kosten...", "Dennis deelde zijn favoriete boek: Zero to One van Peter Thiel.", 4), # Remove stat elements (replace with empty or relevant values) ("30%", ""), ("goedkoper dan traditioneel", ""), ]), ``` > **Character limits:** Card title line 1: max **20 chars**. Card title line 2: max **20 chars**. > Card body: max **100 chars** (≈2 lines). Exceeding these causes text to overflow the card box. --- ### `team-photo` Dark slide with full-bleed photo and stat overlay. For team events or company culture. | Placeholder text | What it is | |---|---| | `TEAM EVENT` | Section label | | `Rotterdam Summit 2025` | Slide title | | `150+ Helloprinters. 14 markten.` | Sub-headline | | `Twee dagen strategie, innovatie en teambuilding.` | Body text | | `150+` | Stat 1 number | | `Helloprinters` | Stat 1 label | | `14` | Stat 2 number | | `Markets` | Stat 2 label | | `2` | Stat 3 number | | `Days` | Stat 3 label | --- ### `process-timeline` White slide with 4 horizontal process steps. For workflows, onboarding, roadmaps. | Placeholder text | What it is | |---|---| | `WORKFLOW` | Section label | | `Van ontwerp tot levering` | Slide title | | `1` | Step 1 number | | `Upload` | Step 1 title | | `Upload je ontwerp of gebruik onze online editor.` | Step 1 description | | `2` | Step 2 number | | `Designcheck` | Step 2 title | | `Automatische controle op resolutie, afloop en kleuren.` | Step 2 description | | `3` | Step 3 number | | `Productie` | Step 3 title | | `We matchen je order aan de beste supplier.` | Step 3 description | | `4` | Step 4 number | | `Levering` | Step 4 title | | `Track & trace tot aan je deur. Gemiddeld 5 werkdagen.` | Step 4 description | | `Gemiddelde levertijd: ` | Footer note line 1 (note trailing space) | | `5 werkdagen in NL/BE` | Footer note line 2 | | `Express: 2 werkdagen →` | Footer note line 3 | --- ### `before-after` White slide comparing two states side by side (gray left panel, dark right panel). | Placeholder text | What it is | |---|---| | `IMPACT` | Section label | | `AI-First Operations: Voor en Na` | Slide title | | `Handmatig proces` | Left panel title | | `Content creation duurde 2–4 uur per product per markt. Handmatige keyword research, copy schrijven, vertalen en publiceren.` | Left panel body | | `4h` | Left stat 1 | | `per product per markt` | Left stat 1 label | | `50` | Left stat 2 | | `producten per week max` | Left stat 2 label | | `3 FTE` | Left stat 3 | | `nodig` | Left stat 3 label | | `Geautomatiseerd` | Right panel title | | `Claude Skills handelen keyword research, copy generation en Contentful publishing af. Mens reviewt alleen het eindresultaat.` | Right panel body | | `15min` | Right stat 1 | | `500+` | Right stat 2 | | `producten per week` | Right stat 2 label | | `0.5 FTE` | Right stat 3 | | `menselijke review` | Right stat 3 label | > Note: `⬤ VOORHEEN` and `⬤ NU MET AI SKILLS` are colored dot labels — best left as-is. --- ### `big-number` Dark background with one giant number. Maximum impact for a single key metric. Max 1 per 5 slides. | Placeholder text | What it is | |---|---| | `Q1 HIGHLIGHT` | Section label (top right, green) | | `+42%` | The hero number/stat | | `Year-over-year growth in new customer acquisition` | Label below the number | | `Driven by marketplace expansion into 3 new markets and a 28% improvement in organic search visibility across all locales.` | Context paragraph | --- ### `section-divider` Green full-bleed slide announcing a new section. | Placeholder text | What it is | |---|---| | `02` | Section number (appears twice: large decorative + small label — both get replaced) | | `Financial Performance` | Section title | | `Omzet, marges en key metrics over het afgelopen kwartaal met een vooruitblik op de rest van het jaar.` | Section description | > The number `02` appears twice in the XML (visible number + large background decoration). > Replacing it changes both at once. Always replace with a two-digit number like `01`, `02`, `03`. --- ### `closing` Dark closing slide with centered logo, tagline, and contact footer. Always last. No replacements needed — all text is permanent brand content: - "Making print easier, for everyone, everywhere." - helloprint.com | info@helloprint.com | ★★★★★ Uitstekend — 32.000+ reviews ```python ("closing", []) ``` --- ### `agenda` White agenda slide with numbered items (up to 5), time allocations, and section label. | Placeholder text | What it is | |---|---| | `TEAM UPDATE — AI & GROWTH` | Section label (top left, green) | | `Premium Hardcover Boekjes` | Slide title | | `Q1 Resultaten` | Item 1 title | | `Revenue, margins, order volume en key highlights` | Item 1 description | | `5 min` | Item 1 time (right side) | | `Financial Performance` | Item 2 title | | `Deep dive in de cijfers per markt en categorie` | Item 2 description | | `10 min` | Item 2 time (2nd occurrence) | | `Product & Platform` | Item 3 title | | `Nieuwe features, marketplace expansie en tech roadmap` | Item 3 description | | `AI & Automation` | Item 4 title | | `Skill updates, voortgang en planning voor HY1` | Item 4 description | > Note: Item 5 (`Q&A` / `Open vragen en discussie` / `15 min`) is at the bottom and uses > unique text — replace as needed. The item numbers (01–05) are visual icons, not plain text. --- ### `testimonial` Dark background with large quote, avatar initials, name, and title. | Placeholder text | What it is | |---|---| | `Helloprint heeft ons de flexibiliteit gegeven om snel te schakelen. Van 500 visitekaartjes tot 50.000 brochures — alles wordt op tijd en perfect geleverd.` | Quote text | | `MV` | Avatar initials | | `Martine Verhoeven` | Person name | | `Marketing Director — TechCorp BV` | Person title and company | --- ## RECOMMENDED SLIDE ORDER ``` title-dark → agenda → section-divider → [content slides] → closing ``` Content slides to mix and match between dividers: - `content-bullets-kpis` — text + KPIs summary - `before-after` — transformation/impact - `big-number` — single hero metric - `chart-kpi-cards` — data-heavy - `usp-4-cards` — features/benefits - `process-timeline` — workflow steps - `two-column-product` — product/feature spotlight - `impact-statement` — bold statement - `testimonial` — social proof - `team-photo` — culture/team **Rule:** No more than 3 content slides in a row without a visual break (section-divider, big-number, or impact-statement). --- ## WRITING STYLE All text in presentations must follow Helloprint's tone: **direct, professional, no fluff**. - Start with the main message — no preamble - Short titles (max 8 words) - Body text max 3 lines per block - KPI numbers should be specific and real - Avoid filler words: "We are proud to...", "Please note that..." - Never use ALL CAPS except section labels (those are auto-uppercase in the template) **Language:** Default to Dutch for internal NL/BE audiences, English for international. Match the language of the brief — don't mix languages in one presentation. **Ampersand:** Use `&` in your Python strings. The engine handles XML escaping automatically. Never write `&` in replacement text. **Special characters:** Use Unicode directly — `—` (em dash), `→`, `▲`, `▼`, `✓`, `€`, `+`. See `references/writing-style-guide.md` for detailed Helloprint tone of voice guidelines. See `references/internal-language.md` for internal Helloprint terminology. --- ## FULL EXAMPLE ```python import sys, shutil, os # 1. Setup SKILL_DIR = "/path/to/helloprint-presentation-creator" shutil.copy(f"{SKILL_DIR}/HP_MainTemplate_baseline.pptx", "/sessions/brave-bold-cerf/hp_baseline.pptx") shutil.copy(f"{SKILL_DIR}/generate_presentation.py", "/sessions/brave-bold-cerf/generate_presentation.py") sys.path.insert(0, "/sessions/brave-bold-cerf") from generate_presentation import generate # 2. Build slide plan plan = [ ("title-dark", [ ("Q1 2025 Business Review", "AI & Automation — Q2 2025 Update"), ("Kwartaalresultaten, strategische prioriteiten en roadmap H2", "Voortgang, resultaten en roadmap voor het tweede kwartaal"), ("Team Strategy & Leadership", "AI & Growth Team"), ]), ("agenda", [ ("Premium Hardcover Boekjes", "Wat bespreken we vandaag"), ("Q1 Resultaten", "AI Skills Voortgang"), ("Revenue, margins, order volume en key highlights", "20 skills live, impact en learnings Q1"), ("Financial Performance", "Content Automation"), ("Deep dive in de cijfers per markt en categorie", "SEO output, kwaliteit en schaalresultaten"), ]), ("section-divider", [ ("02", "01"), ("Financial Performance", "Content Automation"), ("Omzet, marges en key metrics over het afgelopen kwartaal met een vooruitblik op de rest van het jaar.", "Hoe we 500+ pagina's per maand genereren — on-brand en meertalig."), ]), ("big-number", [ ("Q1 HIGHLIGHT", "Q1 RESULTAAT"), ("+42%", "500+"), ("Year-over-year growth in new customer acquisition", "Productpagina's gegenereerd in Q1 via AI Skills"), ("Driven by marketplace expansion into 3 new markets and a 28% improvement in organic search visibility across all locales.", "Uitgerold in NL, BE, DE en FR. Gemiddeld 15 min per pagina. Schaalbaar naar alle 14 markten in Q2."), ]), ("closing", []), ] # 3. Generate generate(plan, "/Users/derkdissselhof/Library/Application Support/Claude/local-agent-mode-sessions/a2d0567c-5a2d-4037-a100-87a5e74b9a55/3f471e31-d031-4ffe-bb3a-282799a05800/local_0cbc5cf3-74a0-4400-80d7-33c648a960dc/outputs/MyPresentation.pptx") ``` --- ## CHARACTER LIMITS Text boxes in the baseline have fixed widths. Exceeding these limits causes text to wrap to a second line or overflow the element, breaking the visual design. **Always stay within these limits.** | Template | Field | Max chars | |---|---|---| | All slides | Section label (top left, green) | 40 | | All slides | Slide title | 45 | | `section-divider` | Section title | 25 | | `section-divider` | Section description | 130 | | `usp-4-cards` | Card title line 1 | 20 | | `usp-4-cards` | Card title line 2 | 20 | | `usp-4-cards` | Card body text | 100 | | `agenda` | Item title | 25 | | `agenda` | Item description | 70 | | `big-number` | Hero label (below number) | 55 | | `big-number` | Context paragraph | 200 | | `process-timeline` | Step title | 15 | | `process-timeline` | Step description | 80 | | `testimonial` | Quote text | 210 | | `testimonial` | Person name | 30 | | `testimonial` | Person title | 45 | | `content-bullets-kpis` | Bullet title | 25 | | `content-bullets-kpis` | Bullet body | 100 | > **Template fix recommended:** If you need more room, open `HP_MainTemplate_baseline.pptx` in > PowerPoint, select the relevant text box, go to **Format Shape → Text Options → enable > "Shrink text on overflow"**. This makes the layout robust against occasional overruns. > After editing, save as the new baseline and re-upload to Gitea via skill-sync. --- ## TROUBLESHOOTING **Text not replaced?** Check that your `old_text` exactly matches the placeholder (copy-paste from the table above). The match is case-sensitive and whitespace-sensitive. **`&` showing literally?** You passed `&` as new_text — change it to `&`. **USP cards all same content?** Known limitation — see usp-4-cards note above. **Slide out of order?** The order in `slide_plan` determines the output order, not the template index. Put slides in the list in the order you want them.