plans/issues/issue-2514.md
Executor instructions: Reproduce-and-consolidate plan. Do not attempt a standalone fix here — the mechanism lives in plans/issues/issue-1935.md. Honor the approval gate before closing. Update the row in
plans/issues/README.mdwhen done.Drift check (run first):
gh api repos/motiondivision/motion/issues/2514 --jq .state→ must beopen. Check the README rows for issue-1935 (mechanism) before acting on Step 3.
42bfbe3ed, 2026-06-11Re-report of the closed #1972/#2006: a layoutId indicator (nav underline /
highlight) animates to the wrong position when sibling content height changes
at the same time, and the horizontal-only workaround from #1972 doesn't help
for vertically-stacked navs. A commenter found style={{ originY: '0px' }}
(or originX for horizontal) papers over it per-direction. This is the same
phenomenon issue #1935 requests a real mechanism for (shared animation
resolved relative to a layout ancestor instead of page space): the shared
element's page-space origin goes stale the instant surrounding content
shifts.
codesandbox.io/p/devbox/framer-motion-layoutid-bug-vertical-scroll-v92zzt)
were unreachable at planning time (Cloudflare 403). #1972's sandbox
(framer-motion-layoutid-issue-uu7kb9) likewise. Retry once; otherwise
reconstruct: a VERTICAL list of nav items with a layoutId="indicator"
highlight, where selecting an item also expands/collapses content ABOVE
the list (height change → vertical shift), mirroring #1972's description
plus this issue's vertical orientation.packages/motion-dom/src/projection/shared/stack.ts:45-73); relative
resolution bails for shared-child/non-shared-parent combos
(packages/motion-dom/src/projection/node/create-projection-node.ts:1315-1335);
origin defaults (originX/originY 0.5) explain why the commenter's
originY: '0px' changes the failure shape — removeBoxTransforms/box
correction uses tracked origins, and pinning the origin aligns the stale
delta along one axis only.dev/react/src/tests/layout-shared-vertical-shift.tsx exporting App:
#expander: a div above the nav whose height toggles 0 ↔ 200px with a
button (NO layout props — instant shift, as in real apps).<motion.div layoutId="indicator" transition={{ type: "tween", ease: "linear", duration: 10 }} />.Spec packages/framer-motion/cypress/integration/layout-shared-vertical-shift.ts:
click item 2; cy.wait(500); .then() on the indicator rect: assert it lies
between its old and new boxes as measured in the SHIFTED coordinate space
(i.e. its x/y at 5% progress should be ≈ old position + expander height, not
the stale pre-shift position). On current main this fails by ≈ the expander
height on the y axis.
Verify: spec fails on main with the predicted signature → reproduction confirmed; record the delta. If it does NOT fail, try the #1972 horizontal variant once; if still clean, go to Step 3b.
Do not fix here. Reference the spec from plans/issues/issue-1935.md Phase 3 gate 3 (it is the same scenario, vertical flavor). Keep the test page + spec on the issue-1935 branch or attach to the issue as a gist if 1935 is not yet approved — per repo policy do NOT merge a permanently-red or never-green test on its own.
Comment on #2514: confirmed at <commit>, root cause is shared-stack
animations resolving in page space while content shifts (same as #1935),
fix tracked there; include the originX/originY per-axis workaround caveat.
Recommend closing as duplicate-tracked-by-#1935. Close ONLY after the
plans/issues/README.md row reads APPROVED-CLOSE:
gh api -X PATCH repos/motiondivision/motion/issues/2514 -f state=closed -f state_reason=not_planned
(state_reason duplicate is not API-settable; mention #1935 in the comment).
Comment asking for an updated reproduction (note the old sandboxes are gone/unreachable), recommend close-as-needs-repro; same approval gate.
APPROVED-CLOSEplans/issues/README.md row updated