.grid-table-cell-repeat(@n, @i: 1) when (@i =< @n) {
  &:first-child:nth-last-child(@{i}), &:first-child:nth-last-child(@{i}) ~ *:not([class*="@{cell}-"]):not([colspan]) {
    width: 100% / @i;
  }
  .grid-table-cell-repeat(@n, (@i + 1));
}

.grid-gutter-repeat(@n, @grid-steps, @unit, @start, @step, @i: 1) when (@i =< @n) {
  @value: (@start * @step) + @i * @step;
  &.@{gutter}-@{i} {
    margin-left: unit(-@value/2, @unit);
    margin-right: unit(-@value/2, @unit);
    &:not([class*="cell-"]):not(table):not(.@{content-holder}) {
      width: auto;
    }
    table& {
      width: calc(100% ~" + " unit(@value, @unit));
    }
    &.@{content-holder} {
      @margin: (@content-min-margin * 2);
      @gutter: unit(@value, @unit);
      width: calc(@content-max-width ~" + @{gutter}");
      max-width: calc(100% ~" - ( @{margin} - @{gutter})");
    }
    > [class*=" @{cell}"], > [class^="@{cell}"], > .@{row} > [class*=" @{cell}"], > .@{row} > [class^="@{cell}"], > tbody > tr > td, > tr > td {
      border-left: unit(@value/2, @unit) solid transparent;
      border-right: unit(@value/2, @unit) solid transparent;
      &.@{start-before} {
        margin-left: unit(-@value, @unit);
      }
      &.@{end-before} {
        margin-right: unit(-@value, @unit);
      }
    }
    > [class*="@{grid}"].@{row} {
      border-left: unit(@value/2, @unit) solid transparent;
      border-right: unit(@value/2, @unit) solid transparent;
    }
  }

  .grid-gutter(@grid-steps, @i, @value, @unit);
  .grid-gutter-repeat(@n, @grid-steps, @unit, @start, @step, (@i + 1));
}

.grid-gutter(@n, @grid-space, @value, @unit, @i: 1) when (@i =< @n) {
  &.@{gutter}-@{grid-space} {
    .@{cell}-@{i} {
      &.@{start-before}, &.@{end-before} {
        width: calc(unit((100 / @n) * @i, %) ~" + " unit(@value, @unit));
      }
      &.@{start-before}.@{end-before} {
        width: calc(unit((100 / @n) * @i, %) ~" + " unit(@value*2, @unit));
      }
    }
  }
  .grid-gutter(@n, @grid-space, @value, @unit, (@i + 1));
}


.grid-space-repeat(@n, @grid-steps, @unit, @start, @step, @i: 1) when (@i =< @n) {
  @value: (@start * @step) + @i * @step;
  &.@{space}-@{i} {
    margin-top: unit(-@value/2, @unit);
    margin-bottom: unit(-@value/2, @unit);
    &:not(.@{grid}) {
      width: auto;
    }
    &:not(.@{space-margin}) {
      > [class*=" @{cell}"], > [class^="@{cell}"], > .@{row} > [class*=" @{cell}"], > .@{row} > [class^="@{cell}"], > tbody > tr > td, > tr > td {
        border-top: unit(@value/2, @unit) solid transparent;
        border-bottom: unit(@value/2, @unit) solid transparent;
      }
    }

    > [class*="@{grid}"].@{row} {
      border-top: unit(@value/2, @unit) solid transparent;
      border-bottom: unit(@value/2, @unit) solid transparent;
    }
  }
  .grid-space(@grid-steps, @i, @value, @unit);
  .grid-space-repeat(@n, @grid-steps, @unit, @start, @step, (@i + 1));
}

.grid-space(@n, @grid-space, @value, @unit, @i: 1) when (@i =< @n) {
  &[class*="@{space}-@{grid-space}"] {
    &.@{space-margin} {
      .@{cell}-@{i} {
        margin-top: unit(@value/2, @unit);
        margin-bottom: unit(@value/2, @unit);
      }
    }
  }
  .grid-space(@n, @grid-space, @value, @unit, (@i + 1));
}

