Repository: maykinmedia/django-admin-index (language: python)

Issue:
Templates are not properly namespaced
With the 1.6 release (and possibly before that), there admin-index templates override admin templates (correctly) and include some includes, see https://github.com/maykinmedia/django-admin-index/tree/master/django_admin_index/templates

These `includes` should be namespaced under `django_admin_index/includes` rather than being directly in the top-level namespace. The current template in there has a fairly generic template name of `includes/app_list.html` which is bound to cause conflicts at some point. This should be `django_admin_index/includes/app_list.html`, which also allows for more specific overrides if needed.


Discussion / hints:

Fix patch:
diff --git a/.editorconfig b/.editorconfig
index 22fb1f9..cab4062 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -10,5 +10,8 @@ insert_final_newline = true
 charset = utf-8
 end_of_line = lf
 
+[*.scss]
+indent_size = 2
+
 [Makefile]
 indent_style = tab
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index ef818b5..77f14d0 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -14,15 +14,13 @@ jobs:
     runs-on: ubuntu-latest
     strategy:
       matrix:
-        python: ['3.7', '3.8', '3.10']
-        django: ['2.2', '3.0', '3.2', '4.0']
+        python: ['3.7', '3.8', '3.9', '3.10']
+        django: ['2.2', '3.2', '4.0']
         exclude:
-          - python: '3.7'
-            django: '4.0'
-          - python: '3.8'
-            django: '2.2'
           - python: '3.10'
             django: '2.2'
+          - python: '3.7'
+            django: '4.0'
 
     name: Run the test suite (Python ${{ matrix.python }}, Django ${{ matrix.django }})
 
diff --git a/.isort.cfg b/.isort.cfg
deleted file mode 100644
index 3a01115..0000000
--- a/.isort.cfg
+++ /dev/null
@@ -1,4 +0,0 @@
-[settings]
-line_length=119
-known_third_party=django
-known_first_party=django_admin_index
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index fa73006..414f288 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -2,6 +2,49 @@
 Change history
 ==============
 
+2.0.0
+=====
+
+*March ??, 2022*
+
+This release contains breaking changes in the admin markup and stylesheets, hence the
+major version bump.
+
+Breaking changes
+----------------
+
+* Dropped support for non-LTS Django versions (1.11, 3.0). Only Django 2.2, 3.2 and 4.0
+  are officially supported and tested.
+* Fixed #69 -- Properly namespaced the ``includes/app_list.html`` template to
+  ``django_admin_index/includes/app_list.html``
+* Refactored the styling (#71)
+
+    * All django-admin-index classnames now have a ``djai-`` prefix to prevent
+      collissions (e.g. bootstrap has a ``dropdown-menu`` as well)
+    * Colour definitions now leverage the Django 3.2 CSS variables, see
+      ``scss/_vars.scss``. For Django < 3.2 these don't exist, but the fallback values
+      are defined. This makes it easier to theme django-admin-index in your project by
+      just overriding the CSS variables instead of the entire relevant selector.
+    * The markup of the ``django_admin_index/includes/app_list.html`` has been slightly
+      modified, some class names are moved around.
+    * The breadcrumbs are no longer sticky/fixed by default, override this in your own
+      styling if desired. Possibly in the future this may be controllable with a CSS var.
+    * Made a mimimal working layout on mobile. Tabs wrap on the next line and the menus
+      are no longer hidden behind the breadcrumbs.
+
+* Reduced amount of overridden ``django.contrib.admin`` template code - people
+  overriding the django-admin-index templates may want to revisit these.
+
+Other improvements
+------------------
+
+* Added optional support for Django Debug Toolbar
+* Added template overrides for ``registration/password_reset_form.html`` and
+  ``registration/password_reset_done.html``
+* Updated isort config to be black-compatible
+* Updated test project (used for local testing and CI) to Django 2.2 and Django 3.2+
+* Included ``AppConfig.default_auto_field`` for Django 3.2+
+
 1.6.0
 =====
 
diff --git a/CONTRIBUTORS.rst b/CONTRIBUTORS.rst
index fe18590..87c5c7d 100644
--- a/CONTRIBUTORS.rst
+++ b/CONTRIBUTORS.rst
@@ -10,4 +10,5 @@ Contributors
 * Baptiste Darthenay (@batisteo)
 * Sven van de Scheur (@svenvandescheur)
 * Alex de Landgraaf (@alextreme)
-* Steven Bal (@stevenbal)
\ No newline at end of file
+* Steven Bal (@stevenbal)
+* Sergei Maertens (@sergei-maertens)
diff --git a/README.rst b/README.rst
index 88b7fe2..3310215 100644
--- a/README.rst
+++ b/README.rst
@@ -115,16 +115,41 @@ There are 3 settings you can add to your ``settings.py``:
 Extra
 =====
 
+Theming
+-------
+
+By default, django-admin-index tabs/dropdowns are styled in the Django admin theme
+colours. On Django 3.2+ these are controlled through CSS variables in the
+``static/admin/css/base.css`` stylesheet. These CSS variables are used as defaults for
+django-admin-index' own CSS variables.
+
+See ``scss/_vars.scss`` for all the available CSS variables you can use to customize
+the color palette. A simple example:
+
+.. code-block:: css
+
+    :root {
+      --djai-tab-bg: #ff0080;
+      --djai-tab-bg--hover: #a91b60;
+    }
+
+Any rules not supported by CSS vars can be overridden with regular CSS. All elements
+have CSS class names following the BEM methodology, such as
+``.djai-dropdown-menu__item`` and
+``.djai-dropdown-menu__item.djai-dropdown-menu__item--active``.
+
+
 Sticky header
 -------------
 
 The header (typically "Django administration") including the menu (added by this
-library) and the breadcrumbs, all become sticky (ie. they stay visible when you scroll
-down on large pages). If you don't want this, you can add some CSS lines, like::
+library) become sticky (ie. they stay visible when you scroll down on large pages). If
+you don't want this, you can add some CSS lines, like::
+
+.. code-block:: css
 
     #header { position: initial; }
     .dropdown-menu { position: initial; }
-    .breadcrumbs { position: initial; }
 
 
 Breadcrumbs
@@ -132,7 +157,9 @@ Breadcrumbs
 
 You can also squeeze additional content in the breadcrumbs, just after
 ``Home``. Simply overwrite the block ``breadcrumbs_pre_changelist`` in the
-admin templates you desire (``change_list.html``, ``change_form.html``, etc.)::
+admin templates you desire (``change_list.html``, ``change_form.html``, etc.)
+
+.. code-block:: django
 
     {% block breadcrumbs_pre_changelist %}
     &rsaquo; Meaningful breadcrumb element
diff --git a/django_admin_index/admin.py b/django_admin_index/admin.py
index b9388e6..96bba58 100644
--- a/django_admin_index/admin.py
+++ b/django_admin_index/admin.py
@@ -1,6 +1,7 @@
 from __future__ import absolute_import, unicode_literals
 
 from django.contrib import admin
+
 from ordered_model.admin import OrderedModelAdmin
 
 from .models import AppGroup, AppLink
diff --git a/django_admin_index/apps.py b/django_admin_index/apps.py
index 134d2ee..944739c 100644
--- a/django_admin_index/apps.py
+++ b/django_admin_index/apps.py
@@ -13,6 +13,8 @@ class AdminIndexConfig(AppConfig):
     name = "django_admin_index"
     label = "admin_index"
     verbose_name = _("Admin Index")
+    # swap to BigAutoField once we drop 2.2 support & then generate migrations
+    default_auto_field = "django.db.models.AutoField"
 
     def ready(self):
         register(check_admin_index_app, Tags.compatibility)
@@ -21,8 +23,6 @@ def ready(self):
 
 
 def check_admin_index_app(app_configs, **kwargs):
-    from django.conf import settings
-
     issues = []
     app_config_names = [app_config.name for app_config in apps.get_app_configs()]
 
diff --git a/django_admin_index/models.py b/django_admin_index/models.py
index 0c16344..d2d8f6d 100644
--- a/django_admin_index/models.py
+++ b/django_admin_index/models.py
@@ -6,6 +6,7 @@
 from django.urls import reverse
 from django.utils.text import capfirst
 from django.utils.translation import gettext_lazy as _
+
 from ordered_model.models import OrderedModel, OrderedModelQuerySet
 
 from .conf import settings
