@use 'sass:map';
@use 'sass:list';
// ==============================================================================
// Breakpoint definitions
// ==============================================================================
$grid-breakpoints: (
  base: 0,
  mobile: 576px,
  tablet: 768px,
  desktop: 1025px,
) !default;

// ==============================================================================
// Helper functions
// ==============================================================================

// Helper function to calculate the next breakpoint based on a given one
@function breakpoint-next(
  $name,
  $breakpoints: $grid-breakpoints,
  $breakpoint-names: map.keys($breakpoints)
) {
  $n: list.index($list: $breakpoint-names, $value: $name);

  @return if(
    $condition: $n < length($breakpoint-names),
    $if-true: list.nth($list: $breakpoint-names, $n: $n + 1),
    $if-false: null,
  );
}

// Helper function to get the smallest breakpoint from the list
@function breakpoint-min($name, $breakpoints: $grid-breakpoints) {
  $min: map.get($map: $breakpoints, $key: $name);

  @return if($condition: $min != 0, $if-true: $min, $if-false: null,);
}

// Helper function to get the largest breakpoint from the list
@function breakpoint-max($name, $breakpoints: $grid-breakpoints) {
  $next: breakpoint-next($name: $name, $breakpoints: $breakpoints);

  @return if(
    $condition: $next,
    $if-true:  breakpoint-min($name: $next, $breakpoints: $breakpoints) - 1px,
    $if-false: null,
  );
}

// ==============================================================================
// Media query: Larger than (up)
// ==============================================================================

// Media of at least the minimum breakpoint width.
// No query for the smallest breakpoint.
// Makes the @content apply to the given breakpoint and wider.

@mixin device-up($name, $breakpoints: $grid-breakpoints) {
  $min: breakpoint-min($name: $name, $breakpoints: $breakpoints);

  @if $min {
    @media (min-width: $min) {
      @content;
    }
  } @else {
    @content;
  }
}

// ==============================================================================
// Media query: Smaller than (down)
// ==============================================================================
// Media of at most the maximum breakpoint width.
// No query for the largest breakpoint.
// Makes the @content apply to the given breakpoint and narrower.

@mixin device-down($name, $breakpoints: $grid-breakpoints) {
  $max: breakpoint-max($name: $name, $breakpoints: $breakpoints);

  @if $max {
    @media (max-width: $max) {
      @content;
    }
  } @else {
    @content;
  }
}

// ==============================================================================
// Media query: Only
// ==============================================================================
// Media between the breakpoint's minimum and maximum widths.
// No minimum for the smallest breakpoint, and no maximum for the largest one.
// Makes the @content apply only to the given breakpoint,
// not viewports any wider or narrower.

@mixin device-only($name, $breakpoints: $grid-breakpoints) {
  $min: breakpoint-min($name: $name, $breakpoints: $breakpoints);
  $max: breakpoint-max($name: $name, $breakpoints: $breakpoints);

  @if ($min != null and $max != null) {
    @media (min-width: $min) and (max-width: $max) {
      @content;
    }
  } @else if ($max == null) {
    @include device-up($name);
  } @else if ($min == null) {
    @include device-down($name);
  }
}

// ==============================================================================
// Media query: Hide on screens smaller than (down)
// ==============================================================================

@mixin device-hide-down($name, $breakpoints: $grid-breakpoints) {
  $max: breakpoint-max($name: $name, $breakpoints: $breakpoints);

  @if $max {
    @media (max-width: $max) {
      display: none;
    }
  }
}

// ==============================================================================
// Media query: Use on devices with coarse input only
// ==============================================================================

@mixin pointer-coarse {
  @media (pointer: coarse) {
    @content;
  }
}

// ==============================================================================
// Media query: Use on devices with fine input only
// ==============================================================================

// Pointer media queries are not supported in IE.
// Use -ms-high-contrast to detect IE and apply pointer: fine here
@mixin pointer-fine {
  @media
    not all and (pointer: coarse),
    (-ms-high-contrast: none) {
    @content;
  }
}
