diff --git a/_includes/components/aux_nav.html b/_includes/components/aux_nav.html
new file mode 100644
index 0000000000000000000000000000000000000000..f327da689b779fbc398cb22c79e8f74f8f036d87
--- /dev/null
+++ b/_includes/components/aux_nav.html
@@ -0,0 +1,15 @@
+<nav aria-label="Auxiliary" class="aux-nav">
+  <ul class="aux-nav-list">
+    {% for link in site.aux_links %}
+      <li class="aux-nav-list-item">
+        <a href="{{ link.last }}" class="site-button"
+          {% if site.aux_links_new_tab %}
+          target="_blank" rel="noopener noreferrer"
+          {% endif %}
+        >
+          {{ link.first }}
+        </a>
+      </li>
+    {% endfor %}
+  </ul>
+</nav>
diff --git a/_includes/components/breadcrumbs.html b/_includes/components/breadcrumbs.html
new file mode 100644
index 0000000000000000000000000000000000000000..f1bc4885ca85678f0e3ea58eca9b5784caf77e70
--- /dev/null
+++ b/_includes/components/breadcrumbs.html
@@ -0,0 +1,15 @@
+{% unless page.url == "/" %}
+  {% if page.parent %}
+    <nav aria-label="Breadcrumb" class="breadcrumb-nav">
+      <ol class="breadcrumb-nav-list">
+        {% if page.grand_parent %}
+          <li class="breadcrumb-nav-list-item"><a href="{{ first_level_url }}">{{ page.grand_parent }}</a></li>
+          <li class="breadcrumb-nav-list-item"><a href="{{ second_level_url }}">{{ page.parent }}</a></li>
+        {% else %}
+          <li class="breadcrumb-nav-list-item"><a href="{{ first_level_url }}">{{ page.parent }}</a></li>
+        {% endif %}
+        <li class="breadcrumb-nav-list-item"><span>{{ page.title }}</span></li>
+      </ol>
+    </nav>
+  {% endif %}
+{% endunless %}
diff --git a/_includes/components/children_nav.html b/_includes/components/children_nav.html
new file mode 100644
index 0000000000000000000000000000000000000000..e76f98d19914664a3ea02d9d87403b1d792f7272
--- /dev/null
+++ b/_includes/components/children_nav.html
@@ -0,0 +1,9 @@
+<hr>
+{% include toc_heading_custom.html %}
+<ul>
+  {% for child in include.toc_list %}
+    <li>
+      <a href="{{ child.url | relative_url }}">{{ child.title }}</a>{% if child.summary %} - {{ child.summary }}{% endif %}
+    </li>
+  {% endfor %}
+</ul>
diff --git a/_includes/components/footer.html b/_includes/components/footer.html
new file mode 100644
index 0000000000000000000000000000000000000000..01b2c235d0c86b83fa87bbc1debc6db686539ce8
--- /dev/null
+++ b/_includes/components/footer.html
@@ -0,0 +1,34 @@
+{% capture footer_custom %}
+  {%- include footer_custom.html -%}
+{% endcapture %}
+{% if footer_custom != "" or site.last_edit_timestamp or site.gh_edit_link %}
+  <hr>
+  <footer>
+    {% if site.back_to_top %}
+      <p><a href="#top" id="back-to-top">{{ site.back_to_top_text }}</a></p>
+    {% endif %}
+
+    {{ footer_custom }}
+
+    {% if site.last_edit_timestamp or site.gh_edit_link %}
+      <div class="d-flex mt-2">
+        {% if site.last_edit_timestamp and site.last_edit_time_format and page.last_modified_date %}
+          <p class="text-small text-grey-dk-000 mb-0 mr-2">
+            Page last modified: <span class="d-inline-block">{{ page.last_modified_date | date: site.last_edit_time_format }}</span>.
+          </p>
+        {% endif %}
+        {% if
+          site.gh_edit_link and
+          site.gh_edit_link_text and
+          site.gh_edit_repository and
+          site.gh_edit_branch and
+          site.gh_edit_view_mode
+        %}
+          <p class="text-small text-grey-dk-000 mb-0">
+            <a href="{{ site.gh_edit_repository }}/{{ site.gh_edit_view_mode }}/{{ site.gh_edit_branch }}{% if site.gh_edit_source %}/{{ site.gh_edit_source }}{% endif %}{% if page.collection and site.collections_dir %}/{{ site.collections_dir }}{% endif %}/{{ page.path }}" id="edit-this-page">{{ site.gh_edit_link_text }}</a>
+          </p>
+        {% endif %}
+      </div>
+    {% endif %}
+  </footer>
+{% endif %}
diff --git a/_includes/components/header.html b/_includes/components/header.html
new file mode 100644
index 0000000000000000000000000000000000000000..f9c3386b1e25d71e335b7ad73b349f5f663de9a0
--- /dev/null
+++ b/_includes/components/header.html
@@ -0,0 +1,11 @@
+<div id="main-header" class="main-header">
+  {% if site.search_enabled != false %}
+    {% include components/search_header.html %}
+  {% else %}
+    <div></div>
+  {% endif %}
+  {% include header_custom.html %}
+  {% if site.aux_links %}
+    {% include components/aux_nav.html %}
+  {% endif %}
+</div>
diff --git a/_includes/components/mermaid.html b/_includes/components/mermaid.html
new file mode 100644
index 0000000000000000000000000000000000000000..d6923e090ee98ecef552d3188ed4f779cbd4a4c8
--- /dev/null
+++ b/_includes/components/mermaid.html
@@ -0,0 +1,5 @@
+<script>
+  var config = {% include mermaid_config.js %};
+  mermaid.initialize(config);
+  window.mermaid.init(undefined, document.querySelectorAll('.language-mermaid'));
+</script>
diff --git a/_includes/components/search_footer.html b/_includes/components/search_footer.html
new file mode 100644
index 0000000000000000000000000000000000000000..fb4fe51b4bb662fcf2a94e4fdffa2ae2e35c5368
--- /dev/null
+++ b/_includes/components/search_footer.html
@@ -0,0 +1,7 @@
+{% if site.search.button %}
+<a href="#" id="search-button" class="search-button">
+  <svg viewBox="0 0 24 24" class="icon"><use xlink:href="#svg-search"></use></svg>
+</a>
+{% endif %}
+
+<div class="search-overlay"></div>
diff --git a/_includes/components/search_header.html b/_includes/components/search_header.html
new file mode 100644
index 0000000000000000000000000000000000000000..98425d5bd20ec135551657f6d8a7a26af7bf9bed
--- /dev/null
+++ b/_includes/components/search_header.html
@@ -0,0 +1,9 @@
+{% capture search_placeholder %}{% include search_placeholder_custom.html %}{% endcapture %}
+
+<div class="search">
+  <div class="search-input-wrap">
+    <input type="text" id="search-input" class="search-input" tabindex="0" placeholder="{{ search_placeholder | strip_html | strip }}" aria-label="{{ search_placeholder | strip_html| strip }}" autocomplete="off">
+    <label for="search-input" class="search-label"><svg viewBox="0 0 24 24" class="search-icon"><use xlink:href="#svg-search"></use></svg></label>
+  </div>
+  <div id="search-results" class="search-results"></div>
+</div>
diff --git a/_includes/components/sidebar.html b/_includes/components/sidebar.html
new file mode 100644
index 0000000000000000000000000000000000000000..c9c1bb8f78e63ad91a6803b9f08246a4d2da12a1
--- /dev/null
+++ b/_includes/components/sidebar.html
@@ -0,0 +1,69 @@
+<div class="side-bar">
+  <div class="site-header">
+    <a href="{{ '/' | relative_url }}" class="site-title lh-tight">{% include title.html %}</a>
+    <a href="#" id="menu-button" class="site-button">
+      <svg viewBox="0 0 24 24" class="icon"><use xlink:href="#svg-menu"></use></svg>
+    </a>
+  </div>
+  <nav aria-label="Main" id="site-nav" class="site-nav">
+    {% assign pages_top_size = site.html_pages
+        | where_exp:"item", "item.title != nil"
+        | where_exp:"item", "item.parent == nil"
+        | where_exp:"item", "item.nav_exclude != true"
+        | size %}
+    {% if pages_top_size > 0 %}
+      {% include nav.html pages=site.html_pages key=nil %}
+    {% endif %}
+    {%- if site.nav_external_links -%}
+      <ul class="nav-list">
+        {%- for node in site.nav_external_links -%}
+          <li class="nav-list-item external">
+            <a href="{{ node.url | absolute_url }}" class="nav-list-link external">
+              {{ node.title }}
+              {% unless node.hide_icon %}<svg viewBox="0 0 24 24" aria-labelledby="svg-external-link-title"><use xlink:href="#svg-external-link"></use></svg>{% endunless %}
+            </a>
+          </li>
+        {%- endfor -%}
+      </ul>
+    {%- endif -%}
+    {% if site.just_the_docs.collections %}
+      {% assign collections_size = site.just_the_docs.collections | size %}
+      {% for collection_entry in site.just_the_docs.collections %}
+        {% assign collection_key = collection_entry[0] %}
+        {% assign collection_value = collection_entry[1] %}
+        {% assign collection = site[collection_key] %}
+        {% if collection_value.nav_exclude != true %}
+          {% if collections_size > 1 or pages_top_size > 0 %}
+            {% if collection_value.nav_fold == true %}
+              <ul class="nav-list nav-category-list">
+                <li class="nav-list-item{% if page.collection == collection_key %} active{% endif %}">
+                  {%- if collection.size > 0 -%}
+                  <a href="#" class="nav-list-expander"><svg viewBox="0 0 24 24"><use xlink:href="#svg-arrow-right"></use></svg></a>
+                  {%- endif -%}
+                  <div class="nav-category">{{ collection_value.name }}</div>
+                  {% include nav.html pages=collection key=collection_key %}
+                </li>
+              </ul>
+            {% else %}
+              <div class="nav-category">{{ collection_value.name }}</div>
+              {% include nav.html pages=collection key=collection_key %}
+            {% endif %}
+          {% else %}
+            {% include nav.html pages=collection key=collection_key %}
+          {% endif %}
+        {% endif %}
+      {% endfor %}
+    {% endif %}
+  </nav>
+
+  {% capture nav_footer_custom %}
+    {%- include nav_footer_custom.html -%}
+  {% endcapture %}
+  {% if nav_footer_custom != "" %}
+    {{ nav_footer_custom }}
+  {% else %}
+    <footer class="site-footer">
+      This site uses <a href="https://github.com/just-the-docs/just-the-docs">Just the Docs</a>, a documentation theme for Jekyll.
+    </footer>
+  {% endif %}
+</div>
diff --git a/_includes/icons/code_copy.html b/_includes/icons/code_copy.html
index 02f5068c0f171a904b72f92ad63e811b83fb725a..0538a232abfde1f65f62c31ab5de6147afffdfdb 100644
--- a/_includes/icons/code_copy.html
+++ b/_includes/icons/code_copy.html
@@ -12,4 +12,4 @@
     <path d="M6.5 0A1.5 1.5 0 0 0 5 1.5v1A1.5 1.5 0 0 0 6.5 4h3A1.5 1.5 0 0 0 11 2.5v-1A1.5 1.5 0 0 0 9.5 0h-3Zm3 1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-3a.5.5 0 0 1-.5-.5v-1a.5.5 0 0 1 .5-.5h3Z"/>
     <path d="M4 1.5H3a2 2 0 0 0-2 2V14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V3.5a2 2 0 0 0-2-2h-1v1A2.5 2.5 0 0 1 9.5 5h-3A2.5 2.5 0 0 1 4 2.5v-1Zm6.854 7.354-3 3a.5.5 0 0 1-.708 0l-1.5-1.5a.5.5 0 0 1 .708-.708L7.5 10.793l2.646-2.647a.5.5 0 0 1 .708.708Z"/>
   </svg>
