$baseline-grid:            8px !default;
$layout-gutter-width:      ($baseline-grid * 2) !default;
$layout-breakpoint-xs:     600px !default;
$layout-breakpoint-sm:     960px !default;
$layout-breakpoint-md:     1280px !default;
$layout-breakpoint-lg:     1920px !default;

// Function
//-- Must be defined before variables
@function rem($multiplier) {
  $font-size: 10px;
  @return $multiplier * $font-size;
}

// Shared Checkbox variables

@mixin margin-selectors($before:1em, $after:1em, $start:0px, $end:0px) {
  -webkit-margin-before: $before;
  -webkit-margin-after: $after;
  -webkit-margin-start: $start;
  -webkit-margin-end: $end;
}

@mixin not-selectable($value:none) {
  -webkit-touch-callout: $value;
  -webkit-user-select: $value;
  -khtml-user-select: $value;
  -moz-user-select: $value;
  -ms-user-select: $value;
  user-select: $value;
}


@mixin pie-clearfix {
  &:after {
    content: '';
    display: table;
    clear: both;
  }
}

@function map-to-string($map) {
  $map-str: '{';
  $keys: map-keys($map);
  $len: length($keys);
  @for $i from 1 through $len {
    $key: nth($keys, $i);
    $value: map-get($map, $key);
    $map-str: $map-str + '_' + $key + '_: _' + map-get($map, $key) + '_';
    @if $i != $len {
      $map-str: $map-str + ',';
    }
  }
  @return $map-str + '}';
}

// This is a mixin, which fixes IE11's vertical alignment issue, when using `min-height`.
// See https://connect.microsoft.com/IE/feedback/details/816293/
@mixin ie11-min-height-flexbug($min-height) {
  &::before {
    content: '';
    min-height: $min-height;
    visibility: hidden;
    display: inline-block;
  }
}

// mixin definition ; sets LTR and RTL within the same style call
// @see https://css-tricks.com/almanac/properties/d/direction/

@mixin rtl($prop, $ltr-value, $rtl-value) {
  #{$prop}: $ltr-value;
  [dir=rtl] & {
    #{$prop}: $rtl-value;
  }
}

@mixin rtl-prop($ltr-prop, $rtl-prop, $value, $reset-value) {
  #{$ltr-prop}: $value;
  [dir=rtl] & {
    #{$ltr-prop}: $reset-value;
    #{$rtl-prop}: $value;
  }
}

// To reverse padding (top left bottom right) -> (top right bottom left)
@function rtl-value($list) {
  @if length($list) == 4 {
    @return nth($list, 1) nth($list, 4) nth($list, 3) nth($list, 2)
  }
  @if length($list) == 5 {
    @return nth($list, 1) nth($list, 4) nth($list, 3) nth($list, 2) nth($list, 5)
  }
  @return $list;
}

/**
 *  Responsive attributes
 *
 *  References:
 *  1) https://scotch.io/tutorials/a-visual-guide-to-css3-flexbox-properties#flex
 *  2) https://css-tricks.com/almanac/properties/f/flex/
 *  3) https://css-tricks.com/snippets/css/a-guide-to-flexbox/
 *  4) https://github.com/philipwalton/flexbugs#3-min-height-on-a-flex-container-wont-apply-to-its-flex-items
 *  5) http://godban.com.ua/projects/flexgrid
 */

@mixin flex-order-for-name($sizes:null) {
  @if $sizes == null {
    $sizes : '';

    .flex-order {
      order : 0;
    }
  }

  @for $i from -20 through 20 {
    $order : '';
    $suffix : '';

    @each $s in $sizes {
      @if $s != '' { $suffix : '#{$s}-#{$i}'; }
      @else        { $suffix : '#{$i}';       }

      $order : '.flex-order-#{$suffix}';
    }

    #{$order} {
      order: #{$i};
    }
  }
}

