////
/// Andy.SCSS: Open-Source Collection of Useful SASS Mixins Library.
/// URL: http://gillesbertaux.com/andy$
/// Repository: https://github.com/gillesbertaux/andy
/// By: Gilles Bertaux | http://gillesbertaux.com | @gillesbertaux
/// The purpose of Andy is to gather useful mixins and avoid endless research
/// or heavy framework use. Feel free to fork it on Github and add your own mixins:
////


/// Base font size setting for Andy
/// @access public
/// @type Length
$base-font-size: 16px !default;


/// Mixin helper to output vendor-prefixed CSS
/// @access private
/// @author HugoGiraudel
/// @param {String} $property - Unprefixed CSS property
/// @param {*} $value - Raw CSS value
/// @param {List} $prefixes [()] - List of prefixes to output
@mixin prefix($property, $value, $prefixes: ()) {
  @each $prefix in $prefixes {
    -#{$prefix}-#{$property}: $value;
  }

  #{$property}: $value;
}


/// Mixin helper to prefix `@keyframes`
/// @access private
/// @param {String} $name - Animation name
@mixin keyframes($name) {
    @-webkit-keyframes #{$name} {
        @content;
    }

    @keyframes #{$name} {
        @content;
    }
}


/// Function helper to strip a single character from a string; by default, simply removes the character.
/// @access private
/// @param {String} $string - The string to alter.
/// @param {String} $to-replace - The character to check for.
/// @param {String} $replacement [''] - The character to replace the removed character with.
/// @example scss - Usage {
///   .foo:after {
///     content: str-replace('Hello.', '.', '!');
///   }
/// @example css - Result
///   .foo:after {
///     content: 'Hello!'
///   }
@function str-replace($string, $to-replace, $replacement:'') {
  $target-location: str-index($string, $to-replace);
  @if $target-location == null { @return $string; }
  $string-without-target: str-slice($string, 1, $target-location - 1) + str-slice($string, $target-location + 1);
  $string: str-insert($string-without-target, $replacement, $target-location);
  @return $string;
}


/// Background gradient helper
/// @access public
/// @param {Color} $start-color - Start color
/// @param {Color} $end-color - End color
/// @param {String} $orientation - Type of gradient, either `vertical`, `horizontal` or `radial`
/// @example scss - Usage
///   .foo {
///     @include background-gradient(red, black, 'vertical');
///   }
/// @example css - Result
///   .foo {
///     background: -webkit-linear-gradient(top, red, black);
///     background: linear-gradient(to bottom, red, black);
///   }
@mixin background-gradient($start-color, $end-color, $orientation) {
    background: $start-color;

    @if $orientation == 'vertical' {
      background: -webkit-linear-gradient(top, $start-color, $end-color);
      background: linear-gradient(to bottom, $start-color, $end-color);
    } @else if $orientation == 'horizontal' {
      background: -webkit-linear-gradient(left, $start-color, $end-color);
      background: linear-gradient(to right, $start-color, $end-color);
    } @else {
      background: -webkit-radial-gradient(center, ellipse cover, $start-color, $end-color);
      background: radial-gradient(ellipse at center, $start-color, $end-color);
    }
}


/// Background size helper
/// @access public
/// @param {Length} $width - Background width
/// @param {Length} $height [$width] - Background height
/// @example scss - Usage
///   .foo {
///     @include background-size(100%);
///   }
/// @example scss - Result
///   .foo {
///     -webkit-background-size: 100% 100%;
///     -moz-background-size: 100% 100%;
///     background-size: 100% 100%;
///   }
@mixin background-size($width, $height: $width) {
    @include prefix(background-size, $width $height, 'webkit' 'moz');
}