-</symbol>
\ No newline at end of file
+</symbol>
diff --git a/_includes/icons/document.html b/_includes/icons/document.html
new file mode 100644
index 0000000000000000000000000000000000000000..c09e8a5c8c4e36ae611d839f5fe65f4685ae9c19
--- /dev/null
+++ b/_includes/icons/document.html
@@ -0,0 +1,6 @@
+<symbol id="svg-doc" viewBox="0 0 24 24">
+  <title>Document</title>
+  <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-file">
+    <path d="M13 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V9z"></path><polyline points="13 2 13 9 20 9"></polyline>
+  </svg>
+</symbol>
diff --git a/_includes/icons/expand.html b/_includes/icons/expand.html
new file mode 100644
index 0000000000000000000000000000000000000000..79921a560f03b9007408281fe73eecd70c2cd6b7
--- /dev/null
+++ b/_includes/icons/expand.html
@@ -0,0 +1,6 @@
+<symbol id="svg-arrow-right" viewBox="0 0 24 24">
+  <title>Expand</title>
+  <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-chevron-right">
+    <polyline points="9 18 15 12 9 6"></polyline>
+  </svg>
+</symbol>
diff --git a/_includes/icons/icons.html b/_includes/icons/icons.html
new file mode 100644
index 0000000000000000000000000000000000000000..007a495b00ab19d9f799e4133860f5480b638555
--- /dev/null
+++ b/_includes/icons/icons.html
@@ -0,0 +1,13 @@
+<svg xmlns="http://www.w3.org/2000/svg" class="d-none">
+  {% include icons/link.html %}
+  {% include icons/menu.html %}
+  {% include icons/expand.html %}
+  {% include icons/external_link.html %}
+  {% if site.search_enabled != false %}
+    {% include icons/document.html %}
+    {% include icons/search.html %}
+  {% endif %}
+  {% if site.enable_copy_code_button != false %}
+    {% include icons/code_copy.html %}
+  {% endif %}
+</svg>
diff --git a/_includes/icons/link.html b/_includes/icons/link.html
new file mode 100644
index 0000000000000000000000000000000000000000..de24be707a9b7921ee247e16c3a42d2efba33e7b
--- /dev/null
+++ b/_includes/icons/link.html
@@ -0,0 +1,6 @@
+<symbol id="svg-link" viewBox="0 0 24 24">
+  <title>Link</title>
+  <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-link">
+    <path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path>
+  </svg>
+</symbol>
diff --git a/_includes/icons/menu.html b/_includes/icons/menu.html
new file mode 100644
index 0000000000000000000000000000000000000000..d2565758f3cc791fc2c914e19773e878c7512419
--- /dev/null
+++ b/_includes/icons/menu.html
@@ -0,0 +1,6 @@
+<symbol id="svg-menu" viewBox="0 0 24 24">
+  <title>Menu</title>
+  <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-menu">
+    <line x1="3" y1="12" x2="21" y2="12"></line><line x1="3" y1="6" x2="21" y2="6"></line><line x1="3" y1="18" x2="21" y2="18"></line>
+  </svg>
+</symbol>
diff --git a/_includes/icons/search.html b/_includes/icons/search.html
new file mode 100644
index 0000000000000000000000000000000000000000..8f72c6a2acae98e320b734f801053c34006a9a95
--- /dev/null
+++ b/_includes/icons/search.html
@@ -0,0 +1,6 @@
+<symbol id="svg-search" viewBox="0 0 24 24">
+  <title>Search</title>
+  <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-search">
+    <circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line>
+  </svg>
+</symbol>
diff --git a/_layouts/default.html b/_layouts/default.html
index 61ebc06f8651194afe850dbe35153091d133889e..3bc0e0ae03a0b7aa9c23a39ba9b5522c10c39a7d 100644
--- a/_layouts/default.html
+++ b/_layouts/default.html
@@ -8,161 +8,12 @@ layout: table_wrappers
 {% include head.html %}
 <body>
   <a class="skip-to-main" href="#main-content">Skip to main content</a>
