- Gate stripStudioEditsFromTarget/bakeVisibilityOnDelete behind a
stripStudioEdits flag on the delete mutation type so they only fire on
user-initiated deletes, not on internal delete-then-recreate drags.
- Add bakeVisibilityOnDelete to the remove-all-keyframes handler so
elements with CSS opacity:0 stay visible after collapsing keyframes.
- Fix integer rounding in readAllAnimatedProperties: use 3-decimal
precision for visual properties (opacity, scale, rotation) instead of
Math.round which corrupted mid-fade values to 0.
- Guard VISUAL_BASELINE against cross-tween contamination by querying
__timelines for properties animated by other tweens on the same element.
- Harden bakeVisibilityOnDelete: reverse-scan keyframes for the last one
containing opacity, guard against relative values (+=/-=/*=), and add
Number.isFinite check.
- Fix falsy-zero doubling in drag commit: replace || fallback with
Number.isFinite so a base GSAP position of 0 is correctly preserved.
- Fix gesture recording sign inversion: remove pointerElementOffset
subtraction from dx/dy formula and instead apply it once to basePosition
so the element center tracks the pointer.
- Fix TypeScript build errors in gsapSoftReload.ts (6 double-casts).
- Strip all diagnostic logs from production code.
* feat(studio): add drag-to-reorder in layers panel with z-index persistence
Layers panel now sorts siblings by computed z-index (descending) to
reflect visual stacking order. Users can drag layer rows to reorder
them within a sibling group — on drop, sequential z-index values are
assigned and persisted via the existing inline-style patch pipeline
with a single preview reload.
- sortLayersByZIndex: recursive sibling-group sort by computed z-index
- useLayerDrag: pointer-capture drag gesture with 4px threshold,
insertion indicator line, and depth-constrained sibling reorder
- handleDomZIndexReorderCommit: batch z-index commit with coalesced
undo entry and single skipRefresh=false on the final patch
* fix(studio): harden layer drag-to-reorder edge cases
- Guard drag initiation against locked compositions by checking
data-timeline-locked ancestors in isLayerDraggable
- Show not-allowed cursor and reduced opacity on non-draggable layer rows
- Fire toast when attempting to drag a layer with no same-depth siblings
- Preserve z-index spacing on reorder by redistributing existing values
instead of flattening to sequential integers
- Auto-set position:relative on unpositioned elements when z-index is
applied so the stacking order actually takes visual effect
- Add tests for isLayerDraggable (anonymous, id, selector, locked, free)
* fix(studio): handle z-index ties in layer reorder + trim file sizes
- Fall back to sequential z-index when any duplicates exist in the
sibling set, not just when all values are identical — fixes silent
no-op reorder when tied values preserve DOM-order stacking
- Trim useDomEditSession.ts from 602 to 600 lines (CI file-size gate)
* test(studio): add duplicate z-index tiebreak test for layer sorting
Cover the [2, 1, 2] case where tied z-index values fall back to
reverse DOM order — locks the hasDupes fix against regressions.
* style(studio): fix oxfmt formatting in LayersPanel