@use "sass:map";
/* stylelint-disable no-descending-specificity, declaration-no-important */

/* -------------------------------------
   Design tokens & helpers
-------------------------------------- */
$mm-panel-height: 288px !default;
$mm-z-content: 2 !default;
$mm-gutter-x: map.get($spacers, 3) !default;
$mm-gutter-y: map.get($spacers, "2-5") !default;

/* Helpers */
@mixin link-reset {
  text-decoration: none;
  &:hover {
    text-decoration: underline;
  }
}

@mixin mm-item-padding($py: $mm-gutter-y, $px: $mm-gutter-x) {
  padding: $py $px;
}

/* -------------------------------------
   Component
-------------------------------------- */

.bcl-mega-menu {
  --bcl-mega-menu-zindex: 40;
}

// The mega menu position should not be relative to its nav item.
.nav-item:has(> .bcl-mega-menu) {
  @include media-breakpoint-up(lg) {
    position: static;
  }
}

// Low-specificity defaults for interactive elements inside the component.
// This does not apply to the trigger, which should get styles from the navbar.
.bcl-mega-menu__container {
  :where(a) {
    @include link-reset;
  }
  :where(a, button) {
    &:focus-visible {
      outline: 2px solid $primary;
      // Prevent outline from being cut off in scroll container.
      outline-offset: -2px;
    }
  }
}

// Disable page-level scroll while open, in lg+ viewport.
@include media-breakpoint-up(lg) {
  body:has(.bcl-mega-menu > [aria-expanded="true"]) {
    overflow-y: hidden;
  }
}

// Show a half-transparent page overlay in lg+ viewport.
@include media-breakpoint-up(lg) {
  .bcl-mega-menu:has(> [aria-expanded="true"]) {
    &::after {
      position: absolute;
      inset-inline: 0;
      background: #fff;
      opacity: 0.5;
      content: "";
      z-index: calc(var(--bcl-mega-menu-zindex) - 10);
      // The overlay can be as tall as we want, because the body scroll is disabled.
      block-size: 300vw;
    }
  }
}

// Use '[class]' to bump specificity.
// The element also has .dropdown-menu, causing competing styles.
.bcl-mega-menu__container[class] {
  // Only show when expanded.
  // Use ARIA state instead of .show sibling hacks.
  // @todo Explain why.
  display: none;
  .bcl-mega-menu > [aria-expanded="true"] + & {
    display: block;
    @include media-breakpoint-up(lg) {
      display: flex;
    }
  }
  // Override the z-index from bootstrap .dropdown-menu.
  z-index: var(--bcl-mega-menu-zindex);
  // Transition animation for open/close.
  @media (prefers-reduced-motion: no-preference) {
    transition:
      opacity 0.15s ease,
      transform 0.15s ease;
    .bcl-mega-menu > [aria-expanded="true"] + & {
      opacity: 1;
      transform: none;
    }
    .bcl-mega-menu > [aria-expanded="false"] + & {
      opacity: 0;
      transform: translateY(-4px);
      pointer-events: none;
    }
  }

  position: absolute;
  inset-block-start: 0;
  inset-inline-start: 0;
  inline-size: 100%;
  margin-block-start: 0;
  padding: 0;
  border: 0;
  border-radius: 0;

  @include media-breakpoint-up(lg) {
    inset-block-start: 100%;
    padding-block: map.get($spacers, "2-5");
    border-bottom: var(--bs-border-width) var(--bs-border-style)
      var(--bs-border-color);
  }
}

// Show a shadowy bar to separate content from links columns.
.bcl-mega-menu__container .shadow-container {
  // In medium viewport, the content appears above the links.
  // The shadowy bar is horizontal.
  @include media-breakpoint-up(lg) {
    position: relative;
    .shadow-bg {
      position: absolute;
      inset-inline-start: 50%;
      inset-block-end: 0;
      inline-size: 100vw;
      block-size: 8px;
      transform: translateX(-50%);
      box-shadow: 0 4px 5px 0 rgba(224, 229, 245, 0.5);
    }
  }
  // In larger viewport, the content appears left of the links.
  // The shadowy bar is vertical.
  @include media-breakpoint-up(xl) {
    block-size: 100%;
    position: absolute;
    inset-inline-end: 0;
    inset-block-start: 0;
    .shadow-bg {
      inset-inline-start: auto;
      inset-inline-end: 0;
      block-size: 100%;
      inline-size: 10px;
      transform: none;
      box-shadow: 4px 3px 4px 0 rgba(224, 229, 245, 0.5);
    }
  }
}

// The back button.
.bcl-mega-menu__back-button-block {
  position: relative;
  padding: 20px map.get($spacers, 1) 0;
  > .btn-link {
    @include link-reset;
  }
}

// Left column with the description and "Discover more" link.
.bcl-mega-menu__info {
  > .content-block {
    padding: $mm-gutter-x;
    background: $primary-bg-subtle;
    @include media-breakpoint-up(lg) {
      margin-inline-end: 0;
      background: $white;
      padding-inline-end: map.get($spacers, 4);
      // Allow vertical scrollbar if content is too tall.
      max-block-size: $mm-panel-height;
      overflow-y: auto;
    }

    > .content-link {
      @include link-reset;
    }
  }
}

// Add a scrollbar in desktop viewport.
@include media-breakpoint-up(lg) {
  .__submenu_body {
    block-size: $mm-panel-height;
    overflow-y: auto;
    scrollbar-color: $primary-bg-light-subtle transparent;
    scrollbar-width: thin;
    &:has(> .__see_all) {
      ul.bcl-mega-menu__items {
        height: calc(100% - 48px); /* 48px = see all button height */
      }
    }
  }
}