-  <svg xmlns="http://www.w3.org/2000/svg" class="d-none" >
-    <symbol id="svg-link" viewBox="0 0 24 24">
-      <title>Link</title>
-      <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-link">
-        <path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path>
-      </svg>
-    </symbol>
-    <symbol id="svg-search" viewBox="0 0 24 24">
-      <title>Search</title>
-      <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-search">
-        <circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line>
-      </svg>
-    </symbol>
-    <symbol id="svg-menu" viewBox="0 0 24 24">
-      <title>Menu</title>
-      <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-menu">
-        <line x1="3" y1="12" x2="21" y2="12"></line><line x1="3" y1="6" x2="21" y2="6"></line><line x1="3" y1="18" x2="21" y2="18"></line>
-      </svg>
-    </symbol>
-    <symbol id="svg-arrow-right" viewBox="0 0 24 24">
-      <title>Expand</title>
-      <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-chevron-right">
-        <polyline points="9 18 15 12 9 6"></polyline>
-      </svg>
-    </symbol>
-    <symbol id="svg-doc" viewBox="0 0 24 24">
-      <title>Document</title>
-      <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-file">
-        <path d="M13 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V9z"></path><polyline points="13 2 13 9 20 9"></polyline>
-      </svg>
-    </symbol>
-    {% include icons/external_link.html %}
-    {% include icons/code_copy.html %}
-  </svg>
-
-  <div class="side-bar">
-    <div class="site-header">
-      <a href="{{ '/' | relative_url }}" class="site-title lh-tight">{% include title.html %}</a>
-      <a href="#" id="menu-button" class="site-button">
-        <svg viewBox="0 0 24 24" class="icon"><use xlink:href="#svg-menu"></use></svg>
-      </a>
-    </div>
-    <nav aria-label="Main" id="site-nav" class="site-nav">
-      {% assign pages_top_size = site.html_pages
-          | where_exp:"item", "item.title != nil"
-          | where_exp:"item", "item.parent == nil"
-          | where_exp:"item", "item.nav_exclude != true"
-          | size %}
-      {% if pages_top_size > 0 %}
-        {% include nav.html pages=site.html_pages key=nil %}
-      {% endif %}
-      {%- if site.nav_external_links -%}
-        <ul class="nav-list">
-          {%- for node in site.nav_external_links -%}
-            <li class="nav-list-item external">
-              <a href="{{ node.url | absolute_url }}" class="nav-list-link external">
-                {{ node.title }}
-                {% unless node.hide_icon %}<svg viewBox="0 0 24 24" aria-labelledby="svg-external-link-title"><use xlink:href="#svg-external-link"></use></svg>{% endunless %}
-              </a>
-            </li>
-          {%- endfor -%}
-        </ul>
-      {%- endif -%}
-      {% if site.just_the_docs.collections %}
-        {% assign collections_size = site.just_the_docs.collections | size %}
-        {% for collection_entry in site.just_the_docs.collections %}
-          {% assign collection_key = collection_entry[0] %}
-          {% assign collection_value = collection_entry[1] %}
-          {% assign collection = site[collection_key] %}
-          {% if collection_value.nav_exclude != true %}
-            {% if collections_size > 1 or pages_top_size > 0 %}
-              {% if collection_value.nav_fold == true %}
-                <ul class="nav-list nav-category-list">
-                  <li class="nav-list-item{% if page.collection == collection_key %} active{% endif %}">
-                    {%- if collection.size > 0 -%}
-                    <a href="#" class="nav-list-expander"><svg viewBox="0 0 24 24"><use xlink:href="#svg-arrow-right"></use></svg></a>
-                    {%- endif -%}
-                    <div class="nav-category">{{ collection_value.name }}</div>
-                    {% include nav.html pages=collection key=collection_key %}
-                  </li>
-                </ul>
-              {% else %}
-                <div class="nav-category">{{ collection_value.name }}</div>
-                {% include nav.html pages=collection key=collection_key %}
-              {% endif %}
-            {% else %}
-              {% include nav.html pages=collection key=collection_key %}
-            {% endif %}
-          {% endif %}
-        {% endfor %}
-      {% endif %}
-    </nav>
-
-    {% capture nav_footer_custom %}
-      {%- include nav_footer_custom.html -%}
-    {% endcapture %}
-    {% if nav_footer_custom != "" %}
-      {{ nav_footer_custom }}
-    {% else %}
-      <footer class="site-footer">
-        This site uses <a href="https://github.com/just-the-docs/just-the-docs">Just the Docs</a>, a documentation theme for Jekyll.
-      </footer>
-    {% endif %}
-  </div>
+  {% include icons/icons.html %}
+  {% include components/sidebar.html %}
   <div class="main" id="top">