@mixin offset-for-name($sizes:null) {
  @if $sizes == null { $sizes : ''; }

  @for $i from 0 through 19 {
    $offsets : '';
    $suffix : '';

    @each $s in $sizes {
      @if $s != '' { $suffix : '#{$s}-#{$i * 5}'; }
      @else        { $suffix : '#{$i * 5}';       }

      $offsets : '.offset-#{$suffix}, .flex-offset-#{$suffix}';
    }

    #{$offsets} {
      @if $i != 0 { @include rtl-prop(margin-left, margin-right, #{$i * 5 + '%'}, auto); }
      @else { @include rtl-prop(margin-left, margin-right, 0, auto); }
    }
  }

  @each $i in 33 {
    $offsets : '';
    $suffix : '';

    @each $s in $sizes {
      @if $s != '' {  $suffix : '#{$s}-#{$i}';   }
      @else        {  $suffix : '#{$i}';         }

      $offsets : '.offset-#{$suffix}, .flex-offset-#{$suffix} ';
    }

    #{$offsets} {
      margin-left: calc(100% / 3);
    }
  }

  @each $i in 66 {
    $offsets : '';
    $suffix : '';

    @each $s in $sizes {
      @if $s != '' {  $suffix : '#{$s}-#{$i}';   }
      @else        {  $suffix : '#{$i}';         }

      $offsets : '.offset-#{$suffix}, .flex-offset-#{$suffix} ';
    }

    #{$offsets} {
      @include rtl-prop(margin-left, margin-right, calc(200% / 3), auto);
    }
  }
}

@mixin layout-for-name($name: null) {
  @if $name == null { $name : '';          }
  @if $name != ''   { $name : '-#{$name}'; }

  .layout#{$name}, .layout#{$name}-column, .layout#{$name}-row {
    box-sizing: border-box;
    display: -webkit-box;
    display: -webkit-flex;
    display: -moz-box;
    display: -ms-flexbox;
    display: flex;
  }
  .layout#{$name}-column {  flex-direction: column;     }
  .layout#{$name}-row    {  flex-direction: row;        }
}

@mixin flex-properties-for-name($name: null) {
  $flexName: 'flex';
  @if $name != null {
    $flexName: 'flex-#{$name}';
    $name : '-#{$name}';
  } @else {
    $name : '';
  }

  .#{$flexName}             { flex: 1;         box-sizing: border-box; }  // === flex: 1 1 0%;

  .#{$flexName}-grow        { flex: 1 1 100%;  box-sizing: border-box; }
  .#{$flexName}-initial     { flex: 0 1 auto;  box-sizing: border-box; }
  .#{$flexName}-auto        { flex: 1 1 auto;  box-sizing: border-box; }
  .#{$flexName}-none        { flex: 0 0 auto;  box-sizing: border-box; }
  .#{$flexName}-noshrink    { flex: 1 0 auto;  box-sizing: border-box; }
  .#{$flexName}-nogrow      { flex: 0 1 auto;  box-sizing: border-box; }

  // (1-20) * 5 = 0-100%
  @for $i from 0 through 20 {
    $value : #{$i * 5 + '%'};

    .#{$flexName}-#{$i * 5} {
      flex: 1 1 #{$value};
      max-width: #{$value};
      max-height: 100%;
      box-sizing: border-box;
    }

    .layout-row > .#{$flexName}-#{$i * 5} {
      flex: 1 1 #{$value};
      max-width: #{$value};
      max-height: 100%;
      box-sizing: border-box;

      // Bug workaround for http://crbug.com/546034 - flex issues on Chrome 48
      @if $i == 0 {  min-width: 0;  }
    }

    .layout-column > .#{$flexName}-#{$i * 5} {
      flex: 1 1 #{$value};
      max-width: 100%;
      max-height: #{$value};
      box-sizing: border-box;
    }

    .layout-row {
      > .#{$flexName}-33   , > .#{$flexName}-33     {  flex: 1 1 33.33%;  max-width: 33.33%;  max-height: 100%; box-sizing: border-box; }
      > .#{$flexName}-66   , > .#{$flexName}-66     {  flex: 1 1 66.66%;  max-width: 66.66%;  max-height: 100%; box-sizing: border-box; }
    }

    .layout-column {
      > .#{$flexName}-33   , > .#{$flexName}-33     {  flex: 1 1 33.33%;  max-width: 100%;  max-height: 33.33%; box-sizing: border-box; }
      > .#{$flexName}-66   , > .#{$flexName}-66     {  flex: 1 1 66.66%;  max-width: 100%;  max-height: 66.66%; box-sizing: border-box; }
    }

    .layout#{$name}-row > .#{$flexName}-#{$i * 5} {
      flex: 1 1 #{$value};
      max-width: #{$value};
      max-height: 100%;
      box-sizing: border-box;

      // Bug workaround for http://crbug.com/546034 - flex issues on Chrome 48
      @if $i == 0 {  min-width: 0;  }
    }

    .layout#{$name}-column > .#{$flexName}-#{$i * 5} {
      flex: 1 1 #{$value};
      max-width: 100%;
      max-height: #{$value};
      box-sizing: border-box;

      // Bug workaround for http://crbug.com/546034 - flex issues on Chrome 48
      @if $i == 0 {  min-height: 0;  }
    }

  }

  .layout#{$name}-row {
    > .#{$flexName}-33   , > .#{$flexName}-33     {  flex: 1 1 33.33%;  max-width: 33.33%;  max-height: 100%; box-sizing: border-box; }
    > .#{$flexName}-66   , > .#{$flexName}-66     {  flex: 1 1 66.66%;  max-width: 66.66%;  max-height: 100%; box-sizing: border-box; }

    // Bug workaround for http://crbug.com/546034 - flex issues on Chrome 48
    > .flex                                       { min-width: 0;   }

  }

  .layout#{$name}-column {
    > .#{$flexName}-33   , > .#{$flexName}-33     {  flex: 1 1 33.33%;  max-width: 100%;  max-height: 33.33%; box-sizing: border-box; }
    > .#{$flexName}-66   , > .#{$flexName}-66     {  flex: 1 1 66.66%;  max-width: 100%;  max-height: 66.66%; box-sizing: border-box; }

    // Bug workaround for http://crbug.com/546034 - flex issues on Chrome 48
    > .flex                                       { min-height: 0;   }
  }

}

