@import "carbon-components/scss/globals/scss/vars";
@import "carbon-components/scss/globals/scss/helper-mixins";
@import "carbon-components/scss/globals/scss/vendor/@carbon/elements/scss/import-once/import-once";

/// Tab icon styles
/// @access private
/// @group components
@mixin tabs-icon {
  .#{$prefix}--tabs__nav-link.#{$prefix}--tabs__nav-link--icon {
    display: flex;
    align-items: center;
  }

  .#{$prefix}--tabs__nav-item--icon {
    display: flex;
    align-items: center;
    padding-inline-start: $carbon--spacing-03;
  }

  .#{$prefix}--tabs__nav-item--disabled .#{$prefix}--tabs__nav-item--icon svg {
    fill: $disabled-02;
  }

  .#{$prefix}--tabs--container
    .#{$prefix}--tabs__nav-item--disabled
    .#{$prefix}--tabs__nav-item--icon
    svg {
    fill: $text-on-color-disabled;
  }

  .#{$prefix}--tabs--container
    .#{$prefix}--tabs__nav-link.#{$prefix}--tabs__nav-link--icon {
    inline-size: 100%;
  }

  .#{$prefix}--tabs--container .#{$prefix}--tabs__nav-item--icon {
    margin-inline-start: auto;
    padding-inline-start: $carbon--spacing-05;
  }
}

@include exports('tabs-icon') {
  @include tabs-icon;
}

/// Icon-only tab styles
/// At `md` and up, the nav link is a square icon trigger and the label is
/// surfaced as a portalled tooltip (rendered by `Tab.svelte`). Below `md` the
/// tabs collapse into the legacy dropdown, where each item keeps its full-width
/// footprint and shows the icon next to its text label.
/// @access private
/// @group components
@mixin tabs-icon-only {
  $icon-tab-size: $carbon--spacing-08; // 40px
  $icon-tab-size-lg: $carbon--spacing-09; // 48px
  // Container tabs are 48px tall, so icon-only container tabs are square at 48px.
  $icon-tab-size-container: $carbon--spacing-09; // 48px

  // Below md (dropdown menu): show the icon beside the label and keep the
  // full-width item border. The label span is hidden in the desktop row below.
  // Double class so `display: flex` out-specifies the base `a.bx--tabs__nav-link`
  // (`display: block`) rule that is imported after this file.
  a.#{$prefix}--tabs__nav-link.#{$prefix}--tabs__nav-link--icon-only {
    display: flex;
    align-items: center;
    gap: $carbon--spacing-03;
  }

  // Lift the icon out of its default beside-label spacing so it sits flush.
  .#{$prefix}--tabs__nav-link--icon-only .#{$prefix}--tabs__nav-item--icon {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
  }

  // Container type adds an auto inline-start margin to push the icon to the end;
  // neutralize it so the icon stays beside the label (mobile) / centered (md).
  .#{$prefix}--tabs--container
    .#{$prefix}--tabs__nav-link--icon-only
    .#{$prefix}--tabs__nav-item--icon {
    margin-inline-start: 0;
    padding-inline-start: 0;
  }

  // Mobile dropdown: Carbon's disabled underline (`2px solid $disabled-01`) is
  // near-invisible, so disabled items look like they are missing a separator.
  // Restore the same separator the enabled items use.
  @include carbon--breakpoint-down(md) {
    .#{$prefix}--tabs__nav-item--disabled
      a.#{$prefix}--tabs__nav-link.#{$prefix}--tabs__nav-link--icon-only {
      border-bottom: 1px solid $ui-03;
    }
  }

  @include carbon--breakpoint(md) {
    // The icon-only nav is absolutely positioned and overlays the panel; the
    // `.bx--tabs` container reserves only 40px by default, so the 48px lg row
    // would cover the panel by 8px. Reserve the full 48px instead.
    .#{$prefix}--tabs.#{$prefix}--tabs__icon--lg {
      min-height: $icon-tab-size-lg;
    }

    // Square icon trigger; double class to out-specify the base
    // `a.bx--tabs__nav-link` rules, which are imported after this file.
    a.#{$prefix}--tabs__nav-link.#{$prefix}--tabs__nav-link--icon-only {
      justify-content: center;
      gap: 0;
      width: $icon-tab-size;
      min-width: $icon-tab-size;
      height: $icon-tab-size;
      padding: 0;

      &:focus,
      &:active {
        width: $icon-tab-size;
        min-width: $icon-tab-size;
        padding: 0;
      }
    }

    // Hide the text label in the desktop icon-only row (kept for the dropdown).
    .#{$prefix}--tabs__nav-link--icon-only .#{$prefix}--tabs__nav-item-label {
      display: none;
    }

    // Container type: contained tabs are 48px tall, so make the icon-only link a
    // 48px square (instead of the 40px default) so it does not look stretched.
    .#{$prefix}--tabs--container
      a.#{$prefix}--tabs__nav-link.#{$prefix}--tabs__nav-link--icon-only {
      width: $icon-tab-size-container;
      min-width: $icon-tab-size-container;
      height: $icon-tab-size-container;
      padding: 0;
    }

    // Large icon scale: 48px square trigger. The `.bx--tabs__icon--lg` ancestor
    // raises specificity above the default-scale rules above.
    .#{$prefix}--tabs__icon--lg {
      a.#{$prefix}--tabs__nav-link.#{$prefix}--tabs__nav-link--icon-only,
      &.#{$prefix}--tabs--container
        a.#{$prefix}--tabs__nav-link.#{$prefix}--tabs__nav-link--icon-only {
        width: $icon-tab-size-lg;
        min-width: $icon-tab-size-lg;
        height: $icon-tab-size-lg;

        &:focus,
        &:active {
          width: $icon-tab-size-lg;
          min-width: $icon-tab-size-lg;
        }
      }

      // 20px icon at lg scale (Carbon React); default scale stays 16px.
      .#{$prefix}--tabs__nav-link--icon-only .#{$prefix}--tabs__nav-item--icon svg {
        block-size: to-rem(20px);
        inline-size: to-rem(20px);
      }
    }
  }
}

