Index: frontend/node_modules/postcss-nested/LICENSE
===================================================================
--- frontend/node_modules/postcss-nested/LICENSE	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/postcss-nested/LICENSE	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,20 @@
+The MIT License (MIT)
+
+Copyright 2014 Andrey Sitnik <andrey@sitnik.ru>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Index: frontend/node_modules/postcss-nested/README.md
===================================================================
--- frontend/node_modules/postcss-nested/README.md	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/postcss-nested/README.md	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,85 @@
+# PostCSS Nested
+
+<img align="right" width="135" height="95"
+     title="Philosopher’s stone, logo of PostCSS"
+     src="https://postcss.org/logo-leftp.svg">
+
+[PostCSS] plugin to unwrap nested rules closer to Sass syntax.
+
+```css
+.phone {
+  &_title {
+    width: 500px;
+    @media (max-width: 500px) {
+      width: auto;
+    }
+    body.is_dark & {
+      color: white;
+    }
+  }
+  img {
+    display: block;
+  }
+}
+
+.title {
+  font-size: var(--font);
+
+  @at-root html {
+    --font: 16px;
+  }
+}
+```
+
+will be processed to:
+
+```css
+.phone_title {
+  width: 500px;
+}
+@media (max-width: 500px) {
+  .phone_title {
+    width: auto;
+  }
+}
+body.is_dark .phone_title {
+  color: white;
+}
+.phone img {
+  display: block;
+}
+
+.title {
+  font-size: var(--font);
+}
+html {
+  --font: 16px;
+}
+```
+
+Related plugins:
+
+- Use [`postcss-current-selector`] **after** this plugin if you want
+  to use current selector in properties or variables values.
+- Use [`postcss-nested-ancestors`] **before** this plugin if you want
+  to reference any ancestor element directly in your selectors with `^&`.
+
+Alternatives:
+
+- See also [`postcss-nesting`], which implements [CSSWG draft].
+- [`postcss-nested-props`] for nested properties like `font-size`.
+
+<a href="https://evilmartians.com/?utm_source=postcss-nested">
+  <img src="https://evilmartians.com/badges/sponsored-by-evil-martians.svg"
+       alt="Sponsored by Evil Martians" width="236" height="54">
+</a>
+
+[`postcss-current-selector`]: https://github.com/komlev/postcss-current-selector
+[`postcss-nested-ancestors`]: https://github.com/toomuchdesign/postcss-nested-ancestors
+[`postcss-nested-props`]: https://github.com/jedmao/postcss-nested-props
+[`postcss-nesting`]: https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-nesting
+[CSSWG draft]: https://drafts.csswg.org/css-nesting-1/
+[PostCSS]: https://github.com/postcss/postcss
+
+## Docs
+Read full docs **[here](https://github.com/postcss/postcss-nested#readme)**.
Index: frontend/node_modules/postcss-nested/index.d.ts
===================================================================
--- frontend/node_modules/postcss-nested/index.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/postcss-nested/index.d.ts	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,41 @@
+// Original definitions (@types/postcss-nested)
+// by Maxim Vorontsov <https://github.com/VorontsovMaxim>
+
+import { PluginCreator } from 'postcss'
+
+declare namespace nested {
+  interface Options {
+    /**
+     * By default, plugin will bubble only `@media`, `@supports` and `@layer`
+     * at-rules. Use this option to add your custom at-rules to this list.
+     */
+    bubble?: string[]
+
+    /**
+     * By default, plugin will unwrap only `@font-face`, `@keyframes`,
+     * and `@document` at-rules. You can add your custom at-rules
+     * to this list by this option.
+     */
+    unwrap?: string[]
+
+    /**
+     * By default, plugin will strip out any empty selector generated
+     * by intermediate nesting levels. You can set this option to `true`
+     * to preserve them.
+     */
+    preserveEmpty?: boolean
+
+    /**
+     * The plugin supports the SCSS custom at-rule `@at-root` which breaks
+     * rule blocks out of their nested position. If you want, you can choose
+     * a new custom name for this rule in your code.
+     */
+    rootRuleName?: string
+  }
+
+  type Nested = PluginCreator<Options>
+}
+
+declare const nested: nested.Nested
+
+export = nested
Index: frontend/node_modules/postcss-nested/index.js
===================================================================
--- frontend/node_modules/postcss-nested/index.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/postcss-nested/index.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,361 @@
+const { AtRule, Rule } = require('postcss')
+let parser = require('postcss-selector-parser')
+
+/**
+ * Run a selector string through postcss-selector-parser
+ */
+function parse(rawSelector, rule) {
+  let nodes
+  try {
+    parser(parsed => {
+      nodes = parsed
+    }).processSync(rawSelector)
+  } catch (e) {
+    if (rawSelector.includes(':')) {
+      throw rule ? rule.error('Missed semicolon') : e
+    } else {
+      throw rule ? rule.error(e.message) : e
+    }
+  }
+  return nodes.at(0)
+}
+
+/**
+ * Replaces the "&" token in a node's selector with the parent selector
+ * similar to what SCSS does.
+ *
+ * Mutates the nodes list
+ */
+function interpolateAmpInSelector(nodes, parent) {
+  let replaced = false
+  nodes.each(node => {
+    if (node.type === 'nesting') {
+      let clonedParent = parent.clone({})
+      if (node.value !== '&') {
+        node.replaceWith(
+          parse(node.value.replace('&', clonedParent.toString()))
+        )
+      } else {
+        node.replaceWith(clonedParent)
+      }
+      replaced = true
+    } else if ('nodes' in node && node.nodes) {
+      if (interpolateAmpInSelector(node, parent)) {
+        replaced = true
+      }
+    }
+  })
+  return replaced
+}
+
+/**
+ * Combines parent and child selectors, in a SCSS-like way
+ */
+function mergeSelectors(parent, child) {
+  let merged = []
+  parent.selectors.forEach(sel => {
+    let parentNode = parse(sel, parent)
+
+    child.selectors.forEach(selector => {
+      if (!selector) {
+        return
+      }
+      let node = parse(selector, child)
+      let replaced = interpolateAmpInSelector(node, parentNode)
+      if (!replaced) {
+        node.prepend(parser.combinator({ value: ' ' }))
+        node.prepend(parentNode.clone({}))
+      }
+      merged.push(node.toString())
+    })
+  })
+  return merged
+}
+
+/**
+ * Move a child and its preceeding comment(s) to after "after"
+ */
+function breakOut(child, after) {
+  let prev = child.prev()
+  after.after(child)
+  while (prev && prev.type === 'comment') {
+    let nextPrev = prev.prev()
+    after.after(prev)
+    prev = nextPrev
+  }
+  return child
+}
+
+function createFnAtruleChilds(bubble) {
+  return function atruleChilds(rule, atrule, bubbling, mergeSels = bubbling) {
+    let children = []
+    atrule.each(child => {
+      if (child.type === 'rule' && bubbling) {
+        if (mergeSels) {
+          child.selectors = mergeSelectors(rule, child)
+        }
+      } else if (child.type === 'atrule' && child.nodes) {
+        if (bubble[child.name]) {
+          atruleChilds(rule, child, mergeSels)
+        } else if (atrule[rootRuleMergeSel] !== false) {
+          children.push(child)
+        }
+      } else {
+        children.push(child)
+      }
+    })
+    if (bubbling) {
+      if (children.length) {
+        let clone = rule.clone({ nodes: [] })
+        for (let child of children) {
+          clone.append(child)
+        }
+        atrule.prepend(clone)
+      }
+    }
+  }
+}
+
+function pickDeclarations(selector, declarations, after) {
+  let parent = new Rule({
+    nodes: [],
+    selector
+  })
+  parent.append(declarations)
+  after.after(parent)
+  return parent
+}
+
+function atruleNames(defaults, custom) {
+  let list = {}
+  for (let name of defaults) {
+    list[name] = true
+  }
+  if (custom) {
+    for (let name of custom) {
+      list[name.replace(/^@/, '')] = true
+    }
+  }
+  return list
+}
+
+function parseRootRuleParams(params) {
+  params = params.trim()
+  let braceBlock = params.match(/^\((.*)\)$/)
+  if (!braceBlock) {
+    return { selector: params, type: 'basic' }
+  }
+  let bits = braceBlock[1].match(/^(with(?:out)?):(.+)$/)
+  if (bits) {
+    let allowlist = bits[1] === 'with'
+    let rules = Object.fromEntries(
+      bits[2]
+        .trim()
+        .split(/\s+/)
+        .map(name => [name, true])
+    )
+    if (allowlist && rules.all) {
+      return { type: 'noop' }
+    }
+    let escapes = rule => !!rules[rule]
+    if (rules.all) {
+      escapes = () => true
+    } else if (allowlist) {
+      escapes = rule => (rule === 'all' ? false : !rules[rule])
+    }
+
+    return {
+      escapes,
+      type: 'withrules'
+    }
+  }
+  // Unrecognized brace block
+  return { type: 'unknown' }
+}
+
+function getAncestorRules(leaf) {
+  let lineage = []
+  let parent = leaf.parent
+
+  while (parent && parent instanceof AtRule) {
+    lineage.push(parent)
+    parent = parent.parent
+  }
+  return lineage
+}
+
+function unwrapRootRule(rule) {
+  let escapes = rule[rootRuleEscapes]
+
+  if (!escapes) {
+    rule.after(rule.nodes)
+  } else {
+    let nodes = rule.nodes
+
+    let topEscaped
+    let topEscapedIdx = -1
+    let breakoutLeaf
+    let breakoutRoot
+    let clone
+
+    let lineage = getAncestorRules(rule)
+    lineage.forEach((parent, i) => {
+      if (escapes(parent.name)) {
+        topEscaped = parent
+        topEscapedIdx = i
+        breakoutRoot = clone
+      } else {
+        let oldClone = clone
+        clone = parent.clone({ nodes: [] })
+        oldClone && clone.append(oldClone)
+        breakoutLeaf = breakoutLeaf || clone
+      }
+    })
+
+    if (!topEscaped) {
+      rule.after(nodes)
+    } else if (!breakoutRoot) {
+      topEscaped.after(nodes)
+    } else {
+      let leaf = breakoutLeaf
+      leaf.append(nodes)
+      topEscaped.after(breakoutRoot)
+    }
+
+    if (rule.next() && topEscaped) {
+      let restRoot
+      lineage.slice(0, topEscapedIdx + 1).forEach((parent, i, arr) => {
+        let oldRoot = restRoot
+        restRoot = parent.clone({ nodes: [] })
+        oldRoot && restRoot.append(oldRoot)
+
+        let nextSibs = []
+        let _child = arr[i - 1] || rule
+        let next = _child.next()
+        while (next) {
+          nextSibs.push(next)
+          next = next.next()
+        }
+        restRoot.append(nextSibs)
+      })
+      restRoot && (breakoutRoot || nodes[nodes.length - 1]).after(restRoot)
+    }
+  }
+
+  rule.remove()
+}
+
+const rootRuleMergeSel = Symbol('rootRuleMergeSel')
+const rootRuleEscapes = Symbol('rootRuleEscapes')
+
+function normalizeRootRule(rule) {
+  let { params } = rule
+  let { escapes, selector, type } = parseRootRuleParams(params)
+  if (type === 'unknown') {
+    throw rule.error(
+      `Unknown @${rule.name} parameter ${JSON.stringify(params)}`
+    )
+  }
+  if (type === 'basic' && selector) {
+    let selectorBlock = new Rule({ nodes: rule.nodes, selector })
+    rule.removeAll()
+    rule.append(selectorBlock)
+  }
+  rule[rootRuleEscapes] = escapes
+  rule[rootRuleMergeSel] = escapes ? !escapes('all') : type === 'noop'
+}
+
+const hasRootRule = Symbol('hasRootRule')
+
+module.exports = (opts = {}) => {
+  let bubble = atruleNames(
+    ['media', 'supports', 'layer', 'container', 'starting-style'],
+    opts.bubble
+  )
+  let atruleChilds = createFnAtruleChilds(bubble)
+  let unwrap = atruleNames(
+    [
+      'document',
+      'font-face',
+      'keyframes',
+      '-webkit-keyframes',
+      '-moz-keyframes'
+    ],
+    opts.unwrap
+  )
+  let rootRuleName = (opts.rootRuleName || 'at-root').replace(/^@/, '')
+  let preserveEmpty = opts.preserveEmpty
+
+  return {
+    Once(root) {
+      root.walkAtRules(rootRuleName, node => {
+        normalizeRootRule(node)
+        root[hasRootRule] = true
+      })
+    },
+
+    postcssPlugin: 'postcss-nested',
+
+    RootExit(root) {
+      if (root[hasRootRule]) {
+        root.walkAtRules(rootRuleName, unwrapRootRule)
+        root[hasRootRule] = false
+      }
+    },
+
+    Rule(rule) {
+      let unwrapped = false
+      let after = rule
+      let copyDeclarations = false
+      let declarations = []
+
+      rule.each(child => {
+        if (child.type === 'rule') {
+          if (declarations.length) {
+            after = pickDeclarations(rule.selector, declarations, after)
+            declarations = []
+          }
+
+          copyDeclarations = true
+          unwrapped = true
+          child.selectors = mergeSelectors(rule, child)
+          after = breakOut(child, after)
+        } else if (child.type === 'atrule') {
+          if (declarations.length) {
+            after = pickDeclarations(rule.selector, declarations, after)
+            declarations = []
+          }
+          if (child.name === rootRuleName) {
+            unwrapped = true
+            atruleChilds(rule, child, true, child[rootRuleMergeSel])
+            after = breakOut(child, after)
+          } else if (bubble[child.name]) {
+            copyDeclarations = true
+            unwrapped = true
+            atruleChilds(rule, child, true)
+            after = breakOut(child, after)
+          } else if (unwrap[child.name]) {
+            copyDeclarations = true
+            unwrapped = true
+            atruleChilds(rule, child, false)
+            after = breakOut(child, after)
+          } else if (copyDeclarations) {
+            declarations.push(child)
+          }
+        } else if (child.type === 'decl' && copyDeclarations) {
+          declarations.push(child)
+        }
+      })
+
+      if (declarations.length) {
+        after = pickDeclarations(rule.selector, declarations, after)
+      }
+
+      if (unwrapped && preserveEmpty !== true) {
+        rule.raws.semicolon = true
+        if (rule.nodes.length === 0) rule.remove()
+      }
+    }
+  }
+}
+module.exports.postcss = true
Index: frontend/node_modules/postcss-nested/package.json
===================================================================
--- frontend/node_modules/postcss-nested/package.json	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/postcss-nested/package.json	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,34 @@
+{
+  "name": "postcss-nested",
+  "version": "6.2.0",
+  "description": "PostCSS plugin to unwrap nested rules like how Sass does it",
+  "keywords": [
+    "postcss",
+    "css",
+    "postcss-plugin",
+    "sass",
+    "nested"
+  ],
+  "author": "Andrey Sitnik <andrey@sitnik.ru>",
+  "license": "MIT",
+  "repository": "postcss/postcss-nested",
+  "engines": {
+    "node": ">=12.0"
+  },
+  "funding": [
+    {
+      "type": "opencollective",
+      "url": "https://opencollective.com/postcss/"
+    },
+    {
+      "type": "github",
+      "url": "https://github.com/sponsors/ai"
+    }
+  ],
+  "peerDependencies": {
+    "postcss": "^8.2.14"
+  },
+  "dependencies": {
+    "postcss-selector-parser": "^6.1.1"
+  }
+}