.grid-cell(@n, @i: 1) when (@i =< @n) {
  .@{cell}-@{i} {
    width: unit((100 / @n) * @i, %);
  }
  & when (@grid-step-fractions = true) {
    .@{cell}-@{i}-9 {
      width: unit((100 / @n) * @i + (100 / @n / (10/9)), %);
    }
    .@{cell}-@{i}-8 {
      width: unit((100 / @n) * @i + (100 / @n / (10/8)), %);
    }
    .@{cell}-@{i}-7 {
      width: unit((100 / @n) * @i + (100 / @n / (10/7)), %);
    }
    .@{cell}-@{i}-6 {
      width: unit((100 / @n) * @i + (100 / @n / (10/6)), %);
    }
    .@{cell}-@{i}-5 {
      width: unit((100 / @n) * @i + (100 / @n / (10/5)), %);
    }
    .@{cell}-@{i}-4 {
      width: unit((100 / @n) * @i + (100 / @n / (10/3)), %);
    }
    .@{cell}-@{i}-3 {
      width: unit((100 / @n) * @i + (100 / @n / (10/3)), %);
    }
    .@{cell}-@{i}-2 {
      width: unit((100 / @n) * @i + (100 / @n / (10/2)), %);
    }
    .@{cell}-@{i}-1 {
      width: unit((100 / @n) * @i + (100 / @n / (10/1)), %);
    }
  }

  .grid-cell(@n, (@i + 1));
}

.grid-cell-mobile(@mobile-class, @mobile-name, @n, @i: 1) when (@i =< @n) {
  & when (@mobile-name = desktop) {
    @media (min-width: @desktop-min-width) {
      .@{mobile-class}-@{cell}-@{i} {
        width: unit((100 / @n) * @i, %);
        .flex(0 0 auto) !important;
      }
    }
  }
  & when not (@mobile-name = desktop) {
    @media (max-width: ~"@{@{mobile-name}-max-width}") {
      .@{mobile-class}-@{cell}-@{i} {
        width: unit((100 / @n) * @i, %);
        .flex(0 0 auto) !important;
      }
    }
  }
  .grid-cell-mobile(@mobile-class, @mobile-name, @n, (@i + 1));
}

.grid-cell-extend(@n, @i: 1) when (@i =< @n) {
  table& .@{cell}-@{i} {
    min-width: unit((100 / @n) * @i, %);
    max-width: unit((100 / @n) * @i, %);
    width: unit((100 / @n) * @i, %);
  }
  &.@{column} {
    > .@{cell}-@{i}, > .row > .@{cell}-@{i} {
      width: auto;
      flex: 1 1 unit((100 / @n) * @i, %);
    }
    .@{width}-@{i} {
      width: unit((100 / @n) * @i, %);
    }
  }
  .grid-cell-extend(@n, (@i + 1));
}

.grid-offset(@n, @i: 0) when (@i < @n) {
  [class*="@{cell}"], &[class*="@{width}-"] {
    &.@{offset-left}-@{i}, &.@{offset}-@{i} {
      margin-left: unit((100 / @n) * @i, %) !important;
    }
    &.@{offset-right}-@{i} {
      margin-right: unit((100 / @n) * @i, %) !important;
    }
  }
  &.@{offset-left}-@{i}, &.@{offset}-@{i}, .@{row}.@{offset-left}-@{i}, .@{row}.@{offset}-@{i} {
    [class*="@{cell}"]:first-child {
      margin-left: unit((100 / @n) * @i, %);
    }
  }
  &.@{offset-right}-@{i}, .@{row}.@{offset-right}-@{i} {
    [class*="@{cell}"]:last-child {
      margin-right: unit((100 / @n) * @i, %);
    }
  }
  .grid-offset(@n, (@i + 1));
}

