mcpField
M
make-deck

make-deck

github.com/bluzir文档处理10754 次安装27 周前更新
代码仓库

关于 make-deck

make-deck 是用于生成 HTML 幻灯片演示文稿的技能,面向需要制作设计统一且可验证的演示文稿的用户。它包含设计上下文检测、版式预算和溢出检查流程,并支持演讲者备注与导出流程。

主要功能

  1. 01检测项目与品牌设计上下文
  2. 02构建 HTML 幻灯片
  3. 03规划版式与垂直空间
  4. 04按信号决定演讲者备注
  5. 05检查溢出并验证布局
  6. 06提供导出与后续编辑流程

适用场景

  1. 01根据项目设计令牌制作演示文稿
  2. 02将长文档内容整理为带备注的幻灯片
  3. 03检查幻灯片内容是否溢出画布
  4. 04将 HTML 幻灯片导出为 PDF 或 PPTX

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/bluzir/claude-code-design --skill make-deck

安装后在 Claude Code 中输入/make-deck确认已加载。

详细介绍

制作幻灯片

构建一套经过精心设计、而非看起来像 AI 生成的 HTML 幻灯片。使用 starters/deck_stage.js 实现键盘导航、缩放、演讲者备注和打印为 PDF。

阶段 0 — 上下文预检(自动检测,最多提问 1 次)

提出设计问题之前,先通过自动检查静默检测上下文。只有在没有发现任何信息时,才询问用户。

自动检测(无需用户输入)
  1. Read .claude/design-tokens.json — 如果存在,则加载项目设计令牌
  2. Bash(ls ~/.claude/design-systems/ 2>/dev/null) — 组织级注册表。如果需求中提到的品牌名称与某个文件夹匹配,则自动应用该设计系统(例如,需求中提到“Acme deck”,且存在 ~/.claude/design-systems/acme/ → 使用 Acme)
  3. 在项目根目录执行 Glob **/tailwind.config.* **/theme.{ts,js,json} **/tokens.{css,scss} **/_variables.* — 如果找到文件,则记录“检测到代码库”并 Read 这些文件
  4. 扫描用户消息/附件,查找:
    • GitHub URL → 先调用 Skill: ingest-github
    • Figma URL → 先调用 Skill: ingest-figma
    • 图像附件 → 先调用 Skill: ingest-screenshot
    • 附加的 .md / .txt / .pdf 文件 → Read 文件(其中可能包含品牌参考或内容)
单问题回退方案(仅当未检测到任何信息时)

如果自动检测后仍未找到上下文,则使用 AskUserQuestion 提出一个问题,选项为文本:

  • 使用现有设计系统 — 列出 ~/.claude/design-systems/ 中的名称(如有)
  • 来自代码库 — “粘贴本地路径或 github URL”
  • 来自截图 — “附加图像”
  • 来自 Figma — “粘贴 figma URL(需要 FIGMA_TOKEN)”
  • 无上下文 — 调用 Skill: frontend-design,从零开始设计美学风格
  • 替我决定 — 由 Claude 选择 frontend-design

用一行报告找到或选择的内容:“正在使用。继续……”

阶段 1 — 模糊性检查

检查用户的需求($ARGUMENTS),查找以下信号:

  • 受众 — “面向 X”“面向投资者”“团队”“利益相关者”等
  • 风格 — 指定的美学风格(“New Yorker”“WSJ”“极简”“醒目”“类似 Apple”)或品牌参考
  • 长度 — “N 张幻灯片”“简短”“快速”

如果三项中至少有两项 → 跳过长问卷,最多提出 1–2 个澄清问题后继续。

如果少于两项 → 调用 AskUserQuestion,询问:

  • 受众(谁会观看、情绪状态、技术水平)
  • 语气(正式/随意、幽默/严肃)
  • 长度(幻灯片数量)
  • 视觉效果(简约/丰富、照片/插图/图表)
  • 方案选择(是否需要 2–3 套幻灯片方案,还是只要一套)

即使通过模糊性检查,只要仍有不明确之处,也至少提出 4 个相关问题。不要询问品牌背景——阶段 0 已处理。

阶段 1.5 — 演讲者备注启发式判断(由 Agent 决定,不提供开关)

不要询问用户“是否使用演讲者备注?”,而是根据以下信号判断:

