# Edit the master timeline

> Modify the root GSAP timeline in index.html: adjust section data-start/duration, z-index stacking, seam cut times (CUT, CUT2–CUT6), and window.__timelines registration.

- Repository: heygen-com/hyperframes-launches
- GitHub: https://github.com/heygen-com/hyperframes-launches
- Human docs: https://www.grok-wiki.com/public/docs/heygen-com-hyperframes-launches-996f3eaa626b
- Complete Markdown: https://www.grok-wiki.com/public/docs/heygen-com-hyperframes-launches-996f3eaa626b/llms-full.txt

## Source Files

- `index.html`
- `compositions/chat-response.html`
- `compositions/response-scroll.html`
- `compositions/compose-tasklist.html`
- `compositions/outro.html`

---

---
title: "Edit the master timeline"
description: "Modify the root GSAP timeline in index.html: adjust section data-start/duration, z-index stacking, seam cut times (CUT, CUT2–CUT6), and window.__timelines registration."
---

The `claude-paper` master cut in `index.html` splits timing across two layers: HyperFrames reads each section’s `data-start` and `data-duration` to decide when a scene composition is active, while a paused root GSAP timeline registered as `window.__timelines["claude-paper"]` drives only the cross-section seams—opacity crossfades, inverse zoom-throughs, and leftward cut-the-curve throws. The root composition runs 53.3 seconds at 1920×1080 and stacks ten absolutely positioned section divs under `#claude-paper`.

## Responsibility split

| Layer | Owner | What it controls |
| --- | --- | --- |
| Section attributes | `#claude-paper` child divs | When each `compositions/*.html` plate loads and plays its own `window.__timelines[id]` |
| Root GSAP timeline | Bottom `<script>` in `index.html` | Seam blending between stacked sections (opacity, `scale`, `filter`, `xPercent`) |
| z-index CSS | `<style>` block in `index.html` | Paint order during overlapping visibility windows |

<Note>
The root timeline comment states it drives **only** cross-section opacity crossfades. Section visibility windows belong to the HyperFrames framework. Do not move intra-scene animation into the root timeline.
</Note>

## Section schedule

Each section div carries `data-composition-id`, `data-composition-src`, `data-start`, `data-duration`, and `data-track-index`. Overlapping `data-start` values are intentional—they reserve time for seams without black frames.

| # | Element ID | Composition ID | `data-start` | `data-duration` | End (start + duration) |
| --- | --- | --- | --- | --- | --- |
| 1 | `sec-connector` | `connector-morph` | 0 | 6.7 | 6.7 |
| 2 | `sec-chat` | `chat-response` | 6.7 | 6.9 | 13.6 |
| 3 | `sec-response` | `response-scroll` | 13.0 | 6.7 | 19.7 |
| 4 | `sec-followup` | `followup-type` | 19.4 | 6.0 | 25.4 |
| 5 | `sec-thinking` | `thinking-big` | 25.0 | 1.3 | 26.3 |
| 6 | `sec-compose` | `compose-ui` | 25.8 | 13.3 | 39.1 |
| 7 | `sec-sure` | `sure-response` | 38.8 | 0.4 | 39.2 |
| 8 | `sec-thinking2` | `thinking-big-2` | 39.0 | 1.3 | 40.3 |
| 9 | `sec-tasklist` | `compose-tasklist` | 40.3 | 9.8 | 50.1 |
| 10 | `sec-outro` | `outro` | 49.9 | 3.4 | 53.3 |

The root `#claude-paper` element sets `data-duration="53.3"`, which must equal the latest section end time (currently `49.9 + 3.4`).

```text
index.html
├── #claude-paper  (data-composition-id="claude-paper", data-duration="53.3")
│   ├── #sec-connector … #sec-outro   ← data-start / data-duration / data-composition-src
│   └── <audio> elements              ← global SFX/VO (separate schedule)
└── <script>
      rootTimeline = gsap.timeline({ paused: true })
      window.__timelines["claude-paper"] = rootTimeline
```

## z-index stacking

Sections are `position: absolute; inset: 0`. Later narrative beats sit above earlier ones so crossfades and hard cuts reveal the incoming plate on top.

| z-index | Section ID | `will-change` |
| --- | --- | --- |
| 1 | `sec-connector` | — |
| 2 | `sec-chat` | — |
| 3 | `sec-response` | — |
| 4–10 | `sec-followup` … `sec-outro` | `transform, filter, opacity` |

<Warning>
Reordering z-index without matching seam logic inverts crossfade direction. If section 3 must fade in over section 2, section 3 needs the higher z-index.
</Warning>

## Seam cut constants

Six named cut times in the root script anchor outgoing throws and incoming reveals. Each maps to a transition grammar type used across the cut.