@include exports('tabs-icon-only') {
  @include tabs-icon-only;
}

/// Tab full-width styles
/// @access private
/// @group components
@mixin tabs-full-width {
  .#{$prefix}--tabs--full-width .#{$prefix}--tabs__nav {
    width: 100%;
  }

  .#{$prefix}--tabs--full-width .#{$prefix}--tabs__nav-item {
    flex: 1;
  }

  .#{$prefix}--tabs--full-width .#{$prefix}--tabs__nav-link {
    width: 100%;
    max-width: none;
  }
}

@include exports('tabs-full-width') {
  @include tabs-full-width;
}

/// Tab tall (secondary label) styles
/// @access private
/// @group components
@mixin tabs-tall {
  @include carbon--breakpoint(md) {
    .#{$prefix}--tabs--tall.#{$prefix}--tabs--container {
      min-height: 4rem;
    }

    .#{$prefix}--tabs--tall .#{$prefix}--tabs__nav-item {
      min-height: 4rem;
    }

    .#{$prefix}--tabs--tall.#{$prefix}--tabs--container a.#{$prefix}--tabs__nav-link {
      display: flex;
      flex-direction: column;
      align-items: flex-start;
      justify-content: center;
      height: 100%;
    }
  }

  .#{$prefix}--tabs__nav-item-label-wrapper {
    display: flex;
    line-height: normal;
  }

  .#{$prefix}--tabs--container .#{$prefix}--tabs__nav-item-secondary-label {
    @include carbon--type-style("caption-01");

    min-height: 1rem;
  }
}

@include exports('tabs-tall') {
  @include tabs-tall;
}

/// Tab container panel background
/// @access private
/// @group components
@mixin tabs-container-panel {
  .#{$prefix}--tabs--container ~ .#{$prefix}--tab-content {
    background-color: $ui-01;
  }
}

@include exports('tabs-container-panel') {
  @include tabs-container-panel;
}

/// Container type: remove link border on disabled tab hover
/// Default tabs add a bottom border to the nav link on disabled hover; container
/// tabs use a different visual treatment and should not show this border.
/// @access private
/// @group components
@mixin tabs-container-disabled-hover {
  .#{$prefix}--tabs--container
    .#{$prefix}--tabs__nav-item--disabled:hover
    .#{$prefix}--tabs__nav-link {
    border-bottom: none;
    border-block-end: none;
  }
}

@include exports('tabs-container-disabled-hover') {
  @include tabs-container-disabled-hover;
}

/// Container type: do not apply fixed 10rem width to nav links.
/// Default tabs get width: 10rem at 42rem viewport from base Carbon styles
/// (including :focus and :active); container tabs should size naturally.
/// @access private
/// @group components
@mixin tabs-container-nav-link-width {
  @media (min-width: 42rem) {
    .#{$prefix}--tabs--container .#{$prefix}--tabs__nav-link,
    .#{$prefix}--tabs--container .#{$prefix}--tabs__nav-link:focus,
    .#{$prefix}--tabs--container .#{$prefix}--tabs__nav-link:active {
      width: auto;
    }
  }
}

