← 100 theme gallery
saas-motion-kit · transition atlas

24 transitions that tell the story

The stock set (crossfade, push, zoom-through, circle iris, blinds) already lives in HyperFrames, and a good film repeats two or three of those as its rhythm. This atlas holds the other kind: narrative transitions that carry meaning from one scene into the next. Each card loops a live demo on the fictional Acme brand and says when to reach for it, what to avoid and how to build it seek-safe in GSAP.

  1. Keep a quiet base. Plain hard cuts can carry the in-between beats. Log them as motif:cut in the ledger so the audit knows they are deliberate, and never let a flashy transition become the default.
  2. Spend narrative ones where the story turns. The hook, the reveal, the proof moment, the CTA. Pick the one whose meaning matches the message of that cut.
  3. Never twice. Use each atlas transition once per film, and don't put two from the same family back to back. Match the tone words to your brief.

Cut

04

The edit does the work. No overlap and no wipe: the match between the last frame of A and the first frame of B carries the meaning.

T01cutenergy ●○○

Match Cut: Shape

premiumcalmtrustworthy

A hard cut between two circles with the same centre and diameter, so the eye reads one shape turning into another.

Use when
Reframing a problem as its answer: the coral alert dot becomes the teal status ring. Best on the hook-to-reveal cut, where the viewer should feel 'same thing, new meaning'.
Avoid
A near-miss in position or size reads as a mistake, so lock both shapes to one centre. Use it once per film; a second shape match turns a clever beat into a gimmick.
Recipe · HyperFrames

Lock both circles to one centre and diameter in the 1920×1080 frame, then let the push-in run through the cut.

tl.fromTo('#a',{scale:1},{scale:1.12,duration:1.4,ease:'power2.in',transformOrigin:'50% 45%'},T-1.4); tl.set('#a',{opacity:0},T); tl.set('#b',{opacity:1},T);
tl.fromTo('#b',{scale:1.12},{scale:1.2,duration:0.7,ease:'power3.out',transformOrigin:'50% 45%'},T);

HyperFramescustom (hard cut); css-other morph circle is the nearest built-in

T02cutenergy ●●○

Match Cut: Motion

boldplayfulpremium

An object moving across scene A is cut mid-movement, and a different object in scene B carries on along the same path at the same speed.

Use when
Handing momentum from cause to effect: a 'Deploy' pill slides right and a 'Shipped' badge lands where it was heading. Good for workflow steps that should feel like one gesture.
Avoid
Direction, screen position and speed must match on the cut frame or the eye jumps. Don't cut on a still object, and don't follow it with a whip pan: two directional handoffs in a row blur together.
Recipe · HyperFrames

Cut on the fastest frame; both objects share one motion path and velocity at T.

tl.fromTo('#a .pill',{x:-520},{x:120,duration:1,ease:'power2.in'},T-1); tl.set('#a',{opacity:0},T); tl.set('#b',{opacity:1},T);
tl.fromTo('#b .badge',{x:120},{x:560,duration:0.6,ease:'power2.out'},T);

HyperFramescustom (hard cut); css-blur directional blur can soften the seam

T03cutenergy ●●○

Graphic Match: Color

boldpremiumwarm

The camera pushes into a flat field of colour in scene A until it fills the frame, then cuts to scene B, which uses that colour as its background.

Use when
Going from a detail to a chapter card or brand moment: the teal bar in a chart becomes the teal of the next scene, so the colour carries the idea ('growth') across.
Avoid
Needs a flat, clean colour area; gradients, photos and textures break the match. Pointless between two scenes that already share a background.
Recipe · HyperFrames

Scale A from the centre of the colour area until it covers the frame, then cut.

tl.fromTo('#a',{scale:1},{scale:16,duration:0.8,ease:'power3.in',transformOrigin:'63% 53%'},T-0.8); tl.set('#a',{opacity:0},T); tl.set('#b',{opacity:1},T);
tl.fromTo('#b .title',{y:40,opacity:0},{y:0,opacity:1,duration:0.5,ease:'power3.out'},T+0.1);

HyperFramescss-other (morph circle), closest; here the colour comes from a push-in, not a circle

T04cutenergy ●●●

Beat Cut with Hold-frame

urgentboldcelebratory

Scene A freezes for one beat, drained of colour, then a hard cut lands exactly on the downbeat into a punched-in scene B.

