@notificationPrefixCls: rc-notification;
@notificationMotionDuration: 0.3s;
@notificationMotionEase: cubic-bezier(0.22, 1, 0.36, 1);
@notificationMotionOffset: 64px;

.generate-placement(
  @placement,
  @vertical,
  @horizontal,
  @flexDirection,
  @transformOrigin,
  @stackClip,
  @motionX
) {
  &-@{placement} {
    @{vertical}: 0;
    @{horizontal}: 0;
    display: flex;
    flex-direction: @flexDirection;

    .@{notificationPrefixCls}-notice {
      @{vertical}: var(--notification-y, 0);
      @{horizontal}: 0;
      transform-origin: @transformOrigin;
    }

    .@{notificationPrefixCls}-fade-appear-prepare,
    .@{notificationPrefixCls}-fade-enter-prepare {
      opacity: 0;
      transform: translateX(@motionX) scale(var(--notification-scale, 1));
      transition: none;
    }

    .@{notificationPrefixCls}-fade-appear-start,
    .@{notificationPrefixCls}-fade-enter-start {
      opacity: 0;
      transform: translateX(@motionX) scale(var(--notification-scale, 1));
    }

    .@{notificationPrefixCls}-fade-appear-active,
    .@{notificationPrefixCls}-fade-enter-active {
      opacity: 1;
      transform: translateX(0) scale(var(--notification-scale, 1));
    }

    .@{notificationPrefixCls}-fade-leave-start {
      opacity: 1;
      transform: translateX(0) scale(var(--notification-scale, 1));
    }

    .@{notificationPrefixCls}-fade-leave-active {
      opacity: 0;
      transform: translateX(@motionX) scale(var(--notification-scale, 1));
    }

    &.@{notificationPrefixCls}-stack:not(.@{notificationPrefixCls}-stack-expanded) {
      .@{notificationPrefixCls}-notice {
        clip-path: @stackClip;
      }

      .@{notificationPrefixCls}-notice[data-notification-index='0'] {
        clip-path: inset(-50% -50% -50% -50%);
      }
    }
  }
}

.generate-center-placement(
  @placement,
  @vertical,
  @flexDirection,
  @transformOrigin,
  @stackClip,
  @motionY
) {
  &-@{placement} {
    @{vertical}: 0;
    left: 50%;
    display: flex;
    flex-direction: @flexDirection;
    transform: translateX(-50%);

    .@{notificationPrefixCls}-notice {
      @{vertical}: var(--notification-y, 0);
      left: 0;
      transform-origin: @transformOrigin;
    }

    .@{notificationPrefixCls}-fade-appear-prepare,
    .@{notificationPrefixCls}-fade-enter-prepare {
      opacity: 0;
      transform: translateY(@motionY) scale(var(--notification-scale, 1));
      transition: none;
    }

    .@{notificationPrefixCls}-fade-appear-start,
    .@{notificationPrefixCls}-fade-enter-start {
      opacity: 0;
      transform: translateY(@motionY) scale(var(--notification-scale, 1));
    }

    .@{notificationPrefixCls}-fade-appear-active,
    .@{notificationPrefixCls}-fade-enter-active {
      opacity: 1;
      transform: translateY(0) scale(var(--notification-scale, 1));
    }

    .@{notificationPrefixCls}-fade-leave-start {
      opacity: 1;
      transform: translateY(0) scale(var(--notification-scale, 1));
    }

    .@{notificationPrefixCls}-fade-leave-active {
      opacity: 0;
      transform: translateY(@motionY) scale(var(--notification-scale, 1));
    }

    &.@{notificationPrefixCls}-stack:not(.@{notificationPrefixCls}-stack-expanded) {
      .@{notificationPrefixCls}-notice {
        clip-path: @stackClip;
      }

      .@{notificationPrefixCls}-notice[data-notification-index='0'] {
        clip-path: inset(-50% -50% -50% -50%);
      }
    }
  }
}

