/* ************************************************** */
/* #region VARIABLES                                  */
/* ************************************************** */

:root {
    --dt-transition-duration: 200ms;
    --dt-slide-animation: var(--dt-transition-duration) ease-out both;
}

/* #endregion */

desktop-container {
    display: flex;
    position: absolute;
    min-width: 0;
    width: 100%;
    min-height: 0;
    height: 100%;
    padding-inline: calc(var(--grid-gap) / 2);
    padding-block: 0 calc(var(--grid-gap) / 2);
    overflow: auto;
    visibility: hidden;
    z-index: -1;
}

desktop-container.active {
    visibility: visible;
    z-index: 1;
}

/* ************************************************** */
/* #region ANIMATIONS                                 */
/* ************************************************** */

@keyframes ws-slide-out-left {
    to {
        transform: translateX(-100vw);
        opacity: 0;
    }
}
@keyframes ws-slide-in-right {
    from {
        transform: translateX(100vw);
        opacity: 0;
    }
}
@keyframes ws-slide-out-right {
    to {
        transform: translateX(100vw);
        opacity: 0;
    }
}
@keyframes ws-slide-in-left {
    from {
        transform: translateX(-100vw);
        opacity: 0;
    }
}

/* #endregion */

/* ************************************************** */
/* #region SLIDE TRANSITION - GENERAL                 */
/* ************************************************** */

/* Turn off default page cross-fade */
::view-transition-old(root),
::view-transition-new(root) {
    animation: none;
}

/* #endregion */

/* ************************************************** */
/* #region SLIDE TRANSITION - DESKTOP CONTAINER       */
/* ************************************************** */

desktop-container.active {
    view-transition-name: panels;
}

::view-transition-old(panels),
::view-transition-new(panels) {
    animation: var(--dt-slide-animation);
}

:root[data-ws-direction="right"]::view-transition-old(panels) {
    animation-name: ws-slide-out-left;
}
:root[data-ws-direction="right"]::view-transition-new(panels) {
    animation-name: ws-slide-in-right;
}

:root[data-ws-direction="left"]::view-transition-old(panels) {
    animation-name: ws-slide-out-right;
}
:root[data-ws-direction="left"]::view-transition-new(panels) {
    animation-name: ws-slide-in-left;
}

/* #endregion */

/* ************************************************** */
/* #region SLIDE TRANSITION - BODY FLOATERS (FLOATER_DESTINATION = 'body') */
/* ************************************************** */

/*
#body-floaters-container is a single persistent element living outside desktop-container (sibling in <body>), shared across every desktop — individual floaters inside it are shown/hidden per-desktop via [data-desktop-active], but the container node itself never gets destroyed/recreated on switch.

Named the same way desktop-container.active names "panels" — old/new snapshots of the WHOLE container are captured as one image and slide together using the same keyframes/direction plumbing "panels" uses.

Named after desktop-container in DOM order, so its view-transition-group naturally paints above "panels" — floaters stack above the desktop content during the slide.
*/
#body-floaters-container {
    view-transition-name: floaters;
}

::view-transition-old(floaters),
::view-transition-new(floaters) {
    animation: var(--dt-slide-animation);
}

:root[data-ws-direction="right"]::view-transition-old(floaters) {
    animation-name: ws-slide-out-left;
}
:root[data-ws-direction="right"]::view-transition-new(floaters) {
    animation-name: ws-slide-in-right;
}

:root[data-ws-direction="left"]::view-transition-old(floaters) {
    animation-name: ws-slide-out-right;
}
:root[data-ws-direction="left"]::view-transition-new(floaters) {
    animation-name: ws-slide-in-left;
}

/* #endregion */

/* ************************************************** */
/* #region SLIDE TRANSITION - PORTALS                 */
/* ************************************************** */

/*
.portal is the shared, single-instance widget canvas (MolstarPortal / KetcherPortal / ExcalidrawPortal) that gets reparented between panels/floaters/desktops on acquire/release. Its own match-element identity is what gives it a smooth morph when it moves from a floater to a panel (or vice versa) WITHIN the same desktop — that's the whole point of naming it individually.

But that same persistent identity is what made it glide from its old desktop's position/size to its new desktop's position/size during a DESKTOP SWITCH — because old-rect and new-rect are genuinely different places, unlike "panels"/"floaters" which are always full-viewport in both states. The extra rule below kills that.

TEST RULE — this is the new bit: data-ws-direction is stamped onto <html> for the duration of a desktop switch (see desktop-manager.js) and removed once the transition settles. While it's present, .portal loses its own view-transition-name entirely ("none" opts it out of independent capture), so instead of animating as its own group, it just gets flattened as pixels into whichever named ancestor currently contains it — "panels" if docked in a panel, "floaters" if floating. It has no independent existence to morph, so it rides along baked into the outgoing bitmap and reappears baked into the incoming bitmap — sliding/fading exactly like its container, no position/size tween.

Outside of a desktop switch (no data-ws-direction on <html>), .portal keeps its normal match-element behavior for panel↔floater docking.
*/
.portal {
    view-transition-name: match-element;
    view-transition-class: portals;
}

:root[data-ws-direction] .portal {
    view-transition-name: none;
}

::view-transition-group(*.portals) {
    animation-duration: var(--dt-transition-duration);
    animation-timing-function: ease-out;
}

::view-transition-old(*.portals),
::view-transition-new(*.portals) {
    animation: var(--dt-slide-animation);
}

:root[data-ws-direction="right"]::view-transition-old(*.portals) {
    animation-name: ws-slide-out-left;
}
:root[data-ws-direction="right"]::view-transition-new(*.portals) {
    animation-name: ws-slide-in-right;
}

:root[data-ws-direction="left"]::view-transition-old(*.portals) {
    animation-name: ws-slide-out-right;
}
:root[data-ws-direction="left"]::view-transition-new(*.portals) {
    animation-name: ws-slide-in-left;
}

/* #endregion */