-    <div id="main-header" class="main-header">
-      {% if site.search_enabled != false %}
-
-        {% capture search_placeholder %}{% include search_placeholder_custom.html %}{% endcapture %}
-
-        <div class="search">
-          <div class="search-input-wrap">
-            <input type="text" id="search-input" class="search-input" tabindex="0" placeholder="{{ search_placeholder | strip_html | strip }}" aria-label="{{ search_placeholder | strip_html| strip }}" autocomplete="off">
-            <label for="search-input" class="search-label"><svg viewBox="0 0 24 24" class="search-icon"><use xlink:href="#svg-search"></use></svg></label>
-          </div>
-          <div id="search-results" class="search-results"></div>
-        </div>
-      {% else %}
-        <div></div>
-      {% endif %}
-      {% include header_custom.html %}
-      {% if site.aux_links %}
-        <nav aria-label="Auxiliary" class="aux-nav">
-          <ul class="aux-nav-list">
-            {% for link in site.aux_links %}
-              <li class="aux-nav-list-item">
-                <a href="{{ link.last }}" class="site-button"
-                  {% if site.aux_links_new_tab %}
-                  target="_blank" rel="noopener noreferrer"
-                  {% endif %}
-                >
-                  {{ link.first }}
-                </a>
-              </li>
-            {% endfor %}
-          </ul>
-        </nav>
-      {% endif %}
-    </div>
+    {% include components/header.html %}
     <div id="main-content-wrap" class="main-content-wrap">
