@use "spacing";
@use "breakpoints";

// Grid gutters
$grid-gutter: (
  "xs": spacing.$spacing-4,
  "sm": spacing.$spacing-4,
  "md": spacing.$spacing-6,
  "lg": spacing.$spacing-6,
  "xl": spacing.$spacing-6,
) !default;

// Grid columns
$grid-columns: (
  "xs": 12,
  "sm": 12,
  "md": 12,
  "lg": 12,
  "xl": 12,
) !default;

// Well padding
$well-padding: (
  "xs": spacing.$spacing-4,
  "sm": spacing.$spacing-8,
  "md": spacing.$spacing-8,
  "lg": 200px,
  "xl": 200px,
) !default;

// Well content max width
$well-content-max-width: (
  "xs": 840px,
  "sm": 840px,
  "md": 840px,
  "lg": 1040px,
  "xl": 1040px,
) !default;

// Mixin to define the spacing variables used for the well bounds
// NOTE: we pull this out as a separate mixin so that applications can choose
// to define the variables at a higher level than a `Well` component if they
// need to
@mixin well-vars {
  --Well-padding: #{map-get($well-padding, "xs")};
  --Well-content-max-width: #{map-get($well-content-max-width, "xs")};
  --Well-content-width: min(100% - 2 * var(--Well-padding), var(--Well-content-max-width));

  @each $breakpoint in map-keys($well-padding) {
    @include breakpoints.breakpoint-at-least($breakpoint) {
      --Well-padding: #{map-get($well-padding, $breakpoint)};
      --Well-content-max-width: #{map-get($well-content-max-width, $breakpoint)};
    }
  }
}

// Mixin to define the spacing variables used for the grid layout
// NOTE: we pull this out as a separate mixin so that applications can choose
// to define the variables at a higher level than a `Grid` component if they
// need to
@mixin grid-vars {
  --Grid-gutter: #{map-get($grid-gutter, "xs")};
  --Grid-columns: #{map-get($grid-columns, "xs")};

  @each $breakpoint in map-keys($grid-gutter) {
    @include breakpoints.breakpoint-at-least($breakpoint) {
      --Grid-gutter: #{map-get($grid-gutter, $breakpoint)};
      --Grid-columns: #{map-get($grid-columns, $breakpoint)};
    }
  }
}

// Mixin to define the outer well container with a max body width and padding
// on the sides
@mixin well {
  padding: 0 var(--Well-padding);
  margin-left: auto;
  margin-right: auto;
  max-width: calc(var(--Well-content-max-width) + 2 * var(--Well-padding));

  @include well-vars();
}

// Mixin to define a basic grid with a responsive gutter and number of columns
@mixin grid {
  display: flex;
  flex-wrap: wrap;
  margin-left: calc(-.5 * var(--Grid-gutter));
  margin-right: calc(-.5 * var(--Grid-gutter));

  @include grid-vars();

  & > * {
    width: 100%;
    max-width: 100%;
  }
}

// Mixin to define a grid item that can specify an optional column span and
// offset. Must be used in the context of a grid container.
@mixin grid-item-columns-auto-layout() {
  flex: 1 0;
}

@mixin grid-item-columns($columns) {
  width: calc(#{$columns} / var(--Grid-columns) * 100%);
  flex: 0 0 auto;
}

@mixin grid-item-offset($offset) {
  margin-left: calc(#{$offset} / var(--Grid-columns) * 100%);
}

@mixin grid-item($columns: 0, $offset: 0, $auto-layout: true) {
  @if $auto-layout {
    @include grid-item-columns-auto();
  }

  @if $columns > 0 {
    @include grid-item-columns($columns);
  }

  @if $offset > 0 {
    @include grid-item-offset($offset);
  }

  padding: 0 calc(.5 * var(--Grid-gutter));
}
