////////////////////////////////////////////////////////////////////////////////
// Units
////////////////////////////////////////////////////////////////////////////////

@use "sass:math";
@use 'sass:string';
@use 'sass:meta';

// This units creator will render six positive and six negative sass variables for 
// gaps, spacers, and gutters relative to the basev values defined below.
// =============================================================================
// Base Values 
// =============================================================================

/// @see https://codepen.io/marknotton/pen/ExPbNGe

// These three values will act a constant baseline for all following unit delcarations.

// Gaps must use an absolute and static 'px' unit. It should not be relative to any
// parent container and is not intended for font sizes, so you should not use 'rem' or 'em'. 
$gap : 16px !default;
$base-gap : $gap;

// Spacers must use a 'vh' unit so they are relative to the users viewport height-wise.
// They should primarily be used for the top and bottom margins on a component level.
$spacer : 4vh !default; 
$base-spacer : $spacer; 

// Gutters must use a 'vw' unit so they are relative to the users viewport width-wise. 
// They should primarily be used for the left and right padding or margin on a parent level.
// As a suggestion, this gutter constant should be half the size of the spacer value.
$gutter : 3vw !default;
$base-gutter : $gutter; 

// =============================================================================
// Asbolute Units 
// =============================================================================

// Gaps ------------------------------------------------------------------------
// Gaps are an absolute unit (px) intended to be used on individual elements within a componented. 
// The aim is to retain consistant spacing amongst block, inline, table and group html elements.

@function gap($amount : 1) {
  @if ( $amount == 1 ) { 
    @return var(--gap); 
  } @else { 
    @return calc(var(--gap) * #{$amount}); 
  }
}

$gap0 : gap(0.5); $gap0- : gap(-0.5);
$gap  : gap(1);   $gap-  : gap(-1);
$gap2 : gap(2);   $gap2- : gap(-2);
$gap3 : gap(3);   $gap3- : gap(-3);
$gap4 : gap(4);   $gap4- : gap(-4);
$gap5 : gap(5);   $gap5- : gap(-5);
$gap6 : gap(6);   $gap6- : gap(-6);

// =============================================================================
// Relative Units 
// =============================================================================

@function _dynamic-unit($custom-property, $amount, $min, $max, $use-negative : false, $use-clamp : true) {

  // Calc Method
  $result : calc((#{$custom-property} * #{$amount}) + #{if($min == 0, 0px, $min)});
  
  // Clamp Method
  @if ( $use-clamp ) {
    @if ( $amount == 0 ) {
      $result : clamp(#{math.div($min, 2)}, #{$custom-property} * 0.5, #{$max});
    } @else if ( $amount == 1 ) {
      $result : clamp(#{$min}, #{$custom-property}, #{$max});
    } @else {
      $result : clamp(#{$min}, #{$custom-property} * #{$amount}, #{$max});
    }
  } 

  @if ( $use-negative ) {
    $result : calc(-1 * #{$result});
  }

  @return $result;

} 

// Spacers ------------------------------------------------------------------------
// Spacers are a relative viewport height (vh) unit intended to be used on a componented level.
// The aim is to retain consistant top and bottom spacing amongst 'section' and 'custom' elements.
// Spacers will equate to something like: `($spacer * x) + $gap`. 
// The '$gap' is added so that vh spacing will never scale too close to 0px. 

@function spacer($amount : 1, $min : $base-gap, $max : null, $use-negative : false, $use-clamp : true) {
  @if ( $amount == 0) { $amount : 0.5; $min : math.div($min, 2); }
  @if ( meta.type-of($max) == 'null' ) { 
    @if ( meta.type-of($min) == 'string' and string.index($min, 'var') ) {
      $max : calc(#{$min} * #{$amount + 1}); 
    } @else {
      $max : #{$min * ($amount + 1)}; 
    }
  }
  @return _dynamic-unit(var(--spacer), $amount, $min, $max, $use-negative, $use-clamp);
}

$spacer0 : var(--spacer0); $spacer0- : var(--spacer0-);
$spacer  : var(--spacer1); $spacer-  : var(--spacer1-);
$spacer2 : var(--spacer2); $spacer2- : var(--spacer2-);
$spacer3 : var(--spacer3); $spacer3- : var(--spacer3-);
$spacer4 : var(--spacer4); $spacer4- : var(--spacer4-);
$spacer5 : var(--spacer5); $spacer5- : var(--spacer5-);
$spacer6 : var(--spacer6); $spacer6- : var(--spacer6-);

// Gutters ------------------------------------------------------------------------
// Gutters are a relative viewport width (vw) unit intended to be used on a parent level;
// for example, a wrapper container or body with nested components. 
// The aim is to retain consistant left and right spacing amongst 'section' and 'custom' elements.
// Gutters will equate to something like: `($gutter * x) + $gap`. 
// The '$gap' is added so that vw spacing will never scale too close to 0px. 

@function gutter($amount : 1, $min : $base-gap, $max : null, $use-negative : false, $use-clamp : true) {
  @if ( $amount == 0) { $amount : 0.5; $min : math.div($min, 2); }
  @if ( meta.type-of($max) == 'null' ) { 
    @if ( meta.type-of($min) == 'string' and string.index($min, 'var') ) {
      $max : calc(#{$min} * #{$amount + 1}); 
    } @else {
      $max : #{$min * ($amount + 1)}; 
    }
  }
  @return _dynamic-unit(var(--gutter), $amount, $min, $max, $use-negative, $use-clamp);
}

$gutter0 : var(--gutter0); $gutter0- : var(--gutter0-);
$gutter  : var(--gutter1); $gutter-  : var(--gutter1-);
$gutter2 : var(--gutter2); $gutter2- : var(--gutter2-);
$gutter3 : var(--gutter3); $gutter3- : var(--gutter3-);
$gutter4 : var(--gutter4); $gutter4- : var(--gutter4-);
$gutter5 : var(--gutter5); $gutter5- : var(--gutter5-);
$gutter6 : var(--gutter6); $gutter6- : var(--gutter6-);