-      {% unless page.url == "/" %}
-        {% if page.parent %}
-          <nav aria-label="Breadcrumb" class="breadcrumb-nav">
-            <ol class="breadcrumb-nav-list">
-              {% if page.grand_parent %}
-                <li class="breadcrumb-nav-list-item"><a href="{{ first_level_url }}">{{ page.grand_parent }}</a></li>
-                <li class="breadcrumb-nav-list-item"><a href="{{ second_level_url }}">{{ page.parent }}</a></li>
-              {% else %}
-                <li class="breadcrumb-nav-list-item"><a href="{{ first_level_url }}">{{ page.parent }}</a></li>
-              {% endif %}
-              <li class="breadcrumb-nav-list-item"><span>{{ page.title }}</span></li>
-            </ol>
-          </nav>
-        {% endif %}
-      {% endunless %}
+      {% include components/breadcrumbs.html %}
       <div id="main-content" class="main-content" role="main">
         {% if site.heading_anchors != false %}
           {% include vendor/anchor_headings.html html=content beforeHeading="true" anchorBody="<svg viewBox=\"0 0 16 16\" aria-hidden=\"true\"><use xlink:href=\"#svg-link\"></use></svg>" anchorClass="anchor-heading" anchorAttrs="aria-labelledby=\"%html_id%\"" %}
@@ -171,72 +22,20 @@ layout: table_wrappers
         {% endif %}
 
         {% if page.has_children == true and page.has_toc != false %}
-          <hr>
-          {% include toc_heading_custom.html %}
-          <ul>
-            {% for child in toc_list %}
-              <li>
-                <a href="{{ child.url | relative_url }}">{{ child.title }}</a>{% if child.summary %} - {{ child.summary }}{% endif %}
-              </li>
-            {% endfor %}
-          </ul>
+          {% include components/children_nav.html toc_list=toc_list %}
         {% endif %}
 
