@view-transition {
    navigation: auto;
}

html[data-page="world"] .world-canvas,
html[data-page="world"] .world-deferred-shared-target,
html[data-page="resume"] .resume-world-portal__visual {
    view-transition-name: personal-world;
}

/*
 * A resume return carries one validated alpha-backed planet frame. Make that
 * exact frame the sole destination shared element so the browser never
 * interpolates toward a transparent placeholder (or captures a second
 * "ghost" planet inside the root snapshot).
 */
html[data-page="world"][data-return-snapshot-state="available"] .world-canvas,
html[data-page="world"][data-return-snapshot-state="available"] .world-deferred-shared-target,
html[data-page="world"][data-return-snapshot-state="available"] .astro-world-shared-target {
    view-transition-name: none;
}

html[data-page="world"][data-return-snapshot-state="available"] .astro-world-return-snapshot {
    view-transition-name: personal-world;
}

html[data-page="world"] .world-deferred-placeholder {
    position: fixed;
    inset: 0;
    min-height: 100vh;
    min-height: 100svh;
    overflow: hidden;
    background: #a8ced4;
}

html[data-page="world"] .world-deferred-shared-target {
    position: fixed;
    top: 50%;
    left: 50%;
    display: block;
    width: min(84vmin, 820px);
    height: min(84vmin, 820px);
    opacity: 0;
    pointer-events: none;
    transform: translate3d(-50%, -50%, 0);
}

html[data-page="world"] .world-resume-handoff-snapshot {
    view-transition-name: none;
}

html[data-page="world"]
    .world-shell[data-transition-phase="overview-hold"][data-transition-direction="to-resume"][data-resume-handoff-snapshot="captured"]
    .world-canvas {
    view-transition-name: none;
}

html[data-page="world"]
    .world-shell[data-transition-phase="overview-hold"][data-transition-direction="to-resume"][data-resume-handoff-snapshot="captured"]
    .world-resume-handoff-snapshot {
    view-transition-name: personal-world;
}

/*
 * Resume entrance layers are captured independently from the page background.
 * Their destination snapshots can therefore move in opposite directions while
 * the planet is still flying to its portal, without competing with GSAP for
 * ownership of the live elements' transforms.
 */
html[data-page="resume"] .navbar {
    view-transition-name: resume-navigation;
}

html[data-page="resume"] .experiments-header-wrapper {
    view-transition-name: resume-hero;
}

html[data-page="resume"] .cards-wrapper {
    view-transition-name: resume-cards;
}

/*
 * The reverse transition already clears these live layers before navigation.
 * Remove their individual names as soon as that direction is selected so they
 * cannot escape the hidden root snapshot during resume -> world.
 */
html[data-page="resume"][data-page-transition-direction="to-world"] .navbar,
html[data-page="resume"][data-page-transition-direction="to-world"] .experiments-header-wrapper,
html[data-page="resume"][data-page-transition-direction="to-world"] .cards-wrapper {
    view-transition-name: none;
}

html[data-page="resume"] .resume-world-portal {
    transform-origin: 50% 50%;
}

/*
 * Resume remains the stationary underlay while the live planet freezes and
 * its exact frame is captured in place. The cross-document shared element
 * owns both the flight from the upper-left portal and the enlargement; hiding
 * these layers before navigation creates a white gap behind that flight.
 */
html[data-page="resume"][data-page-transition-state="freezing-return"] .navbar,
html[data-page="resume"][data-page-transition-state="capturing-return"] .navbar,
html[data-page="resume"][data-page-transition-state="leaving"] .navbar,
html[data-page="resume"][data-page-transition-state="freezing-return"] main,
html[data-page="resume"][data-page-transition-state="capturing-return"] main,
html[data-page="resume"][data-page-transition-state="leaving"] main,
html[data-page="resume"][data-page-transition-state="freezing-return"] .detail-modal-overlay,
html[data-page="resume"][data-page-transition-state="capturing-return"] .detail-modal-overlay,
html[data-page="resume"][data-page-transition-state="leaving"] .detail-modal-overlay,
html[data-page="resume"][data-page-transition-state="freezing-return"] .site-footer,
html[data-page="resume"][data-page-transition-state="capturing-return"] .site-footer,
html[data-page="resume"][data-page-transition-state="leaving"] .site-footer {
    pointer-events: none;
}