@mixin layout-align-for-name($suffix: null) {

  // Alignment attributes for layout containers' children
  // Arrange on the Main Axis
  // center, start, end, space-between, space-around
  // flex-start is the default for justify-content
  // ------------------------------

  $name: 'layout-align';
  @if $suffix != null {
    $name: 'layout-align-#{$suffix}';
  }

  .#{$name},
  .#{$name}-start-stretch // defaults
  {
    justify-content : flex-start;
    align-content : stretch;
    align-items: stretch;
  }

  // Main Axis Center
  .#{$name}-start,
  .#{$name}-start-start,
  .#{$name}-start-center,
  .#{$name}-start-end,
  .#{$name}-start-stretch
  {
    justify-content: flex-start;
  }

  // Main Axis Center
  .#{$name}-center,           //stretch
  .#{$name}-center-start,
  .#{$name}-center-center,
  .#{$name}-center-end,
  .#{$name}-center-stretch
  {
    justify-content: center;
  }

  // Main Axis End
  .#{$name}-end, //stretch
  .#{$name}-end-start,
  .#{$name}-end-center,
  .#{$name}-end-end,
  .#{$name}-end-stretch
  {
    justify-content: flex-end;
  }

  // Main Axis Space Around
  .#{$name}-space-around, //stretch
  .#{$name}-space-around-center,
  .#{$name}-space-around-start,
  .#{$name}-space-around-end,
  .#{$name}-space-around-stretch
  {
    justify-content: space-around;
  }

  // Main Axis Space Between
  .#{$name}-space-between, //stretch
  .#{$name}-space-between-center,
  .#{$name}-space-between-start,
  .#{$name}-space-between-end,
  .#{$name}-space-between-stretch
  {
    justify-content: space-between;
  }


  // Arrange on the Cross Axis
  // center, start, end
  // stretch is the default for align-items
  // ------------------------------

  // Cross Axis Start
  .#{$name}-start-start,
  .#{$name}-center-start,
  .#{$name}-end-start,
  .#{$name}-space-between-start,
  .#{$name}-space-around-start
  {
    align-items: flex-start;
    align-content: flex-start;
  }

  // Cross Axis Center
  .#{$name}-start-center,
  .#{$name}-center-center,
  .#{$name}-end-center,
  .#{$name}-space-between-center,
  .#{$name}-space-around-center
  {
    align-items: center;
    align-content: center;
    max-width: 100%;
  }

  // Cross Axis Center IE overflow fix
  .#{$name}-start-center > *,
  .#{$name}-center-center > *,
  .#{$name}-end-center > *,
  .#{$name}-space-between-center > *,
  .#{$name}-space-around-center > *
  {
    max-width: 100%;
    box-sizing: border-box;
  }

  // Cross Axis End
  .#{$name}-start-end,
  .#{$name}-center-end,
  .#{$name}-end-end,
  .#{$name}-space-between-end,
  .#{$name}-space-around-end
  {
    align-items: flex-end;
    align-content: flex-end;
  }

  // Cross Axis Start
  .#{$name}-start-stretch,
  .#{$name}-center-stretch,
  .#{$name}-end-stretch,
  .#{$name}-space-between-stretch,
  .#{$name}-space-around-stretch
  {
    align-items: stretch;
    align-content: stretch;
  }
}