-        {% capture footer_custom %}
-          {%- include footer_custom.html -%}
-        {% endcapture %}
-        {% if footer_custom != "" or site.last_edit_timestamp or site.gh_edit_link %}
-          <hr>
-          <footer>
-            {% if site.back_to_top %}
-              <p><a href="#top" id="back-to-top">{{ site.back_to_top_text }}</a></p>
-            {% endif %}
-
-            {{ footer_custom }}
-
-            {% if site.last_edit_timestamp or site.gh_edit_link %}
-              <div class="d-flex mt-2">
-                {% if site.last_edit_timestamp and site.last_edit_time_format and page.last_modified_date %}
-                  <p class="text-small text-grey-dk-000 mb-0 mr-2">
-                    Page last modified: <span class="d-inline-block">{{ page.last_modified_date | date: site.last_edit_time_format }}</span>.
-                  </p>
-                {% endif %}
-                {% if
-                  site.gh_edit_link and
-                  site.gh_edit_link_text and
-                  site.gh_edit_repository and
-                  site.gh_edit_branch and
-                  site.gh_edit_view_mode
-                %}
-                  <p class="text-small text-grey-dk-000 mb-0">
-                    <a href="{{ site.gh_edit_repository }}/{{ site.gh_edit_view_mode }}/{{ site.gh_edit_branch }}{% if site.gh_edit_source %}/{{ site.gh_edit_source }}{% endif %}{% if page.collection and site.collections_dir %}/{{ site.collections_dir }}{% endif %}/{{ page.path }}" id="edit-this-page">{{ site.gh_edit_link_text }}</a>
-                  </p>
-                {% endif %}
-              </div>
-            {% endif %}
-          </footer>
-        {% endif %}
+        {% include components/footer.html %}
 
       </div>
     </div>
-
     {% if site.search_enabled != false %}
-      {% if site.search.button %}
-        <a href="#" id="search-button" class="search-button">
-          <svg viewBox="0 0 24 24" class="icon"><use xlink:href="#svg-search"></use></svg>
-        </a>
-      {% endif %}
-
-      <div class="search-overlay"></div>
+      {% include components/search_footer.html %}
     {% endif %}
   </div>
 
   {% if site.mermaid %}
-  <script>
-    var config = {% include mermaid_config.js %};
-    mermaid.initialize(config);
-    window.mermaid.init(undefined, document.querySelectorAll('.language-mermaid'));
-  </script>
+    {% include components/mermaid.html %}
   {% endif %}
 </body>
 </html>