diff --git a/django_admin_index/static/admin/css/admin-index.css b/django_admin_index/static/admin/css/admin-index.css
index 5c64ed8..e5a9f78 100644
--- a/django_admin_index/static/admin/css/admin-index.css
+++ b/django_admin_index/static/admin/css/admin-index.css
@@ -1,2 +1,2 @@
-.breadcrumbs{position:fixed;top:84px;z-index:4000;width:100%;padding:12px 40px!important}.dropdown-menu{position:fixed;top:42px;display:block;cursor:pointer;margin-top:8px;z-index:5000}.dropdown-menu .dropdown-menu__item,.dropdown-menu .dropdown-menu__item:link,.dropdown-menu .dropdown-menu__item:visited{color:#fff;display:inline-block;padding:10px;position:relative;z-index:50;background-color:#4383a3}.dropdown-menu .dropdown-menu__item.dropdown-menu__item--active,.dropdown-menu .dropdown-menu__item:link.dropdown-menu__item--active,.dropdown-menu .dropdown-menu__item:visited.dropdown-menu__item--active{background-color:#79aec8;text-decoration:none}.dropdown-menu .dropdown-menu__item:hover,.dropdown-menu .dropdown-menu__item:link:hover,.dropdown-menu .dropdown-menu__item:visited:hover{background-color:#79aec8;text-decoration:none!important}.dropdown-menu .dropdown-menu__item:hover .dropdown-menu__drop,.dropdown-menu .dropdown-menu__item:link:hover .dropdown-menu__drop,.dropdown-menu .dropdown-menu__item:visited:hover .dropdown-menu__drop{display:block}.dropdown-menu .dropdown-menu__drop{box-shadow:0 4px 8px 0 rgba(0,0,0,.2),0 6px 20px 0 rgba(0,0,0,.2);position:absolute;left:0;top:100%;display:none;background-color:#417690;min-width:150px;z-index:50}.dropdown-menu .dropdown-menu__link,.dropdown-menu .dropdown-menu__link:link,.dropdown-menu .dropdown-menu__link:visited{color:#fff;display:block;padding:10px}.dropdown-menu .dropdown-menu__link:hover,.dropdown-menu .dropdown-menu__link:link:hover,.dropdown-menu .dropdown-menu__link:visited:hover{background-color:#79aec8;text-decoration:none!important}.dropdown-menu .dropdown-menu__link.dropdown-menu__link--active,.dropdown-menu .dropdown-menu__link:link.dropdown-menu__link--active,.dropdown-menu .dropdown-menu__link:visited.dropdown-menu__link--active{background-color:#79aec8;text-decoration:none}#header{display:grid;grid-template-columns:2fr 2fr;grid-template-rows:1fr 1fr;grid-gap:10px;z-index:5000;position:fixed;width:calc(100% - 50px)}@media (max-width:768px){#header{width:calc(100% - 20px)}}#content,#main{padding-top:104px}#content #nav-sidebar,#main #nav-sidebar{position:static}.content #content{padding-top:0}body[class*=change-] #content,body[class*=change-] #main{padding-top:144px}body[class*=change-] #content #nav-sidebar,body[class*=change-] #main #nav-sidebar{position:static}body[class*=change-] .content #content{padding-top:0}
+#content{position:relative;z-index:1}#container{min-height:100%;height:auto}#main{z-index:1}#header{z-index:2}#nav-sidebar{top:var(--djai-nav-sidebar-offset,84px)}#header{position:sticky;top:0;overflow:visible}.djai-dropdown-menu{flex-basis:100%;display:block;margin-top:var(--djai-tablist-spacing-top,10px)}#header{flex-wrap:wrap;padding-bottom:0}.djai-dropdown-menu .djai-dropdown-menu__item{display:inline-block;position:relative;padding:10px;background-color:var(--djai-tab-bg,#4383a3);cursor:pointer}.djai-dropdown-menu .djai-dropdown-menu__item,.djai-dropdown-menu .djai-dropdown-menu__item:link,.djai-dropdown-menu .djai-dropdown-menu__item:visited{color:var(--djai-tab-fg,var(--primary-fg,#fff))}.djai-dropdown-menu .djai-dropdown-menu__item--active{background-color:var(--djai-tab-bg--active,var(--primary,#79aec8))}.djai-dropdown-menu .djai-dropdown-menu__item--active,.djai-dropdown-menu .djai-dropdown-menu__item--active:link,.djai-dropdown-menu .djai-dropdown-menu__item--active:visited{text-decoration:none;color:var(--djai-tab-fg--active,var(--primary-fg,#fff))}.djai-dropdown-menu .djai-dropdown-menu__item:focus,.djai-dropdown-menu .djai-dropdown-menu__item:hover{background-color:var(--djai-tab-bg--hover,var(--primary,#79aec8))}.djai-dropdown-menu .djai-dropdown-menu__item:focus,.djai-dropdown-menu .djai-dropdown-menu__item:focus:link,.djai-dropdown-menu .djai-dropdown-menu__item:focus:visited,.djai-dropdown-menu .djai-dropdown-menu__item:hover,.djai-dropdown-menu .djai-dropdown-menu__item:hover:link,.djai-dropdown-menu .djai-dropdown-menu__item:hover:visited{text-decoration:none!important;color:var(--djai-tab-fg--hover,var(--primary-fg,#fff))}.djai-dropdown-menu .djai-dropdown-menu__item:focus .djai-dropdown-menu__drop,.djai-dropdown-menu .djai-dropdown-menu__item:hover .djai-dropdown-menu__drop{display:block}.djai-dropdown-menu .djai-dropdown-menu__drop{display:none;position:absolute;left:0;top:100%;min-width:150px;z-index:1;max-height:75vh;overflow-y:auto;background-color:var(--djai-dropdown-bg,var(--secondary,#417690));box-shadow:0 4px 8px 0 rgba(0,0,0,.2),0 6px 20px 0 rgba(0,0,0,.2)}.djai-dropdown-menu .djai-dropdown-menu__drop-item{background-color:transparent}.djai-dropdown-menu .djai-dropdown-menu__drop-item--active{background-color:var(--djai-dropdown-bg--active,var(--primary,#79aec8))}.djai-dropdown-menu .djai-dropdown-menu__drop-item:focus,.djai-dropdown-menu .djai-dropdown-menu__drop-item:hover{background-color:var(--djai-dropdown-bg--hover,var(--primary,#79aec8))}#header .djai-dropdown-menu .djai-dropdown-menu__drop-item a,#header .djai-dropdown-menu .djai-dropdown-menu__drop-item a:link,#header .djai-dropdown-menu .djai-dropdown-menu__drop-item a:visited{color:var(--djai-dropdown-fg,var(--header-link-color,var(--primary-fg,#fff)))}#header .djai-dropdown-menu .djai-dropdown-menu__drop-item a:hover{text-decoration:none}.djai-dropdown-menu .djai-dropdown-menu__link{display:block;padding:10px}@media (max-width:767px){.breadcrumbs{position:relative;z-index:1}.djai-dropdown-menu{align-self:flex-start}.djai-dropdown-menu .djai-dropdown-menu__item{margin-top:3px}}
 /*# sourceMappingURL=/admin-index.css.map */
\ No newline at end of file
diff --git a/django_admin_index/static/admin/css/admin-index.css.map b/django_admin_index/static/admin/css/admin-index.css.map
index 5ce6cf6..d4ac75c 100644
--- a/django_admin_index/static/admin/css/admin-index.css.map
+++ b/django_admin_index/static/admin/css/admin-index.css.map
@@ -1,1 +1,1 @@
-{"version":3,"sources":["components/_breadcrumbs.scss","components/_dropdown-menu.scss","components/_header.scss","components/_main.scss"],"names":[],"mappings":"AAAA,aAEI,cAAA,CACA,QAAA,CACA,YAAA,CACA,UAAA,CACA,4BCNJ,eAEI,cAAA,CACA,QAAA,CACA,aAAA,CACA,cAAA,CACA,cAAA,CACA,aAEA,yHAGI,UAAA,CACA,oBAAA,CACA,YAAA,CACA,iBAAA,CACA,UAAA,CACA,yBAEA,6MACI,wBAAA,CACA,qBAGJ,2IACI,wBAAA,CACA,+BAEA,0MACI,cAKZ,oCACI,iEAAA,CACA,iBAAA,CACA,MAAA,CACA,QAAA,CACA,YAAA,CACA,wBAAA,CACA,eAAA,CACA,WAGJ,yHAGI,UAAA,CACA,aAAA,CACA,aAEA,2IACI,wBAAA,CACA,+BAGJ,6MACI,wBAAA,CACA,qBC3DZ,QACI,YAAA,CACA,6BAAA,CACA,0BAAA,CACA,aAAA,CACA,YAAA,CACA,cAAA,CAEA,wBAEA,yBAVJ,QAWQ,yBCXR,eAGI,kBAEA,yCACI,gBAMJ,kBACI,cAKJ,yDAGI,kBAEA,mFACI,gBAMJ,uCACI","file":"admin-index.css","sourceRoot":"../../../../scss","sourcesContent":[".breadcrumbs {\n    /* Show the header at all times */\n    position: fixed;\n    top: 84px;\n    z-index: 4000;\n    width: 100%;\n    padding: 12px 40px !important;\n}\n",".dropdown-menu {\n    /* Show the header at all times */\n    position: fixed;\n    top: 42px;\n    display: block;\n    cursor: pointer;\n    margin-top: 8px;\n    z-index: 5000;\n\n    .dropdown-menu__item,\n    .dropdown-menu__item:link,\n    .dropdown-menu__item:visited {\n        color: #fff;\n        display: inline-block;\n        padding: 10px;\n        position: relative;\n        z-index: 50;\n        background-color: #4383a3;\n\n        &.dropdown-menu__item--active {\n            background-color: #79aec8;\n            text-decoration: none;\n        }\n\n        &:hover {\n            background-color: #79aec8;\n            text-decoration: none !important;\n\n            .dropdown-menu__drop {\n                display: block;\n            }\n        }\n    }\n\n    .dropdown-menu__drop {\n        box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.2);\n        position: absolute;\n        left: 0;\n        top: 100%;\n        display: none;\n        background-color: #417690;\n        min-width: 150px;\n        z-index: 50;\n    }\n\n    .dropdown-menu__link,\n    .dropdown-menu__link:link,\n    .dropdown-menu__link:visited {\n        color: #fff;\n        display: block;\n        padding: 10px;\n\n        &:hover {\n            background-color: #79aec8;\n            text-decoration: none !important;\n        }\n\n        &.dropdown-menu__link--active {\n            background-color: #79aec8;\n            text-decoration: none;\n        }\n    }\n}\n","#header {\n    display: grid;\n    grid-template-columns: 2fr 2fr;\n    grid-template-rows: 1fr 1fr;\n    grid-gap: 10px;\n    z-index: 5000;\n    position: fixed;\n\n    width: calc(100% - 50px);\n\n    @media (max-width: 768px) {\n        width: calc(100% - 20px);\n    }\n}\n","#main,\n#content // < Django 3.2\n{\n    padding-top: 104px;\n\n    #nav-sidebar {\n        position: initial;\n    }\n}\n\n.content // > Django 3.2\n{\n    #content {\n        padding-top: 0;\n    }\n}\n\nbody[class*=\"change-\"] {\n    #main,\n    #content // < Django 3.2\n    {\n        padding-top: 144px;\n\n        #nav-sidebar {\n            position: initial;\n        }\n    }\n\n    .content // > Django 3.2\n    {\n        #content {\n            padding-top: 0;\n        }\n    }\n}\n\n"]}
\ No newline at end of file
+{"version":3,"sources":["_django22.scss","components/_containers.scss","components/_header.scss","components/_dropdown-menu.scss","_vars.scss"],"names":[],"mappings":"AAGA,SAGE,iBAAA,CACA,UCFF,WAGE,eAAA,CACA,YAGF,MAIE,UAGF,QACE,UAGF,aACE,wCCRF,QACE,eAAA,CACA,KAAA,CAEA,iBCFF,oBAQE,eAAA,CAGA,aAAA,CACA,gDAVS,QACP,cAAA,CAEA,iBASF,8CACE,oBAAA,CACA,iBAAA,CACA,YAAA,CACA,2CCtBU,CDuBV,eAzBF,uJA4BI,gDAGF,sDACE,mEAhCJ,+KAmCM,oBAAA,CACA,wDAKJ,wGAEE,kEA3CJ,kVA8CM,8BAAA,CACA,uDAGF,4JACE,cAKN,8CACE,YAAA,CAGA,iBAAA,CACA,MAAA,CACA,QAAA,CACA,eAAA,CACA,SAAA,CAGA,eAAA,CACA,eAAA,CAGA,iEC9De,CD+Df,kEAIF,mDAEE,6BAEA,2DACE,wEAIF,kHAEE,uEAvFJ,oMA6FM,8EAGF,mEACE,qBAKN,8CACE,aAAA,CACA,aAMJ,yBAGE,aACE,iBAAA,CACA,UAGF,oBACE,sBAEA,8CACE","file":"admin-index.css","sourceRoot":"../../../../scss","sourcesContent":["/*\nDjango 2.2 specific fixes\n */\n#content {\n  // fix the filter bar on the right being layered over the header.\n  // header has z-index: 2 so within the stack context this layers on top now.\n  position: relative;\n  z-index: 1;\n}\n","/*\nOverride some containers to make the sticky header work with Django.\n */\n@import '../vars';\n\n#container {\n  // Django itself sets height: 100%, which causes the container to be less high than\n  // the content and that in turn causes the sticky header to fall off the page.\n  min-height: 100%;\n  height: auto;\n}\n\n#main {\n  // z-index is contextual, by specifying it explicitly here, we can have our header\n  // use z-index relative to this one without having to fiddle with #main child element\n  // z-indices.\n  z-index: 1;\n}\n\n#header {\n  z-index: 2; // overlay the #main container, which contains the sidebar on Django 3.2+\n}\n\n#nav-sidebar {\n  top: $djai-nav-sidebar-offset;\n}\n","/*\nThe header is the container for our admin-index menu dropdown, which we make\nvisible at all times. For this, the header itself needs to receive a position fixes or\nsticky so that it stays in view when scrolling down vertically.\n\nIf the header itself is sticky and the container for the dropdowns, we don't need to\nmess with height offsets relative to the header/branding - which may not be pixel-\nperfect because of font-rendering shenanigans.\n\nWe also stick to Django's flexbox model for the header and don't force it into a CSS\ngrid layout. (TODO: check on 2.2 what the CSS looks like).\n\nTODO: future enhancement -> control position of header/admin menu via CSS var, so users\nhave the option to easily specify static/sticky positioning.\n */\n\n#header {\n  position: sticky;\n  top: 0;\n  // the dropdown menu is a child and overflows\n  overflow: visible;\n}\n","/*\nThe dropdown menu is injected as a child into the header, which has a flexbox display\nstyle (direction: row). This causes the menu to be on the same row as the branding and\nuser tools. However, we set the flex-basis to 100% to make it take up the full width\nof the container and let the parent wrap.\n */\n@import '../vars';\n\n$djai-block: 'djai-dropdown-menu';\n\n\n@mixin link-style() {\n  &, &:link, &:visited {\n    @content;\n  }\n}\n\n\n.#{$djai-block} {\n  // position it properly in the header as a separate row\n  @at-root #header {\n    flex-wrap: wrap;\n    // remove the padding at the bottom so our dropdown items line up\n    padding-bottom: 0;\n  }\n\n  flex-basis: 100%;\n\n  // own layout\n  display: block;\n  margin-top: $djai-tablist-spacing-top;\n\n  & &__item {\n    display: inline-block;\n    position: relative;\n    padding: 10px;\n    background-color: $djai-tab-bg;\n    cursor: pointer;\n\n    @include link-style {\n      color: $djai-tab-fg;\n    }\n\n    &--active {\n      background-color: $djai-tab-bg--active;\n\n      @include link-style {\n        text-decoration: none;\n        color: $djai-tab-fg--active;\n      }\n    }\n\n    // deliberately after the --active style so it overrides it\n    &:hover,\n    &:focus {\n      background-color: $djai-tab-bg--hover;\n\n      @include link-style {\n        text-decoration: none !important;\n        color: $djai-tab-fg--hover;\n      }\n\n      .#{$djai-block}__drop {\n        display: block;\n      }\n    }\n  }\n\n  & &__drop {\n    display: none; // hidden by default, visible by hovering over the parent\n\n    // position it relative to the tab\n    position: absolute;\n    left: 0;\n    top: 100%;\n    min-width: 150px;\n    z-index: 1;\n\n    // ensure that very long lists have scrollable content\n    max-height: 75vh;\n    overflow-y: auto;\n\n    // theme\n    background-color: $djai-dropdown-bg;\n    box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2),\n                0 6px 20px 0 rgba(0, 0, 0, 0.2);\n  }\n\n  & &__drop-item {\n\n    background-color: transparent;  // take the bg color of the dropdown block\n\n    &--active {\n      background-color: $djai-dropdown-bg--active;\n    }\n\n    // deliberately after the --active style so it overrides it\n    &:hover,\n    &:focus {\n      background-color: $djai-dropdown-bg--hover;\n    }\n\n    // force a more specific rule so our own color overrides are used\n    @at-root #header & a {\n      @include link-style {\n        color: $djai-dropdown-fg;\n      }\n\n      &:hover {\n        text-decoration: none;\n      }\n    }\n  }\n\n  & &__link {\n    display: block;\n    padding: 10px;\n  }\n\n}\n\n// mobile styling\n@media (max-width: $djai-breakpoint--mobile) {\n  // ensure that the dropdown menus are on top of the breadcrumbs instead of hidden\n  // behind them. The #header element has z-index 2.\n  .breadcrumbs {\n    position: relative;\n    z-index: 1;\n  }\n\n  .#{$djai-block} {\n    align-self: flex-start;  // don't center, but align left\n\n    & &__item {\n      margin-top: 3px;\n    }\n  }\n}\n","// Define SASS variables which emit the CSS variables from Django 3.2 with a default\n// value for Django 2.2. Once support is dropped for Django 2.2, we can remove the\n// defaults as Django itself defines these variables in `admin/css/base.css`.\n\n$color-primary: var(--primary, #79aec8);\n$color-secondary: var(--secondary, #417690);\n$color-primary-fg: var(--primary-fg, #fff);\n\n$color-header-link-color: var(--header-link-color, #{$color-primary-fg});\n\n/* admin-index specific variables */\n// default of 10px is the padding-bottom default of the header\n$djai-tablist-spacing-top: var(--djai-tablist-spacing-top, 10px);\n\n$djai-tab-bg: var(--djai-tab-bg, #4383a3);\n$djai-tab-bg--active: var(--djai-tab-bg--active, #{$color-primary});\n$djai-tab-bg--hover: var(--djai-tab-bg--hover, #{$color-primary});\n$djai-tab-fg: var(--djai-tab-fg, #{$color-primary-fg});\n$djai-tab-fg--active: var(--djai-tab-fg--active, #{$color-primary-fg});\n$djai-tab-fg--hover: var(--djai-tab-fg--hover, #{$color-primary-fg});\n\n$djai-dropdown-bg: var(--djai-dropdown-bg, #{$color-secondary});\n$djai-dropdown-bg--active: var(--djai-dropdown-bg--active, #{$color-primary});\n$djai-dropdown-bg--hover: var(--djai-dropdown-bg--hover, #{$color-primary});\n$djai-dropdown-fg: var(--djai-dropdown-fg, #{$color-header-link-color});\n\n// compensate for the sticky header by offsetting the nav sidebar. Default values\n// come from a clean django-startproject on Django 3.2 with the standard admin CSS.\n// If you use different fonts/paddings... etc, you can override this variable for your\n// own situation.\n$default-nav-sidebar-offset: 10px + 28px + 46px;  // heading padding top + branding height + dropdown-menu\n$djai-nav-sidebar-offset: var(--djai-nav-sidebar-offset, #{$default-nav-sidebar-offset});\n\n/*\n  Responsive styling. Breakpoints are taken from Django 3.2 admin/css/responsive.css\n*/\n$djai-breakpoint--mobile: 767px;\n$djai-breakpoint--tablet: 1024px;\n"]}
\ No newline at end of file
diff --git a/django_admin_index/templates/admin/change_form.html b/django_admin_index/templates/admin/change_form.html
index 6d77361..c309da0 100644
--- a/django_admin_index/templates/admin/change_form.html
+++ b/django_admin_index/templates/admin/change_form.html
@@ -1,106 +1,21 @@
-{% extends "admin/base_site.html" %}
-{% load i18n admin_urls static admin_modify django_admin_index %}
+{% extends "admin/change_form.html" %}
+{% load i18n admin_urls django_admin_index %}
 
-{% block extrahead %}{{ block.super }}
-    <script type="text/javascript" src="{% url 'admin:jsi18n' %}"></script>
-    {{ media }}
-{% endblock %}
-
-{% block extrastyle %}{{ block.super }}
-    <link rel="stylesheet" type="text/css" href="{% static "admin/css/forms.css" %}">{% endblock %}
-
-{% block coltype %}colM{% endblock %}
-
-{% block bodyclass %}{{ block.super }} app-{{ opts.app_label }} model-{{ opts.model_name }} change-form{% endblock %}
-
-{% block nav-global %}{% include "includes/app_list.html" %}{% endblock nav-global %}
+{% block nav-global %}{% include "django_admin_index/includes/app_list.html" %}{% endblock nav-global %}
 
 {% if not is_popup %}
-    {% block breadcrumbs %}
-        {% admin_index_settings as admin_index_settings %}
-        <div class="breadcrumbs">
-            <a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
-            {# NOTE: Remove app groups if needed #}
-            {% if not admin_index_settings.HIDE_APP_INDEX_PAGES %}
-                &rsaquo;
-                <a href="{% url 'admin:app_list' app_label=opts.app_label %}">{{ opts.app_config.verbose_name }}</a>
-            {% endif %}
-            {% block breadcrumbs_pre_changelist %}{% endblock %}
-            &rsaquo; {% if has_view_permission or has_change_permission %}
-            <a href="{% url opts|admin_urlname:'changelist' %}">{{ opts.verbose_name_plural|capfirst }}</a>{% else %}
-            {{ opts.verbose_name_plural|capfirst }}{% endif %}
-            &rsaquo; {% if add %}{% blocktrans with name=opts.verbose_name %}Add {{ name }}{% endblocktrans %}{% else %}
-            {{ original|truncatewords:"18" }}{% endif %}
-        </div>
-    {% endblock %}
+{% block breadcrumbs %}
+{% admin_index_settings as admin_index_settings %}
+<div class="breadcrumbs">
+<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
+{# NOTE: Remove app groups if needed #}
+{% if not admin_index_settings.HIDE_APP_INDEX_PAGES %}
+    &rsaquo;
+    <a href="{% url 'admin:app_list' app_label=opts.app_label %}">{{ opts.app_config.verbose_name }}</a>
 {% endif %}
-
-{% block content %}
-    <div id="content-main">
-        {% block object-tools %}
-            {% if change %}{% if not is_popup %}
-                <ul class="object-tools">
-                    {% block object-tools-items %}
-                        {# NOTE: This does not work in Django 1.11 and 2.0. The template part remains the same. #}
-                        {# {% change_form_object_tools %} #}
-                        <li>
-                            {% url opts|admin_urlname:'history' original.pk|admin_urlquote as history_url %}
-                            <a href="{% add_preserved_filters history_url %}"
-                               class="historylink">{% trans "History" %}</a>
-                        </li>
-                        {% if has_absolute_url %}
-                            <li><a href="{{ absolute_url }}" class="viewsitelink">{% trans "View on site" %}</a></li>
-                        {% endif %}
-                    {% endblock %}
-                </ul>
-            {% endif %}{% endif %}
-        {% endblock %}
-        <form {% if has_file_field %}enctype="multipart/form-data" {% endif %}action="{{ form_url }}" method="post"
-              id="{{ opts.model_name }}_form" novalidate>{% csrf_token %}{% block form_top %}{% endblock %}
-            <div>
-                {% if is_popup %}<input type="hidden" name="{{ is_popup_var }}" value="1">{% endif %}
-                {% if to_field %}<input type="hidden" name="{{ to_field_var }}" value="{{ to_field }}">{% endif %}
-                {% if save_on_top %}{% block submit_buttons_top %}{% submit_row %}{% endblock %}{% endif %}
-                {% if errors %}
-                    <p class="errornote">
-                        {% if errors|length == 1 %}{% trans "Please correct the error below." %}{% else %}
-                            {% trans "Please correct the errors below." %}{% endif %}
-                    </p>
-                    {{ adminform.form.non_field_errors }}
-                {% endif %}
-
-                {% block field_sets %}
-                    {% for fieldset in adminform %}
-                        {% include "admin/includes/fieldset.html" %}
-                    {% endfor %}
-                {% endblock %}
-
-                {% block after_field_sets %}{% endblock %}
-
-                {% block inline_field_sets %}
-                    {% for inline_admin_formset in inline_admin_formsets %}
-                        {% include inline_admin_formset.opts.template %}
-                    {% endfor %}
-                {% endblock %}
-
-                {% block after_related_objects %}{% endblock %}
-
-                {% block submit_buttons_bottom %}{% submit_row %}{% endblock %}
-
-                {% block admin_change_form_document_ready %}
-                    <script type="text/javascript"
-                            id="django-admin-form-add-constants"
-                            src="{% static 'admin/js/change_form.js' %}"
-                        {% if adminform and add %}
-                            data-model-name="{{ opts.model_name }}"
-                        {% endif %}>
-                    </script>
-                {% endblock %}
-
-                {# JavaScript for prepopulated fields #}
-                {% prepopulated_fields_js %}
-
-            </div>
-        </form>
-    </div>
+{% block breadcrumbs_pre_changelist %}{% endblock %}
+&rsaquo; {% if has_view_permission %}<a href="{% url opts|admin_urlname:'changelist' %}">{{ opts.verbose_name_plural|capfirst }}</a>{% else %}{{ opts.verbose_name_plural|capfirst }}{% endif %}
+&rsaquo; {% if add %}{% blocktrans with name=opts.verbose_name %}Add {{ name }}{% endblocktrans %}{% else %}{{ original|truncatewords:"18" }}{% endif %}
+</div>
 {% endblock %}
+{% endif %}
diff --git a/django_admin_index/templates/admin/change_list.html b/django_admin_index/templates/admin/change_list.html
index 0ea2a26..9cb1e02 100644
--- a/django_admin_index/templates/admin/change_list.html
+++ b/django_admin_index/templates/admin/change_list.html
@@ -1,107 +1,20 @@
-{% extends "admin/base_site.html" %}
-{% load i18n admin_urls static admin_list django_admin_index %}
+{% extends "admin/change_list.html" %}
+{% load i18n admin_urls django_admin_index %}
 
-{% block extrastyle %}
-    {{ block.super }}
-    <link rel="stylesheet" type="text/css" href="{% static "admin/css/changelists.css" %}">
-    {% if cl.formset %}
-        <link rel="stylesheet" type="text/css" href="{% static "admin/css/forms.css" %}">
-    {% endif %}
-    {% if cl.formset or action_form %}
-        <script type="text/javascript" src="{% url 'admin:jsi18n' %}"></script>
-    {% endif %}
-    {{ media.css }}
-    {% if not actions_on_top and not actions_on_bottom %}
-        <style>
-            #changelist table thead th:first-child {
-                width: inherit
-            }
-        </style>
-    {% endif %}
-{% endblock %}
-
-{% block extrahead %}
-    {{ block.super }}
-    {{ media.js }}
-{% endblock %}
-
-{% block bodyclass %}{{ block.super }} app-{{ opts.app_label }} model-{{ opts.model_name }} change-list{% endblock %}
-
-{% block nav-global %}{% include "includes/app_list.html" %}{% endblock nav-global %}
+{% block nav-global %}{% include "django_admin_index/includes/app_list.html" %}{% endblock nav-global %}
 
 {% if not is_popup %}
-    {% block breadcrumbs %}
-        {% admin_index_settings as admin_index_settings %}
-        <div class="breadcrumbs">
-            <a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
-            {# NOTE: Remove app groups if needed #}
-            {% if not admin_index_settings.HIDE_APP_INDEX_PAGES %}
-                &rsaquo;
-                <a href="{% url 'admin:app_list' app_label=cl.opts.app_label %}">{{ cl.opts.app_config.verbose_name }}</a>
-            {% endif %}
-            {% block breadcrumbs_pre_changelist %}{% endblock %}
-            &rsaquo; {{ cl.opts.verbose_name_plural|capfirst }}
-        </div>
-    {% endblock %}
+{% block breadcrumbs %}
+{% admin_index_settings as admin_index_settings %}
+<div class="breadcrumbs">
+<a href="{% url 'admin:index' %}">{% trans 'Home' %}</a>
+{# NOTE: Remove app groups if needed #}
+{% if not admin_index_settings.HIDE_APP_INDEX_PAGES %}
+&rsaquo;
+<a href="{% url 'admin:app_list' app_label=cl.opts.app_label %}">{{ cl.opts.app_config.verbose_name }}</a>
 {% endif %}
-
-{% block coltype %}flex{% endblock %}
-
-{% block content %}
-    <div id="content-main">
-        {% block object-tools %}
-            <ul class="object-tools">
-                {% block object-tools-items %}
-                    {# NOTE: This does not work in Django 1.11 and 2.0. The template part remains the same. #}
-                    {# {% change_list_object_tools %} #}
-                    {% if has_add_permission %}
-                        <li>
-                            {% url cl.opts|admin_urlname:'add' as add_url %}
-                            <a href="{% add_preserved_filters add_url is_popup to_field %}" class="addlink">
-                                {% blocktrans with cl.opts.verbose_name as name %}Add {{ name }}{% endblocktrans %}
-                            </a>
-                        </li>
-                    {% endif %}
-                {% endblock %}
-            </ul>
-        {% endblock %}
-        {% if cl.formset and cl.formset.errors %}
-            <p class="errornote">
-                {% if cl.formset.total_error_count == 1 %}{% trans "Please correct the error below." %}{% else %}
-                    {% trans "Please correct the errors below." %}{% endif %}
-            </p>
-            {{ cl.formset.non_form_errors }}
-        {% endif %}
-        <div class="module{% if cl.has_filters %} filtered{% endif %}" id="changelist">
-            <div class="changelist-form-container">
-                {% block search %}{% search_form cl %}{% endblock %}
-                {% block date_hierarchy %}{% if cl.date_hierarchy %}{% date_hierarchy cl %}{% endif %}{% endblock %}
-
-                <form id="changelist-form" method="post"{% if cl.formset and cl.formset.is_multipart %}
-                      enctype="multipart/form-data"{% endif %} novalidate>{% csrf_token %}
-                    {% if cl.formset %}
-                        <div>{{ cl.formset.management_form }}</div>
-                    {% endif %}
-
-
-                    {% block result_list %}
-                        {% if action_form and actions_on_top and cl.show_admin_actions %}{% admin_actions %}{% endif %}
-                        {% result_list cl %}
-                        {% if action_form and actions_on_bottom and cl.show_admin_actions %}
-                            {% admin_actions %}{% endif %}
-                    {% endblock %}
-                    {% block pagination %}{% pagination cl %}{% endblock %}
-                </form>
-
-            </div>
-            {% block filters %}
-                {% if cl.has_filters %}
-                    <div id="changelist-filter">
-                        <h2>{% trans 'Filter' %}</h2>
-                        {% for spec in cl.filter_specs %}{% admin_list_filter cl spec %}{% endfor %}
-                    </div>
-                {% endif %}
-            {% endblock %}
-        </div>
-    </div>
+{% block breadcrumbs_pre_changelist %}{% endblock %}
+&rsaquo; {{ cl.opts.verbose_name_plural|capfirst }}
+</div>
 {% endblock %}
+{% endif %}
diff --git a/django_admin_index/templates/admin/delete_confirmation.html b/django_admin_index/templates/admin/delete_confirmation.html
index 5674007..355f941 100644
--- a/django_admin_index/templates/admin/delete_confirmation.html
+++ b/django_admin_index/templates/admin/delete_confirmation.html
@@ -1,4 +1,4 @@
-{% extends "admin/base_site.html" %}
+{% extends "admin/delete_confirmation.html" %}
 {% load i18n admin_urls static django_admin_index %}
 
 {% block extrahead %}
@@ -8,9 +8,7 @@
     <script type="text/javascript" src="{% static 'admin/js/cancel.js' %}"></script>
 {% endblock %}
 
-{% block bodyclass %}{{ block.super }} app-{{ opts.app_label }} model-{{ opts.model_name }} delete-confirmation{% endblock %}
-
-{% block nav-global %}{% include "includes/app_list.html" %}{% endblock nav-global %}
+{% block nav-global %}{% include "django_admin_index/includes/app_list.html" %}{% endblock nav-global %}
 
 {% block breadcrumbs %}
 {% admin_index_settings as admin_index_settings %}
@@ -26,35 +24,3 @@
 &rsaquo; {% trans 'Delete' %}
 </div>
 {% endblock %}
-
-{% block content %}
-{% if perms_lacking %}
-    <p>{% blocktrans with escaped_object=object %}Deleting the {{ object_name }} '{{ escaped_object }}' would result in deleting related objects, but your account doesn't have permission to delete the following types of objects:{% endblocktrans %}</p>
-    <ul>
-    {% for obj in perms_lacking %}
-        <li>{{ obj }}</li>
-    {% endfor %}
-    </ul>
-{% elif protected %}
-    <p>{% blocktrans with escaped_object=object %}Deleting the {{ object_name }} '{{ escaped_object }}' would require deleting the following protected related objects:{% endblocktrans %}</p>
-    <ul>
-    {% for obj in protected %}
-        <li>{{ obj }}</li>
-    {% endfor %}
-    </ul>
-{% else %}
-    <p>{% blocktrans with escaped_object=object %}Are you sure you want to delete the {{ object_name }} "{{ escaped_object }}"? All of the following related items will be deleted:{% endblocktrans %}</p>
-    {% include "admin/includes/object_delete_summary.html" %}
-    <h2>{% trans "Objects" %}</h2>
-    <ul>{{ deleted_objects|unordered_list }}</ul>
-    <form method="post">{% csrf_token %}
-    <div>
-    <input type="hidden" name="post" value="yes">
-    {% if is_popup %}<input type="hidden" name="{{ is_popup_var }}" value="1">{% endif %}
-    {% if to_field %}<input type="hidden" name="{{ to_field_var }}" value="{{ to_field }}">{% endif %}
-    <input type="submit" value="{% trans "Yes, I'm sure" %}">
-    <a href="#" class="button cancel-link">{% trans "No, take me back" %}</a>
-    </div>
-    </form>
-{% endif %}
-{% endblock %}
diff --git a/django_admin_index/templates/admin/delete_selected_confirmation.html b/django_admin_index/templates/admin/delete_selected_confirmation.html
index e2f2b1b..e91f49f 100644
--- a/django_admin_index/templates/admin/delete_selected_confirmation.html
+++ b/django_admin_index/templates/admin/delete_selected_confirmation.html
@@ -1,5 +1,5 @@
-{% extends "admin/base_site.html" %}
-{% load i18n l10n admin_urls static django_admin_index %}
+{% extends "admin/delete_selected_confirmation.html" %}
+{% load i18n admin_urls static django_admin_index %}
 
 {% block extrahead %}
     {# NOTE: Switched these 2 variables around to allow overrides #}
@@ -8,9 +8,7 @@
     <script type="text/javascript" src="{% static 'admin/js/cancel.js' %}"></script>
 {% endblock %}
 
-{% block bodyclass %}{{ block.super }} app-{{ opts.app_label }} model-{{ opts.model_name }} delete-confirmation delete-selected-confirmation{% endblock %}
-
-{% block nav-global %}{% include "includes/app_list.html" %}{% endblock nav-global %}
+{% block nav-global %}{% include "django_admin_index/includes/app_list.html" %}{% endblock nav-global %}
 
 {% block breadcrumbs %}
 {% admin_index_settings as admin_index_settings %}
@@ -25,39 +23,3 @@
 &rsaquo; {% trans 'Delete multiple objects' %}
 </div>
 {% endblock %}
-
-{% block content %}
-{% if perms_lacking %}
-    <p>{% blocktrans %}Deleting the selected {{ objects_name }} would result in deleting related objects, but your account doesn't have permission to delete the following types of objects:{% endblocktrans %}</p>
-    <ul>
-    {% for obj in perms_lacking %}
-        <li>{{ obj }}</li>
-    {% endfor %}
-    </ul>
-{% elif protected %}
-    <p>{% blocktrans %}Deleting the selected {{ objects_name }} would require deleting the following protected related objects:{% endblocktrans %}</p>
-    <ul>
-    {% for obj in protected %}
-        <li>{{ obj }}</li>
-    {% endfor %}
-    </ul>
-{% else %}
-    <p>{% blocktrans %}Are you sure you want to delete the selected {{ objects_name }}? All of the following objects and their related items will be deleted:{% endblocktrans %}</p>
-    {% include "admin/includes/object_delete_summary.html" %}
-    <h2>{% trans "Objects" %}</h2>
-    {% for deletable_object in deletable_objects %}
-        <ul>{{ deletable_object|unordered_list }}</ul>
-    {% endfor %}
-    <form method="post">{% csrf_token %}
-    <div>
-    {% for obj in queryset %}
-    <input type="hidden" name="{{ action_checkbox_name }}" value="{{ obj.pk|unlocalize }}">
-    {% endfor %}
-    <input type="hidden" name="action" value="delete_selected">
-    <input type="hidden" name="post" value="yes">
-    <input type="submit" value="{% trans "Yes, I'm sure" %}">
-    <a href="#" class="button cancel-link">{% trans "No, take me back" %}</a>
-    </div>
-    </form>
-{% endif %}
-{% endblock %}
diff --git a/django_admin_index/templates/admin/index.html b/django_admin_index/templates/admin/index.html
index 02bec8c..3a8048b 100644
--- a/django_admin_index/templates/admin/index.html
+++ b/django_admin_index/templates/admin/index.html
@@ -1,15 +1,7 @@
-{% extends "admin/base_site.html" %}
-{% load i18n static django_admin_index %}
+{% extends "admin/index.html" %}
+{% load i18n django_admin_index %}
 
-{% block extrastyle %}{{ block.super }}<link rel="stylesheet" type="text/css" href="{% static "admin/css/dashboard.css" %}">{% endblock %}
-
-{% block coltype %}colMS{% endblock %}
-
-{% block bodyclass %}{{ block.super }} dashboard{% endblock %}
-
-{% block nav-global %}{% include "includes/app_list.html" %}{% endblock nav-global %}
-
-{% block breadcrumbs %}{% endblock %}
+{% block nav-global %}{% include "django_admin_index/includes/app_list.html" %}{% endblock nav-global %}
 
 {% block content %}
 <div id="content-main">
@@ -62,35 +54,3 @@
 {% endif %}
 </div>
 {% endblock %}
-
-{% block sidebar %}
-<div id="content-related">
-    <div class="module" id="recent-actions-module">
-        <h2>{% trans 'Recent actions' %}</h2>
-        <h3>{% trans 'My actions' %}</h3>
-            {% load log %}
-            {% get_admin_log 10 as admin_log for_user user %}
-            {% if not admin_log %}
-            <p>{% trans 'None available' %}</p>
-            {% else %}
-            <ul class="actionlist">
-            {% for entry in admin_log %}
-            <li class="{% if entry.is_addition %}addlink{% endif %}{% if entry.is_change %}changelink{% endif %}{% if entry.is_deletion %}deletelink{% endif %}">
-                {% if entry.is_deletion or not entry.get_admin_url %}
-                    {{ entry.object_repr }}
-                {% else %}
-                    <a href="{{ entry.get_admin_url }}">{{ entry.object_repr }}</a>
-                {% endif %}
-                <br>
-                {% if entry.content_type %}
-                    <span class="mini quiet">{% filter capfirst %}{{ entry.content_type }}{% endfilter %}</span>
-                {% else %}
-                    <span class="mini quiet">{% trans 'Unknown content' %}</span>
-                {% endif %}
-            </li>
-            {% endfor %}
-            </ul>
-            {% endif %}
-    </div>
-</div>
-{% endblock %}
diff --git a/django_admin_index/templates/admin/object_history.html b/django_admin_index/templates/admin/object_history.html
index 85271e4..3e5e7a2 100644
--- a/django_admin_index/templates/admin/object_history.html
+++ b/django_admin_index/templates/admin/object_history.html
@@ -1,7 +1,7 @@
-{% extends "admin/base_site.html" %}
+{% extends "admin/object_history.html" %}
 {% load i18n admin_urls django_admin_index %}
 
-{% block nav-global %}{% include "includes/app_list.html" %}{% endblock nav-global %}
+{% block nav-global %}{% include "django_admin_index/includes/app_list.html" %}{% endblock nav-global %}
 
 {% block breadcrumbs %}
 {% admin_index_settings as admin_index_settings %}
@@ -17,33 +17,3 @@
 &rsaquo; {% trans 'History' %}
 </div>
 {% endblock %}
-
-{% block content %}
-<div id="content-main">
-<div class="module">
-
-{% if action_list %}
-    <table id="change-history">
-        <thead>
-        <tr>
-            <th scope="col">{% trans 'Date/time' %}</th>
-            <th scope="col">{% trans 'User' %}</th>
-            <th scope="col">{% trans 'Action' %}</th>
-        </tr>
-        </thead>
-        <tbody>
-        {% for action in action_list %}
-        <tr>
-            <th scope="row">{{ action.action_time|date:"DATETIME_FORMAT" }}</th>
-            <td>{{ action.user.get_username }}{% if action.user.get_full_name %} ({{ action.user.get_full_name }}){% endif %}</td>
-            <td>{{ action.get_change_message }}</td>
-        </tr>
-        {% endfor %}
-        </tbody>
-    </table>
-{% else %}
-    <p>{% trans "This object doesn't have a change history. It probably wasn't added via this admin site." %}</p>
-{% endif %}
-</div>
-</div>
-{% endblock %}
diff --git a/django_admin_index/templates/django_admin_index/includes/app_list.html b/django_admin_index/templates/django_admin_index/includes/app_list.html
new file mode 100644
index 0000000..751dbcf
--- /dev/null
+++ b/django_admin_index/templates/django_admin_index/includes/app_list.html
@@ -0,0 +1,30 @@
+{% load i18n django_admin_index static %}
+
+{% dashboard_app_list as dashboard_app_list %}
+{% display_dropdown_menu request as should_display_dropdown %}
+
+{% if dashboard_app_list and should_display_dropdown %}
+    <div class="djai-dropdown-menu">
+        <link rel="stylesheet" type="text/css" href="{% static "admin/css/admin-index.css" %}">
+        {% url 'admin:index' as home %}
+        <a href="{{ home }}"
+           class="djai-dropdown-menu__item {% if request.path == home %}djai-dropdown-menu__item--active{% endif %}">
+            {% trans "Dashboard" %}
+        </a>
+        {% for app in dashboard_app_list %}
+            <div class="djai-dropdown-menu__item {% if app.active %}djai-dropdown-menu__item--active{% endif %}" tabindex="0">
+                <span>{{ app.name }}</span>
+                <span class="djai-dropdown-menu__drop">
+                    {% for model in app.models %}
+                        {% if model.admin_url %}
+                            <div class="djai-dropdown-menu__drop-item {% if model.active %}djai-dropdown-menu__drop-item--active{% endif %}">
+                                <a href="{{ model.admin_url }}"
+                                   class="djai-dropdown-menu__link">{{ model.name }}</a>
+                            </div>
+                        {% endif %}
+                    {% endfor %}
+                </span>
+            </div>
+        {% endfor %}
+    </div>
+{% endif %}
diff --git a/django_admin_index/templates/includes/app_list.html b/django_admin_index/templates/includes/app_list.html
deleted file mode 100644
index 9301982..0000000
--- a/django_admin_index/templates/includes/app_list.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{% load i18n django_admin_index static %}
-
-{% dashboard_app_list as dashboard_app_list %}
-{% display_dropdown_menu request as should_display_dropdown %}
-
-{% if dashboard_app_list and should_display_dropdown %}
-    <div class="dropdown-menu">
-        <link rel="stylesheet" type="text/css" href="{% static "admin/css/admin-index.css" %}">
-        {% url 'admin:index' as home %}
-        <a href="{{ home }}"
-           class="dropdown-menu__item {% if request.path == home %}dropdown-menu__item--active{% endif %}">
-            {% trans "Dashboard" %}
-        </a>
-        {% for app in dashboard_app_list %}
-            <div class="dropdown-menu__item {% if app.active %}dropdown-menu__item--active{% endif %}">
-                <span>{{ app.name }}</span>
-                <span class="dropdown-menu__drop">
-                        {% for model in app.models %}
-                            {% if model.admin_url %}
-                                <div class="dropdown-menu__drop-item">
-                                    <a href="{{ model.admin_url }}"
-                                       class="dropdown-menu__link {% if model.active %}dropdown-menu__link--active{% endif %}">{{ model.name }}</a>
-                                </div>
-                            {% endif %}
-                        {% endfor %}
-                    </span>
-            </div>
-        {% endfor %}
-    </div>
-{% endif %}
diff --git a/django_admin_index/templates/registration/password_change_done.html b/django_admin_index/templates/registration/password_change_done.html
new file mode 100644
index 0000000..9988c93
--- /dev/null
+++ b/django_admin_index/templates/registration/password_change_done.html
@@ -0,0 +1,4 @@
+{% extends "registration/password_change_done.html" %}
+{% load django_admin_index %}
+
+{% block nav-global %}{% include "django_admin_index/includes/app_list.html" %}{% endblock nav-global %}
diff --git a/django_admin_index/templates/registration/password_change_form.html b/django_admin_index/templates/registration/password_change_form.html
new file mode 100644
index 0000000..ccd6baa
--- /dev/null
+++ b/django_admin_index/templates/registration/password_change_form.html
@@ -0,0 +1,4 @@
+{% extends "registration/password_change_form.html" %}
+{% load django_admin_index %}
+
+{% block nav-global %}{% include "django_admin_index/includes/app_list.html" %}{% endblock nav-global %}
diff --git a/package-lock.json b/package-lock.json
index 2c9ef79..7696770 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,11 +1,12 @@
 {
   "name": "django-admin-index",
-  "version": "1.5.0",
+  "version": "1.6.0",
   "lockfileVersion": 2,
   "requires": true,
   "packages": {
     "": {
-      "version": "1.5.0",
+      "name": "django-admin-index",
+      "version": "1.6.0",
       "license": "BSD-3-Clause",
       "devDependencies": {
         "parcel": "^1.12.4",
@@ -61,12 +62,6 @@
         "node": ">=6"
       }
     },
-    "node_modules/@babel/core/node_modules/json5/node_modules/minimist": {
-      "version": "1.2.5",
-      "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
-      "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
-      "dev": true
-    },
     "node_modules/@babel/core/node_modules/source-map": {
       "version": "0.5.7",
       "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
@@ -342,6 +337,9 @@
         "@babel/helper-plugin-utils": "^7.0.0",
         "@babel/helper-remap-async-to-generator": "^7.1.0",
         "@babel/plugin-syntax-async-generators": "^7.2.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
       }
     },
     "node_modules/@babel/plugin-proposal-dynamic-import": {
@@ -352,6 +350,9 @@
       "dependencies": {
         "@babel/helper-plugin-utils": "^7.0.0",
         "@babel/plugin-syntax-dynamic-import": "^7.2.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
       }
     },
     "node_modules/@babel/plugin-proposal-json-strings": {
@@ -362,6 +363,9 @@
       "dependencies": {
         "@babel/helper-plugin-utils": "^7.0.0",
         "@babel/plugin-syntax-json-strings": "^7.2.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
       }
     },
     "node_modules/@babel/plugin-proposal-object-rest-spread": {
@@ -372,6 +376,9 @@
       "dependencies": {
         "@babel/helper-plugin-utils": "^7.0.0",
         "@babel/plugin-syntax-object-rest-spread": "^7.2.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
       }
     },
     "node_modules/@babel/plugin-proposal-optional-catch-binding": {
@@ -382,6 +389,9 @@
       "dependencies": {
         "@babel/helper-plugin-utils": "^7.0.0",
         "@babel/plugin-syntax-optional-catch-binding": "^7.2.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
       }
     },
     "node_modules/@babel/plugin-proposal-unicode-property-regex": {
@@ -396,6 +406,9 @@
       },
       "engines": {
         "node": ">=4"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
       }
     },
     "node_modules/@babel/plugin-syntax-async-generators": {
@@ -405,6 +418,9 @@
       "dev": true,
       "dependencies": {
         "@babel/helper-plugin-utils": "^7.0.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
       }
     },
     "node_modules/@babel/plugin-syntax-dynamic-import": {
@@ -414,6 +430,9 @@
       "dev": true,
       "dependencies": {
         "@babel/helper-plugin-utils": "^7.0.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
       }
     },
     "node_modules/@babel/plugin-syntax-flow": {
@@ -423,6 +442,9 @@
       "dev": true,
       "dependencies": {
         "@babel/helper-plugin-utils": "^7.0.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
       }
     },
     "node_modules/@babel/plugin-syntax-json-strings": {
@@ -432,6 +454,9 @@
       "dev": true,
       "dependencies": {
         "@babel/helper-plugin-utils": "^7.0.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
       }
     },
     "node_modules/@babel/plugin-syntax-jsx": {
@@ -441,6 +466,9 @@
       "dev": true,
       "dependencies": {
         "@babel/helper-plugin-utils": "^7.0.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
       }
     },
     "node_modules/@babel/plugin-syntax-object-rest-spread": {
@@ -450,6 +478,9 @@
       "dev": true,
       "dependencies": {
         "@babel/helper-plugin-utils": "^7.0.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
       }
     },
     "node_modules/@babel/plugin-syntax-optional-catch-binding": {
@@ -459,6 +490,9 @@
       "dev": true,
       "dependencies": {
         "@babel/helper-plugin-utils": "^7.0.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
       }
     },
     "node_modules/@babel/plugin-transform-arrow-functions": {
@@ -468,6 +502,9 @@
       "dev": true,
       "dependencies": {
         "@babel/helper-plugin-utils": "^7.0.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
       }
     },
     "node_modules/@babel/plugin-transform-async-to-generator": {
@@ -479,6 +516,9 @@
         "@babel/helper-module-imports": "^7.0.0",
         "@babel/helper-plugin-utils": "^7.0.0",
         "@babel/helper-remap-async-to-generator": "^7.1.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
       }
     },
     "node_modules/@babel/plugin-transform-block-scoped-functions": {
@@ -488,6 +528,9 @@
       "dev": true,
       "dependencies": {
         "@babel/helper-plugin-utils": "^7.0.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
       }
     },
     "node_modules/@babel/plugin-transform-block-scoping": {
@@ -498,6 +541,9 @@
       "dependencies": {
         "@babel/helper-plugin-utils": "^7.0.0",
         "lodash": "^4.17.13"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
       }
     },
     "node_modules/@babel/plugin-transform-classes": {
@@ -514,6 +560,9 @@
         "@babel/helper-replace-supers": "^7.5.5",
         "@babel/helper-split-export-declaration": "^7.4.4",
         "globals": "^11.1.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
       }
     },
     "node_modules/@babel/plugin-transform-computed-properties": {
@@ -523,6 +572,9 @@
       "dev": true,
       "dependencies": {
         "@babel/helper-plugin-utils": "^7.0.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
       }
     },
     "node_modules/@babel/plugin-transform-destructuring": {
@@ -532,6 +584,9 @@
       "dev": true,
       "dependencies": {
         "@babel/helper-plugin-utils": "^7.0.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
       }
     },
     "node_modules/@babel/plugin-transform-dotall-regex": {
@@ -546,6 +601,9 @@
       },
       "engines": {
         "node": ">=4"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
       }
     },
     "node_modules/@babel/plugin-transform-duplicate-keys": {
@@ -555,6 +613,9 @@
       "dev": true,
       "dependencies": {
         "@babel/helper-plugin-utils": "^7.0.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
       }
     },
     "node_modules/@babel/plugin-transform-exponentiation-operator": {
@@ -565,6 +626,9 @@
       "dependencies": {
         "@babel/helper-builder-binary-assignment-operator-visitor": "^7.1.0",
         "@babel/helper-plugin-utils": "^7.0.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
       }
     },
     "node_modules/@babel/plugin-transform-flow-strip-types": {
@@ -575,6 +639,9 @@
       "dependencies": {
         "@babel/helper-plugin-utils": "^7.0.0",
         "@babel/plugin-syntax-flow": "^7.2.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
       }
     },
     "node_modules/@babel/plugin-transform-for-of": {
@@ -584,6 +651,9 @@
       "dev": true,
       "dependencies": {
         "@babel/helper-plugin-utils": "^7.0.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
       }
     },
     "node_modules/@babel/plugin-transform-function-name": {
@@ -594,6 +664,9 @@
       "dependencies": {
         "@babel/helper-function-name": "^7.1.0",
         "@babel/helper-plugin-utils": "^7.0.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
       }
     },
     "node_modules/@babel/plugin-transform-literals": {
@@ -603,6 +676,9 @@
       "dev": true,
       "dependencies": {
         "@babel/helper-plugin-utils": "^7.0.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
       }
     },
     "node_modules/@babel/plugin-transform-member-expression-literals": {
@@ -612,6 +688,9 @@
       "dev": true,
       "dependencies": {
         "@babel/helper-plugin-utils": "^7.0.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
       }
     },
     "node_modules/@babel/plugin-transform-modules-amd": {
@@ -623,6 +702,9 @@
         "@babel/helper-module-transforms": "^7.1.0",
         "@babel/helper-plugin-utils": "^7.0.0",
         "babel-plugin-dynamic-import-node": "^2.3.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
       }
     },
     "node_modules/@babel/plugin-transform-modules-commonjs": {
@@ -635,6 +717,9 @@
         "@babel/helper-plugin-utils": "^7.0.0",
         "@babel/helper-simple-access": "^7.1.0",
         "babel-plugin-dynamic-import-node": "^2.3.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
       }
     },
     "node_modules/@babel/plugin-transform-modules-systemjs": {
@@ -646,6 +731,9 @@
         "@babel/helper-hoist-variables": "^7.4.4",
         "@babel/helper-plugin-utils": "^7.0.0",
         "babel-plugin-dynamic-import-node": "^2.3.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
       }
     },
     "node_modules/@babel/plugin-transform-modules-umd": {
@@ -656,6 +744,9 @@
       "dependencies": {
         "@babel/helper-module-transforms": "^7.1.0",
         "@babel/helper-plugin-utils": "^7.0.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
       }
     },
     "node_modules/@babel/plugin-transform-named-capturing-groups-regex": {
@@ -665,6 +756,9 @@
       "dev": true,
       "dependencies": {
         "regexpu-core": "^4.6.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0"
       }
     },
     "node_modules/@babel/plugin-transform-new-target": {
@@ -674,6 +768,9 @@
       "dev": true,
       "dependencies": {
         "@babel/helper-plugin-utils": "^7.0.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
       }
     },
     "node_modules/@babel/plugin-transform-object-super": {
@@ -684,6 +781,9 @@
       "dependencies": {
         "@babel/helper-plugin-utils": "^7.0.0",
         "@babel/helper-replace-supers": "^7.5.5"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
       }
     },
     "node_modules/@babel/plugin-transform-parameters": {
@@ -695,6 +795,9 @@
         "@babel/helper-call-delegate": "^7.4.4",
         "@babel/helper-get-function-arity": "^7.0.0",
         "@babel/helper-plugin-utils": "^7.0.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
       }
     },
     "node_modules/@babel/plugin-transform-property-literals": {
@@ -704,6 +807,9 @@
       "dev": true,
       "dependencies": {
         "@babel/helper-plugin-utils": "^7.0.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
       }
     },
     "node_modules/@babel/plugin-transform-react-jsx": {
@@ -715,6 +821,9 @@
         "@babel/helper-builder-react-jsx": "^7.3.0",
         "@babel/helper-plugin-utils": "^7.0.0",
         "@babel/plugin-syntax-jsx": "^7.2.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
       }
     },
     "node_modules/@babel/plugin-transform-regenerator": {
@@ -724,6 +833,9 @@
       "dev": true,
       "dependencies": {
         "regenerator-transform": "^0.14.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
       }
     },
     "node_modules/@babel/plugin-transform-reserved-words": {
@@ -733,6 +845,9 @@
       "dev": true,
       "dependencies": {
         "@babel/helper-plugin-utils": "^7.0.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
       }
     },
     "node_modules/@babel/plugin-transform-shorthand-properties": {
@@ -742,6 +857,9 @@
       "dev": true,
       "dependencies": {
         "@babel/helper-plugin-utils": "^7.0.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
       }
     },
     "node_modules/@babel/plugin-transform-spread": {
@@ -751,6 +869,9 @@
       "dev": true,
       "dependencies": {
         "@babel/helper-plugin-utils": "^7.0.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
       }
     },
     "node_modules/@babel/plugin-transform-sticky-regex": {
@@ -761,6 +882,9 @@
       "dependencies": {
         "@babel/helper-plugin-utils": "^7.0.0",
         "@babel/helper-regex": "^7.0.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
       }
     },
     "node_modules/@babel/plugin-transform-template-literals": {
@@ -771,6 +895,9 @@
       "dependencies": {
         "@babel/helper-annotate-as-pure": "^7.0.0",
         "@babel/helper-plugin-utils": "^7.0.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
       }
     },
     "node_modules/@babel/plugin-transform-typeof-symbol": {
@@ -780,6 +907,9 @@
       "dev": true,
       "dependencies": {
         "@babel/helper-plugin-utils": "^7.0.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
       }
     },
     "node_modules/@babel/plugin-transform-unicode-regex": {
@@ -791,6 +921,9 @@
         "@babel/helper-plugin-utils": "^7.0.0",
         "@babel/helper-regex": "^7.4.4",
         "regexpu-core": "^4.6.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
       }
     },
     "node_modules/@babel/preset-env": {
@@ -849,6 +982,9 @@
         "invariant": "^2.2.2",
         "js-levenshtein": "^1.1.3",
         "semver": "^5.5.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
       }
     },
     "node_modules/@babel/runtime": {
@@ -1011,6 +1147,7 @@
       "version": "2.1.8",
       "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz",
       "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==",
+      "deprecated": "Chokidar 2 does not receive security updates since 2019. Upgrade to chokidar 3 with 15x fewer dependencies",
       "dev": true,
       "dependencies": {
         "anymatch": "^2.0.0",
@@ -1033,12 +1170,17 @@
       "version": "1.2.13",
       "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz",
       "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==",
+      "deprecated": "fsevents 1 will break on node v14+ and could be using insecure binaries. Upgrade to fsevents 2.",
       "dev": true,
       "hasInstallScript": true,
       "optional": true,
       "os": [
         "darwin"
       ],
+      "dependencies": {
+        "bindings": "^1.5.0",
+        "nan": "^2.12.1"
+      },
       "engines": {
         "node": ">= 4.0"
       }
@@ -1094,6 +1236,18 @@
       "integrity": "sha512-2scffjvioEmNz0OyDSLGWDfKCVwaKc6l9Pm9kOIREU13ClXZvHpg/nRL5xyjSSSLhOnXqft2HpsAzNEEA8cFFg==",
       "dev": true
     },
+    "node_modules/acorn": {
+      "version": "8.7.0",
+      "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz",
+      "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==",
+      "dev": true,
+      "bin": {
+        "acorn": "bin/acorn"
+      },
+      "engines": {
+        "node": ">=0.4.0"
+      }
+    },
     "node_modules/acorn-globals": {
       "version": "4.3.4",
       "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.4.tgz",
@@ -1126,15 +1280,19 @@
       }
     },
     "node_modules/ajv": {
-      "version": "6.10.2",
-      "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz",
-      "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==",
+      "version": "6.12.6",
+      "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+      "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
       "dev": true,
       "dependencies": {
-        "fast-deep-equal": "^2.0.1",
+        "fast-deep-equal": "^3.1.1",
         "fast-json-stable-stringify": "^2.0.0",
         "json-schema-traverse": "^0.4.1",
         "uri-js": "^4.2.2"
+      },
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/epoberezkin"
       }
     },
     "node_modules/alphanum-sort": {
@@ -1513,9 +1671,9 @@
       "dev": true
     },
     "node_modules/bn.js": {
-      "version": "4.11.8",
-      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
-      "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==",
+      "version": "4.12.0",
+      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
+      "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==",
       "dev": true
     },
     "node_modules/boolbase": {
@@ -1672,23 +1830,33 @@
       "dev": true
     },
     "node_modules/browserslist": {
-      "version": "4.7.1",
-      "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.7.1.tgz",
-      "integrity": "sha512-QtULFqKIAtiyNx7NhZ/p4rB8m3xDozVo/pi5VgTlADLF2tNigz/QH+v0m5qhn7XfHT7u+607NcCNOnC0HZAlMg==",
+      "version": "4.20.0",
+      "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.20.0.tgz",
+      "integrity": "sha512-bnpOoa+DownbciXj0jVGENf8VYQnE2LNWomhYuCsMmmx9Jd9lwq0WXODuwpSsp8AVdKM2/HorrzxAfbKvWTByQ==",
       "dev": true,
       "dependencies": {
-        "caniuse-lite": "^1.0.30000999",
-        "electron-to-chromium": "^1.3.284",
-        "node-releases": "^1.1.36"
+        "caniuse-lite": "^1.0.30001313",
+        "electron-to-chromium": "^1.4.76",
+        "escalade": "^3.1.1",
+        "node-releases": "^2.0.2",
+        "picocolors": "^1.0.0"
       },
       "bin": {
         "browserslist": "cli.js"
+      },
+      "engines": {
+        "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/browserslist"
       }
     },
     "node_modules/buffer": {
       "version": "4.9.1",
       "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz",
       "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=",
+      "deprecated": "This version of 'buffer' is out-of-date. You must update to v4.9.2 or newer",
       "dev": true,
       "dependencies": {
         "base64-js": "^1.0.2",
@@ -1795,10 +1963,14 @@
       }
     },
     "node_modules/caniuse-lite": {
-      "version": "1.0.30000999",
-      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000999.tgz",
-      "integrity": "sha512-1CUyKyecPeksKwXZvYw0tEoaMCo/RwBlXmEtN5vVnabvO0KPd9RQLcaAuR9/1F+KDMv6esmOFWlsXuzDk+8rxg==",
-      "dev": true
+      "version": "1.0.30001316",
+      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001316.tgz",
+      "integrity": "sha512-JgUdNoZKxPZFzbzJwy4hDSyGuH/gXz2rN51QmoR8cBQsVo58llD3A0vlRKKRt8FGf5u69P9eQyIH8/z9vN/S0Q==",
+      "dev": true,
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/browserslist"
+      }
     },
     "node_modules/caseless": {
       "version": "0.12.0",
@@ -1866,9 +2038,9 @@
       }
     },
     "node_modules/chokidar/node_modules/glob-parent": {
-      "version": "5.1.1",
-      "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz",
-      "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==",
+      "version": "5.1.2",
+      "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+      "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
       "dev": true,
       "dependencies": {
         "is-glob": "^4.0.1"
@@ -2005,13 +2177,13 @@
       }
     },
     "node_modules/color": {
-      "version": "3.1.2",
-      "resolved": "https://registry.npmjs.org/color/-/color-3.1.2.tgz",
-      "integrity": "sha512-vXTJhHebByxZn3lDvDJYw4lR5+uB3vuoHsuYA5AKuxRVn5wzzIfQKGLBmgdVRHKTJYeK5rvJcHnrd0Li49CFpg==",
+      "version": "3.2.1",
+      "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz",
+      "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==",
       "dev": true,
       "dependencies": {
-        "color-convert": "^1.9.1",
-        "color-string": "^1.5.2"
+        "color-convert": "^1.9.3",
+        "color-string": "^1.6.0"
       }
     },
     "node_modules/color-convert": {
@@ -2030,9 +2202,9 @@
       "dev": true
     },
     "node_modules/color-string": {
-      "version": "1.5.3",
-      "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.3.tgz",
-      "integrity": "sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw==",
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.0.tgz",
+      "integrity": "sha512-9Mrz2AQLefkH1UvASKj6v6hj/7eWgjnT/cVsR8CumieLoT+g900exWeNogqtweI8dxloXN9BDQTYro1oWu/5CQ==",
       "dev": true,
       "dependencies": {
         "color-name": "^1.0.0",
@@ -2127,6 +2299,7 @@
       "version": "2.6.10",
       "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.10.tgz",
       "integrity": "sha512-I39t74+4t+zau64EN1fE5v2W31Adtc/REhzWN+gWRRXg6WH5qAsZm62DHpQ1+Yhe4047T55jvzz7MUqF/dBBlA==",
+      "deprecated": "core-js@<3.4 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Please, upgrade your dependencies to the actual version of core-js.",
       "dev": true,
       "hasInstallScript": true
     },
@@ -2381,13 +2554,13 @@
       }
     },
     "node_modules/css-select": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/css-select/-/css-select-2.0.2.tgz",
