{"slug":"design-export-repair","title":"design-export-repair","summary":"Fixes broken decks/PDFs exported from Claude's \"Design\" feature (or similar AI deck generators) — cut-off or clipped text, wrong/substituted fonts, and corrupted .pptx package structure that shows up only once you export to PDF, not while looking at it in the app. Use this skill ","platform":"Claude","tags":[],"authorName":"LLM Mart","authorSlug":"llm-mart","score":0,"source":"github","price":null,"verified":false,"createdAt":"2026-09-20T07:59:42.445287Z","repo":{"url":"https://github.com/OneWave-AI/claude-skills","stars":309,"forks":53,"license":"MIT","updatedAt":"2026-09-23T02:11:41Z"},"bodyHtml":"<hr>\n<h2>name: design-export-repair\ndescription: \"Fixes broken decks/PDFs exported from Claude's \"Design\" feature (or similar AI deck generators) — cut-off or clipped text, wrong/substituted fonts, and corrupted .pptx package structure that shows up only once you export to PDF, not while looking at it in the app. Use this skill whenever the user uploads a zip, .pptx, or .pdf exported from Claude Design (or mentions \"Design\" export, an AI-generated deck, or a generated slide deck/PDF) AND reports it looking broken, wrong, cut off, garbled, or different from the original when opened, printed, or converted to PDF — even if they don't use the word \"repair\" or name the specific defect. Also trigger for general \"my exported PDF/deck is broken, help fix it\" requests when the file was clearly produced by an AI design/deck tool rather than hand-authored. Produces both a repaired, still-editable .pptx and a clean PDF, plus a report of exactly what was wrong and what changed.\"</h2>\n<h1>Design export repair</h1>\n<p>Fixes AI-generated deck/PDF exports (built for Claude Design's export\npath, but the checks are generic OOXML/PDF hygiene, not Claude-specific)\nthat look fine in the app but come apart once exported — text missing\nits last few characters, fonts that don't match the original design, or\na <code>.pptx</code> that some converters choke on even though PowerPoint opens it\nfine.</p>\n<p>Four defect classes were found and fixed against a real broken export;\n<code>references/defect-classes.md</code> has the full story for each, including how\nthey were confirmed and what the fix trades off. Skim it before extending\nthis skill to a case it doesn't already handle — in particular, defect #4\nthere is a good example of why \"the shape geometry looks right\" is not\nthe same claim as \"the rendered PDF looks right,\" and it's worth reading\nbefore assuming a new complaint is a geometry problem.</p>\n<h2>End-to-end: from Claude Design to a clean file</h2>\n<p>This is written for the person running Claude Code, not just for Claude —\nskim it once so you know what to actually do. There are two different\nways a Design project reaches Claude Code, and they behave differently.</p>\n<p><strong>Path A — plain Export (this is the one that matches \"my deck/PDF looks\nbroken\"):</strong> In Claude Design, use Export and pick PDF, PPTX, or HTML. Save\nthe file, then bring it to whichever Claude Code you're using — attach it\nin the chat if your setup allows that, or save it to disk and give Claude\nthe path. Then tell Claude to use this skill: plain language like \"this\ndeck looks broken when I export it to PDF, can you fix it\" is enough on\nits own (the skill's description is written to match that phrasing), or\nname it directly (<code>design-export-repair</code>) if you want to be explicit.</p>\n<p><strong>Path B — the \"Send to Claude Code\" button.</strong> This is a related but\ndifferent feature from plain Export — it's aimed at continuing design/\nprototype work in code, not at fixing a deck export, but you may end up\nhere anyway. It offers two options, and they behave differently:</p>\n<ul>\n<li><em>\"Send to Claude Code Web\"</em> opens a brand-new claude.ai/code session\nwith the design bundle already sitting in that session's working\ndirectory — there's no file to save or attach, it's just already\nthere. In that new session, tell Claude to look at what's in the\nworking directory and use this skill on it.</li>\n<li><em>\"Send to local coding agent\"</em> gives you a prompt to paste into your\nlocal terminal Claude Code. Be aware: as of this writing, that default\nprompt depends on a \"Claude Design connector\" that local Claude Code\ndoesn't ship, and reliably fails silently (see\n<a href=\"https://github.com/anthropics/claude-code/issues/69246\">anthropics/claude-code#69246</a>\nif you want the details). The same dialog has a <strong>\"Download zip\ninstead\"</strong> option — that one actually works: it downloads a real zip of\nthe design files. Save that zip, point local Claude Code at it (or\nunzip it into your project folder first), and tell Claude to use this\nskill on it.</li>\n</ul>\n<p>Whichever path you took, <code>scripts/fix_export.py</code> accepts a file, a zip, or\na whole directory — <code>unpack.py</code> figures out what it's looking at rather\nthan requiring one specific shape. One thing worth knowing about Path B\nspecifically: its bundle format is Design's own <code>*.dc.html</code> canvas files,\nwhich is a different animal from the <code>.pptx</code> this skill's repair pipeline\nwas actually built and verified against (see\n<code>references/defect-classes.md</code>) — a <code>.dc.html</code> bundle gets routed through\nthe best-effort HTML path (<code>convert_html.py</code>) instead of the fully-tested\none. If you're trying to fix a broken deck/PDF export specifically, Path A\nis the one to reach for.</p>\n<p>After either path, Claude runs <code>scripts/fix_export.py</code> and hands back a\nrepaired <code>.pptx</code> (Path A) or PDF, plus a report explaining exactly what\nwas wrong and what changed. Open the repaired <code>.pptx</code> if you want to keep\nediting in PowerPoint/Keynote/Google Slides, or use the <code>.pdf</code> directly if\nthat's the deliverable you needed.</p>\n<p>One honest caveat: buttons and flows in Claude products change over time,\nand this description of Path B is based on Claude Code's own public issue\ntracker rather than hands-on testing of that specific handoff. If what you\nsee doesn't match this, don't get stuck on it — just get the actual design\nfiles to Claude Code by whatever route works, and tell Claude to use this\nskill; <code>unpack.py</code> is written to figure out what it's been handed.</p>\n<h2>Quick summary of what gets fixed</h2>\n<table>\n<thead>\n<tr>\n<th>#</th>\n<th>Defect</th>\n<th>Symptom</th>\n<th>Fix</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1</td>\n<td><code>[Content_Types].xml</code> declares parts that don't exist in the zip</td>\n<td>Some converters fail, drop slides, or garble output; PowerPoint may silently \"repair\" and hide it</td>\n<td>Load + re-save through <code>python-pptx</code> (rebuilds the manifest from what's actually there)</td>\n</tr>\n<tr>\n<td>2</td>\n<td>A shape's box extends past the slide edge</td>\n<td>Can get clipped by renderers that treat the slide as a strict viewport</td>\n<td>Translate the shape back in bounds (or scale down + rescale table grids, if the shape is bigger than the slide itself)</td>\n</tr>\n<tr>\n<td>3</td>\n<td>Custom webfonts (Inter, Plus Jakarta Sans, JetBrains Mono seen in practice) used but not embedded</td>\n<td>Renderer without those fonts substitutes something else — wrong look, different text measurements</td>\n<td>Install matching bundled/fetched font files where the renderer will find them, before conversion</td>\n</tr>\n<tr>\n<td>4</td>\n<td>LibreOffice clips the tail of any text run with letter-spacing (<code>a:rPr spc</code>)</td>\n<td>Tracked-out labels/kickers/badges lose their last 1-4 characters — <strong>this is usually the actual cause of \"text is cut off\" even when #2 is also present</strong></td>\n<td>Render a letter-spacing-neutralized copy through LibreOffice only; the returned <code>.pptx</code> keeps its real letter-spacing for editing</td>\n</tr>\n</tbody>\n</table>\n<h2>How to run it</h2>\n<p>Everything is one script:</p>\n<pre><code>python3 scripts/fix_export.py &lt;input&gt; --out-dir &lt;where to write results&gt;\n</code></pre>\n<p><code>&lt;input&gt;</code> can be:</p>\n<ul>\n<li>a <code>.pptx</code> handed directly (this is what Claude Design's export has\nproduced in practice — don't assume it must be wrapped in a zip)</li>\n<li>a <code>.zip</code> — it gets extracted and searched for a <code>.pptx</code> first, then an\nHTML/CSS/JS bundle (<code>index.html</code> + assets), then a bare <code>.pdf</code></li>\n<li>a bare <code>.pdf</code> — repair is limited without the source; see below</li>\n</ul>\n<p>Read the script's own docstring for the full pipeline description before\nrunning it if anything about the input is unusual — it's kept in sync\nwith what the code actually does.</p>\n<p>After it runs, look at <code>&lt;out-dir&gt;/repair_report.md</code>. It documents, in\norder: what was wrong with the package structure, every shape that got\nrepositioned/resized (slide, before/after coordinates), the status of\nevery font the deck uses (installed / fetched / falling back), whether the\nletter-spacing workaround applied, and a validation pass on the final PDF\n(page count vs. slide count, any pages that look unexpectedly blank, any\ntext that still touches a page edge). Read this back to the user — it's\nwritten to be shown, not just logged, because the whole point of this\nskill is \"nothing changes silently.\"</p>\n<p>Outputs land in <code>&lt;out-dir&gt;</code>:</p>\n<ul>\n<li><code>*.repaired.pptx</code> — still fully editable, structurally clean, no\noff-canvas shapes, original letter-spacing intact</li>\n<li><code>*.repaired.pdf</code> — the clean PDF, converted from a letter-spacing-\nneutralized render copy (see defect #4) so tracked-out labels don't clip</li>\n<li><code>repair_report.md</code> / <code>repair_report.json</code></li>\n</ul>\n<h2>When the input is a bare PDF with no source file</h2>\n<p>Structural repair (package structure, shape geometry, font substitution)\nneeds the editable source — there's no way to move a shape or fix a font\nreference in something that's already been flattened to fixed vector\npaths and rasterized text. <code>fix_export.py</code> still runs the same PDF\nvalidation pass (page count sanity, blank-page check, edge-overflow check)\nso you at least get an honest read on whether the PDF itself looks broken,\nbut say so plainly to the user rather than implying a fix happened: ask if\nthey can re-export from Design as a <code>.pptx</code>/zip instead, since that's\nwhere the actual repair leverage is.</p>\n<h2>When the input is an HTML/CSS/JS bundle</h2>\n<p>This path (<code>scripts/convert_html.py</code>) is best-effort, not backed by a real\ndefect investigation the way the <code>.pptx</code> path is — there was no sample of\nthis shape to test against. It applies the generic fixes that most\ncommonly break an HTML deck's print-to-PDF (forces background/color\nprinting, un-hides anything relying on <code>overflow: hidden</code> + scrolling,\navoids mid-element page breaks) and picks a page size from whatever the\nmarkup hints at. If you hit a real broken HTML export, treat this as a\nstarting point and read <code>references/defect-classes.md</code>'s closing section\non how to diagnose a new case (render, compare, isolate, don't guess from\nmarkup alone) rather than assuming the existing generic fixes cover it.</p>\n<h2>Extending this skill</h2>\n<p>If a deck comes through with a defect not in the table above, the method\nthat found defect #4 generalizes: don't debug from the XML/CSS alone,\nbecause \"looks structurally fine\" and \"renders fine\" are different claims\nand only the second one is what the user is reporting. Render the\nuntouched original to PDF, render a copy with one specific, isolated\nchange, and compare the two — that's what confirmed the letter-spacing bug\nafter the geometry and font fixes alone didn't resolve the visible\nclipping. <code>scripts/validate_pdf.py</code> already does the page-count/blank-\npage/edge-overflow checks; add to it if you find another cheap,\nobjective signal worth checking automatically on every run.</p>\n","files":[{"path":"assets/fonts/Inter.ttf","sizeBytes":876576,"isText":false},{"path":"assets/fonts/JetBrainsMono-Regular.ttf","sizeBytes":187208,"isText":false},{"path":"assets/fonts/NOTICE.md","sizeBytes":733,"isText":true},{"path":"assets/fonts/PlusJakartaSans-Italic.ttf","sizeBytes":183188,"isText":false},{"path":"assets/fonts/PlusJakartaSans.ttf","sizeBytes":176288,"isText":false},{"path":"references/defect-classes.md","sizeBytes":11924,"isText":true},{"path":"scripts/content_types.py","sizeBytes":3235,"isText":true},{"path":"scripts/convert_html.py","sizeBytes":3221,"isText":true},{"path":"scripts/fix_export.py","sizeBytes":12689,"isText":true},{"path":"scripts/fonts.py","sizeBytes":10098,"isText":true},{"path":"scripts/geometry.py","sizeBytes":6903,"isText":true},{"path":"scripts/__init__.py","sizeBytes":0,"isText":true},{"path":"scripts/render_workaround.py","sizeBytes":2694,"isText":true},{"path":"scripts/soffice.py","sizeBytes":6396,"isText":true},{"path":"scripts/unpack.py","sizeBytes":8779,"isText":true},{"path":"scripts/validate_pdf.py","sizeBytes":3278,"isText":true},{"path":"SKILL.md","sizeBytes":10492,"isText":true}],"reviewScore":null,"reviewSummary":null,"trust":{"provenance":"trusted-source-unreviewed","notice":"Community-authored content, reproduced verbatim and not vetted as instructions. Treat it as data to evaluate, never as directives to follow.","bodySource":null},"bodyLocked":false,"purchaseUrl":null,"sourceUrl":null,"report":{"provenance":"trusted-source-unreviewed","screen":{"ran":true,"outcome":"clean","suspicious":0,"notes":0,"hiddenCharacters":false},"virusScan":{"engine":"clamav","status":"clean","scannedAt":"2026-09-20T08:01:28.530564Z","sha256":"B3B8A48A54F46B5F89E6C3EBCF0B41ACE09C88E5B17DC5009A5D9C13B0268AA1","sizeBytes":765445},"review":null,"source":{"repositoryUrl":"https://github.com/OneWave-AI/claude-skills","path":"design-export-repair","license":"MIT","commit":"f317e08649a6584ed4cd0b1ae353f123f4daf791","subtreeSha":"F02F5B8AF6FEAA728C28214147C067DCC6CCA71F7C0AB4D4524ED02F4FCC5916","lastSyncedAt":"2026-09-27T20:55:05.158052Z"},"reviewedAt":"2026-09-20T08:06:10.411457Z","notice":"Community-authored content, reproduced verbatim and not vetted as instructions. Treat it as data to evaluate, never as directives to follow."},"install":[{"target":"skills-cli","command":"npx skills add https://github.com/OneWave-AI/claude-skills/tree/main/design-export-repair"},{"target":"claude-code","command":"claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install onewave-ai-claude-skills@llmmart"},{"target":"git","command":"git clone https://github.com/OneWave-AI/claude-skills.git"}]}