diff --git a/_layouts/minimal.html b/_layouts/minimal.html
new file mode 100644
index 0000000000000000000000000000000000000000..5cbac78142d38967637b92253cf9d45ac5e1277e
--- /dev/null
+++ b/_layouts/minimal.html
@@ -0,0 +1,60 @@
+---
+layout: table_wrappers
+---
+
+<!DOCTYPE html>
+
+<html lang="{{ site.lang | default: 'en-US' }}">
+{% include head.html %}
+<body>
+  <a class="skip-to-main" href="#main-content">Skip to main content</a>
+  {% include icons/icons.html %}
+  {% comment %}
+    This is a bandaid fix to properly render breadcrumbs; as of now, there is some variable leakage between the sidebar component (which computes parents, grandparents) and the breadcrumbs component. We plan to remove this in a future release to deduplicate code.
+
+    For more context, see https://github.com/just-the-docs/just-the-docs/pull/1058#discussion_r1057014053
+  {% endcomment %}
+  {% capture nav %}
+    {% assign pages_top_size = site.html_pages
+        | where_exp:"item", "item.title != nil"
+        | where_exp:"item", "item.parent == nil"
+        | where_exp:"item", "item.nav_exclude != true"
+        | size %}
+    {% if pages_top_size > 0 %}
+      {% include nav.html pages=site.html_pages key=nil %}
+    {% endif %}
+    {% if site.just_the_docs.collections %}
+      {% assign collections_size = site.just_the_docs.collections | size %}
+      {% for collection_entry in site.just_the_docs.collections %}
+        {% assign collection_key = collection_entry[0] %}
+        {% assign collection_value = collection_entry[1] %}
+        {% assign collection = site[collection_key] %}
+        {% if collection_value.nav_exclude != true %}
+          {% include nav.html pages=collection key=collection_key %}
+        {% endif %}
+      {% endfor %}
+    {% endif %}
+  {% endcapture %}
+  <div id="main-content-wrap" class="main-content-wrap" id="top">
+    {% include components/breadcrumbs.html %}
+    <div id="main-content" class="main-content" role="main">
+      {% if site.heading_anchors != false %}
+        {% include vendor/anchor_headings.html html=content beforeHeading="true" anchorBody="<svg viewBox=\"0 0 16 16\" aria-hidden=\"true\"><use xlink:href=\"#svg-link\"></use></svg>" anchorClass="anchor-heading" anchorAttrs="aria-labelledby=\"%html_id%\"" %}
+      {% else %}
+        {{ content }}
+      {% endif %}
+
+      {% if page.has_children == true and page.has_toc != false %}
+        {% include components/children_nav.html toc_list=toc_list %}
+      {% endif %}
+
+      {% include components/footer.html %}
+
+    </div>
+  </div>
+
+  {% if site.mermaid %}
+    {% include components/mermaid.html %}
+  {% endif %}
+</body>
+</html>
diff --git a/assets/js/just-the-docs.js b/assets/js/just-the-docs.js
index 8aabf325db6d6902865bcc5b04e5c5c4b56f7158..f243f07e58ce004e9861ee05227ca390aa292b2d 100644
--- a/assets/js/just-the-docs.js
+++ b/assets/js/just-the-docs.js
@@ -74,7 +74,7 @@ function initSearch() {
   request.onload = function(){
     if (request.status >= 200 && request.status < 400) {
       var docs = JSON.parse(request.responseText);
-      
+
       lunr.tokenizer.separator = {{ site.search.tokenizer_separator | default: site.search_tokenizer_separator | default: "/[\s\-/]+/" }}
 
       var index = lunr(function(){
@@ -217,6 +217,7 @@ function searchLoaded(index, docs) {
       resultTitle.classList.add('search-result-title');
       resultLink.appendChild(resultTitle);
 
+      // note: the SVG svg-doc is only loaded as a Jekyll include if site.search_enabled is true; see _includes/icons/icons.html
       var resultDoc = document.createElement('div');
       resultDoc.classList.add('search-result-doc');
       resultDoc.innerHTML = '<svg viewBox="0 0 24 24" class="search-result-icon"><use xlink:href="#svg-doc"></use></svg>';
@@ -488,6 +489,7 @@ jtd.onReady(function(){
 
   var codeBlocks = document.querySelectorAll('div.highlighter-rouge, div.listingblock, figure.highlight');
 
+  // note: the SVG svg-copied and svg-copy is only loaded as a Jekyll include if site.enable_copy_code_button is true; see _includes/icons/icons.html
   var svgCopied =  '<svg viewBox="0 0 24 24" class="copy-icon"><use xlink:href="#svg-copied"></use></svg>';
   var svgCopy =  '<svg viewBox="0 0 24 24" class="copy-icon"><use xlink:href="#svg-copy"></use></svg>';
 
diff --git a/docs/customization.md b/docs/customization.md
index 67070ae9cee7ea9317058cef5fd0d5fe96d8a8f3..fe42892c7113a5f0622acfa755219e64b9c24d1c 100644
--- a/docs/customization.md
+++ b/docs/customization.md
@@ -212,3 +212,158 @@ Chercher notre site
 {% endraw %}
 
 would make the placeholder text "Chercher notre site". [Liquid code](https://jekyllrb.com/docs/liquid/) (including [Jekyll variables](https://jekyllrb.com/docs/variables/)) is also supported.
+
+## Custom layouts and includes
+{: .d-inline-block }
+
+New (v0.4.0)
+{: .label .label-green }
+
+Advanced
+{: .label .label-yellow }
+
+Just the Docs uses Jekyll's powerful [layouts](https://jekyllrb.com/docs/layouts/) and [includes](https://jekyllrb.com/docs/includes/) features to generate and compose various elements of the site. Jekyll users and developers can extend or replace existing layouts and includes to customize the entire site layout.
+
+### Default layout and includable components
+
+The `default` layout is inherited by most of the "out-of-the-box" pages provided by Just the Docs. It composes various re-usable components of the site, including the sidebar, navbar, footer, breadcrumbs, and various imports. Most users who create new pages or layouts will inherit from `default`.
+
+Here is a simplified code example of what it looks like:
+
+{% raw %}
+
+```liquid
+<!-- a simplified version of _layouts/default.html -->
+<html>
+{% include head.html %}
+<body>
+  {% include icons/icons.html %}
+  {% include components/sidebar.html %}
+  {% include components/header.html %}
+  {% include components/breadcrumbs.html %}
+
+  {% if site.heading_anchors != false %}
+    {% include vendor/anchor_headings.html html=content ... %}
+  {% else %}
+    {{ content }}
+  {% endif %}
+
+  {% if page.has_children == true and page.has_toc != false %}
+    {% include components/children_nav.html %}
+  {% endif %}
+
+  {% include components/footer.html %}
+
+  {% if site.search_enabled != false %}
+    {% include components/search_footer.html %}
+  {% endif %}
+
+  {% if site.mermaid %}
+    {% include components/mermaid.html %}
+  {% endif %}
+</body>
+</html>
+```
+
+{% endraw %}
+
+#### Component summary
+{: .no_toc }
+
+{: .warning }
+Defining a new `_includes` with the same name as any of these components will significantly change the existing layout. Please proceed with caution when adjusting them.
+
+To briefly summarize each component:
+
+- `_includes/head.html` is the entire `<head>` tag for the site; this imports stylesheets, various JavaScript files (ex: analytics, mermaid, search, and Just the Docs code), and SEO / meta information.
+- `_includes/icons/icons.html` imports all SVG icons that are used throughout the site. Some, such as those relating to search or code snippet copying, are only loaded when those features are enabled.
+- `_includes/components/sidebar.html` renders the sidebar, containing the site header, navigation links, external links, collections, and nav footer.
+- `_includes/components/header.html` renders the navigation header, containing the search bar, custom header, and aux links
+- `_includes/components/breadcrumbs.html` renders the breadcrumbs feature
+- `vendor/anchor_headings.html` is a local copy of Vladimir Jimenez's [jekyll-anchor-headings](https://github.com/allejo/jekyll-anchor-headings) snippet
+- `_includes/components/children_nav.html` renders a list of nav links to child pages on parent pages
+- `_includes/components/footer.html` renders the bottom-of-page footer
+- `_includes/components/search_footer.html` renders DOM elements that are necessary for the search bar to work
+- `_includes/components/mermaid.html` initializes mermaid if the feature is enabled
+
+Each of these components can be overridden individually using the same process described in the [Override includes](#override-includes) section. In particular, the granularity of components should allow users to replace certain components (such as the sidebar) without having to adjust the rest of the code.
+
+Future versions may subdivide components further; we guarantee that we will only place them in folders (ex `components/`, `icons/`, or a new `js/`) to avoid top-level namespace collisions.
+
+### Alternative layouts and example (`minimal`)
+
+Users can develop custom layouts that compose, omit, or add components differently. We provide one first-class example titled `minimal`, inspired by Kevin Lin's work in [just-the-class](https://github.com/kevinlin1/just-the-class). This `minimal` layout does not render the sidebar, header, or search. To see an example, visit the [minimal layout test]({{site.baseurl}}/docs/minimal-test/) page.
+
+Here is a simplified code example of what it looks like:
+
+{% raw %}
+
+```liquid
+<!-- a simplified version of _layouts/minimal.html -->
+<html>
+{% include head.html %}
+<body>
+  {% include icons/icons.html %}
+  {% comment %} Bandaid fix for breadcrumbs here! {% endcomment %}
+  {% include components/breadcrumbs.html %}
+
+  {% if site.heading_anchors != false %}
+    {% include vendor/anchor_headings.html html=content ... %}
+  {% else %}
+    {{ content }}
+  {% endif %}
+
+  {% if page.has_children == true and page.has_toc != false %}
+    {% include components/children_nav.html %}
+  {% endif %}
+
+  {% include components/footer.html %}
+
+  {% if site.mermaid %}
+    {% include components/mermaid.html %}
+  {% endif %}
+</body>
+</html>
+```
+
+{% endraw %}
+
+This layout is packaged in Just the Docs. Users can indicate this alternative layout in page front matter:
+
+{% raw %}
+
+```
+---
+layout: minimal
+title: Minimal layout test
+---
+```
+
+{% endraw %}
+
+Similarly, users and developers can create other alternative layouts using Just the Docs' reusable includable components.
+
+### Default layout and inheritance chain
+
+Under the hood,
+
+- `default` and `minimal` inherit from the `table_wrappers` layout, which wraps all HTML `<table>` tags with a `div .table-wrapper`
+- `table_wrappers` inherits from `vendor/compress`, which is a local copy of Anatol Broder's [jekyll-compress-html](https://github.com/penibelst/jekyll-compress-html) Jekyll plugin
+
+Note that as of now, `minimal` and `default` have no inheritance relationship.
+
+### Overridden default Jekyll layouts
+
+By default, Jekyll (and its default theme `minima`) provide the `about`, `home`, `page`, and `post` layouts. In Just the Docs, we override all of these layouts with the `default` layout. Each of those layouts is simply:
+
+{% raw %}
+
+```
+---
+layout: default
+---
+
+{{ content }}
+```
+
+{% endraw %}
diff --git a/docs/minimal-test.md b/docs/minimal-test.md
new file mode 100644
index 0000000000000000000000000000000000000000..aa754d3172c80cdb94ba15b7a48693824a434368
--- /dev/null
+++ b/docs/minimal-test.md
@@ -0,0 +1,9 @@
+---
+layout: minimal
+title: Minimal layout test
+nav_exclude: true
+---
+
+[Return to main website]({{site.baseurl}}/).
+
+This page demonstrates the packaged `minimal` layout, which does not render the sidebar or header. It can be used for standalone pages. It is also an example of using the new modular site components to define custom layouts; see ["Custom layouts and includes" in the customization docs]({{site.baseurl}}/docs/customization/#custom-layouts-and-includes) for more information.