// =================================================================
// Typography Tools
// =================================================================

@use "sass:math";

// Headings
// -----------------------------------------------------------------

// Supported Headings Depth
//
// The number of headings that are supported by the theme.
// It's highly unlikely this will ever change - it's a web standards thing.
// If you just want to give your top-level headings more contrast, it's
// better to adjust `$heading-growth-rate` up, which will weigh the font size distribution
// more heavily towards the top.
//
// Styleguide Typography.Factory.$_depth-headings
//
// Access: Private
//
// Since: 2.0.0

$_depth-headings: 6;

// Minimum Heading Size
//
// The minimum font size in pixels for headings to use. Unless you're a designer
// and you know what you're doing, leave this at `$font-size-base`.
// Anything lower means you'll need to compensate with other design elements
// to preserve the visual hierarchy - think uppercasing, color, stuff like that.
// This directly affects the `<h6>` tag. It indirectly affects all other heading
// font sizes as well by serving as the lower limit to our scale.
//
// Styleguide Configuration.Headings.Minimum Heading Size
//
// Access: Public
//
// Since: 2.0.0

// Minimum Heading Size
//
// The minimum font size in pixels for headings to use. Unless you're a designer
// and you know what you're doing, leave this at `$font-size-base`.
// Anything lower means you'll need to compensate with other design elements
// to preserve the visual hierarchy - think uppercasing, color, stuff like that.
// This directly affects the `<h6>` tag. It indirectly affects all other heading
// font sizes as well by serving as the lower limit to our scale.
//
// Styleguide Typography.Headings.$min-size-headings
//
// Access: Public
//
// Since: 2.0.0

$min-size-headings: $font-size-base !default;

// Minimum Heading Size - Mobile
//
// The minimum font size in pixels for headings to use on mobile. Unless you're a
// designer and you know what you're doing, leave this at `$font-size-base`.
// Anything lower means you'll need to compensate with other design elements
// to preserve the visual hierarchy - think uppercasing, color, stuff like that.
// This directly affects the `<h6>` tag. It indirectly affects all other heading
// font sizes as well by serving as the lower limit to our scale.
//
// Styleguide Configuration.Headings.Minimum Heading Size (Mobile)
//
// Access: Public
//
// Since: 2.0.0

// Minimum Heading Size - Mobile
//
// The minimum font size in pixels for headings to use on mobile. Unless you're a
// designer and you know what you're doing, leave this at `$font-size-base`.
// Anything lower means you'll need to compensate with other design elements
// to preserve the visual hierarchy - think uppercasing, color, stuff like that.
// This directly affects the `<h6>` tag. It indirectly affects all other heading
// font sizes as well by serving as the lower limit to our scale.
//
// Styleguide Typography.Headings.$min-size-headings-mobile
//
// Access: Public
//
// Since: 2.0.0

$min-size-headings-mobile: $min-size-headings !default;

// Maximum Heading Size
//
// The maximum font size in pixels for headings to use. This directly affects `<h1>`
// headings _within content_. Do not use a larger value, such as those you might find
// on a landing page or in a homepage slider, to determine this value. Be sure to
// test it against deeply nested pages, which tend to have longer page titles.
// It indirectly affects all other heading  font sizes as well by serving as the
// upper limit to our scale.
//
// Styleguide Configuration.Headings.Maximum Heading Size
//
// Access: Public
//
// Since: 2.0.0

// Maximum Heading Size
//
// The maximum font size in pixels for headings to use. This directly affects `<h1>`
// headings _within content_. Do not use a larger value, such as those you might find
// on a landing page or in a homepage slider, to determine this value. Be sure to
// test it against deeply nested pages, which tend to have longer page titles.
// It indirectly affects all other heading  font sizes as well by serving as the
// upper limit to our scale.
//
// Styleguide Typography.Headings.$max-size-headings
//
// Access: Public
//
// Since: 2.0.0

$max-size-headings: 55px !default;

