%YAML 1.2
---
# Derived from https://github.com/i-akhmadullin/Sublime-CSS3
name: CSS
file_extensions:
  - css
  - css.erb
  - css.liquid
scope: source.css
variables:
  # Many variable names taken directly from https://www.w3.org/TR/css3-selectors/#lex
  unicode: '\\\h{1,6}[ \t\n\f]?'
  escape: '(?:{{unicode}}|\\[^\n\f\h])'
  nonascii: '[\p{L}\p{M}\p{S}\p{N}&&[^[:ascii:]]]'
  nmstart: '(?:[[_a-zA-Z]{{nonascii}}]|{{escape}})'
  nmchar: '(?:[[-\w]{{nonascii}}]|{{escape}})'
  ident: '(?:--{{nmchar}}+|-?{{nmstart}}{{nmchar}}*)'

  # Types
  # https://www.w3.org/TR/css3-values/#numeric-types
  integer: '(?:[-+]?\d+)'
  number: '[-+]?(?:(?:\d*\.\d+(?:[eE]{{integer}})*)|{{integer}})'

  # Units
  # https://www.w3.org/TR/css3-values/#lengths
  font_relative_lengths: '(?i:em|ex|ch|rem)'
  viewport_percentage_lengths: '(?i:vw|vh|vmin|vmax)'
  absolute_lengths: '(?i:cm|mm|q|in|pt|pc|px|fr)'
  angle_units: '(?i:deg|grad|rad|turn)'
  duration_units: '(?i:s|ms)'
  frequency_units: '(?i:Hz|kHz)'
  resolution_units: '(?i:dpi|dpcm|dppx)'

  custom_element_chars: |-
    (?x:
        [-_a-z0-9\x{00B7}]
      | \\\.
      | [\x{00C0}-\x{00D6}]
      | [\x{00D8}-\x{00F6}]
      | [\x{00F8}-\x{02FF}]
      | [\x{0300}-\x{037D}]
      | [\x{037F}-\x{1FFF}]
      | [\x{200C}-\x{200D}]
      | [\x{203F}-\x{2040}]
      | [\x{2070}-\x{218F}]
      | [\x{2C00}-\x{2FEF}]
      | [\x{3001}-\x{D7FF}]
      | [\x{F900}-\x{FDCF}]
      | [\x{FDF0}-\x{FFFD}]
      | [\x{10000}-\x{EFFFF}]
    )

  combinators: '(?:>{1,3}|[~+])'

  # Predefined Counter Styles
  # https://drafts.csswg.org/css-counter-styles-3/#predefined-counters
  counter_styles: |-
    (?xi:
        arabic-indic | armenian | bengali | cambodian | circle
      | cjk-decimal | cjk-earthly-branch | cjk-heavenly-stem | decimal-leading-zero
      | decimal | devanagari | disclosure-closed | disclosure-open | disc
      | ethiopic-numeric | georgian | gujarati | gurmukhi | hebrew
      | hiragana-iroha | hiragana | japanese-formal | japanese-informal
      | kannada | katakana-iroha | katakana | khmer
      | korean-hangul-formal | korean-hanja-formal | korean-hanja-informal | lao
      | lower-alpha | lower-armenian | lower-greek | lower-latin | lower-roman
      | malayalam | mongolian | myanmar | oriya | persian
      | simp-chinese-formal | simp-chinese-informal
      | square | tamil | telugu | thai | tibetan
      | trad-chinese-formal | trad-chinese-informal
      | upper-alpha | upper-armenian | upper-latin | upper-roman
    )