@mixin layout-padding-margin() {

  // NOTE: these`> *` selectors should only be applied for layout="row" or layout="column" children !!
  .layout-padding-sm > *,
  .layout-padding    > .flex-sm
  {
    padding: $layout-gutter-width / 4;
  }

  .layout-padding,
  .layout-padding-gt-sm,
  .layout-padding-md,

    // NOTE: these`> *` selectors should only be applied for layout="row" or layout="column" children !!
  .layout-padding        > *,
  .layout-padding-gt-sm  > *,
  .layout-padding-md     > *,

  .layout-padding        > .flex,
  .layout-padding        > .flex-gt-sm,
  .layout-padding        > .flex-md
  {
    padding: $layout-gutter-width / 2;
  }

  // NOTE: these`> *` selectors should only be applied for layout="row" or layout="column" children !!
  .layout-padding-gt-md  > *,
  .layout-padding-lg     > *,
  .layout-padding-gt-lg  > *,

  .layout-padding        > .flex-gt-md,
  .layout-padding        > .flex-lg,
  .layout-padding        > .flex-lg,
  .layout-padding        > .flex-gt-lg
  {
    padding: $layout-gutter-width / 1;
  }

  // Margin enhancements

  .layout-margin-sm      > *,
  .layout-margin         > .flex-sm
  {
    margin: $layout-gutter-width / 4;
  }

  .layout-margin,
  .layout-margin-gt-sm,
  .layout-margin-md,

    // NOTE: these`> *` selectors should only be applied for layout="row" or layout="column" children !!
  .layout-margin         > *,
  .layout-margin-gt-sm   > *,
  .layout-margin-md      > *,

  .layout-margin         > .flex,
  .layout-margin         > .flex-gt-sm,
  .layout-margin         > .flex-md
  {
    margin: $layout-gutter-width / 2;
  }

  // NOTE: these`> *` selectors should only be applied for layout="row" or layout="column" children !!
  .layout-margin-gt-md  > *,
  .layout-margin-lg     > *,
  .layout-margin-gt-lg  > *,

  .layout-margin        > .flex-gt-md,
  .layout-margin        > .flex-lg,
  .layout-margin        > .flex-gt-lg
  {
    margin: $layout-gutter-width / 1;
  }

  .layout-wrap {
    flex-wrap: wrap;
  }

  .layout-nowrap {
    flex-wrap: nowrap;
  }

  .layout-fill {
    margin: 0;
    width: 100%;
    min-height: 100%;
    height: 100%;
  }
}

@mixin layouts_for_breakpoint($name:null) {
  @include flex-order-for-name($name);
  @include offset-for-name($name);
  @include layout-align-for-name($name);

  @include flex-properties-for-name($name);
  @include layout-for-name($name);
}

/* IE10-IE11 column-flex bug fix (set proper default value) */
.layout-column > .flex {
  -ms-flex-basis: auto;
  flex-basis: auto;
}