Use when
The 'wait for it' before a reveal or a drop: the freeze tells the viewer to look, the downbeat cut delivers the answer. Built for music-led promos and launch reels.
Avoid
Only on a real downbeat; off the grid it reads as a glitch. One hold per section at most, and never on a frame the viewer still needs to read.
Recipe · HyperFrames

Snap T to the beat grid (hyperframes beats). The freeze is simply no tweens on #a between T-0.5 and T.

tl.fromTo('#a',{filter:'saturate(1)'},{filter:'saturate(0.2) contrast(1.1)',duration:0.08,ease:'none'},T-0.5); tl.set('#a',{opacity:0},T); tl.set('#b',{opacity:1},T);
tl.fromTo('#b',{scale:1.1},{scale:1,duration:0.35,ease:'expo.out'},T);

HyperFramescustom (hard cut on the beat grid)

Carry

04

Something survives the change. An object, a word, a cursor or a line walks from one scene into the next and becomes part of it.

T05carryenergy ●●○

Object Carry

playfultrustworthywarm

One element lifts out of scene A, flies across the change and docks into its slot in scene B, becoming part of the new layout.

Use when
Showing one item moving through a system: an alert becomes a ticket, a file becomes a row, a card lands on a board. The viewer follows the object, so the scene change feels earned.
Avoid
The object needs an obvious destination in B. One carried object per transition, and not on the next cut too: carry after carry starts to feel like a screensaver.
Recipe · HyperFrames

Render the carried element once, above both scenes, and tween it between two measured rects.

tl.fromTo('#chip',{x:0,y:0,scale:1},{x:-880,y:120,scale:0.92,duration:0.9,ease:'power3.inOut'},T);
tl.fromTo('#a',{x:0,opacity:1},{x:-240,opacity:0,duration:0.6,ease:'power2.in'},T); tl.fromTo('#b',{x:320,opacity:0},{x:0,opacity:1,duration:0.7,ease:'power3.out'},T+0.2);

HyperFramesshared-element (Tier-A, worker-authored)

T06carryenergy ●○○

Type Carry

calmpremiumtrustworthy

One word of the headline stays on screen while the rest leaves, then scene B builds its layout around that word.

Use when
When the next scene proves one word of the claim: 'watched' becomes the title of the monitoring panel, 'owned' becomes the owner column. A calm bridge from headline to proof.
Avoid
The word must mean the same thing in both scenes. Don't carry filler words, don't swap the font mid-flight, and don't carry type twice in a row.
Recipe · HyperFrames

Split the headline into word spans; the kept word is its own layer above both scenes.

tl.fromTo('#a .rest',{y:0,opacity:1},{y:-30,opacity:0,duration:0.4,ease:'power2.in',stagger:0.05},T);
tl.fromTo('#word',{x:0,y:0,scale:1},{x:0,y:-300,scale:0.55,duration:0.8,ease:'power3.inOut',transformOrigin:'0% 0%'},T+0.1); tl.fromTo('#b .item',{y:24,opacity:0},{y:0,opacity:1,duration:0.5,ease:'power3.out',stagger:0.06},T+0.5);

HyperFramesshared-element (Tier-A, worker-authored)

T07carryenergy ●●○

Cursor Carry

technicaltrustworthycalm

A cursor clicks a card and the clicked card grows into the next full scene, like a container transform.

Use when
Product demos and walkthroughs: 'click here and this opens'. Cause and effect are on screen, so it suits navigation and drilling into detail.
Avoid
The clicked element must be what the next scene is about. Keep the cursor slow and deliberate; don't click into a screen with no clear target, or three times in one demo.
Recipe · HyperFrames

Clip scene B to the clicked card's rect, then open the clip to the full frame.

tl.fromTo('#cursor',{x:-800,y:420},{x:0,y:0,duration:0.7,ease:'power2.inOut'},T-0.9); tl.fromTo('#cursor',{scale:1},{scale:0.85,duration:0.08,ease:'power1.inOut',yoyo:true,repeat:1},T-0.16);
tl.fromTo('#b',{clipPath:'inset(25% 10% 40% 58% round 24px)'},{clipPath:'inset(0% 0% 0% 0% round 0px)',duration:0.8,ease:'power3.inOut'},T);

HyperFramesshared-element (Tier-A); rules card-morph-anchor + cursor-click-ripple

T08carryenergy ●○○

Line-to-Horizon

calmwarmpremium

