# Sequence Desk > A Remotion composition is a tree, and a Sequence CLIPS ITS CHILDREN. Offsets compose > additively down the tree, so a card at frame 15 holding a headline at frame 7 puts > that headline at frame 22 — and if the card is 90 frames long, the headline renders for > 83 frames of the 120 frames it asked for. The last 37 frames never happen, and nothing > throws, nothing logs, and no warning is printed. ## The one thing to know **A SEQUENCE CLIPS ITS CHILDREN.** Everything on this page follows from that. ```text absolute start = parent's absolute start + this Sequence's `from` visible window = own window ∩ parent's visible window ∩ the composition ``` Offsets **compose additively down the tree**, so a child three levels deep starts at the sum of every `from` above it — a number nobody works out by hand. A card at frame 15 for 90 frames, and a headline inside it at frame 7 for 120 frames. Both rows are ordinary. The headline actually starts at frame 22 and the card ends at frame 105, so the headline renders for 83 frames of the 120 frames it asked for. **The last 37 frames never happen**, and nothing throws, nothing logs, and no warning is printed. **And useCurrentFrame() inside a Sequence is RELATIVE** — it counts from that sequence's own start. So an animation written for frames 0..119 completes only if its sequence is VISIBLE for that long. **Having a duration is not the same as being visible.** Everything here is FRAMES. Seconds are the intent and frames are the storage, so a value in seconds is multiplied by the fps and rounded — and re-rendering at another rate converts every boundary independently and rounds each one. ## A worked tree | Sequence | Parent | Row says | Actually starts | Asks for | Renders | Cut by | | --- | --- | --- | --- | --- | --- | --- | | `gradient` | — | frame 0 | frame 0 | the rest | 360 frames | — | | · `card` | `gradient` | frame 15 | frame 15 | 90 frames | 90 frames | — | | · · `headline` | `card` | frame 7 | frame 22 | 120 frames | 83 frames | `card` (37 frames) | | · · `sweep` | `card` | frame 55 | frame 70 | 45 frames | 35 frames | `card` (10 frames) | **Every row above is ordinary and two of them are wrong.** `headline` says frame 7 and starts at frame 22 — 15 plus 7, a sum nobody adds up. It asks for 120 frames and renders for 83 frames, because `card` ends at frame 105 and **a Sequence clips its children**. The last 37 frames never happen. `sweep` loses 10 frames the same way. Nothing throws, nothing logs, and no warning is printed. What you see is an animation that stops in the middle of its motion. ## What a child outside its parent does | The shape | The child asks for | It renders | What is lost | What you see | | --- | --- | --- | --- | --- | | child ends after the parent does | 120 frames | 60 frames | 60 frames off the end | the animation stops mid-motion and is gone | | child starts before the parent mounts | 60 frames | 30 frames | 30 frames off the front | it appears already in progress; the entrance never happens | | child entirely after the parent ends | 40 frames | **0 frames** | 40 frames off the end | **nothing at all — it is simply not there** | | child runs past the composition | 60 frames | 40 frames | 20 frames off the end | the animation stops mid-motion and is gone | **All four are silent.** The third is the worst, because an absence is what people check last: it reads as a styling bug for a long time before anybody opens the timeline. ## The same numbers at another rate | At 30 fps | At 24 fps | At 25 fps | At 60 fps | | --- | --- | --- | --- | | 7 frames | **5.6 → 6** | **5.83 → 6** | 14 | | 15 frames | 12 | **12.5 → 13** | 30 | | 33 frames | **26.4 → 26** | **27.5 → 28** | 66 | | 41 frames | **32.8 → 33** | **34.17 → 34** | 82 | | 45 frames | 36 | **37.5 → 38** | 90 | | 90 frames | 72 | 75 | 180 | | 120 frames | 96 | 100 | 240 | | 360 frames | 288 | 300 | 720 | **8 of these 24 conversions do not land on a frame** and are rounded. Frames are the storage and seconds are the intent: a timeline timed by eye at one rate is not the same timeline at another, and each boundary is rounded independently so the errors do not cancel. ## What it is A single-page app at https://sequence-desk.skillsafe.ai/. The engine is free and runs entirely in the browser with no account; writing the report costs credits. 5 lanes over one sheet, each handing its result to the next. ## The free engine `sequence.js` makes no network calls at all. Given a sheet it resolves every Sequence to its absolute window, intersects it with its parent's visible window and with the composition, reports how many frames each one loses and WHAT cut them, finds the ones that render for zero frames, walks the timeline for frames with nothing mounted, lists which siblings overlap, converts every boundary to another rate and says which stop landing on a frame, and totals the render. It emits 31 findings. All of that is sent with every paid run as `prescan`, so the model is never asked to do arithmetic it can be given. A Sequence with no `durationInFrames` runs to the end of its parent and therefore clips nothing. That is the default, and a wrapper that was given a duration "for tidiness" is the commonest accidental clip in a Remotion project — no number fixes it, because the duration should not be there. ## Sheet grammar ```text COMPOSITION name | the product launch film fps | 30 duration | 12s compare | 24 SEQUENCES s1 | | the background gradient | 0 | - | runs the whole way s2 | s1 | the title card | 0.5s | 3s | fades in over the gradient s3 | s2 | the headline words | 7 | 4s | authored for four seconds ``` A SEQUENCES row is `id | parent | what it is | from | duration | why`. **`from` is relative to the PARENT**, exactly as it is in the code. An empty parent column means top level. A duration of `-` (or blank, or `rest`) means no `durationInFrames` at all, which is Remotion's default: the child runs to the end of its parent. Frames or seconds anywhere: `90`, `3s`, `500ms`. Seconds are multiplied by the fps and **rounded**, and the rounding is reported. In COMPOSITION, `duration` is the outermost clip and `compare` is the rate to check the timeline against — it defaults to 24 fps, or to 30 fps if the composition is already at that rate. ## Lanes | task | Lane | Fields | Sections | | --- | --- | --- | --- | | `plan` | Lay the timeline out before it is built | `brief, known` | Summary, The Sheet, The Tree, Reasoning, Next Step | | `check` | What this timeline actually shows | `sheet, worry` | Summary, Verdict, Findings, Corrected Sheet, Next Step | | `tree` | Where every sequence actually sits | `sheet` | Summary, Every Sequence, What Clips What, The One To Fix, Next Step | | `rate` | The same timeline at another frame rate | `sheet` | Summary, What Moves, What Holds, What To Do About It, Next Step | | `deliver` | Decide what changes: a number, the nesting, or nothing | `sheet, fixed` | Summary, A Number Fixes, Only Re-nesting Fixes, Nothing Fixes, Next Step | Every run body must carry `task`. The body IS the input object — do not wrap it in an `{"input": ...}` envelope, which returns 200 while hiding `task` from the model. ## Thresholds | Number | Value | What it decides | | --- | --- | --- | | deep nesting | past 3 levels | where an offset stops being readable as a sum | | a flash | 2 frames or fewer | where a visible window is too short to register | | the compared rate | 24 fps | what a 30 fps design is most often re-cut to, unless `compare` says otherwise | | the default rate | 30 fps | assumed when no fps is given, and it decides every seconds-to-frames value | | the default length | 300 frames | assumed when no duration is given; it is the outermost clip | | the rates in common use | 23.976 fps, 24 fps, 25 fps, 29.97 fps, 30 fps, 48 fps, 50 fps, 59.94 fps, 60 fps, 120 fps | anything else is usually a digit out of place | ## Severity Severity is fixed by the code. **Errors are reserved for frames the viewer never sees** — a sequence that renders for zero frames, or one whose animation is cut at either end. A gap in the timeline and a boundary that will round at another rate are warnings: real costs somebody has to decide about, not things that stop working. | Code | Severity | Scope | What it means | | --- | --- | --- | --- | | `FPS-ASSUMED` | warn | composition | The frame rate was assumed | | `DURATION-ASSUMED` | warn | composition | The composition's length was assumed | | `FPS-UNUSUAL` | note | composition | That frame rate is not one in common use | | `NO-SEQUENCES` | warn | composition | No sequences given | | `SINGLE-SEQUENCE` | note | composition | One sequence, and nothing to nest | | `PARENT-MISSING` | warn | sequence | Its parent is not on the sheet | | `PARENT-CYCLE` | warn | sequence | The parent chain loops | | `DEEP-NESTING` | note | sequence | Its offset is a sum of several | | `OFFSET-COMPOSES` | note | sequence | Where it actually sits | | `NEVER-RENDERS` | error | sequence | It never renders at all | | `CLIPPED-TAIL` | error | sequence | The animation never finishes | | `CLIPPED-HEAD` | error | sequence | You never see it start | | `TINY-WINDOW` | warn | sequence | It is visible for almost no time | | `ZERO-DURATION` | warn | sequence | Its duration is zero | | `INHERITS-DURATION` | note | sequence | No duration given, so it runs to the end of its parent | | `FULLY-VISIBLE` | note | sequence | Every frame it asks for, it gets | | `SECONDS-ROUNDED` | warn | sequence | A value in seconds did not land on a frame | | `WRITTEN-IN-SECONDS` | note | sequence | This row was written in seconds | | `FRACTIONAL-FRAME` | warn | sequence | A frame count with a fraction in it | | `BLANK-FRAMES` | warn | composition | Some frames have nothing mounted | | `TRAILING-BLANK` | warn | composition | The composition ends on blank frames | | `LEADING-BLANK` | note | composition | The composition opens on blank frames | | `FULLY-COVERED` | note | composition | Something is mounted on every frame | | `CONTENT-PAST-END` | warn | composition | Content runs past the end of the composition | | `CONTENT-FITS` | note | composition | The content ends exactly where the composition does | | `SIBLINGS-OVERLAP` | note | composition | Two siblings occupy the same frames | | `NO-OVERLAP` | note | composition | Nothing overlaps anything | | `FPS-CHANGE-MOVES-EVERYTHING` | note | composition | At another frame rate this is a different timeline | | `FPS-CHANGE-IS-CLEAN` | note | composition | At the compared rate every boundary still lands on a frame | | `RENDER-COST` | note | composition | What this costs to render | | `RENDERING-BLANK` | warn | composition | Part of the render is blank | ## Which decision matters **One thing decides more than any other, and it is not a duration: it is the NESTING.** A sequence's window is intersected with its parent's, so the fix for a clipped child is as often "move it out of that parent" as "give the parent more frames". - If the child belongs to the parent — a label on a card — lengthen the parent. - If it merely happens to be inside it, **re-parent it** and the clipping disappears without any number changing. - If the parent is a layout wrapper with no timing meaning of its own, give it no `durationInFrames` at all and it stops clipping anything. The last one is the fix people miss, because a wrapper with a duration looks like a decision and is usually a copy-paste. ## API Full documentation at https://sequence-desk.skillsafe.ai/api.html. The engine is client-side only and has no endpoint, but everything it computes is above, so you can reproduce every figure in your own pipeline without this app. ## What this page cannot do - **It has not rendered anything.** Every figure is arithmetic on numbers somebody typed in, and a row here is a claim about the code rather than a reading of it. - **It models `from` and `durationInFrames` only.** ``, `premountFor`, `loop`, `` and layout offsets all move things and none of them is on this sheet. - **Visible is not the same as on screen.** A mounted sequence can be behind another, transparent, or off the canvas, and this counts it as rendering. - **Document order decides what is on top**, and a sheet has no document order. - **It says nothing about what the animation does** — only about which frames it gets. - **Frame numbers are zero-based**, so a composition of 360 frames ends at frame 359. ## Source Lanes derived from the `video-report` skill in https://github.com/remotion-dev/remotion, which makes videos programmatically with React. Every video it makes is a tree of Sequences, and every one of them clips its children. Not affiliated with or endorsed by the authors of that repository.