// IE 10/11 do not respect box-sizing: border-box; on flex items so we need a max-width
// This is fixed in IE12 - https://github.com/philipwalton/flexbugs/issues/3
.flex(@basis: 0, @flex: 0, @max: 100%) {
	flex: @basis @flex @max;
	max-width: @max;
	max-height: @max;
}

// Gradient animation mixin -- basically used for buttons
// takes a start and end color
.gradient-animation(@start, @end) {
	position: relative;
	background-size: 100%;
	background-image: linear-gradient(@start, @end);
	transition: opacity @timing-animation-hover, box-shadow (@timing-animation-hover / 2);
	z-index: 0;

	&::before {
		position: absolute;
		display: block;
		height: 100%;
		width: 100%;
		top: 0;
		left: 0;
		background-image: linear-gradient(@end, @start);
		box-shadow: none;
		opacity: 0;
		transition: opacity @timing-animation-hover, box-shadow (@timing-animation-hover / 2);
		z-index: -1;
		content: '';
	}

	&:hover:not(&-is-active)::before {
		opacity: 1;
	}

	&:active:not(&-is-disabled) {
		box-shadow: @shadow-inset;
	}

	&:focus {
		.focus-glow();
	}

	&:active:focus {
		border-radius: @size-borderRadius;
		box-shadow: @shadow-inset;
	}

	&:active::before {
		border-radius: @size-borderRadius;
		box-shadow: @shadow-inset;
		opacity: 1;
	}
}

// gradient reset takes a background if different than none
.gradient-reset(@background: none) {
	background: @background;

	&::before {
		content: '';
		display: none;
	}

	&:active {
		&::before {
			box-shadow: none;
		}
	}
}

// Creates a disabled element **uses `.gradient-reset()`**
// * `@name` is passed in to help name space the styles.
// * `@start-color` gradient start color if other than transparent.
// * `@end-color` gradient end color if other than transparent.
// * `@gradient` is the flow of the gradient.
.make-is-disabled(@name, @start-color: @color-transparent, @end-color: @color-transparent, @gradient: @standardGradient) {
	&.@{name}-is-disabled {
		.gradient-reset(linear-gradient(@gradient, @start-color, @end-color));

		&:hover {
			text-decoration: none;
		}
	}
}

.inset-box-shadow(@color: #000) {
	box-shadow: 0 3px 3px fade(@color, 5%) inset;
}

// Normalize box sizing
.box-sizing(@box-sizing: border-box) {
	box-sizing: @box-sizing;
}

// Defines a standard 30% opacity
.opacity(@opacity: .30) {
	opacity: @opacity;
}

.text-truncate() {
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

// This helps prevent flickering on safari when using certain animations. See
// the following link for more info: http://stackoverflow.com/questions/3461441/prevent-flicker-on-webkit-transition-of-webkit-transform
.no-safari-flicker() {
	-webkit-transform: translate3d(0, 0, 0);
}

// This helps prevent strange SVG aliasing in firefox
.no-firefox-svg-aliasing() {
	-moz-transform: translate3d(0, 0, 0);
}

// Creates a drop shadow using a background gradient.
// * `@start` color at the top of the gradient
// * `@stop` color at end and fills the rest of the container
// * `@height` the height of the gradient
.dropshadow-gradient(@start, @stop, @height) {
	background-image: linear-gradient(@start 0, @stop @height);
}

// Create a border like line.  There are times that you may not want to set a
// border that is thicker than 2px because the way that borders intersect.
// This will use a background gradient to create a "border" within a container
// * `@direction` *'to bottom'* defines the side the "border" is on
// * `@line` *@color-primary* defines "border" color
// * `@background` *@color-white* defines the remainder fill color-primary
// * `@height` *3px* defines the thickness of the "border"
.hardstop-gradient(@direction: to bottom, @line: @color-primary, @background: @color-white, @height: 3px) {
	background-image: linear-gradient(@direction, @line 0, @line @height, @background @height);
}

// Create an element which displays the properties of a selectable UI component
.is-selectable() {
	cursor: pointer;
}

// -----------------------------------------------------------------------------
// Animations
// -----------------------------------------------------------------------------

// This set of mixins in intended to be used with ReactCSSTransitionGroup. It's
// important that you place this mixin directly underneath the parent that
// should be animating.

.transition-group-animation-fade(@timing: @timing-animation-fade) {
	&-enter {
		.opacity(0.01);
	}

	&-enter&-enter-active {
		.opacity(1);

		transition: opacity @timing ease-in;
	}

	&-leave {
		.opacity(1);
	}

	&-leave&-leave-active {
		.opacity(0.01);

		transition: opacity @timing ease-in;
	}
}

// This is a simple mixin to normalize the styles for an unselectable and unclickable element.
.no-cursor() {
	cursor: not-allowed;
}

// Place a styled box on the left edge of the current element with the given scale and width
.left-marker(@scale:1; @width: @size-XXS + 1) {
	position: relative;

	&::after {
		position: absolute;
		left: 0;
		top: 0;
		height: 100%;
		width: @width;
		background-color: @color-primary;
		content: '';
		transform-origin: 0 0;
		transform: scaleX(@scale);
		transition: transform @timing-animation-hover;
	}
}

.focus-glow(@color: @color-primary-30) {
	box-shadow: 0 0 0 3px @color;
}

// -----------------------------------------------------------------------------
// Typography
// -----------------------------------------------------------------------------

.bold() {
	font-weight: 500;
}

// -----------------------------------------------------------------------------
// Charts
// -----------------------------------------------------------------------------

// This function will apply all the variables in `@color-chart-variables` as
// `fill` or `stroke`s.
.chart-color-loop(
	@i: length(@color-chart-variables),
	@fill: false,
	@stroke: false,
) when (@i > 0) {
	@name: extract(@color-chart-variables, @i);

	&-@{name} when(@fill = true) {
		fill: @@name;
	}

	&-@{name} when(@stroke = true) {
		stroke: @@name;
	}

	// Recurse
	.chart-color-loop(
		@i: @i - 1,
		@fill: @fill,
		@stroke: @stroke
	);
}

.link() {
	text-decoration: none;
	color: @color-linkColor;

	&:hover {
		color: @color-linkColorHover;
	}
}

