/*
 * nesting
 */

#header {
    width: 300px;

    .navigation {
        font-size: 12px;
    }

    @media (min-width: 768px) {
        width: 600px;

        @media (min-resolution: 192dpi) {
            background-image: url(/img/retina2x.png);
        }
    }
}


/*
 * parent selector
 */

.component {
    &:hover {
        text-decoration: underline;
    }

    // compound selector
    &__element,
    &--modifier {
        border: 1px;
    }

    // multiple &
    & + & {
        color: red;
    }

    // changing selector order
    body.firefox & {
        font-weight: normal;
    }
}


/*
 * variables, data types
 */

// assignment
@number:                      5em;
@double-quoted-string:        "foo";
@single-quoted-string:        'bar';
@double-quoted-escape-string: ~"foo";
@single-quoted-escape-string: ~'bar';
@not-quoted-string:           baz;
@spaces-list:                 1px 2px 3px 4px;
@commas-list:                 arial, some-other-arial, sans-serif;
@color:                       #fe57a1;

@detached-ruleset: {
    color: red;

    div {
        color: blue;
    }
};

#main {
    // property value
    width: @width;

    // variable reference
    color: @@color-variable-name;

    // property variable
    background-color: $color;

    // use detached ruleset
    @detached-ruleset(); // parentheses required
}

// media type, feature test
@import "foo" @type and @feature-test, (@feature-test-content);
@media @type and @feature-test, (@feature-test-content) {
    width: 700px;
}

// font feature value
@font-feature-values Font One {
    @styleset {
        nice-style: @value;
    }
}

// @keyframes name
@keyframes @myanim {
    from { width: 0; }
    to   { width: 100%; }
}


/*
 * cases where Less doesn't currently accept variables (as of Less 3.0.0)
 * but may be still be incidentally highlighted
 */

// font feature values font name
@font-feature-values @fontname {
    @styleset {
        nice-style: 12;
    }
}

// @namespace name
@namespace @name url('http://www.w3.org/2000/svg');

// @page custom name, pseudo-page
@page @name {
    margin: 0;

    @left-top {
    	content: '';
  	}
}


/*
 * variable interpolation
 */

// selector
@{hash-id},
#@{id},
#i@{d},
@{whole-class},
.part-@{class}-fragment,
@{div},
d@{i}v,
[@{attr}=@{value}],
[@{attr-selector-content}],
@{attr-selector},
@{selection},
::se@{lect}ion,
@{hover},
:ho@{v}er,
@{lang-fr},
:la@{ng}(fr),
:lang(@{fr}),
:nth-child(@{expr}),
:not(@{div}) {

    // property name
    @{font}: serif;
    background-@{image}: none;
    border-@{bottom}-width: 0;

    // inside strings
    content: "@{var}";
    content: '@{var}';

    // nested interpolations
    content: "@{@{nested}-variable}";
}

// font feature type, custom name
@font-feature-values Font One {
    @{type} {
        @{name}: 12;
    }
}

// inside @import url()
@import url("http://fonts.googleapis.com/css?family=@{family}");
// inside @import string
@import "http://fonts.googleapis.com/css?family=@{family}";

// @keyframes selectors
@keyframes myanim {
    @{from} { width: 0; }
    @{to}   { width: 100%; }
}

// @page margin box type
@page toc, :first {
    margin: 0;

    @{margin-box-type} {
    	content: '';
  	}
}


/*
 * operations
 */

body {
    width: (1px + (2em - 3rem)) * (4 / 5vh);

    // unary negation
    z-index: -@z-index;
    margin-bottom: -(@base * 2);
}


/*
 * functions
 */

