@use '../../compiled/tokens/scss/breakpoint';
@use '../../compiled/tokens/scss/color';
@use 'sass:color' as sass-color;
@use '../../compiled/tokens/scss/ease';
@use '../../compiled/tokens/scss/scale';
@use '../../compiled/tokens/scss/size';
@use '../../compiled/tokens/scss/transition';
@use '../../mixins/border-radius';
@use '../../mixins/focus';
@use '../../mixins/ms';
@use '../../mixins/theme';

@include theme.props {
  --theme-color-background-icon: #{sass-color.adjust(
      color.$base-orange,
      $lightness: 30%
    )};
  --theme-color-icon: #{color.$base-orange};
  --theme-color-icon-error: #{color.$status-error-dark};
  --theme-color-background-icon-error: #{color.$status-error-light};
}

@include theme.props(dark) {
  --theme-color-background-icon: #{color.$base-orange};
  --theme-color-icon: #{sass-color.adjust(color.$base-orange, $lightness: 30%)};
  --theme-color-icon-error: #{color.$status-error-light};
  --theme-color-background-icon-error: #{color.$status-error-dark};
}

.c-alert {
  @include border-radius.conditional(size.$border-radius-medium);
  background: var(--theme-color-background-secondary);
  color: var(--theme-color-text-emphasis);
}

/// We use a separate inner element so we can constrain it when the alert is
/// full-width without having to factor in the size of the optional dismissal
/// control.
///
/// We lay out elements using CSS Grid to avoid relying on negative margins
/// so that the dismissal control's interactive area will reach the element's
/// edges.
///
/// The spacing here involves more "magic" numbers than I wanted it to, but
/// since the default container is pretty subtle neither the standard container
/// padding nor control padding felt quite right. We may want to revisit that
/// in the future.
.c-alert__inner {
  display: grid;
  grid-column-gap: ms.step(1);
  grid-template-areas:
    'icon .       dismiss'
    'icon content dismiss'
    'icon .       dismiss';
  grid-template-columns: minmax(0, auto) 1fr minmax(0, auto);
  grid-template-rows: ms.step(-1) minmax(0, auto) ms.step(-1);
  margin: 0 auto;
  max-inline-size: size.$max-width-spread;
}

// Adds a box shadow to add the appearance of the alert floating
// above the containers below. Floating has a white background for higher
// contrast between the background and the shadow.
.c-alert--floating {
  box-shadow: 0 0 0 size.$edge-medium var(--theme-color-shadow-inner),
    size.$edge-large size.$edge-large 0 size.$edge-medium
      var(--theme-color-shadow-outer);
  @include theme.styles {
    --theme-color-shadow-inner: #{sass-color.change(
        color.$brand-primary-darker,
        $alpha: 0.4
      )};
    --theme-color-shadow-outer: #{sass-color.change(
        color.$brand-primary-darker,
        $alpha: 0.2
      )};
  }
  @include theme.styles(dark) {
    --theme-color-shadow-inner: #{sass-color.change(
        color.$brand-primary-darker,
        $alpha: 0.6
      )};
    --theme-color-shadow-outer: #{sass-color.change(
        color.$brand-primary-darker,
        $alpha: 0.4
      )};
  }
}

/**
 * 1. This number was chosen because in combination with the usual
 * single-line height of the element, it makes a perfect square.
 */
.c-alert__extra {
  --icon-size: #{size.$icon-medium};
  align-items: center;
  background-color: var(--theme-color-background-icon);
  border-bottom-left-radius: size.$border-radius-medium;
  border-top-left-radius: size.$border-radius-medium;
  color: var(--theme-color-icon);
  display: flex;
  grid-area: icon;
  inline-size: ms.step(5); /* 1 */
  justify-content: center;

  // On large screens, when the alert content reaches it's max width and
  // the icon no longer touches the edge of its container, we change the
  // icon style so it's self contained.
  @media (min-width: breakpoint.$xxl) {
    border: ms.step(-4) solid var(--theme-color-background-secondary);
    border-radius: size.$border-radius-full;
  }

  .c-alert--error & {
    background-color: var(--theme-color-background-icon-error);
    color: var(--theme-color-icon-error);
  }
}

.c-alert__content {
  grid-area: content;
}

/// Reset the dismissal button's appearance and center-align its content
/// 1. This is a magic number but it just feels right, y'know?
.c-alert__dismiss {
  align-items: center;
  appearance: none;
  background: transparent;
  border: 0;
  border-radius: size.$border-radius-medium;
  color: inherit;
  cursor: pointer;
  display: flex;
  font: inherit;
  grid-area: dismiss;
  justify-content: center;
  margin: 0;
  min-inline-size: ms.step(5); // 1
  padding: 0;

  @include focus.focus-visible {
    box-shadow: 0 0 0 size.$edge-large color.$brand-primary-lighter;
  }
}

/// We apply the transition effects to the icon so the button itself won't break
/// outside of the alert, which is particularly important when it's full-width.
.c-alert__dismiss-icon {
  transition: filter transition.$slow ease.$out,
    transform transition.$quick ease.$out;

  .c-alert__dismiss:hover & {
    transform: scale(scale.$effect-grow);
  }

  .c-alert__dismiss:active & {
    transform: scale(scale.$effect-shrink);
  }
}