.grid-offset-mobile(@n, @i: 0) when (@i < @n) {
  @media (min-width: @desktop-min-width) {
    .@{d}-@{offset}-@{i}, .@{d}-@{offset-left}-@{i} {
      &[class*="@{cell}"], &[class*="@{width}-"] {
        margin-left: unit((100 / @n) * @i, %) !important;
      }
    }
    &.@{d}-@{offset}-@{i}, &.@{d}-@{offset-left}-@{i} {
      [class*="@{cell}"]:first-child {
        margin-left: unit((100 / @n) * @i, %);
      }
    }
    .@{d}-@{offset-right}-@{i} {
      &[class*="@{cell}"], &[class*="@{width}-"] {
        margin-right: unit((100 / @n) * @i, %) !important;
      }
    }
    &.@{d}-@{offset-right}-@{i} {
      [class*="@{cell}"]:last-child {
        margin-right: unit((100 / @n) * @i, %);
      }
    }
  }

  @media (max-width: @tablet-max-width) {
    .@{t}-@{offset}-@{i}, .@{t}-@{offset-left}-@{i} {
      &[class*="@{cell}"], &[class*="@{width}-"] {
        margin-left: unit((100 / @n) * @i, %) !important;
      }
    }
    &.@{t}-@{offset}-@{i}, &.@{t}-@{offset-left}-@{i} {
      [class*="@{cell}"]:first-child {
        margin-left: unit((100 / @n) * @i, %);
      }
    }
    .@{t}-@{offset-right}-@{i} {
      &[class*="@{cell}"], &[class*="@{width}-"] {
        margin-right: unit((100 / @n) * @i, %) !important;
      }
    }
    &.@{t}-@{offset-right}-@{i} {
      [class*="@{cell}"]:last-child {
        margin-right: unit((100 / @n) * @i, %);
      }
    }
  }

  @media (max-width: @tablet-portrait-max-width) {
    .@{tp}-@{offset}-@{i}, .@{tp}-@{offset-left}-@{i} {
      &[class*="@{cell}"], &[class*="@{width}-"] {
        margin-left: unit((100 / @n) * @i, %) !important;
      }
    }
    &.@{tp}-@{offset}-@{i}, &.@{tp}-@{offset-left}-@{i} {
      [class*="@{cell}"]:first-child {
        margin-left: unit((100 / @n) * @i, %);
      }
    }
    .@{tp}-@{offset-right}-@{i} {
      &[class*="@{cell}"], &[class*="@{width}-"] {
        margin-right: unit((100 / @n) * @i, %) !important;
      }
    }
    &.@{tp}-@{offset-right}-@{i} {
      [class*="@{cell}"]:last-child {
        margin-right: unit((100 / @n) * @i, %);
      }
    }
  }
  @media (max-width: @mobile-max-width) {
    .@{m}-@{offset}-@{i}, .@{m}-@{offset-left}-@{i} {
      &[class*="@{cell}"], &[class*="@{width}-"] {
        margin-left: unit((100 / @n) * @i, %) !important;
      }
    }
    &.@{m}-@{offset}-@{i}, &.@{m}-@{offset-left}-@{i} {
      [class*="@{cell}"]:first-child {
        margin-left: unit((100 / @n) * @i, %);
      }
    }
    .@{m}-@{offset-right}-@{i} {
      &[class*="@{cell}"], &[class*="@{width}-"]  {
        margin-right: unit((100 / @n) * @i, %) !important;
      }
    }
    &.@{m}-@{offset-right}-@{i} {
      [class*="@{cell}"]:last-child {
        margin-right: unit((100 / @n) * @i, %);
      }
    }
  }

  @media (max-width: @mobile-portrait-max-width) {
    .@{mp}-@{offset}-@{i}, .@{mp}-@{offset-left}-@{i} {
      &[class*="@{cell}"], &[class*="@{width}-"] {
        margin-left: unit((100 / @n) * @i, %) !important;
      }
    }
    &.@{mp}-@{offset}-@{i}, &.@{mp}-@{offset-left}-@{i} {
      [class*="@{cell}"]:first-child {
        margin-left: unit((100 / @n) * @i, %);
      }
    }
    .@{mp}-@{offset-right}-@{i} {
      &[class*="@{cell}"], &[class*="@{width}-"] {
        margin-right: unit((100 / @n) * @i, %) !important;
      }
    }
    &.@{mp}-@{offset-right}-@{i} {
      [class*="@{cell}"]:last-child {
        margin-right: unit((100 / @n) * @i, %);
      }
    }
  }

  .grid-offset-mobile(@n, (@i + 1));
}

.@{cell}-fill {
  .flex(1 1 auto);
  width: auto;
  min-width: 0;
  min-height: 0;
}

.@{cell}-auto {
  .flex(0 0 auto);
  width: auto;
  min-width: 0;
  min-height: 0;
}

@media (min-width: @desktop-min-width) {
  .@{d}-@{cell}-fill {
    .flex(1 1 auto);
    width: auto;
  }

  .@{d}-@{cell}-auto {
    .flex(0 0 auto);
    width: auto;
  }
}
@media (max-width: @tablet-max-width) {
  .@{t}-@{cell}-fill {
    .flex(1 1 auto);
    width: auto;
  }

  .@{t}-@{cell}-auto {
    .flex(0 0 auto);
    width: auto;
  }
}
@media (max-width: @tablet-portrait-max-width) {
  .@{tp}-@{cell}-fill {
    .flex(1 1 auto);
    width: auto;
  }

  .@{tp}-@{cell}-auto {
    .flex(0 0 auto);
    width: auto;
  }
}
@media (max-width: @mobile-max-width) {
  .@{m}-@{cell}-fill {
    .flex(1 1 auto);
    width: auto;
  }

  .@{m}-@{cell}-auto {
    .flex(0 0 auto);
    width: auto;
  }
}
@media (max-width: @mobile-portrait-max-width) {
  .@{mp}-@{cell}-fill {
    .flex(1 1 auto);
    width: auto;
  }

  .@{mp}-@{cell}-auto {
    .flex(0 0 auto);
    width: auto;
  }
}

