建立 16:9 的 HTML 投影片簡報,並匯出為 PDF(非 PowerPoint 格式)。 適用於製作簡報、提案或演講(例如:X 的 10 頁募資簡報、Y 的培訓課程、季度成果報告)。
Slide Creator — HTML → PDF 簡報
將 HTML 投影片簡報透過無頭 Chromium 匯出為像素完美的 16:9 PDF。
輸出格式:PDF — 非 Microsoft PowerPoint (.pptx)。PDF 可在所有裝置上保留精確的版面、字型和顏色。
為什麼用 HTML → PDF
- CSS 版面(Grid/Flexbox)遠比任何 PPT 編輯器靈活
- 完整的網頁排版、漸層、SVG、動畫(列印時優雅降級)
- 適合 Git 管理、可重現、可腳本化
- 一個指令即可產生精確 16:9 頁面尺寸的 PDF
工作流程
0. 識別場景(新增)
在進行任何其他步驟之前,先識別簡報場景。請參閱 references/content-scaffolding.md 取得完整範本。
| 場景關鍵字 | 使用的範本 |
|---|---|
| pitch / investor / fundraising | pitch-deck |
| conference / keynote / summit / talk | conference-keynote |
| product launch / launch event | product-launch |
| report / research / analysis | research-report |
| (以上皆非) | 詢問使用者最適合的場景 |
每個範本定義:投影片數量、頁面標題、每頁所需內容。
0.5 雙語版面(如有需要)
如果觀眾是雙語(例如香港、新加坡、全球華語會議),或使用者提到中文 + 英文:
- 使用
references/content-scaffolding.md中的bilingual版面模式 - 標題:英文(大)+ 中文副標題(較小,使用 --text-muted)
- 內文項目:中文優先,英文可選用括號補充
- 避免為港/台/星/雙語觀眾製作純英文簡報
1. 規劃簡報
根據場景範本定義投影片數量和每頁內容。每張投影片 = 一個 <section class="slide">。
1.5 美術指導(在建立之前執行)
當使用者未提供特定視覺風格時,請執行此步驟。
請參閱skills/slide-creator/references/art-direction.md取得完整風格分類、
CSS token 範本和風格簡報輸出格式。
步驟 A — 詢問 4 個問題:
- 觀眾與場合:簡報對象是誰,以及什麼情境(投資人 / 內部團隊 / 公開演講)?
- 情緒關鍵字:希望觀眾有什麼感受(權威 / 活力 / 友善 / 極客現代)?
- 品牌限制:是否有任何品牌顏色、標誌或字型要求?
- 參考素材:是否有任何範本參考可對齊(圖片、網頁連結、現有簡報截圖)?
步驟 B — 產生視覺風格挑選頁面:
請勿以文字描述呈現風格選項 — 使用者無法僅從文字評估風格。
參考素材處理規則:
- 如果使用者提供 圖片檔案/截圖:從視覺中取色樣(主色/表面色/強調色)、檢查版面密度、圓角半徑、字型調性。
- 如果使用者提供 網頁 URL:使用
web_fetch提取設計線索。關鍵 — 請遵循此提取協議,避免誤讀風格:- 忽略品牌名稱/網域名稱 — 切勿從產品的產業或名稱推斷視覺風格(例如 "Neo" 不代表霓虹,"Opera" 不代表歐洲奢華)。
- 閱讀文案調性與詞彙 — 頁面上使用的文字揭示情緒(例如 "surgical precision"、"quiet confidence" → 內斂;"unleash"、"radically" → 大膽/激進)。
- 提取明確的顏色詞彙 — 在擷取的文字中尋找 CSS 關鍵字,或內文/替代標籤中提到的顏色名稱。暖色 vs 冷色、淺色 vs 深色、柔和 vs 飽和。
- 推斷版面密度 — 計算每區塊的字數;稀疏 = 編輯/奢華,密集 = 技術/功能。
- 識別裝飾主題 — 提到或暗示的(例如幾何、漸層、攝影、插圖、線條藝術、粗獷主義)。
- 對照 art-direction.md — 找到最接近的範本,然後描述差異(例如 "風格 G 但更暖,將藍色換成焦橙色,加入細微的網格線")。
- 不確定時:保守為上 — 低調描述風格匹配,並提供 3 個選項,其中選項 A 是最佳解讀,B 更安全/簡潔,C 更具實驗性。切勿自信地斷言與實際視覺證據矛盾的風格。
- 如果使用者同時提供兩者:優先處理圖片線索,其次 URL 線索。
- 如果未提供任何參考:使用內建風格分類預設值。
然後:
- 建立
output/style-picker/index.html— 一個包含 3 個並排迷你投影片預覽(16:9 比例)的頁面,每個預覽都使用真實 CSS(顏色、字型、版面、裝飾元素)完整渲染。每個預覽必須看起來像實際的投影片,而非色票。 - 將這 3 個選項建構成:(A) 忠於參考、(B) 較安全的企業變體、(C) 更大膽的創意變體。
- 使用
preview(action='serve')提供目錄服務,並顯示預覽 URL。 - 每張卡片下方有標籤:風格名稱 + 一行描述。
- 加入
onclick高亮,讓使用者可以點擊表示選擇。
使用者透過說「選 A」/「我要 B」/「混合 A+C」等方式選擇。
步驟 C — 產生 style-brief.md:
一旦使用者選定風格,在專案目錄中撰寫 style-brief.md(範本在 art-direction.md 中)。
所有後續的 HTML/CSS 工作都必須遵循此簡報。
步驟 D — 詢問品牌資產(標誌/顏色):
在使用者選定風格後,詢問:
「您有要加入的標誌或品牌顏色嗎?您可以上傳圖片檔案,我會將標誌嵌入到所有投影片中。」
如果上傳標誌:在 HTML 中以 base64 嵌入(在 bash 中使用 base64.b64encode),放置在左上角或右上角,高度 ≤60px。
如果提供品牌顏色:在 CSS token 區塊中以使用者的顏色覆蓋 --accent。
2. 選擇主題
如果已完成美術指導,則 style-brief.md 即為主題規格 — 跳過此表格。
否則,作為快速備用方案:
| 風格 | 背景 | 強調色 | 字型 | 情緒 |
|---|---|---|---|---|
| 深色科技 | #000 / #0a0a0a |
亮橘/藍/綠 | Inter, Space Grotesk | 大膽、現代 |
| 淺色簡潔 | #fff / #f8f8f8 |
海軍藍、青綠、珊瑚色 | Inter, DM Sans | 專業、極簡 |
| 漸層 | 深色漸層 | 鮮豔強調色 | 任何無襯線字型 | 創意、活力 |
| 企業 | #1a1a2e / 白色 |
品牌色 | 系統字型 | 可信賴、正式 |
| 活潑 | 柔和粉彩 | 溫暖流行色 | Nunito, Poppins | 友善、休閒 |
3. 建立 HTML + CSS
建立一個專案目錄,包含 index.html + styles.css。
從 assets/base.css 開始 — 結構骨架(投影片尺寸、列印規則、版面輔助),不含顏色或字型。然後疊加你的主題:
/* 主題層範例 — 可自由自訂 */
body {
font-family: 'Inter', sans-serif;
color: #fff;
background: #000;
}
.slide { background: #0a0a0a; }
.slide-tag { background: rgba(0,120,255,0.15); color: #0078ff; }
.card { background: rgba(255,255,255,0.04); border: 1px solid rgba(255,255,255,0.08); }
強制性結構規則(在 base.css 中 — 請勿移除):
.slide { width: 1280px; height: 720px; page-break-after: always; overflow: hidden; }
@page { size: 1280px 720px; margin: 0; }
關鍵規則:
- 使用
px單位 — 投影片尺寸切勿使用vh/vw/rem/% - Google Fonts:在
<head>中使用<link>,匯出腳本會等待網路閒置 - Viewport meta:
<meta name="viewport" content="width=1280"> - 內容必須在 720px 高度內 — 超出部分會被裁切
4. 預覽(可選)
在匯出前使用 preview(action='serve') 在瀏覽器中預覽。
5. 匯出為 PDF
python3 skills/slide-creator/scripts/export_pdf.py --dir <專案目錄> --output output/<名稱>.pdf
選項:
--dir— 包含index.html的目錄(必要)--output/-o— 輸出 PDF 路徑(預設:<dir>/deck.pdf)--width— 投影片寬度(px,預設:1280)--height— 投影片高度(px,預設:720)
6. 驗證
腳本會列印投影片數量並確認輸出路徑。額外檢查:
import fitz
doc = fitz.open("output/deck.pdf")
print(f"頁數: {doc.page_count}")
for p in doc:
r = p.rect
print(f" {r.width*96/72:.0f}x{r.height*96/72:.0f}px")
風格指南
- 無預設品牌 — 每份簡報都會獲得量身定制的主題
- 優先採用美術指導優先的工作流程(問題 → 參考 → 使用者選擇 →
style-brief.md) - 詢問使用者偏好:深色/淺色、強調色、字型、情緒
- 每張投影片應有清晰的視覺層次:標籤 → 標題 → 內容
- 保持文字簡潔 — 投影片是視覺化的,不是文件
- 使用
.bg-glow搭配主題色的放射狀漸層增加深度 - 預設情況下不要使用
web_search進行風格探索;優先使用使用者提供的參考圖片/連結以及art-direction.md中的範本。 - 當使用者提供參考連結時,使用
web_fetch提取設計線索(色調/語調/版面),但最終使用本地範本和 token 變數實作 CSS。 - 當使用者要求「美術指導建議 / 風格建議」時,務必產生視覺風格挑選預覽頁面(3 個選項)— 切勿僅依賴純文字描述。
- 嚴格根據所選風格簡報建立 HTML,然後匯出 PDF(除非使用者明確選擇退出,否則不要跳過簡報)
- 風格選定後,在建立之前務必詢問標誌/品牌資產
- 對於港/台/星/雙語觀眾,預設使用雙語版面,除非使用者表示僅需英文
風格微調(風格選定後)
如果使用者說「將主色改為紅色」/「更換字型」/「增加圓角半徑」,請勿重新開始美術指導。
而是直接在 styles.css 中修改 --accent / --font-head / --radius CSS 變數。
只有當使用者想要完全不同的風格時,才重新開始美術指導。
注意事項
-
Chromium:在容器啟動時透過
workspace/setup.sh預先安裝(約 641 MB 快取於~/.cache/ms-playwright/)。請勿在每次匯出時執行playwright install— 它會重新下載相同的瀏覽器。僅在export_pdf.py失敗並顯示Executable doesn't exist時執行,並在該情況下也將指令附加到workspace/setup.sh以便持久化。 -
字型:Google Fonts 需要 HTTP — 匯出腳本會自動啟動本地伺服器
-
表情符號渲染:無頭 Chromium 可能缺少表情符號字型 — 請改用 SVG 圖示
-
大圖片:以 base64 嵌入或使用相對路徑(本地伺服器提供專案目錄服務)
-
投影片溢出:超過 720px 高度的內容會被裁切 — 請在範圍內設計
-
⚠️ PDF 文字無法選取(2026 年驗證):在包含文字的任何祖先元素上使用
filter/backdrop-filterCSS 會導致 Chromium 在 PDF 匯出期間將該圖層點陣化為點陣圖 — 所有子文字變成像素,無法選取。修正:切勿對包含文字的容器套用filter/backdrop-filter。僅套用於空的裝飾性<div>元素(例如.blur-layer、.glow-overlay),且這些元素沒有文字子元素。同樣的規則也適用於文字父元素上的mix-blend-mode。匯出前檢查清單:在 HTML 中搜尋非裝飾性元素上的filter/backdrop-filter並移除。 -
⚠️ 頁尾 / 來源歸屬 — 使用標準元件 + 嚴格的底部安全區域約定(2026 年驗證):臨時頁尾標記會導致投影片間定位不一致。請一律使用此
.slide-footer模式來處理所有來源引用、頁碼和免責聲明。硬性版面約定(請勿跳過):
- 每張非封面投影片必須有一個專用的內容包裝器(例如
.slide-body),為頁尾保留空間。 - 硬性規則:
.slide-body必須透過底部安全區域>= 96px(預設 96px)來保留頁尾空間。範例:.slide-body { padding: 52px 72px 96px; }。 - 頁尾必須在正常流程之外:
position: absolute; bottom: 24px,作為.slide-body的同級元素,直接位於.slide之下。 - 切勿將來源/免責文字放在
.slide-body內部。 - 封面頁只有在沒有
.slide-footer時才可例外。
這強制了物理分離:主體內容區域在保留的頁尾通道上方結束,而頁尾保持在畫布底部通道,因此無論內容密度如何,它們都不會重疊。
<footer class="slide-footer"> <span class="footer-source">來源:CoinGecko · Coinglass · DefiLlama</span> <span class="footer-page">03 / 12</span> </footer>.slide-footer { position: absolute; bottom: 24px; left: 48px; right: 48px; display: flex; justify-content: space-between; align-items: center; font-size: 11px; color: rgba(255,255,255,0.35); border-top: 1px solid rgba(255,255,255,0.08); padding-top: 8px; z-index: 2; } .slide > *:not(.bg-glow):not(.slide-footer) { position: relative; z-index: 1; } .slide-body { padding-bottom: 96px; }切勿使用內聯 /
position: relative頁尾 — 它們會在投影片內容高度變化時移動。同時將.slide-footer排除在通用.slide > *堆疊規則之外,否則 CSS 順序可能意外覆蓋頁尾分層。
驗證檢查清單(匯出前必要):- 每張非封面投影片都有
.slide-body和.slide-footer作為同級元素; .slide-body底部內距為>=96px;- 來源/免責文字僅出現在
.slide-footer內部,絕不在主體容器中。
- 每張非封面投影片必須有一個專用的內容包裝器(例如
-
⚠️ z-index / 裝飾覆蓋層錯誤(2026 年驗證):
.bg-glow和其他裝飾性偽圖層必須以z-index: 0定位,所有實際投影片內容必須明確給予z-index: 1。如果.bg-glow是.slide > *的同級元素(而非::before/::after偽元素),請加入此規則以確保內容不會在視覺上被埋沒:.slide > *:not(.bg-glow) { position: relative; z-index: 1; } .bg-glow { position: absolute; z-index: 0; pointer-events: none; }失敗模式:PDF 匯出顯示內容被推到底部或不可見,即使瀏覽器預覽看起來正常(瀏覽器合成處理 z 順序比 Chromium 的列印路徑更寬容)。