body {
    // Less string format function
    content: %("1 plus 2 is %d", 1 + 2);

    // single line comments not parsed inside url()
    background: url(http://example.com/styles.css);

    // semicolons separators
    color: hsl(90; 100%; 50%);
}


/*
 * extend
 */

// attached to selector
#main:extend(.card-style),
.sidebar :extend(div pre),
:not(:extend(#footer)) { /* not allowed as argument to :not() */
    color: blue;
}

#main {
    // inside ruleset
    &:extend(#board:nth-child(2n+3));

    // all keyword
    &:extend(div ~ .inline[name="foo"] all);
}


/*
 * property merge
 */

code {
    // with comma
    box-shadow+: 0 0 20px black;

    // with space
    transform+_: scale(2);
}


/*
 * mixins
 */

// mixin definition
.black() {
    color: black;
}

// with parameters
.box(@margin, @padding) { // comma separated
    margin: @margin;
    padding: @padding;
}
.box(@margin; @padding) { // semicolon separated
    margin: @margin;
    padding: @padding;
}
.box(@margin: 10px; @padding: 10px) { // default parameters
    margin: @margin;
    padding: @padding;
}

// @arguments
.box-shadow(@x: 0; @y: 0; @blur: 1px; @color: #000) {
    box-shadow: @arguments;
}

// variable arguments
.mixin(...) {} // 0 or more arguments
.mixin(@a; ...) {} // at least 1 argument
.mixin(@a; @rest...) {} // remaining arguments bound to variable

// with pattern
.mixin(dark; 5px) {}
.mixin(light; #000) {}

// mixin call
#main {
    // existing styles
    #header;
    .card-style;

    // existing styles with parentheses (optional),
    // or mixins with parentheses and no required parameters
    #header();
    .card-style();

    // namespaced styles
    #outer > .inner;
    #outer .inner;
    #outer.inner;

    // important modifier
    #header !important;
    .card-style() !important;
    #outer > .inner !important;

    // with parameters
    .box(20px, 10px); // comma separated
    .box(20px; 10px); // semicolon separated
    .box(@padding: 10px; @margin: 20px); // named parameters
    .box(@list...); // expands values in @list as arguments
    .mixin({ // detached ruleset
        color: red;
        div {
            color: blue;
        }
    });

    // with pattern
    .mixin(dark; 5px);
    .mixin(light; #000);
}


/*
 * guards
 */

// regular styles
button when (@my-option = true) {
    color: white;
}
& when (@my-option = true) {
    button {
        color: white;
    }
    a {
        color: blue;
    }
}

// namespace
#namespace when (@mode = huge) {
    .mixin() {}
}
#namespace {
    .mixin() when (@mode = huge) {}
}

// mixin
.mixin (@a) when (lightness(@a) >= 50%) {
    background-color: black;
}
.mixin (@a) when (lightness(@a) < 50%) {
    background-color: white;
}

// comparison operators, logical operators
.mixin (@a) when (@a >= 0) and (@a =< 0) {}
.mixin (@a) when (@a < 0) or (@a > 0) {}
.mixin (@a) when (@a < 0), (@a > 0) {}
.mixin (@a) when not (@a = 0) {}

// true keyword
.mixin (@a) when (@a) {}
.mixin (@a) when (@a = true) {}


/*
 * at-rules
 */

// @import
@import "@{themes}/tidal-wave.less";
@import (optional, reference) "foo.less" screen and (orientation: landscape), print; // import options

// @plugin
@plugin 'my-plugin';
@plugin (options) 'my-plugin'; // plugin options

// @plugin function call
my-plugin();
div {
    my-plugin(red; 10px);
}


/*
 * test cases
 */

.declarations-or-selectors {
    // declarations
    display:block;
    font-family:arial;
    @{property}:block;

    background-image:url( \( \) \{ { );
    background-image:url( url( { )   );
    background-image:url( @var       );
    background-image:url( /* ) { */  );
    background-image:url( " ) { "    );
    background-image:url( ' ) { '    );

    margin:@var 10px;

    display:/* { */block;

    font-family:" \" \{ { ", serif;
    font-family:" @{var}  ", serif;

    font-family:' \' \{ { ', serif;
    font-family:' @{var}  ', serif;


    // incorrectly highlighted declarations
    display:block
    ;
    display:block // {
    ;

    // selectors
    input:focus { opacity: 0.5; }
    div:nth-child(2n+1) { background-color: gray; }
    div:-moz-full-screen { display: block; }

    @{selector}:focus { color: blue; }

    a:@{state} { color: blue; }

    a:focus[id=\]\;     ] { color: blue; }
    a:focus[id=@{var}   ] { color: blue; }
    a:focus[id=/* ] ; */] { color: blue; }
    a:focus[id=" ] ; "  ] { color: blue; }
    a:focus[id=' ] ; '  ] { color: blue; }

    a:@{var} { color: blue; }

    a:/* ; */focus { color: blue; }

    a:focus[id=" ] \" \; ; "] { color: blue; }
    a:focus[id=" @{var}    "] { color: blue; }

    a:focus[id=' ] \' \; ; '] { color: blue; }
    a:focus[id=' @{var}    '] { color: blue; }

    a:focus // ;
    { color: blue; }
}


// from file.css

@charset "UTF-8";
// Less will move the first @charset rule to the top
// and ignore any other @charset rules


/*
 * general
 */

/* whitespace */
#main
{
    color:aqua;
    float: left!important;
    margin  :  0  ;
    width
        :
        100%
        !
        important
        ;
}

/* case insensitivity */
Body {
    FONT: 12Px/16pX iTaLiC sans-SERIF;
}


/*
 * selectors
 */

/* simple selectors */
#testID,       /* id */
.someclass,    /* class */
div,           /* type */
*,             /* universal */
[lang|="zh"], /* attribute */
[ /* comment */ lang /* comment */ |= /* comment */ "zh" /* comment */ ] {
    color: black;
}

/* combinators */
header + main, /* adjacent sibling */
li ~ li,       /* general sibling */
ul > li,       /* child */
ul ul {        /* descendant */
    color: blue;
}

/* pseudo-elements */
:after,
::/* comment */after,
::placeholder,
::/* comment */selection {
    color: green;
}

/* pseudo-classes */
:hover,
:/* comment */required,
:lang(fr),
:/* comment */not(div#sidebar.fancy),
:nth-child(n+1),
:/* comment */nth-last-child(-2n /* comment */ - /* comment */ 30),
:nth-of-type(5),
:/* comment */nth-last-of-type(even) {
    color: yellow;
}

/* pseudo-classes with invalid arguments */
:not(div:before),         /* pseudo-element */
:not(input::placeholder), /* pseudo-element */
:not(p:not(:lang(en))),   /* nested :not */
:nth-child(1.2n),         /* non-integer */
:nth-child(.5),           /* non-integer */
:nth-child(n+-1) {        /* number sign */
    color: red;
}

/* namespace qualified */
a,           /* type in default namespace */
svg|a,       /* type in specified namespace */
|a,          /* type in no namespace */
*|a,         /* type in all namespaces (including no namespace) */
svg|*,       /* universal */
svg|[fill] { /* attribute */
    color: white;
}


/*
 * basic data types
 */

#main {
    /* angle */
    transform: rotate(+33.333e+3deg);

    /* color */
    color: #f00;
    color: #f00f; /* #rgba */
    color: #ff0000;
    color: #ff0000ff; /* #rrggbbaa */
    color: red;
    color: lightgoldenrodyellow;
    color: rebeccapurple;
    color: currentColor;

    /* frequency (not currently used for any property) */
    content: 44.1kHz;

    /* integer */
    z-index: +255;
    z-index: -1;

    /* length */
    width: 10px;
    width: 10.5rem;
    width: -10e-2vw;

    /* number */
    opacity: .5;
    opacity: 0.3333;
    opacity: 1;
    opacity: 2e-34;

    /* percentage */
    width: 100%;

    /* string */
    content: "double quoted";
    content: 'single quoted';

    /* time */
    transition-duration: .4s;
    transition-duration: 400ms;

    /* unicode range */
    unicode-range: U+0025-00FF;
    unicode-range: U+4??; /* wildcard range */
}

/* ratio */
@media (min-aspect-ratio: 16/9) {}
@media (min-aspect-ratio: 16 /* comment */ / /* comment */ 9) {}

/* resolution */
@media (min-resolution: +2.54dpcm) {}


/*
 * identifiers
 */

/* leading hyphens */
#-here.-there,
#-- .--everywhere { /* two hyphens: https://stackoverflow.com/a/30822662 */
    color: blue;
}

/* non-ASCII */
#español,
#你好,
.❤♫ {
    color: green;
}

/* invalid identifiers */
#1id,      /* starts with digit */
.-2class { /* starts with hyphen digit */
    color: maroon;
}


/*
 * escaping
 */

/* selectors */
#\..\+\ space\@\>,                            /* special character escape */
#\E9 dition .\0000E9dition .motion_\e9motion, /* Unicode character escape */
.\e33 div,                                    /* trailing space terminates Unicode character escape */
.\e33  div,                                   /* extra space to denote separate tokens */
.\31 23 {                                     /* escape leading digit of identifier */

    /* property value */
    content: "\E9 dition \
              \"\0000E9dition\" \
              \e9motion";
    font-family: \E9 dition, \"\0000E9dition\", \e9motion;

    /* function name */
    background: \u\72\l(image.png);
}


/*
 * functions
 */

#main {
    /* url */
    background: url("image.svg");

    /* function argument keywords */
    background-image: linear-gradient(to left top, #fff, blue);
    grid-template-columns: repeat(2, minmax(max-content, 300px) 1fr) 100px;
}


/*
 * style properties
 */

#main {
    /* svg */
    fill: url(#pattern);
    text-rendering: optimizeLegibility;

    /* css3 */
    font-variant-east-asian: jis04;
    size: letter;
    transition-timing-function: ease-in;

    /* animatable */
    transition-property: height, font-size, visibility;

    /* custom properties */
    --my-custom-color: #fff;
    color: var(--my-custom-color);
    background-color: var(--my-custom-color, white);
}

/*
 * modifiers
 */
body {
    background: pink !important;
}


/*
 * media queries
 */

@media screen, (orientation: portrait) {}
@media not (print and (min-monochrome: 16) and (color)) {}
@media only screen {} @media not print {}


/*
 * at-rules
 */

/* @font-face */
@font-face {
    font-family: MyHelvetica;
    src: local("Helvetica Neue"),
         local("HelveticaNeue"),
         url(MgOpenModerna.ttf);
}

/* @font-feature-values */
@font-feature-values Font One {
    @styleset {
        nice-style: 12;
    }
}
.nice-look {
    font-variant-alternates: styleset(nice-style);
}

/* @import */
@import URL("fineprint.css");
@import 'custom.css';
@import url('landscape.css') screen and (orientation: landscape), print;

/* @keyframes */
@keyframes myanim {
    from { opacity: 0.0; }
    50%  { opacity: 0.5; }
    to   { opacity: 1.0; }
}

/* @media */
@media all {
    body {
        background: gray;
    }
    @media screen, (orientation: portrait) {
        body {
            background: grey;
        }
    }
}

/* @namespace */
@namespace "http://www.w3.org/1999/xhtml";
@namespace svg url(http://www.w3.org/2000/svg);

/* @page */
@page {
    bleed: 1cm;
}
@page toc, :blank {
    margin: 2cm;
    marks: crop cross;
}
@page index:/*comment*/left {
    size: A4;

    @top-right {
        content: "Page " counter(page);
    }
}

/* @supports */
@supports (animation-name: test) {
    @keyframes 'my-complicated-animation' {
        0%   { width: 0; }
        100% { width: 100%; }
    }
}


/*
 * vendor-specific extensions
 */

/* pseudo-elements */
input[type="number"]::-webkit-outer-spin-button,
input[type="number"]::/* comment */-webkit-inner-spin-button {
    -webkit-appearance: none;
}
input[type="number"] {
    -moz-appearance: textfield;
}

/* pseudo-classes */
#page:-moz-full-screen,
#page:/* comment */-ms-fullscreen,
#page:-webkit-full-screen {
    background: silver;
}

/* functions */
.footer {
    background-image: -webkit-linear-gradient(to left top, #fff, blue);
}

/* style properties */
#sidebar {
    -ms-overflow-style: -ms-autohiding-scrollbar;
}
@supports not ((text-align-last: justify) or (-moz-text-align-last: justify)) {
    body {
        text-align: justify;
    }
}

/* at-rules */
@-webkit-keyframes myanim {
    from { opacity: 0.0; }
    50%  { opacity: 0.5; }
    to   { opacity: 1.0; }
}
