Index: frontend/node_modules/postcss-clamp/index.js
===================================================================
--- frontend/node_modules/postcss-clamp/index.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/postcss-clamp/index.js	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,126 @@
+let valueParser = require('postcss-value-parser')
+
+function parseValue (value) {
+  let parsed = value.match(/([\d.-]+)(.*)/)
+  if (!parsed || !parsed[1] || !parsed[2] || isNaN(parsed[1])) {
+    return undefined
+  }
+  return [parseFloat(parsed[1]), parsed[2]]
+}
+
+function compose (first, second, third) {
+  if (first && second && third) {
+    return `max(${first}, min(${second}, ${third}))`
+  }
+  if (first && second) {
+    return `max(${first}, ${second})`
+  }
+
+  return first
+}
+
+function updateValue (declaration, value, preserve) {
+  let newValue = value
+  let newValueAst = valueParser(value)
+  let valueAST = valueParser(declaration.value)
+  // Walk can't be interrupted, so we only care about first
+  let foundClamp = false
+
+  valueAST.walk((node, index, nodes) => {
+    let isClamp = node.type === 'function' && node.value === 'clamp'
+
+    if (!isClamp || foundClamp) {
+      return
+    }
+
+    foundClamp = true
+    nodes[index] = newValueAst
+  })
+
+  if (foundClamp) {
+    newValue = valueAST.toString()
+  }
+
+  if (preserve) {
+    declaration.cloneBefore({ value: newValue })
+  } else {
+    declaration.value = newValue
+  }
+}
+
+module.exports = opts => {
+  opts = opts || {}
+  let precalculate = opts.precalculate ? Boolean(opts.precalculate) : false
+  let preserve = opts.preserve ? Boolean(opts.preserve) : false
+
+  return {
+    postcssPlugin: 'postcss-clamp',
+    Declaration (decl) {
+      if (!decl || !decl.value.includes('clamp')) {
+        return
+      }
+      valueParser(decl.value).walk(node => {
+        let nodes = node.nodes
+        if (
+          node.type !== 'function' ||
+          node.value !== 'clamp' ||
+          nodes.length !== 5
+        ) {
+          return
+        }
+        let first = nodes[0]
+        let second = nodes[2]
+        let third = nodes[4]
+        let naive = compose(
+          valueParser.stringify(first),
+          valueParser.stringify(second),
+          valueParser.stringify(third)
+        )
+        if (!precalculate || second.type !== 'word' || third.type !== 'word') {
+          updateValue(decl, naive, preserve)
+          return
+        }
+        let parsedSecond = parseValue(second.value)
+        let parsedThird = parseValue(third.value)
+        if (parsedSecond === undefined || parsedThird === undefined) {
+          updateValue(decl, naive, preserve)
+          return
+        }
+        let [secondValue, secondUnit] = parsedSecond
+        let [thirdValue, thirdUnit] = parsedThird
+        if (secondUnit !== thirdUnit) {
+          updateValue(decl, naive, preserve)
+          return
+        }
+        let parsedFirst = parseValue(first.value)
+        if (parsedFirst === undefined) {
+          let secondThirdValue = `${secondValue + thirdValue}${secondUnit}`
+          updateValue(
+            decl,
+            compose(valueParser.stringify(first), secondThirdValue),
+            preserve
+          )
+          return
+        }
+        let [firstValue, firstUnit] = parsedFirst
+        if (firstUnit !== secondUnit) {
+          let secondThirdValue = `${secondValue + thirdValue}${secondUnit}`
+          updateValue(
+            decl,
+            compose(valueParser.stringify(first), secondThirdValue),
+            preserve
+          )
+          return
+        }
+
+        updateValue(
+          decl,
+          compose(`${firstValue + secondValue + thirdValue}${secondUnit}`),
+          preserve
+        )
+      })
+    }
+  }
+}
+
+module.exports.postcss = true