A chart line flattens and stretches across the full width, and becomes the horizon or divider of the next scene.

Use when
Going from data to meaning: 'the numbers settled' becomes a calm landscape, a roadmap or a section divider. Good for the exhale after a proof moment.
Avoid
Needs one clean line, not a busy multi-series chart, and a scene B with a strong horizontal. Don't reuse it for the outro.
Recipe · HyperFrames

Keep the stroke constant (vector-effect: non-scaling-stroke) while you squash the line.

tl.fromTo('#line path',{scaleY:1},{scaleY:0.01,duration:0.7,ease:'power3.inOut',transformOrigin:'50% 50%'},T); tl.fromTo('#line',{scaleX:1,y:0},{scaleX:1.4,y:150,duration:0.6,ease:'power3.inOut'},T+0.4);
tl.fromTo('#b .sky',{opacity:0},{opacity:1,duration:0.6,ease:'sine.out'},T+0.7); tl.fromTo('#b .sun',{y:120},{y:0,duration:0.9,ease:'power2.out'},T+0.8);

HyperFramescustom

Camera

04

Move the lens, not the layers. Push through, whip, pull back or slide in depth, so the viewer travels between scenes.

T09cameraenergy ●●●

Push-Through

boldtechnicalmysterious

The camera flies into a window inside scene A (a card preview, a screen) and comes out the other side in scene B.

Use when
Going deeper: from the dashboard into one report, from the overview into the product. Works as a hero reveal because it feels like entering the product.
Avoid
The window must hold a true miniature of B, or the landing jumps. It is high energy: once per film, and not straight after a zoom or dolly.
Recipe · HyperFrames

Nest a mini copy of B in the window, scale A until the window exactly fills the frame, then swap.

tl.fromTo('#a',{scale:1},{scale:5,duration:0.9,ease:'power4.inOut',transformOrigin:'1440px 528px'},T); // origin = s·(window top-left)/(s−1)
tl.set('#a',{opacity:0},T+0.9); tl.set('#b',{opacity:1},T+0.9);

HyperFramescss-scale (zoom through), aimed at a UI window

T10cameraenergy ●●●

Whip Pan with Motion Blur

urgentplayfulbold

The camera whips sideways so fast that scene A smears into a horizontal blur and scene B snaps sharp beside it.

Use when
Two things happening at once ('meanwhile, in support…') or a quick before/after. Adds energy without changing the subject.
Avoid
Twice per film at most, and never back and forth in a row. Only a horizontal blur sells it; a plain gaussian blur reads as a focus problem.
Recipe · HyperFrames

Put A and B on one wide strip and fade in a directionally blurred copy at peak speed.

tl.fromTo('#strip',{x:0},{x:-1920,duration:0.45,ease:'expo.inOut'},T);
tl.fromTo('#strip-blur',{opacity:0},{opacity:1,duration:0.18,ease:'power2.in',yoyo:true,repeat:1},T+0.05); // copy uses an SVG feGaussianBlur stdDeviation='40 0'

HyperFramesshader: whip pan · css-blur (directional blur)

T11cameraenergy ●●○

Dolly-Out Reveal

premiumtrustworthycelebratory

The camera pulls back from scene A until it becomes one tile in a grid of other scenes.

Use when
Revealing scale or context: 'this is one of 40 workflows', 'every team gets this view'. A strong move from one feature to the whole platform.
Avoid
The other tiles must be real, readable product surfaces, not filler. Don't follow it with a push into a different tile; it reads as indecision.
Recipe · HyperFrames

Build the grid at its final size with A inside the target tile, and start it scaled so that tile fills the frame.

tl.fromTo('#grid',{scale:3.333},{scale:1,duration:1.2,ease:'power3.inOut',transformOrigin:'50% 50%'},T);
tl.fromTo('#grid .hero',{borderRadius:0},{borderRadius:16,duration:1.2,ease:'power3.inOut'},T);

HyperFramescss-scale (zoom out), inverted into a grid

T12cameraenergy ●●○

Parallax Slide

warmplayfulcalm

A slide from A to B on three layers at three speeds: the backdrop drifts, the main card slides, the foreground details rush past.

Use when
Stepping through a sequence (plan, build, ship) when a plain push feels flat. The depth turns a sideways move into travel through a space.
Avoid
Three layers with clear ratios (about 0.3×, 1×, 1.4×) and no more. Not for dense data scenes: text moving at different speeds is hard to read.
Recipe · HyperFrames

