Remotion 口播包裝設計系統(v1 hub)
風格目標:復刻基準片的口播 HUD 包裝(參考圖庫在專案 refs/)。本檔案是硬約束 hub:鐵律 + tokens 語意 + 元件速查 + 錯題集;板塊細則在 references/(2026-07-16 深度對比 77 條差距的沉澱落點)。沒有寫在體系裡的視覺決策,先補充進對應板塊檔案再寫程式碼。
板塊路由表(做什麼讀哪個檔案)
| 板塊 | 檔案 | 管什麼 |
|---|---|---|
| 規格表(先查再寫) | references/specs.md | 基準片實測數值真源:卡寬/字型大小/位置/動效幀數裝配前必查,表裡沒有才現測並回填,禁止目測 |
| 版式構圖 | references/layout.md | 三區、takeover 機制(A 級不帶 PiP、壓暗升格已否決)、一螢幕一重心、編組模板、咬合位 |
| 字型排版 | references/typography.md | 唯一最大字、h1 義務、hero 三明治、SideLabel title 變體 |
| 色彩質感 | references/texture.md | 果凍塊/glow、SURFACE 亮暗變體、印章規格唯一線、同螢幕色系 ≤2、亮面禁裸字細則 |
| 動效 | references/motion.md | useEnter/useExit、分拍、build-up、服役區間、Breathe、淨屏 |
| 資訊設計 | references/infographic.md | 圖表選件、比喻圖形化、waffle、大數字三層、微圖形詞彙 |
| 敘事/節奏/字幕/素材/聲音 | remotion-assembly 的 references/ | narrative / rhythm / subtitle / broll / audio |
| 錯題集(症狀→修法索引) | 獨立 skill remotion-gotchas-index | 全文「錯題 #NN」的修法位置查這裡;渲染異常/畫面不對先查 |
工程底座清單(substrate —— 冷啟動 / 新片起步前先確認在位)
本設計系統是全倉共享的底座,不是每片重建。下列檔案是整套流程(assembly「輸入驗收→出幀→三道閘」+ motion §12 門控)的運行前提;一個新片預設複用它們,只新增自己的 composition + 字幕 + Scene,不重造底座。冷啟動讀者(禁讀 src/)常在此撲空——先按此表確認檔案在位、要取具體數值就打開對應檔案讀,別指望 skill 抄給你。
| 底座檔案 | 裝的什麼 | 冷啟動怎麼用 |
|---|---|---|
src/design/tokens.ts | 數值唯一真源:COLOR(四語意 + 基礎色 hex)、SURFACE、FONT、GRADIENT、SIZE 階梯(kicker…mega)、GRID、RADIUS、SAFE、MOTION 幀數 | 要 SIZE.mega、語意色 hex 等具體像素/顏色,直接讀這個檔案取——skill 故意不抄(防快照與程式碼漂移,見 §1);檔案不在=底座缺失,先建底座 |
src/design/*.tsx | 元件庫(§3 全表:SideLabel/HeroText/Chip…)+ FontGuard.tsx(字型門衛,錯題 #01)+ qc.tsx(QC 探針 QcProbe:逐幀讀 [data-qc] 盒判重疊,錯題 #29) | 寫包裝元素前查 §3 元件表定位檔案 |
src/design/motion.ts | useEnter/useExit/usePop 底層 hook + MOTION 常數 | motion.md 規則引用的 hook 都在此 |
src/design/fonts.ts | @fontsource 本地字型註冊(錯題 #01:webfont 走網路會靜默出宋體) | package.json sideEffects 必含它 |
src/koubo/scenes/shared.tsx | 裝配層門控四件套 Enter/DimAfter/Exit/ClearOut(motion §12)+ Place 定位盒 + qcAllow QC 咬合白名單(assembly §2.5 閘①) | 裝配寫 Scene 直接套這些包裝器,勿手搓 opacity |
src/Root.tsx | composition 註冊處(現有 <Composition id="Koubo-0715-01" fps={30} …/>) | 新片在此加一條 <Composition>,id 自定;段渲腳本要對上這個 id(見 assembly §6 render-service 改 id) |
src/koubo/ | 每片專屬:subtitles-<片名>.ts / SubtitleTrack.tsx / <片名主元件>.tsx / scenes/SceneNN.tsx | 新片只在這一層新增檔案(結構見 assembly §4) |
真·從零 bootstrap(src/ 完全為空):底座在位前 assembly 流程無法起步(取不到任何 token、出不了第一幀、落不了三道閘)。順序=先建底座再談裝配:① tokens.ts 定數值真源 → ② fonts.ts + FontGuard.tsx(錯題 #01)→ ③ motion.ts 三 hook → ④ §3 元件庫 → ⑤ src/koubo/scenes/shared.tsx 門控四件套 + Place/qcAllow → ⑥ src/design/qc.tsx QC 探針 → ⑦ src/Root.tsx 註冊 composition。以本倉 src/design 為參考實現移植;移植後數值仍從 tokens.ts 讀取,不回填進 skill。
0. 六條鐵律
- 資訊區預設在左,人物在右:資訊區預設在左(使用者裁定的作者預設)、HUD 錨定左側縱向生長、人物區禁入;但每片構圖先問使用者、別自作主張,三區座標與 takeover 例外機制見 references/layout.md 規則 1。
- 一切文字雙層結構:英文 UPPERCASE 寬字距 kicker(小)+ 中文粗黑(大)。只有一層文字的元件視為未完成。
- 一句話只高亮一個詞:中文標題裡換色/強調詞最多一處,顏色必須取自四色語意系統。
- 真素材為主體,Remotion 是合成器不是繪圖板(2026-07-16 seg01 定案升級):「產品體驗」類畫面(打字/生成/介面/示範)一律真素材剪輯——自錄屏 > 官方影片 > 網頁截圖 > UI 模擬卡;手繪只做 HUD 層(側標/字幕/圖表/印章/比喻圖形)。用 CSS 手搓專業 motion 團隊的作品必敗,「怎麼調都差點意思/差很遠」的根源就是拿繪圖板打合成器的仗。採集與剪輯管線見 assembly references/broll.md。
- 亮面禁裸字(2026-07-16 深度對比裁決,橫跨 6 個板塊的頭號跨界規則):亮背景(白板/白牆/淺色接管底)上禁止無底文字——一切文字必須坐在深色底板(SURFACE.darkPlate)、卡體或 light 表面變體上,textShadow 不算方案。細則見 references/texture.md。
- 一螢幕一個主導層:每個資訊螢幕有且只有一個「最大字/最大件」,主區之外最多 2 個晶片級小元素。細則見 references/typography.md 與 layout.md。
1. Design Tokens
唯一真源 = src/design/tokens.ts,所有元件只允許 import 那裡的值。本節只寫語意與使用規則,不抄數值——此前快照與程式碼漂移過一次(2026-07-16 發現 kicker/h1 等多處對不上),以程式碼為準。
- 四色語意(唯一允許的強調色):blue=定義/方法/中性推進;green=正面/低門檻/已生效;yellow=機會/警示/爭議/轉折;red=負面/陷阱/危機。基礎色另有 white/grey/greyDim/cardBg/cardStroke。
- 字型(分兩層,別混):MG 包裝層——
FONT.zh=Noto Sans SC(包裝層中文唯一字型,標題一律FONT.zhHeavy);FONT.en=Inter(kicker/正文/數字);FONT.enTitle=Archivo Black(英文標題與大字結論,窄方超黑,weight 一律 400——Inter 撐不起大字氣勢,2026-07 字形對比結論)。底部字幕層——FONT.subZh=PingFang SC 400 /FONT.subEn=Inter 300(2026-07-26 五檔實拍對照後使用者裁定):字幕是跟讀層不是包裝層,細體才有蘋果字幕的質感,且與 MG 粗黑標題拉開層次、不搶注意力;舊版整條用 Noto 700 顯得像貼紙。PingFang SC 是 macOS 系統字型,不走@fontsource打包——本機渲染沒問題,Windows/Linux 環境會回退到打包的 Noto Sans SC 400 細檔(fonts.ts 已引入,觀感相近但非同款),跨機器渲染前先渲一幀確認字幕觀感。字幕英文行必須用比例西文字型,見錯題 #42。 - 大字結論一律純語意色 + textShadow,禁止 backgroundClip:text 漸變字(錯題 #06);
GRADIENT僅用於色塊/描邊類用途。 - 字型大小只允許用
SIZE階梯(kicker / subSmall / chip / subZh / subEn / card / h2 / h1 / mega),禁止階梯外字型大小;1080p 基準,4K 輸出等比 ×2。 - 間距一律
GRID(8px)的倍數;圓角用RADIUS;安全區用SAFE(側標錨點、堆疊左緣、字幕距底;常駐卡不越 x55%,人物禁入區/右區座標見 layout.md;字幕禁區 y>82%,左區元素底邊 ≤y840 是比 y82% 更嚴的左區硬線)。
2. 章節側標 SideLabel(全片常駐,最高優先順序元件)
- 結構:
│(4px 豎線,語意色)+ENGLISH KICKER · 中文短語(第一行,英文用 kicker 規格+語意色,中文白色 34px)+ 第二行灰色 24px 補充說明。 - 位置:固定
SAFE.sideLabel,切換時舊標籤淡出 12 幀、新標籤左滑入 15 幀。 - 命名帶編號體系:
SCENE 01、PATH 1/2/3、正反對仗(DISSOLVED·01..vsIMMUNE·01..)。 - 顏色 = 本段情緒語意,見 tokens 註解。參考:
refs/01-版式與側標/。
3. 元件規格速查(詳規格隨實現補充,先看參考圖再寫)
| 元件 | 關鍵規格 | 參考 |
|---|---|---|
| BilingualSub | 中 52 白+黑影 / 英 28 純白,底部置中,永遠在最上層 | 任意 refs |
| HeroText | kicker + 中文 h1/h2,高亮詞換語意色;變體:紅刪除線糾偏、黃筆刷底線、傾斜印章 | refs/02 |
| Chip | 黑卡 RADIUS.chip + 彩色圖示 + 34px 文字,可一處換色詞 | refs/03 |
| Checklist | Chip 縱向堆疊,逐條彈入;未啟動條目 opacity 0.35 | refs/03 |
| InfoCard | 圖示 + kicker + 44px 標題 + 藍色高亮詞 | refs/01 |
| StepList | ①②③圓圈編號 + 中文 + 英文小 kicker,逐步點亮 | refs/04 |
| FlowChain | 黑卡 + → 箭頭串聯,逐節點出現 | refs/04 |
| CompareCard | logo + 名稱 + 紅 ✕ 弱點 chip + 綠 ✓ 強項 chip,縱向堆疊 | refs/04 |
| Formula | 大字 A 符號 B(>、»、⇄、=),符號用語意色 | refs/05 |
| BigNumber | Inter 大數字 + 單位小字 + kicker;計數器用 spring 滾動 | refs/05 |
| BarChart | 資料條 8px 圓角;重點條變黃 + 頂部皇冠 chip;其餘灰 | refs/05 |
| CurveOverlay | 2–3px 黃色曲線直接疊 B-roll,右端點標註 | refs/05 |
| Timeline | 兩端點區間型 / 事件掛紅綠結果 chip 型 | refs/05 |
| ScoreBoard | 綠:紅大數字比分 | refs/05 |
| PhoneMockup | iPhone 外框 + 漸變描邊發光 + 內嵌截圖長圖滾動 | refs/06 |
| WindowCard | mac 紅綠燈 + app 圖示 + 功能 chip,內容動態 | refs/04 |
| QuoteDoc | 白底截圖卡 + 黃螢光高亮 + 黑底中文譯條浮層 | refs/07 |
| TweetCard | 頭像 + 身份 kicker + 紅色大字結論 + views chip | refs/07 |
| PersonCard | 圓頭像 + 名字 + 身份小字 + 機構 chip | refs/07 |
| Stamp | 傾斜 -8°~-6° 描邊印章字(紅/綠),蓋章動畫=scale 1.3→1 + 輕震 | refs/08 |
| MatrixIcon | 方塊矩陣圖示:紅=會被溶解陣營 / 綠=免疫陣營 | refs/08 |
| CardWall | 白色小卡 3→20 張逐張鋪滿,模擬需求爆炸 | refs/06 |
| BeforeAfter | 兩個圖示卡 + 藍色箭頭 + 下掛結論 chip | refs/04 |
| Breathe | idle 微動效包裝器:呼吸 scale ±0.6% + 浮動 ±3px,phase 錯開相位防同步;包在主主角元素外層 | src/design/Breathe.tsx |
| BrickWall | 錯縫金磚橫牆逐塊砌起 + 中央標籤,「建牆/硬性門檻」比喻 | src/design/BrickWall.tsx |
| UnitMatrix | N 組方塊矩陣逐格點亮;fillRatio waffle 模式(73% 資料場) | src/design/UnitMatrix.tsx |
| CloneCascade | 源圖示卡 + 仿品依次淡入 + 警示 chip,「被抄襲/蒸餾」比喻 | src/design/CloneCascade.tsx |
批次線 Scene 內聯件(2026-07-17 批次生產新增,尚未提升共享件)
下列件當前只活在單個 Scene 裡,標註「Scene 內聯,第二次複用時提升 src/design 共享件並補 specs 規格行」——寫新片撞到同類需求時先查這裡,別重造:
| 內聯件 | 位置 | 做什麼 | 提升條件 |
|---|---|---|---|
| DissolveGrid | scenes/Scene08.tsx | 溶解網格:會被溶解陣營方塊逐格溶散、中央 ⚡ 底板淡出後白輪廓懸空 | 第二次「陣營溶解」比喻複用時 |
| VerdictBox(決算框) | scenes/Scene17.tsx | 紅綠鏡像決算框:≈400×170 描邊空框先立 + 框內 header + 橫排 3 chip 分批入框(紅先滿綠後滿,製造「你站哪邊」懸置) | 第二次「VS 決算」升格時 |
| NamePlate + CtaBadge(CTA 徽章排) | scenes/Scene19.tsx | 片尾 CTA 底部一條橫排:名牌先落定當錨點 → 四動作徽章逐枚彈入(評論徽章末位最寬=強調) | 第二次片尾 CTA 收尾時 |
圖示規範
- 圖示一律用 lucide-react 線性 SVG 圖示,顏色取語意色(
COLOR[accent]),strokeWidth 2.5左右;禁止 emoji(彩色圓角塊與基準片的單色線性風格衝突,2026-07 第三批驗收教訓)。 - Chip / Checklist / SideLabel 的
iconprop 均接受 ReactNode:icon={<Lock size={26} strokeWidth={2.5} />}。
質感規範 → references/texture.md
果凍塊漸變、同色 glow、vignette、真 logo、SURFACE 亮暗變體、印章規格唯一線全部在 texture.md(2026-07-16 起它是質感唯一真源,本節舊文已遷走)。
4. 動效規則 → references/motion.md
useEnter/useExit、分拍入場、服役區間、Breathe、章間淨屏、禁止項全部在 motion.md(2026-07-16 起它是動效唯一真源,本節舊文已遷走;注意舊規則「舊資訊降透明常駐」已被「服役區間+退場紀律」取代)。
5. 匯出前自檢(每次渲染前跑一遍)
- grep 檢查是否有元件內聯了 tokens 之外的色值/字型大小/字型。
- 所有常駐卡是否越過 faceZone / subtitleZone。
- 每句標題高亮詞是否 ≤ 1 處;英文 kicker 是否全大寫加字距。
- 截取 3–5 個關鍵幀與 refs/ 對應參考圖並排對比,不像就說明差在哪一條 token,改 token 不改元件內聯。
6. 錯題集
#01 中文靜默退化為宋體(2026-07-15 · 設計系統首日)
- 症狀:渲染/截圖裡中文變宋體,英文正常;同一元件有時正常有時不正常(看運氣)。
- 原因:三層,最後一層才是真兇。①
@remotion/google-fonts執行時從 gstatic 拉字型,國內網路拉不到,靜默 fallback;② 中文 webfont 按 unicode-range 分包,載入與截圖有競態;③ 樹搖:package.json的sideEffects: ["*.css"]使只被副作用匯入的fonts.ts在生產打包時被整個剔除,字型 CSS 根本不在渲染 bundle 裡(document.fonts.size === 0)——Studio 開發模式不樹搖,所以「Studio 正常、渲染翻車」。 - 修法:① 字型走
@fontsource本地包(src/design/fonts.ts);②package.json的sideEffects必須包含"src/design/fonts.ts";③ 任何含文字的合成掛<FontGuard/>:load→check 循環驗證,且必須同查document.fonts.size > 0(fonts.check()在零字型註冊時會空洞返回 true),逾時直接 cancelRender 報錯,絕不靜默出宋體幀。 - 教訓:「Studio 正常、匯出翻車」優先懷疑生產打包差異(樹搖/壓縮),不是玄學競態;驗收字型必須靠 FontGuard 硬門檻,人眼靠不住縮圖。
#02 remotion still 輸出「○」= 復用舊圖
- 症狀:改了程式碼重渲,輸出檔案看起來毫無變化;命令列顯示
○而不是+。 - 修法:驗收渲染前先刪舊輸出(或渲到新檔名);必要時加
--bundle-cache=false。+=真渲染,○=可疑。 - 教訓:對比驗收必須基於確認新鮮的渲染產物,否則會誤診「修復無效」(本次因此多繞了兩輪)。
#03 縮圖對比圖會騙人
- 症狀:並排對比小圖裡中文看著像宋體,原圖實際正常。
- 修法:判斷字型/描邊細節時必須裁切原解析度區域性放大看,不要用整幀縮圖下結論。
#04 JSX 屬性字串不解析 \uXXXX 跳脫
- 症狀:
<Chip icon="\u2705" />畫面上顯示字面\u2705而不是 ✅。 - 原因:JSX 屬性的字串字面量是 HTML 式文字,不走 JS 跳脫解析;只有 JS 運算式裡的字串(
icon={'\u2705'})才解析跳脫。用指令稿批次寫 TSX 時最容易踩。 - 修法:emoji/特殊字元在 JSX 屬性裡直接寫真字元(
icon="✅");確需跳脫時寫成icon={'\u2705'}。
#06 backgroundClip: text 漸變字渲染發暗
- 症狀:大字標題用 backgroundImage 漸變 + WebkitBackgroundClip:'text' + WebkitTextFillColor:'transparent',Studio 裡尚可,渲染出圖顏色發暗發悶(亮紅變磚紅),使用者一眼否掉。
- 修法:大字結論一律純語意色
COLOR[semantic]+ textShadow;想要層次感靠陰影和字重,不靠漸變填滿。tokens.GRADIENT 僅留給色塊/描邊類用途。
#08 成片 MG 文字邊緣暈影、塗抹感(「加了 MG 畫質變差」)(2026-07-16 · 0715-01 v3)
- 症狀:使用者看成片說畫質差;放大看 MG 文字邊緣有 JPEG 蚊噪/暈影,越銳利的元素越明顯。素材本身 15 Mbps HEVC 很乾淨。
- 原因:Remotion 預設管線雙重壓縮——每幀用品質 80 的 JPEG 截圖,再以 CRF 18 壓 H264。MG 大字/細線是高頻訊號,最先出壓縮偽影。加 MG 前偽影藏在實拍紋理裡不顯眼,所以被誤診為「MG 導致畫質差」。
- 修法:
remotion.config.ts固化Config.setJpegQuality(100)+Config.setCrf(15)(本專案已設,勿回退)。體積約 +20%,渲染略慢,值得。 - 診斷法:同一幀從素材/舊成片/新引數測試段各截一張,裁同一 MG 文字區域放大並排看;先渲 5 秒測試段驗證引數再渲全片。
#09 長渲染中途消失、mp4 成殘片(2026-07-16 · 0715-01 v3)
- 症狀:渲染跑了很久後「程式還在」但產物檔案長時間不增長;或渲染無聲無息消失,留下打不開的 mp4。
- 原因:① 渲染掛在 AI 會話的子程式裡,會話重啟/退出連帶殺掉渲染(本次在 90% 處被殺);② 檢測程式用
pgrep -f "remotion render"會匹配到檢測指令稿自身(命令列裡含同樣字串),造成「程式還活著」的假象。 - 修法:① 超過幾分鐘的渲染一律
nohup npx remotion render … > /tmp/xx.log 2>&1 & disown脫離會話;② 完成判據認日誌裡的+ 輸出檔名行(+=真渲染成功),不認程式存在性;③ 檢測程式要排除自匹配(看 CPU 佔用或用精確 PID);④ 重渲前刪掉殘片。 - 教訓:殘片 mp4(時長/體積對不上)絕不交付,先
ffprobe驗時長與音軌再給使用者看。