/// Separated border-radius helpers
/// @access public
/// @param {Length} $top-left-radius - Top left radius
/// @param {Length} $top-right-radius - Top right radius
/// @param {Length} $bottom-right-radius - Bottom right radius
/// @param {Length} $bottom-left-radius - Bottom left radius
/// @example scss - Usage
///   .foo {
///     @include border-radius-separate(1px, 2px, 3px, 4px);
///   }
/// @example css - Result
///   .foo {
///     -webkit-border-top-left-radius: 1px;
///     -moz-border-top-left-radius: 1px;
///     border-top-left-radius: 1px;
///     -webkit-border-top-right-radius: 2px;
///     -moz-border-top-right-radius: 2px;
///     border-top-right-radius: 2px;
///     -webkit-border-bottom-right-radius: 3px;
///     -moz-border-bottom-right-radius: 3px;
///     border-bottom-right-radius: 3px;
///     -webkit-border-bottom-left-radius: 4px;
///     -moz-border-bottom-left-radius: 4px;
///     border-bottom-left-radius: 4px;
///   }
@mixin border-radius-separate($top-left-radius, $top-right-radius, $bottom-right-radius, $bottom-left-radius) {
    @include prefix(border-top-left-radius, $top-left-radius, 'webkit' 'moz');
    @include prefix(border-top-right-radius, $top-right-radius, 'webkit' 'moz');
    @include prefix(border-bottom-right-radius, $bottom-right-radius, 'webkit' 'moz');
    @include prefix(border-bottom-left-radius, $bottom-left-radius, 'webkit' 'moz');
}


/// Box-sizing helper
/// @access public
/// @param {String} $type - Either `border-box`, `padding-box` or `content-box`
/// @example scss - Usage
///   .foo {
///     @include box-sizing(border-box);
///   }
/// @example css - Result
///   .foo {
///     -moz-box-sizing: border-box;
///     box-sizing: border-box;
///   }
@mixin box-sizing($type) {
    @include prefix(box-sizing, $type, 'moz');
}


/// Horizontally centers block elements
/// @access public
/// @example scss - Usage
///   .foo {
///     @include center-block;
///   }
/// @example css - Result
///   .foo {
///     display: block;
///     margin-left: auto;
///     margin-right: auto;
///   }
@mixin center-block {
    display: block;
    margin-left: auto;
    margin-right: auto;
}


/// Horizontally and vertically centers block elements
/// Important: you must have a parent element with `position: relative`.
/// @access public
/// @example scss - Usage
///   .foo {
///     @include center-both;
///   }
/// @example css - Result
///   .foo {
///     position: absolute;
///     top: 50%;
///     left: 50%;
///     -webkit-transform: translate(-50%, -50%);
///     -ms-transform: translate(-50%, -50%);
///     transform: translate(-50%, -50%);
///   }
@mixin center-both {
    position: absolute;
    top: 50%;
    left: 50%;
    @include prefix(transform, translate(-50%, -50%), 'webkit' 'ms');
}


/// Vertically centers block elements with known height.
/// @access public
/// @param {Length} $height - Element's height
/// @example scss - Usage
///   .foo {
///     @include center-h(42px);
///   }
/// @example css - Result
///   .foo {
///     position: absolute;
///     top: 50%;
///     height: 42px;
///     margin-top: -21px;
///   }
@mixin center-h($height) {
    position: absolute;
    top: 50%;
    height: $height;
    margin-top: -($height / 2);
}

/// Vertically centers block elements with unknown height.
/// @access public
/// @example scss - Usage
///   .foo {
///     @include center-h--unk;
///   }
/// @example css - Result
///   .foo {
///     position: relative;
///     top: 50%;
///     -webkit-transform: translateY(-50%);
///     -ms-transform: translateY(-50%);
///     transform: translateY(-50%);
///   }
@mixin center-h--unk {
    position: relative;
    top: 50%;
    @include prefix(transform, translateY(-50%), 'webkit' 'ms');
}


/// Clearfix extend
/// @access public
/// @example scss - Usage
///   .foo {
///     @extend %clearfix;
///   }
%clearfix {
    *zoom: 1;

    &:before, &:after {
        content: ' ';
        display: table;
    }

    &:after {
        clear: both;
    }
}


/// Adds a thin black line above the element, and a thin gray line below the element, creating an inlay effect.
/// @access public
/// @example scss - Usage
///   .foo {
///     @include outline;
///   }
/// @example css - Result
///   .foo {
///     box-shadow: rgba(255, 255, 255, 0.5) 0 1px 0, inset rgba(0, 0, 0, 0.75) 0 1px 0;
///   }
@mixin outline {
    box-shadow: rgba(255, 255, 255, 0.5) 0 1px 0, inset rgba(0, 0, 0, 0.75) 0 1px 0;
}