.@{notificationPrefixCls} {
  position: fixed;
  z-index: 1000;
  width: 360px;
  height: 100vh;
  padding: 24px;
  box-sizing: border-box;
  pointer-events: none;
  overflow: hidden;
  overscroll-behavior: contain;

  .generate-placement(
    topRight,
    top,
    right,
    column,
    ~'center bottom',
    inset(50% -50% -50% -50%),
    @notificationMotionOffset
  );
  .generate-placement(
    bottomRight,
    bottom,
    right,
    column-reverse,
    ~'center top',
    inset(-50% -50% 50% -50%),
    @notificationMotionOffset
  );
  .generate-placement(
    topLeft,
    top,
    left,
    column,
    ~'center bottom',
    inset(50% -50% -50% -50%),
    -@notificationMotionOffset
  );
  .generate-placement(
    bottomLeft,
    bottom,
    left,
    column-reverse,
    ~'center top',
    inset(-50% -50% 50% -50%),
    -@notificationMotionOffset
  );
  .generate-center-placement(
    top,
    top,
    column,
    ~'center bottom',
    inset(50% -50% -50% -50%),
    -@notificationMotionOffset
  );
  .generate-center-placement(
    bottom,
    bottom,
    column-reverse,
    ~'center top',
    inset(-50% -50% 50% -50%),
    @notificationMotionOffset
  );

  &-list {
    overflow-x: hidden;
    overflow-y: auto;
    overscroll-behavior: contain;
    -ms-overflow-style: none;
    scrollbar-width: none;

    &::-webkit-scrollbar {
      display: none;
      width: 0;
      height: 0;
    }
  }

  &-list-content {
    position: relative;
    display: flex;
    flex-shrink: 0;
    flex-direction: column;
    gap: 8px;
    width: 100%;
    pointer-events: none;
    transition: transform @notificationMotionDuration @notificationMotionEase;
    will-change: transform;
  }

  &-stack-expanded {
    pointer-events: auto;

    .@{notificationPrefixCls}-list-content {
      transition: none;
    }
  }

  &-notice {
    position: absolute;
    box-sizing: border-box;
    width: 100%;
    padding: 14px 16px;
    border: 2px solid #111;
    border-radius: 14px;
    background: linear-gradient(180deg, #ffffff 0%, #f4f9ff 100%);
    box-shadow: 8px 8px 0 rgba(0, 0, 0, 0.16);
    color: #111;
    font-size: 14px;
    line-height: 1.5;
    pointer-events: auto;
    transform: scale(var(--notification-scale, 1));
    transition:
      transform @notificationMotionDuration @notificationMotionEase,
      inset @notificationMotionDuration @notificationMotionEase,
      clip-path @notificationMotionDuration @notificationMotionEase,
      opacity @notificationMotionDuration @notificationMotionEase;

    &-section {
      padding-right: 36px;
      white-space: pre-wrap;
    }

    &:not(&-closable) &-section {
      padding-right: 0;
    }

    &-close {
      position: absolute;
      top: 12px;
      right: 12px;
      display: inline-flex;
      align-items: center;
      justify-content: center;
      width: 28px;
      height: 28px;
      border: 2px solid #111;
      border-radius: 999px;
      background: #fff;
      color: #111;
      font-size: 14px;
      line-height: 1;
      cursor: pointer;
      transition:
        transform @notificationMotionDuration @notificationMotionEase,
        box-shadow @notificationMotionDuration @notificationMotionEase,
        background-color @notificationMotionDuration @notificationMotionEase;

      &:hover {
        background: #f4f9ff;
        box-shadow: 4px 4px 0 rgba(0, 0, 0, 0.12);
      }
    }

    &-progress {
      position: absolute;
      right: 16px;
      bottom: 8px;
      left: 16px;
      display: block;
      inline-size: auto;
      block-size: 2px;
      overflow: hidden;
      border: 0;
      border-radius: 1px;
      appearance: none;
      -webkit-appearance: none;

      &,
      &::-webkit-progress-bar {
        background-color: rgba(0, 0, 0, 0.08);
      }

      &::-moz-progress-bar {
        background-color: #31afff;
      }

      &::-webkit-progress-value {
        background-color: #31afff;
      }
    }
  }

  &-stack {
    .@{notificationPrefixCls}-notice {
      clip-path: inset(-50% -50% -50% -50%);
    }

    &:not(.@{notificationPrefixCls}-stack-expanded) {
      .@{notificationPrefixCls}-notice {
        --notification-scale: ~'calc(1 - min(var(--notification-index, 0), 2) * 0.06)';
      }

      .@{notificationPrefixCls}-notice:not(.@{notificationPrefixCls}-notice-stack-in-threshold) {
        opacity: 0;
        pointer-events: none;
      }
    }
  }
}

.@{notificationPrefixCls}-fade {
  backface-visibility: hidden;
  will-change: transform, opacity;
}