需求中的信号→ 演讲者备注
“快速”“站会”“闪电演讲”“回顾”,或少于 100 个字符关闭 — 幻灯片内容完整自足,不添加备注
“面向投资者”“董事会会议”“主题演讲”“全员大会”开启 — 幻灯片内容精简,由备注承载叙述
附有 PRD/长文档(超过 500 词)开启 — 幻灯片提炼内容,备注提供讲稿
只要求 1–3 张幻灯片关闭
要求 10 张或更多幻灯片开启(可能需要故事线)
模糊/以上信号都没有提出一个是/否问题

如果开启:在 <body> 末尾生成 <script type="application/json" id="speaker-notes">[...]</script>,每张幻灯片对应一个字符串——采用完整、自然的口语叙述,而非项目符号摘要。幻灯片应以视觉内容为主。

如果关闭:完全跳过备注;幻灯片必须独立成篇。

阶段 2 — 视觉系统

根据阶段 0 收集的上下文,预先确定视觉系统:

  • 章节标题版式、主标题版式、图像版式
  • 整套幻灯片最多使用 1–2 种背景颜色
  • 字体层级(展示字体/一级标题/正文/说明文字)
  • 配色方案(使用已加载的设计令牌,或通过 Skill: frontend-design 生成)

撰写幻灯片之前,先用一段话说明视觉系统。

阶段 3 — 构建

  1. 使用 shell 创建 artifacts/<slug>.html:
    <!doctype html>
    <html lang="en">
    <head>
      <meta charset="utf-8"/>
      <title>{{deck title}}</title>
      <script src="./deck_stage.js"></script>
      <style>/* your tokens + slide styles */</style>
    </head>
    <body>
      <deck-stage width="1920" height="1080">
        <section></section>
        ...
      </deck-stage>
    </body>
    </html>
    
  2. Bash(cp starters/deck_stage.js "$(dirname <html>)/") — 将 starter 复制到 与 HTML 相同的目录(对于 artifacts/foo/deck.html 这类嵌套路径尤其重要)
  3. 一次性编写所有幻灯片。规则:
    • 第 1 张幻灯片不能只有标题(直接进入内容)
    • 在 1920×1080 画布上,文本字号 ≥ 24px
    • text-wrap: pretty
    • 使用 CSS Grid 布局
    • 不使用渐变、表情符号或 Inter/Roboto/Arial — 选择有特色的字体
    • 不使用 SVG 绘制图像 — 改用带标签的占位 div
    • 在幻灯片间变换布局节奏(不要全部使用同一模板)
  4. 演讲者备注:遵循阶段 1.5 的决定 — 不要再次询问。
3.1 垂直空间预算 — 编写前先计算(!)

<deck-stage> 区段设置了 overflow: hidden — 溢出在视觉上不会提示,超出的内容会直接消失。必须提前做好垂直空间预算。

每张幻灯片的典型 chrome 布局会占用 1080px 画布约 430px:

项目预留空间
区段顶部内边距96px
Chrome 行(绝对定位,但有视觉分量)24px
Kicker 上边距 + Kicker44 + 22 = 66px
h2.section-title(字号 80–96px × 2 行)~200px
h2 下边距36px
内容网格上边距16px
区段底部内边距96px
预留空间总计~430px

内容预算:1080 − 430 = ~650px。 内容区内的主要卡片、行或媒体容器都必须在此范围内。

严格限制,确保布局合理:

  • 主要卡片 min-height:≤ 500px
  • 模拟界面之后的内容列/深度内容列 min-height:≤ 620px
  • 解剖结构行最多 5 行,每行约 110px;或 4 行,每行约 130px
  • 简短的 h2(1 行,≤ 60 个字符)→ 可多出 140px 预算;较长的 h2(2 行)→ 按 200px 计算
  • 如果需要更高的内容,请移除 Kicker,或将 Kicker 与 h2 合并到一行 — 不要让卡片变高

如果某张幻灯片显得太拥挤 — 拆分内容,或删减内容。溢出是设计问题,不是字体排版问题。

3.2 俄语/长词连字符处理

在 <section> 上设置 hyphens: manual; -webkit-hyphens: manual;,以防浏览器在单词中间插入软连字符(这会导致较窄列中的俄语长单词被拆行)。

