@use "../../wc";

:host {
  display: block;
  --zn-col-basis: 250px;
  --col-width: 23%;
}

:host([contents]) {
  display: contents;
}

.cols {
  display: flex;
  flex-wrap: wrap;
  flex-grow: 1;
  flex-shrink: 1;
  width: 100%;
  container-type: inline-size;
  gap: var(--zn-gap);

  max-width: 100%;

  @for $i from 1 through 12 {
    ::slotted(.zn-col-#{$i}) {
      flex-basis: calc(var(--zn-col-basis) * #{$i});
      min-width: calc(var(--col-width) * #{$i});
      flex-grow: #{$i}
    }
  }

  @for $i from 1 through 12 {
    &--mc-#{$i} {
      --col-width: calc(100% / #{$i + 1});
    }
  }

  &--layout-121 {
    ::slotted(.zn-col-2) {
      order: -1;
      min-width: 100%;

      @include wc.container-query(hd) {
        order: initial;
        min-width: 46%;
      }
    }
  }

  &--divide {
    ::slotted(*:not(:last-child)) {
      position: relative;

      &:after {
        content: "";
        position: absolute;
        display: block;
        width: 1px;
        top: 0;
        height: 100%;
        max-height: 100%;
        right: calc((var(--zn-spacing-small) / 2) * -1);
        background-color: rgb(var(--zn-border-color));
      }
    }
  }

  &--no-gap {
    gap: 0;
  }

  // The row rule below each child is drawn by a pseudo reaching to -100vw, so border mode has to clip. Clipping
  // every layout would cut the focus ring off any control sitting flush against a column edge.
  &--border {
    overflow: hidden;
  }

  &--border ::slotted(*) {
    position: relative;
    padding-bottom: var(--zn-spacing-small); // Add spacing between element and border
  }

  // Adds full-width lines between bordered cols
  // Last row elements get overflow:hidden via JS to clip this pseudo
  &--border ::slotted(*):before {
    content: "";
    position: absolute;
    bottom: -1px;
    left: -100vw;
    right: -5px;
    z-index: 1111;
    border-bottom: 1px solid rgb(var(--zn-border-color)) !important;
  }

  // Children marked with [stack-split] act as a single column while the cols are
  // side by side, and dissolve into individual columns once stacked (see below).
  ::slotted([stack-split]) {
    display: flex;
    flex-direction: column;
    gap: var(--zn-gap);
  }

  &--pad {
    padding: var(--zn-spacing-2x-small);
  }

  &--pad-x {
    padding-inline: var(--zn-spacing-2x-small);
  }

  &--pad-y {
    padding-block: var(--zn-spacing-2x-small);
  }
}

//
// Responsive stacking
//
// `stack-at` names the container width the cols collapse to a single column below.
// While stacked, `--zn-stacked` flips to 1 so the per-child `order: calc(var(--zn-stacked) * n)`
// written by the component only takes effect in the stacked state, and `--zn-stack-basis`
// gives promoted [stack-split] children something to size against.
//
// `:host()` is only in the selector to out-specify the `.zn-col-#{$i}` min-width rules above.
//
$stack-sizes: (sm, smp, ph, md, lg, hd, '3k', '4k');

@each $size in $stack-sizes {
  :host([stack-at="#{$size}"]) {
    @include wc.container-query(null, $size) {
      .cols ::slotted(*) {
        --zn-stacked: 1;
        --zn-stack-basis: 100%;

        flex-basis: 100%;
        min-width: 100%;
        max-width: 100%;
      }

      // Hand this column's children over to the cols so each can be ordered individually
      .cols ::slotted([stack-split]) {
        display: contents;
      }

      // Vertical dividers make no sense once the columns are on top of each other
      .cols--divide ::slotted(*:not(:last-child)):after {
        display: none;
      }
    }
  }
}
