/// Susy3 Configuration
/// ===================
/// Susy3 has 4 core settings, in a single settings map.
/// You'll notice a few differences from Susy2:
///
/// **Columns** no longer accept a single number, like `12`,
/// but use a syntax more similar to the new
/// CSS [grid-template-columns][columns] –
/// a list of relative sizes for each column on the grid.
/// Unitless numbers in Susy act very similar to `fr` units in CSS,
/// and the `susy-repeat()` function (similar to the css `repeat()`)
/// helps quickly establish equal-width columns.
///
/// [columns]: https://developer.mozilla.org/en-US/docs/Web/CSS/grid-template-columns
///
/// - `susy-repeat(12)` will create 12 fluid, equal-width columns
/// - `susy-repeat(6, 120px)` will create 6 equal `120px`-wide columns
/// - `120px susy-repeat(4) 120px` will create 6 columns,
///   the first and last are `120px`,
///   while the middle 4 are equal fractions of the remainder.
///   Susy will output `calc()` values in order to achieve this.
///
/// **Gutters** haven't changed –
/// a single fraction or explicit width –
/// but the `calc()` output feature
/// means you can now use any combination of units and fractions
/// to create static-gutters on a fluid grid, etc.
///
/// **Spread** existed in the Susy2 API as a span option,
/// and was otherwise handled behind the scenes.
/// Now we're giving you full control over all spread issues.
/// You can find a more [detailed explanation of spread on the blog][spread].
///
/// [spread]: http://oddbird.net/2017/06/13/susy-spread/
///
/// You can access your global settings at any time
/// with the `susy-settings()` function,
/// or grab a single setting from the global scope
/// with `susy-get('columns')`, `susy-get('gutters')` etc.
///
/// @group config
/// @link http://oddbird.net/2017/06/13/susy-spread/
///   Article: Understanding Spread in Susy3
///
/// @see $susy
/// @see susy-settings
/// @see susy-get



// Susy
// ----
/// The grid is defined in a single map variable,
/// with four initial properties:
/// `columns`, `gutters`, `spread` and `container-spread`.
/// Anything you put in the root `$susy` variable map
/// will be treated as a global project default.
/// You can create similar configuration maps
/// under different variable names,
/// to override the defaults as-needed.
///
/// @group config
/// @type Map
///
/// @see $_susy-defaults
/// @see {function} susy-repeat
/// @link
///   https://codepen.io/mirisuzanne/pen/EgmJJp?editors=1100
///   Spread examples on CodePen
///
/// @prop {list} columns -
///   Columns are described by a list of numbers,
///   representing the relative width of each column.
///   The syntax is a simplified version of CSS native
///   `grid-template-columns`,
///   expecting a list of grid-column widths.
///   Unitless numbers create fractional fluid columns
///   (similar to the CSS-native `fr` unit),
///   while length values (united numbers)
///   are used to define static columns.
///   You can mix-and match units and fractions,
///   to create a mixed grid.
///   Susy will generate `calc()` values when necessary,
///   to make all your units work together.
///
///   Use the `susy-repeat($count, $value)` function
///   to more easily repetative columns,
///   similar to the CSS-native `repeat()`.
///
///   - `susy-repeat(8)`:
///     an 8-column, symmetrical, fluid grid.
///     <br />Identical to `(1 1 1 1 1 1 1 1)`.
///   - `susy-repeat(6, 8em)`:
///     a 6-column, symmetrical, em-based grid.
///     <br />Identical to `(8em 8em 8em 8em 8em 8em)`.
///   - `(300px susy-repeat(4) 300px)`:
///     a 6-column, asymmetrical, mixed fluid/static grid
///     using `calc()` output.
///     <br />Identical to `(300px 1 1 1 1 300px)`.
///
///   **NOTE** that `12` is no longer a valid 12-column grid definition,
///   and you must list all the columns individually
///   (or by using the `susy-repeat()` function).
///
/// @prop {number} gutters -
///   Gutters are defined as a single width,
///   or fluid ratio, similar to the native-CSS
///   `grid-column-gap` syntax.
///   Similar to columns,
///   gutters can use any valid CSS length unit,
///   or unitless numbers to define a relative fraction.
///
///   - `0.5`:
///     a fluid gutter, half the size of a single-fraction column.
///   - `1em`:
///     a static gutter, `1em` wide.
///
///   Mix static gutters with fluid columns, or vice versa,
///   and Susy will generate the required `calc()` to make it work.
///
/// @prop {string} spread [narrow] -
///   Spread of an element across adjacent gutters:
///   either `narrow` (none), `wide` (one), or `wider` (two)
///
///   - Both spread settings default to `narrow`,
///     the most common use-case.
///     A `narrow` spread only has gutters *between* columns
///     (one less gutter than columns).
///     This is how all css-native grids work,
///     and most margin-based grid systems.
///   - A `wide` spread includes the same number of gutters as columns,
///     spanning across a single side-gutter.
///     This is how most padding-based grid systems often work,
///     and is also useful for pushing and pulling elements into place.
///   - The rare `wider` spread includes gutters
///     on both sides of the column-span
///     (one more gutters than columns).
///
/// @prop {string} container-spread [narrow] -
///   Spread of a container around adjacent gutters:
///   either `narrow` (none), `wide` (one), or `wider` (two).
///   See `spread` property for details.
///
/// @since 3.0.0-beta.1 -
///   `columns` setting no longer accepts numbers
///   (e.g. `12`) for symmetrical fluid grids,
///   or the initial `12 x 120px` syntax for
///   symmetrical fixed-unit grids.
///   Use `susy-repeat(12)` or `susy-repeat(12, 120px)` instead.
///
/// @example scss - default values
///   // 4 symmetrical, fluid columns
///   // gutters are 1/4 the size of a column
///   // elements span 1 less gutter than columns
///   // containers span 1 less gutter as well
///   $susy: (
///     'columns': susy-repeat(4),
///     'gutters': 0.25,
///     'spread': 'narrow',
///     'container-spread': 'narrow',
///   );
///
/// @example scss - inside-static gutters
///   // 6 symmetrical, fluid columns…
///   // gutters are static, triggering calc()…
///   // elements span equal columns & gutters…
///   // containers span equal columns & gutters…
///   $susy: (
///     'columns': susy-repeat(6),
///     'gutters': 0.5em,
///     'spread': 'wide',
///     'container-spread': 'wide',
///   );
$susy: () !default;