-      "integrity": "sha512-dSpYaDVoWaELjvZ3mS6IKZM/y2PMPa/XYoEfYNZePL4U/XgyxZNroHEHReDx/d+VgXh9VbCTtFqLkFbmeqeaRQ==",
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/css-select/-/css-select-2.1.0.tgz",
+      "integrity": "sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ==",
       "dev": true,
       "dependencies": {
         "boolbase": "^1.0.0",
-        "css-what": "^2.1.2",
+        "css-what": "^3.2.1",
         "domutils": "^1.7.0",
         "nth-check": "^1.0.2"
       }
@@ -2447,19 +2620,16 @@
         "regjsparser": "bin/parser"
       }
     },
-    "node_modules/css-unit-converter": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/css-unit-converter/-/css-unit-converter-1.1.1.tgz",
-      "integrity": "sha1-2bkoGtz9jO2TW9urqDeGiX9k6ZY=",
-      "dev": true
-    },
     "node_modules/css-what": {
-      "version": "2.1.3",
-      "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz",
-      "integrity": "sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==",
+      "version": "3.4.2",
+      "resolved": "https://registry.npmjs.org/css-what/-/css-what-3.4.2.tgz",
+      "integrity": "sha512-ACUm3L0/jiZTqfzRM3Hi9Q8eZqd6IK37mMWPLz9PJxkLWllYeRf+EHUSHYEtFop2Eqytaq1FizFVh7XfBnXCDQ==",
       "dev": true,
       "engines": {
-        "node": "*"
+        "node": ">= 6"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/fb55"
       }
     },
     "node_modules/cssesc": {
@@ -2472,13 +2642,13 @@
       }
     },
     "node_modules/cssnano": {
-      "version": "4.1.10",
-      "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-4.1.10.tgz",
-      "integrity": "sha512-5wny+F6H4/8RgNlaqab4ktc3e0/blKutmq8yNlBFXA//nSFFAqAngjNVRzUvCgYROULmZZUoosL/KSoZo5aUaQ==",
+      "version": "4.1.11",
+      "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-4.1.11.tgz",
+      "integrity": "sha512-6gZm2htn7xIPJOHY824ERgj8cNPgPxyCSnkXc4v7YvNW+TdVfzgngHcEhy/8D11kUWRUMbke+tC+AUcUsnMz2g==",
       "dev": true,
       "dependencies": {
         "cosmiconfig": "^5.0.0",
-        "cssnano-preset-default": "^4.0.7",
+        "cssnano-preset-default": "^4.0.8",
         "is-resolvable": "^1.0.0",
         "postcss": "^7.0.0"
       },
@@ -2487,9 +2657,9 @@
       }
     },
     "node_modules/cssnano-preset-default": {
-      "version": "4.0.7",
-      "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-4.0.7.tgz",
-      "integrity": "sha512-x0YHHx2h6p0fCl1zY9L9roD7rnlltugGu7zXSKQx6k2rYw0Hi3IqxcoAGF7u9Q5w1nt7vK0ulxV8Lo+EvllGsA==",
+      "version": "4.0.8",
+      "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-4.0.8.tgz",
+      "integrity": "sha512-LdAyHuq+VRyeVREFmuxUZR1TXjQm8QQU/ktoo/x7bz+SdOge1YKc5eMN6pRW7YWBmyq59CqYba1dJ5cUukEjLQ==",
       "dev": true,
       "dependencies": {
         "css-declaration-sorter": "^4.0.1",
@@ -2520,7 +2690,7 @@
         "postcss-ordered-values": "^4.1.2",
         "postcss-reduce-initial": "^4.0.3",
         "postcss-reduce-transforms": "^4.0.2",
-        "postcss-svgo": "^4.0.2",
+        "postcss-svgo": "^4.0.3",
         "postcss-unique-selectors": "^4.0.1"
       },
       "engines": {
@@ -2628,6 +2798,7 @@
       "version": "4.1.1",
       "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
       "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+      "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)",
       "dev": true,
       "dependencies": {
         "ms": "^2.1.1"
@@ -2841,15 +3012,15 @@
       }
     },
     "node_modules/dot-prop": {
-      "version": "4.2.0",
-      "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz",
-      "integrity": "sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ==",
+      "version": "5.3.0",
+      "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz",
+      "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==",
       "dev": true,
       "dependencies": {
-        "is-obj": "^1.0.0"
+        "is-obj": "^2.0.0"
       },
       "engines": {
-        "node": ">=4"
+        "node": ">=8"
       }
     },
     "node_modules/dotenv": {
@@ -2893,26 +3064,32 @@
       "dev": true
     },
     "node_modules/electron-to-chromium": {
-      "version": "1.3.285",
-      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.285.tgz",
-      "integrity": "sha512-DYR9KW723sUbGK++DCmCmM95AbNXT4Q0tlCFMcYijFjayhuDqlGYR68OemlP8MJj0gjkwdeItIUfd0oLCgw+4A==",
+      "version": "1.4.83",
+      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.83.tgz",
+      "integrity": "sha512-Wm15TA5pLMOHtsik6uQTVyzXG8IpkVxnXAoAqV4+6zbJH3n5qnVz3iNAW+65r6WSrrYo0w6B8JJ0lcv2NhSmXQ==",
       "dev": true
     },
     "node_modules/elliptic": {
-      "version": "6.5.1",
-      "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.1.tgz",
-      "integrity": "sha512-xvJINNLbTeWQjrl6X+7eQCrIy/YPv5XCpKW6kB5mKvtnGILoLDcySuwomfdzt0BMdLNVnuRNTuzKNHj0bva1Cg==",
+      "version": "6.5.4",
+      "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz",
+      "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==",
       "dev": true,
       "dependencies": {
-        "bn.js": "^4.4.0",
-        "brorand": "^1.0.1",
+        "bn.js": "^4.11.9",
+        "brorand": "^1.1.0",
         "hash.js": "^1.0.0",
-        "hmac-drbg": "^1.0.0",
-        "inherits": "^2.0.1",
-        "minimalistic-assert": "^1.0.0",
-        "minimalistic-crypto-utils": "^1.0.0"
+        "hmac-drbg": "^1.0.1",
+        "inherits": "^2.0.4",
+        "minimalistic-assert": "^1.0.1",
+        "minimalistic-crypto-utils": "^1.0.1"
       }
     },