/// Given the location of a webfont, will generate a font-face declaration with multiple file formats.
/// @access public
/// @param {String} $font-name - Font family name
/// @param {String} $file-name - File name (no extension)
/// @param {String | Number} $weight [normal] - Font weight
/// @param {String} $style [normal] - Font style
/// @example scss - Usage
///   @include font-face('gotham', '/fonts/gotham');
@mixin font-face($font-name, $file-name, $weight: normal, $style: normal) {
  @font-face {
    font-family: quote($font-name);
    src: url($file-name + '.eot');
    src: url($file-name + '.eot?#iefix')  format('embedded-opentype'),
         url($file-name + '.woff') format('woff'),
         url($file-name + '.ttf')  format('truetype'),
         url($file-name + '.svg##{$font-name}')  format('svg');
    font-weight: $weight;
    font-style: $style;
  }
}


/// Given a font size in pixels, reproduces that font size in rems.
/// @access public
/// @param {Length} $size - Font size
/// @example scss - Usage
///   .foo {
///     @include font-size(16px);
///   }
/// @example css - Result
///   .foo {
///     font-size: 16px;
///     font-size: 1rem;
///   }
@mixin font-size($size) {
  @if unitless($size) {
    $size: $size * 1px;
  }

  font-size: $size;
  font-size: ($size / $base-font-size) * 1rem;
}


/// Forces browsers to use hardware acceleration for transforms
/// @access public
/// @example scss - Usage
///   .foo {
///     @include ha;
///   }
/// @example css - Result
///   .foo {
///     -webkit-transform: translate3d(0, 0, 0);
///     -moz-transform: translate3d(0, 0, 0);
///     transform: translate3d(0, 0, 0);
///   }
@mixin ha {
    @include prefix(transform, translate3d(0, 0, 0), 'webkit' 'ms');
}


/// Retina image media query helper; given an image path with a 2x-sized version of an image, will load that image as a background-image on high-resolution devices.
/// @access public
/// @param {String} $image - Image path
/// @param {Length} $width - Image width
/// @param {Height} $height - Image height
/// @example scss - Usage
///   .foo {
///     @include image-2x('../images/image.png', 100%, auto);
///   }
@mixin image-2x($image, $width, $height) {
    @media (-webkit-min-device-pixel-ratio: 1.3),
           (min-resolution: 124dpi),
           (min-resolution: 1.3dppx) {
        /* on retina, use image that's scaled by 2 */
        background-image: url($image);
        background-size: $width $height;
    }
}


/// Generates line-height values in both pixels and rems.
/// @access public
/// @param {Number} $height-value [12] - Height value
/// @example scss - Usage
///   .foo {
///     @include line-height(16);
///   }
/// @example css - Result
///   .foo {
///     line-height: 16px;
///     line-height: 1rem;
///   }
@mixin line-height($height-value: 12) {
    line-height: $height-value * 1px; //fallback for old browsers
    line-height: (1 / ($base-font-size / ($base-font-size * 0 + 1)) * $height-value * 1rem);
}


/// Media query helper for declaring media queries by width, and, optionally, ratio.
/// @access public
/// @param {Length} $width - Max-width
/// @param {Number | False} $ratio [false] - Min device pixel ratio
/// @example scss - Usage
///   .foo {
///     @include mquery(350px, 2) {
///       width: 100%;
///     }
///   }
@mixin mquery($width, $ratio: false) {
    @if $ratio {
        @media
            only screen and (max-width: $width) and  (min--moz-device-pixel-ratio: $ratio),
            only screen and (max-width: $width) and  (-webkit-min-device-pixel-ratio: $ratio),
            only screen and (max-width: $width) and  (min-device-pixel-ratio: $ratio) {
            @content;
        }
    } @else {
        @media only screen and (max-width: $width) {
            @content;
        }
    }
}


/// Media query helper for declaring media queries by device pixel ratio.
/// @access public
/// @param {Number} $ratio - Min device pixel ratio
/// @example scss - Usage
///   .foo {
///     @include mquery-r(2) {
///       width: 100%;
///     }
///   }
@mixin mquery-r($ratio) {
    @media
        only screen and (-webkit-min-device-pixel-ratio: $ratio),
        only screen and (min--moz-device-pixel-ratio: $ratio),
        only screen and (-o-min-device-pixel-ratio: $ratio),
        only screen and (min-device-pixel-ratio: $ratio) {
        @content;
    }
}