// Maximum Heading Size (Mobile)
//
// The maximum font size in pixels for headings to use on mobile. This directly affects `<h1>`
// headings _within content_. Do not use a larger value, such as those you might find
// on a landing page or in a homepage slider, to determine this value. Be sure to
// test it against deeply nested pages, which tend to have longer page titles.
// It indirectly affects all other heading  font sizes as well by serving as the
// upper limit to our scale.
//
// Styleguide Configuration.Headings.Maximum Heading Size (Mobile)
//
// Access: Public
//
// Since: 2.0.0

// Maximum Heading Size (Mobile)
//
// The maximum font size in pixels for headings to use on mobile. This directly affects `<h1>`
// headings _within content_. Do not use a larger value, such as those you might find
// on a landing page or in a homepage slider, to determine this value. Be sure to
// test it against deeply nested pages, which tend to have longer page titles.
// It indirectly affects all other heading  font sizes as well by serving as the
// upper limit to our scale.
//
// Styleguide Typography.Headings.$max-size-headings-mobile
//
// Access: Public
//
// Since: 2.0.0

$max-size-headings-mobile: 36px !default;

// Minimum Line Height
//
// The minimum line height ratio for headings to use. Do not use any units with
// this value. This value directly affects the `<h1>` tag and indirectly affects
// all other heading  font sizes as well by serving as the lower limit to our scale.
// In typography, the relationship between font-size and line-height is that larger
// font-sizes demand lower line-height values to preserve vertical rhythm.
//
// Styleguide Configuration.Headings.Minimum Line Height
//
// Access: Public
//
// Since: 2.0.0

// Minimum Line Height
//
// The minimum line height ratio for headings to use. Do not use any units with
// this value. This value directly affects the `<h1>` tag and indirectly affects
// all other heading  font sizes as well by serving as the lower limit to our scale.
// In typography, the relationship between font-size and line-height is that larger
// font-sizes demand lower line-height values to preserve vertical rhythm.
//
// Styleguide Typography.Headings.$min-line-height
//
// Access: Public
//
// Since: 2.0.0

$min-line-height: 1.15 !default;

// Maximum Line Height
//
// The maximum line height ratio for headings to use. Do not use any units with
// this value. This value directly affects the `<h6>` tag and indirectly affects
// all other heading  font sizes as well by serving as the upper limit to our scale.
// Because we set the `<h6>` tag to be the same size as our body copy by default,
// it also gets the same line-height ratio by default.
//
// Styleguide Configuration.Headings.Maximum Line Height
//
// Access: Public
//
// Since: 2.0.0

// Maximum Line Height
//
// The maximum line height ratio for headings to use. Do not use any units with
// this value. This value directly affects the `<h6>` tag and indirectly affects
// all other heading  font sizes as well by serving as the upper limit to our scale.
// Because we set the `<h6>` tag to be the same size as our body copy by default,
// it also gets the same line-height ratio by default.
//
// Styleguide Typography.Headings.$max-line-height
//
// Access: Public
//
// Since: 2.0.0

$max-line-height: $line-height-base !default;

// Heading Growth Rate
//
// Adjusts the rate of growth between font sizes.
// 1 is a completely even rate of growth.
// Higher numbers will grow the font size exponentially. This is the way
// most type scales are set up.
//
// A higher number will adjust the font size more dramatically at larger sizes.
// By default, this is optimized for heavy use of h1-h4, and minimal use of h5 and h6.
//
// Styleguide Configuration.Headings.Heading Growth Rate (Size)
//
// Access: Public
//
// Since: 2.0.0

$heading-growth-rate: 3.5 !default;

// Calculate Growth Scale
//
// Calculates the multiplier needed for growth between a minimum and maximum value
// based on a given rate of growth.
//
// @param {int} $min - The minimum value to use. Units, if used, must match `$max`.
// @param {int} $max - The minimum value to use. Units, if used, must match `$min`.
// @param {int} $steps - The total number of values to calculate.
// @return {int} - A number to multiply by in an exponential equation to equal the
// maximum value on the last value calculated. Useful to calculate `$scale` for use
// in the `calc-size` function.
//
// @see calc-size
// @requires pow - an exponential function in the mathsass library
//
// Styleguide Typography.Factory.calc-scale
//
// Access: Public
//
// Since: 2.0.0

@function calc-scale ( $min, $max, $steps, $rate ) {
	@return math.div( $max - $min , math.pow( $steps, $rate ) );
}

