1仕組みと動作原理
本書が管轄するのは特定トランジションの実装ではなく「あらゆるトランジションが正しく合成されるための前提条件」です。個別のトランジションカタログは transition registry にあり、本書はその下層にある共通ドクトリンのみを扱います(crossfade / push-slide / zoom-through / cut-the-curve などのカタログは別リソースに存在)。
This is the **render-correctness doctrine** for PLV scene-to-scene seams: the prerequisites and master-timeline mechanics that make any transition composite correctly, independent of which specific transition is chosen. The per-transition catalog (crossfade, push-slide, zoom-through, cut-the-curve, …) lives in the transition registry — this page is the doctrine that sits underneath all of them.
白フラッシュ防御(正確性に関する中核的課題):一部のトランジションでは2つのラッパーの不透明度合計が1未満になる区間が発生します。#root に不透明な背景色が指定されていない場合、レンダラーはこの「窪み」をデフォルトの白ページと合成してしまい、接合部ごとに白い閃光が発生します(ダークトーンの映像では特に目立ち、作者の記録では Spotify 案件で2回観測)。
Several templates open a window where the two wrappers' summed opacity < 1 (the cut-the-curve mid-window cut, zoom-through's 0.15 floor, plain crossfade's power-curve dip). Whatever is BEHIND the wrappers shows through during that window. If the assembled `index.html` `#root` has no opaque background, the renderer composites the dip over its default **white** page → a white flash at every seam, glaring on dark films (observed on two Spotify runs before the fix).
修正は必須の前提条件:#root に不透明な背景色を塗布し、assemble-index.mjs がその出力を担保すること。これらのテンプレートを利用する他のコンシューマも同等の保証を自己責任で行う必要があります。
**The assembler must paint the stage:** `#root { background: var(--canvas-deep, var(--canvas, #000)) }` — `assemble-index.mjs` now emits this; any other consumer of these templates owns the same guarantee.
インジェクターによるトランジション適用の4ステップ機構:退場ラッパーの data-duration を延長(最終フレームを静止)→ 入場ラッパーの data-start を前倒し(オーバーラップ区間を生成)→ 全クリップの data-track-index を 0/1 のピンポンに再配置(同トラックの重複は不可、上位トラックが前面)→ T=オーバーラップ開始位置で window.__timelines["main"] に gsap_template を注入。
1. Extends `#el-<from>` wrapper `data-duration` by `duration_s` (holds its final frame — verified: `core/src/runtime/init.ts:1393-1410` external-slot branch). 2. Pulls `#el-<to>` wrapper `data-start` earlier by `duration_s` (creates the overlap window). 3. Reassigns **all** clip `data-track-index` as a 0/1 ping-pong so the two overlapping wrappers never share a track (same-track overlap is illegal — `core/src/lint/rules/composition.ts`). Higher track composites on top. 4. Stamps the `gsap_template` into `window.__timelines["main"]` at `T = overlap-start`.
適用範囲の厳密な定義:Tier-B-ready(オーバーレイDOMの注入やシーン側の協調を必要とせず、2つのシーンラッパーに対する純粋な transform/opacity/filter 操作のみを行うもの)のトランジションのみを対象とします。オーバーレイ系(staggered blocks、blinds、light leak、grid dissolve、page burn)やシェーダートランジションは次フェーズへ明示的に延期されています。
The transitions this doctrine governs are **Tier-B-ready**: pure transform / opacity / filter on the two scene **clip wrappers** (`#el-<sid>`), no injected overlay DOM, no per-scene cooperation. Overlay families (staggered blocks, blinds, light leak, grid dissolve, page burn) and shader transitions are deferred to later phases.
テンプレートプレースホルダーの規約:__OLD__ / __NEW__(引用符付きラッパーセレクタ)、__T__(マスタークロック上のオーバーラップ開始点)、__DUR__(該当接合部の duration_s)、__DX__ / __DY__(方向ごとの変位 ±1920 / ±1080)、__ORIGIN_OUT__ / __ORIGIN_IN__(squeeze 用の transformOrigin ペア)。
| `__OLD__` | `"#el-<from>"` — outgoing clip wrapper selector (quoted) | | `__NEW__` | `"#el-<to>"` — incoming clip wrapper selector (quoted) | | `__T__` | overlap-start time in seconds (master clock) | | `__DUR__` | `duration_s` for this boundary |
直感に反する結論:filter / scaleX / transformOrigin はマスタータイムライン上では lint-clean である — プロパティのホワイトリストは scene-worker のプロンプトのみを制限し、index.html は制限しないためです。
`filter` / `scaleX` / `transformOrigin` are lint-clean on the master timeline (verified: `core/src/lint/rules/gsap.ts` has no per-property whitelist and scopes its checks to `data-composition-id` ranges; the x/y/scale/rotation/opacity whitelist is a _scene-worker_ prompt rule only — it does not bind index.html).
結論に添えられた検証姿勢と実施日:プロトタイプレンダリングの実測(2026-05-31)により、マスタータイムラインのラッパー tween がシークおよびレンダリングされること(子コンポーネント自身の停止中タイムラインとの二重シークは発生せず、実行時に独立駆動)、延長されたラッパーがシーンiの最終フレームを固定すること、上位トラックの入場ラッパーが退場ラッパーと正しくオーバーラップしブレンドされることを確認済み。
Verified by prototype render (2026-05-31): the master-timeline wrapper tween is seeked and rendered (no double-seek with the sub-comp's own paused timeline — the runtime drives them independently), the extended wrapper holds scene _i_'s final frame, and the higher-track incoming wrapper composites over + blends with the outgoing one.
description に明記されたロードタイミング:マスタータイムライン / index.html の組み立て時、白フラッシュ発生時(特に暗いトーンの映像)、トランジションの不透明度の落ち込みが透ける理由を調査する際、およびオーバーラップするシーンラッパーのレンダリング側メカニズムを照合する際。
Load when assembling the master timeline / index.html, when a white flash appears at a cut or crossfade seam (especially on dark films), when reasoning about why a transition opacity dip shows through, or when verifying the render-side mechanics of how overlapping scene wrappers blend.
2コア機能
3外部依存関係
| Kind | Dependency / Endpoint |
|---|---|
| package | 同仓组件依赖:assemble-index.mjs(负责给 #root 刷底)、injector / transition registry(gsap_template 的施加方) |
| reference | 框架源码坐标(作为论证依据被引用):core/src/runtime/init.ts、core/src/lint/rules/composition.ts、core/src/lint/rules/gsap.ts |
4推奨統制措置と判定根拠
- SKILL.md: 純粋なプロンプト指示およびルール文書であり、スクリプト実行や外部影響は一切なし
5二重目の独立検証
- [discrepancy] 文档引用的源码路径在本 pin 是否真实存在(core/src/runtime/init.ts:1393-1410、core/src/lint/rules/composition.ts、core/src/lint/rules/gsap.ts) — 三处在仓库根下均**不存在**(core/src/… 无此目录)。实际已迁到 packages/ 前缀:`packages/core/src/runtime/init.ts` 存在(1393 行附近确为时长/clip 解析相关代码,可见 derivedDuration 等分支,但行号与分支名不能逐字对应 `external-slot branch`);而 `packages/core/src/lint/rules/` 目录不存在,lint 现为 `packages/core/src/lint/index.ts` 单入口。结论:这三条源码坐标是写作时点的旧路径,在本 pin 已失效——不影响其结论(白闪机制、同轨非法),但照抄坐标去查源码会扑空。属上游文档与代码结构漂移,非本 skill 的行为风险。
- [discrepancy] 「assemble-index.mjs now emits this」是否属实,且写法是否与文档一致 — 属实但表达不同。pin 内 assemble-index.mjs 共 4 份(product-launch-video / faceless-explainer / music-to-video / pr-to-video)。以 product-launch-video 版为准:它确实在 <head> 样式里输出 `#root { position: relative; … background: ${groundColor}; }`(groundColor 取自 frame.md 的 canvas 语义色),并在 html,body 上兜底 `background: #000`。而文档写的字面式样是 `var(--canvas-deep, var(--canvas, #000))`——全仓(*.ts/*.mjs/*.html)对 `canvas-deep` **零命中**,即该 CSS 变量名在当前代码里并不存在。行为目标(#root 不透明、不会白闪)一致,具体表达式已演进。
- [ok] 「白闪」结论是否只是传言 — 文档给出机理(summed opacity < 1 的窗口 + 渲染器默认白页)与经验出处(observed on two Spotify runs before the fix),并指认三个会开窗的模板(cut-the-curve 中段、zoom-through 的 0.15 下限、普通 crossfade 的 power 曲线凹坑);后在 cut-the-curve/SKILL.md 里交叉印证(zoom-through 出场透明度确为 0.15)。机理自洽、可验,接受为文档声明。
- [ok] 是否真的没有脚本/网络(green 档前提) — 目录全量仅 SKILL.md;全文 URL、curl、npx、node 调用、process.env 均零命中。文中出现的路径串(core/src/…)是文字引用,不是可执行指令。
- [ok] 「不含 per-transition catalog」的自述是否属实 — SKILL.md 正文只谈前置条件与机序,未列任何具体转场的参数(唯一出现 cut-the-curve/zoom-through 之处是在解释「谁会开出不透明度和 <1 的窗」);转场目录确实不在本目录内。
6結論
b3f716c34090b9a1…