+    "node_modules/elliptic/node_modules/inherits": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+      "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+      "dev": true
+    },
     "node_modules/encodeurl": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
@@ -2990,6 +3167,15 @@
         "node": ">= 0.4"
       }
     },
+    "node_modules/escalade": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
+      "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
     "node_modules/escape-html": {
       "version": "1.0.3",
       "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
@@ -3014,8 +3200,7 @@
         "esprima": "^3.1.3",
         "estraverse": "^4.2.0",
         "esutils": "^2.0.2",
-        "optionator": "^0.8.1",
-        "source-map": "~0.6.1"
+        "optionator": "^0.8.1"
       },
       "bin": {
         "escodegen": "bin/escodegen.js",
@@ -3023,6 +3208,9 @@
       },
       "engines": {
         "node": ">=4.0"
+      },
+      "optionalDependencies": {
+        "source-map": "~0.6.1"
       }
     },
     "node_modules/esprima": {
@@ -3296,9 +3484,9 @@
       "dev": true
     },
     "node_modules/fast-deep-equal": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz",
-      "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=",
+      "version": "3.1.3",
+      "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+      "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
       "dev": true
     },
     "node_modules/fast-glob": {
@@ -3441,7 +3629,9 @@
       "version": "2.1.3",
       "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz",
       "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==",
+      "deprecated": "\"Please update to latest v2.3 or v2.2\"",
       "dev": true,
+      "hasInstallScript": true,
       "optional": true,
       "os": [
         "darwin"
@@ -3566,6 +3756,7 @@
       "version": "5.1.3",
       "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz",
       "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==",
+      "deprecated": "this library is no longer supported",
       "dev": true,
       "dependencies": {
         "ajv": "^6.5.5",
@@ -3717,12 +3908,6 @@
       "integrity": "sha1-wc56MWjIxmFAM6S194d/OyJfnDg=",
       "dev": true
     },
-    "node_modules/html-comment-regex": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/html-comment-regex/-/html-comment-regex-1.1.2.tgz",
-      "integrity": "sha512-P+M65QY2JQ5Y0G9KKdlDpo0zK+/OHptU5AaBwUfAIDJZk1MYf32Frm84EcOytfJE0t5JvkAnKlmjsXDnWzCJmQ==",
-      "dev": true
-    },
     "node_modules/html-encoding-sniffer": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz",
@@ -3742,18 +3927,19 @@
       }
     },
     "node_modules/htmlnano": {
-      "version": "0.2.6",
-      "resolved": "https://registry.npmjs.org/htmlnano/-/htmlnano-0.2.6.tgz",
-      "integrity": "sha512-HUY/99maFsWX2LRoGJpZ/8QRLCkyY0UU1El3wgLLFAHQlD3mCxCJJNcWJk5SBqaU49MLhIWVDW6cGBeuemvaPQ==",
+      "version": "0.2.9",
+      "resolved": "https://registry.npmjs.org/htmlnano/-/htmlnano-0.2.9.tgz",
+      "integrity": "sha512-jWTtP3dCd7R8x/tt9DK3pvpcQd7HDMcRPUqPxr/i9989q2k5RHIhmlRDFeyQ/LSd8IKrteG8Ce5g0Ig4eGIipg==",
       "dev": true,
       "dependencies": {
-        "cssnano": "^4.1.10",
-        "normalize-html-whitespace": "^1.0.0",
-        "posthtml": "^0.13.1",
-        "posthtml-render": "^1.2.2",
+        "cssnano": "^4.1.11",
+        "posthtml": "^0.15.1",
         "purgecss": "^2.3.0",
+        "relateurl": "^0.2.7",
+        "srcset": "^3.0.0",
         "svgo": "^1.3.2",
-        "terser": "^4.8.0",
+        "terser": "^5.6.1",
+        "timsort": "^0.3.0",
         "uncss": "^0.17.3"
       }
     },
