@use "sass:map";

/* Where each sub-menu panel rests outside the menu, and the transform that
   slides it into view. Both effects animate along the same axis, so the whole
   direction matrix is generated from this one table. */
$pp-slide-menu-directions: (
    left: (
        top: 0,
        start: 100%,
        transform: translateX(-100%),
        vertical: false,
    ),
    right: (
        top: 0,
        start: -100%,
        transform: translateX(100%),
        vertical: false,
    ),
    top: (
        top: 100%,
        start: 0,
        transform: translateY(-100%),
        vertical: true,
    ),
    bottom: (
        top: -100%,
        start: 0,
        transform: translateY(100%),
        vertical: true,
    ),
);

.pp-icon {
    display: inline-block;
    line-height: 1;
    text-align: center;
    transition: all .3s;

    i,
    svg {
        width: 1em;
        height: 1em;
        position: relative;
        display: block;
    }
}

.pp-slide-menu {
    width: 100%;
    position: relative;
    overflow: hidden;
    display: inline-block;
    background: #fff;

    ul {
        position: relative;
        width: 100%;
        margin: 0;
        padding-inline-start: 0;
        list-style: none;
    }

    a,
    a:hover {
        text-decoration: none;
    }
}

.pp-slide-menu .pp-slide-menu-sub-menu {
    width: 100%;
    position: absolute;
    background: #fff;

    /* Arrow glyphs are position:relative, so without an explicit stacking order
       the ones belonging to later parent items paint over this panel. */
    z-index: 1;
}

/* The active panel's height is applied inline to the root list, so it has to be
   transitioned alongside the slide or the container snaps between levels. */
.pp-slide-menu .pp-slide-menu__menu,
.pp-slide-menu .pp-slide-menu-sub-menu {
    transition: transform .3s ease-in-out, height .3s ease-in-out;
    margin: 0;
    padding: 0;
}

.pp-slide-menu .pp-slide-menu-sub-menu:not(.pp-slide-menu-is-active) {
    opacity: 0;
    transition: transform .3s ease-in-out, opacity .3s ease;
}

.pp-slide-menu .pp-slide-menu-item {
    display: -ms-flexbox;
    display: flex;
    -ms-flex-direction: row-reverse;
    flex-direction: row-reverse;
    -ms-flex-align: center;
    align-items: center;
    border-bottom: 1px solid;
    transition: opacity .3s ease-in-out;
}

.pp-slide-menu .pp-slide-menu-back {
    -ms-flex-direction: row;
    flex-direction: row;

    > .pp-slide-menu-arrow {
        border-inline-end: 1px solid rgba(172, 170, 170, 0.2);
    }
}

.pp-slide-menu .pp-slide-menu-arrow,
.pp-slide-menu .pp-slide-menu-item {
    border-color: rgba(172, 170, 170, 0.2);
}

.pp-slide-menu .pp-menu-item-back,
.pp-slide-menu .pp-slide-menu-item-link {
    display: inline-block;
    -ms-flex-positive: 1;
    flex-grow: 1;
    color: #333;
}

.pp-slide-menu .pp-slide-menu-arrow,
.pp-slide-menu .pp-slide-menu-item-link {
    padding: 10px 12px;
    transition: all .3s linear;
}

.pp-slide-menu .pp-slide-menu-arrow {
    padding: 10px 24px;
    cursor: pointer;
}

/* Descriptions sit inside the link so they share its hit area, but they belong
   on their own line under the label. */
.pp-slide-menu .pp-slide-menu-item-description {
    display: block;
}

/* The back row is a real button, so the UA styling has to be stripped back to
   match the anchors it sits alongside. Colour and padding are deliberately left
   to the shared .pp-slide-menu-item-link rules. */
.pp-slide-menu button.pp-slide-menu-item-link {
    appearance: none;
    background: none;
    border: 0;
    margin: 0;
    font: inherit;
    text-align: inherit;
    cursor: pointer;
}

.pp-slide-menu .pp-slide-menu-arrow:focus-visible,
.pp-slide-menu .pp-slide-menu-item-link:focus-visible {
    outline: 2px solid currentcolor;
    outline-offset: -2px;
}

.pp-slide-menu .pp-slide-menu-item.pp-slide-menu-item-has-children > .pp-slide-menu-arrow {
    border-inline-start: 1px solid rgba(172, 170, 170, 0.2);
}

/* Accordion mode. Panels leave the absolutely positioned overlay world and join
   the flow under their parent row, so the direction and effect rules below stop
   applying on their own. The widget-level prefix is needed on every selector to
   outrank the panel rules above, which are scoped to .pp-slide-menu. */
.elementor-widget-pp-slide-menu.pp-slide-menu-submenu--accordion {

    .pp-slide-menu .pp-slide-menu-item {
        flex-wrap: wrap;
    }

    .pp-slide-menu .pp-slide-menu-sub-menu {
        position: static;
        display: none;
        opacity: 1;
        flex: 0 0 100%;
        width: 100%;
        z-index: auto;
    }

    .pp-slide-menu .pp-slide-menu-submenu-open > .pp-slide-menu-sub-menu {
        display: block;
    }

    // The default indicator points along the row when collapsed; turning it a
    // quarter turn points it at the panel it just opened. Only the glyph turns -
    // the arrow box carries the separator border, background and padding, all of
    // which would rotate with it. The rotation is left alone in RTL because the
    // glyph is not mirrored either, so flipping it would point the arrow away
    // from the panel.
    .pp-slide-menu .pp-slide-menu-submenu-open > .pp-slide-menu-arrow i,
    .pp-slide-menu .pp-slide-menu-submenu-open > .pp-slide-menu-arrow svg {

        /*rtl:ignore*/
        transform: rotate(90deg);
    }
}

/* The fade below is push-only: that effect slides the parent list out from
   under the sub-menu, whereas overlay simply covers it. */
.elementor-widget-pp-slide-menu.pp-slide-menu-effect--push {

    .pp-slide-menu-sub-menu.pp-slide-menu-is-active {
        z-index: 999;
    }

    .pp-slide-menu-is-active-parent > li:not(.pp-slide-menu-item-is-active) {
        opacity: 0;
    }
}

@each $direction, $config in $pp-slide-menu-directions {

    .elementor-widget-pp-slide-menu.pp-slide-menu-direction--#{$direction} {

        .pp-slide-menu-sub-menu {
            top: map.get($config, top);
            inset-inline-start: map.get($config, start);
        }

        &.pp-slide-menu-effect--overlay .pp-slide-menu-sub-menu.pp-slide-menu-is-active {
            transform: map.get($config, transform);
        }

        &.pp-slide-menu-effect--push {

            @if map.get($config, vertical) {
                overflow-y: hidden;
            }

            .pp-slide-menu-is-active-parent {
                transform: map.get($config, transform);
            }
        }
    }
}