// Calculate Relative Size
//
// Calculates a size, relative to a base size. By default, we use `$font-size-base` to
// assist with calculating the ratio for ems. However, you can pass your own base for
// using with your own unit standard. You can also choose _not_ to scale by passing
// 'true' to 'scaled'. You might choose to do this if your minimums and maximums
// are already scaled units, such as with line-height, or if you specify your min
// and max font-sizes in ems.
//
// @param {int} $step - The step within your scale you want to calculate.
// @param {int} $rate - The rate of growth at which your scale changes. Leave at 1 for even
// (linear) growth. Anything higher will create exponential growth.
// @param {int} $scale - A scaling number determined by your maximum value, if you have one.
// You may wish to use the `calc-scale` function to find this number. Leave at 1 if you do
// not need an upper limit.
// @param {int} $min - The minimum amount you need returned.
// @param {bool} $scaled - Whether or not to return a scaled value, using `$base` as the base
// unit. By default, this will scale to ems, returning a value based on `$font-size-base` equalling
// 1 em.
// @param {int} $base - A value to divide by in order to return a scaled value. The units on this
// value need to match `$min` - that is, if `$min` is in pixels, this needs to be in pixels as well.
// @return {int} - A unitless size.
//
// @requires pow - an exponential function in the mathsass library
// @see calc-scale
//
// Styleguide Typography.Factory.calc-size
//
// Access: Public
//
// Since: 2.0.0

@function calc-size( $step, $rate: 1, $scale: 1, $min: 0, $scaled: false, $base: $font-size-base ) {
	@if $scaled {
		@return math.pow( ( $step ), $rate ) * $scale + $min;
	} @else {
		@return math.div( math.pow( ( $step ), $rate ) * $scale + $min , $base );
	}
}

// Font Styles Map and Adding Custom Styles
//
// Holds values for font-size and line-height for all font styles. Two special case
// scenarios, `font-size-secondary` and `font-size-minimum`, have pixel values. Secondary
// is used for information in a theme that is secondary to main content, such as widgets,
// asides, footbars, and shortcodes, and resets the base value which headings and paragraph
// text uses. `font-size-minimum` is the lowest allowable font size in pixels - it never gets
// scaled, because it should never be smaller than that amount.
//
// Other values, such as those used for headings (`font-size-1` for `<h1>`, `font-size-2` for
// `<h2>`, etc) are dynamically added after we generate the headings scale.
//
// These values are used to build the font-size placeholders. You can override invidividual
// values and create your own custom values and placeholders by redeclaring values you want
// to override and adding new values in your own `$font-styles-theme` map.
//
// $font-styles-theme must be set BEFORE this file is imported.
//
// Styleguide Typography.Placeholders and Classes.$font-styles-theme
//
// Access: Public
//
// Since: 2.0.0

$font-styles: (
	secondary: (
	  	font-size-mobile: 12px,
	  	font-size-desktop: 16px,
		line-height: $min-line-height,
	),
	minimum: (
    	font-size-mobile: 11px,
		font-size-desktop: 13px,
		line-height: $min-line-height
	),
);

// Heading Size Scale
//
// The multiplier needed to calculate the scale between minimum and maximum
// font sizes on headings. This value is dependent on the heading minimum, maximum,
// and growth rate; it should never be changed directly. Change those instead.
//
// Styleguide Typography.Factory.$_heading-size-scale
//
// Access: Private
//
// Since: 2.0.0

$_heading-size-scale: calc-scale( $min-size-headings, $max-size-headings, $_depth-headings, $heading-growth-rate );

// Heading Size Scale - Mobile
//
// The multiplier needed to calculate the scale between minimum and maximum
// font sizes on headings on mobile. This value is dependent on the heading minimum, maximum,
// and growth rate; it should never be changed directly. Change those instead.
//
// Styleguide Typography.Factory.$_heading-size-scale-mobile
//
// Access: Private
//
// Since: 2.0.0

$_heading-size-scale-mobile: calc-scale( $min-size-headings-mobile, $max-size-headings-mobile, $_depth-headings, $heading-growth-rate );