One ease, three distances.

tl.fromTo('#bg',{x:0},{x:-580,duration:1,ease:'power3.inOut'},T); tl.fromTo('#mid',{x:0},{x:-1920,duration:1,ease:'power3.inOut'},T);
tl.fromTo('#fg',{x:0},{x:-2690,duration:1,ease:'power3.inOut'},T);

HyperFramescss-push (push slide), split into three depth layers

Mask

04

One scene opens a window onto the next. The window's shape is the message: the logo, a word, the subject, a strip.

T13maskenergy ●●○

Product-Shape Mask

premiumboldcelebratory

Scene B shows through the brand mark (or a key UI shape), and the shape grows until B fills the frame.

Use when
Brand-to-product moments: the logo opens onto the product, the app icon opens onto the app. Also a strong first cut after a cold open.
Avoid
The shape must be recognisable when small, so use simple marks and UI shapes. Once per film, and not in the same film as a text mask.
Recipe · HyperFrames

Animate clip-path inset() with the mark's corner radius from its rect to the full frame.

tl.fromTo('#mark .fill',{opacity:1},{opacity:0,duration:0.25,ease:'power1.out'},T);
tl.fromTo('#b',{clipPath:'inset(28% 43.5% 49% 43.5% round 62px)'},{clipPath:'inset(0% 0% 0% 0% round 0px)',duration:0.9,ease:'power3.inOut'},T+0.25); tl.fromTo('#mark .line',{scale:1,opacity:1},{scale:6,opacity:0,duration:0.7,ease:'power2.in'},T+0.25);

HyperFramescss-radial (circle / diamond iris) with a custom clip shape; shader: sdf-iris

T14maskenergy ●●○

Text Mask

boldpremiummysterious

A huge word fills the frame with scene B showing through its letters; then the letters open up and B takes over.

Use when
Title moments and chapter openers where one word is the message ('LIVE', 'NOW', the product name). The classic name reveal for a launch film.
Avoid
Needs heavy type and a visually rich scene B, or the letters look empty. Short words only (3–5 letters); never twice per film.
Recipe · HyperFrames

Knockout layer: ink background, white type, mix-blend-mode: multiply over B (isolate the parent).

tl.fromTo('#knock',{scale:1.2,opacity:0},{scale:1,opacity:1,duration:0.3,ease:'power3.out'},T);
tl.fromTo('#knock .ch',{scale:1},{scale:5,duration:0.7,ease:'power4.in',stagger:0.04},T+0.7); tl.fromTo('#knock',{backgroundColor:'#0E1726'},{backgroundColor:'#FFFFFF',duration:0.5,ease:'power2.in'},T+0.85);

HyperFramescustom (mix-blend knockout)

T15maskenergy ●●○

Focal Iris

technicalurgentmysterious

An iris opens from the subject (the anomaly, the button, the face) rather than the frame centre, and scene B grows out of that point.

Use when
Drilling into a detail: 'look here, and this is what it means'. Where the iris starts tells the viewer what caused the next scene.
Avoid
Make the subject obvious first (pulse or ring it). Don't open from the centre (that's the stock iris) or on a busy frame with two possible subjects.
Recipe · HyperFrames

Use the subject's centre as the origin of the ring, the clip and the lean-in.

tl.fromTo('#a .ring',{scale:0.5,opacity:0},{scale:1,opacity:1,duration:0.4,ease:'back.out(2)'},T-0.5);
tl.fromTo('#b',{clipPath:'circle(0% at 72% 34%)'},{clipPath:'circle(105% at 72% 34%)',duration:0.8,ease:'power3.in'},T); tl.fromTo('#a',{scale:1},{scale:1.2,duration:0.8,ease:'power3.in',transformOrigin:'72% 34%'},T);

HyperFramescss-radial (circle iris) with the origin moved to the subject

T16maskenergy ●●●

Split Stack

boldtechnicalurgent

The frame splits into three horizontal strips and scene B slides in strip by strip, each at its own speed.

Use when
Topic changes and list beats ('three things changed'): the strips feel editorial and structured. Also good in a fast feature montage.
Avoid
Line the strips up with B's layout so no headline is cut in half at rest. Too busy for calm films; don't pair it with other stripe or blind effects.
Recipe · HyperFrames

Three copies of B clipped to thirds, same ease, rising durations.

