@use "sass:math";
// Foundation for Apps
//
// BREAKPOINTS
// -----------
// Foundation for Apps has three core breakpoints: small (> 0), medium (>= 640), and large (>= 1024).
// There are two additional breakpoints, xlarge, and xxlarge, which (by default) do not output as sizing classes.
// Access named breakpoints using the mixin breakpoint($size), where $size is a breakpoint value.
// You can also pass an em, rem, or pixel value into this mixin to generate an em-based media query.
// Create new named breakpoints using the $breakpoints map. Change which named breakpoints get their own classes by modifying the $breakpoint-classes map.
// NOTE: If you change the $breakpoints map, know that all values must be ordered by width, smallest width first. So 0 is always your first value.

// 1. Variables
// - - - - - - - - - - - - - - -

/// @Foundation.settings
// Breakpoints
// These are our named breakpoints. You can use them in our breakpoint function like this: @include breakpoint(medium) { // Medium and larger styles }
$breakpoints: (
    small: rem-calc(0),
    medium: rem-calc(640),
    large: rem-calc(1200),
    xlarge: rem-calc(1440),
    xxlarge: rem-calc(1920)
) !default;

// All of the names in this list will be output as classes in your CSS, like small-12, medium-6, and so on.
$breakpoint-classes: (small medium large) !default;
///

// 2. Mixins
// - - - - - - - - - - - - - - -

/// Wraps a media query around the content you put inside the mixin. This mixin accepts a number of values:
///  - If a string is passed, the mixin will look for it in the $breakpoints map, and use a media query there.
///  - If a pixel value is passed, it will be converted to an em value using $rem-base.
///  - If a rem value is passed, the unit will be changed to em.
///  - If an em value is passed, the value will be used as-is.
///
/// @param {mixed} $val - Breakpoint name or px/em/rem value to process.
///
/// @output If the breakpoint is "0px and larger", outputs the content. Otherwise, outputs the content wrapped in a media query.
@mixin breakpoint($val: small) {
    // Size or keyword
    $bp: nth($val, 1);
    // Value for max-width media queries
    $bpMax: 0;
    // Direction of media query (up, down, or only)
    $dir: if(length($val) > 1, nth($val, 2), up);
    // Eventual output
    $str: "only screen";
    // Is it a named media query?
    $named: false;

    // Orientation media queries have a unique syntax
    @if $bp == "landscape" or $bp == "portrait" {
        $str: $str + " and (orientation: #{$bp})";
    } @else {
        // Try to pull a named breakpoint out of the $breakpoints map
        @if type-of($bp) == "string" {
            @if map-has-key($breakpoints, $bp) {
                @if $dir == "only" {
                    $next-bp: map-next($breakpoints, $bp);
                    @if $next-bp == null {
                        $bpMax: null;
                    } @else {
                        $bpMax: $next-bp - math.div(1, 16);
                    }
                }
                $bp: map-get($breakpoints, $bp);
                $named: true;
            } @else {
                $bp: 0;
            }
        }

        // Pixel and unitless values are converted to rems
        @if unit($bp) == "px" or unit($bp) == "" {
            $bp: rem-calc($bp);
        }
        // Finally, the rem value is turned into an em value
        $bp: strip-unit($bp) * 1em;

        // Skip media query creation if the input is "0 up" or "0 down"
        @if $bp > 0 or $dir == "only" {
            // And lo, a media query was born
            @if $dir == "only" {
                @if $named == true {
                    $str: $str + " and (min-width: #{$bp})";
                    @if $bpMax != null {
                        $str: $str + " and (max-width: #{$bpMax})";
                    }
                } @else {
                    @debug 'ERROR: Only named media queries can have an "only" range.';
                }
            } @else if $dir == "down" {
                $max: $bp - (1/16);
                $str: $str + " and (max-width: #{$max})";
            } @else {
                $str: $str + " and (min-width: #{$bp})";
            }
        }
    }

    // Output
    @if $bp == 0em and $dir != "only" {
        @content;
    } @else {
        @media #{$str} {
            @content;
        }
    }
}

/// Prefixes selector $class with breakpoint keywords, allowing you to create a batch of breakpoint classes with one chunk of code. If you want to skip a breakpoint (like small, because mobile first and all that), add values to the $omit parameter.
///
/// @param {string} $class - Class to prefix with the breakpoint name and a hyphen.
/// @param {list} $omit - Named breakpoints to skip. No class will be added with breakpoints in this list.
@mixin each-breakpoint($class, $omit: ()) {
    // Iterate through breakpoint classes
    @each $size in $breakpoint-classes {
        // Only do something if the breakpoint is not in $omit
        @if index($omit, $size) == null {
            $val: map-get($breakpoints, $size);
            // Prefix $class with $size and a hyphen
            .#{$size + "-" + $class} {
                @include breakpoint($size) {
                    @content;
                }
            }
        }
    }
}

// 3. CSS Output
// - - - - - - - - - - - - - - -

// Meta styles are included in all builds, as they are a dependancy of the Javascript.
// Used to provide media query values for javascript components.
// Forward slash placed around everything to convince PhantomJS to read the value.

meta.foundation-version {
    font-family: "#{$foundation-version}";
}
meta.foundation-mq {
    font-family: "#{map-serialize($breakpoints)}";
}