// Susy Repeat
// -----------
/// Similar to the `repeat(<count>, <value>)` function
/// that is available in native CSS Grid templates,
/// the `susy-repeat()` function helps generate repetative layouts
/// by repeating any value a given number of times.
/// Where Susy previously allowed `8` as a column definition
/// for 8 equal columns, you should now use `susy-repeat(8)`.
///
/// @group config
///
/// @param {integer} $count -
///   The number of repetitions, e.g. `12` for a 12-column grid.
/// @param {*} $value [1] -
///   The value to be repeated.
///   Technically any value can be repeated here,
///   but the function exists to repeat column-width descriptions:
///   e.g. the default `1` for single-fraction fluid columns,
///   `5em` for a static column,
///   or even `5em 120px` if you are alternating column widths.
///
/// @return {list} -
///   List of repeated values
///
/// @example scss
///   // 12 column grid, with 5em columns
///   $susy: (
///     columns: susy-repeat(12, 5em),
///   );
///
/// @example scss
///   // asymmetrical 5-column grid
///   $susy: (
///     columns: 20px susy-repeat(3, 100px) 20px,
///   );
///
///   /* result: #{susy-get('columns')} */
@function susy-repeat(
  $count,
  $value: 1
) {
  $return: ();

  @for $i from 1 through $count {
    $return: join($return, $value);
  }

  @return $return;
}



// Susy Defaults
// -------------
/// Configuration map of Susy factory defaults.
/// Do not override this map directly –
/// use `$susy` for user and project setting overrides.
///
/// @access private
/// @type Map
///
/// @see $susy
///
/// @prop {number | list} columns [susy-repeat(4)]
/// @prop {number} gutters [0.25]
/// @prop {string} spread ['narrow']
/// @prop {string} container-spread ['narrow']
$_susy-defaults: (
  'columns': susy-repeat(4),
  'gutters': 0.25,
  'spread': 'narrow',
  'container-spread': 'narrow',
);



// Susy Settings
// -------------
/// Return a combined map of Susy settings,
/// based on the factory defaults (`$_susy-defaults`),
/// user-defined project configuration (`$susy`),
/// and any local overrides required –
/// such as a configuration map passed into a function.
///
/// @group config
///
/// @param {maps} $overrides… -
///   Optional map override of global configuration settings.
///   See `$susy` above for properties.
///
/// @return {map} -
///   Combined map of Susy configuration settings,
///   in order of specificity:
///   any `$overrides...`,
///   then `$susy` project settings,
///   and finally the `$_susy-defaults`
///
/// @example scss - global settings
///   @each $key, $value in susy-settings() {
///     /* #{$key}: #{$value} */
///   }
///
/// @example scss - local settings
///   $local: ('columns': 1 2 3 5 8);
///
///   @each $key, $value in susy-settings($local) {
///     /* #{$key}: #{$value} */
///   }
@function susy-settings(
  $overrides...
) {
  $settings: map-merge($_susy-defaults, $susy);

  @each $config in $overrides {
    $settings: map-merge($settings, $config);
  }

  @return $settings;
}



// Susy Get
// --------
/// Return the current global value of any Susy setting
///
/// @group config
///
/// @param {string} $key -
///   Setting to retrieve from the configuration.
///
/// @return {*} -
///   Value mapped to `$key` in the configuration maps,
///   in order of specificity:
///   `$susy`, then `$_susy-defaults`
///
/// @example scss -
///   /* columns: #{susy-get('columns')} */
///   /* gutters: #{susy-get('gutters')} */
@function susy-get(
  $key
) {
  $settings: susy-settings();

  @if not map-has-key($settings, $key) {
    @return _susy-error(
      'There is no Susy setting called `#{$key}`',
      'susy-get');
  }

  @return map-get($settings, $key);
}