html[data-page="resume"][data-page-transition-state="freezing-return"] .resume-world-portal,
html[data-page="resume"][data-page-transition-state="capturing-return"] .resume-world-portal,
html[data-page="resume"][data-page-transition-state="leaving"][data-page-transition-direction="to-world"] .resume-world-portal {
    filter: saturate(1.08) brightness(1.04);
    pointer-events: none;
}

::view-transition-group(root) {
    animation-duration: 1080ms;
    animation-fill-mode: both;
    animation-timing-function: cubic-bezier(0.22, 1, 0.36, 1);
}

::view-transition-image-pair(root),
::view-transition-old(root),
::view-transition-new(root),
::view-transition-image-pair(personal-world),
::view-transition-old(personal-world),
::view-transition-new(personal-world),
::view-transition-image-pair(resume-navigation),
::view-transition-old(resume-navigation),
::view-transition-new(resume-navigation),
::view-transition-image-pair(resume-hero),
::view-transition-old(resume-hero),
::view-transition-new(resume-hero),
::view-transition-image-pair(resume-cards),
::view-transition-old(resume-cards),
::view-transition-new(resume-cards) {
    mix-blend-mode: normal;
}

::view-transition-image-pair(root) {
    isolation: isolate;
}

/*
 * Keep the shared element on top of both documents. The browser still owns
 * the geometry interpolation; these rules only stage timing and cross-fade.
 */
::view-transition-group(personal-world) {
    z-index: 10000;
    overflow: visible;
    animation-duration: 980ms;
    animation-fill-mode: both;
    animation-timing-function: cubic-bezier(0.2, 0.86, 0.24, 1);
}

::view-transition-image-pair(personal-world) {
    overflow: visible;
    border-radius: 0;
    isolation: isolate;
}

::view-transition-old(personal-world),
::view-transition-new(personal-world) {
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center;
    animation-duration: 980ms;
    animation-fill-mode: both;
    animation-timing-function: cubic-bezier(0.22, 1, 0.36, 1);
}

/*
 * World -> resume: the shared planet travels from the centred handoff circle
 * to the upper-left portal while the destination layers resolve in parallel.
 */
html[data-page="resume"]::view-transition-group(root) {
    z-index: 0;
    animation-duration: 980ms;
}

html[data-page="resume"]::view-transition-new(root) {
    z-index: 0;
    animation: none;
    opacity: 1;
}

html[data-page="resume"]::view-transition-old(root) {
    z-index: 1;
    animation: personal-world-sky-out-to-resume 900ms cubic-bezier(0.4, 0, 0.2, 1) both;
}

html[data-page="resume"]::view-transition-old(personal-world) {
    animation-name: personal-world-source-handoff;
}

html[data-page="resume"]::view-transition-new(personal-world) {
    animation-name: personal-world-target-underlay;
}

html[data-page="resume"]::view-transition-group(resume-navigation),
html[data-page="resume"]::view-transition-group(resume-hero),
html[data-page="resume"]::view-transition-group(resume-cards) {
    z-index: 120;
    animation-duration: 980ms;
    animation-fill-mode: both;
}

html[data-page="resume"]::view-transition-group(resume-navigation) {
    z-index: 160;
}

html[data-page="resume"]::view-transition-group(resume-hero) {
    z-index: 140;
}

html[data-page="resume"]::view-transition-old(resume-navigation),
html[data-page="resume"]::view-transition-old(resume-hero),
html[data-page="resume"]::view-transition-old(resume-cards) {
    animation: none;
    opacity: 0;
}

html[data-page="resume"]::view-transition-new(resume-navigation) {
    animation: personal-resume-navigation-in 600ms cubic-bezier(0.16, 1, 0.3, 1) 40ms both;
}

