diff --git a/gatsby/.eslintrc.js b/gatsby/.eslintrc.js
index 1e0b5ab..2e9f3fc 100644
--- a/gatsby/.eslintrc.js
+++ b/gatsby/.eslintrc.js
@@ -10,6 +10,7 @@ module.exports = {
   },
   'env': {
     'node': true, // defines things like process.env when generating through node
+    'browser': true
   },
   'extends': [
     'eslint:recommended', // use recommended configs
@@ -23,5 +24,7 @@ module.exports = {
     'indent': ['warn', 2],
     'comma-dangle': ['warn', 'always-multiline'],
     'no-unused-vars': 1,
+    'jsx-quotes': 1,
+    'react/jsx-sort-props': 1,
   },
 };
diff --git a/gatsby/data/gallery/DSC08521-3.jpg b/gatsby/data/gallery/DSC08521.jpg
similarity index 100%
rename from gatsby/data/gallery/DSC08521-3.jpg
rename to gatsby/data/gallery/DSC08521.jpg
diff --git a/gatsby/data/gallery/DSC3214-3.jpg b/gatsby/data/gallery/DSC3214.jpg
similarity index 100%
rename from gatsby/data/gallery/DSC3214-3.jpg
rename to gatsby/data/gallery/DSC3214.jpg
diff --git a/gatsby/gatsby-node.js b/gatsby/gatsby-node.js
index 1e4e0bd..b4c6f3b 100644
--- a/gatsby/gatsby-node.js
+++ b/gatsby/gatsby-node.js
@@ -3,6 +3,8 @@ const util = require('util');
 const path = require('path');
 const { read } = require('fast-exif');
 const iptc = require('node-iptc');
+const Vibrant = require('node-vibrant');
+const R = require('ramda');
 
 const readFile = util.promisify(fs.readFile);
 
@@ -16,7 +18,7 @@ function convertDMSToDD(dms, positiveDirection) {
   return positiveDirection ? res : -res;
 }
 
-function transformMetaToNodeData(exifData, iptcData) {
+function transformMetaToNodeData(exifData, iptcData, vibrantData) {
   const gps = { longitude: null, latitude: null };
 
   if (exifData) {
@@ -36,12 +38,27 @@ function transformMetaToNodeData(exifData, iptcData) {
     }
   }
 
+  // console.log('asdf', JSON.stringify(vibrantData.Vibrant.getTitleTextColor()));
+
+  const vibrant = R.map((swatch) => 
+    swatch.getRgb()
+  // ({
+  //   // rgb: swatch.getRgb(),
+  //   // hsl: swatch.getHsl(),
+  //   // hex: swatch.getHex(),
+  //   // // titleTextColor: swatch.getTitleTextColor(),
+  //   // // bodyTextColor: swatch.getBodyTextColor(),
+  // })
+  , vibrantData);
+
+  console.log(vibrant);
 
   return {
     exif: exifData?.exif,
     gps,
     dateTaken: exifData?.exif?.DateTimeOriginal,
     iptc: iptcData || undefined,
+    vibrant,
   };
 }
 
@@ -54,10 +71,14 @@ exports.onCreateNode = async function ({ node, getNode, actions }) {
     const file = await readFile(parent.absolutePath);
     const iptcData = iptc(file);
     const exifData = await read(parent.absolutePath);
+    const vibrantData = await Vibrant.from(parent.absolutePath)
+      .quality(1)
+      .getPalette();
+
     createNodeField({
       node,
       name: 'imageMeta',
-      value: transformMetaToNodeData(exifData, iptcData),
+      value: transformMetaToNodeData(exifData, iptcData, vibrantData),
     });
   }
 };
diff --git a/gatsby/package.json b/gatsby/package.json
index a28c38d..dbcfd38 100644
--- a/gatsby/package.json
+++ b/gatsby/package.json
@@ -34,7 +34,9 @@
     "gatsby-plugin-sharp": "^3.6.0",
     "gatsby-source-filesystem": "^3.6.0",
     "gatsby-transformer-sharp": "^3.6.0",
+    "kebab-case": "^1.0.1",
     "node-iptc": "^1.0.5",
+    "node-vibrant": "^3.2.1-alpha.1",
     "postcss": "^8.3.4",
     "postcss-nested": "^5.0.5",
     "ramda": "^0.27.1",
diff --git a/gatsby/src/components/GalleryImage.js b/gatsby/src/components/GalleryImage.js
index 14115c7..8ae01f8 100644
--- a/gatsby/src/components/GalleryImage.js
+++ b/gatsby/src/components/GalleryImage.js
@@ -26,21 +26,21 @@ const GalleryImage = ({ data }) => {
     </Helmet>
     <div className="min-h-screen flex flex-col justify-center">
       {/* TODO: change layout by amount of empty space on side of page, not aspect ratio? */}
-      <div style={{ margin: '0 5vw' }} className={classnames('flex mx-auto', ar > 1 ? 'flex-col' : 'flex-row-reverse')}>
-        <div className='flex-grow-0'>
+      <div className={classnames('flex mx-auto', ar > 1 ? 'flex-col' : 'flex-row-reverse')} style={{ margin: '0 5vw' }}>
+        <div className="flex-grow-0">
           <GatsbyImage
+            alt={name}
             className=""
-            loading='eager'
-            objectFit='contain'
+            image={getImage(image)}
+            key={image.base}
+            loading="eager"
+            objectFit="contain"
             style={{
               maxWidth: `calc(max(90vh, 500px) * ${ar})`,
               // height: '90vh',
               maxHeight: '90vh',
               minHeight: '500px',
-            }}
-            key={image.base}
-            image={getImage(image)}
-            alt={name} />
+            }} />
         </div>
         <div className={classnames('flex-shrink-0 mr-4', ar <= 1 && 'pt-4 flex-auto text-right')}>
           {hasName(image) && <h1 className="text-2xl mt-2">{name}</h1>}