/// Given an opacity value, generates that value as well as a way to display that opacity value in Internet Explorer 8 and 9.
/// @access public
/// @param {Float} $opacity - Opacity
/// @example scss - Usage
///   .foo {
///     @include opacity(0.5);
///   }
/// @example css - Result
///   .foo {
///     opacity: 0.5;
///     filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=#50)";
///   }
@mixin opacity($opacity) {
    opacity: $opacity;
    -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=#{$opacity * 100})";
}


/// Generates the color black, with, optionally, a set opacity.
/// @access public
/// @param {Float} $opacity - Opacity
/// @example scss - Usage
///   .foo {
///     border-color: black(0.1);
///   }
/// @example css - Result
///   .foo {
///     border-color: rgba(0, 0, 0, 0.1);
///   }
@function black($opacity) {
    @return rgba(0, 0, 0, $opacity);
}


/// Generates the color white, with, optionally, a set opacity.
/// @access public
/// @param {Float} $opacity - Opacity
/// @example scss - Usage
///   .foo {
///     border-color: white(0.1);
///   }
/// @example css - Result
///   .foo {
///     border-color: rgba(255, 255, 255, 0.1);
///   }
@function white($opacity) {
    @return rgba(255, 255, 255, $opacity);
}


/// Shorthandizes position declarations.
/// @access public
/// @param {String} $type - Either `relative`, `absolute` or `fixed`
/// @param {Length} $left [null] - Left offset
/// @param {Length} $right [null] - Right offset
/// @param {Length} $top [null] - Top offset
/// @param {Length} $bottom [null] - Bottom offset
/// @example scss - Usage
///   .foo {
///     @include position(absolute, $top: 10px, $left: 10px);
///   }
/// @example css - Result
///   .foo {
///     position: absolute;
///     left: 10px;
///     top: 10px;
///   }
@mixin position($type, $top: null, $right: null, $bottom: null, $left: null) {
    position: $type;
    top: $top;
    right: $right;
    bottom: $bottom;
    left: $left;
}


/// Sizing helper
/// @access public
/// @param {Length} $width - Width
/// @param {Length} $height [$width] - Height
/// @example scss - Usage
///   .foo {
///     @include size(350px);
///   }
/// @example css - Result
///   .foo {
///     width: 350px;
///     height: 350px;
///   }
@mixin size($width, $height: $width) {
    width: $width;
    height: $height;
}


/// Embossing text shadow
/// @access public
/// @param {Float} $value - Opacity value
/// @example scss - Usage
///   .foo {
///     @include text-shadow(0.5);
///   }
/// @example css - Result
///   .foo {
///     text-shadow: rgba(255, 255, 255, 0.5) 0 1px 0;
///   }
@mixin text-shadow($value) {
    text-shadow: rgba(255, 255, 255, $value) 0 1px 0;
}


/// Automatically prefix any transform
/// @access public
/// @param {String} $transformation - The transform to apply
/// @example scss - Usage
///   .foo {
///     @include transform(translateX(10px));
///   }
/// @example css - Result
///   .foo {
///     -webkit-transform: translateX(10px);
///     -ms-transform: translateX(10px);
///     transform: translateX(10px);
///   }
@mixin transform($transformation){
  @include prefix(transform, $transformation, 'webkit' 'ms');
}


/// Transition helper
/// @param {Time} $time [1s] - Duration
/// @param {String} $timing-function [ease-in-out] - Timing function or cubic bezier curve
/// @example scss - Usage
///   .foo {
///     @include transition(0.3s, ease-in);
///   }
/// @example css - Result
///   .foo {
///     -webkit-transition: all 0.3s ease-in;
///     transition: all 0.3s ease-in;
///   }
@mixin transition($time: 1s, $timing-function: ease-in-out) {
    @include prefix(transition, all $time $timing-function, 'webkit');
}


