$chromatic-color-variants: 'blue', 'red', 'green', 'cobalt', 'orange', 'pink',
  'purple';
$active-selector: ':where(.active, :hover):where(:not(:disabled))';

.Button {
  position: relative;
  box-sizing: border-box;
  transition:
    background-color var(--motion-transition-fast),
    box-shadow var(--motion-transition-fast);

  /* Size */
  &:where(.size-xs) {
    min-width: 20px;
    height: 20px;
    padding: 0 2px;

    &:where(.style-floating, .style-floating-alt) {
      padding: 0 7px;
    }
  }

  &:where(.size-s) {
    min-width: 24px;
    height: 24px;
    padding: 0 4px;

    &:where(.style-floating, .style-floating-alt) {
      padding: 0 9px;
    }
  }

  &:where(.size-m) {
    min-width: 36px;
    height: 36px;
    padding: 0 10px;

    &:where(.style-floating, .style-floating-alt) {
      padding: 0 14px;
    }
  }

  &:where(.size-l) {
    min-width: 44px;
    height: 44px;
    padding: 0 12px;

    &:where(.style-floating, .style-floating-alt) {
      padding: 0 18px;
    }
  }

  &:where(.size-xl) {
    min-width: 54px;
    height: 54px;
    padding: 0 20px;

    &:where(.style-floating, .style-floating-alt) {
      padding: 0 23px;
    }
  }

  &:where(.size-xs, .size-s) {
    & :where(.ButtonText) {
      padding: 0 3px;
    }
  }

  &:where(.size-m, .size-l, .size-xl) {
    & :where(.ButtonContent) {
      gap: 2px;
    }

    & :where(.ButtonText) {
      padding: 0 4px;
    }
  }

  /* Color variants */
  &:where(.style-primary) {
    @each $color-variant in $chromatic-color-variants {
      &:where(.color-#{$color-variant}) {
        color: var(--color-text-absolute-white);
        /* stylelint-disable-next-line bezier/validate-token */
        background-color: var(--color-fill-accent-#{$color-variant}-heavier);

        &#{$active-selector} {
          /* stylelint-disable-next-line bezier/validate-token */
          background-color: var(
            --color-fill-accent-#{$color-variant}-heavier-hovered
          );
        }
      }
    }

    &:where(.color-monochrome) {
      color: var(--color-text-absolute-white);
      background-color: var(--color-fill-absolute-black-light);

      &#{$active-selector} {
        background-color: var(--color-fill-absolute-black-light-hovered);
      }
    }

    &:where(.color-monochrome-light) {
      color: var(--color-text-absolute-white);
      background-color: var(--color-fill-neutral-heavier);
    }

    &:where(.color-monochrome-dark) {
      color: var(--color-text-inverse);
      background-color: var(--color-fill-neutral-heaviest);
    }
  }

  &:where(.style-secondary) {
    @each $color-variant in $chromatic-color-variants {
      &:where(.color-#{$color-variant}) {
        /* stylelint-disable bezier/validate-token */
        color: var(--color-text-accent-#{$color-variant});
        background-color: var(--color-fill-accent-#{$color-variant});

        &#{$active-selector} {
          background-color: var(--color-fill-accent-#{$color-variant}-hovered);
        }
        /* stylelint-enable bezier/validate-token */
      }
    }

    &:where(.color-monochrome) {
      color: var(--color-text-neutral);
      background-color: var(--color-fill-neutral-light);

      &#{$active-selector} {
        background-color: var(--color-fill-neutral-light-hovered);
      }
    }

    &:where(.color-monochrome-light) {
      color: var(--color-text-neutral-light);
      background-color: var(--color-fill-neutral-light);

      &#{$active-selector} {
        background-color: var(--color-fill-neutral-light-hovered);
      }
    }

    &:where(.color-monochrome-dark) {
      color: var(--color-text-neutral);
      background-color: var(--color-fill-neutral-light);

      &#{$active-selector} {
        background-color: var(--color-fill-neutral-light-hovered);
      }
    }
  }

  &:where(.style-tertiary) {
    background-color: transparent;

    @each $color-variant in $chromatic-color-variants {
      &:where(.color-#{$color-variant}) {
        /* stylelint-disable-next-line bezier/validate-token */
        color: var(--color-text-accent-#{$color-variant});

        &#{$active-selector} {
          /* stylelint-disable-next-line bezier/validate-token */
          background-color: var(--color-fill-accent-#{$color-variant}-hovered);
        }
      }
    }

    &:where(.color-monochrome) {
      color: var(--color-text-neutral);

      &#{$active-selector} {
        background-color: var(--color-fill-neutral-light-hovered);
      }
    }

    &:where(.color-monochrome-light) {
      color: var(--color-text-neutral-light);

      &#{$active-selector} {
        background-color: var(--color-fill-neutral-light-hovered);
      }
    }

    &:where(.color-monochrome-dark) {
      color: var(--color-text-neutral);

      &#{$active-selector} {
        background-color: var(--color-fill-neutral-light-hovered);
      }
    }
  }

  &:where(.style-floating, .style-floating-alt) {
    @each $color-variant in $chromatic-color-variants {
      &:where(.color-#{$color-variant}) {
        color: var(--color-text-absolute-white);
        /* stylelint-disable-next-line bezier/validate-token */
        background-color: var(--color-fill-accent-#{$color-variant}-heavier);

        &#{$active-selector} {
          /* stylelint-disable-next-line bezier/validate-token */
          background-color: var(
            --color-fill-accent-#{$color-variant}-heavier-hovered
          );
        }
      }
    }

    &:where(.color-monochrome) {
      color: var(--color-text-neutral);
      background-color: var(--color-fill-bright);
    }

    &:where(.color-monochrome-light) {
      color: var(--color-text-neutral-light);
      background-color: var(--color-fill-bright);
    }

    &:where(.color-monochrome-dark) {
      color: var(--color-text-neutral);
      background-color: var(--color-fill-bright);
    }
  }

  /* Effect */
  &:where(.style-primary, .style-secondary, .style-tertiary) {
    &:where(.size-xs) {
      border-radius: var(--radius-6);
    }

    &:where(.size-s, .size-m) {
      border-radius: var(--radius-8);
    }

    &:where(.size-l) {
      border-radius: var(--radius-12);
    }

    &:where(.size-xl) {
      border-radius: var(--radius-16);
    }
  }

  &:where(.style-floating) {
    overflow: hidden;
    border-radius: 9999px;
  }

  &:where(.style-floating-alt) {
    border-radius: var(--radius-8);
  }

  &:where(.style-primary.color-blue:focus-visible) {
    outline: 3px solid var(--color-state-action-light);
  }

  /* Hover styles for text, icon, and loader */
  &:where(.color-monochrome):where(.style-secondary, .style-tertiary):where(
      :not(.active, :hover)
    ) {
    &:where(.size-s, .size-xs) .ButtonText {
      color: var(--color-text-neutral-light);
    }

    &:where(.size-s, .size-xs) :is(.ButtonIcon, .ButtonLoader) {
      color: var(--color-text-neutral-lighter);
    }

    &:where(.size-m, .size-l, .size-xl) :is(.ButtonIcon, .ButtonLoader) {
      color: var(--color-text-neutral-light);
    }
  }

  &:where(.color-monochrome-light):where(
      .style-secondary,
      .style-tertiary,
      .style-floating
    ):where(:not(.active, :hover)) {
    & :is(.ButtonIcon, .ButtonLoader) {
      color: var(--color-text-neutral-lighter);
    }
  }

  &:where(.color-monochrome-dark):where(
      .style-secondary,
      .style-tertiary,
      .style-floating
    ):where(:not(.active, :hover)) {
    & :is(.ButtonIcon, .ButtonLoader) {
      color: var(--color-text-neutral-light);
    }
  }

  /* NOTE: If there is no text, button is square, so padding is 0 */
  &:not(:has(.ButtonText)) {
    padding: 0;
  }

  &:disabled {
    cursor: not-allowed;
    opacity: var(--opacity-disabled);
  }

  &:is(.style-floating, .style-floating-alt) {
    box-shadow: var(--elevation-2);

    &:where(:hover) {
      box-shadow: var(--elevation-3);
    }
  }
}

.ButtonContent {
  display: flex;
  align-items: center;
  justify-content: center;

  /* NOTE: Using the visibility property to preserve content area while loading */
  &:where(.loading) {
    visibility: hidden;
  }
}

.ButtonLoader {
  position: absolute;
  inset: 0;

  display: flex;
  align-items: center;
  justify-content: center;
}