| Constant | Time (s) | Outgoing → incoming | Seam type | Root GSAP pattern |
| --- | --- | --- | --- | --- |
| *(none)* | 6.7 | `connector-morph` → `chat-response` | Hard cut | No root tween; scenes are pixel-matched at the composer |
| *(none)* | 13.0 | `chat-response` → `response-scroll` | Opacity crossfade | 0.6s mutual fade (`power1.inOut`) |
| `CUT` | 25.2 | `followup-type` → `thinking-big` | Inverse zoom-through | Outbound `scale: 0.8`, `blur(20px)`; inbound from `scale: 1.25` |
| `CUT2` | 26.0 | `thinking-big` → `compose-ui` | Inverse zoom-through | Same pattern as `CUT` |
| `CUT3` | 38.8 | `compose-ui` → `sure-response` | Leftward cut-the-curve | Outbound `xPercent: -13`, opacity `1 → 0.55`; hard cut to inbound at opacity 1 |
| `CUT4` | 39.2 | `sure-response` → `thinking-big-2` | Inverse zoom-through | Same pattern as `CUT` |
| `CUT5` | 40.3 | `thinking-big-2` → `compose-tasklist` | Leftward cut-the-curve | Same throw pattern as `CUT3` |
| `CUT6` | 49.9 | `compose-tasklist` → `outro` | Leftward cut-the-curve | Same throw pattern as `CUT3`; aligns with download click at ~49.3s in `compose-tasklist` |

Inverse zoom-through seams use a 0.2s outbound recess (`CUT - 0.2`), a hard `set` at the cut second, then a 0.5s inbound settle with `expo.out`. Leftward cut-the-curve seams use a 0.26s outbound throw (`CUTn - 0.26`) before the hard opacity swap.

```mermaid
sequenceDiagram
  participant HF as HyperFrames runtime
  participant Root as rootTimeline (claude-paper)
  participant Out as Outgoing section
  participant In as Incoming section

  HF->>Out: activate at data-start
  HF->>In: activate at overlapping data-start
  Root->>Out: throw / recess / fade (CUT window)
  Root->>In: reveal at CUT instant
  Note over Root,In: Scene timelines run independently via window.__timelines[id]
```

Scene plates pre-position elements for these handoffs—for example `sure-response` enters at `x: 210, opacity: 0.55` to match the compose-ui throw, and `compose-tasklist` opens with `win` at `x: 210, opacity: 0.55` to carry `CUT5`.

## `window.__timelines` registration

Every composition—root and scenes—registers a paused GSAP timeline on the shared global:

```javascript
window.__timelines = window.__timelines || {};
const rootTimeline = gsap.timeline({ paused: true });
// … seam tweens …
window.__timelines["claude-paper"] = rootTimeline;
```

<ParamField body="key" type="string" required>
Must match `data-composition-id` on the registering element. Root key is `claude-paper`; scene keys include `chat-response`, `response-scroll`, `compose-tasklist`, `outro`, and the other section IDs.
</ParamField>

<ParamField body="timeline" type="gsap.core.Timeline" required>
Always `{ paused: true }`. HyperFrames seeks the timeline against the master clock; scene scripts may use `?t=` or `?dev=1` query params for local scrubbing only.
</ParamField>

If the root registration key drifts from `data-composition-id="claude-paper"`, the framework cannot drive seam blending and sections may pop without transitions.

## Edit workflow

<Steps>
<Step title="Plan the time shift">

Decide whether you are moving a section boundary, changing a section’s length, or retiming a seam. List every dependent surface: adjacent `data-start`/`data-duration`, the matching `CUT` constant, scene handoff keyframes, and `<audio>` `data-start` values.

</Step>

<Step title="Update section attributes">

Edit the target `#sec-*` div and, if total runtime changes, `#claude-paper` `data-duration`. Keep intentional overlaps—for example `response-scroll` starting at 13.0 while `chat-response` ends at 13.6 leaves 0.6s for the opacity crossfade.

</Step>

<Step title="Retarget seam tweens">

Move every GSAP position argument tied to the boundary. For inverse zoom-throughs, update both the constant (`CUT`, `CUT2`, `CUT4`) and the derived offsets (`CUT - 0.2`). For leftward cuts, update `CUT3`, `CUT5`, `CUT6` and their `CUTn - 0.26` throw start.

Example—shifting the chat→response crossfade from 13.0s to 14.0s:

```javascript
rootTimeline.to("#sec-response", { opacity: 1, duration: 0.6, ease: "power1.inOut" }, 14.0);
rootTimeline.to("#sec-chat", { opacity: 0, duration: 0.6, ease: "power1.inOut" }, 14.0);
```

</Step>

<Step title="Align scene compositions">

When a cut time moves, verify the outgoing scene still finishes its throw and the incoming scene still opens at the matched pose. Scene `data-duration` on the template root must cover the visible window declared in `index.html`. Mismatches produce black tails or one-frame flashes at hard cuts.

</Step>

<Step title="Resync audio and SFX">

