Page Transition Out In Timing
Page transitions must use asymmetric timing: exit in 150-200ms (ease-in, accelerating out of view) and entrance in 250-400ms (ease-out, decelerating into position) — exits must complete before entrance begins in route-ba…
$ prime install @community/rule-page-transition-out-in-timing Projection
Always in _index.xml · the agent never has to ask for this.
PageTransitionOutInTiming [rule] v1.0.0
Exit is intentional — the user chose to leave. The animation should confirm the decision quickly (150ms) with an accelerating curve (ease-in) that reads as 'departing'. Entrance is discovery — the user is absorbing new content. It should decelerate into position (ease-out, 300ms) giving the eye time to orient. Symmetric timing (same duration for both) feels indecisive and makes the total transition 100ms longer than necessary.
Page transitions must use asymmetric timing: exit in 150-200ms (ease-in, accelerating out of view) and entrance in 250-400ms (ease-out, decelerating into position) — exits must complete before entrance begins in route-based systems, or overlap by ≤50ms via out-in mode.
Loaded when retrieval picks the atom as adjacent / supporting.
PageTransitionOutInTiming [rule] v1.0.0
Exit is intentional — the user chose to leave. The animation should confirm the decision quickly (150ms) with an accelerating curve (ease-in) that reads as 'departing'. Entrance is discovery — the user is absorbing new content. It should decelerate into position (ease-out, 300ms) giving the eye time to orient. Symmetric timing (same duration for both) feels indecisive and makes the total transition 100ms longer than necessary.
Page transitions must use asymmetric timing: exit in 150-200ms (ease-in, accelerating out of view) and entrance in 250-400ms (ease-out, decelerating into position) — exits must complete before entrance begins in route-based systems, or overlap by ≤50ms via out-in mode.
Thresholds
- Exit Duration: 150-200ms
- Exit Easing: ease-in — cubic-bezier(0.4, 0, 1, 1)
- Entrance Duration: 250-400ms
- Entrance Easing: ease-out — cubic-bezier(0.16, 1, 0.3, 1)
- Total Max: 550ms (exit 200ms + entrance 350ms)
- Overlap: 0-50ms — exit must be mostly complete before entrance starts
Code
/* View Transitions API */
::view-transition-old(root) {
animation: exit-page 200ms cubic-bezier(0.4, 0, 1, 1) both;
}
::view-transition-new(root) {
animation: enter-page 350ms cubic-bezier(0.16, 1, 0.3, 1) both;
}
@keyframes exit-page { to { opacity: 0; transform: translateX(-30px); } }
@keyframes enter-page { from { opacity: 0; transform: translateX(30px); } }
/* Framer Motion / Motion.dev */
/* <AnimatePresence mode="wait"> — wait mode ensures exit completes before entrance */
/* exit: { opacity: 0, x: -30, transition: { duration: 0.2, ease: [0.4, 0, 1, 1] } } */
/* initial: { opacity: 0, x: 30 } */
/* animate: { opacity: 1, x: 0, transition: { duration: 0.35, ease: [0.16, 1, 0.3, 1] } } */
@media (prefers-reduced-motion: reduce) {
::view-transition-old(root),
::view-transition-new(root) { animation-duration: 0.01ms !important; }
}
Applies When
- SPA route changes (Next.js, React Router, Vue Router)
- Tab panel switching with enter/exit animations
- Wizard step transitions
- Full-page modal open/close
Loaded when retrieval picks the atom as a focal / direct hit.
PageTransitionOutInTiming [rule] v1.0.0
Exit is intentional — the user chose to leave. The animation should confirm the decision quickly (150ms) with an accelerating curve (ease-in) that reads as 'departing'. Entrance is discovery — the user is absorbing new content. It should decelerate into position (ease-out, 300ms) giving the eye time to orient. Symmetric timing (same duration for both) feels indecisive and makes the total transition 100ms longer than necessary.
Page transitions must use asymmetric timing: exit in 150-200ms (ease-in, accelerating out of view) and entrance in 250-400ms (ease-out, decelerating into position) — exits must complete before entrance begins in route-based systems, or overlap by ≤50ms via out-in mode.
Thresholds
- Exit Duration: 150-200ms
- Exit Easing: ease-in — cubic-bezier(0.4, 0, 1, 1)
- Entrance Duration: 250-400ms
- Entrance Easing: ease-out — cubic-bezier(0.16, 1, 0.3, 1)
- Total Max: 550ms (exit 200ms + entrance 350ms)
- Overlap: 0-50ms — exit must be mostly complete before entrance starts
Code
/* View Transitions API */
::view-transition-old(root) {
animation: exit-page 200ms cubic-bezier(0.4, 0, 1, 1) both;
}
::view-transition-new(root) {
animation: enter-page 350ms cubic-bezier(0.16, 1, 0.3, 1) both;
}
@keyframes exit-page { to { opacity: 0; transform: translateX(-30px); } }
@keyframes enter-page { from { opacity: 0; transform: translateX(30px); } }
/* Framer Motion / Motion.dev */
/* <AnimatePresence mode="wait"> — wait mode ensures exit completes before entrance */
/* exit: { opacity: 0, x: -30, transition: { duration: 0.2, ease: [0.4, 0, 1, 1] } } */
/* initial: { opacity: 0, x: 30 } */
/* animate: { opacity: 1, x: 0, transition: { duration: 0.35, ease: [0.16, 1, 0.3, 1] } } */
@media (prefers-reduced-motion: reduce) {
::view-transition-old(root),
::view-transition-new(root) { animation-duration: 0.01ms !important; }
}
Applies When
- SPA route changes (Next.js, React Router, Vue Router)
- Tab panel switching with enter/exit animations
- Wizard step transitions
- Full-page modal open/close
Rationale
The perceptual logic: exits feel slow when they decelerate (ease-out) because they drag — the user has already decided to go and the UI seems to resist. Entrances feel abrupt when they accelerate (ease-in) because content appears then snaps into position. Each direction has a natural easing.
Thresholds
- Exit Duration: 150-200ms
- Exit Easing: ease-in — cubic-bezier(0.4, 0, 1, 1)
- Entrance Duration: 250-400ms
- Entrance Easing: ease-out — cubic-bezier(0.16, 1, 0.3, 1)
- Total Max: 550ms (exit 200ms + entrance 350ms)
- Overlap: 0-50ms — exit must be mostly complete before entrance starts
Code
/* View Transitions API */
::view-transition-old(root) {
animation: exit-page 200ms cubic-bezier(0.4, 0, 1, 1) both;
}
::view-transition-new(root) {
animation: enter-page 350ms cubic-bezier(0.16, 1, 0.3, 1) both;
}
@keyframes exit-page { to { opacity: 0; transform: translateX(-30px); } }
@keyframes enter-page { from { opacity: 0; transform: translateX(30px); } }
/* Framer Motion / Motion.dev */
/* <AnimatePresence mode="wait"> — wait mode ensures exit completes before entrance */
/* exit: { opacity: 0, x: -30, transition: { duration: 0.2, ease: [0.4, 0, 1, 1] } } */
/* initial: { opacity: 0, x: 30 } */
/* animate: { opacity: 1, x: 0, transition: { duration: 0.35, ease: [0.16, 1, 0.3, 1] } } */
@media (prefers-reduced-motion: reduce) {
::view-transition-old(root),
::view-transition-new(root) { animation-duration: 0.01ms !important; }
}
Applies When
- SPA route changes (Next.js, React Router, Vue Router)
- Tab panel switching with enter/exit animations
- Wizard step transitions
- Full-page modal open/close
Source
prime-system/examples/frontend-design/primes/compiled/@community/rule-page-transition-out-in-timing/atom.yaml