// Item lists on any level.
ul.bcl-mega-menu__items {
  list-style: none;
  margin: 0;
  padding-inline-start: 0;
  // Add space above in mobile viewport.
  @include media-breakpoint-down(lg) {
    margin: 1rem 0 0;
  }
  // Style the items.
  > li {
    // In mobile, items are separated by a border.
    @include media-breakpoint-down(lg) {
      &:not(:first-child) > * {
        border-top: 1px solid $primary-bg-subtle;
      }
    }
    > span,
    > a,
    > button {
      @include mm-item-padding();
      // Use flex for icon spacing.
      display: flex;
      gap: 1rem;
      justify-content: space-between;
      > svg {
        flex-shrink: 0;
        align-self: center;
      }
    }
    > a {
      color: $link-color;
      text-decoration: none;

      &:hover {
        text-decoration: underline;
      }
    }
    > a,
    > button {
      &:hover {
        background: $primary-bg-subtle;
      }
    }
    > span,
    > button {
      color: $dark;
    }
    // Buttons are used for parent items.
    > button {
      // Buttons don't occupy full width by default.
      width: 100%;
      // Unset common button styles.
      border: none;
      border-radius: 0;
      text-align: inherit;
      background: none;
      white-space: normal;

      // Show an icon.
      &::after {
        background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill-rule='evenodd' d='M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708'/%3E%3C/svg%3E");
        flex-shrink: 0;
        align-self: center;
        content: "";
        height: 1em;
        width: 1em;
      }

      &[aria-expanded="true"] {
        background: $primary-bg-subtle;
        @include media-breakpoint-up(lg) {
          // Simulate a border-left without having to adjust the padding.
          position: relative;
          &::before {
            content: "";
            position: absolute;
            width: 4px;
            top: 0;
            bottom: 0;
            left: 0;
            background-color: $primary;
          }
        }
      }
    }
  }
}

// First submenu.
.bcl-mega-menu__menu {
  // On desktop, sub-submenus are positioned relative to this one.
  @include media-breakpoint-up(lg) {
    position: relative;
    // Avoid a space between the parent menu and the submenu.
    @include padding-right(0);
  }
  @include media-breakpoint-down(lg) {
    > .bcl-mega-menu__items {
      &:has(.bcl-mega-menu__submenu:not([hidden])) {
        > .__leaf,
        > .__parent {
          display: none;
        }
      }
      > .__parent {
        &:has(.bcl-mega-menu__submenu:not([hidden])) {
          display: block;
        }
      }
    }
  }
}

// Nested submenu.
// This element has the 'hidden' attribute, unless it is expanded.
.bcl-mega-menu__submenu {
  // Position relative to the parent.
  position: absolute;
  // In mobile it covers the parent.
  @include media-breakpoint-down(lg) {
    inset: 0 0 auto;
    min-height: 100%;
  }
  // In desktop, it appears next to the parent.
  @include media-breakpoint-up(lg) {
    block-size: 100%;
    inset: 0 0 0 100%;
    inline-size: 100%;
  }

  // In mobile, there is a white background that covers the viewport width.
  @include media-breakpoint-down(lg) {
    &:before {
      position: absolute;
      content: "";
      left: 50%;
      margin-left: -50vw;
      width: 100vw;
      top: 0;
      height: 100%;
      background: white;
      z-index: -1;
    }
  }

  background: white;
  // In desktop, it gets a light background.
  @include media-breakpoint-up(lg) {
    background: $primary-bg-subtle;
  }

  // Layout for children
  display: flex;
  flex-direction: column;

  > .__header {
    // The title only shows in mobile.
    > .__label {
      @include mm-item-padding(map.get($spacers, 3));
      margin: 0;
      color: $dark;
      background: $primary-bg-subtle;
      display: block;
      font-size: 20px;
      @include media-breakpoint-up(lg) {
        display: none;
      }
    }
  }
  @include media-breakpoint-up(lg) {
    > .__submenu_body > .bcl-mega-menu__items {
      flex: 1 1 0;
      overflow-y: auto;
      > li > :is(span, a, button) {
        @include mm-item-padding($px: map.get($spacers, "4-25"));
      }
    }
  }
  .__see_all {
    border-top: 1px solid $neutral-border-color;
    @include media-breakpoint-up(lg) {
      border-top: 1px solid $primary-border-subtle;
      margin: 0 map.get($spacers, "4-25");
    }
    > .see-all-button {
      @include mm-item-padding();
      // Use flex for icon spacing.
      display: flex;
      align-items: center;
      color: $link-color;
      @include media-breakpoint-up(lg) {
        padding: $mm-gutter-y map.get($spacers, "4-25");
        margin: 0 -1.75rem;
      }
      &:hover {
        background: $primary-bg-subtle;
      }
      > svg {
        flex-shrink: 0;
      }
      > span {
        text-overflow: ellipsis;
        overflow: hidden;
        display: block;
        white-space: nowrap;
      }
    }
  }
}

// Set light-blue full-width background on some elements.
@include media-breakpoint-down(lg) {
  .bcl-mega-menu__submenu > .__header,
  .bcl-mega-menu .content-block,
  .bcl-mega-menu__back-button-block {
    position: relative;
    &::before {
      position: absolute;
      inset-inline-start: 50%;
      content: "";
      background: $primary-bg-subtle;
      inline-size: 100vw;
      block-size: 100%;
      inset-block-start: 0;
      z-index: -1;
      transform: translateX(-50%);
    }
  }
  .bcl-mega-menu {
    .__submenu_body {
      max-height: var(--oel-mega-menu-submenu-height);
      overflow: auto;
      scrollbar-color: $primary-bg-light-subtle transparent;
      scrollbar-width: thin;
    }
  }
}