// Heading Line Height Scale
//
// The multiplier needed to calculate the scale between minimum and maximum
// line heights on headings. This value is dependent on the heading minimum, maximum,
// and growth rate; it should never be changed directly. Change those instead.
//
// Styleguide Typography.Factory.$heading-lh-scale
//
// Access: Private
//
// Since: 2.0.0

$heading-lh-scale: calc-scale( $min-line-height, $max-line-height, $_depth-headings, $heading-growth-rate );

// A simple counter variable to help keep track of
// how many headings we have left to calculate.
//
// Access: Private
//
// Since: 2.0.0

$_h: $_depth-headings;

// Calculates font sizes and line heights for headings,
// and adds them to the `$font-styles` map.
//
// Access: Private
//
// Since: 2.0.0

@while $_h >= 0 {
	$font-style: ( );
	$size: null;
	$size-mobile: null;
	$lh: null;
	$name: null;
	$heading-name: $_depth-headings - $_h;

	@if $_h == 0 {
		$size: math.div( $min-size-headings, $font-size-base ) + em;
		$size-mobile: math.div( $min-size-headings-mobile, $font-size-base ) + em;
	} @else {
		$size: calc-size( $_h + 1, $heading-growth-rate, $_heading-size-scale, $min-size-headings ) + em;
		$size-mobile: calc-size( $_h + 1, $heading-growth-rate, $_heading-size-scale-mobile, $min-size-headings-mobile ) + em;
	}

	@if $_h == $_depth-headings {
		$lh: $min-line-height;
		$name: 'maximum';
	} @else {
		$lh: calc-size( $heading-name, $heading-growth-rate, $heading-lh-scale, $min-line-height, true );
		$name: $heading-name;
	}

	$font-style: (
		#{$name}: (
			font-size-mobile: $size-mobile,
			font-size-desktop: $size,
			line-height: $lh
		)
	);

	$font-styles: map_merge( $font-styles, $font-style );

	$_h: $_h - 1;
}

// Merges custom styles and overrides with the default font size map.
// $font-styles-theme must be set BEFORE this is called.
//
// Access: Private
//
// Since: 2.0.0

@if variable-exists( font-styles-theme ) {
	$font-styles: map_merge( $font-styles, $font-styles-theme );
}

// Font styles mixin
//
// A mixin to get and print font styles, just like `<h>` tags.
// Handy for when the placeholders just aren't working for you.
// Accepts a valid style, such as `6` (like h6) or `secondary`.
// Also accepts any style you've defined in the theme.
//
// #### Example:
//
// ##### Make a `<h4>` look like an `<h2>`.
//
// ```
// 			.comparison-title {
//				@include font-size( '2' );
//			}
// ```
//
// Styleguide Typography.Mixins.font-size
//
// Access: Public
//
// Since: 2.0.0

@mixin font-size( $style ) {
	$settings: map-get( $font-styles, $style );

	font-size: map-get( $settings, font-size-mobile );
	line-height: map-get( $settings, line-height );

	@include breakpoint( $xs ) {
		font-size: map-get( $settings, font-size-desktop );
		line-height: map-get( $settings, line-height );
	}
}

// Creates placeholders for each font style, which are used by `<h>` tags
// as well as throughout the theme.
//
// Access: Private
//
// Since: 2.0.0

@each $style, $settings in $font-styles {
	%font-size-#{$style} {
		@include font-size( $style );
	}

	@if $burf-extras {
		.font-size-#{$style} {
			@extend %font-size-#{$style} !optional;
		}
	}
}

// Heading Base
//
// Controls base styles for all heading tags.
//
// Styleguide Typography.Placeholders and Classes.%heading-base
//
// Access: Public
//
// Since: 1.0.0

