Index: frontend/node_modules/postcss-import/LICENSE
===================================================================
--- frontend/node_modules/postcss-import/LICENSE	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/postcss-import/LICENSE	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,20 @@
+The MIT License (MIT)
+
+Copyright (c) 2014 Maxime Thirouin, Jason Campbell & Kevin Mårtensson
+
+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-import/README.md
===================================================================
--- frontend/node_modules/postcss-import/README.md	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/postcss-import/README.md	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,244 @@
+# postcss-import
+
+[![Build](https://img.shields.io/travis/postcss/postcss-import/master)](https://travis-ci.org/postcss/postcss-import)
+[![Version](https://img.shields.io/npm/v/postcss-import)](https://github.com/postcss/postcss-import/blob/master/CHANGELOG.md)
+[![postcss compatibility](https://img.shields.io/npm/dependency-version/postcss-import/peer/postcss)](https://postcss.org/)
+
+> [PostCSS](https://github.com/postcss/postcss) plugin to transform `@import`
+rules by inlining content.
+
+This plugin can consume local files, node modules or web_modules.
+To resolve path of an `@import` rule, it can look into root directory
+(by default `process.cwd()`), `web_modules`, `node_modules`
+or local modules.
+_When importing a module, it will look for `index.css` or file referenced in
+`package.json` in the `style` or `main` fields._
+You can also provide manually multiples paths where to look at.
+
+**Notes:**
+
+- **This plugin should probably be used as the first plugin of your list.
+This way, other plugins will work on the AST as if there were only a single file
+to process, and will probably work as you can expect**.
+- This plugin works great with
+[postcss-url](https://github.com/postcss/postcss-url) plugin,
+which will allow you to adjust assets `url()` (or even inline them) after
+inlining imported files.
+- In order to optimize output, **this plugin will only import a file once** on
+a given scope (root, media query...).
+Tests are made from the path & the content of imported files (using a hash
+table).
+If this behavior is not what you want, look at `skipDuplicates` option
+- If you are looking for **Glob Imports**, you can use [postcss-import-ext-glob](https://github.com/dimitrinicolas/postcss-import-ext-glob) to extend postcss-import.
+- Imports which are not modified (by `options.filter` or because they are remote
+  imports) are moved to the top of the output.
+- **This plugin attempts to follow the CSS `@import` spec**; `@import`
+  statements must precede all other statements (besides `@charset`).
+
+## Installation
+
+```console
+$ npm install -D postcss-import
+```
+
+## Usage
+
+Unless your stylesheet is in the same place where you run postcss
+(`process.cwd()`), you will need to use `from` option to make relative imports
+work.
+
+```js
+// dependencies
+const fs = require("fs")
+const postcss = require("postcss")
+const atImport = require("postcss-import")
+
+// css to be processed
+const css = fs.readFileSync("css/input.css", "utf8")
+
+// process css
+postcss()
+  .use(atImport())
+  .process(css, {
+    // `from` option is needed here
+    from: "css/input.css"
+  })
+  .then((result) => {
+    const output = result.css
+
+    console.log(output)
+  })
+```
+
+`css/input.css`:
+
+```css
+/* can consume `node_modules`, `web_modules` or local modules */
+@import "cssrecipes-defaults"; /* == @import "../node_modules/cssrecipes-defaults/index.css"; */
+@import "normalize.css"; /* == @import "../node_modules/normalize.css/normalize.css"; */
+
+@import "foo.css"; /* relative to css/ according to `from` option above */
+
+@import "bar.css" (min-width: 25em);
+
+@import 'baz.css' layer(baz-layer);
+
+body {
+  background: black;
+}
+```
+
+will give you:
+
+```css
+/* ... content of ../node_modules/cssrecipes-defaults/index.css */
+/* ... content of ../node_modules/normalize.css/normalize.css */
+
+/* ... content of css/foo.css */
+
+@media (min-width: 25em) {
+/* ... content of css/bar.css */
+}
+
+@layer baz-layer {
+/* ... content of css/baz.css */
+}
+
+body {
+  background: black;
+}
+```
+
+Checkout the [tests](test) for more examples.
+
+### Options
+
+### `filter`
+Type: `Function`  
+Default: `() => true`
+
+Only transform imports for which the test function returns `true`. Imports for
+which the test function returns `false` will be left as is. The function gets
+the path to import as an argument and should return a boolean.
+
+#### `root`
+
+Type: `String`  
+Default: `process.cwd()` or _dirname of
+[the postcss `from`](https://github.com/postcss/postcss#node-source)_
+
+Define the root where to resolve path (eg: place where `node_modules` are).
+Should not be used that much.  
+_Note: nested `@import` will additionally benefit of the relative dirname of
+imported files._
+
+#### `path`
+
+Type: `String|Array`  
+Default: `[]`
+
+A string or an array of paths in where to look for files.
+
+#### `plugins`
+
+Type: `Array`  
+Default: `undefined`
+
+An array of plugins to be applied on each imported files.
+
+#### `resolve`
+
+Type: `Function`  
+Default: `null`
+
+You can provide a custom path resolver with this option. This function gets
+`(id, basedir, importOptions)` arguments and should return a path, an array of
+paths or a promise resolving to the path(s). If you do not return an absolute
+path, your path will be resolved to an absolute path using the default
+resolver.
+You can use [resolve](https://github.com/substack/node-resolve) for this.
+
+#### `load`
+
+Type: `Function`  
+Default: null
+
+You can overwrite the default loading way by setting this option.
+This function gets `(filename, importOptions)` arguments and returns content or
+promised content.
+
+#### `skipDuplicates`
+
+Type: `Boolean`  
+Default: `true`
+
+By default, similar files (based on the same content) are being skipped.
+It's to optimize output and skip similar files like `normalize.css` for example.
+If this behavior is not what you want, just set this option to `false` to
+disable it.
+
+#### `addModulesDirectories`
+
+Type: `Array`  
+Default: `[]`
+
+An array of folder names to add to [Node's resolver](https://github.com/substack/node-resolve).
+Values will be appended to the default resolve directories:
+`["node_modules", "web_modules"]`.
+
+This option is only for adding additional directories to default resolver. If
+you provide your own resolver via the `resolve` configuration option above, then
+this value will be ignored.
+
+#### `nameLayer`
+
+Type: `Function`
+Default: `null`
+
+You can provide a custom naming function for anonymous layers (`@import 'baz.css' layer;`).
+This function gets `(index, rootFilename)` arguments and should return a unique string.
+
+This option only influences imports without a layer name.
+Without this option the plugin will warn on anonymous layers.
+
+#### Example with some options
+
+```js
+const postcss = require("postcss")
+const atImport = require("postcss-import")
+
+postcss()
+  .use(atImport({
+    path: ["src/css"],
+  }))
+  .process(cssString)
+  .then((result) => {
+    const { css } = result
+  })
+```
+
+## `dependency` Message Support
+
+`postcss-import` adds a message to `result.messages` for each `@import`. Messages are in the following format:
+
+```
+{
+  type: 'dependency',
+  file: absoluteFilePath,
+  parent: fileContainingTheImport
+}
+```
+
+This is mainly for use by postcss runners that implement file watching.
+
+---
+
+## CONTRIBUTING
+
+* ⇄ Pull requests and ★ Stars are always welcome.
+* For bugs and feature requests, please create an issue.
+* Pull requests must be accompanied by passing automated tests (`$ npm test`).
+
+## [Changelog](CHANGELOG.md)
+
+## [License](LICENSE)
Index: frontend/node_modules/postcss-import/index.js
===================================================================
--- frontend/node_modules/postcss-import/index.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/postcss-import/index.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,420 @@
+"use strict"
+// builtin tooling
+const path = require("path")
+
+// internal tooling
+const joinMedia = require("./lib/join-media")
+const joinLayer = require("./lib/join-layer")
+const resolveId = require("./lib/resolve-id")
+const loadContent = require("./lib/load-content")
+const processContent = require("./lib/process-content")
+const parseStatements = require("./lib/parse-statements")
+const assignLayerNames = require("./lib/assign-layer-names")
+const dataURL = require("./lib/data-url")
+
+function AtImport(options) {
+  options = {
+    root: process.cwd(),
+    path: [],
+    skipDuplicates: true,
+    resolve: resolveId,
+    load: loadContent,
+    plugins: [],
+    addModulesDirectories: [],
+    nameLayer: null,
+    ...options,
+  }
+
+  options.root = path.resolve(options.root)
+
+  // convert string to an array of a single element
+  if (typeof options.path === "string") options.path = [options.path]
+
+  if (!Array.isArray(options.path)) options.path = []
+
+  options.path = options.path.map(p => path.resolve(options.root, p))
+
+  return {
+    postcssPlugin: "postcss-import",
+    Once(styles, { result, atRule, postcss }) {
+      const state = {
+        importedFiles: {},
+        hashFiles: {},
+        rootFilename: null,
+        anonymousLayerCounter: 0,
+      }
+
+      if (styles.source?.input?.file) {
+        state.rootFilename = styles.source.input.file
+        state.importedFiles[styles.source.input.file] = {}
+      }
+
+      if (options.plugins && !Array.isArray(options.plugins)) {
+        throw new Error("plugins option must be an array")
+      }
+
+      if (options.nameLayer && typeof options.nameLayer !== "function") {
+        throw new Error("nameLayer option must be a function")
+      }
+
+      return parseStyles(result, styles, options, state, [], []).then(
+        bundle => {
+          applyRaws(bundle)
+          applyMedia(bundle)
+          applyStyles(bundle, styles)
+        }
+      )
+
+      function applyRaws(bundle) {
+        bundle.forEach((stmt, index) => {
+          if (index === 0) return
+
+          if (stmt.parent) {
+            const { before } = stmt.parent.node.raws
+            if (stmt.type === "nodes") stmt.nodes[0].raws.before = before
+            else stmt.node.raws.before = before
+          } else if (stmt.type === "nodes") {
+            stmt.nodes[0].raws.before = stmt.nodes[0].raws.before || "\n"
+          }
+        })
+      }
+
+      function applyMedia(bundle) {
+        bundle.forEach(stmt => {
+          if (
+            (!stmt.media.length && !stmt.layer.length) ||
+            stmt.type === "charset"
+          ) {
+            return
+          }
+
+          if (stmt.layer.length > 1) {
+            assignLayerNames(stmt.layer, stmt.node, state, options)
+          }
+
+          if (stmt.type === "import") {
+            const parts = [stmt.fullUri]
+
+            const media = stmt.media.join(", ")
+
+            if (stmt.layer.length) {
+              const layerName = stmt.layer.join(".")
+
+              let layerParams = "layer"
+              if (layerName) {
+                layerParams = `layer(${layerName})`
+              }
+
+              parts.push(layerParams)
+            }
+
+            if (media) {
+              parts.push(media)
+            }
+
+            stmt.node.params = parts.join(" ")
+          } else if (stmt.type === "media") {
+            if (stmt.layer.length) {
+              const layerNode = atRule({
+                name: "layer",
+                params: stmt.layer.join("."),
+                source: stmt.node.source,
+              })
+
+              if (stmt.parentMedia?.length) {
+                const mediaNode = atRule({
+                  name: "media",
+                  params: stmt.parentMedia.join(", "),
+                  source: stmt.node.source,
+                })
+
+                mediaNode.append(layerNode)
+                layerNode.append(stmt.node)
+                stmt.node = mediaNode
+              } else {
+                layerNode.append(stmt.node)
+                stmt.node = layerNode
+              }
+            } else {
+              stmt.node.params = stmt.media.join(", ")
+            }
+          } else {
+            const { nodes } = stmt
+            const { parent } = nodes[0]
+
+            let outerAtRule
+            let innerAtRule
+            if (stmt.media.length && stmt.layer.length) {
+              const mediaNode = atRule({
+                name: "media",
+                params: stmt.media.join(", "),
+                source: parent.source,
+              })
+
+              const layerNode = atRule({
+                name: "layer",
+                params: stmt.layer.join("."),
+                source: parent.source,
+              })
+
+              mediaNode.append(layerNode)
+              innerAtRule = layerNode
+              outerAtRule = mediaNode
+            } else if (stmt.media.length) {
+              const mediaNode = atRule({
+                name: "media",
+                params: stmt.media.join(", "),
+                source: parent.source,
+              })
+
+              innerAtRule = mediaNode
+              outerAtRule = mediaNode
+            } else if (stmt.layer.length) {
+              const layerNode = atRule({
+                name: "layer",
+                params: stmt.layer.join("."),
+                source: parent.source,
+              })
+
+              innerAtRule = layerNode
+              outerAtRule = layerNode
+            }
+
+            parent.insertBefore(nodes[0], outerAtRule)
+
+            // remove nodes
+            nodes.forEach(node => {
+              node.parent = undefined
+            })
+
+            // better output
+            nodes[0].raws.before = nodes[0].raws.before || "\n"
+
+            // wrap new rules with media query and/or layer at rule
+            innerAtRule.append(nodes)
+
+            stmt.type = "media"
+            stmt.node = outerAtRule
+            delete stmt.nodes
+          }
+        })
+      }
+
+      function applyStyles(bundle, styles) {
+        styles.nodes = []
+
+        // Strip additional statements.
+        bundle.forEach(stmt => {
+          if (["charset", "import", "media"].includes(stmt.type)) {
+            stmt.node.parent = undefined
+            styles.append(stmt.node)
+          } else if (stmt.type === "nodes") {
+            stmt.nodes.forEach(node => {
+              node.parent = undefined
+              styles.append(node)
+            })
+          }
+        })
+      }
+
+      function parseStyles(result, styles, options, state, media, layer) {
+        const statements = parseStatements(result, styles)
+
+        return Promise.resolve(statements)
+          .then(stmts => {
+            // process each statement in series
+            return stmts.reduce((promise, stmt) => {
+              return promise.then(() => {
+                stmt.media = joinMedia(media, stmt.media || [])
+                stmt.parentMedia = media
+                stmt.layer = joinLayer(layer, stmt.layer || [])
+
+                // skip protocol base uri (protocol://url) or protocol-relative
+                if (
+                  stmt.type !== "import" ||
+                  /^(?:[a-z]+:)?\/\//i.test(stmt.uri)
+                ) {
+                  return
+                }
+
+                if (options.filter && !options.filter(stmt.uri)) {
+                  // rejected by filter
+                  return
+                }
+
+                return resolveImportId(result, stmt, options, state)
+              })
+            }, Promise.resolve())
+          })
+          .then(() => {
+            let charset
+            const imports = []
+            const bundle = []
+
+            function handleCharset(stmt) {
+              if (!charset) charset = stmt
+              // charsets aren't case-sensitive, so convert to lower case to compare
+              else if (
+                stmt.node.params.toLowerCase() !==
+                charset.node.params.toLowerCase()
+              ) {
+                throw new Error(
+                  `Incompatable @charset statements:
+  ${stmt.node.params} specified in ${stmt.node.source.input.file}
+  ${charset.node.params} specified in ${charset.node.source.input.file}`
+                )
+              }
+            }
+
+            // squash statements and their children
+            statements.forEach(stmt => {
+              if (stmt.type === "charset") handleCharset(stmt)
+              else if (stmt.type === "import") {
+                if (stmt.children) {
+                  stmt.children.forEach((child, index) => {
+                    if (child.type === "import") imports.push(child)
+                    else if (child.type === "charset") handleCharset(child)
+                    else bundle.push(child)
+                    // For better output
+                    if (index === 0) child.parent = stmt
+                  })
+                } else imports.push(stmt)
+              } else if (stmt.type === "media" || stmt.type === "nodes") {
+                bundle.push(stmt)
+              }
+            })
+
+            return charset
+              ? [charset, ...imports.concat(bundle)]
+              : imports.concat(bundle)
+          })
+      }
+
+      function resolveImportId(result, stmt, options, state) {
+        if (dataURL.isValid(stmt.uri)) {
+          return loadImportContent(result, stmt, stmt.uri, options, state).then(
+            result => {
+              stmt.children = result
+            }
+          )
+        }
+
+        const atRule = stmt.node
+        let sourceFile
+        if (atRule.source?.input?.file) {
+          sourceFile = atRule.source.input.file
+        }
+        const base = sourceFile
+          ? path.dirname(atRule.source.input.file)
+          : options.root
+
+        return Promise.resolve(options.resolve(stmt.uri, base, options))
+          .then(paths => {
+            if (!Array.isArray(paths)) paths = [paths]
+            // Ensure that each path is absolute:
+            return Promise.all(
+              paths.map(file => {
+                return !path.isAbsolute(file)
+                  ? resolveId(file, base, options)
+                  : file
+              })
+            )
+          })
+          .then(resolved => {
+            // Add dependency messages:
+            resolved.forEach(file => {
+              result.messages.push({
+                type: "dependency",
+                plugin: "postcss-import",
+                file,
+                parent: sourceFile,
+              })
+            })
+
+            return Promise.all(
+              resolved.map(file => {
+                return loadImportContent(result, stmt, file, options, state)
+              })
+            )
+          })
+          .then(result => {
+            // Merge loaded statements
+            stmt.children = result.reduce((result, statements) => {
+              return statements ? result.concat(statements) : result
+            }, [])
+          })
+      }
+
+      function loadImportContent(result, stmt, filename, options, state) {
+        const atRule = stmt.node
+        const { media, layer } = stmt
+
+        assignLayerNames(layer, atRule, state, options)
+
+        if (options.skipDuplicates) {
+          // skip files already imported at the same scope
+          if (state.importedFiles[filename]?.[media]?.[layer]) {
+            return
+          }
+
+          // save imported files to skip them next time
+          if (!state.importedFiles[filename]) {
+            state.importedFiles[filename] = {}
+          }
+          if (!state.importedFiles[filename][media]) {
+            state.importedFiles[filename][media] = {}
+          }
+          state.importedFiles[filename][media][layer] = true
+        }
+
+        return Promise.resolve(options.load(filename, options)).then(
+          content => {
+            if (content.trim() === "") {
+              result.warn(`${filename} is empty`, { node: atRule })
+              return
+            }
+
+            // skip previous imported files not containing @import rules
+            if (state.hashFiles[content]?.[media]?.[layer]) {
+              return
+            }
+
+            return processContent(
+              result,
+              content,
+              filename,
+              options,
+              postcss
+            ).then(importedResult => {
+              const styles = importedResult.root
+              result.messages = result.messages.concat(importedResult.messages)
+
+              if (options.skipDuplicates) {
+                const hasImport = styles.some(child => {
+                  return child.type === "atrule" && child.name === "import"
+                })
+                if (!hasImport) {
+                  // save hash files to skip them next time
+                  if (!state.hashFiles[content]) {
+                    state.hashFiles[content] = {}
+                  }
+                  if (!state.hashFiles[content][media]) {
+                    state.hashFiles[content][media] = {}
+                  }
+                  state.hashFiles[content][media][layer] = true
+                }
+              }
+
+              // recursion: import @import from imported file
+              return parseStyles(result, styles, options, state, media, layer)
+            })
+          }
+        )
+      }
+    },
+  }
+}
+
+AtImport.postcss = true
+
+module.exports = AtImport
Index: frontend/node_modules/postcss-import/lib/assign-layer-names.js
===================================================================
--- frontend/node_modules/postcss-import/lib/assign-layer-names.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/postcss-import/lib/assign-layer-names.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,17 @@
+"use strict"
+
+module.exports = function (layer, node, state, options) {
+  layer.forEach((layerPart, i) => {
+    if (layerPart.trim() === "") {
+      if (options.nameLayer) {
+        layer[i] = options
+          .nameLayer(state.anonymousLayerCounter++, state.rootFilename)
+          .toString()
+      } else {
+        throw node.error(
+          `When using anonymous layers in @import you must also set the "nameLayer" plugin option`
+        )
+      }
+    }
+  })
+}
Index: frontend/node_modules/postcss-import/lib/data-url.js
===================================================================
--- frontend/node_modules/postcss-import/lib/data-url.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/postcss-import/lib/data-url.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,17 @@
+"use strict"
+
+const dataURLRegexp = /^data:text\/css;base64,/i
+
+function isValid(url) {
+  return dataURLRegexp.test(url)
+}
+
+function contents(url) {
+  // "data:text/css;base64,".length === 21
+  return Buffer.from(url.slice(21), "base64").toString()
+}
+
+module.exports = {
+  isValid,
+  contents,
+}
Index: frontend/node_modules/postcss-import/lib/join-layer.js
===================================================================
--- frontend/node_modules/postcss-import/lib/join-layer.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/postcss-import/lib/join-layer.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,9 @@
+"use strict"
+
+module.exports = function (parentLayer, childLayer) {
+  if (!parentLayer.length && childLayer.length) return childLayer
+  if (parentLayer.length && !childLayer.length) return parentLayer
+  if (!parentLayer.length && !childLayer.length) return []
+
+  return parentLayer.concat(childLayer)
+}
Index: frontend/node_modules/postcss-import/lib/join-media.js
===================================================================
--- frontend/node_modules/postcss-import/lib/join-media.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/postcss-import/lib/join-media.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,28 @@
+"use strict"
+
+const startsWithKeywordRegexp = /^(all|not|only|print|screen)/i
+
+module.exports = function (parentMedia, childMedia) {
+  if (!parentMedia.length && childMedia.length) return childMedia
+  if (parentMedia.length && !childMedia.length) return parentMedia
+  if (!parentMedia.length && !childMedia.length) return []
+
+  const media = []
+
+  parentMedia.forEach(parentItem => {
+    const parentItemStartsWithKeyword = startsWithKeywordRegexp.test(parentItem)
+
+    childMedia.forEach(childItem => {
+      const childItemStartsWithKeyword = startsWithKeywordRegexp.test(childItem)
+      if (parentItem !== childItem) {
+        if (childItemStartsWithKeyword && !parentItemStartsWithKeyword) {
+          media.push(`${childItem} and ${parentItem}`)
+        } else {
+          media.push(`${parentItem} and ${childItem}`)
+        }
+      }
+    })
+  })
+
+  return media
+}
Index: frontend/node_modules/postcss-import/lib/load-content.js
===================================================================
--- frontend/node_modules/postcss-import/lib/load-content.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/postcss-import/lib/load-content.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,12 @@
+"use strict"
+
+const readCache = require("read-cache")
+const dataURL = require("./data-url")
+
+module.exports = filename => {
+  if (dataURL.isValid(filename)) {
+    return dataURL.contents(filename)
+  }
+
+  return readCache(filename, "utf-8")
+}
Index: frontend/node_modules/postcss-import/lib/parse-statements.js
===================================================================
--- frontend/node_modules/postcss-import/lib/parse-statements.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/postcss-import/lib/parse-statements.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,172 @@
+"use strict"
+
+// external tooling
+const valueParser = require("postcss-value-parser")
+
+// extended tooling
+const { stringify } = valueParser
+
+function split(params, start) {
+  const list = []
+  const last = params.reduce((item, node, index) => {
+    if (index < start) return ""
+    if (node.type === "div" && node.value === ",") {
+      list.push(item)
+      return ""
+    }
+    return item + stringify(node)
+  }, "")
+  list.push(last)
+  return list
+}
+
+module.exports = function (result, styles) {
+  const statements = []
+  let nodes = []
+
+  styles.each(node => {
+    let stmt
+    if (node.type === "atrule") {
+      if (node.name === "import") stmt = parseImport(result, node)
+      else if (node.name === "media") stmt = parseMedia(result, node)
+      else if (node.name === "charset") stmt = parseCharset(result, node)
+    }
+
+    if (stmt) {
+      if (nodes.length) {
+        statements.push({
+          type: "nodes",
+          nodes,
+          media: [],
+          layer: [],
+        })
+        nodes = []
+      }
+      statements.push(stmt)
+    } else nodes.push(node)
+  })
+
+  if (nodes.length) {
+    statements.push({
+      type: "nodes",
+      nodes,
+      media: [],
+      layer: [],
+    })
+  }
+
+  return statements
+}
+
+function parseMedia(result, atRule) {
+  const params = valueParser(atRule.params).nodes
+  return {
+    type: "media",
+    node: atRule,
+    media: split(params, 0),
+    layer: [],
+  }
+}
+
+function parseCharset(result, atRule) {
+  if (atRule.prev()) {
+    return result.warn("@charset must precede all other statements", {
+      node: atRule,
+    })
+  }
+  return {
+    type: "charset",
+    node: atRule,
+    media: [],
+    layer: [],
+  }
+}
+
+function parseImport(result, atRule) {
+  let prev = atRule.prev()
+  if (prev) {
+    do {
+      if (
+        prev.type !== "comment" &&
+        (prev.type !== "atrule" ||
+          (prev.name !== "import" &&
+            prev.name !== "charset" &&
+            !(prev.name === "layer" && !prev.nodes)))
+      ) {
+        return result.warn(
+          "@import must precede all other statements (besides @charset or empty @layer)",
+          { node: atRule }
+        )
+      }
+      prev = prev.prev()
+    } while (prev)
+  }
+
+  if (atRule.nodes) {
+    return result.warn(
+      "It looks like you didn't end your @import statement correctly. " +
+        "Child nodes are attached to it.",
+      { node: atRule }
+    )
+  }
+
+  const params = valueParser(atRule.params).nodes
+  const stmt = {
+    type: "import",
+    node: atRule,
+    media: [],
+    layer: [],
+  }
+
+  // prettier-ignore
+  if (
+    !params.length ||
+    (
+      params[0].type !== "string" ||
+      !params[0].value
+    ) &&
+    (
+      params[0].type !== "function" ||
+      params[0].value !== "url" ||
+      !params[0].nodes.length ||
+      !params[0].nodes[0].value
+    )
+  ) {
+    return result.warn(`Unable to find uri in '${  atRule.toString()  }'`, {
+      node: atRule,
+    })
+  }
+
+  if (params[0].type === "string") stmt.uri = params[0].value
+  else stmt.uri = params[0].nodes[0].value
+  stmt.fullUri = stringify(params[0])
+
+  let remainder = params
+  if (remainder.length > 2) {
+    if (
+      (remainder[2].type === "word" || remainder[2].type === "function") &&
+      remainder[2].value === "layer"
+    ) {
+      if (remainder[1].type !== "space") {
+        return result.warn("Invalid import layer statement", { node: atRule })
+      }
+
+      if (remainder[2].nodes) {
+        stmt.layer = [stringify(remainder[2].nodes)]
+      } else {
+        stmt.layer = [""]
+      }
+      remainder = remainder.slice(2)
+    }
+  }
+
+  if (remainder.length > 2) {
+    if (remainder[1].type !== "space") {
+      return result.warn("Invalid import media statement", { node: atRule })
+    }
+
+    stmt.media = split(remainder, 2)
+  }
+
+  return stmt
+}
Index: frontend/node_modules/postcss-import/lib/process-content.js
===================================================================
--- frontend/node_modules/postcss-import/lib/process-content.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/postcss-import/lib/process-content.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,59 @@
+"use strict"
+
+// builtin tooling
+const path = require("path")
+
+// placeholder tooling
+let sugarss
+
+module.exports = function processContent(
+  result,
+  content,
+  filename,
+  options,
+  postcss
+) {
+  const { plugins } = options
+  const ext = path.extname(filename)
+
+  const parserList = []
+
+  // SugarSS support:
+  if (ext === ".sss") {
+    if (!sugarss) {
+      try {
+        sugarss = require("sugarss")
+      } catch {} // Ignore
+    }
+    if (sugarss)
+      return runPostcss(postcss, content, filename, plugins, [sugarss])
+  }
+
+  // Syntax support:
+  if (result.opts.syntax?.parse) {
+    parserList.push(result.opts.syntax.parse)
+  }
+
+  // Parser support:
+  if (result.opts.parser) parserList.push(result.opts.parser)
+  // Try the default as a last resort:
+  parserList.push(null)
+
+  return runPostcss(postcss, content, filename, plugins, parserList)
+}
+
+function runPostcss(postcss, content, filename, plugins, parsers, index) {
+  if (!index) index = 0
+  return postcss(plugins)
+    .process(content, {
+      from: filename,
+      parser: parsers[index],
+    })
+    .catch(err => {
+      // If there's an error, try the next parser
+      index++
+      // If there are no parsers left, throw it
+      if (index === parsers.length) throw err
+      return runPostcss(postcss, content, filename, plugins, parsers, index)
+    })
+}
Index: frontend/node_modules/postcss-import/lib/resolve-id.js
===================================================================
--- frontend/node_modules/postcss-import/lib/resolve-id.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/postcss-import/lib/resolve-id.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,42 @@
+"use strict"
+
+// external tooling
+const resolve = require("resolve")
+
+const moduleDirectories = ["web_modules", "node_modules"]
+
+function resolveModule(id, opts) {
+  return new Promise((res, rej) => {
+    resolve(id, opts, (err, path) => (err ? rej(err) : res(path)))
+  })
+}
+
+module.exports = function (id, base, options) {
+  const paths = options.path
+
+  const resolveOpts = {
+    basedir: base,
+    moduleDirectory: moduleDirectories.concat(options.addModulesDirectories),
+    paths,
+    extensions: [".css"],
+    packageFilter: function processPackage(pkg) {
+      if (pkg.style) pkg.main = pkg.style
+      else if (!pkg.main || !/\.css$/.test(pkg.main)) pkg.main = "index.css"
+      return pkg
+    },
+    preserveSymlinks: false,
+  }
+
+  return resolveModule(`./${id}`, resolveOpts)
+    .catch(() => resolveModule(id, resolveOpts))
+    .catch(() => {
+      if (paths.indexOf(base) === -1) paths.unshift(base)
+
+      throw new Error(
+        `Failed to find '${id}'
+  in [
+    ${paths.join(",\n        ")}
+  ]`
+      )
+    })
+}
Index: frontend/node_modules/postcss-import/package.json
===================================================================
--- frontend/node_modules/postcss-import/package.json	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/postcss-import/package.json	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,65 @@
+{
+  "name": "postcss-import",
+  "version": "15.1.0",
+  "description": "PostCSS plugin to import CSS files",
+  "keywords": [
+    "css",
+    "postcss",
+    "postcss-plugin",
+    "import",
+    "node modules",
+    "npm"
+  ],
+  "author": "Maxime Thirouin",
+  "license": "MIT",
+  "repository": "https://github.com/postcss/postcss-import.git",
+  "files": [
+    "index.js",
+    "lib"
+  ],
+  "engines": {
+    "node": ">=14.0.0"
+  },
+  "dependencies": {
+    "postcss-value-parser": "^4.0.0",
+    "read-cache": "^1.0.0",
+    "resolve": "^1.1.7"
+  },
+  "devDependencies": {
+    "ava": "^5.0.0",
+    "eslint": "^8.2.0",
+    "eslint-config-problems": "^7.0.0",
+    "eslint-plugin-prettier": "^4.0.0",
+    "postcss": "^8.0.0",
+    "postcss-scss": "^4.0.0",
+    "prettier": "~2.8.0",
+    "sugarss": "^4.0.0"
+  },
+  "peerDependencies": {
+    "postcss": "^8.0.0"
+  },
+  "scripts": {
+    "ci": "eslint . && ava",
+    "lint": "eslint . --fix",
+    "pretest": "npm run lint",
+    "test": "ava"
+  },
+  "eslintConfig": {
+    "extends": "eslint-config-problems",
+    "env": {
+      "node": true
+    },
+    "plugins": [
+      "prettier"
+    ],
+    "rules": {
+      "prettier/prettier": [
+        "error",
+        {
+          "semi": false,
+          "arrowParens": "avoid"
+        }
+      ]
+    }
+  }
+}