html[data-page="resume"]::view-transition-new(resume-hero) {
    animation: personal-resume-hero-in 700ms cubic-bezier(0.16, 1, 0.3, 1) 70ms both;
}

html[data-page="resume"]::view-transition-new(resume-cards) {
    animation: personal-resume-cards-in 760ms cubic-bezier(0.16, 1, 0.3, 1) 110ms both;
}

/* Resume -> world: fly the upper-left planet to centre while enlarging it. */
html[data-page="world"]::view-transition-group(root) {
    z-index: 0;
    animation-duration: 860ms;
}

html[data-page="world"]::view-transition-group(personal-world) {
    /*
     * The source keeps its authored upper-left portal geometry. This one
     * compositor-owned interpolation moves and enlarges it directly into the
     * centred 84vmin live-scene hold while world sky fades over the resume.
     */
    animation-delay: 0ms;
    animation-duration: 820ms;
}

html[data-page="world"]::view-transition-old(root) {
    z-index: 0;
    animation: none;
    opacity: 1;
}

html[data-page="world"]::view-transition-new(root) {
    z-index: 1;
    animation: personal-world-sky-in-to-world 820ms cubic-bezier(0.22, 1, 0.36, 1) both;
}

html[data-page="world"]::view-transition-old(personal-world),
html[data-page="world"]::view-transition-new(personal-world) {
    animation-delay: 0ms;
    animation-duration: 820ms;
}

html[data-page="world"]::view-transition-old(personal-world) {
    animation-name: personal-world-source-handoff;
}

html[data-page="world"]::view-transition-new(personal-world) {
    animation-name: personal-world-target-underlay;
}

@keyframes personal-world-sky-out-to-resume {
    0% {
        opacity: 1;
    }

    72% {
        opacity: 0.08;
    }

    100% {
        opacity: 0;
    }
}

@keyframes personal-world-sky-in-to-world {
    0% {
        opacity: 0;
    }

    22% {
        opacity: 0.08;
    }

    100% {
        opacity: 1;
    }
}

@keyframes personal-resume-navigation-in {
    0% {
        opacity: 0;
        transform: translateY(-16px);
    }

    100% {
        opacity: 1;
        transform: translateY(0);
    }
}

@keyframes personal-resume-hero-in {
    0% {
        opacity: 0;
        transform: translateY(-28px);
    }

    100% {
        opacity: 1;
        transform: translateY(0);
    }
}

@keyframes personal-resume-cards-in {
    0% {
        opacity: 0;
        transform: translateY(52px) scale(0.985);
    }

    100% {
        opacity: 1;
        transform: translateY(0) scale(1);
    }
}

@keyframes personal-world-source-handoff {
    0%,
    100% {
        opacity: 1;
    }
}

@keyframes personal-world-target-underlay {
    0%,
    100% {
        opacity: 0;
    }
}

@media (prefers-reduced-motion: reduce) {
    html[data-page="resume"] .navbar,
    html[data-page="resume"] main,
    html[data-page="resume"] .detail-modal-overlay,
    html[data-page="resume"] .site-footer,
    html[data-page="resume"] .resume-world-portal,
    ::view-transition-group(root),
    ::view-transition-old(root),
    ::view-transition-new(root),
    ::view-transition-group(personal-world),
    ::view-transition-image-pair(personal-world),
    ::view-transition-old(personal-world),
    ::view-transition-new(personal-world),
    ::view-transition-group(resume-navigation),
    ::view-transition-old(resume-navigation),
    ::view-transition-new(resume-navigation),
    ::view-transition-group(resume-hero),
    ::view-transition-old(resume-hero),
    ::view-transition-new(resume-hero),
    ::view-transition-group(resume-cards),
    ::view-transition-old(resume-cards),
    ::view-transition-new(resume-cards) {
        animation-delay: 0ms !important;
        animation-duration: 1ms !important;
        transition-duration: 1ms !important;
    }
}