@include exports('tabs-container-nav-link-width') {
  @include tabs-container-nav-link-width;
}

/// Dismissible tab styles: a close button per tab, left-aligned icons, and the
/// selection indicator re-homed from the nav link to the nav item so it spans
/// both the link and the close button. In Carbon v10 the underline (default)
/// and inset top border (container) sit on the link, which is narrower than the
/// item once a close button is added.
/// @access private
/// @group components
@mixin tabs-dismissible {
  .#{$prefix}--tabs--dismissible .#{$prefix}--tabs__nav-item {
    display: flex;
    align-items: center;
  }

  .#{$prefix}--tabs--dismissible .#{$prefix}--tabs__nav-link {
    display: flex;
    align-items: center;
    min-inline-size: 0;
  }

  // Default: size the link to its content so the close button sits next to the
  // label with a fixed gap, instead of growing to the full tab width.
  .#{$prefix}--tabs--dismissible:not(.#{$prefix}--tabs--container)
    .#{$prefix}--tabs__nav-link {
    flex: 0 1 auto;
    padding-inline-end: $carbon--spacing-03;
  }

  // Container: fill the cell so the close button aligns to the trailing edge.
  .#{$prefix}--tabs--dismissible.#{$prefix}--tabs--container
    .#{$prefix}--tabs__nav-link {
    flex: 1 1 auto;
    padding-inline-end: $carbon--spacing-04;
  }

  .#{$prefix}--tabs--dismissible .#{$prefix}--tabs__nav-item-label {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .#{$prefix}--tabs--dismissible .#{$prefix}--tabs__nav-item--icon-left {
    display: flex;
    flex-shrink: 0;
    align-items: center;
    padding-inline-end: $carbon--spacing-03;
  }

  .#{$prefix}--tabs--dismissible .#{$prefix}--tabs__nav-item--close {
    display: flex;
    flex-shrink: 0;
    align-items: center;
  }

  // Default: at md the link's asymmetric vertical padding ($spacing-04 top /
  // $spacing-03 bottom) drops the label below the nav-item center, so nudge the
  // close button down to share the text's optical baseline. Below md the link
  // padding is symmetric (dropdown rows), so the nudge must not apply there.
  @include carbon--breakpoint(md) {
    .#{$prefix}--tabs--dismissible:not(.#{$prefix}--tabs--container)
      .#{$prefix}--tabs__nav-item--close {
      position: relative;
      inset-block-start: $carbon--spacing-01;
    }
  }

  // Container: nudge the close button off the label.
  .#{$prefix}--tabs--dismissible.#{$prefix}--tabs--container
    .#{$prefix}--tabs__nav-item--close {
    margin-inline-start: $carbon--spacing-02;
  }

  // Trailing padding so the close button is not flush with the tab edge.
  .#{$prefix}--tabs--dismissible .#{$prefix}--tabs__nav-item {
    padding-inline-end: $carbon--spacing-03;
  }

  // Move the focus outline from the link to the whole nav item so it wraps the
  // label and the close button as a single target.
  .#{$prefix}--tabs--dismissible .#{$prefix}--tabs__nav-item:focus-within {
    outline: 2px solid $focus;
    outline-offset: -2px;
  }

  .#{$prefix}--tabs--dismissible a.#{$prefix}--tabs__nav-link:focus,
  .#{$prefix}--tabs--dismissible a.#{$prefix}--tabs__nav-link:active {
    outline: none;
  }

  @include carbon--breakpoint(md) {
    // Default variant: drop Carbon's fixed 10rem link width (including the
    // focus/active width reset) so the tab sizes to its content.
    .#{$prefix}--tabs--dismissible:not(.#{$prefix}--tabs--container)
      a.#{$prefix}--tabs__nav-link,
    .#{$prefix}--tabs--dismissible:not(.#{$prefix}--tabs--container)
      a.#{$prefix}--tabs__nav-link:focus,
    .#{$prefix}--tabs--dismissible:not(.#{$prefix}--tabs--container)
      a.#{$prefix}--tabs__nav-link:active {
      inline-size: auto;
    }

    // Default variant: move the bottom underline from the link to the item.
    .#{$prefix}--tabs--dismissible:not(.#{$prefix}--tabs--container)
      .#{$prefix}--tabs__nav-item {
      border-block-end: 2px solid $ui-03;
    }

    .#{$prefix}--tabs--dismissible:not(.#{$prefix}--tabs--container)
      .#{$prefix}--tabs__nav-item:hover:not(.#{$prefix}--tabs__nav-item--selected):not(.#{$prefix}--tabs__nav-item--disabled) {
      border-block-end-color: $ui-04;
    }

    .#{$prefix}--tabs--dismissible:not(.#{$prefix}--tabs--container)
      .#{$prefix}--tabs__nav-item--selected:not(.#{$prefix}--tabs__nav-item--disabled) {
      border-block-end-color: $interactive-04;
    }

    .#{$prefix}--tabs--dismissible:not(.#{$prefix}--tabs--container)
      .#{$prefix}--tabs__nav-item--disabled {
      border-block-end-color: $disabled-01;
    }

    // Remove the link border in every state so only the item border shows.
    // Carbon's hover/selected link rules outrank a plain link selector, so each
    // state is matched explicitly to win on specificity.
    .#{$prefix}--tabs--dismissible:not(.#{$prefix}--tabs--container)
      a.#{$prefix}--tabs__nav-link,
    .#{$prefix}--tabs--dismissible:not(.#{$prefix}--tabs--container)
      .#{$prefix}--tabs__nav-item:hover:not(.#{$prefix}--tabs__nav-item--selected):not(.#{$prefix}--tabs__nav-item--disabled)
      .#{$prefix}--tabs__nav-link,
    .#{$prefix}--tabs--dismissible:not(.#{$prefix}--tabs--container)
      .#{$prefix}--tabs__nav-item--selected:not(.#{$prefix}--tabs__nav-item--disabled)
      .#{$prefix}--tabs__nav-link {
      border-block-end: none;
    }

    // Container variant: move the inset top indicator from the link to the item.
    .#{$prefix}--tabs--dismissible.#{$prefix}--tabs--container
      .#{$prefix}--tabs__nav-item--selected:not(.#{$prefix}--tabs__nav-item--disabled) {
      box-shadow: inset 0 2px 0 0 $interactive-04;
    }

    .#{$prefix}--tabs--dismissible.#{$prefix}--tabs--container
      .#{$prefix}--tabs__nav-item--selected:not(.#{$prefix}--tabs__nav-item--disabled)
      .#{$prefix}--tabs__nav-link {
      box-shadow: none;
    }
  }

  // The close button is not in the tab order (keyboard dismissal uses Delete on
  // the tab), so suppress its own focus ring. The nav item's :focus-within
  // outline wraps the whole tab, avoiding a doubled outline when it is clicked.
  .#{$prefix}--tabs__nav-item--close-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    inline-size: $carbon--spacing-06;
    block-size: $carbon--spacing-06;
    padding: $carbon--spacing-02;
    border: 0;
    margin: 0;
    background: transparent;
    outline: none;
    cursor: pointer;
  }

  // Guard hover styling against the disabled marker so a disabled close button
  // keeps its disabled treatment on hover instead of lighting up.
  .#{$prefix}--tabs__nav-item--close-icon:not(.#{$prefix}--tabs__nav-item--close-icon--disabled):hover {
    background-color: $hover-ui;
  }

  .#{$prefix}--tabs__nav-item--close-icon svg {
    fill: $text-02;
  }

  .#{$prefix}--tabs__nav-item--close-icon:not(.#{$prefix}--tabs__nav-item--close-icon--disabled):hover
    svg,
  .#{$prefix}--tabs__nav-item--close-icon:focus svg {
    fill: $text-01;
  }

  .#{$prefix}--tabs__nav-item--close-icon--disabled {
    cursor: not-allowed;
  }

  .#{$prefix}--tabs__nav-item--close-icon--disabled svg,
  .#{$prefix}--tabs__nav-item--disabled
    .#{$prefix}--tabs__nav-item--icon-left
    svg {
    fill: $disabled-02;
  }

  // Container disabled tabs sit on a $disabled-02 background, so the close icon
  // and left icon need a contrasting disabled token to stay visible.
  .#{$prefix}--tabs--dismissible.#{$prefix}--tabs--container
    .#{$prefix}--tabs__nav-item--close-icon--disabled
    svg,
  .#{$prefix}--tabs--dismissible.#{$prefix}--tabs--container
    .#{$prefix}--tabs__nav-item--disabled
    .#{$prefix}--tabs__nav-item--icon-left
    svg {
    fill: $text-on-color-disabled;
  }
}

@include exports('tabs-dismissible') {
  @include tabs-dismissible;
}
