// can be called with an empty value and will then return a default (0)
// i.e. if # val(la) is empty (not set), we call @safevalue(# val(la)px); padding: @safevalue; -> and padding would be set to 0 instead of causing a less compiler error.
// be wary of less scope where a variable is not set if it has been set in the same block already. Workaround is to use &{your-calls here}
.safevalue (@value; @fallback: 0) when not (isnumber(@value)){
  @safevalue: @fallback;
}
.safevalue (@value; @fallback: 0) when(default()){
  @safevalue: @value;
}

// dynamically lighten OR darken a color based on the lightness of another color
.lightenordarken(@color; @changeby: 15%) when (lightness(@color) < 51%) {
	@dyncolor: lighten(@color, @changeby);
}
.lightenordarken(@color; @changeby: 15%) when (lightness(@color) > 50%) {
	@dyncolor: darken(@color, @changeby);
}

.rgbabg (@color; @opacity: 100%) when (alpha(@color) < 1), (@opacity = 100%) {
	background: rgb(red(@color), green(@color), blue(@color));
	background: @color /* less condition 1 */;
}
.rgbabg (@color; @opacity: 100%) when (alpha(@color) = 1) and (@opacity < 100%) {
	background: rgb(red(@color), green(@color), blue(@color));
	background: fade(@color, @opacity) /* less condition 2 */;
}
.safecolor (@color; @opacity: 100%) when (alpha(@color) < 1), (@opacity = 100%) {
	@fallbackcolor: rgb(red(@color), green(@color), blue(@color));
	@rgbacolor: @color;
}
.safecolor (@color; @opacity: 100%) when (alpha(@color) = 1) and (@opacity < 100%) {
	@fallbackcolor: rgb(red(@color), green(@color), blue(@color));
	@rgbacolor: fade(@color, @opacity);
}
.retina-sprite (@file, @type, @width, @height) {
	background-image: url('@{file}.@{type}');
	
	@media  (-webkit-min-device-pixel-ratio: 2),
			(min-device-pixel-ratio: 2),
			(min-resolution: 192dpi),
			(min-resolution: 2dppx){
		background-size: @width @height;
		background-image: url('@{file}@2x.@{type}');
	}
}
.text-shadow (@string: 0 1px 3px rgba(0, 0, 0, 0.25)) {
	text-shadow: @string;
}
.box-shadow (@string) {
	-webkit-box-shadow: @string;
	box-shadow:         @string;
}
.drop-shadow (@x: 0, @y: 1px, @blur: 2px, @spread: 0, @alpha: 0.25) {
	-webkit-box-shadow:	@x @y @blur @spread rgba(0, 0, 0, @alpha);
	box-shadow:			@x @y @blur @spread rgba(0, 0, 0, @alpha);
}
.inner-shadow (@x: 0, @y: 1px, @blur: 2px, @spread: 0, @alpha: 0.25) {
	-webkit-box-shadow: inset @x @y @blur @spread rgba(0, 0, 0, @alpha);
	box-shadow:         inset @x @y @blur @spread rgba(0, 0, 0, @alpha);
}
.box-sizing (@type: border-box) {
	-webkit-box-sizing: @type;
	box-sizing:         @type;
}

.border-radius (@radius: 5px) {
	border-radius:         @radius;
	background-clip:         padding-box;
}
.border-radiuses (@topright: 0, @bottomright: 0, @bottomleft: 0, @topleft: 0) {
	border-top-right-radius:            @topright;
	border-bottom-right-radius:         @bottomright;
	border-bottom-left-radius:          @bottomleft;
	border-top-left-radius:             @topleft;

	background-clip:         padding-box; 
}

.opacity (@opacity: 0.5) {
	opacity: 			@opacity;
}

.gradient (@startColor: #eee, @endColor: white, @start: 0%, @end: 100%) {
	background-color: @endColor;
	background-image:        -webkit-gradient(linear, left top, left bottom, color-stop(@start,@startColor), color-stop(@end,@endColor));
	background-image: -webkit-linear-gradient(top, @startColor @start, @endColor @end);
	background-image:         linear-gradient(to bottom, @startColor @start, @endColor @end);
}
.horizontal-gradient (@startColor: #eee, @endColor: white) {
 	background-color: @startColor;
	background-image:        -webkit-gradient(linear, left top, right top, from(@startColor), to(@endColor));
	background-image: -webkit-linear-gradient(left, @startColor, @endColor);
	background-image:         linear-gradient(to right, @startColor, @endColor);
}
.animation (@name, @duration: 300ms, @delay: 0, @ease: ease) when not (@name = none) {
	-webkit-animation: @name @duration @delay @ease;
	animation:		   @name @duration @delay @ease;
}
.animation (@name, @duration: 300ms, @delay: 0, @ease: ease) when (@name = none) {
	-webkit-animation: @name;
	animation:		   @name;
}
.transition (@transition) {
	-webkit-transition: @transition;  
	-o-transition:      @transition;
	transition:         @transition;  
}
.transform(@string){
	-webkit-transform: 	@string;
	-ms-transform: 		@string;
	transform: 			@string;
}
.scale (@factor) {
	-webkit-transform:   scale(@factor);
	-ms-transform: 		 scale(@factor);
	transform: 			 scale(@factor);
}
.rotate (@deg) {
	-webkit-transform:   rotate(@deg);
	-ms-transform: 		 rotate(@deg);
	transform: 		 	 rotate(@deg);
}
.skew (@deg, @deg2) {
	-webkit-transform:   skew(@deg, @deg2);
	-ms-transform: 		 skew(@deg, @deg2);
	transform: 			 skew(@deg, @deg2);
}
.translate (@x, @y:0) {
	-webkit-transform:   translate(@x, @y);
	-ms-transform: 		 translate(@x, @y);
	transform: 			 translate(@x, @y);
}
.translate3d (@x, @y: 0, @z: 0) {
	-webkit-transform:   translate3d(@x, @y, @z);
	-ms-transform: 		 translate3d(@x, @y, @z);
	transform: 			 translate3d(@x, @y, @z);
}
.perspective (@value: 1000) {
	-webkit-perspective:@value;
	perspective: 		@value;
}
.transform-origin (@x:center, @y:center) {
	-webkit-transform-origin: @x @y;
	-ms-transform-origin:     @x @y;
	transform-origin:        @x @y;
}
.hyphens (@type: auto, @lines: 2, @chars: auto 3) {
	-webkit-hyphens: @type;
	    -ms-hyphens: @type;
	     -o-hyphens: @type;
	        hyphens: @type;
	        
	// CSS4, hopefully:
	-webkit-hyphenate-limit-lines: @lines;
	   -moz-hyphenate-limit-lines: @lines;
	    -ms-hyphenate-limit-lines: @lines;
	        hyphenate-limit-lines: @lines;
	-webkit-hyphenate-limit-chars: @chars;
	   -moz-hyphenate-limit-chars: @chars;
	    -ms-hyphenate-limit-chars: @chars;
	        hyphenate-limit-chars: @chars;
}