['#b1','#b2','#b3'].forEach((s,i)=>tl.fromTo(s,{xPercent:100},{xPercent:0,duration:0.5+i*0.2,ease:'power4.out'},T+i*0.06));
tl.fromTo('#a',{xPercent:0,filter:'brightness(1)'},{xPercent:-12,filter:'brightness(0.85)',duration:0.9,ease:'power2.in'},T);

HyperFramescss-cover (staggered blocks / blinds), reduced to three strips

Material

04

The frame is made of something. Paper folds, ink bleeds, pixels sort and glass bends: a tactile handoff.

T17materialenergy ●○○

Paper Fold

warmplayfulnostalgic

Scene A folds in half like a sheet of paper, and the folded sheet drops away to show scene B underneath.

Use when
Closing one chapter and opening the next: a report folded into a proposal, a draft put away. Friendly and analogue, good for onboarding and small-team stories.
Avoid
Needs a perspective parent, and the front and back faces must swap at exactly 90° or the fold flickers. Too slow for launch energy; never fold twice in a film.
Recipe · HyperFrames

Split A into halves; hinge the top half on its bottom edge (parent: perspective 1600px) and swap its front/back faces at 90°.

tl.fromTo('#a-top',{rotationX:0},{rotationX:-180,duration:0.9,ease:'power2.inOut',transformOrigin:'50% 100%'},T); tl.set('#a-top .front',{opacity:0},T+0.45); tl.set('#a-top .back',{opacity:1},T+0.45);
tl.fromTo('#a-sheet',{y:0,rotation:0},{y:1300,rotation:-6,duration:0.5,ease:'power3.in'},T+0.9);

HyperFramescss-3d (3D card flip), closest

T18materialenergy ●○○

Ink Bleed

mysteriouspremiumwarm

A drop of ink lands on scene A and spreads with a rough, organic edge until the frame is ink, and scene B surfaces from it.

Use when
Moments of commitment and craft: signing, approving, publishing. Feels handmade, a welcome contrast in a very digital film.
Avoid
Needs a slow, calm track; fast ink looks like a paint splash. One ink colour only, and not in the same film as glitch or dither.
Recipe · HyperFrames

Grow blobs inside a layer with a goo filter (feDisplacementMap + feGaussianBlur + alpha threshold).

tl.fromTo('#ink .blob',{scale:0},{scale:1,duration:1.2,ease:'power2.in',stagger:0.08},T);
tl.fromTo('#b .title',{opacity:0,y:20},{opacity:1,y:0,duration:0.6,ease:'power3.out'},T+1.1);

HyperFramesshader: domain warp / cross-warp morph, closest

T19materialenergy ●●●

Dither / Pixel Sort

technicalnostalgicbold

Scene B replaces A through an ordered dither: a wave of chunky pixels sweeps across, led by a band of sorted colour streaks.

Use when
Tech moments: data being processed, an AI 'thinking', a system rebuilding. A retro-digital accent that suits developer tools.
Avoid
Chunky pixels only; fine dither vanishes in video compression. Once per film, and never over small text that must stay readable.
Recipe · HyperFrames

Four copies of B, each masked to one cell of a 2×2 Bayer pattern, wiped in with a lag.

[0,1,2,3].forEach(i=>tl.fromTo('#b'+i,{clipPath:'inset(0% 100% 0% 0%)'},{clipPath:'inset(0% 0% 0% 0%)',duration:0.9,ease:'none'},T+i*0.12));
tl.fromTo('#sort-band',{x:-200},{x:1920,duration:0.9,ease:'none'},T);

HyperFramescss-grid (grid dissolve), closest; shader: glitch

T20materialenergy ●○○

Glass Refraction Wipe

premiumcalmtechnical

A pane of frosted glass slides across the frame; behind it scene A turns into scene B, softened and bent as it passes.

Use when
Premium, calm reveals: a new plan, a redesigned screen, a before/after told with restraint.
Avoid
backdrop-filter is heavy to render, so keep the pane narrow and the move short. It doesn't read on flat, empty scenes; don't combine it with other blur transitions.
Recipe · HyperFrames

Drive the pane and the reveal edge with the same ease so the edge always sits inside the glass.

tl.fromTo('#pane',{x:-640},{x:2120,duration:1.4,ease:'power2.inOut'},T); // pane: backdrop-filter blur(6px) saturate(1.5)
tl.fromTo('#b',{clipPath:'inset(0% 100% 0% 0%)'},{clipPath:'inset(0% 0% 0% 0%)',duration:1.4,ease:'power2.inOut'},T);

