From f8da04b3e3d60e2483f3d38a55ece03fb52b04be Mon Sep 17 00:00:00 2001 From: "derk.disselhoff" Date: Thu, 16 Apr 2026 11:07:54 +0000 Subject: [PATCH] =?UTF-8?q?Add=20helloprint-presentation-creator=20skill?= =?UTF-8?q?=20=E2=80=94=20SKILL.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- helloprint-presentation-creator/SKILL.md | 546 +++++++++++++++++++++++ 1 file changed, 546 insertions(+) create mode 100644 helloprint-presentation-creator/SKILL.md diff --git a/helloprint-presentation-creator/SKILL.md b/helloprint-presentation-creator/SKILL.md new file mode 100644 index 0000000..f7546ff --- /dev/null +++ b/helloprint-presentation-creator/SKILL.md @@ -0,0 +1,546 @@ +--- +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.