Help us improve
Share bugs, ideas, or general feedback.
From deckify
Generates HTML slide design system markdown from a reference URL by analyzing color palette, typography, logo, and aesthetic mood, applying rules like 1280×720 fit, overflow safety, and mobile fixes.
npx claudepluginhub seacen/deckify --plugin deckifyHow this skill is triggered — by the user, by Claude, or both
Slash command
/deckify:deckifyThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Turn a reference URL into a production-ready Design System markdown plus a verified 9-slide HTML sample deck. Another agent (or you) can use the DS to build precise, mobile-friendly HTML slides in the brand's visual language. The sample deck is the proof that the DS spec works.
evals/README.mdevals/build_report.pyevals/hard_checks.pyevals/rubric.jsonevals/trigger_evals.jsonreferences/decision-questions.mdreferences/ds-template.mdreferences/ds-template.zh.mdreferences/llm-prompts/discover-pages.mdreferences/llm-prompts/synthesize-brand.mdreferences/verification-deck-spec.mdscripts/_ab_common.pyscripts/embed_logo.pyscripts/enumerate_assets.pyscripts/fetch_pages.pyscripts/fetch_sitemap.pyscripts/init_workspace.pyscripts/persist_brand_source.pyscripts/setup.pyGenerates self-contained HTML slide presentations with keyboard navigation, swipe support, fullscreen, animations, embedded images, and brand-accurate styling from guides.
Generates self-contained HTML slide decks for product presentations. Reads pm-context.md, extracts brand colors from websites, adds keyboard navigation and print-friendly layouts.
Generates self-contained HTML slide decks from briefs, notes, or topics. Supports 13 layouts, 8 style presets, inline editing, and PDF export.
Share bugs, ideas, or general feedback.
Turn a reference URL into a production-ready Design System markdown plus a verified 9-slide HTML sample deck. Another agent (or you) can use the DS to build precise, mobile-friendly HTML slides in the brand's visual language. The sample deck is the proof that the DS spec works.
Right before Phase 0, print exactly one of these two banners. Pick the language from how the user is currently writing to you — if their invocation message is in Chinese, print the 中文 banner; otherwise print the English one. You don't need to wait for Phase 2 / decisions.json — at this point the conversation language is the only signal you need, and it's already obvious from what the user just typed.
Print the banner cleanly with surrounding blank lines, then continue straight into Phase 0 — do not add a "Hi! I'm deckify, what's your brand?" intro on top of this. The user already gave you the URL; the slogan is the entire hello.
English (default):
═══════════════════════════════════════════════════════════════════════
The next deck writes itself.
Train deckify on your brand once.
Every deck after that is just a prompt.
— deckify
═══════════════════════════════════════════════════════════════════════
中文 (after Round 0 confirms zh):
═══════════════════════════════════════════════════════════════════════
PPT 翻篇了,
AI 用 HTML 接管讲故事的边界。
— deckify
═══════════════════════════════════════════════════════════════════════
"Make slides in the visual language of brand X" is deceptively hard. The naive approach — show Claude the URL and say "make slides like this" — produces drift: colors shift, fonts get substituted, the logo renders as an emoji or a placeholder, and slides clip the deck at 720px because nobody told the model that a slide is a fixed-size box, not a scrolling document.
This skill solves the problem by separating what changes per brand from what never should:
That split is the whole game. Without it, every new brand = relearning the same hard-won bugs.
Before the first run on any new machine, verify the standalone agent-browser CLI is installed:
python3 scripts/setup.py
This script:
python3 is on PATHagent-browser is on PATH and can open a pageagent-browser install after first install (downloads Chrome from Chrome for Testing)If the user is on Linux and Chrome won't download, suggest agent-browser install --with-deps (pulls in libnss3, etc.).
Do NOT silently fall back to curl if agent-browser is missing — modern brand sites hydrate client-side and curl returns a near-empty shell, breaking the whole pipeline. Surface the install command and stop.
All user artefacts land in
~/deckify/— independent of the cwd you run from. The brand's DS markdown, verification deck, persisted recon source, and per-run reports all go to~/deckify/decks/<brand>/and~/deckify/reports/. Do not write user artefacts into the deckify source repo, into the cwd, into a temp dir, or anywhere else.~/deckify/is created on first use; subsequent runs reuse it. This is enforced byscripts/persist_brand_source.pyat Phase 6 — it always resolves to~/deckify/, ignoring cwd. (If you're a skill maintainer running the Phase A panel, seetools/phase-a/README.md— that path is separate and writes to the deckify repo'stests/, not to~/deckify/.)
Architecture: Python scripts only do what's deterministic (fetch, enumerate, quality-gate, embed). Every act of judgment — which subpages to crawl, which candidate is the real wordmark, what the brand palette actually is — is done by you, the LLM running this skill, using the guideline files in references/llm-prompts/.
1a. fetch_sitemap.py → 1b. (LLM picks pages) → 1c. fetch_pages.py
↓
1f. embed_logo.py ← 1e. (LLM synthesizes) ← 1d. enumerate_assets.py
Each step's output is the next step's input. Don't skip.
Phase 1 happens in a transient workspace inside the OS temp dir — these are large, regenerable recon files (DOM dumps, screenshots, raw asset pools), not durable artifacts. The OS sweeps them on its own schedule (macOS ~3 days idle, Linux on reboot, Windows by user / Disk Cleanup). Durable artifacts (brand.json / decisions.json / assets / DS markdown / deck HTML) get copied out at Phase 6.
# Cross-platform: creates /var/folders/.../T/deckify-<slug>-<rand>/ on macOS,
# %TEMP%\deckify-<slug>-<rand>\ on Windows, /tmp/deckify-<slug>-<rand>/ on Linux.
WS=$(python3 scripts/init_workspace.py <brand-slug>)
echo "Workspace: $WS"
1a — Fetch sitemap + home (deterministic)
python3 scripts/fetch_sitemap.py <URL> "$WS"
Pulls recon/home.html + recon/home.png + recon/sitemap.xml + recon/sitemap-urls.txt + recon/nav-links.json + recon/jsonld.json.
1b — Pick subpages to fetch (LLM, you)
Read references/llm-prompts/discover-pages.md. Then read the discovery files from 1a, decide which 5–8 subpages are most likely to expose the brand's real wordmark / palette / typography / aesthetic, and write them to $WS/pages.txt (one URL per line, # comments allowed).
1c — Batch-fetch the chosen pages (deterministic)
python3 scripts/fetch_pages.py "$WS/pages.txt" "$WS"
For each URL: desktop screenshot + DOM dump + per-page probe (every inline SVG anywhere with metadata, every <img> with size+region, every background-image: url(), every JSON-LD logo field, all <link rel*=icon>, all :root vars, computed bg/color/font on a wide selector set, @font-face srcs, preload font URLs). Lands at $WS/recon/pages/<slug>/{dom.html,shot.png,probe.json}.
1d — Aggregate into a candidate pool (deterministic)
python3 scripts/enumerate_assets.py "$WS"
Merges every page's probe.json into one $WS/raw-assets.json. Each logo candidate gets a stable 8-char id. Color frequency, computed palette per surface, font frequencies, font-face URLs are all aggregated. Candidates are ranked by interestingness as a hint, but nothing is filtered out — that's your job.
1e — Synthesize brand from raw assets (LLM, you)
Read references/llm-prompts/synthesize-brand.md. Then:
$WS/raw-assets.json$WS/recon/pages/<slug>/shot.png for each indexed page using your host's image-viewing capability (the Read tool in Claude Code, the equivalent in Codex / OpenClaw, or your own image loader if scripted)id), brand_primary / secondary / ink / paper / accents (with hex + evidence), display + body fonts, spacing/radius/shadow style, aesthetic mood + precedents$WS/brand.json per the schema in synthesize-brand.md, including chosen_logo.id plus 2–3 alt_logo_ids1f — Materialize the chosen logo (deterministic)
python3 scripts/embed_logo.py "$WS"
Looks up chosen_logo.id in raw-assets, downloads if remote, runs the quality gate (SVG must have <path d> ≥ 40 chars or <image> child; raster ≥ 64×64), and writes $WS/assets/logo.{svg|png|…} + $WS/assets/logo.embed.html (a <symbol id="brand-wm"> snippet ready to paste into Phase 3) + $WS/assets/logo.dataurl.
If quality-gate fails (exit 1), swap chosen_logo.id to the next item in alt_logo_ids in brand.json and rerun. If all alternatives fail, stop and ask the user for a logo URL or file path. Never invent a typographic placeholder.
Goal: take the brand.json you produced in 1e and resolve the decisions YOU couldn't make alone — language, ambiguous logo picks, contested colour direction, proprietary typography fallbacks. Don't ask the user to confirm things YOU already have strong evidence for — that's noise.
Host-conditional interaction rule (this is a hard rule on Claude Code, a recommendation elsewhere — read carefully):
| Host environment | Required mechanism | If unavailable |
|---|---|---|
| Claude Code / Claude Desktop | MUST use the AskUserQuestion tool for every Round below. If the tool is deferred (schema not loaded at session start), invoke ToolSearch with query: "select:AskUserQuestion" first to load its schema, then call it. Do not substitute plain text questions — that bypasses the structured-choice UI, loses analytics, and produces ambiguous free-text answers the rest of this phase depends on. | No graceful fallback — refuse to proceed and tell the user the tool is missing. |
| Codex CLI / OpenClaw / similar AI hosts | Use the host's nearest equivalent structured-question mechanism if it exists (each host names it differently). | If no structured mechanism exists, fall back to a single block of clearly-numbered text questions with explicit option labels. |
| Headless / scripted runs (no human in the loop) | Skip Phase 2 entirely; commit brand.json as-is and write decisions.json with interaction_mode: "headless-defaults" and the synthesizer's best evidence-based picks for every required field. | N/A — by definition there's no user to ask. |
After Phase 2 finishes, always record which mode was actually used in decisions.json:
{
"interaction_mode": "ask-user-question" | "host-equivalent" | "text-fallback" | "headless-defaults",
"host": "claude-code" | "codex" | "openclaw" | "other-name" | "headless",
// ... rest of decisions.json (language, slide_emphasis, etc.) ...
}
This field is what audit_skill.py and build_report.py use to detect "this run silently downgraded interaction quality" — a recurring failure mode where an agent skips structured Q&A and the resulting brand DS reflects guesswork instead of user choice.
Question philosophy: ask only where you are genuinely uncertain. A confident, evidence-backed brand.json shouldn't need 4 confirmation rounds — it needs maybe 1 or 2 for the genuinely ambiguous decisions, plus the always-required language round. If a decision is unambiguous (single canonical SVG logo, dominant chord with 100× CSS frequency, body font is the only computed font), commit and don't waste the user's attention.
Round 0 (ALWAYS first): language. Ask the user with exactly two options: 中文 (Simplified Chinese) and English. These are the only two languages with maintained sister templates (ds-template.zh.md and ds-template.md). Do NOT offer Japanese / Spanish / Other free-text — there is no ds-template.<other>.md to route to, so any non-zh/en answer would silently fall back to the English template + a per-run translation pass, which produces drift and undercuts the language_consistency hard check. If the user genuinely needs another language, they can author it in 中文 or English and re-translate downstream. After this answer, conduct every subsequent round AND Phase 3 generation in that language. Token names (--primary, --accent, etc.), code snippets, CSS, hex values, viewBox numbers, and HTML comment anchors (<!-- ENGINEERING-DNA: ... -->) stay in English regardless — only the prose changes.
Round 1 (CONDITIONAL — only if logo is ambiguous): logo selection. Trigger when you have ≥ 2 candidates that all pass the quality gate AND no clear winner from the synthesize-brand priority order. Surface 2–3 specific candidates with their evidence:
Round 2 (CONDITIONAL — only if dominant chord is contested): palette anchor. Trigger when colour-frequency analysis has 2+ candidates with similar counts (within 1.5×) AND the screenshots don't clearly resolve which is the brand's actual primary chord (vs a campaign accent). Surface the top 2–3 colours with their hex + role evidence; ask which is the brand's actual --primary.
Round 3 (CONDITIONAL — only if typography needs licensing decision): font fallback. Trigger when font.frequencies show a proprietary face (UnileverDesire, SF Pro, Söhne, Stripe Sans) that won't be licensable for a typical standalone slide deck. Surface 2–3 fallback options:
Round 4 (ALWAYS, but short): slide-type emphasis for the verification deck. Multi-select from the 8 required slide types per references/verification-deck-spec.md — which 2–3 should the deck particularly lean into for this brand's voice? (e.g. Apple → Type J pullquote + Type F image + Type H chart.)
Round 5+ (CONDITIONAL — only when needed): scope-of-deck decisions. Quarterly review vs annual letter vs internal deck — only ask if the user's original prompt didn't clarify. If they said "build me a DS for SaaS pitch decks", that's enough; don't re-ask.
Take the user's responses. Save the final decisions to $WS/decisions.json. If the user redirects on a token (e.g., "actually use the secondary as primary"), update brand.json's palette accordingly so Phase 3 generation reflects it.
Anti-pattern: asking 4 ceremonial confirmation questions when the recon was unambiguous. Each interactive question costs the user attention — earn it with genuine choices, not with reciting back what you already know.
If the user gives no clear direction on something, default to brand.json's pick (LLM's best evidence-based guess) and note it in the output.
Step 0 — Pick the template by language. Read decisions.json for language:
English → use references/ds-template.md (the English source-of-truth)中文 / Chinese / zh → use references/ds-template.zh.md (the Chinese sister template; same engineering-DNA anchors, prose pre-translated)These are the two and only two supported languages — Phase 2 Round 0 only offers them, so decisions.json.language will always be one of these. There is no general translation-pass fallback; if you ever see another value here, treat it as a bug in Round 0 and re-ask the language question instead of silently translating.
Both templates contain identical:
{{BRAND_NAME}}, {{BRAND_SLUG}}, {{PHILOSOPHY_PARAGRAPH}}, {{PRIMARY_HEX}}, {{ACCENT_HEX}}, {{BRAND_PALETTE_TOKENS}}, etc.<!-- ENGINEERING-DNA: fit-contract -->, <!-- ENGINEERING-DNA: scale-to-fit -->, etc. These are language-agnostic stable identifiers used by evals/hard_checks.py:check_ds_engineering_dna.Steps:
Fill brand-variable placeholders from $WS/decisions.json + $WS/brand.json (palette hex, font families, brand name, etc.).
Logo embed: paste the contents of $WS/assets/logo.embed.html directly into the §4 Logo section's "Definition (once per HTML file)" block. embed_logo.py already produced the correct <symbol id="brand-wm"> snippet — vector or base64-raster form, with hardcoded fills stripped so currentColor works. Do not regenerate this; do not re-extract paths.
Set {{LOGO_VIEWBOX}} placeholder in §4's .logo usage examples to match the viewBox in the embed snippet.
Language pass (only when Round 0 picked 中文): if Step 0 already routed you to ds-template.zh.md, the prose is already pre-translated — your work in this step is limited to (a) translating the brand-variable text you injected via placeholders ({{PHILOSOPHY_PARAGRAPH}}, {{TYPE_PHILOSOPHY_NOTE}}, etc.) and (b) checking that no English sentences leaked through. The output must be single-language throughout — no leftover English sentences mixed into a Chinese DS.
Translate everything that is prose, including:
## 1. Design Philosophy → ## 1. 设计理念)Never translate:
--primary, --accent, --surface, --ink, --mid, --rule, --tint, --green, --red, --warn, --teal, plus brand-palette tokenscss js html block stays as-is)<!-- ENGINEERING-DNA: fit-contract -->, <!-- ENGINEERING-DNA: typography-safety -->, etc. These are stable identifiers — the prose around them adapts; the IDs stay.How the engineering-DNA hard check works under translation: evals/hard_checks.py:check_ds_engineering_dna reads the markdown looking for <!-- ENGINEERING-DNA: <id> --> HTML comments — NOT for the English chapter titles. As long as you preserve the comment anchors verbatim, the chapter heading and surrounding prose can be in any language. So ### 5.1 单页适配契约 <!-- ENGINEERING-DNA: fit-contract --> passes the check the same as the English original.
Write the final markdown to the user's chosen path. Default: ./{{BRAND_SLUG}}-PPT-Design-System.md. Confirm path before writing if it would overwrite an existing file.
The DS markdown is the deliverable. The verification deck is the proof that the DS produces correct slides. Skipping this means shipping an unverified spec — don't.
The Phase B fix-routing rule, enforced structurally. When a hard check fails, the fix lives in the brand DS — never in the deck alone. This is not advice; this is the workflow contract that makes Phase B work at all, because if you patch the deck to make the check pass, you've healed one slide and left the spec wrong. The next deck built from this DS will have the same bug; every other brand sharing the affected DS pattern will too.
Starting now this is checked: hard_checks.py includes a
phase_b_workflow check that hashes the deck and the DS each run. On a
re-run, if the deck changed but the DS didn't, the check FAILS with
deck_modified_without_ds_update. There is no way around this short of
also editing the DS — which is the point.
The correct loop is:
references/verification-deck-spec.md §8 — it
names the brand DS section that owns the rule.If after step 5 the same check still fails, the fix you applied to the DS didn't actually capture the rule — go back to step 2 and read the fix-mapping more carefully, or pick a different DS section.
Step 4a — Write the verification deck.
Read references/verification-deck-spec.md. It defines the 8 required slide types (cover, narrative+pullquote, two-column, data table, chart, flip cards, timeline, big pull-quote) and 6 coverage rules (multi-column collapse, click interaction, semantic colour, real numbers, bespoke composition, absorber variety). Write the deck to ~/deckify/decks/<brand>/<brand>-deck.html using copy drawn from the recon corpus — never invented stats.
Where artefacts live: every brand the user generates lands under
~/deckify/decks/<brand>/(a fixed home-directory convention — independent of the cwd you happen to be in, the deckify source repo, or any project structure). The brand DS markdown, the verification deck, the persisted recon source, and per-run hard-check reports all live under that single tree.~/deckify/is created on first use; it is the only path you should write user artefacts to. Do not write into the deckify source repo (the maintainer'sdecks/there is a reference panel — not your output target).
Step 4b — Run the runtime hard checks (deterministic).
For Layer 2 (single brand the user just generated), run hard_checks.py directly. Cross-platform — only Python, no shell required:
# Pick a per-run output dir under ~/deckify/. Re-use the same out_dir across
# re-runs of the same brand — that's how phase_b_workflow can compare SHAs
# (it persists a .provenance.json there). A fresh timestamped dir per
# attempt also works; the gate will treat it as a first run each time.
REPORTS="$HOME/deckify/reports/runs/$(date +%Y-%m-%dT%H-%M-%S)"
mkdir -p "$REPORTS/per-sample/<brand>"
# 11 deterministic checks: slide dimensions (1280×720), fit contract intact,
# token-only colors, no emoji, mobile collapse at 375 px, logo renders,
# language consistency, text layout safe (no truncation, no glued-to-bottom),
# DS engineering DNA preserved, CJK font quality (zh decks only),
# AND phase_b_workflow (no deck-only fixes — see EXTREMELY-IMPORTANT above).
python3 <skill-path>/evals/hard_checks.py \
"$HOME/deckify/decks/<brand>/<brand>-deck.html" \
"$HOME/deckify/decks/<brand>/<brand>-PPT-Design-System.md" \
"$REPORTS/per-sample/<brand>"
Phase A skill-author note: the multi-brand panel runner is python3 tools/phase-a/run_phase_a.py — see tools/phase-a/README.md. That tool is for skill maintainers tuning the deckify skill against the reference brand panel; it writes to the deckify repo's tests/reports/, not to ~/deckify/. End-user runs always use ~/deckify/.
Step 4c — On any hard-check failure, FIX THE BRAND DS — never the deck alone.
See the <EXTREMELY-IMPORTANT> block above. The brand DS markdown is your tunable; the deck is the verification artifact. When a check fails, trace it to the relevant section of your brand's DS (use the fail → DS-section mapping table in references/verification-deck-spec.md §8), update the DS, regenerate the deck from the updated DS, re-run hard checks.
Iterate until hard checks are 10/11+ PASS (cjk_font_quality is soft for en decks; the rest including phase_b_workflow must all pass).
Hard checks measure DOM shapes; they don't measure whether the deck looks on-brand. That's your job.
Phase 5 is single-brand — it scores the one deck the user just generated. Do not iterate over a panel here; that's Layer 1 (skill-author territory, see evals/run_phase_a.py).
Step 5a — Read the per-slide screenshots.
For the user's brand at ~/deckify/reports/runs/<latest>/per-sample/<brand>/slides/, view the PNGs using your host's image-viewing capability (Read tool in Claude Code, equivalents elsewhere). Re-read the brand's DS markdown for context.
Step 5b — Score against the rubric.
Read evals/rubric.json — 6 dimensions (logo present and branded, slide visual quality, brand fidelity, content substantive, engineering DNA visible in DS, CJK typography quality for zh decks), each 0–5. Plus 5 disqualifiers (D1 logo missing, D2 dimensions wrong, D3 console errors, D4 mobile horizontal scroll, D5 DS template violated).
For cjk_typography_quality: this is a vision-judged quality score, not a hard constraint. The hard check cjk_font_quality only catches the absolute bug (zero CJK fonts in chain). The judge dimension catches "the CJK is technically rendering, but looks thin / cheap / mismatched with Latin / wrong weight / wrong serif-vs-sans pairing." If you score this ≤ 3, the fix routes to DS §3 CJK 字体回退链 — typically swap CJK family to front of font-family chain AND bump body font-weight to 500/600. en decks return 5 for this dimension (not applicable).
Step 5c — Write judge.json.
Land at ~/deckify/reports/runs/<latest>/per-sample/<brand>/judge.json with this schema:
{
"ok": true,
"judged_by": "<your model id>",
"scores": {
"scores": {
"logo_present_and_branded": 0,
"slide_visual_quality": 0,
"brand_fidelity": 0,
"content_substantive": 0,
"engineering_dna_visible_in_ds": 0,
"cjk_typography_quality": 0
},
"reasoning": "<2-3 sentences explaining the lowest scores>",
"regression_flags": []
}
}
Step 5d — Aggregate (single brand).
python3 <skill-path>/evals/build_report.py <run-dir> 4 \
"<brand>|<source-url>|$HOME/deckify/decks/<brand>/<brand>-deck.html|$HOME/deckify/decks/<brand>/<brand>-PPT-Design-System.md"
PASS criteria (per rubric.json): hard 9/10+ AND judge avg ≥ 4 AND no disqualifier triggered.
Step 5e — Failure handling. All routes go to the user's brand DS (this is Layer 2; never edit skill source from a Phase 5 failure):
brand_fidelity → revisit ~/deckify/decks/<brand>/source/brand.json (was the mood paragraph too generic? did the palette flatten to white+grey+single-accent?). Update with sharper evidence, regenerate the brand DS §1 + §2, regenerate the deck, re-judge.slide_visual_quality → tighten the user's brand DS §6 (per-slide-type spec) or §7 (component density), regenerate the deck, re-judge.content_substantive → the Phase 1 recon corpus was thin; widen pages.txt to broader subpages OR pull more verbatim phrases from existing recon screenshots into the deck.engineering_dna_visible_in_ds → the user's brand DS is missing a required chapter or it got diluted during the language pass. Restore the chapter verbatim from references/ds-template.md (or .zh.md for zh decks).cjk_typography_quality → fix ~/deckify/decks/<brand>/<brand>-PPT-Design-System.md §3 CJK 字体回退链, then propagate the new font-family chain into the deck.references/verification-deck-spec.md §8.Iterate until PASS. The skill is not done until both hard 9/10+ AND judge ≥ 4.
Step 6a — Persist durable artifacts out of the temp workspace. Before the OS sweeps $WS, copy the parts that encode user judgment + LLM synthesis into the user's home deckify directory:
python3 <skill-path>/scripts/persist_brand_source.py "$WS" <brand-slug>
This copies brand.json, decisions.json, pages.txt, and assets/ (logo files) from $WS into ~/deckify/decks/<brand-slug>/source/ — sitting next to the DS markdown and the deck HTML. The recon/ DOM dumps + raw-assets.json are intentionally not copied — those are large + regenerable from the URL, and the OS will sweep them on its own.
After this step, the brand has a complete persisted bundle in the user's home tree:
~/deckify/
└── decks/
└── <brand>/
├── <brand>-PPT-Design-System.md ← the deliverable
├── <brand>-deck.html ← verification deck
└── source/
├── brand.json ← LLM synthesis
├── decisions.json ← user choices (Phase 2)
├── pages.txt ← LLM-picked subpages
└── assets/ ← embedded logo files
├── logo.svg
├── logo.embed.html
├── logo.dataurl
└── logo.report.json
Per-run hard-check + judge reports live alongside, under ~/deckify/reports/runs/<ts>/per-sample/<brand>/.
Step 6b — Hand back to the user.
Give the user:
~/deckify/decks/<brand>/)~/deckify/reports/runs/<latest>/summary.md for the full per-brand breakdownStep 6c — Print the closing message. After the summary above, print exactly one of these two closing blocks depending on decisions.json.language. By Phase 6 you have a confirmed language choice from Phase 2 — use that. The closing is a real piece of writing, not flavour text — preserve every word, including the line breaks. Print it AFTER the deliverable summary so the user has already seen what they got, then read this as the parting thought.
English (default):
═══════════════════════════════════════════════════════════════════════
Done.
You're holding two things: a Design System markdown that you — or any
AI agent — can use forever to build precise, brand-faithful slides;
and a sample deck that proves the spec works.
Notice what just happened. You didn't open PowerPoint. You didn't
move a single text box. You didn't fight a template. PPT was built
for **humans to draw with their hands** — every box, every gradient,
every line spacing, hand-placed. That made sense for fifty years.
The job has changed. Slides are no longer drawn; they're **imagined
and described**. The author has shifted from human to AI, and AI's
native medium isn't `.pptx` binary — it's HTML. Living markup,
animatable, queryable, transformable, copy-paste-able into any
conversation. Where PPT slows AI down, HTML lets it run.
Welcome to the deck for the AI era.
— deckify
═══════════════════════════════════════════════════════════════════════
中文 (when decisions.json.language === "中文"):
═══════════════════════════════════════════════════════════════════════
完成了。
你现在拥有两份东西:一份 Design System markdown —— 你或任何 AI agent 都能
拿它无限次地生成贴合这个品牌的精准 slides;一份示范 deck,证明这套规范确实
可以工作。
留意一下刚才发生了什么。你没有打开 PowerPoint。你没有挪动一个文本框。你没
有跟模板较劲。PPT 是 **为「人手绘」而设计的** —— 每个方块、每段渐变、每行
间距,都靠手摆。这在过去五十年里讲得通。
但 slide 的制作方式变了。slide 不再被「画」出来,它们被 **想象出来、描述
出来**。创作者已经从人变成了 AI,而 AI 的母语不是 `.pptx` 二进制 —— 是
HTML。活的标签、可动画、可被查询、可被改写、可粘贴进任何对话。PPT 拖慢
AI 的地方,HTML 让 AI 跑起来。
欢迎来到 AI 时代的 deck。
— deckify
═══════════════════════════════════════════════════════════════════════
These parts of the generated DS must be copied verbatim from references/ds-template.md. They came from real, painful bugs. If you find yourself thinking "this section is overkill, let me trim it," stop — you are about to reintroduce a bug someone else already fixed.
overflow:hidden safety net (.slide, .sw .sc, and any flex:1 absorber); single-absorber rule; 602px content-height budget math; pre-build height checklist; verify at native 1280×720 (the transform:scale() masks overflow at scaled sizes).<symbol> + currentColor: <symbol> defined once in a hidden <svg> block at the top of <body>; referenced via <use href="#…">; fill: currentColor set on the outer <svg> (NOT on the <path> — selectors don't pierce shadow DOM). Variants: .W (white-on-dark), .L (brand-dark-on-light).:root CSS variables. No ad-hoc hex values. Token names stay stable across brands (--primary, --accent, --surface, --ink, --mid, --rule, --tint, --green, --red, --warn, --teal) even when the actual hex differs — so downstream slide code doesn't need to know which DS it's using.@media rules that override style="display:flex" and style*="grid-template-columns" in case bespoke slides used inline styles). This is how mobile parity survives bespoke slide compositions.onclick="this.classList.toggle('on')"; mobile CSS kills 3D transforms and uses display:none/flex to swap front/back. CSS :hover doesn't work on touch.✓ − ! × → ← permitted; 👍🎉🔥 etc. forbidden. (Brand may override toward more or fewer symbols, but the no-emoji rule is invariant.)If any of these is missing from the generated DS, the DS will produce broken decks. The whole point of skillifying this is so future you doesn't have to remember any of it.
--unilever-navy, --stripe-purple). Tokens are abstractions — keep names stable.download_logo.sh failed, ASK the user for a logo URL or local file before generating §4.extract_brand.py reports candidates with frequency — prefer the higher-frequency one and confirm.references/ds-template.md — full DS template with placeholders + engineering DNA (incl. §3.1 Typography Safety, §4 multi-format logo embed, §5 scale-to-fit runtime, §6 Type E row-count rule, §10 mobile cov/sw fill rule). Read in Phase 3.references/verification-deck-spec.md — Phase 4 contract: the 8 required slide types every verification deck must include, plus the 6 coverage rules. Read in Phase 4a.references/decision-questions.md — Phase 2 structured decision checklist + Round 0 language framing.references/llm-prompts/discover-pages.md — guideline you (LLM) read at step 1b to decide which subpages to fetch.references/llm-prompts/synthesize-brand.md — guideline you (LLM) read at step 1e. Includes Design Taste anti-AI-slop guardrails (no Inter as the design choice, no even-weighted accent grids, no SaaS-default chrome).scripts/fetch_sitemap.py — step 1a: home + sitemap + nav-links + JSON-LD.scripts/fetch_pages.py — step 1c: batch-fetch a URL list with full per-page probes.scripts/enumerate_assets.py — step 1d: aggregate all probes into raw-assets.json with stable candidate ids.scripts/embed_logo.py — step 1f: navigate-to-asset-then-same-origin-fetch + quality-gate + base64-embed the chosen logo. Handles cross-origin CDN (Contentful, Cloudinary).scripts/setup.py — Phase 0 dependency check.evals/ — quality contract directory (see evals/README.md). Two layers in one folder:
evals/evals.json + evals/trigger_evals.json — marketplace harness contract (Anthropic skill-eval format).evals/hard_checks.py + evals/rubric.json + evals/build_report.py — Layer 2 runtime auto-eval invoked by Phase 4-5 (cross-platform Python; no shell wrapper).evals/run_phase_a.py — Layer 1 multi-brand panel orchestrator (skill author use only, not part of the runtime path).tests/ — unit + integration + smoke tests.