Voiceover (`data-start="29.6"`), explainer VO (`42.6`), click SFX (`49.30` for the download tap), and the generated type/click tracks are scheduled in absolute master time. Shift them whenever the underlying visual event moves.

</Step>

<Step title="Verify">

Preview the full cut with HyperFrames and scrub across every seam—especially hard cuts at 6.7s, 25.2s, 38.8s, 40.3s, and 49.9s. Confirm paper background `#F0EEE6` stays visible through throws so exposed edges stay seamless.

</Step>
</Steps>

## Constraints and invariants

| Invariant | Why it matters |
| --- | --- |
| `data-duration` on `#claude-paper` equals last section end | Defines render length and export envelope |
| `CUTn` aligns with incoming `data-start` (or the visual event it marks) | Prevents velocity breaks across hard cuts |
| Higher z-index on the incoming section during crossfades | Incoming plate must paint above the outgoing one |
| Paper `#F0EEE6` on `html`, `body`, and `#claude-paper` | Opaque overlaps and throws expose paper, not black |
| Scene `data-duration` ≥ scene GSAP timeline length | Avoids frozen or blank frames before the next section |
| Root key `claude-paper` on `window.__timelines` | Framework seam driver registration |

<Tip>
When lengthening a middle section, shift all downstream `data-start`, `CUT` constants, and audio timestamps together. A spreadsheet column for absolute time prevents cumulative drift.
</Tip>

## Adding or removing a section

1. Add a `#sec-*` div with `data-composition-src`, timing attributes, and a unique `data-track-index`.
2. Assign the next z-index in the `<style>` block; add `will-change` if the seam uses transform, filter, or opacity throws.
3. Author or reuse a `compositions/*.html` plate that registers `window.__timelines["your-id"]`.
4. Insert root seam tweens at the new boundary (or document a hard cut if plates are pixel-matched).
5. Recompute `#claude-paper` `data-duration` and validate the full 1920×1080 render.

Removing a section reverses the sequence; collapse overlaps so no seam references a removed element selector.

## Failure modes

| Symptom | Likely cause | Fix |
| --- | --- | --- |
| Pop or flash at a seam | `CUT` time drifted from `data-start` | Retarget constant and `CUT ± offset` tweens together |
| Both sections visible, wrong stacking | z-index inverted | Raise z-index on the plate that should be on top |
| Black frame between scenes | Gap between section windows | Overlap `data-start`/`data-duration` or extend scene hold tweens |
| Outgoing throw with no inbound motion | Incoming scene initial state not matched | Align entry transforms with outgoing throw (see `sure-response`, `compose-tasklist`, `outro`) |
| Audio off-sync | Visual moved, `<audio>` `data-start` did not | Shift affected audio elements in absolute time |
| Seam tweens never run | Missing `window.__timelines["claude-paper"]` | Confirm registration key matches `data-composition-id` |
| Crossfade shows wrong content | Only one section faded | Ensure both `#sec-*` selectors are tweened (see seam 2 pattern) |

## Quick reference: root timeline skeleton

```javascript
window.__timelines = window.__timelines || {};
const rootTimeline = gsap.timeline({ paused: true });

// Initial hidden states for incoming plates
rootTimeline.set("#sec-response", { opacity: 0 }, 0);
// … set other inbound sections to opacity: 0 …

// Seam 2 — opacity crossfade at 13.0
rootTimeline.to("#sec-response", { opacity: 1, duration: 0.6, ease: "power1.inOut" }, 13.0);
rootTimeline.to("#sec-chat",     { opacity: 0, duration: 0.6, ease: "power1.inOut" }, 13.0);

// Seam 3 — inverse zoom-through
const CUT = 25.2;
rootTimeline.to("#sec-followup", { scale: 0.8, filter: "blur(20px)", duration: 0.2, ease: "power3.in" }, CUT - 0.2);
// … CUT2, CUT3, CUT4, CUT5, CUT6 blocks follow the same templates …

window.__timelines["claude-paper"] = rootTimeline;
```

## Related pages

<CardGroup>
<Card title="Master composition reference" href="/master-composition-reference">
Full section inventory with track-index assignments and composition source paths.
</Card>
<Card title="Transition grammar" href="/transition-grammar">
Normative definitions for hard cuts, opacity crossfades, inverse zoom-through, and leftward cut-the-curve.
</Card>
<Card title="HyperFrames composition model" href="/composition-model">
How `data-composition-id`, template wrappers, and `window.__timelines` fit together.
</Card>
<Card title="Sync audio and SFX" href="/sync-audio-and-sfx">
Retarget voiceover, explainer VO, and generated click/type tracks after timeline edits.
</Card>
<Card title="Author a scene composition" href="/author-scene-composition">
Build or adjust scene plates whose handoff poses must match root seam times.
</Card>
<Card title="Troubleshooting" href="/troubleshooting">
Recovery steps for seam misalignment and timeline registration failures.
</Card>
</CardGroup>