@@ -3769,6 +3955,89 @@
         "node": ">=4"
       }
     },
+    "node_modules/htmlnano/node_modules/dom-serializer": {
+      "version": "1.3.2",
+      "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.3.2.tgz",
+      "integrity": "sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig==",
+      "dev": true,
+      "dependencies": {
+        "domelementtype": "^2.0.1",
+        "domhandler": "^4.2.0",
+        "entities": "^2.0.0"
+      },
+      "funding": {
+        "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
+      }
+    },
+    "node_modules/htmlnano/node_modules/domelementtype": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz",
+      "integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==",
+      "dev": true,
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/fb55"
+        }
+      ]
+    },
+    "node_modules/htmlnano/node_modules/domhandler": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.0.tgz",
+      "integrity": "sha512-fC0aXNQXqKSFTr2wDNZDhsEYjCiYsDWl3D01kwt25hm1YIPyDGHvvi3rw+PLqHAl/m71MaiF7d5zvBr0p5UB2g==",
+      "dev": true,
+      "dependencies": {
+        "domelementtype": "^2.2.0"
+      },
+      "engines": {
+        "node": ">= 4"
+      },
+      "funding": {
+        "url": "https://github.com/fb55/domhandler?sponsor=1"
+      }
+    },
+    "node_modules/htmlnano/node_modules/domutils": {
+      "version": "2.8.0",
+      "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz",
+      "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==",
+      "dev": true,
+      "dependencies": {
+        "dom-serializer": "^1.0.1",
+        "domelementtype": "^2.2.0",
+        "domhandler": "^4.2.0"
+      },
+      "funding": {
+        "url": "https://github.com/fb55/domutils?sponsor=1"
+      }
+    },
+    "node_modules/htmlnano/node_modules/entities": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz",
+      "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==",
+      "dev": true,
+      "funding": {
+        "url": "https://github.com/fb55/entities?sponsor=1"
+      }
+    },
+    "node_modules/htmlnano/node_modules/htmlparser2": {
+      "version": "6.1.0",
+      "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz",
+      "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==",
+      "dev": true,
+      "funding": [
+        "https://github.com/fb55/htmlparser2?sponsor=1",
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/fb55"
+        }
+      ],
+      "dependencies": {
+        "domelementtype": "^2.0.1",
+        "domhandler": "^4.0.0",
+        "domutils": "^2.5.2",
+        "entities": "^2.0.0"
+      }
+    },
     "node_modules/htmlnano/node_modules/is-absolute-url": {
       "version": "3.0.3",
       "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-3.0.3.tgz",
@@ -3793,51 +4062,55 @@
       }
     },
     "node_modules/htmlnano/node_modules/posthtml": {
-      "version": "0.13.1",
-      "resolved": "https://registry.npmjs.org/posthtml/-/posthtml-0.13.1.tgz",
-      "integrity": "sha512-8aJZ63WYL9YsAZVcrIn6U0dSYbna7hcTceZjnbH7dilg01t4t3JDx0UovbhGFscFJg/++qhECCjGEQuJAqD7dA==",
+      "version": "0.15.2",
+      "resolved": "https://registry.npmjs.org/posthtml/-/posthtml-0.15.2.tgz",
+      "integrity": "sha512-YugEJ5ze/0DLRIVBjCpDwANWL4pPj1kHJ/2llY8xuInr0nbkon3qTiMPe5LQa+cCwNjxS7nAZZTp+1M+6mT4Zg==",
       "dev": true,
       "dependencies": {
-        "posthtml-parser": "^0.4.2",
-        "posthtml-render": "^1.2.2"
+        "posthtml-parser": "^0.7.2",
+        "posthtml-render": "^1.3.1"
       },
       "engines": {
         "node": ">=10.0.0"
       }
     },
     "node_modules/htmlnano/node_modules/posthtml-parser": {
-      "version": "0.4.2",
-      "resolved": "https://registry.npmjs.org/posthtml-parser/-/posthtml-parser-0.4.2.tgz",
-      "integrity": "sha512-BUIorsYJTvS9UhXxPTzupIztOMVNPa/HtAm9KHni9z6qEfiJ1bpOBL5DfUOL9XAc3XkLIEzBzpph+Zbm4AdRAg==",
+      "version": "0.7.2",
+      "resolved": "https://registry.npmjs.org/posthtml-parser/-/posthtml-parser-0.7.2.tgz",
+      "integrity": "sha512-LjEEG/3fNcWZtBfsOE3Gbyg1Li4CmsZRkH1UmbMR7nKdMXVMYI3B4/ZMiCpaq8aI1Aym4FRMMW9SAOLSwOnNsQ==",
       "dev": true,
       "dependencies": {
-        "htmlparser2": "^3.9.2"
+        "htmlparser2": "^6.0.0"
+      },
+      "engines": {
+        "node": ">=10"
       }
     },
-    "node_modules/htmlnano/node_modules/posthtml-render": {
-      "version": "1.2.2",
-      "resolved": "https://registry.npmjs.org/posthtml-render/-/posthtml-render-1.2.2.tgz",
-      "integrity": "sha512-MbIXTWwAfJ9qET6Zl29UNwJcDJEEz9Zkr5oDhiujitJa7YBJwEpbkX2cmuklCDxubTMoRWpid3q8DrSyGnUUzQ==",
+    "node_modules/htmlnano/node_modules/source-map": {
+      "version": "0.7.3",
+      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz",
+      "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==",
       "dev": true,
       "engines": {
-        "node": ">=8"
+        "node": ">= 8"
       }
     },
     "node_modules/htmlnano/node_modules/terser": {
-      "version": "4.8.0",
-      "resolved": "https://registry.npmjs.org/terser/-/terser-4.8.0.tgz",
-      "integrity": "sha512-EAPipTNeWsb/3wLPeup1tVPaXfIaU68xMnVdPafIL1TV05OhASArYyIfFvnvJCNrR2NIOvDVNNTFRa+Re2MWyw==",
+      "version": "5.12.1",
+      "resolved": "https://registry.npmjs.org/terser/-/terser-5.12.1.tgz",
+      "integrity": "sha512-NXbs+7nisos5E+yXwAD+y7zrcTkMqb0dEJxIGtSKPdCBzopf7ni4odPul2aechpV7EXNvOudYOX2bb5tln1jbQ==",
       "dev": true,
       "dependencies": {
+        "acorn": "^8.5.0",
         "commander": "^2.20.0",
-        "source-map": "~0.6.1",
-        "source-map-support": "~0.5.12"
+        "source-map": "~0.7.2",
+        "source-map-support": "~0.5.20"
       },
       "bin": {
         "terser": "bin/terser"
       },
       "engines": {
-        "node": ">=6.0.0"
+        "node": ">=10"
       }
     },
     "node_modules/htmlnano/node_modules/uncss": {
@@ -4214,12 +4487,12 @@
       }
     },
     "node_modules/is-obj": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz",
-      "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=",
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz",
+      "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==",
       "dev": true,
       "engines": {
-        "node": ">=0.10.0"
+        "node": ">=8"
       }
     },
     "node_modules/is-plain-object": {
@@ -4252,18 +4525,6 @@
       "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==",
       "dev": true
     },
-    "node_modules/is-svg": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/is-svg/-/is-svg-3.0.0.tgz",
-      "integrity": "sha512-gi4iHK53LR2ujhLVVj+37Ykh9GLqYHX6JOVXbLAucaG/Cqw9xwdFOjDM2qeifLs1sF1npXXFvDu0r5HNgCMrzQ==",
-      "dev": true,
-      "dependencies": {
-        "html-comment-regex": "^1.1.0"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
     "node_modules/is-symbol": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz",
@@ -4438,8 +4699,7 @@
         "esprima": "^3.1.3",
         "estraverse": "^4.2.0",
         "esutils": "^2.0.2",
-        "optionator": "^0.8.1",
-        "source-map": "~0.6.1"
+        "optionator": "^0.8.1"
       },
       "bin": {
         "escodegen": "bin/escodegen.js",
@@ -4447,12 +4707,15 @@
       },
       "engines": {
         "node": ">=4.0"
+      },
+      "optionalDependencies": {
+        "source-map": "~0.6.1"
       }
     },
     "node_modules/jsdom/node_modules/ws": {
-      "version": "6.2.1",
-      "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz",
-      "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==",
+      "version": "6.2.2",
+      "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz",
+      "integrity": "sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==",
       "dev": true,
       "dependencies": {
         "async-limiter": "~1.0.0"
@@ -4477,9 +4740,9 @@
       "dev": true
     },
     "node_modules/json-schema": {
-      "version": "0.2.3",
-      "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
-      "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=",
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz",
+      "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==",
       "dev": true
     },
     "node_modules/json-schema-traverse": {
@@ -4507,18 +4770,18 @@
       }
     },
     "node_modules/jsprim": {
-      "version": "1.4.1",
-      "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
-      "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
+      "version": "1.4.2",
+      "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz",
+      "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==",
       "dev": true,
-      "engines": [
-        "node >=0.6.0"
-      ],
       "dependencies": {
         "assert-plus": "1.0.0",
         "extsprintf": "1.3.0",
-        "json-schema": "0.2.3",
+        "json-schema": "0.4.0",
         "verror": "1.10.0"
+      },
+      "engines": {
+        "node": ">=0.6.0"
       }
     },
     "node_modules/kind-of": {
@@ -4544,9 +4807,9 @@
       }
     },
     "node_modules/lodash": {
-      "version": "4.17.19",
-      "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz",
-      "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==",
+      "version": "4.17.21",
+      "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
+      "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
       "dev": true
     },
     "node_modules/lodash.clone": {
@@ -4904,31 +5167,10 @@
       "dev": true
     },
     "node_modules/node-releases": {
-      "version": "1.1.36",
-      "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.36.tgz",
-      "integrity": "sha512-ggXhX6QGyJSjj3r+6ml2LqqC28XOWmKtpb+a15/Zpr9V3yoNazxJNlcQDS9bYaid5FReEWHEgToH1mwoUceWwg==",
-      "dev": true,
-      "dependencies": {
-        "semver": "^6.3.0"
-      }
-    },
-    "node_modules/node-releases/node_modules/semver": {
-      "version": "6.3.0",
-      "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
-      "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
-      "dev": true,
-      "bin": {
-        "semver": "bin/semver.js"
-      }
-    },
-    "node_modules/normalize-html-whitespace": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/normalize-html-whitespace/-/normalize-html-whitespace-1.0.0.tgz",
-      "integrity": "sha512-9ui7CGtOOlehQu0t/OhhlmDyc71mKVlv+4vF+me4iZLPrNtRL2xoquEdfZxasC/bdQi/Hr3iTrpyRKIG+ocabA==",
-      "dev": true,
-      "engines": {
-        "node": ">= 8"
-      }
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.2.tgz",
+      "integrity": "sha512-XxYDdcQ6eKqp/YjI+tb2C5WM2LgjnZrfYg4vgQt49EK268b6gYCHsBLrK2qvJo4FmCtqmKezb0WZFK4fkrZNsg==",
+      "dev": true
     },
     "node_modules/normalize-path": {
       "version": "3.0.0",
@@ -5348,9 +5590,9 @@
       }
     },
     "node_modules/path-parse": {
-      "version": "1.0.6",
-      "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
-      "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==",
+      "version": "1.0.7",
+      "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
+      "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
       "dev": true
     },
     "node_modules/pbkdf2": {
@@ -5381,6 +5623,12 @@
       "integrity": "sha1-GN4vl+S/epVRrXURlCtUlverpmA=",
       "dev": true
     },
+    "node_modules/picocolors": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
+      "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
+      "dev": true
+    },
     "node_modules/picomatch": {
       "version": "2.2.2",
       "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz",
@@ -5388,6 +5636,9 @@
       "dev": true,
       "engines": {
         "node": ">=8.6"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/jonschlinkert"
       }
     },
     "node_modules/pn": {
@@ -5406,31 +5657,39 @@
       }
     },
     "node_modules/postcss": {
-      "version": "7.0.18",
-      "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.18.tgz",
-      "integrity": "sha512-/7g1QXXgegpF+9GJj4iN7ChGF40sYuGYJ8WZu8DZWnmhQ/G36hfdk3q9LBJmoK+lZ+yzZ5KYpOoxq7LF1BxE8g==",
+      "version": "7.0.39",
+      "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
+      "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
       "dev": true,
       "dependencies": {
-        "chalk": "^2.4.2",
-        "source-map": "^0.6.1",
-        "supports-color": "^6.1.0"
+        "picocolors": "^0.2.1",
+        "source-map": "^0.6.1"
       },
       "engines": {
         "node": ">=6.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/postcss/"
       }
     },
     "node_modules/postcss-calc": {
-      "version": "7.0.1",
-      "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-7.0.1.tgz",
-      "integrity": "sha512-oXqx0m6tb4N3JGdmeMSc/i91KppbYsFZKdH0xMOqK8V1rJlzrKlTdokz8ozUXLVejydRN6u2IddxpcijRj2FqQ==",
+      "version": "7.0.5",
+      "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-7.0.5.tgz",
+      "integrity": "sha512-1tKHutbGtLtEZF6PT4JSihCHfIVldU72mZ8SdZHIYriIZ9fh9k9aWSppaT8rHsyI3dX+KSR+W+Ix9BMY3AODrg==",
       "dev": true,
       "dependencies": {
-        "css-unit-converter": "^1.1.1",
-        "postcss": "^7.0.5",
-        "postcss-selector-parser": "^5.0.0-rc.4",
-        "postcss-value-parser": "^3.3.1"
+        "postcss": "^7.0.27",
+        "postcss-selector-parser": "^6.0.2",
+        "postcss-value-parser": "^4.0.2"
       }
     },
+    "node_modules/postcss-calc/node_modules/postcss-value-parser": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
+      "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==",
+      "dev": true
+    },
     "node_modules/postcss-colormin": {
       "version": "4.0.3",
       "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-4.0.3.tgz",
@@ -5541,17 +5800,17 @@
       }
     },
     "node_modules/postcss-merge-rules/node_modules/postcss-selector-parser": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.1.tgz",
-      "integrity": "sha1-T4dfSvsMllc9XPTXQBGu4lCn6GU=",
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz",
+      "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==",
       "dev": true,
       "dependencies": {
-        "dot-prop": "^4.1.1",
+        "dot-prop": "^5.2.0",
         "indexes-of": "^1.0.1",
         "uniq": "^1.0.1"
       },
       "engines": {
-        "node": ">=4"
+        "node": ">=8"
       }
     },
     "node_modules/postcss-minify-font-values": {
@@ -5615,17 +5874,17 @@
       }
     },
     "node_modules/postcss-minify-selectors/node_modules/postcss-selector-parser": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.1.tgz",
-      "integrity": "sha1-T4dfSvsMllc9XPTXQBGu4lCn6GU=",
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz",
+      "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==",
       "dev": true,
       "dependencies": {
-        "dot-prop": "^4.1.1",
+        "dot-prop": "^5.2.0",
         "indexes-of": "^1.0.1",
         "uniq": "^1.0.1"
       },
       "engines": {
-        "node": ">=4"
+        "node": ">=8"
       }
     },
     "node_modules/postcss-modules-extract-imports": {
@@ -5894,23 +6153,22 @@
       }
     },
     "node_modules/postcss-selector-parser": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz",
