$font-size-base: 1.35rem !default;
$line-height: 1.35rem !default;
$gutter: 2rem !default;
$viewport-min-width: 102.4rem !default;

@mixin box-flex($n) {
    flex: $n 1 auto;
}

@mixin cell-size() {
    @for $i from 1 through 12 {
        &.w#{$i}, &%w#{$i} {
            width: (100% / 12) * $i;
        }
        &.h#{$i}, &%h#{$i} {
            height: (100% / 12) * $i;
        }
    }
}

*, :after, :before {
    box-sizing: border-box;
}

html {
  font-size: 62.5%;
}

body {
    line-height: $line-height;
    font-size: $font-size-base;
}

%viewport {
    position: absolute;
    left: 0px;
    top: 0px;
    bottom: 0px;
    right: 0px;
    margin: 0;
    min-width: $viewport-min-width;
}

.fluid, %fluid {
   @include box-flex(1);
   @include cell-size();

   &.stretched, &%stretched {
      align-self: stretch;
   }

   &.scrollable, &%scrollable {
      flex-basis: 0;
   }

   &.outer, &%outer {
      position: absolute;
      left: 0px;
      top: 0px;

      &.full, &%full {
          right: 0;
          bottom: 0;
      }
    }

}

.solid, %solid {
   @extend %fluid;
   flex-grow: 0;
   flex-shrink: 0;
}

@mixin flow($traits...) {
  $fluid: 1;
  $orientation: horizontal;
  $reverse: 0;
  display: flex;
  @each $trait in $traits {
    @if $trait == horizontal {
      $orientation: horizontal;
    } @else if $trait == vertical {
      $orientation: vertical;
    } @else if $trait == breakable {
      flex-wrap: wrap;
    } @else if $trait == breakable-reverse {
      flex-wrap: wrap-reverse;
      $reverse: 1;
    } @else if $trait == space-between {
      justify-content: space-between;
    } @else if $trait == space-around {
      justify-content: space-around;
    } @else if $trait == solid {
      $fluid: 0;
    }
  }
  @if $fluid == 1 {
    @extend %fluid;
  } @else {
    @extend %solid;
  }
  
  @if $orientation == horizontal {
    @include flow-horizontal($traits);
  } @else if $orientation == vertical {
    @include flow-vertical($traits, $reverse);
  }
}

@mixin flow-horizontal($traits) {
  @extend .flow.horizontal;
  flex-direction: row;
  $unparsed: 0;
  @each $trait in $traits {
    @if $trait == airy {
      & > * {
        margin-left: $gutter/2;
        margin-right: $gutter/2;
        &:first-child { margin-left: 0; }
        &:last-child { margin-right: 0; }
      }
    } @else if $trait == center {
      justify-content: center;
    } @else if $trait == middle {
      align-items: center;
    } @else if $trait == left {
      justify-content: flex-start;
    } @else if $trait == right {
      justify-content: flex-end;
    } @else if $trait == top {
      flex-direction: row;
    } @else if $trait == bottom {
      flex-direction: row-reverse;
    } @else if $trait == rtl {
      flex-direction: row-reverse;
    } @else if $trait == baseline {
      align-items: baseline;
    }
  }
}

@mixin flow-vertical($traits, $reverse: 0) {
  @extend .flow.vertical;
  flex-direction: column;
  @each $trait in $traits {
    @if $trait == airy {
      & > * {
        margin-top: $gutter/2;
        margin-bottom: $gutter/2;
        &:first-child { margin-top: 0; }
        &:last-child { margin-bottom: 0; }
      }
    } @else if $trait == center {
      align-items: center;
    } @else if $trait == middle {
      justify-content: center;
    } @else if $trait == left {
      @if $reverse == 1 {
        align-items: flex-end;
      } @else {
        align-items: flex-start;
      }
    } @else if $trait == right {
      @if $reverse == 1 {
        align-items: flex-start;
      } @else {
        align-items: flex-end;
      }
    } @else if $trait == top {
      justify-content: flex-start;
    } @else if $trait == bottom {
      justify-content: flex-end;
    } @else if $trait == btt {
      flex-direction: column-reverse;
    }
  }
}