阶段 4 — 验证

  1. /done artifacts/<slug>.html — 在浏览器中打开,检查控制台并保存截图

  2. 修复所有错误;反复运行,直到没有问题

  3. 必须执行程序化溢出审计(如果任何幻灯片溢出或空间过紧,将无法结束本轮):

    // Paste into mcp__chrome-devtools__evaluate_script
    async () => {
      const stage = document.querySelector('deck-stage');
      if (!stage) return { skipped: 'no deck-stage' };
      // Decoratives we deliberately ignore (bleed past section bounds by design):
      // glow halos, hero backdrops, chrome overlays, anything flagged data-decorative.
      const DECORATIVE = '.glow, .glow-2, .hero-glow, .chrome, [data-decorative], [aria-hidden="true"].backdrop';
      const isDecorative = (el) => {
        if (el.matches(DECORATIVE) || el.closest(DECORATIVE)) return true;
        const cs = getComputedStyle(el);
        // pointer-events:none + no text + low opacity → visual decoration, skip
        if (cs.pointerEvents === 'none' && !el.textContent?.trim() && parseFloat(cs.opacity) < 1) return true;
        return false;
      };
      const out = [];
      for (let i = 0; i < stage.totalSlides; i++) {
        stage.goToSlide(i);
        await new Promise(r => setTimeout(r, 80));
        const s = stage.querySelectorAll('section')[i];
        const sRect = s.getBoundingClientRect();
        const scale = 1080 / sRect.height;
        // Measure ALL elements (including position:absolute like .arrow-between, .save-cta,
        // .footer-row that ARE meaningful content) — only decoratives are skipped.
        let maxBottom = 0, culprit = null;
        for (const el of s.querySelectorAll('*')) {
          if (isDecorative(el)) continue;
          const cs = getComputedStyle(el);
          if (cs.display === 'none' || cs.visibility === 'hidden') continue;
          const r = el.getBoundingClientRect();
          if (r.height === 0 && r.width === 0) continue;
          const b = (r.bottom - sRect.top) * scale;
          if (b > maxBottom) { maxBottom = b; culprit = el.className?.toString?.().slice(0, 40) || el.tagName; }
        }
        const contentBottom = Math.round(maxBottom);
        const overflow = contentBottom - 1080;
        const headroom = 1080 - contentBottom;
        const status = overflow > 0 ? 'FAIL' : headroom < 40 ? 'WARN' : 'OK';
        out.push({ slide: i + 1, contentBottom, overflow, headroom, status, culprit });
      }
      stage.goToSlide(0);
      return out;
    }
    
    • FAIL(overflow > 0)— 内容被裁切。不要声称已完成。 缩小卡片、字体或内边距,然后重新运行。
    • WARN(headroom < 40px)— 内容在视觉上过于贴近边缘(字体度量稍有变化就可能导致裁切)。目标是至少留出 60px 的余量。
    • OK — 可以交付。

    常见修复方法:减小卡片的 min-height,缩小标题字号,删去一行,合并 Kicker 和标题,缩小垂直间距。

    如果浏览器显示溢出,但此脚本检测不到,请通过绕过缓存强制重新加载:mcp__chrome-devtools__navigate_page({ type: "reload", ignoreCache: true })。这类不一致大多是因为最新一次 Edit 之前的 CSS 状态被缓存。

  4. 在后台静默调用 Skill: verify-artifact(检查布局视觉效果 — 检测到 <deck-stage> 时会自动处理每张幻灯片的截图)

  5. 在本轮结束摘要中引用 .claude/last-preview.png

阶段 5 — 提供后续选项

  • /export-pptx artifacts/<slug>.html — 通过截图生成原生 PPTX
  • /export-pdf artifacts/<slug>.html — PDF
  • /export-standalone artifacts/<slug>.html <dist>.html — 单文件离线 HTML
  • /register-asset artifacts/<slug>.html — 添加到 assets.html 概览
  • 演讲者备注模式 → 添加 <script type="application/json" id="speaker-notes">[...]</script>
  • 可调整模式 → /make-tweakable artifacts/<slug>.html

反模式 — 严禁使用

  • 首先展示标题幻灯片
  • 填充内容
  • AI 生成的劣质卡片样式(圆角 + 左侧边框强调)
  • 通用渐变背景
  • 编造数字或统计数据
  • 编造颜色(使用 oklch() 与现有调色板协调)

评论

支持 Markdown