.grid-cell(@grid-steps);
.grid-cell-mobile(d, desktop, @grid-steps);
.grid-cell-mobile(t, tablet, @grid-steps);
.grid-cell-mobile(tp, tablet-portrait, @grid-steps);
.grid-cell-mobile(m, mobile, @grid-steps);
.grid-cell-mobile(mp, mobile-portrait, @grid-steps);

.@{grid} {
  .grid-cell-extend(@grid-steps);
  & when (@grid-offset = true) {
    .grid-offset(@grid-steps);
    .grid-offset-mobile(@grid-steps);
  }
  & when (@grid-gutter = true) {
    .grid-gutter-repeat(@grid-gutter-steps, @grid-steps, @grid-gutter-unit, @grid-gutter-start, @grid-gutter-step);
  }
  & when (@grid-space = true) {
    .grid-space-repeat(@grid-space-steps, @grid-steps, @grid-space-unit, @grid-space-start, @grid-space-step);
  }

  .display-flex;
  .flex-wrap(wrap);
  .flex-direction(row);
  .align-items(stretch);
  &.@{content-holder} {
    margin-left: auto;
    margin-right: auto;
    width: @content-max-width;
  }
  .@{row} {
    max-width: 100%;
  }
  &:not(.@{column}) {
    > .@{cell}:not(.@{grid}):not(.@{column}), > .@{row} > .@{cell}:not(.@{grid}):not(.@{column}) {
      .flex(~"1 0 0px");
      &:only-child {
        width: 100%;
      }
    }
    > .@{cell}.@{grid}.@{column}, > .@{row} > .@{cell}.@{grid}.@{column} {
      .flex(1 0 100%);
    }
    table& {
      td, th {
        &:not([class*="@{cell}-"]):not([colspan]) {
          .grid-table-cell-repeat(@grid-steps);
        }
      }
    }
  }
  &.@{reverse} {
    .flex-direction(row-reverse);
  }
  &.@{nowrap} {
    .flex-flow(row nowrap);
  }
  &.@{column} {
    .flex-flow(column nowrap);
    .flex-direction(column);
    > .@{row} {
      .flex-flow(column nowrap);
      .flex-direction(column);
    }
  }
  &.@{column-force} {
    .flex-flow(column nowrap);
    .flex-direction(column);
    > .@{row} {
      .flex-flow(column nowrap);
      .flex-direction(column);
      .flex(none);
    }
    > [class*=" @{cell}"], > [class^="@{cell}"], > .@{row} > [class*=" @{cell}"], > .@{row} > [class^="@{cell}"], tbody > .@{row} > [class*=" @{cell}"], tbody > .@{row} > [class^="@{cell}"] {
      .flex(none);
    }
  }
  &.@{column-force} {
    height: 100%;
  }
  &.@{column-wrap} {
    .flex-flow(column wrap);
    height: 100%;
  }
  &.@{justify-center} {
    .justify-content(center);
  }
  &.@{justify-between} {
    .justify-content(space-between);
  }
  &.@{justify-around} {
    .justify-content(space-between);
  }
  &.@{justify-end} {
    .justify-content(flex-end);
  }
  &.@{vertical-center} {
    .align-items(center);
  }
  &.@{vertical-start} {
    .align-items(flex-start);
  }
  &.@{vertical-end} {
    .align-items(flex-end);
  }
  &.@{text-center} {
    [class^="@{cell}"], [class*=" @{cell}"] {
      text-align: center;
      .justify-content(center);
    }
  }
  &.@{text-right} {
    [class^="@{cell}"], [class*=" @{cell}"] {
      text-align: right;
    }
  }
  &.@{text-left} {
    [class^="@{cell}"], [class*=" @{cell}"] {
      text-align: left;
    }
  }
  &.@{floating} {
    display: block;
    &.@{reverse} {
      [class^="@{cell}"], [class*=" @{cell}"] {
        float: right;
      }
    }
    [class^="@{cell}"], [class*=" @{cell}"] {
      float: left;
    }
    .@{row} {
      display: block;
      &:after, &:before {
        content: "";
        display: block;
        clear: both;
      }
    }
  }

  table&, &.@{table} {
    display: table;
    border: 0;
    border-spacing: 0;
    border-collapse: collapse;
    width: 100%;
    table-layout: fixed;
    tr, .@{row} {
      display: table-row;
    }
    td, [class*=" @{cell}"], [class^="@{cell}"] {
      display: table-cell;
      &:first-child {
        border-left: 0;
      }
      &:last-child {
        border-left: 0;
      }
    }
  }

  &.@{column-force} {
    [class*=" @{cell}"], [class^="@{cell}"] {
      width: 100% !important;
      .flex(~"0 0 auto !important");
    }
  }
  @media (min-width: @desktop-min-width) {
    &.@{d}-@{column-force} {
      [class*=" @{cell}"], [class^="@{cell}"] {
        width: 100% !important;
        .flex(~"0 0 auto !important");
      }
    }
    &.@{d}-@{column} {
      > [class*=" @{cell}"], > .@{row} > [class*=" @{cell}"], > [class^="@{cell}"], > .@{row} > [class^="@{cell}"] {
        width: 100% !important;
        .flex(~"0 0 auto !important");
      }
    }
  }
  @media (max-width: @tablet-max-width) {
    &.@{t}-@{column-force} {
      [class*=" @{cell}"], [class^="@{cell}"] {
        width: 100% !important;
        .flex(~"0 0 auto !important");
      }
    }
    &.@{t}-@{column} {
      > [class*=" @{cell}"], > .@{row} > [class*=" @{cell}"], > [class^="@{cell}"], > .@{row} > [class^="@{cell}"] {
        width: 100% !important;
        .flex(~"0 0 auto !important");
      }
    }
  }
  @media (max-width: @tablet-portrait-max-width) {
    &.@{tp}-@{column-force} {
      [class*=" @{cell}"], [class^="@{cell}"] {
        width: 100% !important;
        .flex(~"0 0 auto !important");
      }
    }
    &.@{tp}-@{column} {
      > [class*=" @{cell}"], > .@{row} > [class*=" @{cell}"], > [class^="@{cell}"], > .@{row} > [class^="@{cell}"] {
        width: 100% !important;
        .flex(~"0 0 auto !important");
      }
    }
  }
  @media (max-width: @mobile-max-width) {
    &.@{m}-@{column-force} {
      [class*=" @{cell}"], [class^="@{cell}"] {
        width: 100% !important;
        .flex(~"0 0 auto !important");
      }
    }
    &.@{m}-@{column} {
      > [class*=" @{cell}"], > .@{row} > [class*=" @{cell}"], > [class^="@{cell}"], > .@{row} > [class^="@{cell}"] {
        width: 100% !important;
        .flex(~"0 0 auto !important");
      }
    }
  }
  @media (max-width: @mobile-portrait-max-width) {
    &.@{mp}-@{column-force} {
      [class*=" @{cell}"], [class^="@{cell}"] {
        width: 100% !important;
        .flex(~"0 0 auto !important");
      }
    }
    &.@{mp}-@{column} {
      > [class*=" @{cell}"], > .@{row} > [class*=" @{cell}"], > [class^="@{cell}"], > .@{row} > [class^="@{cell}"] {
        width: 100% !important;
        .flex(~"0 0 auto !important");
      }
    }
  }
}