contexts:
  main:
    - include: comment-block
    - include: selector
    - include: at-rules
    - include: property-list

  at-rules:
    - include: at-charset
    - include: at-counter-style
    - include: at-custom-media
    - include: at-document
    - include: at-font-face
    - include: at-import
    - include: at-keyframes
    - include: at-media
    - include: at-namespace
    - include: at-page
    - include: at-supports

  # When including `color-values` and `color-adjuster-functions`, make sure it is
  # included after the color adjustors to prevent `color-values` from consuming
  # conflicting function names & color constants such as `red`, `green`, or `blue`.
  color-values:
    - include: color-functions
      # https://www.w3.org/TR/CSS22/syndata.html#color-units
    - match: \b(aqua|black|blue|fuchsia|gray|green|lime|maroon|navy|olive|orange|purple|red|silver|teal|white|yellow)\b
      scope: support.constant.color.w3c-standard-color-name.css
      # https://www.w3.org/TR/css3-color/#svg-color
    - match: \b(aliceblue|antiquewhite|aquamarine|azure|beige|bisque|blanchedalmond|blueviolet|brown|burlywood|cadetblue|chartreuse|chocolate|coral|cornflowerblue|cornsilk|crimson|cyan|darkblue|darkcyan|darkgoldenrod|darkgray|darkgreen|darkgrey|darkkhaki|darkmagenta|darkolivegreen|darkorange|darkorchid|darkred|darksalmon|darkseagreen|darkslateblue|darkslategray|darkslategrey|darkturquoise|darkviolet|deeppink|deepskyblue|dimgray|dimgrey|dodgerblue|firebrick|floralwhite|forestgreen|gainsboro|ghostwhite|gold|goldenrod|greenyellow|grey|honeydew|hotpink|indianred|indigo|ivory|khaki|lavender|lavenderblush|lawngreen|lemonchiffon|lightblue|lightcoral|lightcyan|lightgoldenrodyellow|lightgray|lightgreen|lightgrey|lightpink|lightsalmon|lightseagreen|lightskyblue|lightslategray|lightslategrey|lightsteelblue|lightyellow|limegreen|linen|magenta|mediumaquamarine|mediumblue|mediumorchid|mediumpurple|mediumseagreen|mediumslateblue|mediumspringgreen|mediumturquoise|mediumvioletred|midnightblue|mintcream|mistyrose|moccasin|navajowhite|oldlace|olivedrab|orangered|orchid|palegoldenrod|palegreen|paleturquoise|palevioletred|papayawhip|peachpuff|peru|pink|plum|powderblue|rebeccapurple|rosybrown|royalblue|saddlebrown|salmon|sandybrown|seagreen|seashell|sienna|skyblue|slateblue|slategray|slategrey|snow|springgreen|steelblue|tan|thistle|tomato|turquoise|violet|wheat|whitesmoke|yellowgreen)\b
      scope: support.constant.color.w3c-extended-color-keywords.css
      # Special Color Keywords
      # https://www.w3.org/TR/css3-color/#currentcolor
      # https://www.w3.org/TR/css3-color/#transparent-def
    - match: \b((?i)currentColor|transparent)\b
      scope: support.constant.color.w3c-special-color-keyword.css
      # Hex Color
    - match: '(#)(\h{3}|\h{6})\b'
      scope: constant.other.color.rgb-value.css
      captures:
        1: punctuation.definition.constant.css
      # RGBA Hexadecimal Colors
      # https://en.wikipedia.org/wiki/RGBA_color_space#RGBA_hexadecimal_.28word-order.29
    - match: '(#)(\h{4}|\h{8})\b'
      scope: constant.other.color.rgba-value.css
      captures:
        1: punctuation.definition.constant.css

  comment-block:
    - match: /\*
      scope: punctuation.definition.comment.css
      push:
        - meta_scope: comment.block.css
        - match: \*/
          scope: punctuation.definition.comment.css
          pop: true

  at-charset:
    - match: \s*((@)charset\b)\s*
      captures:
        1: keyword.control.at-rule.charset.css
        2: punctuation.definition.keyword.css
      push:
        - meta_scope: meta.at-rule.charset.css
        - include: at-rule-punctuation
        - include: literal-string

  # @counter-style
  # https://drafts.csswg.org/css-counter-styles-3/#the-counter-style-rule
  at-counter-style:
    - match: \s*((@)counter-style\b)\s+(?:(?i:\b(decimal|none)\b)|({{ident}}))\s*(?=\{|$)
      captures:
        1: keyword.control.at-rule.counter-style.css
        2: punctuation.definition.keyword.css
        3: invalid.illegal.counter-style-name.css
        4: entity.other.counter-style-name.css
      push:
        - meta_scope: meta.at-rule.counter-style.css
        - include: comment-block
        - include: rule-list-terminator
        - include: rule-list

  at-custom-media:
    - match: (?=\s*@custom-media\b)
      push:
        - match: ;
          scope: punctuation.terminator.css
          pop: true
        - match: \s*((@)custom-media)
          captures:
            1: keyword.control.at-rule.custom-media.css
            2: punctuation.definition.keyword.css
            3: support.constant.custom-media.css
          push:
            - meta_scope: meta.at-rule.custom-media.css
            - match: \s*(?=;)
              pop: true
            - include: media-query-list

  # @document
  # https://www.w3.org/TR/2012/WD-css3-conditional-20120911/#at-document
  at-document:
    - match: '((@)document)'
      captures:
        1: keyword.control.at-rule.document.css
        2: punctuation.definition.keyword.css
      push:
        - meta_scope: meta.at-rule.document.css
        - match: '\{'
          scope: punctuation.definition.block.begin.css
          push:
            - meta_scope: meta.block.css
            - match: '(?=\})'
              pop: true
            - include: main
        - match: '\}'
          scope: meta.block.css punctuation.definition.block.end.css
          pop: true
        - include: comment-block
        - include: url-function
        - include: url-prefix-function
        - include: domain-function
        - include: regexp-function
        - include: comma-delimiter

  at-font-face:
    - match: '\s*((@)font-face)\s*(?=\{|$)'
      captures:
        1: keyword.control.at-rule.font-face.css
        2: punctuation.definition.keyword.css
      push:
        - meta_scope: meta.at-rule.font-face.css
        - include: comment-block
        - include: rule-list-terminator
        - include: rule-list

  at-import:
    - match: \s*((@)import\b)\s*
      captures:
        1: keyword.control.at-rule.import.css
        2: punctuation.definition.keyword.css
      push:
        - meta_scope: meta.at-rule.import.css
        - include: at-rule-punctuation
        - include: literal-string
        - include: url-function
        - include: media-query-list

  # https://drafts.csswg.org/css-animations/#propdef-animation-name
  keyframe-name:
    - match: '\s*({{ident}})?'
      captures:
        1: entity.other.animation-name.css
      push:
        - match: '\s*(?:(,)|(?=[{;]))'
          captures:
            1: punctuation.definition.arbitrary-repetition.css
          pop: true

  # @keyframes
  # https://drafts.csswg.org/css-animations/#keyframes
  at-keyframes:
    - match: (?=\s*@(?:-webkit-|-moz-|-o-)?keyframes\b)
      push:
        - include: rule-list-terminator
        - match: \s*((@)(-webkit-|-moz-|-o-)?keyframes)
          captures:
            1: keyword.control.at-rule.keyframe.css
            2: punctuation.definition.keyword.css
            3: support.type.property-vendor.css
            4: support.constant.keyframe.css
          push:
            - meta_scope: meta.at-rule.keyframe.css
            - match: '\s*(?=\{)'
              pop: true
            - match: '\s*(?=[^{;])'
              push:
                - match: '\s*(?=[{;])'
                  pop: true
                - include: keyframe-name
        - match: '\s*(\{)'
          captures:
            1: punctuation.section.property-list.css
          push:
            - match: '(?=\})'
              pop: true
            - match: '\s*(?:(from|to)|((?:\.[0-9]+|[0-9]+(?:\.[0-9]*)?)(%)))\s*,?\s*'
              captures:
                1: keyword.keyframe-selector.css
                2: constant.numeric.css
                3: keyword.other.unit.css
            - include: main

  at-media:
    - match: (?=\s*@media\b)
      push:
        - include: rule-list-terminator
        - match: \s*((@)media)
          captures:
            1: keyword.control.at-rule.media.css
            2: punctuation.definition.keyword.css
            3: support.constant.media.css
          push:
            - meta_scope: meta.at-rule.media.css
            - match: '\s*(?=\{)'
              pop: true
            - include: media-query-list
        - match: '\s*(\{)'
          captures:
            1: punctuation.section.property-list.css
          push:
            - match: '(?=\})'
              pop: true
            - include: main

  media-query:
    # Media Types: https://www.w3.org/TR/CSS21/media.html
    - include: comment-block
    - match: \b(?i:all|aural|braille|embossed|handheld|print|projection|screen|speech|tty|tv)\b
      scope: support.constant.media.css
    - match: '\b(?i:and|or|not|only)\b'
      scope: keyword.operator.logic.media.css
    - match: ','
      scope: punctuation.definition.arbitrary-repetition.css
    - match: \(
      scope: punctuation.definition.group.begin.css
      push:
        - match: \)
          scope: punctuation.definition.group.end.css
          pop: true
        - include: comment-block
        - match: |-
            (?x)
            (
                (-webkit-|-o-)?
                ((min|max)-)?
                (-moz-)?
                (
                    ((device-)?(height|width|aspect-ratio|pixel-ratio))|
                    (color(-index)?)|monochrome|resolution
                )
            )|grid|scan|orientation
            \s*(?=[:)])
          captures:
            0: support.type.property-name.media.css
            2: support.type.vendor-prefix.css
            5: support.type.vendor-prefix.css
          push:
            - match: (:)|(?=\))
              captures:
                1: punctuation.separator.key-value.css
              pop: true
        - match: \b(portrait|landscape|progressive|interlace)
          scope: support.constant.property-value.css
        - match: \s*(\d+)(/)(\d+)
          captures:
            1: constant.numeric.css
            2: keyword.operator.arithmetic.css
            3: constant.numeric.css
        - include: numeric-values

  media-query-list:
    - match: '\s*(?=[^{;])'
      push:
        - match: '\s*(?=[{;])'
          pop: true
        - include: media-query

  # @namespace
  # https://www.w3.org/TR/css3-namespace/
  at-namespace:
    - match: '\s*((@)namespace)\s+({{ident}})?'
      captures:
        1: keyword.control.at-rule.namespace.css
        2: punctuation.definition.keyword.css
        3: entity.other.namespace-prefix.css
      push:
        - meta_scope: meta.at-rule.namespace.css
        - include: at-rule-punctuation
        - include: literal-string

  # @page
  # https://www.w3.org/TR/CSS2/page.html
  at-page:
    - match: '\s*((@)page)\s*(?:(:)(first|left|right))?\s*(?=\{|$)'
      captures:
        1: keyword.control.at-rule.page.css
        2: punctuation.definition.keyword.css
        3: punctuation.definition.entity.css
        4: entity.other.pseudo-class.css
      push:
        - meta_scope: meta.at-rule.page.css
        - include: comment-block
        - include: rule-list-terminator
        - include: rule-list

  # @supports
  # https://drafts.csswg.org/css-conditional-3/#at-supports
  at-supports:
    - match: '((@)supports)'
      captures:
        1: keyword.control.at-rule.supports.css
        2: punctuation.definition.keyword.css
      push:
        - meta_scope: meta.at-rule.supports.css
        - match: '\{'
          scope: punctuation.definition.block.begin.css
          push:
            - meta_scope: meta.block.css
            - match: '(?=\})'
              pop: true
            - include: rule-list-body
            - include: main
        - match: '\}'
          scope: meta.block.css punctuation.definition.block.end.css
          pop: true
        - include: at-supports-operators
        - include: at-supports-parens

  at-supports-operators:
    - match: '\b(?i:and|or|not)\b'
      scope: keyword.operator.logic.css

  at-supports-parens:
    - match: '\('
      scope: punctuation.definition.group.begin.css
      push:
        - meta_scope: meta.group.css
        - match: '\)'
          scope: punctuation.definition.group.end.css
          pop: true
        - include: at-supports-operators
        - include: at-supports-parens
        - include: rule-list-body

  property-list:
    - match: '(?=\{)'
      push:
        - match: '\}'
          scope: punctuation.section.property-list.css
          pop: true
        - include: rule-list

  property-value-constants:
    - match: |-
            (?x)\b(
                absolute|active|add
              | all(-(petite|small)-caps|-scroll)?
              | alpha(betic)?
              | alternate(-reverse)?
              | always|annotation|antialiased|at
              | auto(hiding-scrollbar)?
              | avoid(-column|-page|-region)?
              | background(-color|-image|-position|-size)?
              | backwards|balance|baseline|below|bevel|bicubic|bidi-override|blink
              | block(-line-height)?
              | blur
              | bold(er)?
              | border(-bottom|-left|-right|-top)?-(color|radius|width|style)
              | border-(bottom|top)-(left|right)-radius
              | border-image(-outset|-repeat|-slice|-source|-width)?
              | border(-bottom|-left|-right|-top|-collapse|-spacing|-box)?
              | both|bottom
              | box(-shadow)?
              | break-(all|word)
              | brightness
              | butt(on)?
              | capitalize
              | cent(er|ral)
              | char(acter-variant)?
              | cjk-ideographic|clip|clone|close-quote
              | closest-(corner|side)
              | col-resize|collapse
              | color(-stop|-burn|-dodge)?
              | column((-count|-gap|-reverse|-rule(-color|-width)?|-width)|s)?
              | common-ligatures|condensed|consider-shifts|contain
              | content(-box|s)?
              | contextual|contrast|cover
              | crisp(-e|E)dges
              | crop
              | cross(hair)?
              | da(rken|shed)
              | default|dense|diagonal-fractions|difference|disabled
              | discretionary-ligatures|disregard-shifts
              | distribute(-all-lines|-letter|-space)?
              | dotted|double|drop-shadow
              | (nwse|nesw|ns|ew|sw|se|nw|ne|w|s|e|n)-resize
              | ease(-in-out|-in|-out)?
              | element|ellipsis|embed|end|EndColorStr|evenodd
              | exclu(de(-ruby)?|sion)
              | expanded
              | (extra|semi|ultra)-(condensed|expanded)
              | farthest-(corner|side)?
              | fill(-box|-opacity)?
              | filter|fixed|flat
              | flex((-basis|-end|-grow|-shrink|-start)|box)?
              | flip|flood-color
              | font(-size(-adjust)?|-stretch|-weight)?
              | forwards
              | from(-image)?
              | full-width|geometricPrecision|glyphs|gradient|grayscale
              | grid(-height)?
              | groove|hand|hanging|hard-light|height|help|hidden|hide
              | historical-(forms|ligatures)
              | horizontal(-tb)?
              | hue
              | ideograph(-alpha|-numeric|-parenthesis|-space|ic)
              | inactive|include-ruby|infinite|inherit|initial
              | inline(-block|-box|-flex(box)?|-line-height|-table)?
              | inset|inside
              | inter(-ideograph|-word|sect)
              | invert|isolat(e|ion)|italic
              | jis(04|78|83|90)
              | justify(-all)?
              | keep-all
              | large[r]?
              | last|left|letter-spacing
              | light(e[nr]|ing-color)
              | line(-edge|-height|-through)?
              | linear(-gradient|RGB)?
              | lining-nums|list-item|local|loose|lowercase|lr-tb|ltr
              | lumin(osity|ance)|manual
              | margin(-bottom|-box|-left|-right|-top)?
              | marker(-offset|s)?
              | mathematical
              | max-(content|height|lines|size|width)
              | medium|middle
              | min-(content|height|width)
              | miter|mixed|move|multiply|newspaper
              | no-(change|clip|(close|open)-quote|(common|discretionary|historical)-ligatures|contextual|drop|repeat)
              | none|nonzero|normal|not-allowed|nowrap|oblique
              | offset(-after|-before|-end|-start)?
              | oldstyle-nums|opacity|open-quote
              | optimize(Legibility|Precision|Quality|Speed)
              | order|ordinal|ornaments
              | outline(-color|-offset|-width)?
              | outset|outside|over(line|-edge|lay)
              | padding(-bottom|-box|-left|-right|-top)?
              | page|painted|paused
              | perspective-origin
              | petite-caps|pixelated|pointer
              | pre(-line|-wrap)?
              | preserve-3d
              | progid:DXImageTransform.Microsoft.(Alpha|Blur|dropshadow|gradient|Shadow)
              | progress
              | proportional-(nums|width)
              | radial-gradient|recto|region|relative
              | repeat(-[xy])?
              | repeating-(linear|radial)-gradient
              | replaced|reset-size|reverse|ridge|right
              | round
              | row(-resize|-reverse)?
              | run-in
              | ruby(-base|-text)?(-container)?
              | rtl|running|saturat(e|ion)|screen
              | scroll(-position|bar)?
              | separate|sepia
              | scale-down
              | shape-(image-threshold|margin|outside)
              | show
              | sideways(-lr|-rl)?
              | simplified
              | slashed-zero|slice
              | small(-caps|er)?
              | smooth|snap|solid|soft-light
              | space(-around|-between)?
              | span|sRGB
              | stack(ed-fractions)?
              | start(ColorStr)?
              | static
              | step-(end|start)
              | sticky
              | stop-(color|opacity)
              | stretch|strict
              | stroke(-box|-dash(array|offset)|-miterlimit|-opacity|-width)?
              | style(set)?
              | stylistic
              | sub(grid|pixel-antialiased|tract)?
              | super|swash
              | table(-caption|-cell|(-column|-footer|-header|-row)-group|-column|-row)?
              | tabular-nums|tb-rl
              | text((-bottom|-(decoration|emphasis)-color|-indent|-(over|under|after|before)-edge|-shadow|-size(-adjust)?|-top)|field)?
              | thi(ck|n)
              | titling-ca(ps|se)
              | to[p]?
              | touch|traditional
              | transform(-origin)?
              | under(-edge|line)?
              | unicase|unset|uppercase|upright
              | use-(glyph-orientation|script)
              | verso
              | vertical(-align|-ideographic|-lr|-rl|-text)?
              | view-box
              | viewport-fill(-opacity)?
              | visibility
              | visible(Fill|Painted|Stroke)?
              | wait|wavy|weight|whitespace|width|word-spacing
              | wrap(-reverse)?
              | x{1,2}-(large|small)
              | z-index|zero
              | zoom(-in|-out)?
              | ({{counter_styles}})
            )\b
      scope: support.constant.property-value.css
      # Generic Font Families: https://www.w3.org/TR/CSS2/fonts.html
    - match: \b(?i:sans-serif|serif|monospace|fantasy|cursive|system-ui)\b(?=\s*[;,\n}])
      scope: support.constant.font-name.css

  property-values:
    - include: comment-block
    - include: vendor-prefix
    - include: builtin-functions
    - include: unicode-range
    - include: numeric-values
    - include: color-values
    - include: property-value-constants
    - include: literal-string
    - match: \!\s*important
      scope: keyword.other.important.css

  rule-list-terminator:
    - match: '\s*(\})'
      captures:
        1: punctuation.section.property-list.css
      pop: true

  rule-list:
    - match: '\{'
      scope: punctuation.section.property-list.css
      push:
        - meta_scope: meta.property-list.css
        - match: '(?=\s*\})'
          pop: true
        - include: rule-list-body

  rule-list-body:
    - include: comment-block
    - match: "(?=[-a-z])"
      push:
        - meta_scope: meta.property-name.css
        - match: "$|(?![-a-z])"
          pop: true
        - include: vendor-prefix
        - match: '\b(var-)({{ident}})(?=\s)'
          scope: invalid.deprecated.custom-property.css
          captures:
            1: keyword.other.custom-property.prefix.css
            2: support.type.custom-property.name.css
        - include: custom-property-name
        - match: \bfont(-family)?(?!-)\b
          scope: support.type.property-name.css
          push:
            - match: (:)([ \t]*)
              captures:
                1: punctuation.separator.key-value.css
                2: meta.property-value.css
              push:
                - meta_content_scope: meta.property-value.css
                - match: '\s*(;)|(?=[})])'
                  captures:
                    1: punctuation.terminator.rule.css
                  pop: true
                - include: property-values
                - match: '{{ident}}(\s+{{ident}})*'
                  scope: string.unquoted.css
                - match: ','
                  scope: punctuation.separator.css
            - match: ''
              pop: true
        # Property names are sorted by popularity in descending order.
        # Popularity data taken from https://www.chromestatus.com/metrics/css/popularity
        - match: |-
            \b(?x)(
                display|width|background-color|height|position|font-family|font-weight
              | top|opacity|cursor|background-image|right|visibility|box-sizing
              | user-select|left|float|margin-left|margin-top|line-height
              | padding-left|z-index|margin-bottom|margin-right|margin
              | vertical-align|padding-top|white-space|border-radius|padding-bottom
              | padding-right|padding|bottom|clear|max-width|box-shadow|content
              | border-color|min-height|min-width|font-style|border-width
              | border-collapse|background-size|text-overflow|max-height|text-transform
              | text-shadow|text-indent|border-style|overflow-y|list-style-type
              | word-wrap|border-spacing|appearance|zoom|overflow-x|border-top-left-radius
              | border-bottom-left-radius|border-top-color|pointer-events
              | border-bottom-color|align-items|justify-content|letter-spacing
              | border-top-right-radius|border-bottom-right-radius|border-right-width
              | font-smoothing|border-bottom-width|border-right-color|direction
              | border-top-width|src|border-left-color|border-left-width
              | tap-highlight-color|table-layout|background-clip|word-break
              | transform-origin|resize|filter|backface-visibility|text-rendering
              | box-orient|transition-property|transition-duration|word-spacing
              | quotes|outline-offset|animation-timing-function|animation-duration
              | animation-name|transition-timing-function|border-bottom-style
              | border-bottom|transition-delay|transition|unicode-bidi|border-top-style
              | border-top|unicode-range|list-style-position|orphans|outline-width
              | line-clamp|order|flex-direction|box-pack|animation-fill-mode
              | outline-color|list-style-image|list-style|touch-action|flex-grow
              | border-left-style|border-left|animation-iteration-count
              | page-break-inside|box-flex|box-align|page-break-after|animation-delay
              | widows|border-right-style|border-right|flex-align|outline-style
              | outline|background-origin|animation-direction|fill-opacity
              | background-attachment|flex-wrap|transform-style|counter-increment
              | overflow-wrap|counter-reset|animation-play-state|animation
              | will-change|box-ordinal-group|image-rendering|mask-image|flex-flow
              | background-position-y|stroke-width|background-position-x|background-position
              | background-blend-mode|flex-shrink|flex-basis|flex-order|flex-item-align
              | flex-line-pack|flex-negative|flex-pack|flex-positive|flex-preferred-size
              | flex|user-drag|font-stretch|column-count|empty-cells|align-self
              | caption-side|mask-size|column-gap|mask-repeat|box-direction
              | font-feature-settings|mask-position|align-content|object-fit
              | columns|text-fill-color|clip-path|stop-color|font-kerning
              | page-break-before|stroke-dasharray|size|fill-rule|border-image-slice
              | column-width|break-inside|column-break-before|border-image-width
              | stroke-dashoffset|border-image-repeat|border-image-outset|line-break
              | stroke-linejoin|stroke-linecap|stroke-miterlimit|stroke-opacity
              | stroke|shape-rendering|border-image-source|border-image|border
              | tab-size|writing-mode|perspective-origin-y|perspective-origin-x
              | perspective-origin|perspective|text-align-last|text-align|clip-rule
              | clip|text-anchor|column-rule-color|box-decoration-break|column-fill
              | fill|column-rule-style|mix-blend-mode|text-emphasis-color
              | baseline-shift|dominant-baseline|page|alignment-baseline
              | column-rule-width|column-rule|break-after|font-variant-ligatures
              | transform-origin-y|transform-origin-x|transform|object-position
              | break-before|column-span|isolation|shape-outside|all
              | color-interpolation-filters|marker|marker-end|marker-start
              | marker-mid|color-rendering|color-interpolation|background-repeat-x
              | background-repeat-y|background-repeat|background|mask-type
              | flood-color|flood-opacity|text-orientation|mask-composite
              | text-emphasis-style|paint-order|lighting-color|shape-margin
              | text-emphasis-position|text-emphasis|shape-image-threshold
              | mask-clip|mask-origin|mask|font-variant-caps|font-variant-alternates
              | font-variant-east-asian|font-variant-numeric|font-variant-position
              | font-variant|font-size-adjust|font-size|font-language-override
              | font-display|font-synthesis|font|line-box-contain|text-justify
              | text-decoration-color|text-decoration-style|text-decoration-line
              | text-decoration|text-underline-position|grid-template-rows
              | grid-template-columns|grid-template-areas|grid-template|rotate|scale
              | translate|scroll-behavior|grid-column-start|grid-column-end
              | grid-column-gap|grid-row-start|grid-row-end|grid-auto-rows
              | grid-area|grid-auto-flow|grid-auto-columns|image-orientation
              | hyphens|overflow-scrolling|overflow|color-profile|kerning
              | nbsp-mode|color|image-resolution|grid-row-gap|grid-row|grid-column
              | blend-mode|azimuth|pause-after|pause-before|pause|pitch-range|pitch
              | text-height|system|negative|prefix|suffix|range|pad|fallback
              | additive-symbols|symbols|speak-as|speak|grid-gap
            )\b
          scope: support.type.property-name.css
    - match: (:)([ \t]*)
      captures:
        1: punctuation.separator.key-value.css
        2: meta.property-value.css
      push:
        - meta_content_scope: meta.property-value.css
        - match: '\s*(;)|(?=[})])'
          captures:
            1: punctuation.terminator.rule.css
          pop: true
        - include: property-values

  selector:
    - match: '\s*(?=[:.*#a-zA-Z\[])'
      push:
        - meta_scope: meta.selector.css
        - match: "(?=[/@{)])"
          pop: true
          # Custom Elements: http://w3c.github.io/webcomponents/spec/custom/#custom-elements-core-concepts
        - match: '\b([a-z](?:{{custom_element_chars}})*-(?:{{custom_element_chars}})*)\b'
          scope: entity.name.tag.custom.css
        - match: '\b(a|abbr|acronym|address|applet|area|article|aside|audio|b|base|basefont|bdi|bdo|big|blockquote|body|br|button|canvas|caption|cite|code|col|colgroup|content|data|datalist|dd|del|details|dfn|dir|dialog|div|dl|dt|element|em|embed|eventsource|fieldset|figure|figcaption|footer|form|frame|frameset|h[1-6]|head|header|hgroup|hr|html|i|iframe|img|input|ins|isindex|kbd|keygen|label|legend|li|link|main|map|mark|menu|meta|meter|nav|noframes|noscript|object|ol|optgroup|option|output|p|param|picture|pre|progress|q|rp|rt|rtc|s|samp|script|section|select|shadow|small|source|span|strike|strong|style|sub|summary|sup|svg|table|tbody|td|template|textarea|tfoot|th|thead|time|title|tr|track|tt|u|ul|var|video|wbr|xmp|circle|clipPath|defs|ellipse|filter|foreignObject|g|glyph|glyphRef|image|line|linearGradient|marker|mask|path|pattern|polygon|polyline|radialGradient|rect|stop|switch|symbol|text|textPath|tref|tspan|use)\b'
          scope: entity.name.tag.css
          # https://drafts.csswg.org/selectors-4/#class-html
        - match: '(\.){{ident}}'
          scope: entity.other.attribute-name.class.css
          captures:
            1: punctuation.definition.entity.css
          # https://drafts.csswg.org/selectors-4/#id-selectors
        - match: "(#){{ident}}"
          scope: entity.other.attribute-name.id.css
          captures:
            1: punctuation.definition.entity.css
        - match: \*
          scope: entity.name.tag.wildcard.css
          # Combinators
          # https://drafts.csswg.org/selectors-4/#combinators
          # https://drafts.csswg.org/css-scoping/#deep-combinator
        - match: '({{combinators}})(?![>~+])'
          scope: punctuation.separator.combinator.css
        - match: '({{combinators}}){2,}'
          scope: invalid.illegal.combinator.css
        - include: pseudo-elements
        - include: pseudo-classes # pseudo-classes must be included after pseudo-elements
        # Attribute Selectors
        # https://drafts.csswg.org/selectors-4/#attribute-selectors
        - match: '\['
          scope: punctuation.definition.entity.css
          push:
            - meta_scope: meta.attribute-selector.css
            - include: qualified-name
            - match: '({{ident}})'
              scope: entity.other.attribute-name.css
            - match: '\s*([~*|^$]?=)\s*'
              captures:
                1: keyword.operator.attribute-selector.css
              push:
                - match: '[^\s\]\[''"]'
                  scope: string.unquoted.css
                - include: literal-string
                - match: '(?=(\s|\]))'
                  pop: true
            - match: '(?:\s+([iI]))?'  # case insensitive flag
              captures:
                1: keyword.other.css
            - match: '\]'
              scope: punctuation.definition.entity.css
              pop: true

  # Pseudo Elements
  # https://drafts.csswg.org/selectors-4/#pseudo-elements
  pseudo-elements:
    - match: |-
        (?x:
            (:{1,2})(?:before|after|first-line|first-letter) # CSS1 & CSS2 require : or ::
          | (::)(-(?:moz|ms|webkit)-)?(?:{{ident}}) # CSS3 requires ::
        )\b
      scope: entity.other.pseudo-element.css
      captures:
        1: punctuation.definition.entity.css
        2: punctuation.definition.entity.css
        3: support.type.vendor-prefix.css

  # Pseudo Classes
  # https://drafts.csswg.org/selectors-4/#pseudo-classes
  pseudo-classes:
      # Functional Pseudo Classes
      # https://drafts.csswg.org/selectors-4/#functional-pseudo-class

      # Functional Pseudo Classes with a single unquoted string
    - match: '(:)(dir|lang)(?=\()'
      scope: entity.other.pseudo-class.css
      captures:
        1: punctuation.definition.entity.css
      push:
        - meta_scope: meta.function-call.css
        - include: function-notation-terminator
        - match: '\('
          scope: punctuation.definition.group.begin.css
          push:
          - meta_scope: meta.group.css
          - match: '(?=\))'
            pop: true
          - include: unquoted-string

      # Functional Pseudo Classes with selector list
    - match: '(:)(matches|not|has)(?=\()'
      scope: entity.other.pseudo-class.css
      captures:
        1: punctuation.definition.entity.css
      push:
        - meta_scope: meta.function-call.css
        - include: function-notation-terminator
        - match: '\('
          scope: punctuation.definition.group.begin.css
          push:
          - meta_scope: meta.group.css
          - match: '(?=\))'
            pop: true
          - include: selector

      # Special :drop() pseudo-class
    - match: '(:)(drop)(?=\()'
      scope: entity.other.pseudo-class.css
      captures:
        1: punctuation.definition.entity.css
      push:
        - meta_scope: meta.function-call.css
        - include: function-notation-terminator
        - match: '\('
          scope: punctuation.definition.group.begin.css
          push:
          - meta_scope: meta.group.css
          - match: '(?=\))'
            pop: true
          - match: \b(active|valid|invalid)\b
            scope: keyword.other.pseudo-class.css

      # Functional Pseudo Classes with `An+B` param
      # An+B Notation: https://drafts.csswg.org/css-syntax/#anb
      # nth-last-child(), nth-child(), nth-last-of-type(), nth-of-type()
    - match: '(:)(nth-last-child|nth-child|nth-last-of-type|nth-of-type)(?=\()'
      scope: entity.other.pseudo-class.css
      captures:
        1: punctuation.definition.entity.css
      push:
        - meta_scope: meta.function-call.css
        - include: function-notation-terminator
        - match: '\('
          scope: punctuation.definition.group.begin.css
          push:
          - meta_scope: meta.group.css
          - match: '(?=\))'
            pop: true
          - match: \b(even|odd)\b
            scope: keyword.other.pseudo-class.css
          - match: '(?:[-+]?(?:\d+)?(n)(\s*[-+]\s*\d+)?|[-+]?\s*\d+)'
            scope: constant.numeric.css
            captures:
              1: keyword.other.unit.css

      # Regular Pseudo Classes
    - match: '(:)({{ident}})'
      scope: entity.other.pseudo-class.css
      captures:
        1: punctuation.definition.entity.css

  builtin-functions:
    - include: attr-function
    - include: calc-function
    - include: cross-fade-function
    - include: filter-functions
    - include: gradient-functions
    - include: image-function
    - include: image-set-function
    - include: minmax-function
    - include: url-function
    - include: var-function
    - include: color-adjuster-functions

      # filter()
      # https://drafts.fxtf.org/filters/#funcdef-filter
    - match: '\b(filter)(?=\()'
      scope: support.function.filter.css
      push:
        - meta_scope: meta.function-call.css
        - include: function-notation-terminator
        - match: '\('
          scope: punctuation.definition.group.begin.css
          push:
          - meta_scope: meta.group.css
          - match: '(?=\))'
            pop: true
          - include: comma-delimiter
          - include: image-type
          - include: literal-string
          - include: filter-functions

      # counter()
      # https://drafts.csswg.org/css-lists-3/#funcdef-counter
    - match: '\b(counter)(?=\()'
      scope: support.function.counter.css
      push:
        - meta_scope: meta.function-call.css
        - include: function-notation-terminator
        - match: '\('
          scope: punctuation.definition.group.begin.css
          push:
          - meta_scope: meta.group.css
          - match: '(?=\))'
            pop: true
          - match: '({{ident}})'
            scope: entity.other.counter-name.css string.unquoted.css
          - match: '(?=,)'
            push:
              - match: '(?=\))'
                pop: true
              - include: comma-delimiter
              - match: '\b({{counter_styles}}|none)\b'
                scope: support.constant.property-value.counter-style.css

      # counters()
      # https://drafts.csswg.org/css-lists-3/#funcdef-counters
    - match: '\b(counters)(?=\()'
      scope: support.function.counter.css
      push:
        - meta_scope: meta.function-call.css
        - include: function-notation-terminator
        - match: '\('
          scope: punctuation.definition.group.begin.css
          push:
          - meta_scope: meta.group.css
          - match: '(?=\))'
            pop: true
          - match: '({{ident}})'
            scope: entity.other.counter-name.css string.unquoted.css
          - match: '(?=,)'
            push:
              - match: '(?=\))'
                pop: true
              - include: comma-delimiter
              - include: literal-string
              - match: '\b({{counter_styles}}|none)\b'
                scope: support.constant.property-value.counter-style.css

      # symbols()
      # https://drafts.csswg.org/css-counter-styles-3/#symbols-function
    - match: '\b(symbols)(?=\()'
      scope: support.function.counter.css
      push:
        - meta_scope: meta.function-call.css
        - include: function-notation-terminator
        - match: '\('
          scope: punctuation.definition.group.begin.css
          push:
          - meta_scope: meta.group.css
          - match: '(?=\))'
            pop: true
          - match: '\b(cyclic|numeric|alphabetic|symbolic|fixed)\b'
            scope: support.constant.symbol-type.css
          - include: comma-delimiter
          - include: literal-string
          - include: image-type

      # format()
      # https://drafts.csswg.org/css-fonts-3/#descdef-src
      # format() is also mentioned in `issue 2` at https://drafts.csswg.org/css-images-3/#issues-index
      # but does not seem to be implemented in any manner
    - match: '\b(format)(?=\()'
      scope: support.function.font-face.css
      push:
        - meta_scope: meta.function-call.css
        - include: function-notation-terminator
        - match: '\('
          scope: punctuation.definition.group.begin.css
          push:
          - meta_scope: meta.group.css
          - match: '(?=\))'
            pop: true
          - include: literal-string

      # local()
      # https://drafts.csswg.org/css-fonts-3/#descdef-src
    - match: '\b(local)(?=\()'
      scope: support.function.font-face.css
      push:
        - meta_scope: meta.function-call.css
        - include: function-notation-terminator
        - match: '\('
          scope: punctuation.definition.group.begin.css
          push:
          - meta_scope: meta.group.css
          - match: '(?=\))'
            pop: true
          - include: unquoted-string

      # Transform Functions
      # https://www.w3.org/TR/css-transforms-1/#transform-functions

      # transform functions with comma separated <number> types
      # matrix(), scale(), matrix3d(), scale3d()
    - match: '\b(matrix3d|scale3d|matrix|scale)(?=\()'
      scope: support.function.transform.css
      push:
        - meta_scope: meta.function-call.css
        - include: function-notation-terminator
        - match: '\('
          scope: punctuation.definition.group.begin.css
          push:
          - meta_scope: meta.group.css
          - match: '(?=\))'
            pop: true
          - include: comma-delimiter
          - include: number-type
          - include: var-function

      # transform functions with comma separated <number> or <length> types
      # translate(), translate3d()
    - match: '\b(translate(3d)?)(?=\()'
      scope: support.function.transform.css
      push:
        - meta_scope: meta.function-call.css
        - include: function-notation-terminator
        - match: '\('
          scope: punctuation.definition.group.begin.css
          push:
          - meta_scope: meta.group.css
          - match: '(?=\))'
            pop: true
          - include: comma-delimiter
          - include: percentage-type
          - include: length-type
          - include: number-type
          - include: var-function

      # transform functions with a single <number> or <length> type
      # translateX(), translateY()
    - match: '\b(translate[XY])(?=\()'
      scope: support.function.transform.css
      push:
        - meta_scope: meta.function-call.css
        - include: function-notation-terminator
        - match: '\('
          scope: punctuation.definition.group.begin.css
          push:
          - meta_scope: meta.group.css
          - match: '(?=\))'
            pop: true
          - include: percentage-type
          - include: length-type
          - include: number-type

      # transform functions with a single <angle> type
      # rotate(), skewX(), skewY(), rotateX(), rotateY(), rotateZ()
    - match: '\b(rotate[XYZ]?|skew[XY])(?=\()'
      scope: support.function.transform.css
      push:
        - meta_scope: meta.function-call.css
        - include: function-notation-terminator
        - match: '\('
          scope: punctuation.definition.group.begin.css
          push:
          - meta_scope: meta.group.css
          - match: '(?=\))'
            pop: true
          - include: angle-type

      # transform functions with comma separated <angle> types
      # skew()
    - match: '\b(skew)(?=\()'
      scope: support.function.transform.css
      push:
        - meta_scope: meta.function-call.css
        - include: function-notation-terminator
        - match: '\('
          scope: punctuation.definition.group.begin.css
          push:
          - meta_scope: meta.group.css
          - match: '(?=\))'
            pop: true
          - include: comma-delimiter
          - include: angle-type

      # transform functions with a single <length> type
      # translateZ(), perspective()
    - match: '\b(translateZ|perspective)(?=\()'
      scope: support.function.transform.css
      push:
        - meta_scope: meta.function-call.css
        - include: function-notation-terminator
        - match: '\('
          scope: punctuation.definition.group.begin.css
          push:
          - meta_scope: meta.group.css
          - match: '(?=\))'
            pop: true
          - include: length-type

      # transform functions with a comma separated <number> or <angle> types
      # rotate3d()
    - match: '\b(rotate3d)(?=\()'
      scope: support.function.transform.css
      push:
        - meta_scope: meta.function-call.css
        - include: function-notation-terminator
        - match: '\('
          scope: punctuation.definition.group.begin.css
          push:
          - meta_scope: meta.group.css
          - match: '(?=\))'
            pop: true
          - include: comma-delimiter
          - include: angle-type
          - include: number-type

      # transform functions with a single <number> type
      # scaleX(), scaleY(), scaleZ()
    - match: '\b(scale[XYZ])(?=\()'
      scope: support.function.transform.css
      push:
        - meta_scope: meta.function-call.css
        - include: function-notation-terminator
        - match: '\('
          scope: punctuation.definition.group.begin.css
          push:
          - meta_scope: meta.group.css
          - match: '(?=\))'
            pop: true
          - include: comma-delimiter
          - include: number-type

      # Timing Functions
      # https://www.w3.org/TR/web-animations-1/#timing-functions

      # cubic-bezier()
      # https://www.w3.org/TR/web-animations-1/#cubic-bzier-timing-function
    - match: '\b(cubic-bezier)(?=\()'
      scope: support.function.timing.css
      push:
        - meta_scope: meta.function-call.css
        - include: function-notation-terminator
        - match: '\('
          scope: punctuation.definition.group.begin.css
          push:
          - meta_scope: meta.group.css
          - match: '(?=\))'
            pop: true
          - include: comma-delimiter
          - include: number-type

      # steps()
      # https://www.w3.org/TR/web-animations-1/#step-timing-function
    - match: '\b(steps)(?=\()'
      scope: support.function.timing.css
      push:
        - meta_scope: meta.function-call.css
        - include: function-notation-terminator
        - match: '\('
          scope: punctuation.definition.group.begin.css
          push:
          - meta_scope: meta.group.css
          - match: '(?=\))'
            pop: true
          - include: comma-delimiter
          - include: integer-type
          - match: (end|middle|start)
            scope: support.keyword.timing-direction.css

      # Shape Functions
      # https://www.w3.org/TR/css-shapes-1/#typedef-basic-shape

      # rect() - Deprecated
      # https://drafts.fxtf.org/css-masking-1/#funcdef-clip-rect
    - match: '\b(rect)(?=\()'
      scope: support.function.shape.css
      push:
        - meta_scope: meta.function-call.css
        - include: function-notation-terminator
        - match: '\('
          scope: punctuation.definition.group.begin.css
          push:
          - meta_scope: meta.group.css
          - match: '(?=\))'
            pop: true
          - match: \bauto\b
            scope: support.constant.property-value.css
          - include: length-type

      # inset()
      # https://www.w3.org/TR/css-shapes-1/#funcdef-inset
    - match: '\b(inset)(?=\()'
      scope: support.function.shape.css
      push:
        - meta_scope: meta.function-call.css
        - include: function-notation-terminator
        - match: '\('
          scope: punctuation.definition.group.begin.css
          push:
          - meta_scope: meta.group.css
          - match: '(?=\))'
            pop: true
          - match: '\bround\b'
            scope: keyword.other.css
          - include: length-type
          - include: percentage-type

      # circle()
      # https://www.w3.org/TR/css-shapes-1/#funcdef-circle
      # ellipse()
      # https://www.w3.org/TR/css-shapes-1/#funcdef-ellipse
    - match: '\b(circle|ellipse)(?=\()'
      scope: support.function.shape.css
      push:
        - meta_scope: meta.function-call.css
        - include: function-notation-terminator
        - match: '\('
          scope: punctuation.definition.group.begin.css
          push:
          - meta_scope: meta.group.css
          - match: '(?=\))'
            pop: true
          - match: '\bat\b'
            scope: keyword.other.css
          - match: '\b(top|right|bottom|left|center|closest-side|farthest-side)\b'
            scope: support.constant.property-value.css
          - include: length-type
          - include: percentage-type

      # polygon()
      # https://www.w3.org/TR/css-shapes-1/#funcdef-polygon
    - match: '\b(polygon)(?=\()'
      scope: support.function.shape.css
      push:
        - meta_scope: meta.function-call.css
        - include: function-notation-terminator
        - match: '\('
          scope: punctuation.definition.group.begin.css
          push:
          - meta_scope: meta.group.css
          - match: '(?=\))'
            pop: true
          - match: '\b(nonzero|evenodd)\b'
            scope: support.constant.property-value.css
          - include: length-type
          - include: percentage-type

      # toggle()
      # https://www.w3.org/TR/css3-values/#toggle-notation
    - match: '\b(toggle)(?=\()'
      scope: support.function.toggle.css
      push:
        - meta_scope: meta.function-call.css
        - include: function-notation-terminator
        - match: '\('
          scope: punctuation.definition.group.begin.css
          push:
          - meta_scope: meta.group.css
          - match: '(?=\))'
            pop: true
          - include: comma-delimiter
          - include: vendor-prefix
          - include: property-value-constants
          - include: numeric-values
          - include: color-values
          - include: literal-string

      # repeat()
      # https://drafts.csswg.org/css-grid/#funcdef-repeat
    - match: '\b(repeat)(?=\()'
      scope: support.function.grid.css
      push:
        - meta_scope: meta.function-call.css
        - include: function-notation-terminator
        - match: '\('
          scope: punctuation.definition.group.begin.css
          push:
          - meta_scope: meta.group.css
          - match: '(?=\))'
            pop: true
          - include: comma-delimiter
          - include: length-type
          - include: percentage-type
          - include: minmax-function
          - include: integer-type
          - include: var-function
          - match: \b(auto-fill|auto-fit)\b
            scope: support.keyword.repetitions.css
          - match: \b(max-content|min-content|auto)\b
            scope: support.constant.property-value.css

  # var()
  # https://drafts.csswg.org/css-variables/#funcdef-var
  var-function:
    - match: '\b(var)(?=\()'
      scope: support.function.var.css
      push:
        - meta_scope: meta.function-call.css
        - include: function-notation-terminator
        - match: '\('
          scope: punctuation.definition.group.begin.css
          push:
          - meta_scope: meta.group.css
          - match: '(?=\))'
            pop: true
          - include: comma-delimiter
          - include: custom-property-name

  # Filter Functions
  # https://drafts.fxtf.org/filters/#typedef-filter-function
  filter-functions:
      # blur()
      # https://drafts.fxtf.org/filters/#funcdef-filter-blur
    - match: '\b(blur)(?=\()'
      scope: support.function.filter.css
      push:
        - meta_scope: meta.function-call.css
        - include: function-notation-terminator
        - match: '\('
          scope: punctuation.definition.group.begin.css
          push:
          - meta_scope: meta.group.css
          - match: '(?=\))'
            pop: true
          - include: length-type

      # brightness(), contrast(), grayscale(), invert(), opacity(), saturate(), sepia()
      # https://drafts.fxtf.org/filters/#funcdef-filter-brightness
    - match: '\b(brightness|contrast|grayscale|invert|opacity|saturate|sepia)(?=\()'
      scope: support.function.filter.css
      push:
        - meta_scope: meta.function-call.css
        - include: function-notation-terminator
        - match: '\('
          scope: punctuation.definition.group.begin.css
          push:
          - meta_scope: meta.group.css
          - match: '(?=\))'
            pop: true
          - include: percentage-type
          - include: number-type

      # drop-shadow()
      # https://drafts.fxtf.org/filters/#funcdef-filter-drop-shadow
    - match: '\b(drop-shadow)(?=\()'
      scope: support.function.filter.css
      push:
        - meta_scope: meta.function-call.css
        - include: function-notation-terminator
        - match: '\('
          scope: punctuation.definition.group.begin.css
          push:
          - meta_scope: meta.group.css
          - match: '(?=\))'
            pop: true
          - include: length-type
          - include: color-values

      # hue-rotate()
      # https://drafts.fxtf.org/filters/#funcdef-filter-hue-rotate
    - match: '\b(hue-rotate)(?=\()'
      scope: support.function.filter.css
      push:
        - meta_scope: meta.function-call.css
        - include: function-notation-terminator
        - match: '\('
          scope: punctuation.definition.group.begin.css
          push:
          - meta_scope: meta.group.css
          - match: '(?=\))'
            pop: true
          - include: angle-type

  # calc()
  # https://www.w3.org/TR/css3-values/#funcdef-calc
  calc-function:
    - match: '\b(calc)(?=\()'
      scope: support.function.calc.css
      push:
        - meta_scope: meta.function-call.css
        - match: '\('
          scope: punctuation.definition.group.begin.css
          push: inside-calc-parens
        - match: ''
          pop: true

  inside-calc-parens:
    - meta_scope: meta.group.css
    - match: '(?=\))'
      set: function-notation-terminator
    - include: calc-function
    - include: var-function
    - include: numeric-values
    - include: attr-function
    - match: "[-/*+]"
      scope: keyword.operator.css
    - match: '\('
      scope: punctuation.definition.group.begin.css
      push: inside-calc-parens

  # attr()
  # https://www.w3.org/TR/css3-values/#funcdef-attr
  attr-function:
    - match: '\b(attr)(?=\()'
      scope: support.function.attr.css
      push:
        - meta_scope: meta.function-call.css
        - include: function-notation-terminator
        - match: '\('
          scope: punctuation.definition.group.begin.css
          push:
          - meta_scope: meta.group.css
          - match: '(?=\))'
            pop: true
          - include: qualified-name
          - include: literal-string
          - match: '({{ident}})'
            scope: entity.other.attribute-name.css
            push:
            - match: |-
                (?x)\b(
                    {{font_relative_lengths}}
                  | {{viewport_percentage_lengths}}
                  | {{absolute_lengths}}
                  | {{angle_units}}
                  | {{duration_units}}
                  | {{frequency_units}}
                  | {{resolution_units}}
                )\b
              scope: keyword.other.unit.css
            - match: '(?=\))'
              pop: true
            - include: comma-delimiter
            - include: property-value-constants
            - include: numeric-values
            - include: color-values

  # url()
  # https://drafts.csswg.org/css-images-3/#url-notation
  url-function:
    - match: '\b(url)(?=\()'
      scope: support.function.url.css
      push:
        - meta_scope: meta.function-call.css
        - include: function-notation-terminator
        - match: '\('
          scope: punctuation.definition.group.begin.css
          push:
          - meta_scope: meta.group.css
          - match: '(?=\))'
            pop: true
          - include: literal-string
          - include: unquoted-string

  # url-prefix()
  # https://www.w3.org/TR/2012/WD-css3-conditional-20120911/#url-prefix
  url-prefix-function:
    - match: '\b(url-prefix)(?=\()'
      scope: support.function.url-prefix.css
      push:
        - meta_scope: meta.function-call.css
        - include: function-notation-terminator
        - match: '\('
          scope: punctuation.definition.group.begin.css
          push:
          - meta_scope: meta.group.css
          - match: '(?=\))'
            pop: true
          - include: literal-string
          - include: unquoted-string

  # domain()
  # https://www.w3.org/TR/2012/WD-css3-conditional-20120911/#url-domain
  domain-function:
    - match: '\b(domain)(?=\()'
      scope: support.function.domain.css
      push:
        - meta_scope: meta.function-call.css
        - include: function-notation-terminator
        - match: '\('
          scope: punctuation.definition.group.begin.css
          push:
          - meta_scope: meta.group.css
          - match: '(?=\))'
            pop: true
          - include: literal-string
          - include: unquoted-string

  # regexp()
  # https://www.w3.org/TR/2012/WD-css3-conditional-20120911/#url-regexp
  regexp-function:
    - match: '\b(regexp)(?=\()'
      scope: support.function.regexp.css
      push:
        - meta_scope: meta.function-call.css
        - include: function-notation-terminator
        - match: '\('
          scope: punctuation.definition.group.begin.css
          push:
          - meta_scope: meta.group.css
          - match: '(?=\))'
            pop: true
          - include: literal-string

  # image()
  # https://drafts.csswg.org/css-images-3/#funcdef-image
  image-function:
    - match: '\b(image)(?=\()'
      scope: support.function.image.css
      push:
        - meta_scope: meta.function-call.css
        - include: function-notation-terminator
        - match: '\('
          scope: punctuation.definition.group.begin.css
          push:
          - meta_scope: meta.group.css
          - match: '(?=\))'
            pop: true
          - include: image-type
          - include: literal-string
          - include: color-values
          - include: comma-delimiter
          - include: unquoted-string

  # image-set()
  # https://drafts.csswg.org/css-images-3/#funcdef-image-set
  image-set-function:
    - match: '\b(image-set)(?=\()'
      scope: support.function.image.css
      push:
        - meta_scope: meta.function-call.css
        - include: function-notation-terminator
        - match: '\('
          scope: punctuation.definition.group.begin.css
          push:
          - meta_scope: meta.group.css
          - match: '(?=\))'
            pop: true
          - include: literal-string
          - include: color-values
          - include: comma-delimiter
          - include: resolution-type
          - include: image-type
          - match: '[0-9]+(x)'
            scope: constant.numeric.css
            captures:
              1: keyword.other.unit.css
          - include: unquoted-string

  # Gradient Functions
  # https://drafts.csswg.org/css-images-3/#gradients
  gradient-functions:
      # linear-gradient()
      # https://drafts.csswg.org/css-images-3/#linear-gradients
      # repeating-linear-gradient()
      # https://drafts.csswg.org/css-images-3/#funcdef-repeating-linear-gradient
    - match: '\b((?:repeating-)?linear-gradient)(?=\()'
      scope: support.function.gradient.css
      push:
        - meta_scope: meta.function-call.css
        - include: function-notation-terminator
        - match: '\('
          scope: punctuation.definition.group.begin.css
          push:
          - meta_scope: meta.group.css
          - match: '(?=\))'
            pop: true
          - include: angle-type
          - include: comma-delimiter
          - include: color-values
          - include: percentage-type
          - include: length-type
          - match: '\bto\b'
            scope: keyword.other.css
          - match: \b(top|right|bottom|left)\b
            scope: support.constant.property-value.css

      # radial-gradient()
      # https://drafts.csswg.org/css-images-3/#radial-gradients
      # repeating-radial-gradient()
      # https://drafts.csswg.org/css-images-3/#funcdef-repeating-radial-gradient
    - match: '\b((?:repeating-)?radial-gradient)(?=\()'
      scope: support.function.gradient.css
      push:
        - meta_scope: meta.function-call.css
        - include: function-notation-terminator
        - match: '\('
          scope: punctuation.definition.group.begin.css
          push:
          - meta_scope: meta.group.css
          - match: '(?=\))'
            pop: true
          - include: comma-delimiter
          - include: color-values
          - include: percentage-type
          - include: length-type
          - match: '\b(at|circle|ellipse)\b'
            scope: keyword.other.css
          - match: |-
              (?x)\b(
                  left
                | center
                | right
                | top
                | bottom
                | closest-corner
                | closest-side
                | farthest-corner
                | farthest-side
              )\b
            scope: support.constant.property-value.css

  # cross-fade()
  # https://drafts.csswg.org/css-images-3/#cross-fade-function
  cross-fade-function:
    - match: '\b(cross-fade)(?=\()'
      scope: support.function.image.css
      push:
        - meta_scope: meta.function-call.css
        - include: function-notation-terminator
        - match: '\('
          scope: punctuation.definition.group.begin.css
          push:
          - meta_scope: meta.group.css
          - match: '(?=\))'
            pop: true
          - include: comma-delimiter
          - include: percentage-type
          - include: color-values
          - include: image-type
          - include: literal-string
          - include: unquoted-string

  # minmax()
  # https://drafts.csswg.org/css-grid/#valdef-grid-template-columns-minmax
  minmax-function:
    - match: '\b(minmax)(?=\()'
      scope: support.function.grid.css
      push:
        - meta_scope: meta.function-call.css
        - include: function-notation-terminator
        - match: '\('
          scope: punctuation.definition.group.begin.css
          push:
          - meta_scope: meta.group.css
          - match: '(?=\))'
            pop: true
          - include: comma-delimiter
          - include: length-type
          - match: \b(max-content|min-content)\b
            scope: support.constant.property-value.css

  # Color Functions
  # https://drafts.csswg.org/css-color
  color-functions:
      # rgb(), rgba()
      # https://drafts.csswg.org/css-color/#rgb-functions
    - match: '\b(rgba?)(?=\()'
      scope: support.function.color.css
      push:
        - meta_scope: meta.function-call.css
        - include: function-notation-terminator
        - match: '\('
          scope: punctuation.definition.group.begin.css
          push:
          - meta_scope: meta.group.css
          - match: '(?=\))'
            pop: true
          - include: comma-delimiter
          - include: percentage-type
          - include: number-type

      # hsl(), hsla()
      # https://drafts.csswg.org/css-color/#the-hsl-notation
      # hwb() - Not yet implemented by browsers
      # https://drafts.csswg.org/css-color/#funcdef-hwb
    - match: '\b(hsla?|hwb)(?=\()'
      scope: support.function.color.css
      push:
        - meta_scope: meta.function-call.css
        - include: function-notation-terminator
        - match: '\('
          scope: punctuation.definition.group.begin.css
          push:
          - meta_scope: meta.group.css
          - match: '(?=\))'
            pop: true
          - include: comma-delimiter
          - include: angle-type
          - include: percentage-type
          - include: number-type

      # gray() - Not yet implemented by browsers
      # https://drafts.csswg.org/css-color/#funcdef-gray
    - match: '\b(gray)(?=\()'
      scope: support.function.color.css
      push:
        - meta_scope: meta.function-call.css
        - include: function-notation-terminator
        - match: '\('
          scope: punctuation.definition.group.begin.css
          push:
          - meta_scope: meta.group.css
          - match: '(?=\))'
            pop: true
          - include: comma-delimiter
          - include: percentage-type
          - include: number-type

      # device-cmyk() - Not yet implemented by browsers
      # https://drafts.csswg.org/css-color/#funcdef-device-cmyk
    - match: '\b(device-cmyk)(?=\()'
      scope: support.function.color.css
      push:
        - meta_scope: meta.function-call.css
        - include: function-notation-terminator
        - match: '\('
          scope: punctuation.definition.group.begin.css
          push:
          - meta_scope: meta.group.css
          - match: '(?=\))'
            pop: true
          - include: comma-delimiter
          - include: color-adjuster-functions # must be included before `color-values`
          - include: color-values
          - include: percentage-type
          - include: number-type

      # color-mod() - Not yet implemented by browsers
      # https://drafts.csswg.org/css-color/#funcdef-color-mod
    - match: '\b(color)(?=\()'
      scope: support.function.color.css
      push:
        - meta_scope: meta.function-call.css
        - include: function-notation-terminator
        - match: '\('
          scope: punctuation.definition.group.begin.css
          push:
          - meta_scope: meta.group.css
          - match: '(?=\))'
            pop: true
          - include: comma-delimiter
          - include: color-adjuster-functions # must be included before `color-values`
          - include: var-function
          - include: color-values
          - include: angle-type
          - include: number-type

  # Color Adjuster Functions - Not yet implemented by browsers
  # https://drafts.csswg.org/css-color/#typedef-color-adjuster
  color-adjuster-functions:
      # red(), green(), blue(), alpha() - Not yet implemented by browsers
    - match: '\b(red|green|blue|alpha|a)(?=\()'
      scope: support.function.color.css
      push:
        - meta_scope: meta.function-call.css
        - include: function-notation-terminator
        - match: '\('
          scope: punctuation.definition.group.begin.css
          push:
          - meta_scope: meta.group.css
          - match: '(?=\))'
            pop: true
          - include: color-adjuster-operators
          - include: percentage-type
          - include: number-type

      # hue() - Not yet implemented by browsers
    - match: '\b(hue|h)(?=\()'
      scope: support.function.color.css
      push:
        - meta_scope: meta.function-call.css
        - include: function-notation-terminator
        - match: '\('
          scope: punctuation.definition.group.begin.css
          push:
          - meta_scope: meta.group.css
          - match: '(?=\))'
            pop: true
          - include: color-adjuster-operators
          - include: angle-type

      # saturation(), lightness(), whiteness(), blackness() - Not yet implemented by browsers
    - match: '\b(saturation|lightness|whiteness|blackness|[slwb])(?=\()'
      scope: support.function.color.css
      push:
        - meta_scope: meta.function-call.css
        - include: function-notation-terminator
        - match: '\('
          scope: punctuation.definition.group.begin.css
          push:
          - meta_scope: meta.group.css
          - match: '(?=\))'
            pop: true
          - include: color-adjuster-operators
          - include: percentage-type

      # tint(), shade(), contrast() - Not yet implemented by browsers
      # contrast() interferes with the contrast() filter function;
      # therefore, it is not yet implemented here
    - match: '\b(tint|shade)(?=\()'
      scope: support.function.color.css
      push:
        - meta_scope: meta.function-call.css
        - include: function-notation-terminator
        - match: '\('
          scope: punctuation.definition.group.begin.css
          push:
          - meta_scope: meta.group.css
          - match: '(?=\))'
            pop: true
          - include: percentage-type

      # blend(), blenda() - Not yet implemented by browsers
    - match: '\b(blenda|blend)(?=\()'
      scope: support.function.color.css
      push:
        - meta_scope: meta.function-call.css
        - include: function-notation-terminator
        - match: '\('
          scope: punctuation.definition.group.begin.css
          push:
          - meta_scope: meta.group.css
          - match: '(?=\))'
            pop: true
          - match: '\b(rgb|hsl|hwb)\b'
            scope: keyword.other.color-space.css
          - include: color-values
          - include: percentage-type
          - include: var-function

  unicode-range:
    - match: |-
        (?xi)
            (u\+)
            ([0-9a-f?]{1,6}
            (?:(-)[0-9a-f]{1,6})?)
      scope: support.unicode-range.css
      captures:
        1: support.constant.unicode-range.prefix.css
        2: constant.codepoint-range.css
        3: punctuation.section.range.css

  # Qualified Name
  # https://drafts.csswg.org/css-namespaces-3/#css-qnames
  qualified-name:
    - match: '(?:({{ident}})|(\*))?([|])(?!=)'
      captures:
        1: entity.other.namespace-prefix.css
        2: entity.name.namespace.wildcard.css
        3: punctuation.separator.namespace.css

  # Custom Properties
  # https://drafts.csswg.org/css-variables/#typedef-custom-property-name
  custom-property-name:
    - match: '(--)({{nmchar}}+)'
      scope: support.type.custom-property.css
      captures:
        1: punctuation.definition.custom-property.css
        2: support.type.custom-property.name.css

  color-adjuster-operators:
    - match: '[\-\+*](?=\s+)'
      scope: keyword.operator.css

  comma-delimiter:
    - match: '\s*(,)\s*'
      captures:
        1: punctuation.separator.css

  vendor-prefix:
    - match: "-(?:webkit|moz|ms|o)-"
      scope: support.type.vendor-prefix.css

  function-notation-terminator:
    - match: '\)'
      scope: meta.group.css punctuation.definition.group.end.css
      pop: true

  at-rule-punctuation:
    - match: \;
      scope: punctuation.terminator.rule.css
    - match: (?=;|$)
      pop: true

  unquoted-string:
    - match: '[^\s''"]'
      scope: string.unquoted.css

  literal-string:
    - match: "'"
      scope: punctuation.definition.string.begin.css
      push:
        - meta_scope: string.quoted.single.css
        - match: (')|(\n)
          captures:
            1: punctuation.definition.string.end.css
            2: invalid.illegal.newline.css
          pop: true
        - include: string-content
    - match: '"'
      scope: punctuation.definition.string.begin.css
      push:
        - meta_scope: string.quoted.double.css
        - match: (")|(\n)
          captures:
            1: punctuation.definition.string.end.css
            2: invalid.illegal.newline.css
          pop: true
        - include: string-content

  string-content:
    - match: \\\s*\n
      scope: constant.character.escape.newline.css
    - match: '\\(\h{1,6}|.)'
      scope: constant.character.escape.css

  # https://www.w3.org/TR/css3-values/#numeric-types
  numeric-values:
    - include: dimensions
    - include: percentage-type
    - include: number-type

  integer-type:
    - match: '{{integer}}'
      scope: constant.numeric.css

  # Make sure `number-type` is included after any other numeric values
  # as `number-type` will consume all numeric values.
  number-type:
    - match: '{{number}}'
      scope: constant.numeric.css

  percentage-type:
    - match: '{{number}}(%)'
      scope: constant.numeric.css
      captures:
        1: keyword.other.unit.css

  dimensions:
    - include: angle-type
    - include: frequency-type
    - include: length-type
    - include: resolution-type
    - include: time-type

  length-type:
    - match: '{{number}}({{font_relative_lengths}}|{{viewport_percentage_lengths}}|{{absolute_lengths}})\b'
      scope: constant.numeric.css
      captures:
        1: keyword.other.unit.css
    - match: '0\b(?!%)'
      scope: constant.numeric.css

  time-type:
    - match: '{{number}}({{duration_units}})\b'
      scope: constant.numeric.css
      captures:
        1: keyword.other.unit.css

  frequency-type:
    - match: '{{number}}({{frequency_units}})\b'
      scope: constant.numeric.css
      captures:
        1: keyword.other.unit.css

  resolution-type:
    - match: '{{number}}({{resolution_units}})\b'
      scope: constant.numeric.css
      captures:
        1: keyword.other.unit.css

  angle-type:
    - match: '{{number}}({{angle_units}})\b'
      scope: constant.numeric.css
      captures:
        1: keyword.other.unit.css

  # https://drafts.csswg.org/css-images-3/#typedef-image
  image-type:
    - include: cross-fade-function
    - include: gradient-functions
    - include: image-function
    - include: image-set-function
    - include: url-function