/// Generates a grow-then-shrink (or shrink-then-grow) animation using transform(scale).
/// @access public
/// @param {Number} $scale-change [1.1] - The amount to scale by.
/// @param {List} $animation-properties - Animation properties to apply.
/// @example scss - Usage
///   .foo {
///     @include scale(0.5, 3s ease infinite alternate);
///   }
/// @example css - Result
///   .foo {
///     -webkit-animation: "scale-0-5" 3s ease infinite alternate;
///     animation: "scale-0-5" 3s ease infinite alternate;
///   }
///  // -webkit- prefixed @keyframes are also generated
///  @keyframes scale-0-5 {
///    from, to {
///      -webkit-transform: scale(1);
///      -ms-transform: scale(1);
///      transform: scale(1);
///    }
///    50% {
///      -webkit-transform: scale(0.5);
///      -ms-transform: scale(0.5);
///      transform: scale(0.5);
///    }
///  }
@mixin scale($scale-change:1.1, $animation-properties: 1s ease-in-out) {
  $alias: 'scale-' + str-replace($scale-change + '', '.', '-');

  @include keyframes($alias){
    0%, 100% {
      @include transform(scale(1));
    }
    50% {
      @include transform(scale($scale-change));
    }
  }

  @include prefix(animation, $alias $animation-properties, 'webkit');
}


/// Given two opacity values, animates an element between those opacity values.
/// @access public
/// @param {Number} $fade-from [0] - The beginning opacity value.
/// @param {Number} $fade-to [1] - The final opacity value.
/// @param {List} $animation-properties [1s ease] - The animation properties to apply.
/// @example scss - Usage
///   .foo {
///     @include fade(.8, .2, 3s linear);
///   }
/// @example css - Result
///   .foo {
///     -webkit-animation: fade-0-8-0-2 3s linear;
///     animation: fade-0-8-0-2 3s linear;
///   }
/// // (the @keyframes are also generated with a -webkit- vendor prefix)
///   @keyframes fade-0-8-0-2 {
///     from {
///       opacity: 0.8;
///       -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=80)";
///     }
///     to {
///       opacity: 0.2;
///       -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=20)";
///     }
///   }
@mixin fade($fade-from: 0, $fade-to: 1, $animation-properties: 1s ease) {
    $alias: fade- + str-replace($fade-from + '', '.', '-') + '-' + str-replace($fade-to + '', '.', '-');
    @include keyframes($alias){
    from {
      @include opacity($fade-from);
    }
    to {
      @include opacity($fade-to);
    }
  }
  @include prefix(animation, $alias $animation-properties, 'webkit');
}


/// Slide-in-from creates and calls an animation that slides an element on a given axis for a given amount of space. The offset is measured in the distance from the location the element would naturally fall in, were transforms not applied to it.
/// @access public
/// @param {String} $slide-axis [x] - The axis on which to slide; 'x' or 'y'.
/// @param {Length} $slide-offset [-100px] - The offset from the natural element position from which to begin the animation.
/// @param {List} $animation-properties [3s ease-out] - Any animation properties to be included.
/// @example scss - Usage
///   .foo {
///     @include slide-in-from(y, -200px, 3s ease alternate infinite);
///   }
/// @example css - Result
///   .foo {
///     -webkit-animation: slide-in-y--200px 3s linear infinite alternate;
///     animation: slide-in-y--200px 3s linear infinite alternate;
///   }
///
/// // (the @keyframes are also generated with a -webkit- vendor prefix)
///   @keyframes slide-in-y--200px {
///     0% {
///       opacity: 0;
///       -webkit-transform: translateY(-200px);
///       -ms-transform: translateY(-200px);
///       transform: translateY(-200px);
///     }
///     75% {
///       -webkit-transform: translateY(0);
///       -ms-transform: translateY(0);
///       transform: translateY(0);
///     }
///     100% {
///       opacity: 1;
///     }
///   }
@mixin slide-in-from($slide-axis: x, $slide-offset: -100px, $animation-properties: 3s ease-out) {
  $slide-start: if($slide-axis == x, translateX($slide-offset), translateY($slide-offset));
  $slide-end: if($slide-axis == x, translateX(0), translateY(0));

  @include keyframes(slide-in-#{$slide-axis}-#{$slide-offset}){
    0% {
      @include opacity(0);
      @include transform($slide-start);
    }
    75% {
      @include transform($slide-end);
    }
    100% {
      @include opacity(1);
    }
  }

  @include prefix(animation, slide-in-#{$slide-axis}-#{$slide-offset} $animation-properties, 'webkit');
}