[class^="@{cell}-"], [class*=" @{cell}-"], .@{cell} {
  box-sizing: border-box;
  min-width: 0;
  min-height: 0;
  &.@{vertical-center} {
    .align-self(center);
  }
  &.@{vertical-items-center} {
    .display-flex;
    .align-items(center);
  }
  &.@{vertical-items-stretch} {
    .display-flex;
    .align-items(stretch);
  }
  &.@{vertical-items-end} {
    .display-flex;
    .align-items(flex-end);
  }
  &.@{vertical-items-start} {
    .display-flex;
    .align-items(flex-start);
  }
  &.@{items-center} {
    .display-flex;
    .justify-content(center);
  }
  &.@{items-stretch} {
    .display-flex;
    .justify-content(stretch);
  }
  &.@{items-end} {
    .display-flex;
    .justify-content(flex-end);
  }
  &.@{items-start} {
    .display-flex;
    .justify-content(flex-start);
  }
}

.@{row} {
  .flex(1 1 100%);
  .display-flex;
  .flex-wrap(inherit);
  min-width: 0;
  min-height: 0;
  &:not([class*="@{grid}"]) {
    .flex-direction(inherit);
  }
  &.@{vertical-center} {
    [class^="@{cell}"], [class*=" @{cell}"] {
      .align-self(center);
    }
  }
  &.@{text-center} {
    [class^="@{cell}"], [class*=" @{cell}"] {
      text-align: center;
    }
  }
  &.@{text-right} {
    [class^="@{cell}"], [class*=" @{cell}"] {
      text-align: right;
    }
  }
  &.@{text-left} {
    [class^="@{cell}"], [class*=" @{cell}"] {
      text-align: left;
    }
  }
}