-      "integrity": "sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ==",
+      "version": "6.0.9",
+      "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.9.tgz",
+      "integrity": "sha512-UO3SgnZOVTwu4kyLR22UQ1xZh086RyNZppb7lLAKBFK8a32ttG5i87Y/P3+2bRSjZNyJ1B7hfFNo273tKe9YxQ==",
       "dev": true,
       "dependencies": {
-        "cssesc": "^2.0.0",
-        "indexes-of": "^1.0.1",
-        "uniq": "^1.0.1"
+        "cssesc": "^3.0.0",
+        "util-deprecate": "^1.0.2"
       },
       "engines": {
         "node": ">=4"
       }
     },
     "node_modules/postcss-selector-parser/node_modules/cssesc": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-2.0.0.tgz",
-      "integrity": "sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg==",
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
+      "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
       "dev": true,
       "bin": {
         "cssesc": "bin/cssesc"
@@ -5920,12 +6178,11 @@
       }
     },
     "node_modules/postcss-svgo": {
-      "version": "4.0.2",
-      "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-4.0.2.tgz",
-      "integrity": "sha512-C6wyjo3VwFm0QgBy+Fu7gCYOkCmgmClghO+pjcxvrcBKtiKt0uCF+hvbMO1fyv5BMImRK90SMb+dwUnfbGd+jw==",
+      "version": "4.0.3",
+      "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-4.0.3.tgz",
+      "integrity": "sha512-NoRbrcMWTtUghzuKSoIm6XV+sJdvZ7GZSc3wdBN0W19FTtp2ko8NqLsgoh/m9CzNhU3KLPvQmjIwtaNFkaFTvw==",
       "dev": true,
       "dependencies": {
-        "is-svg": "^3.0.0",
         "postcss": "^7.0.0",
         "postcss-value-parser": "^3.0.0",
         "svgo": "^1.0.0"
@@ -5954,17 +6211,11 @@
       "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==",
       "dev": true
     },
-    "node_modules/postcss/node_modules/supports-color": {
-      "version": "6.1.0",
-      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
-      "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
-      "dev": true,
-      "dependencies": {
-        "has-flag": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=6"
-      }
+    "node_modules/postcss/node_modules/picocolors": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
+      "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
+      "dev": true
     },
     "node_modules/posthtml": {
       "version": "0.11.6",
@@ -5990,12 +6241,12 @@
       }
     },
     "node_modules/posthtml-render": {
-      "version": "1.1.5",
-      "resolved": "https://registry.npmjs.org/posthtml-render/-/posthtml-render-1.1.5.tgz",
-      "integrity": "sha512-yvt54j0zCBHQVEFAuR+yHld8CZrCa/E1Z/OcFNCV1IEWTLVxT8O7nYnM4IIw1CD4r8kaRd3lc42+0lgCKgm87w==",
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/posthtml-render/-/posthtml-render-1.4.0.tgz",
+      "integrity": "sha512-W1779iVHGfq0Fvh2PROhCe2QhB8mEErgqzo1wpIt36tCgChafP+hbXIhLDOM8ePJrZcFs0vkNEtdibEWVqChqw==",
       "dev": true,
       "engines": {
-        "node": ">=6"
+        "node": ">=10"
       }
     },
     "node_modules/prelude-ls": {
@@ -6084,18 +6335,6 @@
         "node": ">= 6"
       }
     },
-    "node_modules/purgecss/node_modules/cssesc": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
-      "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
-      "dev": true,
-      "bin": {
-        "cssesc": "bin/cssesc"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
     "node_modules/purgecss/node_modules/postcss": {
       "version": "7.0.32",
       "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.32.tgz",
@@ -6108,20 +6347,10 @@
       },
       "engines": {
         "node": ">=6.0.0"
-      }
-    },
-    "node_modules/purgecss/node_modules/postcss-selector-parser": {
-      "version": "6.0.2",
-      "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.2.tgz",
-      "integrity": "sha512-36P2QR59jDTOAiIkqEprfJDsoNrvwFei3eCqKd1Y0tUsBimsq39BLp7RD+JWny3WgB1zGhJX8XVePwm9k4wdBg==",
-      "dev": true,
-      "dependencies": {
-        "cssesc": "^3.0.0",
-        "indexes-of": "^1.0.1",
-        "uniq": "^1.0.1"
       },
-      "engines": {
-        "node": ">=4"
+      "funding": {
+        "type": "tidelift",
+        "url": "https://tidelift.com/funding/github/npm/postcss"
       }
     },
     "node_modules/purgecss/node_modules/supports-color": {
@@ -6159,6 +6388,7 @@
       "version": "0.2.0",
       "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz",
       "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=",
+      "deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.",
       "dev": true,
       "engines": {
         "node": ">=0.4.x"
@@ -6332,6 +6562,15 @@
         "jsesc": "bin/jsesc"
       }
     },
+    "node_modules/relateurl": {
+      "version": "0.2.7",
+      "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz",
+      "integrity": "sha1-VNvzd+UUQKypCkzSdGANP/LYiKk=",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.10"
+      }
+    },
     "node_modules/remove-trailing-separator": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
@@ -6360,6 +6599,7 @@
       "version": "2.88.0",
       "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz",
       "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==",
+      "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142",
       "dev": true,
       "dependencies": {
         "aws-sign2": "~0.7.0",
@@ -6397,12 +6637,16 @@
       },
       "engines": {
         "node": ">=0.10.0"
+      },
+      "peerDependencies": {
+        "request": "^2.34"
       }
     },
     "node_modules/request-promise-native": {
       "version": "1.0.7",
       "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.7.tgz",
       "integrity": "sha512-rIMnbBdgNViL37nZ1b3L/VfPOpSi0TqVDQPAvO6U14lMzOLrt5nilxCQqtDKhZeDiW0/hkCXGoQjhgJd/tCh6w==",
+      "deprecated": "request-promise-native has been deprecated because it extends the now deprecated request package, see https://github.com/request/request/issues/3142",
       "dev": true,
       "dependencies": {
         "request-promise-core": "1.1.2",
@@ -6411,6 +6655,9 @@
       },
       "engines": {
         "node": ">=0.12.0"
+      },
+      "peerDependencies": {
+        "request": "^2.34"
       }
     },
     "node_modules/request/node_modules/punycode": {
@@ -6454,6 +6701,7 @@
       "version": "0.2.1",
       "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
       "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=",
+      "deprecated": "https://github.com/lydell/resolve-url#deprecated",
       "dev": true
     },
     "node_modules/restore-cursor": {
@@ -6912,6 +7160,7 @@
       "version": "0.5.2",
       "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz",
       "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==",
+      "deprecated": "See https://github.com/lydell/source-map-resolve#deprecated",
       "dev": true,
       "dependencies": {
         "atob": "^2.1.1",
@@ -6922,9 +7171,9 @@
       }
     },
     "node_modules/source-map-support": {
-      "version": "0.5.13",
-      "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz",
-      "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==",
+      "version": "0.5.21",
+      "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
+      "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
       "dev": true,
       "dependencies": {
         "buffer-from": "^1.0.0",
@@ -6935,6 +7184,7 @@
       "version": "0.4.0",
       "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz",
       "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=",
+      "deprecated": "See https://github.com/lydell/source-map-url#deprecated",
       "dev": true
     },
     "node_modules/split-string": {
@@ -6955,6 +7205,18 @@
       "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
       "dev": true
     },
+    "node_modules/srcset": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/srcset/-/srcset-3.0.1.tgz",
+      "integrity": "sha512-MM8wDGg5BQJEj94tDrZDrX9wrC439/Eoeg3sgmVLPMjHgrAFeXAKk3tmFlCbKw5k+yOEhPXRpPlRcisQmqWVSQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
     "node_modules/sshpk": {
       "version": "1.16.1",
       "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz",
@@ -6971,6 +7233,11 @@
         "safer-buffer": "^2.0.2",
         "tweetnacl": "~0.14.0"
       },
+      "bin": {
+        "sshpk-conv": "bin/sshpk-conv",
+        "sshpk-sign": "bin/sshpk-sign",
+        "sshpk-verify": "bin/sshpk-verify"
+      },
       "engines": {
         "node": ">=0.10.0"
       }
@@ -7140,17 +7407,17 @@
       }
     },
     "node_modules/stylehacks/node_modules/postcss-selector-parser": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.1.tgz",
-      "integrity": "sha1-T4dfSvsMllc9XPTXQBGu4lCn6GU=",
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz",
+      "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==",
       "dev": true,
       "dependencies": {
-        "dot-prop": "^4.1.1",
+        "dot-prop": "^5.2.0",
         "indexes-of": "^1.0.1",
         "uniq": "^1.0.1"
       },
       "engines": {
-        "node": ">=4"
+        "node": ">=8"
       }
     },
     "node_modules/supports-color": {
@@ -7169,6 +7436,7 @@
       "version": "1.3.2",
       "resolved": "https://registry.npmjs.org/svgo/-/svgo-1.3.2.tgz",
       "integrity": "sha512-yhy/sQYxR5BkC98CY7o31VGsg014AKLEPxdfhora76l36hD9Rdy5NZA/Ocn6yayNPgSamYdtX2rFJdcv07AYVw==",
+      "deprecated": "This SVGO version is no longer supported. Upgrade to v2.x.x.",
       "dev": true,
       "dependencies": {
         "chalk": "^2.4.1",
@@ -7587,6 +7855,7 @@
       "version": "0.1.0",
       "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz",
       "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=",
+      "deprecated": "Please see https://github.com/lydell/urix#deprecated",
       "dev": true
     },
     "node_modules/url": {
@@ -7643,6 +7912,7 @@
       "version": "3.3.3",
       "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.3.tgz",
       "integrity": "sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ==",
+      "deprecated": "Please upgrade  to version 7 or higher.  Older versions may use Math.random() in certain circumstances, which is known to be problematic.  See https://v8.dev/blog/math-random for details.",
       "dev": true,
       "bin": {
         "uuid": "bin/uuid"
@@ -7655,10 +7925,14 @@
       "dev": true
     },
     "node_modules/vendors": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.3.tgz",
-      "integrity": "sha512-fOi47nsJP5Wqefa43kyWSg80qF+Q3XA6MUkgi7Hp1HQaKDQW4cQrK2D0P7mmbFtsV1N89am55Yru/nyEwRubcw==",
-      "dev": true
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.4.tgz",
+      "integrity": "sha512-/juG65kTL4Cy2su4P8HjtkTxk6VmJDiOPBufWniqQ6wknac6jNiXS9vU+hO3wgusiyqWlzTbVHi0dyJqRONg3w==",
+      "dev": true,
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/wooorm"
+      }
     },
     "node_modules/verror": {
       "version": "1.10.0",
@@ -7772,9 +8046,9 @@
       "dev": true
     },
     "node_modules/ws": {
-      "version": "5.2.2",
-      "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.2.tgz",
-      "integrity": "sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA==",
+      "version": "5.2.3",
+      "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.3.tgz",
+      "integrity": "sha512-jZArVERrMsKUatIdnLzqvcfydI85dvd/Fp1u/VOpfdDWQ4c9qWXe+VIeAbQ5FrDwciAkr+lzofXLz3Kuf26AOA==",
       "dev": true,
       "dependencies": {
         "async-limiter": "~1.0.0"
@@ -7841,14 +8115,6 @@
           "dev": true,
           "requires": {
             "minimist": "^1.2.0"
-          },
-          "dependencies": {
-            "minimist": {
-              "version": "1.2.5",
-              "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
-              "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
-              "dev": true
-            }
           }
         },
         "source-map": {
@@ -8783,7 +9049,11 @@
           "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz",
           "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==",
           "dev": true,
-          "optional": true
+          "optional": true,
+          "requires": {
+            "bindings": "^1.5.0",
+            "nan": "^2.12.1"
+          }
         },
         "is-binary-path": {
           "version": "1.0.1",
@@ -8829,6 +9099,12 @@
       "integrity": "sha512-2scffjvioEmNz0OyDSLGWDfKCVwaKc6l9Pm9kOIREU13ClXZvHpg/nRL5xyjSSSLhOnXqft2HpsAzNEEA8cFFg==",
       "dev": true
     },
+    "acorn": {
+      "version": "8.7.0",
+      "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz",
+      "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==",
+      "dev": true
+    },
     "acorn-globals": {
       "version": "4.3.4",
       "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.4.tgz",
@@ -8854,12 +9130,12 @@
       "dev": true
     },
     "ajv": {
-      "version": "6.10.2",
-      "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz",
-      "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==",
+      "version": "6.12.6",
+      "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+      "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
       "dev": true,
       "requires": {
-        "fast-deep-equal": "^2.0.1",
+        "fast-deep-equal": "^3.1.1",
         "fast-json-stable-stringify": "^2.0.0",
         "json-schema-traverse": "^0.4.1",
         "uri-js": "^4.2.2"
@@ -9186,9 +9462,9 @@
       "dev": true
     },
     "bn.js": {
-      "version": "4.11.8",
-      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
-      "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==",
+      "version": "4.12.0",
+      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
+      "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==",
       "dev": true
     },
     "boolbase": {
@@ -9340,14 +9616,16 @@
       }
     },
     "browserslist": {
-      "version": "4.7.1",
-      "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.7.1.tgz",
-      "integrity": "sha512-QtULFqKIAtiyNx7NhZ/p4rB8m3xDozVo/pi5VgTlADLF2tNigz/QH+v0m5qhn7XfHT7u+607NcCNOnC0HZAlMg==",
+      "version": "4.20.0",
+      "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.20.0.tgz",
+      "integrity": "sha512-bnpOoa+DownbciXj0jVGENf8VYQnE2LNWomhYuCsMmmx9Jd9lwq0WXODuwpSsp8AVdKM2/HorrzxAfbKvWTByQ==",
       "dev": true,
       "requires": {
-        "caniuse-lite": "^1.0.30000999",
-        "electron-to-chromium": "^1.3.284",
-        "node-releases": "^1.1.36"
+        "caniuse-lite": "^1.0.30001313",
+        "electron-to-chromium": "^1.4.76",
+        "escalade": "^3.1.1",
+        "node-releases": "^2.0.2",
+        "picocolors": "^1.0.0"
       }
     },
     "buffer": {
@@ -9445,9 +9723,9 @@
       }
     },
     "caniuse-lite": {
-      "version": "1.0.30000999",
-      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000999.tgz",
-      "integrity": "sha512-1CUyKyecPeksKwXZvYw0tEoaMCo/RwBlXmEtN5vVnabvO0KPd9RQLcaAuR9/1F+KDMv6esmOFWlsXuzDk+8rxg==",
+      "version": "1.0.30001316",
+      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001316.tgz",
+      "integrity": "sha512-JgUdNoZKxPZFzbzJwy4hDSyGuH/gXz2rN51QmoR8cBQsVo58llD3A0vlRKKRt8FGf5u69P9eQyIH8/z9vN/S0Q==",
       "dev": true
     },
     "caseless": {
@@ -9502,9 +9780,9 @@
           }
         },
         "glob-parent": {
-          "version": "5.1.1",
-          "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz",
-          "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==",
+          "version": "5.1.2",
+          "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+          "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
           "dev": true,
           "requires": {
             "is-glob": "^4.0.1"
@@ -9612,13 +9890,13 @@
       }
     },
     "color": {
-      "version": "3.1.2",
-      "resolved": "https://registry.npmjs.org/color/-/color-3.1.2.tgz",
-      "integrity": "sha512-vXTJhHebByxZn3lDvDJYw4lR5+uB3vuoHsuYA5AKuxRVn5wzzIfQKGLBmgdVRHKTJYeK5rvJcHnrd0Li49CFpg==",
+      "version": "3.2.1",
+      "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz",
+      "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==",
       "dev": true,
       "requires": {
-        "color-convert": "^1.9.1",
-        "color-string": "^1.5.2"
+        "color-convert": "^1.9.3",
+        "color-string": "^1.6.0"
       }
     },
     "color-convert": {
@@ -9637,9 +9915,9 @@
       "dev": true
     },
     "color-string": {
-      "version": "1.5.3",
-      "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.3.tgz",
-      "integrity": "sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw==",
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.0.tgz",
+      "integrity": "sha512-9Mrz2AQLefkH1UvASKj6v6hj/7eWgjnT/cVsR8CumieLoT+g900exWeNogqtweI8dxloXN9BDQTYro1oWu/5CQ==",
       "dev": true,
       "requires": {
         "color-name": "^1.0.0",
@@ -9939,13 +10217,13 @@
       }
     },
     "css-select": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/css-select/-/css-select-2.0.2.tgz",
-      "integrity": "sha512-dSpYaDVoWaELjvZ3mS6IKZM/y2PMPa/XYoEfYNZePL4U/XgyxZNroHEHReDx/d+VgXh9VbCTtFqLkFbmeqeaRQ==",
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/css-select/-/css-select-2.1.0.tgz",
+      "integrity": "sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ==",
       "dev": true,
       "requires": {
         "boolbase": "^1.0.0",
-        "css-what": "^2.1.2",
+        "css-what": "^3.2.1",
         "domutils": "^1.7.0",
         "nth-check": "^1.0.2"
       }
@@ -10001,16 +10279,10 @@
         }
       }
     },
-    "css-unit-converter": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/css-unit-converter/-/css-unit-converter-1.1.1.tgz",
-      "integrity": "sha1-2bkoGtz9jO2TW9urqDeGiX9k6ZY=",
-      "dev": true
-    },
     "css-what": {
-      "version": "2.1.3",
-      "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz",
-      "integrity": "sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==",
+      "version": "3.4.2",
+      "resolved": "https://registry.npmjs.org/css-what/-/css-what-3.4.2.tgz",
+      "integrity": "sha512-ACUm3L0/jiZTqfzRM3Hi9Q8eZqd6IK37mMWPLz9PJxkLWllYeRf+EHUSHYEtFop2Eqytaq1FizFVh7XfBnXCDQ==",
       "dev": true
     },
     "cssesc": {
@@ -10020,21 +10292,21 @@
       "dev": true
     },
     "cssnano": {
-      "version": "4.1.10",
-      "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-4.1.10.tgz",
-      "integrity": "sha512-5wny+F6H4/8RgNlaqab4ktc3e0/blKutmq8yNlBFXA//nSFFAqAngjNVRzUvCgYROULmZZUoosL/KSoZo5aUaQ==",
+      "version": "4.1.11",
+      "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-4.1.11.tgz",
+      "integrity": "sha512-6gZm2htn7xIPJOHY824ERgj8cNPgPxyCSnkXc4v7YvNW+TdVfzgngHcEhy/8D11kUWRUMbke+tC+AUcUsnMz2g==",
       "dev": true,
       "requires": {
         "cosmiconfig": "^5.0.0",
-        "cssnano-preset-default": "^4.0.7",
+        "cssnano-preset-default": "^4.0.8",
         "is-resolvable": "^1.0.0",
         "postcss": "^7.0.0"
       }
     },
     "cssnano-preset-default": {
-      "version": "4.0.7",
-      "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-4.0.7.tgz",
-      "integrity": "sha512-x0YHHx2h6p0fCl1zY9L9roD7rnlltugGu7zXSKQx6k2rYw0Hi3IqxcoAGF7u9Q5w1nt7vK0ulxV8Lo+EvllGsA==",
+      "version": "4.0.8",
+      "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-4.0.8.tgz",
+      "integrity": "sha512-LdAyHuq+VRyeVREFmuxUZR1TXjQm8QQU/ktoo/x7bz+SdOge1YKc5eMN6pRW7YWBmyq59CqYba1dJ5cUukEjLQ==",
       "dev": true,
       "requires": {
         "css-declaration-sorter": "^4.0.1",
@@ -10065,7 +10337,7 @@
         "postcss-ordered-values": "^4.1.2",
         "postcss-reduce-initial": "^4.0.3",
         "postcss-reduce-transforms": "^4.0.2",
-        "postcss-svgo": "^4.0.2",
+        "postcss-svgo": "^4.0.3",
         "postcss-unique-selectors": "^4.0.1"
       }
     },