/**
 *  Responsive attributes
 *
 *  References:
 *  1) https://scotch.io/tutorials/a-visual-guide-to-css3-flexbox-properties#flex
 *  2) https://css-tricks.com/almanac/properties/f/flex/
 *  3) https://css-tricks.com/snippets/css/a-guide-to-flexbox/
 *  4) https://github.com/philipwalton/flexbugs#3-min-height-on-a-flex-container-wont-apply-to-its-flex-items
 *  5) http://godban.com.ua/projects/flexgrid
*/

@-moz-document url-prefix() {
  .layout-fill {
    margin: 0;
    width: 100%;
    min-height: 100%;
    height: 100%;
  }
}


/*
 *  Apply Mixins to create Layout/Flexbox styles
 *
 */


@include layouts_for_breakpoint();
@include layout-padding-margin();



/**
 * `hide-gt-sm show-gt-lg` should hide from 600px to 1200px
 * `show-md hide-gt-sm` should show from 0px to 960px and hide at >960px
 * `hide-gt-md show-gt-sm` should show everywhere (show overrides hide)`
 *
 *  hide means hide everywhere
 *  Sizes:
 *         $layout-breakpoint-xs:     600px !default;
 *         $layout-breakpoint-sm:     960px !default;
 *         $layout-breakpoint-md:     1280px !default;
 *         $layout-breakpoint-lg:     1920px !default;
 */


@media (max-width: $layout-breakpoint-xs - 1) {
  // Xtra-SMALL  SCREEN
  .hide-xs, .hide {
    &:not(.show-xs):not(.show) {
      display: none;
    }
  }
  @include layouts_for_breakpoint(xs);
}

@media (min-width: $layout-breakpoint-xs) {
  // BIGGER THAN Xtra-SMALL SCREEN
  @include layouts_for_breakpoint(gt-xs);

}

@media (min-width: $layout-breakpoint-xs) and (max-width: $layout-breakpoint-sm - 1) {
  .hide, .hide-gt-xs {
    &:not(.show-gt-xs):not(.show-sm):not(.show) {
      display: none;
    }
  }
  .hide-sm:not(.show-gt-xs):not(.show-sm):not(.show) {
    display: none;
  }

  @include layouts_for_breakpoint(sm);
}

@media (min-width: $layout-breakpoint-sm) {
  // BIGGER THAN SMALL SCREEN
  @include layouts_for_breakpoint(gt-sm);

}

@media (min-width: $layout-breakpoint-sm) and (max-width: $layout-breakpoint-md - 1) {
  // MEDIUM SCREEN
  .hide, .hide-gt-xs, .hide-gt-sm {
    &:not(.show-gt-xs):not(.show-gt-sm):not(.show-md):not(.show) {
      display: none;
    }
  }
  .hide-md:not(.show-md):not(.show-gt-sm):not(.show-gt-xs):not(.show) {
    display: none;
  }
  @include layouts_for_breakpoint(md);
}

@media (min-width: $layout-breakpoint-md) {
  // BIGGER THAN MEDIUM SCREEN
  @include layouts_for_breakpoint(gt-md);
}

@media (min-width: $layout-breakpoint-md) and (max-width: $layout-breakpoint-lg - 1) {
  // LARGE SCREEN
  .hide,.hide-gt-xs, .hide-gt-sm, .hide-gt-md {
    &:not(.show-gt-xs):not(.show-gt-sm):not(.show-gt-md):not(.show-lg):not(.show) {
      display: none;
    }
  }
  .hide-lg:not(.show-lg):not(.show-gt-md):not(.show-gt-sm):not(.show-gt-xs):not(.show) {
    display: none;
  }

  @include layouts_for_breakpoint(lg);
}

@media (min-width: $layout-breakpoint-lg) {
  @include layouts_for_breakpoint(gt-lg);
  @include layouts_for_breakpoint(xl);

  // BIGGER THAN LARGE SCREEN
  .hide, .hide-gt-xs, .hide-gt-sm, .hide-gt-md, .hide-gt-lg {
    &:not(.show-gt-xs):not(.show-gt-sm):not(.show-gt-md):not(.show-gt-lg):not(.show-xl):not(.show) {
      display: none;
    }
  }
  .hide-xl:not(.show-xl):not(.show-gt-lg):not(.show-gt-md):not(.show-gt-sm):not(.show-gt-xs):not(.show) {
    display: none;
  }

}