@@ -57,7 +57,6 @@ export const query = graphql`
   allFile(filter: {sourceInstanceName: {eq: "gallery"}, base: {eq: $imageFilename}}) {
     edges {
       node {
-        relativePath
         base
         childImageSharp{
           fluid {
diff --git a/gatsby/src/components/IndexComponents.js b/gatsby/src/components/IndexComponents.js
new file mode 100644
index 0000000..6a270d9
--- /dev/null
+++ b/gatsby/src/components/IndexComponents.js
@@ -0,0 +1,15 @@
+import * as React from 'react';
+import classnames from 'classnames';
+
+export const HeroA = ({
+  href,
+  children,
+  className,
+  ...linkProps
+}) => (
+  <a
+    className={classnames('text-muted-light mx-1 hover:text-vibrant-light underline', className)}
+    href={href}
+    {...linkProps}
+  >{children}</a>
+);
diff --git a/gatsby/src/components/MasonryGallery.js b/gatsby/src/components/MasonryGallery.js
index 1f893c4..be73c16 100644
--- a/gatsby/src/components/MasonryGallery.js
+++ b/gatsby/src/components/MasonryGallery.js
@@ -32,7 +32,7 @@ const MasonryGallery = ({ images, itemsPerRow: itemsPerRowByBreakpoint }) => {
   
   return (
     <div
-      className='w-full'
+      className="w-full"
       style={{
         position: 'relative',
       }}
@@ -53,20 +53,20 @@ const MasonryGallery = ({ images, itemsPerRow: itemsPerRowByBreakpoint }) => {
         }
         return (
           <Link 
+            className="inline-block"
             key={`${image.base}`}
-            className='inline-block'
+            state={{modal: true}}
             style={{
               width,
               // marginLeft: '8px',
-            }}
-            state={{modal: true}} to={`/photogallery/${image.base}`}
+            }} to={`/photogallery/${image.base}`}
           >
             <GatsbyImage
-              className='w-full'
-              objectFit='cover'
+              alt={getName(image)}
+              className="w-full"
               // style={{ width }}
               image={getImage(image)}
-              alt={getName(image)}
+              objectFit="cover"
             />
           </Link>
         );
diff --git a/gatsby/src/pages/404.js b/gatsby/src/pages/404.js
index 2fc80a3..16abeea 100644
--- a/gatsby/src/pages/404.js
+++ b/gatsby/src/pages/404.js
@@ -32,7 +32,7 @@ const NotFoundPage = () => {
       <h1 style={headingStyles}>Page not found</h1>
       <p style={paragraphStyles}>
         Sorry{' '}
-        <span role="img" aria-label="Pensive emoji">
+        <span aria-label="Pensive emoji" role="img">
           😔
         </span>{' '}
         we couldn’t find what you were looking for.
diff --git a/gatsby/src/pages/index.js b/gatsby/src/pages/index.js
index e133e91..c094b0c 100644
--- a/gatsby/src/pages/index.js
+++ b/gatsby/src/pages/index.js
@@ -1,50 +1,106 @@
 import * as React from 'react';
-import { Link } from 'gatsby';
-import { StaticImage } from 'gatsby-plugin-image';
+import { Link, graphql } from 'gatsby';
+import { GatsbyImage, getImage } from 'gatsby-plugin-image';
+import { getVibrantToHelmetSafeBodyStyle, getVibrant } from '../utils';
+import { Helmet } from 'react-helmet';
+import { HeroA } from '../components/IndexComponents';
 
-const IndexPage = () => {
-  return (
-    <main className="font-serif sm:block lg:grid">
-      <StaticImage
+const IndexPage = ({ data }) => {
+  const images = data.allFile.edges.map((edge) => edge.node);
+  const [palette, setPalette] = React.useState([
+    [0, 0, 0],
+    [254, 254, 254],
+    [200, 200, 200],
+    [200, 200, 200],
+    [180, 180, 180],
+  ]);
+  const image = React.useRef(images[Math.floor(Math.random() * images.length)]).current;
+  const vibrant = getVibrant(image);
+  console.log('vibrant', getVibrant(image));
+  return (<>
+    <Helmet>
+      <body
+        className="bg-vibrant-dark"
+        style={getVibrantToHelmetSafeBodyStyle(vibrant)}
+      />
+    </Helmet>
+    <main
+      className="font-serif sm:block lg:grid"
+    >
+      <GatsbyImage
+        alt=""
+        className="sm:h-auto lg:h-screen hero-img"
+        image={getImage(image)}
+        loading="eager"
         style={{
           gridArea: '1/1',
-          // maxHeight: '90vh',
-          // height: '100vh',
-        }}
-        className='sm:h-auto lg:h-screen'
-        layout='fullWidth'
-        alt=''
-        src='../../data/gallery/DSC4180.jpg'
-      />
-      <div className='relative grid place-items-center' style={{gridArea: '1/1'}}>
-        <div
-          className="m-2 flex flex-col items-end"
-        >
-          {/* TODO: color thief and fonts */}
-          <section className='bg-green-200 bg-opacity-80 rounded-xl py-6'>
+        }} />
+      <div className="relative grid place-items-center" style={{gridArea: '1/1'}}>
+        <div className="m-2 flex flex-col items-end">
+          <section className="rounded-xl py-6 bg-vibrant-dark-75">
             <div className="mx-auto px-6">
-              <h1 className="italic font-normal text-5xl ">Chuck Dries</h1>
-              <h2 className="italic text-blue-300 text-2xl">Full stack software engineer &amp; hobbyist photographer</h2>
-              <ul>
-                <li>Software Developer, <span className="text-gray-800 italic">Axosoft</span></li>
-                <li><a className="hover:text-pink-400 underline" href="mailto:chuck@chuckdries.com">chuck@chuckdries.com</a> / <span>602.618.0414</span></li>
+              <h1 className="text-vibrant-light font-black text-6xl">Chuck Dries</h1>
+              <h2 className="text-vibrant italic text-2xl" >Full stack software engineer &amp; hobbyist photographer</h2>
+              <ul className="text-muted-light">
+                <li>Software Developer, <span className="italic">Axosoft</span></li>
+                <li><HeroA className="ml-0" href="mailto:chuck@chuckdries.com">chuck@chuckdries.com</HeroA>/<span className="ml-1">602.618.0414</span></li>
                 <li>
-                  <a className="mr-1 hover:text-pink-400 underline" href="http://github.com/chuckdries">Github</a>/
-                  <a className="mx-1 hover:text-pink-400 underline" href="https://www.linkedin.com/in/chuckdries/">LinkedIn</a>/
-                  <a className="mx-1 hover:text-pink-400 underline" href="https://devpost.com/chuckdries">Devpost</a>/
-                  <a className="mx-1 hover:text-pink-400 underline" href="CharlesDriesResumeCurrent.pdf">Resume [pdf]</a>/
-                  <a className="mx-1 hover:text-pink-400 underline" href="https://medium.com/@chuckdries">Medium (blog)</a>
+                  <HeroA className="ml-0" href="http://github.com/chuckdries">Github</HeroA>/
+                  <HeroA href="https://www.linkedin.com/in/chuckdries/">LinkedIn</HeroA>/
+                  <HeroA href="https://devpost.com/chuckdries">Devpost</HeroA>/
+                  <HeroA href="CharlesDriesResumeCurrent.pdf">Resume [pdf]</HeroA>/
+                  <HeroA href="https://medium.com/@chuckdries">Medium (blog)</HeroA>
                   {/* <a href="https://pgp.mit.edu/pks/lookup?op=get&search=0x2BD9D0871DB5A518">Public Key</a> */}
                 </li>
               </ul>
             </div>
           </section>
-          <Link className='text-black hover:underline font-sans inline-block p-3 my-2 rounded-md bg-gray-300 border-2 arrow-after font-bold border-gray-400' to='/photogallery'>
+          <Link className="text-muted-dark bg-muted-light border-muted-light hover:underline font-sans inline-block p-3 my-2 rounded-md border-2 arrow-after font-bold" to="/photogallery">
             Photography</Link>
         </div>
       </div>
+      <div id="asdf" style={{ display: 'block'}}></div>
     </main>
-  );
+  </>);
 };
 
+export const query = graphql`
+{
+  allFile(
+    filter: {
+      sourceInstanceName: {eq: "gallery"},
+      base: {in: ["DSC00201.jpg", "DSC05851.jpg", "DSC4180.jpg", "DSC08521.jpg", "DSC06245.jpg", "_DSC4949.jpg"]}
+      }
+  ) {
+    edges {
+      node {
+        relativePath
+        base
+        childImageSharp {
+          gatsbyImageData(
+            layout: FULL_WIDTH
+            # placeholder: BLURRED
+            placeholder: NONE
+            # blurredOptions: {width: 200}
+            breakpoints: [750, 1080, 1366, 1920, 2560, 3840]
+          )
+          fields {
+            imageMeta {
+              vibrant {
+                DarkMuted
+                DarkVibrant
+                LightMuted
+                LightVibrant
+                Muted
+                Vibrant
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+}
+`;
+
 export default IndexPage;
diff --git a/gatsby/src/styles/global.css b/gatsby/src/styles/global.css
index 3b57012..709e2c6 100644
--- a/gatsby/src/styles/global.css
+++ b/gatsby/src/styles/global.css
@@ -1,4 +1,6 @@
-@import url('https://fonts.googleapis.com/css2?family=Playfair+Display:ital@0;1&display=swap');
+/* @import url('https://fonts.googleapis.com/css2?family=Playfair+Display:ital@0;1&display=swap'); */
+/* black, bold, regular */
+@import url('https://fonts.googleapis.com/css2?family=Playfair+Display:ital,wght@0,400;0,700;0,900;1,400;1,700;1,900&display=swap');
 
 @tailwind base;
 @tailwind components;
diff --git a/gatsby/src/styles/index.css b/gatsby/src/styles/index.css
new file mode 100644
index 0000000..4c9a519
--- /dev/null
+++ b/gatsby/src/styles/index.css
@@ -0,0 +1,3 @@
+/* main.hero {
+  
+} */
diff --git a/gatsby/src/utils.js b/gatsby/src/utils.js
index debb0b3..5eb149d 100644
--- a/gatsby/src/utils.js
+++ b/gatsby/src/utils.js
@@ -1,7 +1,28 @@
+// import kebabCase from 'lodash/kebabCase';
+
 export const getMeta = (image) => image.childImageSharp.fields.imageMeta;
 
 export const getName = (image) => getMeta(image)?.iptc.object_name || image.base;
 
+export const getVibrant = (image) => getMeta(image)?.vibrant;
+
 export const hasName = (image) => Boolean(getMeta(image)?.iptc.object_name);
 
 export const getAspectRatio = (image) => image.childImageSharp.fluid.aspectRatio;
+
+export const getRgba = (palette, alpha) => `rgba(${palette[0]}, ${palette[1]}, ${palette[2]}, ${alpha || 1})`;
+
+export const getVibrantToHelmetSafeBodyStyle = (vibrant) => {
+  const style = {
+    '--muted': vibrant.Muted,
+    '--dark-muted': vibrant.DarkMuted,
+    '--light-muted': vibrant.LightMuted,
+    '--vibrant': vibrant.Vibrant,
+    '--dark-vibrant': vibrant.DarkVibrant,
+    '--light-vibrant': vibrant.LightVibrant,
+  }
+  if (typeof window === 'undefined') {
+    return style;
+  }
+  return Object.keys(style).map(key => `${(key)}: ${style[key]}`).join(';');
+};
diff --git a/gatsby/tailwind.config.js b/gatsby/tailwind.config.js
index bc4915b..3a3657b 100644
--- a/gatsby/tailwind.config.js
+++ b/gatsby/tailwind.config.js
@@ -12,6 +12,7 @@ module.exports = {
       '2xl': '1536px',
     },
     spacing: {
+      '0': '0px',
       '1': '8px',
       '2': '12px',
       '3': '16px',
@@ -26,7 +27,26 @@ module.exports = {
       // serif: ['Didot', 'Didot LT', 'STD', 'Hoefler Text' , 'Garamond', 'Times New Roman', 'serif']
       serif: ['Playfair Display', 'serif'],
     },
-    extend: {},
+    extend: {
+      colors: {
+        vibrant: {
+          DEFAULT: 'rgb(var(--vibrant))',
+          light: 'rgb(var(--light-vibrant))',
+          dark: 'rgb(var(--dark-vibrant))',
+          '75': 'rgba(var(--vibrant), .75)',
+          'light-75': 'rgba(var(--light-vibrant), .75)',
+          'dark-75': 'rgba(var(--dark-vibrant), .75)',
+        },
+        muted: {
+          DEFAULT: 'rgb(var(--muted))',
+          light: 'rgb(var(--light-muted))',
+          dark: 'rgb(var(--dark-muted))',
+          '75': 'rgba(var(--muted), .75)',
+          'light-75': 'rgba(var(--light-muted), .75)',
+          'dark-75': 'rgba(var(--dark-muted), .75)',
+        },
+      },
+    },
   },
   variants: {
     extend: {},
diff --git a/gatsby/yarn.lock b/gatsby/yarn.lock
index fe6db90..8b33bbd 100644
--- a/gatsby/yarn.lock
+++ b/gatsby/yarn.lock
@@ -1348,6 +1348,15 @@
     "@jimp/utils" "^0.14.0"
     bmp-js "^0.1.0"
 
+"@jimp/bmp@^0.16.1":
+  version "0.16.1"
+  resolved "https://registry.yarnpkg.com/@jimp/bmp/-/bmp-0.16.1.tgz#6e2da655b2ba22e721df0795423f34e92ef13768"
+  integrity sha512-iwyNYQeBawrdg/f24x3pQ5rEx+/GwjZcCXd3Kgc+ZUd+Ivia7sIqBsOnDaMZdKCBPlfW364ekexnlOqyVa0NWg==
+  dependencies:
+    "@babel/runtime" "^7.7.2"
+    "@jimp/utils" "^0.16.1"
+    bmp-js "^0.1.0"
+
 "@jimp/core@^0.14.0":
   version "0.14.0"
   resolved "https://registry.yarnpkg.com/@jimp/core/-/core-0.14.0.tgz#870c9ca25b40be353ebda1d2abb48723d9010055"
@@ -1365,6 +1374,23 @@
     pixelmatch "^4.0.2"
     tinycolor2 "^1.4.1"
 
+"@jimp/core@^0.16.1":
+  version "0.16.1"
+  resolved "https://registry.yarnpkg.com/@jimp/core/-/core-0.16.1.tgz#68c4288f6ef7f31a0f6b859ba3fb28dae930d39d"
+  integrity sha512-la7kQia31V6kQ4q1kI/uLimu8FXx7imWVajDGtwUG8fzePLWDFJyZl0fdIXVCL1JW2nBcRHidUot6jvlRDi2+g==
+  dependencies:
+    "@babel/runtime" "^7.7.2"
+    "@jimp/utils" "^0.16.1"
+    any-base "^1.1.0"
+    buffer "^5.2.0"
+    exif-parser "^0.1.12"
+    file-type "^9.0.0"
+    load-bmfont "^1.3.1"
+    mkdirp "^0.5.1"
+    phin "^2.9.1"
+    pixelmatch "^4.0.2"
+    tinycolor2 "^1.4.1"
+
 "@jimp/custom@^0.14.0":
   version "0.14.0"
   resolved "https://registry.yarnpkg.com/@jimp/custom/-/custom-0.14.0.tgz#1dbbf0094df7403f4e03bc984ed92e7458842f74"
@@ -1373,6 +1399,14 @@
     "@babel/runtime" "^7.7.2"
     "@jimp/core" "^0.14.0"
 
+"@jimp/custom@^0.16.1":
+  version "0.16.1"
+  resolved "https://registry.yarnpkg.com/@jimp/custom/-/custom-0.16.1.tgz#28b659c59e20a1d75a0c46067bd3f4bd302cf9c5"
+  integrity sha512-DNUAHNSiUI/j9hmbatD6WN/EBIyeq4AO0frl5ETtt51VN1SvE4t4v83ZA/V6ikxEf3hxLju4tQ5Pc3zmZkN/3A==
+  dependencies:
+    "@babel/runtime" "^7.7.2"
+    "@jimp/core" "^0.16.1"
+
 "@jimp/gif@^0.14.0":
   version "0.14.0"
   resolved "https://registry.yarnpkg.com/@jimp/gif/-/gif-0.14.0.tgz#db159f57c3cfd1566bbe8b124958791998614960"
@@ -1383,6 +1417,16 @@
     gifwrap "^0.9.2"
     omggif "^1.0.9"
 
+"@jimp/gif@^0.16.1":
+  version "0.16.1"
+  resolved "https://registry.yarnpkg.com/@jimp/gif/-/gif-0.16.1.tgz#d1f7c3a58f4666482750933af8b8f4666414f3ca"
+  integrity sha512-r/1+GzIW1D5zrP4tNrfW+3y4vqD935WBXSc8X/wm23QTY9aJO9Lw6PEdzpYCEY+SOklIFKaJYUAq/Nvgm/9ryw==
+  dependencies:
+    "@babel/runtime" "^7.7.2"
+    "@jimp/utils" "^0.16.1"
+    gifwrap "^0.9.2"
+    omggif "^1.0.9"
+
 "@jimp/jpeg@^0.14.0":
   version "0.14.0"
   resolved "https://registry.yarnpkg.com/@jimp/jpeg/-/jpeg-0.14.0.tgz#8a687a6a653bbbae38c522edef8f84bb418d9461"
@@ -1392,6 +1436,15 @@
     "@jimp/utils" "^0.14.0"
     jpeg-js "^0.4.0"
 
+"@jimp/jpeg@^0.16.1":
+  version "0.16.1"
+  resolved "https://registry.yarnpkg.com/@jimp/jpeg/-/jpeg-0.16.1.tgz#3b7bb08a4173f2f6d81f3049b251df3ee2ac8175"
+  integrity sha512-8352zrdlCCLFdZ/J+JjBslDvml+fS3Z8gttdml0We759PnnZGqrnPRhkOEOJbNUlE+dD4ckLeIe6NPxlS/7U+w==
+  dependencies:
+    "@babel/runtime" "^7.7.2"
+    "@jimp/utils" "^0.16.1"
+    jpeg-js "0.4.2"
+
 "@jimp/plugin-blit@^0.14.0":
   version "0.14.0"
   resolved "https://registry.yarnpkg.com/@jimp/plugin-blit/-/plugin-blit-0.14.0.tgz#5eb374be1201313b2113899fb842232d8fcfd345"
@@ -1530,6 +1583,14 @@
     "@babel/runtime" "^7.7.2"
     "@jimp/utils" "^0.14.0"
 
+"@jimp/plugin-resize@^0.16.1":
+  version "0.16.1"
+  resolved "https://registry.yarnpkg.com/@jimp/plugin-resize/-/plugin-resize-0.16.1.tgz#65e39d848ed13ba2d6c6faf81d5d590396571d10"
+  integrity sha512-u4JBLdRI7dargC04p2Ha24kofQBk3vhaf0q8FwSYgnCRwxfvh2RxvhJZk9H7Q91JZp6wgjz/SjvEAYjGCEgAwQ==
+  dependencies:
+    "@babel/runtime" "^7.7.2"
+    "@jimp/utils" "^0.16.1"
+
 "@jimp/plugin-rotate@^0.14.0":
   version "0.14.0"
   resolved "https://registry.yarnpkg.com/@jimp/plugin-rotate/-/plugin-rotate-0.14.0.tgz#3632bc159bf1c3b9ec9f459d9c05d02a11781ee7"
@@ -1600,6 +1661,15 @@
     "@jimp/utils" "^0.14.0"
     pngjs "^3.3.3"
 
+"@jimp/png@^0.16.1":
+  version "0.16.1"
+  resolved "https://registry.yarnpkg.com/@jimp/png/-/png-0.16.1.tgz#f24cfc31529900b13a2dd9d4fdb4460c1e4d814e"
+  integrity sha512-iyWoCxEBTW0OUWWn6SveD4LePW89kO7ZOy5sCfYeDM/oTPLpR8iMIGvZpZUz1b8kvzFr27vPst4E5rJhGjwsdw==
+  dependencies:
+    "@babel/runtime" "^7.7.2"
+    "@jimp/utils" "^0.16.1"
+    pngjs "^3.3.3"
+
 "@jimp/tiff@^0.14.0":
   version "0.14.0"
   resolved "https://registry.yarnpkg.com/@jimp/tiff/-/tiff-0.14.0.tgz#a5b25bbe7c43fc3b07bad4e2ab90e0e164c1967f"
@@ -1608,6 +1678,14 @@
     "@babel/runtime" "^7.7.2"
     utif "^2.0.1"
 
+"@jimp/tiff@^0.16.1":
+  version "0.16.1"
+  resolved "https://registry.yarnpkg.com/@jimp/tiff/-/tiff-0.16.1.tgz#0e8756695687d7574b6bc73efab0acd4260b7a12"
+  integrity sha512-3K3+xpJS79RmSkAvFMgqY5dhSB+/sxhwTFA9f4AVHUK0oKW+u6r52Z1L0tMXHnpbAdR9EJ+xaAl2D4x19XShkQ==
+  dependencies:
+    "@babel/runtime" "^7.7.2"
+    utif "^2.0.1"
+
 "@jimp/types@^0.14.0":
   version "0.14.0"
   resolved "https://registry.yarnpkg.com/@jimp/types/-/types-0.14.0.tgz#ef681ff702883c5f105b5e4e30d49abf39ee9e34"
@@ -1621,6 +1699,19 @@
     "@jimp/tiff" "^0.14.0"
     timm "^1.6.1"
 
+"@jimp/types@^0.16.1":
+  version "0.16.1"
+  resolved "https://registry.yarnpkg.com/@jimp/types/-/types-0.16.1.tgz#0dbab37b3202315c91010f16c31766d35a2322cc"
+  integrity sha512-g1w/+NfWqiVW4CaXSJyD28JQqZtm2eyKMWPhBBDCJN9nLCN12/Az0WFF3JUAktzdsEC2KRN2AqB1a2oMZBNgSQ==
+  dependencies:
+    "@babel/runtime" "^7.7.2"
+    "@jimp/bmp" "^0.16.1"
+    "@jimp/gif" "^0.16.1"
+    "@jimp/jpeg" "^0.16.1"
+    "@jimp/png" "^0.16.1"
+    "@jimp/tiff" "^0.16.1"
+    timm "^1.6.1"
+
 "@jimp/utils@^0.14.0":
   version "0.14.0"
   resolved "https://registry.yarnpkg.com/@jimp/utils/-/utils-0.14.0.tgz#296254e63118554c62c31c19ac6b8c4bfe6490e5"
@@ -1629,6 +1720,14 @@
     "@babel/runtime" "^7.7.2"
     regenerator-runtime "^0.13.3"
 
+"@jimp/utils@^0.16.1":
+  version "0.16.1"
+  resolved "https://registry.yarnpkg.com/@jimp/utils/-/utils-0.16.1.tgz#2f51e6f14ff8307c4aa83d5e1a277da14a9fe3f7"
+  integrity sha512-8fULQjB0x4LzUSiSYG6ZtQl355sZjxbv8r9PPAuYHzS9sGiSHJQavNqK/nKnpDsVkU88/vRGcE7t3nMU0dEnVw==
+  dependencies:
+    "@babel/runtime" "^7.7.2"
+    regenerator-runtime "^0.13.3"
+
 "@mdx-js/mdx@^1.6.22":
   version "1.6.22"
   resolved "https://registry.yarnpkg.com/@mdx-js/mdx/-/mdx-1.6.22.tgz#8a723157bf90e78f17dc0f27995398e6c731f1ba"
@@ -1992,6 +2091,11 @@
   resolved "https://registry.yarnpkg.com/@types/node/-/node-15.12.2.tgz#1f2b42c4be7156ff4a6f914b2fb03d05fa84e38d"
   integrity sha512-zjQ69G564OCIWIOHSXyQEEDpdpGl+G348RAKY0XXy9Z5kU9Vzv1GMNnkar/ZJ8dzXB3COzD9Mo9NtRZ4xfgUww==
 
+"@types/node@^10.12.18":
+  version "10.17.60"
+  resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.60.tgz#35f3d6213daed95da7f0f73e75bcc6980e90597b"
+  integrity sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==
+
 "@types/node@^14.14.10":
   version "14.17.3"
   resolved "https://registry.yarnpkg.com/@types/node/-/node-14.17.3.tgz#6d327abaa4be34a74e421ed6409a0ae2f47f4c3d"
@@ -2186,6 +2290,94 @@
     "@typescript-eslint/types" "4.27.0"
     eslint-visitor-keys "^2.0.0"
 
+"@vibrant/color@^3.2.1-alpha.1":
+  version "3.2.1-alpha.1"
+  resolved "https://registry.yarnpkg.com/@vibrant/color/-/color-3.2.1-alpha.1.tgz#1bcee4545d2276d36f9a1acb42ab3485a9b489ec"
+  integrity sha512-cvm+jAPwao2NerTr3d1JttYyLhp3eD/AQBeevxF7KT6HctToWZCwr2AeTr003/wKgbjzdOV1qySnbyOeu+R+Jw==
+
+"@vibrant/core@^3.2.1-alpha.1":
+  version "3.2.1-alpha.1"
+  resolved "https://registry.yarnpkg.com/@vibrant/core/-/core-3.2.1-alpha.1.tgz#9adff0835b5c750be3386ec01669d2a8d6389fdb"
+  integrity sha512-X9Oa9WfPEQnZ6L+5dLRlh+IlsxJkYTw9b/g3stFKoNXbVRKCeXHmH48l7jIBBOg3VcXOGUdsYBqsTwPNkIveaA==
+  dependencies:
+    "@vibrant/color" "^3.2.1-alpha.1"
+    "@vibrant/generator" "^3.2.1-alpha.1"
+    "@vibrant/image" "^3.2.1-alpha.1"
+    "@vibrant/quantizer" "^3.2.1-alpha.1"
+    "@vibrant/types" "^3.2.1-alpha.1"
+    "@vibrant/worker" "^3.2.1-alpha.1"
+
+"@vibrant/generator-default@^3.2.1-alpha.1":
+  version "3.2.1-alpha.1"
+  resolved "https://registry.yarnpkg.com/@vibrant/generator-default/-/generator-default-3.2.1-alpha.1.tgz#70ae71ea1f72d3e71aa6b244830d01ecae1d755a"
+  integrity sha512-BWnQhDaz92UhyHnpdAzKXHQecY+jvyMXtzjKYbveFxThm6+HVoLjwONlbck7oyOpFzV2OM7V11XuR85BxaHvjw==
+  dependencies:
+    "@vibrant/color" "^3.2.1-alpha.1"
+    "@vibrant/generator" "^3.2.1-alpha.1"
+
+"@vibrant/generator@^3.2.1-alpha.1":
+  version "3.2.1-alpha.1"
+  resolved "https://registry.yarnpkg.com/@vibrant/generator/-/generator-3.2.1-alpha.1.tgz#887b36f7ed978ff94c93cc8a3ac742ce769b6112"
+  integrity sha512-luS5YvMhwMqG01YTj1dJ+cmkuIw1VCByOR6zIaCOwQqI/mcOs88JBWcA1r2TywJTOPlVpjfnDvAlyaKBKh4dMA==
+  dependencies:
+    "@vibrant/color" "^3.2.1-alpha.1"
+    "@vibrant/types" "^3.2.1-alpha.1"
+
+"@vibrant/image-browser@^3.2.1-alpha.1":
+  version "3.2.1-alpha.1"
+  resolved "https://registry.yarnpkg.com/@vibrant/image-browser/-/image-browser-3.2.1-alpha.1.tgz#fe595bfe0c0ddc412300b5419e1e42d8b88d4380"
+  integrity sha512-6xWvQfB20sE6YtCWylgEAHuee3iD8h3aFIDbCS2yj7jIelKcYTrrp5jg2d2BhOOB6pC5JzF+QfpCrm0DmAIlgQ==
+  dependencies:
+    "@vibrant/image" "^3.2.1-alpha.1"
+
+"@vibrant/image-node@^3.2.1-alpha.1":
+  version "3.2.1-alpha.1"
+  resolved "https://registry.yarnpkg.com/@vibrant/image-node/-/image-node-3.2.1-alpha.1.tgz#2901e09aee05d64ac9e792a951ee0727299ab80f"
+  integrity sha512-/Io/Rpo4EkO6AhaXdcxUXkbOFhSFtjm0LSAM4c0AyGA5EbC8PyZqjk8b11bQAEMCaYaweFQfTdGD7oVbXe21CQ==
+  dependencies:
+    "@jimp/custom" "^0.16.1"
+    "@jimp/plugin-resize" "^0.16.1"
+    "@jimp/types" "^0.16.1"
+    "@vibrant/image" "^3.2.1-alpha.1"
+
+"@vibrant/image@^3.2.1-alpha.1":
+  version "3.2.1-alpha.1"
+  resolved "https://registry.yarnpkg.com/@vibrant/image/-/image-3.2.1-alpha.1.tgz#8bcde820f5ad873e2e96b00479def80f86e925a5"
+  integrity sha512-4aF5k79QfyhZOqRovJpbnIjWfe3uuWhY8voqVdd4/qgu4o70/AwVlM+pYmCaJVzI45VWNWWHYA5QlYuKsXnBqQ==
+  dependencies:
+    "@vibrant/color" "^3.2.1-alpha.1"
+    "@vibrant/types" "^3.2.1-alpha.1"
+
+"@vibrant/quantizer-mmcq@^3.2.1-alpha.1":
+  version "3.2.1-alpha.1"
+  resolved "https://registry.yarnpkg.com/@vibrant/quantizer-mmcq/-/quantizer-mmcq-3.2.1-alpha.1.tgz#b36ecb48f4bff9ea35ed23389d8af79c079c079a"
+  integrity sha512-Wuk9PTZtxr8qsWTcgP6lcrrmrq36syVwxf+BUxdgQYntBcQ053SaN34lVGOJ0WPdK5vABoxbYljhceCgiILtZw==
+  dependencies:
+    "@vibrant/color" "^3.2.1-alpha.1"
+    "@vibrant/image" "^3.2.1-alpha.1"
+    "@vibrant/quantizer" "^3.2.1-alpha.1"
+
+"@vibrant/quantizer@^3.2.1-alpha.1":
+  version "3.2.1-alpha.1"
+  resolved "https://registry.yarnpkg.com/@vibrant/quantizer/-/quantizer-3.2.1-alpha.1.tgz#8d29e288ea7acbcd0c9ab8c6b86f80adce606210"
+  integrity sha512-iHnPx/+n4iLtYLm1GClSfyg2fFbMatFG0ipCyp9M6tXNIPAg+pSvUJSGBnVnH7Nl/bR8Gkkj1h0pJ4RsKcdIrQ==
+  dependencies:
+    "@vibrant/color" "^3.2.1-alpha.1"
+    "@vibrant/image" "^3.2.1-alpha.1"
+    "@vibrant/types" "^3.2.1-alpha.1"
+
+"@vibrant/types@^3.2.1-alpha.1":
+  version "3.2.1-alpha.1"
+  resolved "https://registry.yarnpkg.com/@vibrant/types/-/types-3.2.1-alpha.1.tgz#54ecf8b4d1045af699bfaf592e455079801bc951"
+  integrity sha512-ts9u7nsrENoYI5s0MmPOeY5kCLFKvQndKVDOPFCbTA0z493uhDp8mpiQhjFYTf3kPbS04z9zbHLE2luFC7x4KQ==
+
+"@vibrant/worker@^3.2.1-alpha.1":
+  version "3.2.1-alpha.1"
+  resolved "https://registry.yarnpkg.com/@vibrant/worker/-/worker-3.2.1-alpha.1.tgz#d09e4ec72902d36b9632c2c0aab855747acf1015"
+  integrity sha512-mtSlBdHkFNr4FOnMtqtHJxy9z5AsUcZzGlpiHzvWOoaoN9lNTDPwxOBd0q4VTYWuGPrIm6Fuq5m7aRbLv7KqiQ==
+  dependencies:
+    "@vibrant/types" "^3.2.1-alpha.1"
+
 "@webassemblyjs/ast@1.11.0":
   version "1.11.0"
   resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.0.tgz#a5aa679efdc9e51707a4207139da57920555961f"
@@ -8198,6 +8390,11 @@ joi@^17.2.1, joi@^17.4.0:
     "@sideway/formula" "^3.0.0"
     "@sideway/pinpoint" "^2.0.0"
 
+jpeg-js@0.4.2:
+  version "0.4.2"
+  resolved "https://registry.yarnpkg.com/jpeg-js/-/jpeg-js-0.4.2.tgz#8b345b1ae4abde64c2da2fe67ea216a114ac279d"
+  integrity sha512-+az2gi/hvex7eLTMTlbRLOhH6P6WFdk2ITI8HJsaH2VqYO0I594zXSYEP+tf4FW+8Cy68ScDXoAsQdyQanv3sw==
+
 jpeg-js@^0.4.0:
   version "0.4.3"
   resolved "https://registry.yarnpkg.com/jpeg-js/-/jpeg-js-0.4.3.tgz#6158e09f1983ad773813704be80680550eff977b"
@@ -8319,6 +8516,11 @@ junk@^3.1.0:
   resolved "https://registry.yarnpkg.com/junk/-/junk-3.1.0.tgz#31499098d902b7e98c5d9b9c80f43457a88abfa1"
   integrity sha512-pBxcB3LFc8QVgdggvZWyeys+hnrNWg4OcZIU/1X59k5jQdLBlCsYGRQaz234SqoRLTCgMH00fY0xRJH+F9METQ==
 
+kebab-case@^1.0.1:
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/kebab-case/-/kebab-case-1.0.1.tgz#bf734fc95400a3701869215d99a902bd3fe72f60"
+  integrity sha512-txPHx6nVLhv8PHGXIlAk0nYoh894SpAqGPXNvbg2hh8spvHXIah3+vT87DLoa59nKgC6scD3u3xAuRIgiMqbfQ==
+
 keyv@3.0.0:
   version "3.0.0"
   resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.0.0.tgz#44923ba39e68b12a7cec7df6c3268c031f2ef373"
@@ -9472,6 +9674,19 @@ node-releases@^1.1.61, node-releases@^1.1.71:
   resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.73.tgz#dd4e81ddd5277ff846b80b52bb40c49edf7a7b20"
   integrity sha512-uW7fodD6pyW2FZNZnp/Z3hvWKeEW1Y8R1+1CnErE8cXFXzl5blBOoVB41CvMer6P6Q0S5FXDwcHgFd1Wj0U9zg==
 
+node-vibrant@^3.2.1-alpha.1:
+  version "3.2.1-alpha.1"
+  resolved "https://registry.yarnpkg.com/node-vibrant/-/node-vibrant-3.2.1-alpha.1.tgz#d80a3dd22741150b804ae0d3eb99ceaf9f79980a"
+  integrity sha512-EQergCp7fvbvUCE0VMCBnvaAV0lGWSP8SXLmuWQIBzQK5M5pIwcd9fIOXuzFkJx/8hUiiiLvAzzGDS/bIy2ikA==
+  dependencies:
+    "@types/node" "^10.12.18"
+    "@vibrant/core" "^3.2.1-alpha.1"
+    "@vibrant/generator-default" "^3.2.1-alpha.1"
+    "@vibrant/image-browser" "^3.2.1-alpha.1"
+    "@vibrant/image-node" "^3.2.1-alpha.1"
+    "@vibrant/quantizer-mmcq" "^3.2.1-alpha.1"
+    url "^0.11.0"
+
 noms@0.0.0:
   version "0.0.0"
   resolved "https://registry.yarnpkg.com/noms/-/noms-0.0.0.tgz#da8ebd9f3af9d6760919b27d9cdc8092a7332859"