@@ -10339,12 +10611,12 @@
       }
     },
     "dot-prop": {
-      "version": "4.2.0",
-      "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz",
-      "integrity": "sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ==",
+      "version": "5.3.0",
+      "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz",
+      "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==",
       "dev": true,
       "requires": {
-        "is-obj": "^1.0.0"
+        "is-obj": "^2.0.0"
       }
     },
     "dotenv": {
@@ -10385,24 +10657,32 @@
       "dev": true
     },
     "electron-to-chromium": {
-      "version": "1.3.285",
-      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.285.tgz",
-      "integrity": "sha512-DYR9KW723sUbGK++DCmCmM95AbNXT4Q0tlCFMcYijFjayhuDqlGYR68OemlP8MJj0gjkwdeItIUfd0oLCgw+4A==",
+      "version": "1.4.83",
+      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.83.tgz",
+      "integrity": "sha512-Wm15TA5pLMOHtsik6uQTVyzXG8IpkVxnXAoAqV4+6zbJH3n5qnVz3iNAW+65r6WSrrYo0w6B8JJ0lcv2NhSmXQ==",
       "dev": true
     },
     "elliptic": {
-      "version": "6.5.1",
-      "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.1.tgz",
-      "integrity": "sha512-xvJINNLbTeWQjrl6X+7eQCrIy/YPv5XCpKW6kB5mKvtnGILoLDcySuwomfdzt0BMdLNVnuRNTuzKNHj0bva1Cg==",
+      "version": "6.5.4",
+      "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz",
+      "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==",
       "dev": true,
       "requires": {
-        "bn.js": "^4.4.0",
-        "brorand": "^1.0.1",
+        "bn.js": "^4.11.9",
+        "brorand": "^1.1.0",
         "hash.js": "^1.0.0",
-        "hmac-drbg": "^1.0.0",
-        "inherits": "^2.0.1",
-        "minimalistic-assert": "^1.0.0",
-        "minimalistic-crypto-utils": "^1.0.0"
+        "hmac-drbg": "^1.0.1",
+        "inherits": "^2.0.4",
+        "minimalistic-assert": "^1.0.1",
+        "minimalistic-crypto-utils": "^1.0.1"
+      },
+      "dependencies": {
+        "inherits": {
+          "version": "2.0.4",
+          "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+          "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+          "dev": true
+        }
       }
     },
     "encodeurl": {
@@ -10469,6 +10749,12 @@
         "is-symbol": "^1.0.2"
       }
     },
+    "escalade": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
+      "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
+      "dev": true
+    },
     "escape-html": {
       "version": "1.0.3",
       "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
@@ -10709,9 +10995,9 @@
       }
     },
     "fast-deep-equal": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz",
-      "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=",
+      "version": "3.1.3",
+      "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+      "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
       "dev": true
     },
     "fast-glob": {
@@ -11057,12 +11343,6 @@
       "integrity": "sha1-wc56MWjIxmFAM6S194d/OyJfnDg=",
       "dev": true
     },
-    "html-comment-regex": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/html-comment-regex/-/html-comment-regex-1.1.2.tgz",
-      "integrity": "sha512-P+M65QY2JQ5Y0G9KKdlDpo0zK+/OHptU5AaBwUfAIDJZk1MYf32Frm84EcOytfJE0t5JvkAnKlmjsXDnWzCJmQ==",
-      "dev": true
-    },
     "html-encoding-sniffer": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz",
@@ -11079,18 +11359,19 @@
       "dev": true
     },
     "htmlnano": {
-      "version": "0.2.6",
-      "resolved": "https://registry.npmjs.org/htmlnano/-/htmlnano-0.2.6.tgz",
-      "integrity": "sha512-HUY/99maFsWX2LRoGJpZ/8QRLCkyY0UU1El3wgLLFAHQlD3mCxCJJNcWJk5SBqaU49MLhIWVDW6cGBeuemvaPQ==",
+      "version": "0.2.9",
+      "resolved": "https://registry.npmjs.org/htmlnano/-/htmlnano-0.2.9.tgz",
+      "integrity": "sha512-jWTtP3dCd7R8x/tt9DK3pvpcQd7HDMcRPUqPxr/i9989q2k5RHIhmlRDFeyQ/LSd8IKrteG8Ce5g0Ig4eGIipg==",
       "dev": true,
       "requires": {
-        "cssnano": "^4.1.10",
-        "normalize-html-whitespace": "^1.0.0",
-        "posthtml": "^0.13.1",
-        "posthtml-render": "^1.2.2",
+        "cssnano": "^4.1.11",
+        "posthtml": "^0.15.1",
         "purgecss": "^2.3.0",
+        "relateurl": "^0.2.7",
+        "srcset": "^3.0.0",
         "svgo": "^1.3.2",
-        "terser": "^4.8.0",
+        "terser": "^5.6.1",
+        "timsort": "^0.3.0",
         "uncss": "^0.17.3"
       },
       "dependencies": {
@@ -11100,6 +11381,61 @@
           "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
           "dev": true
         },
+        "dom-serializer": {
+          "version": "1.3.2",
+          "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.3.2.tgz",
+          "integrity": "sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig==",
+          "dev": true,
+          "requires": {
+            "domelementtype": "^2.0.1",
+            "domhandler": "^4.2.0",
+            "entities": "^2.0.0"
+          }
+        },
+        "domelementtype": {
+          "version": "2.2.0",
+          "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz",
+          "integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==",
+          "dev": true
+        },
+        "domhandler": {
+          "version": "4.3.0",
+          "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.0.tgz",
+          "integrity": "sha512-fC0aXNQXqKSFTr2wDNZDhsEYjCiYsDWl3D01kwt25hm1YIPyDGHvvi3rw+PLqHAl/m71MaiF7d5zvBr0p5UB2g==",
+          "dev": true,
+          "requires": {
+            "domelementtype": "^2.2.0"
+          }
+        },
+        "domutils": {
+          "version": "2.8.0",
+          "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz",
+          "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==",
+          "dev": true,
+          "requires": {
+            "dom-serializer": "^1.0.1",
+            "domelementtype": "^2.2.0",
+            "domhandler": "^4.2.0"
+          }
+        },
+        "entities": {
+          "version": "2.2.0",
+          "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz",
+          "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==",
+          "dev": true
+        },
+        "htmlparser2": {
+          "version": "6.1.0",
+          "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz",
+          "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==",
+          "dev": true,
+          "requires": {
+            "domelementtype": "^2.0.1",
+            "domhandler": "^4.0.0",
+            "domutils": "^2.5.2",
+            "entities": "^2.0.0"
+          }
+        },
         "is-absolute-url": {
           "version": "3.0.3",
           "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-3.0.3.tgz",
@@ -11118,39 +11454,40 @@
           }
         },
         "posthtml": {
-          "version": "0.13.1",
-          "resolved": "https://registry.npmjs.org/posthtml/-/posthtml-0.13.1.tgz",
-          "integrity": "sha512-8aJZ63WYL9YsAZVcrIn6U0dSYbna7hcTceZjnbH7dilg01t4t3JDx0UovbhGFscFJg/++qhECCjGEQuJAqD7dA==",
+          "version": "0.15.2",
+          "resolved": "https://registry.npmjs.org/posthtml/-/posthtml-0.15.2.tgz",
+          "integrity": "sha512-YugEJ5ze/0DLRIVBjCpDwANWL4pPj1kHJ/2llY8xuInr0nbkon3qTiMPe5LQa+cCwNjxS7nAZZTp+1M+6mT4Zg==",
           "dev": true,
           "requires": {
-            "posthtml-parser": "^0.4.2",
-            "posthtml-render": "^1.2.2"
+            "posthtml-parser": "^0.7.2",
+            "posthtml-render": "^1.3.1"
           }
         },
         "posthtml-parser": {
-          "version": "0.4.2",
-          "resolved": "https://registry.npmjs.org/posthtml-parser/-/posthtml-parser-0.4.2.tgz",
-          "integrity": "sha512-BUIorsYJTvS9UhXxPTzupIztOMVNPa/HtAm9KHni9z6qEfiJ1bpOBL5DfUOL9XAc3XkLIEzBzpph+Zbm4AdRAg==",
+          "version": "0.7.2",
+          "resolved": "https://registry.npmjs.org/posthtml-parser/-/posthtml-parser-0.7.2.tgz",
+          "integrity": "sha512-LjEEG/3fNcWZtBfsOE3Gbyg1Li4CmsZRkH1UmbMR7nKdMXVMYI3B4/ZMiCpaq8aI1Aym4FRMMW9SAOLSwOnNsQ==",
           "dev": true,
           "requires": {
-            "htmlparser2": "^3.9.2"
+            "htmlparser2": "^6.0.0"
           }
         },
-        "posthtml-render": {
-          "version": "1.2.2",
-          "resolved": "https://registry.npmjs.org/posthtml-render/-/posthtml-render-1.2.2.tgz",
-          "integrity": "sha512-MbIXTWwAfJ9qET6Zl29UNwJcDJEEz9Zkr5oDhiujitJa7YBJwEpbkX2cmuklCDxubTMoRWpid3q8DrSyGnUUzQ==",
+        "source-map": {
+          "version": "0.7.3",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz",
+          "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==",
           "dev": true
         },
         "terser": {
-          "version": "4.8.0",
-          "resolved": "https://registry.npmjs.org/terser/-/terser-4.8.0.tgz",
-          "integrity": "sha512-EAPipTNeWsb/3wLPeup1tVPaXfIaU68xMnVdPafIL1TV05OhASArYyIfFvnvJCNrR2NIOvDVNNTFRa+Re2MWyw==",
+          "version": "5.12.1",
+          "resolved": "https://registry.npmjs.org/terser/-/terser-5.12.1.tgz",
+          "integrity": "sha512-NXbs+7nisos5E+yXwAD+y7zrcTkMqb0dEJxIGtSKPdCBzopf7ni4odPul2aechpV7EXNvOudYOX2bb5tln1jbQ==",
           "dev": true,
           "requires": {
+            "acorn": "^8.5.0",
             "commander": "^2.20.0",
-            "source-map": "~0.6.1",
-            "source-map-support": "~0.5.12"
+            "source-map": "~0.7.2",
+            "source-map-support": "~0.5.20"
           }
         },
         "uncss": {
@@ -11468,9 +11805,9 @@
       }
     },
     "is-obj": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz",
-      "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=",
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz",
+      "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==",
       "dev": true
     },
     "is-plain-object": {
@@ -11497,15 +11834,6 @@
       "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==",
       "dev": true
     },
-    "is-svg": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/is-svg/-/is-svg-3.0.0.tgz",
-      "integrity": "sha512-gi4iHK53LR2ujhLVVj+37Ykh9GLqYHX6JOVXbLAucaG/Cqw9xwdFOjDM2qeifLs1sF1npXXFvDu0r5HNgCMrzQ==",
-      "dev": true,
-      "requires": {
-        "html-comment-regex": "^1.1.0"
-      }
-    },
     "is-symbol": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz",
@@ -11653,9 +11981,9 @@
           }
         },
         "ws": {
-          "version": "6.2.1",
-          "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz",
-          "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==",
+          "version": "6.2.2",
+          "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz",
+          "integrity": "sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==",
           "dev": true,
           "requires": {
             "async-limiter": "~1.0.0"
@@ -11676,9 +12004,9 @@
       "dev": true
     },
     "json-schema": {
-      "version": "0.2.3",
-      "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
-      "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=",
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz",
+      "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==",
       "dev": true
     },
     "json-schema-traverse": {
@@ -11703,14 +12031,14 @@
       }
     },
     "jsprim": {
-      "version": "1.4.1",
-      "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
-      "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
+      "version": "1.4.2",
+      "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz",
+      "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==",
       "dev": true,
       "requires": {
         "assert-plus": "1.0.0",
         "extsprintf": "1.3.0",
-        "json-schema": "0.2.3",
+        "json-schema": "0.4.0",
         "verror": "1.10.0"
       }
     },
@@ -11731,9 +12059,9 @@
       }
     },
     "lodash": {
-      "version": "4.17.19",
-      "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz",
-      "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==",
+      "version": "4.17.21",
+      "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
+      "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
       "dev": true
     },
     "lodash.clone": {
@@ -12040,26 +12368,9 @@
       }
     },
     "node-releases": {
-      "version": "1.1.36",
-      "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.36.tgz",
-      "integrity": "sha512-ggXhX6QGyJSjj3r+6ml2LqqC28XOWmKtpb+a15/Zpr9V3yoNazxJNlcQDS9bYaid5FReEWHEgToH1mwoUceWwg==",
-      "dev": true,
-      "requires": {
-        "semver": "^6.3.0"
-      },
-      "dependencies": {
-        "semver": {
-          "version": "6.3.0",
-          "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
-          "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
-          "dev": true
-        }
-      }
-    },
-    "normalize-html-whitespace": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/normalize-html-whitespace/-/normalize-html-whitespace-1.0.0.tgz",
-      "integrity": "sha512-9ui7CGtOOlehQu0t/OhhlmDyc71mKVlv+4vF+me4iZLPrNtRL2xoquEdfZxasC/bdQi/Hr3iTrpyRKIG+ocabA==",
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.2.tgz",
+      "integrity": "sha512-XxYDdcQ6eKqp/YjI+tb2C5WM2LgjnZrfYg4vgQt49EK268b6gYCHsBLrK2qvJo4FmCtqmKezb0WZFK4fkrZNsg==",
       "dev": true
     },
     "normalize-path": {
@@ -12406,9 +12717,9 @@
       "dev": true
     },
     "path-parse": {
-      "version": "1.0.6",
-      "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
-      "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==",
+      "version": "1.0.7",
+      "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
+      "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
       "dev": true
     },
     "pbkdf2": {
@@ -12436,6 +12747,12 @@
       "integrity": "sha1-GN4vl+S/epVRrXURlCtUlverpmA=",
       "dev": true
     },
+    "picocolors": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
+      "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
+      "dev": true
+    },
     "picomatch": {
       "version": "2.2.2",
       "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz",
@@ -12455,37 +12772,40 @@
       "dev": true
     },
     "postcss": {
-      "version": "7.0.18",
-      "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.18.tgz",
-      "integrity": "sha512-/7g1QXXgegpF+9GJj4iN7ChGF40sYuGYJ8WZu8DZWnmhQ/G36hfdk3q9LBJmoK+lZ+yzZ5KYpOoxq7LF1BxE8g==",
+      "version": "7.0.39",
+      "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
+      "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
       "dev": true,
       "requires": {
-        "chalk": "^2.4.2",
-        "source-map": "^0.6.1",
-        "supports-color": "^6.1.0"
+        "picocolors": "^0.2.1",
+        "source-map": "^0.6.1"
       },
       "dependencies": {
-        "supports-color": {
-          "version": "6.1.0",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
-          "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
-          "dev": true,
-          "requires": {
-            "has-flag": "^3.0.0"
-          }
+        "picocolors": {
+          "version": "0.2.1",
+          "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
+          "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
+          "dev": true
         }
       }
     },
     "postcss-calc": {
-      "version": "7.0.1",
-      "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-7.0.1.tgz",
-      "integrity": "sha512-oXqx0m6tb4N3JGdmeMSc/i91KppbYsFZKdH0xMOqK8V1rJlzrKlTdokz8ozUXLVejydRN6u2IddxpcijRj2FqQ==",
+      "version": "7.0.5",
+      "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-7.0.5.tgz",
+      "integrity": "sha512-1tKHutbGtLtEZF6PT4JSihCHfIVldU72mZ8SdZHIYriIZ9fh9k9aWSppaT8rHsyI3dX+KSR+W+Ix9BMY3AODrg==",
       "dev": true,
       "requires": {
-        "css-unit-converter": "^1.1.1",
-        "postcss": "^7.0.5",
-        "postcss-selector-parser": "^5.0.0-rc.4",
-        "postcss-value-parser": "^3.3.1"
+        "postcss": "^7.0.27",
+        "postcss-selector-parser": "^6.0.2",
+        "postcss-value-parser": "^4.0.2"
+      },
+      "dependencies": {
+        "postcss-value-parser": {
+          "version": "4.2.0",
+          "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
+          "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==",
+          "dev": true
+        }
       }
     },
     "postcss-colormin": {
@@ -12574,12 +12894,12 @@
       },
       "dependencies": {
         "postcss-selector-parser": {
-          "version": "3.1.1",
-          "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.1.tgz",
-          "integrity": "sha1-T4dfSvsMllc9XPTXQBGu4lCn6GU=",
+          "version": "3.1.2",
+          "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz",
+          "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==",
           "dev": true,
           "requires": {
-            "dot-prop": "^4.1.1",
+            "dot-prop": "^5.2.0",
             "indexes-of": "^1.0.1",
             "uniq": "^1.0.1"
           }
@@ -12635,12 +12955,12 @@
       },
       "dependencies": {
         "postcss-selector-parser": {
-          "version": "3.1.1",
-          "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.1.tgz",
-          "integrity": "sha1-T4dfSvsMllc9XPTXQBGu4lCn6GU=",
+          "version": "3.1.2",
+          "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz",
+          "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==",
           "dev": true,
           "requires": {
-            "dot-prop": "^4.1.1",
+            "dot-prop": "^5.2.0",
             "indexes-of": "^1.0.1",
             "uniq": "^1.0.1"
           }
@@ -12873,31 +13193,29 @@
       }
     },
     "postcss-selector-parser": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz",
-      "integrity": "sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ==",
+      "version": "6.0.9",
+      "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.9.tgz",
+      "integrity": "sha512-UO3SgnZOVTwu4kyLR22UQ1xZh086RyNZppb7lLAKBFK8a32ttG5i87Y/P3+2bRSjZNyJ1B7hfFNo273tKe9YxQ==",
       "dev": true,
       "requires": {
-        "cssesc": "^2.0.0",
-        "indexes-of": "^1.0.1",
-        "uniq": "^1.0.1"
+        "cssesc": "^3.0.0",
+        "util-deprecate": "^1.0.2"
       },
       "dependencies": {
         "cssesc": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-2.0.0.tgz",
-          "integrity": "sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg==",
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
+          "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
           "dev": true
         }
       }
     },
     "postcss-svgo": {
-      "version": "4.0.2",
-      "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-4.0.2.tgz",
-      "integrity": "sha512-C6wyjo3VwFm0QgBy+Fu7gCYOkCmgmClghO+pjcxvrcBKtiKt0uCF+hvbMO1fyv5BMImRK90SMb+dwUnfbGd+jw==",
+      "version": "4.0.3",
+      "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-4.0.3.tgz",
+      "integrity": "sha512-NoRbrcMWTtUghzuKSoIm6XV+sJdvZ7GZSc3wdBN0W19FTtp2ko8NqLsgoh/m9CzNhU3KLPvQmjIwtaNFkaFTvw==",
       "dev": true,
       "requires": {
-        "is-svg": "^3.0.0",
         "postcss": "^7.0.0",
         "postcss-value-parser": "^3.0.0",
         "svgo": "^1.0.0"
@@ -12941,9 +13259,9 @@
       }
     },
     "posthtml-render": {
-      "version": "1.1.5",
-      "resolved": "https://registry.npmjs.org/posthtml-render/-/posthtml-render-1.1.5.tgz",
-      "integrity": "sha512-yvt54j0zCBHQVEFAuR+yHld8CZrCa/E1Z/OcFNCV1IEWTLVxT8O7nYnM4IIw1CD4r8kaRd3lc42+0lgCKgm87w==",
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/posthtml-render/-/posthtml-render-1.4.0.tgz",
+      "integrity": "sha512-W1779iVHGfq0Fvh2PROhCe2QhB8mEErgqzo1wpIt36tCgChafP+hbXIhLDOM8ePJrZcFs0vkNEtdibEWVqChqw==",
       "dev": true
     },
     "prelude-ls": {
@@ -13014,12 +13332,6 @@
           "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==",
           "dev": true
         },