%heading-base {
	color: var(--bu-heading-color, #{$color-heading});
	font-family: var(--bu-heading-font, #{$font-family-heading});
	margin-bottom: 0.6em;
	margin-top: 1em;

	small {
		color:  var(--bu-heading-color, #{$color-heading-small});
		font-size: 0.75em;
		font-weight: normal;
	}

	.page-title.u-visually-hidden + & {
		margin-top: 0;
	}
}

// Additional documentation for KSS

// Font size 1 placeholder
//
// A placeholder to mimic h1 styles.
// May also be used as a class if `$burf-extras` is enabled.
//
// #### Example:
//
// ##### Make a `<h4>` look like an `<h1>`.
//
// ```
// 			.comparison-title {
//				@extend %font-size-1;
//			}
// ```
//
// Styleguide Typography.Placeholders and Classes.%font-size-1
//
// Access: Public
//
// Since: 2.0.0

// Font size 2 placeholder
//
// A placeholder to mimic h1 styles.
// May also be used as a class if `$burf-extras` is enabled.
//
// #### Example:
//
// ##### Make a `<h4>` look like an `<h2>`.
//
// ```
// 			.comparison-title {
//				@extend %font-size-2;
//			}
// ```
//
// Styleguide Typography.Placeholders and Classes.%font-size-2
//
// Access: Public
//
// Since: 2.0.0

// Font size 3 placeholder
//
// A placeholder to mimic h3 styles.
// May also be used as a class if `$burf-extras` is enabled.
//
// #### Example:
//
// ##### Make a `<h4>` look like an `<h3>`.
//
// ```
// 			.comparison-title {
//				@extend %font-size-3;
//			}
// ```
//
// Styleguide Typography.Placeholders and Classes.%font-size-3
//
// Access: Public
//
// Since: 2.0.0

// Font size 4 placeholder
//
// A placeholder to mimic h4 styles.
// May also be used as a class if `$burf-extras` is enabled.
//
// #### Example:
//
// ##### Make a `<h4>` look like an `<h4>`.
//
// ```
// 			.comparison-title {
//				@extend %font-size-4;
//			}
// ```
//
// Styleguide Typography.Placeholders and Classes.%font-size-4
//
// Access: Public
//
// Since: 2.0.0

// Font size 5 placeholder
//
// A placeholder to mimic h5 styles.
// May also be used as a class if `$burf-extras` is enabled.
//
// #### Example:
//
// ##### Make a `<h4>` look like an `<h5>`.
//
// ```
// 			.comparison-title {
//				@extend %font-size-5;
//			}
// ```
//
// Styleguide Typography.Placeholders and Classes.%font-size-5
//
// Access: Public
//
// Since: 2.0.0

// Font size 6 placeholder
//
// A placeholder to mimic h6 styles.
// May also be used as a class if `$burf-extras` is enabled.
//
// #### Example:
//
// ##### Make a `<h4>` look like an `<h6>`.
//
// ```
// 			.comparison-title {
//				@extend %font-size-6;
//			}
// ```
//
// Styleguide Typography.Placeholders and Classes.%font-size-6
//
// Access: Public
//
// Since: 2.0.0

// Font size maximum placeholder
//
// A placeholder to mimic maximum styles.
// May also be used as a class if `$burf-extras` is enabled.
// Good for banners or other items where typography
// should be extra large.
//
// #### Example:
//
// ##### Make a `<h4>` look one size larger than an `<h1>`.
//
// ```
// 			.comparison-title {
//				@extend %font-size-maximum;
//			}
// ```
//
// Styleguide Typography.Placeholders and Classes.%font-size-maximum
//
// Access: Public
//
// Since: 2.0.0

// Font size minimum placeholder
//
// A placeholder to mimic minimum styles.
// May also be used as a class if `$burf-extras` is enabled.
// Good for legal text, disclaimer, or other minimum size information.
//
// #### Example:
//
// ##### Make a disclaimer as small as possible.
//
// ```
// 			.disclaimer {
//				@extend %font-size-minimum;
//			}
// ```
//
// Styleguide Typography.Placeholders and Classes.%font-size-minimum
//
// Access: Public
//
// Since: 2.0.0

// Font size secondary placeholder
//
// A placeholder to mimic secondary styles.
// May also be used as a class if `$burf-extras` is enabled.
// Good for captions and other secondary information.
//
// #### Example:
//
// ##### Make a caption feel like a secondary element to standard content.
//
// ```
// 			.caption {
//				@extend %font-size-secondary;
//			}
// ```
//
// Styleguide Typography.Placeholders and Classes.%font-size-secondary
//
// Access: Public
//
// Since: 2.0.0