.flow, %flow {
    @extend %fluid;
    display: flex;

    &.space-between, &%space-between {
        justify-content: space-between;
    }

    &.space-around, &%space-around {
        justify-content: space-around;
    }

    &.vertical, &%vertical {
        flex-direction: column;

        &.btt, %btt {
            flex-direction: column-reverse;
        }

        &.airy > *, &%airy > * {
            margin-top: $gutter/2;
            margin-bottom: $gutter/2;
            &:first-child { margin-top: 0; }
            &:last-child { margin-bottom: 0; }
        }
        
         &.half-airy > *, &%half-airy > * {
            margin-top: $gutter/4;
            margin-bottom: $gutter/4;
            &:first-child { margin-top: 0; }
            &:last-child { margin-bottom: 0; }
        }

        &.center, &%center {
            align-items: center;
        }

        &.middle, &%middle {
            justify-content: center;
        }

        &.left, &%left {
            align-items: flex-start;
        }

        &.right, &%right {
            align-items: flex-end;
        }

        &.breakable-reverse, &%breakable-reverse {

            &.left, &%left {
                align-items: flex-end;
            }

            &.right, &%right {
                align-items: flex-start;
            }

        }

        &.top, &%top {
            justify-content: flex-start;
        }

        &.bottom, &%bottom {
            justify-content: flex-end;
        }

    }

    &.horizontal, &%horizontal {
        flex-direction: row;

        &.rtl, &%rtl {
            flex-direction: row-reverse;
        }

        &.airy > *, &%airy > * {
            margin-left: $gutter/2;
            margin-right: $gutter/2;
            &:first-child { margin-left: 0; }
            &:last-child { margin-right: 0; }
        }
        
        &.half-airy > *, &%half-airy > * {
            margin-left: $gutter/4;
            margin-right: $gutter/4;
            &:first-child { margin-left: 0; }
            &:last-child { margin-right: 0; }
        }

        &.center, &%center {
            justify-content: center;
        }

        &.middle, &%middle {
            align-items: center;
        }

        &.top, &%top {
            align-items: flex-start;
        }

        &.bottom, &%bottom {
            align-items: flex-end;
        }

        &.left, &%left {
            justify-content: flex-start;
        }

        &.right, &%right {
            justify-content: flex-end;
        }

        &.baseline, &%baseline {
            align-items: baseline;
        }
    }

    &.breakable, &%breakable {
        flex-wrap: wrap;
    }

    &.breakable-reverse, &%breakable-reverse {
        flex-wrap: wrap-reverse;
    }
}

/* shortcuts */

@mixin padded($size) {
  
  .padded-l, %padded-l {
    padding-left: $size;
    & > *.overflows { margin-left: -$size; }
  }

  .padded-r, %padded-r {
    padding-right: $size;
    & > *.overflows { margin-right: -$size; }
  }

  .padded-t, %padded-t {
    padding-top: $size;
    & > *.overflows { margin-top: -$size; }
  }

  .padded-b, %padded-b {
    padding-bottom: $size;
    & > *.overflows { margin-bottom: -$size; }
  }

  .padded, %padded {
    padding-left: $size;
    padding-right: $size;
    padding-top: $size;
    padding-bottom: $size;
    & > *.overflows {
      margin-left: -$size;
      margin-right: -$size;
      margin-top: -$size;
      margin-bottom: -$size;
    }
    & > *.overflows-h {
      margin-left: -$size;
      margin-right: -$size;
    }
    & > *.overflows-v {
      margin-top: -$size;
      margin-bottom: -$size;
    }
  }

  .padded-h, %padded-h {
    padding-left: $size;
    padding-right: $size;
    & > *.overflows {
      margin-left: -$size;
      margin-right: -$size;
    }
  }

  .padded-v, %padded-v {
    padding-top: $size;
    padding-bottom: $size;
    & > *.overflows {
      margin-top: -$size;
      margin-bottom: -$size;
    }
  }
  
}

@include padded($gutter / 2);

.pad2 { @include padded($gutter); }


/* Misc */

.hidden {
    display: none !important;
}

.visuallyhidden {
    position: absolute;
    overflow: hidden;
    clip: rect(0 0 0 0);
    height: 1px; width: 1px;
    margin: -1px; padding: 0; border: 0;
}

.invisible {
    visibility: hidden;
}

.text-center {
    text-align: center;
}

.text-left {
    text-align: left;
}

.text-right {
    text-align: right;
}

.text-justify {
    text-align: justify;
}