HyperFramescustom; shader: chromatic split for the fringe

Time

04

Bend the clock. Freeze, rewind, ramp or tick through time, so the transition itself says 'earlier', 'later' or 'again'.

T21timeenergy ●●○

Freeze & Rewind Scrub

nostalgicplayfultechnical

Scene A freezes, then scrubs backwards at speed, the clock rolling back, until it lands on the earlier moment that becomes scene B.

Use when
Root-cause stories ('let's go back to 09:42'), flashbacks and 'how did we get here' openers.
Avoid
The rewind has to reverse motion the viewer just saw, or it looks like a random glitch. Once per film; skip the VHS noise for a premium brand.
Recipe · HyperFrames

Reverse A's own tween with a second fromTo, step the clock back, then land on B.

tl.fromTo('#line',{clipPath:'inset(0% 0% 0% 0%)'},{clipPath:'inset(0% 62% 0% 0%)',duration:0.7,ease:'power2.in'},T);
tl.fromTo('#clock',{yPercent:-80},{yPercent:0,duration:0.7,ease:'steps(4)'},T); tl.fromTo('#b .marker',{scale:0},{scale:1,duration:0.4,ease:'back.out(2)'},T+0.7);

HyperFramescss-distortion (VHS tape) for the rewind texture

T22timeenergy ●●●

Speed Ramp

urgentboldcelebratory

Motion slows almost to a stop, rockets into a streaking blur through the change, then eases back to normal speed in scene B.

Use when
Covering distance or time in one breath: 'from plan to launch', flying along a roadmap, the drop in the music.
Avoid
Needs continuous motion on both sides to ramp. One or two per film, on the biggest musical moments, and not next to a whip pan.
Recipe · HyperFrames

One long track, three chained fromTo tweens: slow, expo in, expo out.

tl.fromTo('#track',{x:0},{x:-240,duration:1.2,ease:'none'},T-1.2); tl.fromTo('#track',{x:-240},{x:-10800,duration:0.65,ease:'expo.in',immediateRender:false},T);
tl.fromTo('#track',{x:-10800},{x:-11500,duration:0.55,ease:'expo.out',immediateRender:false},T+0.65); // plus a blurred copy at the peak

HyperFramescss-blur (blur through / directional blur) at the peak

T23timeenergy ●●○

Time-lapse Tick

trustworthywarmnostalgic

A clock or calendar ticks through hours or days at speed while the content grows with it, and the ticking stops on scene B.

Use when
Results over time: 'a week later', 'by Friday', a sprint in five seconds. Time itself becomes the proof.
Avoid
The content must change as time passes, not just the clock. It implies waiting, so not for instant results; don't pair it with a speed ramp.
Recipe · HyperFrames

Step the calendar and the bars with steps(), spin the hand smoothly over the same window.

tl.fromTo('#hand',{rotation:0},{rotation:1440,duration:1.2,ease:'power2.inOut'},T);
tl.fromTo('#days',{yPercent:0},{yPercent:-80,duration:1.2,ease:'steps(4)'},T); tl.fromTo('#bars .bar',{scaleY:0},{scaleY:1,duration:0.01,ease:'none',stagger:0.3},T+0.3);

HyperFramescss-mechanical (clock wipe), closest

T24timeenergy ●○○

Loop Seam

calmpremiumplayful

The film's last move lands exactly on its first frame, so the loop plays forever without a visible seam.

Use when
Booth screens, social loops, website hero videos and GIFs: anything that plays on repeat, often without sound.
Avoid
Every property must match at the seam: position, colour, grain, even a particle's phase. Don't hide a bad seam with a fade; it shows on every loop.
Recipe · HyperFrames

Author the end as the start: the last tween's 'to' is the first frame's 'from'.

tl.fromTo('#strip',{yPercent:0},{yPercent:-33.333,duration:0.8,ease:'power3.inOut'},1); tl.fromTo('#strip',{yPercent:-33.333},{yPercent:-66.667,duration:0.8,ease:'power3.inOut',immediateRender:false},2.6);
tl.fromTo('#orbit',{rotation:0},{rotation:360,duration:DUR,ease:'none'},0); // then: python tools/loop_check.py render.mp4

HyperFramescustom; verify with tools/loop_check.py