.grid-mixins(){

    @defaultCols: 12;
    @defaultGutters: 15px;
    @defaultMaxContainer: 75rem;
    @defaultGridType: flexbox; //the other option is default
    @defaultBreakPoints: xs 0rem sm 36rem md 48rem lg 62rem xl 75rem;
    @defaultFallback: false;

    .make-grids(@columnCount: @defaultCols, @gutterWidth: @defaultGutters, @maxContainerWidth: @defaultMaxContainer, @gridtype:@defaultGridType, @breakPoints:@defaultBreakPoints, @fallback: @defaultFallback) {

        .generate-grid-container();
        .generate-grid-framework();

      	.iter(length(@breakPoints));
        .iter(@i) when (@i > 2) {
            .iter(@i - 2);
            @key:   extract(@breakPoints, @i - 1);
            @value: extract(@breakPoints, @i);
            //create media query and grid
            @media only screen and (min-width: @value) {
                .generate-grid(@key, @gridtype, @columnCount);
                .generate-fixed-container(@value);
            }
        }
      	.iter(@i) when (@i = 2) {
            @key:   extract(@breakPoints, @i - 1);
            @value: extract(@breakPoints, @i);
            @mobileMax: extract(@breakPoints, (@i + 2));
            //set the base grid
            .generate-grid(default, @gridtype, @columnCount);
            //force base grid to single column at mobile breakpoint
            @media only screen and (max-width: @mobileMax) {
                .generate-grid(mobile, @gridtype, @columnCount);
            }
            //override single column mobile grid for smallest size at mobile breakpoint
            @media only screen and (min-width: @value) {
                .generate-grid(@key, @gridtype, @columnCount);
            }
        }

        .generate-grid-container(){

            .ivx-grid-wrap {
                box-sizing: border-box;
                max-width: @maxContainerWidth;
                margin: 0 auto;
            }

            .ivx-grid-container-fluid {
                padding-right: ~"calc(@{gutterWidth} * 2)";
                padding-left: ~"calc(@{gutterWidth} * 2)";
            }

            .ivx-grid-container,
            .ivx-grid-container-fluid {
                margin-right: auto;
                margin-left: auto;
            }

        }

        .generate-fixed-container(@width){

            .ivx-grid-container{
                width: ~"calc(@{width} + (@{gutterWidth} * 2))";
            }

        }

        .generate-grid-framework() when (@gridtype = default){

            .ivx-grid-row {
                margin-right: -@gutterWidth;
                margin-left: -@gutterWidth;
                box-sizing: border-box;
            }

            .ivx-grid-row:before,
            .ivx-grid-row:after {
                content: " ";
                display: table;
            }

            .ivx-grid-row:after {
                clear: both;
            }

            .ivx-grid-row-full-width{
                margin-right: -(@gutterWidth*2);
                margin-left: -(@gutterWidth*2);
            }

            [class*="ivx-grid-col"]{
                box-sizing: border-box;
                padding-left: @gutterWidth;
                padding-right: @gutterWidth;
            }

        }

        .generate-grid-framework() when (@gridtype = flexbox){

            .ivx-grid-row {
                box-sizing: border-box;
                display: -webkit-box;
                display: -ms-flexbox;
                display: flex;
                -webkit-box-flex: 0;
                -ms-flex: 0 1 auto;
                flex: 0 1 auto;
                -webkit-box-orient: horizontal;
                -webkit-box-direction: normal;
                -ms-flex-direction: row;
                flex-direction: row;
                -ms-flex-wrap: wrap;
                flex-wrap: wrap;
                margin-right: -@gutterWidth;
                margin-left: -@gutterWidth;
            }

            .row:after,
            .row:before{
                display: none;
            }

            .ivx-grid-row-full-width{
                margin-right: -(@gutterWidth*2);
                margin-left: -(@gutterWidth*2);
            }

            [class*="ivx-grid-col"]{
                box-sizing: border-box;
                -webkit-box-flex: 0;
                -ms-flex: 0 0 auto;
                flex: 0 0 auto;
                padding-right: @gutterWidth;
                padding-left: @gutterWidth;
            }

        }

        //generate the columns for default grid
        .generate-columns(@size:default, @type:default, @n:12, @i: 1) when (@i =< @n) and (@type = default) and (@size = default) {
            .ivx-grid-@{i}-@{n}{
                width: (@i/@n * 100%);
                float: left;
                box-sizing: border-box;
                padding-left: @gutterWidth;
                padding-right: @gutterWidth;
            }
            .generate-columns(@size, @type, @n, (@i + 1));
        }

        .generate-columns(@size, @type, @n:12, @i: 1) when (@i =< @n) and (@type = default) and not (@size = default) and not (@size = mobile) {
            .ivx-grid-col-@{size}-@{i}-@{n}{
                width: (@i/@n * 100%);
                float: left;
            }
            .generate-columns(@size, @type, @n, (@i + 1));
        }

        .generate-columns(@size:default, @type:default, @n:12, @i: 1) when (@i =< @n) and (@type = default) and (@size = mobile) {
            .ivx-grid-@{i}-@{n}{
                width: 100%;
            }
            .generate-columns(@size, @type, @n, (@i + 1));
        }

        //generate the columns for flexbox grid
        .generate-columns(@size:default, @type:default, @n:12, @i: 1) when (@i =< @n) and (@type = flexbox) and (@size = default) {
            .ivx-grid-@{i}-@{n}{
                box-sizing: border-box;
                -webkit-box-flex: 0;
                -ms-flex: 0 0 auto;
                flex: 0 0 auto;
                padding-right: @gutterWidth;
                padding-left: @gutterWidth;
                flex-basis: (@i/@n * 100%);
                max-width: (@i/@n * 100%);
            }
            .generate-columns(@size, @type, @n, (@i + 1));
        }

        .generate-columns(@size:default, @type:default, @n:12, @i: 1) when (@i =< @n) and (@type = flexbox) and not (@size = default) and not (@size = mobile) {
            .ivx-grid-col-@{size}-@{i}-@{n}{
                flex-basis: (@i/@n * 100%);
                max-width: (@i/@n * 100%);
            }
            .generate-columns(@size, @type, @n, (@i + 1));
        }

        .generate-columns(@size:default, @type:default, @n:12, @i: 1) when (@i =< @n) and (@type = flexbox) and (@size = mobile) {
            .ivx-grid-@{i}-@{n}{
                flex-basis: 100%;
                max-width: 100%;
            }
            .generate-columns(@size, @type, @n, (@i + 1));
        }

        //offsets
        .default-offsets(@size:default, @type:default, @n:12, @i: 1) when (@i < @n){
            .ivx-grid-offset-@{i}-@{n}{
                margin-left: (@i/@n * 100%);
            }
            .default-offsets(@size, @type, @n, (@i + 1));
        }

        .breakpoint-offsets(@size, @type, @n:12, @i: 1) when (@i < @n){
            .ivx-grid-offset-@{size}-@{i}-@{n}{
                margin-left: (@i/@n * 100%);
            }
            .breakpoint-offsets(@size, @type, @n, (@i + 1));
        }

        .mobile-offsets(@size:default, @type:default, @n:12, @i: 1) when (@i < @n) and (@n = @columnCount){
            [class*="ivx-grid-offset"]{
                margin-left: 0;
            }
        }

        //generate the offsets for standard grids
        .generate-offsets(@size:default, @type:default, @n:12, @i: 1) when (@i =< @n) and (@type = default) and (@size = default) {
            .default-offsets(@size, @type, @n, @i);
        }

        .generate-offsets(@size, @type, @n:12, @i: 1) when (@i =< @n) and (@type = default) and not (@size = default) and not (@size = mobile) {
            .breakpoint-offsets(@size, @type, @n, @i;)
        }

        .generate-offsets(@size:default, @type:default, @n:12, @i: 1) when (@i =< @n) and (@type = default) and (@size = mobile) {
            .mobile-offsets(@size, @type, @n, @i);
        }

        //generate the offsets for flexbox grids
        .generate-offsets(@size:default, @type:default, @n:12, @i: 1) when (@i =< @n) and (@type = flexbox) and (@size = default) {
            .default-offsets(@size, @type, @n, @i);
        }

        .generate-offsets(@size:default, @type:default, @n:12, @i: 1) when (@i =< @n) and (@type = flexbox) and not (@size = default) and not (@size = mobile) {
            .breakpoint-offsets(@size, @type, @n, @i);
        }

        .generate-offsets(@size:default, @type:default, @n:12, @i: 1) when (@i =< @n) and (@type = flexbox) and (@size = mobile) {
            .mobile-offsets(@size, @type, @n, @i);
        }

        //create grid
        .generate-grid(@size:default, @type:default, @n, @i: 1) when (@i =< @n) and (@n = @columnCount) and (@fallback = false) {
            .generate-columns(@size, @type, @n);
            .generate-offsets(@size, @type, @n);

            //add 1-4 column grids always
            .generate-grid(@size, @type, 4);
            .generate-grid(@size, @type, 3);
            .generate-grid(@size, @type, 2);
            .generate-grid(@size, @type, 1);
        }

        .generate-grid(@size:default, @type:default, @n, @i: 1) when (@i =< @n) and not (@n = @columnCount) and (@fallback = false) {
            .generate-columns(@size, @type, @n);
            .generate-offsets(@size, @type, @n);
        }

        //fallback for nitro stories - REMOVE when stories are updated
        .generate-grid(@size:default, @type:default, @n, @i: 1) when (@i =< @n) and (@fallback = true) {
            .generate-columns(@size, @type, @i);

            //add all column grids less than column count: WARNING LARGE FILE SIZE
            .generate-grid(@size, @type, @n, (@i + 1));
        }

    }

    //override grid gutters
    .gutter-override(@gutterWidth:15px, @cols:12){

        .ivx-grid-row{
            margin-right: -@gutterWidth;
            margin-left: -@gutterWidth;
        }

        .ivx-grid-row-full-width{
            margin-right: -(@gutterWidth*2);
            margin-left: -(@gutterWidth*2);
        }

        [class*="ivx-grid-col"]{
            padding-right: @gutterWidth;
            padding-left: @gutterWidth;
        }

        //need this to work with old class names
        .loop(@cols);
        .loop(@counter) when (@counter > 0) {
          .loop((@counter - 1));    // next iteration
          [class*="ivx-grid-@{counter}"]{
            padding-right: @gutterWidth;
            padding-left: @gutterWidth;
          }
        }

    }

}