-        "cssesc": {
-          "version": "3.0.0",
-          "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
-          "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
-          "dev": true
-        },
         "postcss": {
           "version": "7.0.32",
           "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.32.tgz",
@@ -13031,17 +13343,6 @@
             "supports-color": "^6.1.0"
           }
         },
-        "postcss-selector-parser": {
-          "version": "6.0.2",
-          "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.2.tgz",
-          "integrity": "sha512-36P2QR59jDTOAiIkqEprfJDsoNrvwFei3eCqKd1Y0tUsBimsq39BLp7RD+JWny3WgB1zGhJX8XVePwm9k4wdBg==",
-          "dev": true,
-          "requires": {
-            "cssesc": "^3.0.0",
-            "indexes-of": "^1.0.1",
-            "uniq": "^1.0.1"
-          }
-        },
         "supports-color": {
           "version": "6.1.0",
           "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
@@ -13214,6 +13515,12 @@
         }
       }
     },
+    "relateurl": {
+      "version": "0.2.7",
+      "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz",
+      "integrity": "sha1-VNvzd+UUQKypCkzSdGANP/LYiKk=",
+      "dev": true
+    },
     "remove-trailing-separator": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
@@ -13718,9 +14025,9 @@
       }
     },
     "source-map-support": {
-      "version": "0.5.13",
-      "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz",
-      "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==",
+      "version": "0.5.21",
+      "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
+      "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
       "dev": true,
       "requires": {
         "buffer-from": "^1.0.0",
@@ -13748,6 +14055,12 @@
       "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
       "dev": true
     },
+    "srcset": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/srcset/-/srcset-3.0.1.tgz",
+      "integrity": "sha512-MM8wDGg5BQJEj94tDrZDrX9wrC439/Eoeg3sgmVLPMjHgrAFeXAKk3tmFlCbKw5k+yOEhPXRpPlRcisQmqWVSQ==",
+      "dev": true
+    },
     "sshpk": {
       "version": "1.16.1",
       "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz",
@@ -13908,12 +14221,12 @@
       },
       "dependencies": {
         "postcss-selector-parser": {
-          "version": "3.1.1",
-          "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.1.tgz",
-          "integrity": "sha1-T4dfSvsMllc9XPTXQBGu4lCn6GU=",
+          "version": "3.1.2",
+          "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz",
+          "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==",
           "dev": true,
           "requires": {
-            "dot-prop": "^4.1.1",
+            "dot-prop": "^5.2.0",
             "indexes-of": "^1.0.1",
             "uniq": "^1.0.1"
           }
@@ -14343,9 +14656,9 @@
       "dev": true
     },
     "vendors": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.3.tgz",
-      "integrity": "sha512-fOi47nsJP5Wqefa43kyWSg80qF+Q3XA6MUkgi7Hp1HQaKDQW4cQrK2D0P7mmbFtsV1N89am55Yru/nyEwRubcw==",
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.4.tgz",
+      "integrity": "sha512-/juG65kTL4Cy2su4P8HjtkTxk6VmJDiOPBufWniqQ6wknac6jNiXS9vU+hO3wgusiyqWlzTbVHi0dyJqRONg3w==",
       "dev": true
     },
     "verror": {
@@ -14454,9 +14767,9 @@
       "dev": true
     },
     "ws": {
-      "version": "5.2.2",
-      "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.2.tgz",
-      "integrity": "sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA==",
+      "version": "5.2.3",
+      "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.3.tgz",
+      "integrity": "sha512-jZArVERrMsKUatIdnLzqvcfydI85dvd/Fp1u/VOpfdDWQ4c9qWXe+VIeAbQ5FrDwciAkr+lzofXLz3Kuf26AOA==",
       "dev": true,
       "requires": {
         "async-limiter": "~1.0.0"
diff --git a/scss/_django22.scss b/scss/_django22.scss
new file mode 100644
index 0000000..74cce45
--- /dev/null
+++ b/scss/_django22.scss
@@ -0,0 +1,9 @@
+/*
+Django 2.2 specific fixes
+ */
+#content {
+  // fix the filter bar on the right being layered over the header.
+  // header has z-index: 2 so within the stack context this layers on top now.
+  position: relative;
+  z-index: 1;
+}
diff --git a/scss/_vars.scss b/scss/_vars.scss
new file mode 100644
index 0000000..6459977
--- /dev/null
+++ b/scss/_vars.scss
@@ -0,0 +1,38 @@
+// Define SASS variables which emit the CSS variables from Django 3.2 with a default
+// value for Django 2.2. Once support is dropped for Django 2.2, we can remove the
+// defaults as Django itself defines these variables in `admin/css/base.css`.
+
+$color-primary: var(--primary, #79aec8);
+$color-secondary: var(--secondary, #417690);
+$color-primary-fg: var(--primary-fg, #fff);
+
+$color-header-link-color: var(--header-link-color, #{$color-primary-fg});
+
+/* admin-index specific variables */
+// default of 10px is the padding-bottom default of the header
+$djai-tablist-spacing-top: var(--djai-tablist-spacing-top, 10px);
+
+$djai-tab-bg: var(--djai-tab-bg, #4383a3);
+$djai-tab-bg--active: var(--djai-tab-bg--active, #{$color-primary});
+$djai-tab-bg--hover: var(--djai-tab-bg--hover, #{$color-primary});
+$djai-tab-fg: var(--djai-tab-fg, #{$color-primary-fg});
+$djai-tab-fg--active: var(--djai-tab-fg--active, #{$color-primary-fg});
+$djai-tab-fg--hover: var(--djai-tab-fg--hover, #{$color-primary-fg});
+
+$djai-dropdown-bg: var(--djai-dropdown-bg, #{$color-secondary});
+$djai-dropdown-bg--active: var(--djai-dropdown-bg--active, #{$color-primary});
+$djai-dropdown-bg--hover: var(--djai-dropdown-bg--hover, #{$color-primary});
+$djai-dropdown-fg: var(--djai-dropdown-fg, #{$color-header-link-color});
+
+// compensate for the sticky header by offsetting the nav sidebar. Default values
+// come from a clean django-startproject on Django 3.2 with the standard admin CSS.
+// If you use different fonts/paddings... etc, you can override this variable for your
+// own situation.
+$default-nav-sidebar-offset: 10px + 28px + 46px;  // heading padding top + branding height + dropdown-menu
+$djai-nav-sidebar-offset: var(--djai-nav-sidebar-offset, #{$default-nav-sidebar-offset});
+
+/*
+  Responsive styling. Breakpoints are taken from Django 3.2 admin/css/responsive.css
+*/
+$djai-breakpoint--mobile: 767px;
+$djai-breakpoint--tablet: 1024px;
diff --git a/scss/admin-index.scss b/scss/admin-index.scss
index 1b96d15..21b72f8 100644
--- a/scss/admin-index.scss
+++ b/scss/admin-index.scss
@@ -1,4 +1,5 @@
-@import "components/breadcrumbs";
-@import "components/dropdown-menu";
+@import "django22";
+
+@import "components/containers";
 @import "components/header";
-@import "components/main";
+@import "components/dropdown-menu";
diff --git a/scss/components/_breadcrumbs.scss b/scss/components/_breadcrumbs.scss
deleted file mode 100644
index 2148cdc..0000000
--- a/scss/components/_breadcrumbs.scss
+++ /dev/null
@@ -1,8 +0,0 @@
-.breadcrumbs {
-    /* Show the header at all times */
-    position: fixed;
-    top: 84px;
-    z-index: 4000;
-    width: 100%;
-    padding: 12px 40px !important;
-}
diff --git a/scss/components/_containers.scss b/scss/components/_containers.scss
new file mode 100644
index 0000000..d9fa172
--- /dev/null
+++ b/scss/components/_containers.scss
@@ -0,0 +1,26 @@
+/*
+Override some containers to make the sticky header work with Django.
+ */
+@import '../vars';
+
+#container {
+  // Django itself sets height: 100%, which causes the container to be less high than
+  // the content and that in turn causes the sticky header to fall off the page.
+  min-height: 100%;
+  height: auto;
+}
+
+#main {
+  // z-index is contextual, by specifying it explicitly here, we can have our header
+  // use z-index relative to this one without having to fiddle with #main child element
+  // z-indices.
+  z-index: 1;
+}
+
+#header {
+  z-index: 2; // overlay the #main container, which contains the sidebar on Django 3.2+
+}
+
+#nav-sidebar {
+  top: $djai-nav-sidebar-offset;
+}
diff --git a/scss/components/_dropdown-menu.scss b/scss/components/_dropdown-menu.scss
index 636b450..4f94e4d 100644
--- a/scss/components/_dropdown-menu.scss
+++ b/scss/components/_dropdown-menu.scss
@@ -1,63 +1,138 @@
-.dropdown-menu {
-    /* Show the header at all times */
-    position: fixed;
-    top: 42px;
-    display: block;
+/*
+The dropdown menu is injected as a child into the header, which has a flexbox display
+style (direction: row). This causes the menu to be on the same row as the branding and
+user tools. However, we set the flex-basis to 100% to make it take up the full width
+of the container and let the parent wrap.
+ */
+@import '../vars';
+
+$djai-block: 'djai-dropdown-menu';
+
+
+@mixin link-style() {
+  &, &:link, &:visited {
+    @content;
+  }
+}
+
+
+.#{$djai-block} {
+  // position it properly in the header as a separate row
+  @at-root #header {
+    flex-wrap: wrap;
+    // remove the padding at the bottom so our dropdown items line up
+    padding-bottom: 0;
+  }
+
+  flex-basis: 100%;
+
+  // own layout
+  display: block;
+  margin-top: $djai-tablist-spacing-top;
+
+  & &__item {
+    display: inline-block;
+    position: relative;
+    padding: 10px;
+    background-color: $djai-tab-bg;
     cursor: pointer;
-    margin-top: 8px;
-    z-index: 5000;
-
-    .dropdown-menu__item,
-    .dropdown-menu__item:link,
-    .dropdown-menu__item:visited {
-        color: #fff;
-        display: inline-block;
-        padding: 10px;
-        position: relative;
-        z-index: 50;
-        background-color: #4383a3;
-
-        &.dropdown-menu__item--active {
-            background-color: #79aec8;
-            text-decoration: none;
-        }
-
-        &:hover {
-            background-color: #79aec8;
-            text-decoration: none !important;
-
-            .dropdown-menu__drop {
-                display: block;
-            }
-        }
+
+    @include link-style {
+      color: $djai-tab-fg;
     }
 
-    .dropdown-menu__drop {
-        box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.2);
-        position: absolute;
-        left: 0;
-        top: 100%;
-        display: none;
-        background-color: #417690;
-        min-width: 150px;
-        z-index: 50;
+    &--active {
+      background-color: $djai-tab-bg--active;
+
+      @include link-style {
+        text-decoration: none;
+        color: $djai-tab-fg--active;
+      }
     }
 
-    .dropdown-menu__link,
-    .dropdown-menu__link:link,
-    .dropdown-menu__link:visited {
-        color: #fff;
+    // deliberately after the --active style so it overrides it
+    &:hover,
+    &:focus {
+      background-color: $djai-tab-bg--hover;
+
+      @include link-style {
+        text-decoration: none !important;
+        color: $djai-tab-fg--hover;
+      }
+
+      .#{$djai-block}__drop {
         display: block;
-        padding: 10px;
+      }
+    }
+  }
+
+  & &__drop {
+    display: none; // hidden by default, visible by hovering over the parent
+
+    // position it relative to the tab
+    position: absolute;
+    left: 0;
+    top: 100%;
+    min-width: 150px;
+    z-index: 1;
+
+    // ensure that very long lists have scrollable content
+    max-height: 75vh;
+    overflow-y: auto;
+
+    // theme
+    background-color: $djai-dropdown-bg;
+    box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2),
+                0 6px 20px 0 rgba(0, 0, 0, 0.2);
+  }
+
+  & &__drop-item {
+
+    background-color: transparent;  // take the bg color of the dropdown block
+
+    &--active {
+      background-color: $djai-dropdown-bg--active;
+    }
+
+    // deliberately after the --active style so it overrides it
+    &:hover,
+    &:focus {
+      background-color: $djai-dropdown-bg--hover;
+    }
+
+    // force a more specific rule so our own color overrides are used
+    @at-root #header & a {
+      @include link-style {
+        color: $djai-dropdown-fg;
+      }
+
+      &:hover {
+        text-decoration: none;
+      }
+    }
+  }
+
+  & &__link {
+    display: block;
+    padding: 10px;
+  }
+
+}
+
+// mobile styling
+@media (max-width: $djai-breakpoint--mobile) {
+  // ensure that the dropdown menus are on top of the breadcrumbs instead of hidden
+  // behind them. The #header element has z-index 2.
+  .breadcrumbs {
+    position: relative;
+    z-index: 1;
+  }
 
-        &:hover {
-            background-color: #79aec8;
-            text-decoration: none !important;
-        }
+  .#{$djai-block} {
+    align-self: flex-start;  // don't center, but align left
 
-        &.dropdown-menu__link--active {
-            background-color: #79aec8;
-            text-decoration: none;
-        }
+    & &__item {
+      margin-top: 3px;
     }
+  }
 }
diff --git a/scss/components/_header.scss b/scss/components/_header.scss
index 704db6b..e49d7d7 100644
--- a/scss/components/_header.scss
+++ b/scss/components/_header.scss
@@ -1,14 +1,22 @@
+/*
+The header is the container for our admin-index menu dropdown, which we make
+visible at all times. For this, the header itself needs to receive a position fixes or
+sticky so that it stays in view when scrolling down vertically.
+
+If the header itself is sticky and the container for the dropdowns, we don't need to
+mess with height offsets relative to the header/branding - which may not be pixel-
+perfect because of font-rendering shenanigans.
+
+We also stick to Django's flexbox model for the header and don't force it into a CSS
+grid layout. (TODO: check on 2.2 what the CSS looks like).
+
+TODO: future enhancement -> control position of header/admin menu via CSS var, so users
+have the option to easily specify static/sticky positioning.
+ */
+
 #header {
-    display: grid;
-    grid-template-columns: 2fr 2fr;
-    grid-template-rows: 1fr 1fr;
-    grid-gap: 10px;
-    z-index: 5000;
-    position: fixed;
-
-    width: calc(100% - 50px);
-
-    @media (max-width: 768px) {
-        width: calc(100% - 20px);
-    }
+  position: sticky;
+  top: 0;
+  // the dropdown menu is a child and overflows
+  overflow: visible;
 }
diff --git a/scss/components/_main.scss b/scss/components/_main.scss
deleted file mode 100644
index 70ba540..0000000
--- a/scss/components/_main.scss
+++ /dev/null
@@ -1,36 +0,0 @@
-#main,
-#content // < Django 3.2
-{
-    padding-top: 104px;
-
-    #nav-sidebar {
-        position: initial;
-    }
-}
-
-.content // > Django 3.2
-{
-    #content {
-        padding-top: 0;
-    }
-}
-
-body[class*="change-"] {
-    #main,
-    #content // < Django 3.2
-    {
-        padding-top: 144px;
-
-        #nav-sidebar {
-            position: initial;
-        }
-    }
-
-    .content // > Django 3.2
-    {
-        #content {
-            padding-top: 0;
-        }
-    }
-}
-
diff --git a/setup.cfg b/setup.cfg
index 01fa3e5..1ee316c 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -22,6 +22,15 @@ ignore =
     docs/_build*
 
 [isort]
-line_length=119
-known_third_party=django
+combine_as_imports = true
+default_section = THIRDPARTY
+include_trailing_comma = true
+line_length = 88
+multi_line_output = 3
+force_grid_wrap = 0
+use_parentheses = True
+ensure_newline_before_comments = True
+skip = env,.tox,.history,.eggs
+known_django=django
 known_first_party=django_admin_index
+sections=FUTURE,STDLIB,DJANGO,THIRDPARTY,FIRSTPARTY,LOCALFOLDER
diff --git a/tox.ini b/tox.ini
index 443a3b8..a3e80e1 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,7 +1,7 @@
 [tox]
 envlist =
-  py{37,38}-django22,
-  py{37,38,310}-django{30,32,40},
+  py{37,38,39}-django22,
+  py{38,39,310}-django{32,40},
   isort,
   black
 skip_missing_interpreters = true
@@ -12,10 +12,9 @@ deps =
   -r{toxinidir}/requirements/test.txt
   -r{toxinidir}/requirements/test-ci.txt
 
-  django22: Django>=2.2,<3.0
-  django30: Django>=3.0,<3.1
-  django32: Django>=3.2,<3.3
-  django40: Django>=4.0
+  django22: Django~=2.2
+  django32: Django~=3.2
+  django40: Django~=4.0
 commands =
     py.test -xv --cov=django_admin_index --cov-report=term --cov-report=xml --no-cov-on-fail []
 


Test patch:
diff --git a/tests/proj/settings.py b/tests/proj/settings.py
index b2043e0..5eed9c7 100644
--- a/tests/proj/settings.py
+++ b/tests/proj/settings.py
@@ -9,8 +9,6 @@
 For the full list of settings and their values, see
 https://docs.djangoproject.com/en/1.9/ref/settings/
 """
-from __future__ import absolute_import, unicode_literals
-
 import os
 import sys
 
@@ -28,7 +26,7 @@
 # SECURITY WARNING: don't run with debug turned on in production!
 DEBUG = True
 
-ALLOWED_HOSTS = []
+ALLOWED_HOSTS = ["*"]
 
 
 # Application definition
@@ -53,9 +51,6 @@
     "django.contrib.messages.middleware.MessageMiddleware",
     "django.middleware.clickjacking.XFrameOptionsMiddleware",
 ]
-# For Django 1.9 and older, MIDDLEWARE_CLASSES is used instead of MIDDLEWARE
-# See: https://docs.djangoproject.com/en/1.10/ref/settings/#std:setting-MIDDLEWARE_CLASSES
-MIDDLEWARE_CLASSES = MIDDLEWARE
 
 ROOT_URLCONF = "tests.proj.urls"
 
@@ -139,3 +134,13 @@
 # https://docs.djangoproject.com/en/1.9/howto/static-files/
 
 STATIC_URL = "/static/"
+
+try:
+    import debug_toolbar  # noqa
+except ImportError:
+    pass
+else:
+    INSTALLED_APPS += ["debug_toolbar"]
+    MIDDLEWARE.insert(0, "debug_toolbar.middleware.DebugToolbarMiddleware")
+
+    INTERNAL_IPS = ["127.0.0.1"]
diff --git a/tests/proj/urls.py b/tests/proj/urls.py
index 9ade9b5..6df85be 100644
--- a/tests/proj/urls.py
+++ b/tests/proj/urls.py
@@ -1,8 +1,12 @@
-from __future__ import absolute_import, unicode_literals
-
+from django.apps import apps
 from django.contrib import admin
-from django.urls import re_path
+from django.urls import include, path
 
 urlpatterns = [
-    re_path(r"^admin/", admin.site.urls),
+    path("admin/", admin.site.urls),
 ]
+
+if apps.is_installed("debug_toolbar"):
+    urlpatterns += [
+        path("__debug__/", include("debug_toolbar.urls")),
+    ]