From d635734c78f8f12394ad948e9bf5be68a746dac2 Mon Sep 17 00:00:00 2001
From: meator <meator.dev@gmail.com>
Date: Sun, 4 May 2025 08:45:35 +0200
Subject: [PATCH 1/3] Force update mdBook theme files

This commit is split in two: 1) overwrite the old theme files 2) reapply
void-docs' changes to the theme. The next commit applies void-docs
changes. This split is done to make the git history clean and to clearly
showcase which changes need to be done in the second commit.

mdBook v0.4.43 was used to generate the default theme.

This update has two benefits:
1. Features added in updates to mdBook made since the old theme files
   were commited will become available.

   It is possible to "backport" newer features into the old theme files,
   but this should be a cleaner solution.
2. It should fix building void-docs using newer versions of mdBook.

   The currently packaged version of mdBook (v0.4.43) has minor
   rendering issues.
---
 src/theme/book.js           | 629 +++++++++++++++++++++++++++++++--
 src/theme/css/chrome.css    | 682 ++++++++++++++++++++++--------------
 src/theme/css/general.css   | 509 +++++++++++----------------
 src/theme/css/print.css     |  37 +-
 src/theme/css/variables.css | 354 +++++++++++++++----
 src/theme/index.hbs         | 574 +++++++++++++++++-------------
 6 files changed, 1824 insertions(+), 961 deletions(-)

diff --git a/src/theme/book.js b/src/theme/book.js
index d1a280f9e..178f1e902 100644
--- a/src/theme/book.js
+++ b/src/theme/book.js
@@ -3,31 +3,458 @@
 // Fix back button cache problem
 window.onunload = function () { };
 
-(function theme() {
-    var html = document.querySelector("html");
-    var themeToggleButton = document.getElementById("theme-toggle");
-
-    themeToggleButton.addEventListener('click', function sidebarToggle() {
-        if (html.classList.contains("void-light")) {
-            html.classList.replace("void-light", "void-dark");
-            localStorage.setItem('mdbook-theme', "void-dark");
+// Global variable, shared between modules
+function playground_text(playground, hidden = true) {
+    let code_block = playground.querySelector("code");
+
+    if (window.ace && code_block.classList.contains("editable")) {
+        let editor = window.ace.edit(code_block);
+        return editor.getValue();
+    } else if (hidden) {
+        return code_block.textContent;
+    } else {
+        return code_block.innerText;
+    }
+}
+
+(function codeSnippets() {
+    function fetch_with_timeout(url, options, timeout = 6000) {
+        return Promise.race([
+            fetch(url, options),
+            new Promise((_, reject) => setTimeout(() => reject(new Error('timeout')), timeout))
+        ]);
+    }
+
+    var playgrounds = Array.from(document.querySelectorAll(".playground"));
+    if (playgrounds.length > 0) {
+        fetch_with_timeout("https://play.rust-lang.org/meta/crates", {
+            headers: {
+                'Content-Type': "application/json",
+            },
+            method: 'POST',
+            mode: 'cors',
+        })
+        .then(response => response.json())
+        .then(response => {
+            // get list of crates available in the rust playground
+            let playground_crates = response.crates.map(item => item["id"]);
+            playgrounds.forEach(block => handle_crate_list_update(block, playground_crates));
+        });
+    }
+
+    function handle_crate_list_update(playground_block, playground_crates) {
+        // update the play buttons after receiving the response
+        update_play_button(playground_block, playground_crates);
+
+        // and install on change listener to dynamically update ACE editors
+        if (window.ace) {
+            let code_block = playground_block.querySelector("code");
+            if (code_block.classList.contains("editable")) {
+                let editor = window.ace.edit(code_block);
+                editor.addEventListener("change", function (e) {
+                    update_play_button(playground_block, playground_crates);
+                });
+                // add Ctrl-Enter command to execute rust code
+                editor.commands.addCommand({
+                    name: "run",
+                    bindKey: {
+                        win: "Ctrl-Enter",
+                        mac: "Ctrl-Enter"
+                    },
+                    exec: _editor => run_rust_code(playground_block)
+                });
+            }
+        }
+    }
+
+    // updates the visibility of play button based on `no_run` class and
+    // used crates vs ones available on https://play.rust-lang.org
+    function update_play_button(pre_block, playground_crates) {
+        var play_button = pre_block.querySelector(".play-button");
+
+        // skip if code is `no_run`
+        if (pre_block.querySelector('code').classList.contains("no_run")) {
+            play_button.classList.add("hidden");
+            return;
+        }
+
+        // get list of `extern crate`'s from snippet
+        var txt = playground_text(pre_block);
+        var re = /extern\s+crate\s+([a-zA-Z_0-9]+)\s*;/g;
+        var snippet_crates = [];
+        var item;
+        while (item = re.exec(txt)) {
+            snippet_crates.push(item[1]);
+        }
+
+        // check if all used crates are available on play.rust-lang.org
+        var all_available = snippet_crates.every(function (elem) {
+            return playground_crates.indexOf(elem) > -1;
+        });
+
+        if (all_available) {
+            play_button.classList.remove("hidden");
         } else {
-            html.classList.replace("void-dark", "void-light");
-            localStorage.setItem('mdbook-theme', "void-light");
+            play_button.classList.add("hidden");
+        }
+    }
+
+    function run_rust_code(code_block) {
+        var result_block = code_block.querySelector(".result");
+        if (!result_block) {
+            result_block = document.createElement('code');
+            result_block.className = 'result hljs language-bash';
+
+            code_block.append(result_block);
+        }
+
+        let text = playground_text(code_block);
+        let classes = code_block.querySelector('code').classList;
+        let edition = "2015";
+        if(classes.contains("edition2018")) {
+            edition = "2018";
+        } else if(classes.contains("edition2021")) {
+            edition = "2021";
+        }
+        var params = {
+            version: "stable",
+            optimize: "0",
+            code: text,
+            edition: edition
+        };
+
+        if (text.indexOf("#![feature") !== -1) {
+            params.version = "nightly";
+        }
+
+        result_block.innerText = "Running...";
+
+        fetch_with_timeout("https://play.rust-lang.org/evaluate.json", {
+            headers: {
+                'Content-Type': "application/json",
+            },
+            method: 'POST',
+            mode: 'cors',
+            body: JSON.stringify(params)
+        })
+        .then(response => response.json())
+        .then(response => {
+            if (response.result.trim() === '') {
+                result_block.innerText = "No output";
+                result_block.classList.add("result-no-output");
+            } else {
+                result_block.innerText = response.result;
+                result_block.classList.remove("result-no-output");
+            }
+        })
+        .catch(error => result_block.innerText = "Playground Communication: " + error.message);
+    }
+
+    // Syntax highlighting Configuration
+    hljs.configure({
+        tabReplace: '    ', // 4 spaces
+        languages: [],      // Languages used for auto-detection
+    });
+
+    let code_nodes = Array
+        .from(document.querySelectorAll('code'))
+        // Don't highlight `inline code` blocks in headers.
+        .filter(function (node) {return !node.parentElement.classList.contains("header"); });
+
+    if (window.ace) {
+        // language-rust class needs to be removed for editable
+        // blocks or highlightjs will capture events
+        code_nodes
+            .filter(function (node) {return node.classList.contains("editable"); })
+            .forEach(function (block) { block.classList.remove('language-rust'); });
+
+        code_nodes
+            .filter(function (node) {return !node.classList.contains("editable"); })
+            .forEach(function (block) { hljs.highlightBlock(block); });
+    } else {
+        code_nodes.forEach(function (block) { hljs.highlightBlock(block); });
+    }
+
+    // Adding the hljs class gives code blocks the color css
+    // even if highlighting doesn't apply
+    code_nodes.forEach(function (block) { block.classList.add('hljs'); });
+
+    Array.from(document.querySelectorAll("code.hljs")).forEach(function (block) {
+
+        var lines = Array.from(block.querySelectorAll('.boring'));
+        // If no lines were hidden, return
+        if (!lines.length) { return; }
+        block.classList.add("hide-boring");
+
+        var buttons = document.createElement('div');
+        buttons.className = 'buttons';
+        buttons.innerHTML = "<button class=\"fa fa-eye\" title=\"Show hidden lines\" aria-label=\"Show hidden lines\"></button>";
+
+        // add expand button
+        var pre_block = block.parentNode;
+        pre_block.insertBefore(buttons, pre_block.firstChild);
+
+        pre_block.querySelector('.buttons').addEventListener('click', function (e) {
+            if (e.target.classList.contains('fa-eye')) {
+                e.target.classList.remove('fa-eye');
+                e.target.classList.add('fa-eye-slash');
+                e.target.title = 'Hide lines';
+                e.target.setAttribute('aria-label', e.target.title);
+
+                block.classList.remove('hide-boring');
+            } else if (e.target.classList.contains('fa-eye-slash')) {
+                e.target.classList.remove('fa-eye-slash');
+                e.target.classList.add('fa-eye');
+                e.target.title = 'Show hidden lines';
+                e.target.setAttribute('aria-label', e.target.title);
+
+                block.classList.add('hide-boring');
+            }
+        });
+    });
+
+    if (window.playground_copyable) {
+        Array.from(document.querySelectorAll('pre code')).forEach(function (block) {
+            var pre_block = block.parentNode;
+            if (!pre_block.classList.contains('playground')) {
+                var buttons = pre_block.querySelector(".buttons");
+                if (!buttons) {
+                    buttons = document.createElement('div');
+                    buttons.className = 'buttons';
+                    pre_block.insertBefore(buttons, pre_block.firstChild);
+                }
+
+                var clipButton = document.createElement('button');
+                clipButton.className = 'clip-button';
+                clipButton.title = 'Copy to clipboard';
+                clipButton.setAttribute('aria-label', clipButton.title);
+                clipButton.innerHTML = '<i class=\"tooltiptext\"></i>';
+
+                buttons.insertBefore(clipButton, buttons.firstChild);
+            }
+        });
+    }
+
+    // Process playground code blocks
+    Array.from(document.querySelectorAll(".playground")).forEach(function (pre_block) {
+        // Add play button
+        var buttons = pre_block.querySelector(".buttons");
+        if (!buttons) {
+            buttons = document.createElement('div');
+            buttons.className = 'buttons';
+            pre_block.insertBefore(buttons, pre_block.firstChild);
+        }
+
+        var runCodeButton = document.createElement('button');
+        runCodeButton.className = 'fa fa-play play-button';
+        runCodeButton.hidden = true;
+        runCodeButton.title = 'Run this code';
+        runCodeButton.setAttribute('aria-label', runCodeButton.title);
+
+        buttons.insertBefore(runCodeButton, buttons.firstChild);
+        runCodeButton.addEventListener('click', function (e) {
+            run_rust_code(pre_block);
+        });
+
+        if (window.playground_copyable) {
+            var copyCodeClipboardButton = document.createElement('button');
+            copyCodeClipboardButton.className = 'clip-button';
+            copyCodeClipboardButton.innerHTML = '<i class="tooltiptext"></i>';
+            copyCodeClipboardButton.title = 'Copy to clipboard';
+            copyCodeClipboardButton.setAttribute('aria-label', copyCodeClipboardButton.title);
+
+            buttons.insertBefore(copyCodeClipboardButton, buttons.firstChild);
+        }
+
+        let code_block = pre_block.querySelector("code");
+        if (window.ace && code_block.classList.contains("editable")) {
+            var undoChangesButton = document.createElement('button');
+            undoChangesButton.className = 'fa fa-history reset-button';
+            undoChangesButton.title = 'Undo changes';
+            undoChangesButton.setAttribute('aria-label', undoChangesButton.title);
+
+            buttons.insertBefore(undoChangesButton, buttons.firstChild);
+
+            undoChangesButton.addEventListener('click', function () {
+                let editor = window.ace.edit(code_block);
+                editor.setValue(editor.originalCode);
+                editor.clearSelection();
+            });
+        }
+    });
+})();
+
+(function themes() {
+    var html = document.querySelector('html');
+    var themeToggleButton = document.getElementById('theme-toggle');
+    var themePopup = document.getElementById('theme-list');
+    var themeColorMetaTag = document.querySelector('meta[name="theme-color"]');
+    var themeIds = [];
+    themePopup.querySelectorAll('button.theme').forEach(function (el) {
+        themeIds.push(el.id);
+    });
+    var stylesheets = {
+        ayuHighlight: document.querySelector("[href$='ayu-highlight.css']"),
+        tomorrowNight: document.querySelector("[href$='tomorrow-night.css']"),
+        highlight: document.querySelector("[href$='highlight.css']"),
+    };
+
+    function showThemes() {
+        themePopup.style.display = 'block';
+        themeToggleButton.setAttribute('aria-expanded', true);
+        themePopup.querySelector("button#" + get_theme()).focus();
+    }
+
+    function updateThemeSelected() {
+        themePopup.querySelectorAll('.theme-selected').forEach(function (el) {
+            el.classList.remove('theme-selected');
+        });
+        themePopup.querySelector("button#" + get_theme()).classList.add('theme-selected');
+    }
+
+    function hideThemes() {
+        themePopup.style.display = 'none';
+        themeToggleButton.setAttribute('aria-expanded', false);
+        themeToggleButton.focus();
+    }
+
+    function get_theme() {
+        var theme;
+        try { theme = localStorage.getItem('mdbook-theme'); } catch (e) { }
+        if (theme === null || theme === undefined || !themeIds.includes(theme)) {
+            return default_theme;
+        } else {
+            return theme;
+        }
+    }
+
+    function set_theme(theme, store = true) {
+        let ace_theme;
+
+        if (theme == 'coal' || theme == 'navy') {
+            stylesheets.ayuHighlight.disabled = true;
+            stylesheets.tomorrowNight.disabled = false;
+            stylesheets.highlight.disabled = true;
+
+            ace_theme = "ace/theme/tomorrow_night";
+        } else if (theme == 'ayu') {
+            stylesheets.ayuHighlight.disabled = false;
+            stylesheets.tomorrowNight.disabled = true;
+            stylesheets.highlight.disabled = true;
+            ace_theme = "ace/theme/tomorrow_night";
+        } else {
+            stylesheets.ayuHighlight.disabled = true;
+            stylesheets.tomorrowNight.disabled = true;
+            stylesheets.highlight.disabled = false;
+            ace_theme = "ace/theme/dawn";
+        }
+
+        setTimeout(function () {
+            themeColorMetaTag.content = getComputedStyle(document.documentElement).backgroundColor;
+        }, 1);
+
+        if (window.ace && window.editors) {
+            window.editors.forEach(function (editor) {
+                editor.setTheme(ace_theme);
+            });
+        }
+
+        var previousTheme = get_theme();
+
+        if (store) {
+            try { localStorage.setItem('mdbook-theme', theme); } catch (e) { }
+        }
+
+        html.classList.remove(previousTheme);
+        html.classList.add(theme);
+        updateThemeSelected();
+    }
+
+    // Set theme
+    var theme = get_theme();
+
+    set_theme(theme, false);
+
+    themeToggleButton.addEventListener('click', function () {
+        if (themePopup.style.display === 'block') {
+            hideThemes();
+        } else {
+            showThemes();
+        }
+    });
+
+    themePopup.addEventListener('click', function (e) {
+        var theme;
+        if (e.target.className === "theme") {
+            theme = e.target.id;
+        } else if (e.target.parentElement.className === "theme") {
+            theme = e.target.parentElement.id;
+        } else {
+            return;
+        }
+        set_theme(theme);
+    });
+
+    themePopup.addEventListener('focusout', function(e) {
+        // e.relatedTarget is null in Safari and Firefox on macOS (see workaround below)
+        if (!!e.relatedTarget && !themeToggleButton.contains(e.relatedTarget) && !themePopup.contains(e.relatedTarget)) {
+            hideThemes();
+        }
+    });
+
+    // Should not be needed, but it works around an issue on macOS & iOS: https://github.com/rust-lang/mdBook/issues/628
+    document.addEventListener('click', function(e) {
+        if (themePopup.style.display === 'block' && !themeToggleButton.contains(e.target) && !themePopup.contains(e.target)) {
+            hideThemes();
+        }
+    });
+
+    document.addEventListener('keydown', function (e) {
+        if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) { return; }
+        if (!themePopup.contains(e.target)) { return; }
+
+        switch (e.key) {
+            case 'Escape':
+                e.preventDefault();
+                hideThemes();
+                break;
+            case 'ArrowUp':
+                e.preventDefault();
+                var li = document.activeElement.parentElement;
+                if (li && li.previousElementSibling) {
+                    li.previousElementSibling.querySelector('button').focus();
+                }
+                break;
+            case 'ArrowDown':
+                e.preventDefault();
+                var li = document.activeElement.parentElement;
+                if (li && li.nextElementSibling) {
+                    li.nextElementSibling.querySelector('button').focus();
+                }
+                break;
+            case 'Home':
+                e.preventDefault();
+                themePopup.querySelector('li:first-child button').focus();
+                break;
+            case 'End':
+                e.preventDefault();
+                themePopup.querySelector('li:last-child button').focus();
+                break;
         }
     });
 })();
 
 (function sidebar() {
-    var html = document.querySelector("html");
+    var body = document.querySelector("body");
     var sidebar = document.getElementById("sidebar");
     var sidebarLinks = document.querySelectorAll('#sidebar a');
     var sidebarToggleButton = document.getElementById("sidebar-toggle");
+    var sidebarResizeHandle = document.getElementById("sidebar-resize-handle");
     var firstContact = null;
 
     function showSidebar() {
-        html.classList.remove('sidebar-hidden')
-        html.classList.add('sidebar-visible');
+        body.classList.remove('sidebar-hidden')
+        body.classList.add('sidebar-visible');
         Array.from(sidebarLinks).forEach(function (link) {
             link.setAttribute('tabIndex', 0);
         });
@@ -37,8 +464,8 @@ window.onunload = function () { };
     }
 
     function hideSidebar() {
-        html.classList.remove('sidebar-visible')
-        html.classList.add('sidebar-hidden');
+        body.classList.remove('sidebar-visible')
+        body.classList.add('sidebar-hidden');
         Array.from(sidebarLinks).forEach(function (link) {
             link.setAttribute('tabIndex', -1);
         });
@@ -49,9 +476,14 @@ window.onunload = function () { };
 
     // Toggle sidebar
     sidebarToggleButton.addEventListener('click', function sidebarToggle() {
-        if (html.classList.contains("sidebar-hidden")) {
+        if (body.classList.contains("sidebar-hidden")) {
+            var current_width = parseInt(
+                document.documentElement.style.getPropertyValue('--sidebar-width'), 10);
+            if (current_width < 150) {
+                document.documentElement.style.setProperty('--sidebar-width', '150px');
+            }
             showSidebar();
-        } else if (html.classList.contains("sidebar-visible")) {
+        } else if (body.classList.contains("sidebar-visible")) {
             hideSidebar();
         } else {
             if (getComputedStyle(sidebar)['transform'] === 'none') {
@@ -62,6 +494,32 @@ window.onunload = function () { };
         }
     });
 
+    sidebarResizeHandle.addEventListener('mousedown', initResize, false);
+
+    function initResize(e) {
+        window.addEventListener('mousemove', resize, false);
+        window.addEventListener('mouseup', stopResize, false);
+        body.classList.add('sidebar-resizing');
+    }
+    function resize(e) {
+        var pos = (e.clientX - sidebar.offsetLeft);
+        if (pos < 20) {
+            hideSidebar();
+        } else {
+            if (body.classList.contains("sidebar-hidden")) {
+                showSidebar();
+            }
+            pos = Math.min(pos, window.innerWidth - 100);
+            document.documentElement.style.setProperty('--sidebar-width', pos + 'px');
+        }
+    }
+    //on mouseup remove windows functions mousemove & mouseup
+    function stopResize(e) {
+        body.classList.remove('sidebar-resizing');
+        window.removeEventListener('mousemove', resize, false);
+        window.removeEventListener('mouseup', stopResize, false);
+    }
+
     document.addEventListener('touchstart', function (e) {
         firstContact = {
             x: e.touches[0].clientX,
@@ -86,34 +544,147 @@ window.onunload = function () { };
             firstContact = null;
         }
     }, { passive: true });
-
-    // Scroll sidebar to current active section
-    var activeSection = sidebar.querySelector(".active");
-    if (activeSection) {
-        sidebar.scrollTop = activeSection.offsetTop;
-    }
 })();
 
 (function chapterNavigation() {
     document.addEventListener('keydown', function (e) {
         if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) { return; }
         if (window.search && window.search.hasFocus()) { return; }
+        var html = document.querySelector('html');
 
+        function next() {
+            var nextButton = document.querySelector('.nav-chapters.next');
+            if (nextButton) {
+                window.location.href = nextButton.href;
+            }
+        }
+        function prev() {
+            var previousButton = document.querySelector('.nav-chapters.previous');
+            if (previousButton) {
+                window.location.href = previousButton.href;
+            }
+        }
         switch (e.key) {
             case 'ArrowRight':
                 e.preventDefault();
-                var nextButton = document.querySelector('.nav-chapters.next');
-                if (nextButton) {
-                    window.location.href = nextButton.href;
+                if (html.dir == 'rtl') {
+                    prev();
+                } else {
+                    next();
                 }
                 break;
             case 'ArrowLeft':
                 e.preventDefault();
-                var previousButton = document.querySelector('.nav-chapters.previous');
-                if (previousButton) {
-                    window.location.href = previousButton.href;
+                if (html.dir == 'rtl') {
+                    next();
+                } else {
+                    prev();
                 }
                 break;
         }
     });
 })();
+
+(function clipboard() {
+    var clipButtons = document.querySelectorAll('.clip-button');
+
+    function hideTooltip(elem) {
+        elem.firstChild.innerText = "";
+        elem.className = 'clip-button';
+    }
+
+    function showTooltip(elem, msg) {
+        elem.firstChild.innerText = msg;
+        elem.className = 'clip-button tooltipped';
+    }
+
+    var clipboardSnippets = new ClipboardJS('.clip-button', {
+        text: function (trigger) {
+            hideTooltip(trigger);
+            let playground = trigger.closest("pre");
+            return playground_text(playground, false);
+        }
+    });
+
+    Array.from(clipButtons).forEach(function (clipButton) {
+        clipButton.addEventListener('mouseout', function (e) {
+            hideTooltip(e.currentTarget);
+        });
+    });
+
+    clipboardSnippets.on('success', function (e) {
+        e.clearSelection();
+        showTooltip(e.trigger, "Copied!");
+    });
+
+    clipboardSnippets.on('error', function (e) {
+        showTooltip(e.trigger, "Clipboard error!");
+    });
+})();
+
+(function scrollToTop () {
+    var menuTitle = document.querySelector('.menu-title');
+
+    menuTitle.addEventListener('click', function () {
+        document.scrollingElement.scrollTo({ top: 0, behavior: 'smooth' });
+    });
+})();
+
+(function controllMenu() {
+    var menu = document.getElementById('menu-bar');
+
+    (function controllPosition() {
+        var scrollTop = document.scrollingElement.scrollTop;
+        var prevScrollTop = scrollTop;
+        var minMenuY = -menu.clientHeight - 50;
+        // When the script loads, the page can be at any scroll (e.g. if you reforesh it).
+        menu.style.top = scrollTop + 'px';
+        // Same as parseInt(menu.style.top.slice(0, -2), but faster
+        var topCache = menu.style.top.slice(0, -2);
+        menu.classList.remove('sticky');
+        var stickyCache = false; // Same as menu.classList.contains('sticky'), but faster
+        document.addEventListener('scroll', function () {
+            scrollTop = Math.max(document.scrollingElement.scrollTop, 0);
+            // `null` means that it doesn't need to be updated
+            var nextSticky = null;
+            var nextTop = null;
+            var scrollDown = scrollTop > prevScrollTop;
+            var menuPosAbsoluteY = topCache - scrollTop;
+            if (scrollDown) {
+                nextSticky = false;
+                if (menuPosAbsoluteY > 0) {
+                    nextTop = prevScrollTop;
+                }
+            } else {
+                if (menuPosAbsoluteY > 0) {
+                    nextSticky = true;
+                } else if (menuPosAbsoluteY < minMenuY) {
+                    nextTop = prevScrollTop + minMenuY;
+                }
+            }
+            if (nextSticky === true && stickyCache === false) {
+                menu.classList.add('sticky');
+                stickyCache = true;
+            } else if (nextSticky === false && stickyCache === true) {
+                menu.classList.remove('sticky');
+                stickyCache = false;
+            }
+            if (nextTop !== null) {
+                menu.style.top = nextTop + 'px';
+                topCache = nextTop;
+            }
+            prevScrollTop = scrollTop;
+        }, { passive: true });
+    })();
+    (function controllBorder() {
+        function updateBorder() {
+            if (menu.offsetTop === 0) {
+                menu.classList.remove('bordered');
+            } else {
+                menu.classList.add('bordered');
+            }
+        }
+        updateBorder();
+        document.addEventListener('scroll', updateBorder, { passive: true });
+    })();
+})();
diff --git a/src/theme/css/chrome.css b/src/theme/css/chrome.css
index 544e7718e..4cd73086d 100644
--- a/src/theme/css/chrome.css
+++ b/src/theme/css/chrome.css
@@ -1,109 +1,114 @@
 /* CSS for UI elements (a.k.a. chrome) */
 
-@import 'variables.css';
-
-::-webkit-scrollbar {
-	background: var(--bg);
-}
-::-webkit-scrollbar-thumb {
-	background: var(--scrollbar);
-}
 html {
-	scrollbar-color: var(--scrollbar) var(--bg);
+    scrollbar-color: var(--scrollbar) var(--bg);
 }
 #searchresults a,
 .content a:link,
 a:visited,
 a > .hljs {
-	color: var(--links);
+    color: var(--links);
+}
+
+/*
+    body-container is necessary because mobile browsers don't seem to like
+    overflow-x on the body tag when there is a <meta name="viewport"> tag.
+*/
+#body-container {
+    /*
+        This is used when the sidebar pushes the body content off the side of
+        the screen on small screens. Without it, dragging on mobile Safari
+        will want to reposition the viewport in a weird way.
+    */
+    overflow-x: clip;
 }
 
 /* Menu Bar */
 
 #menu-bar,
 #menu-bar-hover-placeholder {
-	z-index: 101;
-	margin: auto calc(0px - var(--page-padding));
+    z-index: 101;
+    margin: auto calc(0px - var(--page-padding));
 }
 #menu-bar {
-	position: relative;
-	display: flex;
-	flex-wrap: wrap;
-	background-color: var(--bg);
-	border-bottom-color: var(--bg);
-	border-bottom-width: 1px;
-	border-bottom-style: solid;
+    position: relative;
+    display: flex;
+    flex-wrap: wrap;
+    background-color: var(--bg);
+    border-block-end-color: var(--bg);
+    border-block-end-width: 1px;
+    border-block-end-style: solid;
 }
 #menu-bar.sticky,
-.js #menu-bar-hover-placeholder:hover + #menu-bar,
-.js #menu-bar:hover,
-.js.sidebar-visible #menu-bar {
-	position: -webkit-sticky;
-	position: sticky;
-	top: 0 !important;
+#menu-bar-hover-placeholder:hover + #menu-bar,
+#menu-bar:hover,
+html.sidebar-visible #menu-bar {
+    position: -webkit-sticky;
+    position: sticky;
+    top: 0 !important;
 }
 #menu-bar-hover-placeholder {
-	position: sticky;
-	position: -webkit-sticky;
-	top: 0;
-	height: var(--menu-bar-height);
+    position: sticky;
+    position: -webkit-sticky;
+    top: 0;
+    height: var(--menu-bar-height);
 }
 #menu-bar.bordered {
-	border-bottom-color: var(--table-border-color);
+    border-block-end-color: var(--table-border-color);
 }
 #menu-bar i, #menu-bar .icon-button {
-	position: relative;
-	padding: 0 8px;
-	z-index: 10;
-	line-height: var(--menu-bar-height);
-	cursor: pointer;
-	transition: color 0.5s;
+    position: relative;
+    padding: 0 8px;
+    z-index: 10;
+    line-height: var(--menu-bar-height);
+    cursor: pointer;
+    transition: color 0.5s;
 }
 @media only screen and (max-width: 420px) {
-	#menu-bar i, #menu-bar .icon-button {
-		padding: 0 5px;
-	}
+    #menu-bar i, #menu-bar .icon-button {
+        padding: 0 5px;
+    }
 }
 
 .icon-button {
-	border: none;
-	background: none;
-	padding: 0;
-	color: inherit;
+    border: none;
+    background: none;
+    padding: 0;
+    color: inherit;
 }
 .icon-button i {
-	margin: 0;
+    margin: 0;
 }
 
 .right-buttons {
-	margin: 0 15px;
+    margin: 0 15px;
 }
 .right-buttons a {
-	text-decoration: none;
+    text-decoration: none;
 }
 
 .left-buttons {
-	display: flex;
-	margin: 0 5px;
+    display: flex;
+    margin: 0 5px;
 }
-.no-js .left-buttons {
-	display: none;
+html:not(.js) .left-buttons button {
+    display: none;
 }
 
 .menu-title {
-	display: inline-block;
-	font-weight: 200;
-	font-size: 2.4rem;
-	line-height: var(--menu-bar-height);
-	text-align: center;
-	margin: 0;
-	flex: 1;
-	white-space: nowrap;
-	overflow: hidden;
-	text-overflow: ellipsis;
+    display: inline-block;
+    font-weight: 200;
+    font-size: 2.4rem;
+    line-height: var(--menu-bar-height);
+    text-align: center;
+    margin: 0;
+    flex: 1;
+    white-space: nowrap;
+    overflow: hidden;
+    text-overflow: ellipsis;
 }
-.js .menu-title {
-	cursor: pointer;
+.menu-title {
+    cursor: pointer;
 }
 
 .menu-bar,
@@ -114,371 +119,522 @@ a > .hljs {
 .mobile-nav-chapters:visited,
 .menu-bar .icon-button,
 .menu-bar a i {
-	color: var(--icons);
+    color: var(--icons);
 }
 
 .menu-bar i:hover,
 .menu-bar .icon-button:hover,
 .nav-chapters:hover,
 .mobile-nav-chapters i:hover {
-	color: var(--icons-hover);
+    color: var(--icons-hover);
 }
 
 /* Nav Icons */
 
 .nav-chapters {
-	font-size: 2.5em;
-	text-align: center;
-	text-decoration: none;
+    font-size: 2.5em;
+    text-align: center;
+    text-decoration: none;
 
-	position: fixed;
-	top: 0;
-	bottom: 0;
-	margin: 0;
-	max-width: 150px;
-	min-width: 90px;
+    position: fixed;
+    top: 0;
+    bottom: 0;
+    margin: 0;
+    max-width: 150px;
+    min-width: 90px;
 
-	display: flex;
-	justify-content: center;
-	align-content: center;
-	flex-direction: column;
+    display: flex;
+    justify-content: center;
+    align-content: center;
+    flex-direction: column;
 
-	transition: color 0.5s, background-color 0.5s;
+    transition: color 0.5s, background-color 0.5s;
 }
 
 .nav-chapters:hover {
-	text-decoration: none;
-	transition: color 0.15s, color 0.15s;
+    text-decoration: none;
+    background-color: var(--theme-hover);
+    transition: background-color 0.15s, color 0.15s;
 }
 
 .nav-wrapper {
-	margin-top: 50px;
-	display: none;
+    margin-block-start: 50px;
+    display: none;
 }
 
 .mobile-nav-chapters {
-	font-size: 2.5em;
-	text-align: center;
-	text-decoration: none;
-	width: 90px;
-	border-radius: 5px;
-	background-color: var(--sidebar-bg);
+    font-size: 2.5em;
+    text-align: center;
+    text-decoration: none;
+    width: 90px;
+    border-radius: 5px;
+    background-color: var(--sidebar-bg);
 }
 
-.previous {
-	float: left;
-}
+/* Only Firefox supports flow-relative values */
+.previous { float: left; }
+[dir=rtl] .previous { float: right; }
 
+/* Only Firefox supports flow-relative values */
 .next {
-	float: right;
-	right: var(--page-padding);
+    float: right;
+    right: var(--page-padding);
 }
+[dir=rtl] .next {
+    float: left;
+    right: unset;
+    left: var(--page-padding);
+}
+
+/* Use the correct buttons for RTL layouts*/
+[dir=rtl] .previous i.fa-angle-left:before {content:"\f105";}
+[dir=rtl] .next i.fa-angle-right:before { content:"\f104"; }
 
 @media only screen and (max-width: 1080px) {
-	.nav-wide-wrapper { display: none; }
-	.nav-wrapper { display: block; }
+    .nav-wide-wrapper { display: none; }
+    .nav-wrapper { display: block; }
 }
 
+/* sidebar-visible */
 @media only screen and (max-width: 1380px) {
-	.sidebar-visible .nav-wide-wrapper { display: none; }
-	.sidebar-visible .nav-wrapper { display: block; }
+    #sidebar-toggle-anchor:checked ~ .page-wrapper .nav-wide-wrapper { display: none; }
+    #sidebar-toggle-anchor:checked ~ .page-wrapper .nav-wrapper { display: block; }
 }
 
 /* Inline code */
 
 :not(pre) > .hljs {
-	display: inline;
-	padding: 0.1em 0.3em;
-	border-radius: 3px;
+    display: inline;
+    padding: 0.1em 0.3em;
+    border-radius: 3px;
 }
 
 :not(pre):not(a) > .hljs {
-	color: var(--inline-code-color);
-	overflow-x: initial;
+    color: var(--inline-code-color);
+    overflow-x: initial;
 }
 
 a:hover > .hljs {
-	text-decoration: underline;
+    text-decoration: underline;
 }
 
 pre {
-	position: relative;
+    position: relative;
 }
 pre > .buttons {
-	position: absolute;
-	z-index: 100;
-	right: 5px;
-	top: 5px;
-
-	color: var(--sidebar-fg);
-	cursor: pointer;
+    position: absolute;
+    z-index: 100;
+    right: 0px;
+    top: 2px;
+    margin: 0px;
+    padding: 2px 0px;
+
+    color: var(--sidebar-fg);
+    cursor: pointer;
+    visibility: hidden;
+    opacity: 0;
+    transition: visibility 0.1s linear, opacity 0.1s linear;
+}
+pre:hover > .buttons {
+    visibility: visible;
+    opacity: 1
 }
 pre > .buttons :hover {
-	color: var(--sidebar-active);
+    color: var(--sidebar-active);
+    border-color: var(--icons-hover);
+    background-color: var(--theme-hover);
 }
 pre > .buttons i {
-	margin-left: 8px;
+    margin-inline-start: 8px;
 }
 pre > .buttons button {
-	color: inherit;
-	background: transparent;
-	border: none;
-	cursor: inherit;
+    cursor: inherit;
+    margin: 0px 5px;
+    padding: 4px 4px 3px 5px;
+    font-size: 23px;
+
+    border-style: solid;
+    border-width: 1px;
+    border-radius: 4px;
+    border-color: var(--icons);
+    background-color: var(--theme-popup-bg);
+    transition: 100ms;
+    transition-property: color,border-color,background-color;
+    color: var(--icons);
+}
+
+pre > .buttons button.clip-button {
+    padding: 2px 4px 0px 6px;
+}
+pre > .buttons button.clip-button::before {
+    /* clipboard image from octicons (https://github.com/primer/octicons/tree/v2.0.0) MIT license
+     */
+    content: url('data:image/svg+xml,<svg width="21" height="20" viewBox="0 0 24 25" \
+xmlns="http://www.w3.org/2000/svg" aria-label="Copy to clipboard">\
+<path d="M18 20h2v3c0 1-1 2-2 2H2c-.998 0-2-1-2-2V5c0-.911.755-1.667 1.667-1.667h5A3.323 3.323 0 \
+0110 0a3.323 3.323 0 013.333 3.333h5C19.245 3.333 20 4.09 20 5v8.333h-2V9H2v14h16v-3zM3 \
+7h14c0-.911-.793-1.667-1.75-1.667H13.5c-.957 0-1.75-.755-1.75-1.666C11.75 2.755 10.957 2 10 \
+2s-1.75.755-1.75 1.667c0 .911-.793 1.666-1.75 1.666H4.75C3.793 5.333 3 6.09 3 7z"/>\
+<path d="M4 19h6v2H4zM12 11H4v2h8zM4 17h4v-2H4zM15 15v-3l-4.5 4.5L15 21v-3l8.027-.032L23 15z"/>\
+</svg>');
+    filter: var(--copy-button-filter);
+}
+pre > .buttons button.clip-button:hover::before {
+    filter: var(--copy-button-filter-hover);
+}
+
+@media (pointer: coarse) {
+    pre > .buttons button {
+        /* On mobile, make it easier to tap buttons. */
+        padding: 0.3rem 1rem;
+    }
+
+    .sidebar-resize-indicator {
+        /* Hide resize indicator on devices with limited accuracy */
+        display: none;
+    }
+}
+pre > code {
+    display: block;
+    padding: 1rem;
+}
+
+/* FIXME: ACE editors overlap their buttons because ACE does absolute
+   positioning within the code block which breaks padding. The only solution I
+   can think of is to move the padding to the outer pre tag (or insert a div
+   wrapper), but that would require fixing a whole bunch of CSS rules.
+*/
+.hljs.ace_editor {
+  padding: 0rem 0rem;
 }
+
 pre > .result {
-	margin-top: 10px;
+    margin-block-start: 10px;
 }
 
 /* Search */
 
 #searchresults a {
-	text-decoration: none;
+    text-decoration: none;
 }
 
 mark {
-	border-radius: 2px;
-	padding: 0 3px 1px 3px;
-	margin: 0 -3px -1px -3px;
-	background-color: var(--search-mark-bg);
-	transition: background-color 300ms linear;
-	cursor: pointer;
+    border-radius: 2px;
+    padding-block-start: 0;
+    padding-block-end: 1px;
+    padding-inline-start: 3px;
+    padding-inline-end: 3px;
+    margin-block-start: 0;
+    margin-block-end: -1px;
+    margin-inline-start: -3px;
+    margin-inline-end: -3px;
+    background-color: var(--search-mark-bg);
+    transition: background-color 300ms linear;
+    cursor: pointer;
 }
 
 mark.fade-out {
-	background-color: rgba(0,0,0,0) !important;
-	cursor: auto;
+    background-color: rgba(0,0,0,0) !important;
+    cursor: auto;
 }
 
 .searchbar-outer {
-	margin-left: auto;
-	margin-right: auto;
-	max-width: var(--content-max-width);
+    margin-inline-start: auto;
+    margin-inline-end: auto;
+    max-width: var(--content-max-width);
 }
 
 #searchbar {
-	width: 100%;
-	margin: 5px auto 0px auto;
-	padding: 10px 16px;
-	transition: box-shadow 300ms ease-in-out;
-	border: 1px solid var(--searchbar-border-color);
-	border-radius: 3px;
-	background-color: var(--searchbar-bg);
-	color: var(--searchbar-fg);
+    width: 100%;
+    margin-block-start: 5px;
+    margin-block-end: 0;
+    margin-inline-start: auto;
+    margin-inline-end: auto;
+    padding: 10px 16px;
+    transition: box-shadow 300ms ease-in-out;
+    border: 1px solid var(--searchbar-border-color);
+    border-radius: 3px;
+    background-color: var(--searchbar-bg);
+    color: var(--searchbar-fg);
 }
 #searchbar:focus,
 #searchbar.active {
-	box-shadow: 0 0 3px var(--searchbar-shadow-color);
+    box-shadow: 0 0 3px var(--searchbar-shadow-color);
 }
 
 .searchresults-header {
-	font-weight: bold;
-	font-size: 1em;
-	padding: 18px 0 0 5px;
-	color: var(--searchresults-header-fg);
+    font-weight: bold;
+    font-size: 1em;
+    padding-block-start: 18px;
+    padding-block-end: 0;
+    padding-inline-start: 5px;
+    padding-inline-end: 0;
+    color: var(--searchresults-header-fg);
 }
 
 .searchresults-outer {
-	margin-left: auto;
-	margin-right: auto;
-	max-width: var(--content-max-width);
-	border-bottom: 1px dashed var(--searchresults-border-color);
+    margin-inline-start: auto;
+    margin-inline-end: auto;
+    max-width: var(--content-max-width);
+    border-block-end: 1px dashed var(--searchresults-border-color);
 }
 
 ul#searchresults {
-	list-style: none;
-	padding-left: 20px;
+    list-style: none;
+    padding-inline-start: 20px;
 }
 ul#searchresults li {
-	margin: 10px 0px;
-	padding: 2px;
-	border-radius: 2px;
+    margin: 10px 0px;
+    padding: 2px;
+    border-radius: 2px;
 }
 ul#searchresults li.focus {
-	background-color: var(--searchresults-li-bg);
+    background-color: var(--searchresults-li-bg);
 }
 ul#searchresults span.teaser {
-	display: block;
-	clear: both;
-	margin: 5px 0 0 20px;
-	font-size: 0.8em;
+    display: block;
+    clear: both;
+    margin-block-start: 5px;
+    margin-block-end: 0;
+    margin-inline-start: 20px;
+    margin-inline-end: 0;
+    font-size: 0.8em;
 }
 ul#searchresults span.teaser em {
-	font-weight: bold;
-	font-style: normal;
+    font-weight: bold;
+    font-style: normal;
 }
 
 /* Sidebar */
 
 .sidebar {
-	position: fixed;
-	left: 0;
-	top: 0;
-	bottom: 0;
-	width: var(--sidebar-width);
-	font-size: 0.875em;
-	box-sizing: border-box;
-	-webkit-overflow-scrolling: touch;
-	overscroll-behavior-y: contain;
-	background-color: var(--sidebar-bg);
-	color: var(--sidebar-fg);
-}
+    position: fixed;
+    left: 0;
+    top: 0;
+    bottom: 0;
+    width: var(--sidebar-width);
+    font-size: 0.875em;
+    box-sizing: border-box;
+    -webkit-overflow-scrolling: touch;
+    overscroll-behavior-y: contain;
+    background-color: var(--sidebar-bg);
+    color: var(--sidebar-fg);
+}
+.sidebar-iframe-inner {
+    background-color: var(--sidebar-bg);
+    color: var(--sidebar-fg);
+    padding: 10px 10px;
+    margin: 0;
+    font-size: 1.4rem;
+}
+.sidebar-iframe-outer {
+    border: none;
+    height: 100%;
+    position: absolute;
+    top: 0;
+    bottom: 0;
+    left: 0;
+    right: 0;
+}
+[dir=rtl] .sidebar { left: unset; right: 0; }
 .sidebar-resizing {
-	-moz-user-select: none;
-	-webkit-user-select: none;
-	-ms-user-select: none;
-	user-select: none;
+    -moz-user-select: none;
+    -webkit-user-select: none;
+    -ms-user-select: none;
+    user-select: none;
 }
-.js:not(.sidebar-resizing) .sidebar {
-	transition: transform 0.3s; /* Animation: slide away */
+html:not(.sidebar-resizing) .sidebar {
+    transition: transform 0.3s; /* Animation: slide away */
 }
 .sidebar code {
-	line-height: 2em;
-}
-/* .sidebar .sidebar-scrollbox {
-	overflow-y: auto;
-	position: absolute;
-	top: 0;
-	bottom: 0;
-	left: 0;
-	right: 0;
-	padding: 10px 10px;
-} */
+    line-height: 2em;
+}
+.sidebar .sidebar-scrollbox {
+    overflow-y: auto;
+    position: absolute;
+    top: 0;
+    bottom: 0;
+    left: 0;
+    right: 0;
+    padding: 10px 10px;
+}
 .sidebar .sidebar-resize-handle {
-	position: absolute;
-	cursor: col-resize;
-	width: 0;
-	right: 0;
-	top: 0;
-	bottom: 0;
+    position: absolute;
+    cursor: col-resize;
+    width: 0;
+    right: calc(var(--sidebar-resize-indicator-width) * -1);
+    top: 0;
+    bottom: 0;
+    display: flex;
+    align-items: center;
+}
+
+.sidebar-resize-handle .sidebar-resize-indicator {
+    width: 100%;
+    height: 12px;
+    background-color: var(--icons);
+    margin-inline-start: var(--sidebar-resize-indicator-space);
+}
+
+[dir=rtl] .sidebar .sidebar-resize-handle {
+    left: calc(var(--sidebar-resize-indicator-width) * -1);
+    right: unset;
 }
 .js .sidebar .sidebar-resize-handle {
-	cursor: col-resize;
-	width: 5px;
+    cursor: col-resize;
+    width: calc(var(--sidebar-resize-indicator-width) - var(--sidebar-resize-indicator-space));
+}
+/* sidebar-hidden */
+#sidebar-toggle-anchor:not(:checked) ~ .sidebar {
+    transform: translateX(calc(0px - var(--sidebar-width) - var(--sidebar-resize-indicator-width)));
+    z-index: -1;
 }
-.sidebar-hidden .sidebar {
-	transform: translateX(calc(0px - var(--sidebar-width)));
+[dir=rtl] #sidebar-toggle-anchor:not(:checked) ~ .sidebar {
+    transform: translateX(calc(var(--sidebar-width) + var(--sidebar-resize-indicator-width)));
 }
 .sidebar::-webkit-scrollbar {
-	background: var(--sidebar-bg);
+    background: var(--sidebar-bg);
 }
 .sidebar::-webkit-scrollbar-thumb {
-	background: var(--scrollbar);
+    background: var(--scrollbar);
+}
+
+/* sidebar-visible */
+#sidebar-toggle-anchor:checked ~ .page-wrapper {
+    transform: translateX(calc(var(--sidebar-width) + var(--sidebar-resize-indicator-width)));
+}
+[dir=rtl] #sidebar-toggle-anchor:checked ~ .page-wrapper {
+    transform: translateX(calc(0px - var(--sidebar-width) - var(--sidebar-resize-indicator-width)));
+}
+@media only screen and (min-width: 620px) {
+    #sidebar-toggle-anchor:checked ~ .page-wrapper {
+        transform: none;
+        margin-inline-start: calc(var(--sidebar-width) + var(--sidebar-resize-indicator-width));
+    }
+    [dir=rtl] #sidebar-toggle-anchor:checked ~ .page-wrapper {
+        transform: none;
+    }
 }
 
 .chapter {
-	list-style: none outside none;
-	padding-left: 0;
-	line-height: 2.2em;
+    list-style: none outside none;
+    padding-inline-start: 0;
+    line-height: 2.2em;
 }
 
 .chapter ol {
-	width: 100%;
+    width: 100%;
 }
 
 .chapter li {
-	display: flex;
-	color: var(--sidebar-non-existant);
+    display: flex;
+    color: var(--sidebar-non-existant);
 }
 .chapter li a {
-	display: block;
-	padding: 0;
-	text-decoration: none;
-	color: var(--sidebar-fg);
+    display: block;
+    padding: 0;
+    text-decoration: none;
+    color: var(--sidebar-fg);
 }
 
 .chapter li a:hover {
-	color: var(--sidebar-active);
+    color: var(--sidebar-active);
 }
 
 .chapter li a.active {
-	color: var(--sidebar-active);
+    color: var(--sidebar-active);
 }
 
 .chapter li > a.toggle {
-	cursor: pointer;
-	display: block;
-	margin-left: auto;
-	padding: 0 10px;
-	user-select: none;
-	opacity: 0.68;
+    cursor: pointer;
+    display: block;
+    margin-inline-start: auto;
+    padding: 0 10px;
+    user-select: none;
+    opacity: 0.68;
 }
 
 .chapter li > a.toggle div {
-	transition: transform 0.5s;
+    transition: transform 0.5s;
 }
 
 /* collapse the section */
 .chapter li:not(.expanded) + li > ol {
-	display: none;
+    display: none;
 }
 
 .chapter li.chapter-item {
-	line-height: 1.5em;
-	margin-top: 0.6em;
+    line-height: 1.5em;
+    margin-block-start: 0.6em;
 }
 
 .chapter li.expanded > a.toggle div {
-	transform: rotate(90deg);
+    transform: rotate(90deg);
 }
 
 .spacer {
-	width: 100%;
-	height: 3px;
-	margin: 5px 0px;
+    width: 100%;
+    height: 3px;
+    margin: 5px 0px;
 }
 .chapter .spacer {
-	background-color: var(--sidebar-spacer);
+    background-color: var(--sidebar-spacer);
 }
 
 @media (-moz-touch-enabled: 1), (pointer: coarse) {
-	.chapter li a { padding: 5px 0; }
-	.spacer { margin: 10px 0; }
+    .chapter li a { padding: 5px 0; }
+    .spacer { margin: 10px 0; }
 }
 
 .section {
-	list-style: none outside none;
-	padding-left: 20px;
-	line-height: 1.9em;
+    list-style: none outside none;
+    padding-inline-start: 20px;
+    line-height: 1.9em;
 }
 
 /* Theme Menu Popup */
 
 .theme-popup {
-	position: absolute;
-	left: 10px;
-	top: var(--menu-bar-height);
-	z-index: 1000;
-	border-radius: 4px;
-	font-size: 0.7em;
-	color: var(--fg);
-	background: var(--theme-popup-bg);
-	border: 1px solid var(--theme-popup-border);
-	margin: 0;
-	padding: 0;
-	list-style: none;
-	display: none;
-}
+    position: absolute;
+    left: 10px;
+    top: var(--menu-bar-height);
+    z-index: 1000;
+    border-radius: 4px;
+    font-size: 0.7em;
+    color: var(--fg);
+    background: var(--theme-popup-bg);
+    border: 1px solid var(--theme-popup-border);
+    margin: 0;
+    padding: 0;
+    list-style: none;
+    display: none;
+    /* Don't let the children's background extend past the rounded corners. */
+    overflow: hidden;
+}
+[dir=rtl] .theme-popup { left: unset;  right: 10px; }
 .theme-popup .default {
-	color: var(--icons);
+    color: var(--icons);
 }
 .theme-popup .theme {
-	width: 100%;
-	border: 0;
-	margin: 0;
-	padding: 2px 10px;
-	line-height: 25px;
-	white-space: nowrap;
-	text-align: left;
-	cursor: pointer;
-	color: inherit;
-	background: inherit;
-	font-size: inherit;
+    width: 100%;
+    border: 0;
+    margin: 0;
+    padding: 2px 20px;
+    line-height: 25px;
+    white-space: nowrap;
+    text-align: start;
+    cursor: pointer;
+    color: inherit;
+    background: inherit;
+    font-size: inherit;
 }
 .theme-popup .theme:hover {
-	background-color: var(--theme-hover);
+    background-color: var(--theme-hover);
 }
-.theme-popup .theme:hover:first-child,
-.theme-popup .theme:hover:last-child {
-	border-top-left-radius: inherit;
-	border-top-right-radius: inherit;
+
+.theme-selected::before {
+    display: inline-block;
+    content: "✓";
+    margin-inline-start: -14px;
+    width: 14px;
 }
diff --git a/src/theme/css/general.css b/src/theme/css/general.css
index 4eb45e393..0862b5167 100644
--- a/src/theme/css/general.css
+++ b/src/theme/css/general.css
@@ -1,351 +1,242 @@
-@import 'variables.css';
+/* Base styles and content styles */
 
-body {
-	font-family: 'Ubuntu', sans-serif;
-	font-size: 1rem;
-	line-height: 1.5;
-	color: var(--fg);
-	margin: 0;
-	background-color: var(--bg);
-}
-h1, h2, h3, h4, h5, h6 { color: var(--fg); }
-a, a:visited {
-	color: var(--links);
-	text-decoration: none;
-}
-a:hover, a:visited:hover {
-	color: var(--links-hover);
-	text-decoration: underline;
-}
-
-code {
-	background: var(--inline-code-color);
-	padding: 2px 4px;
-	border-radius: 4px;
-	white-space: pre-wrap;
-	overflow-wrap: break-word;
-}
-pre code {
-	padding: 0;
-	border-radius: 0;
-}
-pre {
-	padding: .5em;
-	margin: 1em 0;
-	background: var(--inline-code-color);
-	border: 1px solid var(--code-border);
-	border-radius: 4px;
-}
-
-blockquote {
-	margin: 20px 0;
-	padding: 0 20px;
-	padding-left: 1em;
-	background: var(--quote-bg);
-	border: 1px solid var(--quote-border);
-	border-left: none;
-	border-right: none;
+:root {
+    /* Browser default font-size is 16px, this way 1 rem = 10px */
+    font-size: 62.5%;
+    color-scheme: var(--color-scheme);
 }
 
-blockquote code {
-	background: var(--quote-code-bg);
+html {
+    font-family: "Open Sans", sans-serif;
+    color: var(--fg);
+    background-color: var(--bg);
+    text-size-adjust: none;
+    -webkit-text-size-adjust: none;
 }
 
-li.js-unavailable {
-		background-color: #f6cf68;
-		border-radius: 10px;
-		margin-left: 1em;
-		padding-left: 1em;
-		padding-right: 1em;
+body {
+    margin: 0;
+    font-size: 1.6rem;
+    overflow-x: hidden;
 }
 
-table {
-	border-collapse: collapse;
-	display: block;
-	overflow-y: auto;
-	border: 1px var(--table-border-color) solid;
-}
-table td {
-	padding: 3px 20px;
-}
-table thead {
-	background: var(--table-header-bg);
-	color: var(--table-header-fg);
-}
-table thead td {
-	font-weight: 700;
-}
-table tbody tr:nth-child(2n) {
-	/* Alternate background colors for rows */
-	background: var(--table-alternate-bg);
+code {
+    font-family: var(--mono-font) !important;
+    font-size: var(--code-font-size);
+    direction: ltr !important;
 }
 
-svg {
-	position: relative;
-	top: .125em;
-	width: 1em;
-	height: auto;
+/* make long words/inline code not x overflow */
+main {
+    overflow-wrap: break-word;
 }
 
-.hidden {
-	display: none;
+/* make wide tables scroll if they overflow */
+.table-wrapper {
+    overflow-x: auto;
 }
 
-.icon-button {
-	border: none;
-	background: none;
-	cursor: pointer;
-	padding: 1em;
+/* Don't change font size in headers. */
+h1 code, h2 code, h3 code, h4 code, h5 code, h6 code {
+    font-size: unset;
 }
 
-/* void navigation */
+.left { float: left; }
+.right { float: right; }
+.boring { opacity: 0.6; }
+.hide-boring .boring { display: none; }
+.hidden { display: none !important; }
 
-#void-nav {
-	width: 100%;
-	min-height: 50px;
-	background: var(--nav-bg);
-	font-size: 14px;
+h2, h3 { margin-block-start: 2.5em; }
+h4, h5 { margin-block-start: 2em; }
 
-	display: flex;
-	flex-direction: row;
-	flex-wrap: wrap;
-}
-#void-nav a,
-#void-nav button,
-#void-nav label {
-	fill: var(--nav-fg);
-	height: 50px;
-	min-height: 100%;
-	display: block;
-	line-height: 50px;
-	padding: 0 15px;
-	font-size: 1.2em;
-}
-#void-nav ul {
-	list-style: none;
-	margin: 0;
-	padding: 0;
+.header + .header h3,
+.header + .header h4,
+.header + .header h5 {
+    margin-block-start: 1em;
 }
 
-#void-nav ul#nav-right {
-	margin-left: auto;
+h1:target::before,
+h2:target::before,
+h3:target::before,
+h4:target::before,
+h5:target::before,
+h6:target::before {
+    display: inline-block;
+    content: "»";
+    margin-inline-start: -30px;
+    width: 30px;
 }
 
-#void-nav ul li {
-	display: inline-block;
-}
-#void-nav ul li a {
-	color: var(--nav-fg);
-	display: block;
-	padding: 0 15px;
-	line-height: 50px;
-	font-size: 1.2em;
-	text-decoration: none
-}
-#void-nav ul li a:hover,
-#void-nav ul li a:focus,
-#void-nav button:hover,
-#void-nav button:focus,
-#void-nav label:hover,
-#void-nav label:focus {
-	background: #000;
+/* This is broken on Safari as of version 14, but is fixed
+   in Safari Technology Preview 117 which I think will be Safari 14.2.
+   https://bugs.webkit.org/show_bug.cgi?id=218076
+*/
+:target {
+    /* Safari does not support logical properties */
+    scroll-margin-top: calc(var(--menu-bar-height) + 0.5em);
 }
 
-#skip-to-content {
-	position: absolute;
-	left: -999px;
-	top: -999px;
+.page {
+    outline: 0;
+    padding: 0 var(--page-padding);
+    margin-block-start: calc(0px - var(--menu-bar-height)); /* Compensate for the #menu-bar-hover-placeholder */
 }
-
-#skip-to-content:active,
-#skip-to-content:focus {
-	position: relative;
-	left: 0;
-	top: 0;
+.page-wrapper {
+    box-sizing: border-box;
+    background-color: var(--bg);
 }
-
-#icon-theme-light {
-	display: var(--theme-toggle-light);
+.no-js .page-wrapper,
+.js:not(.sidebar-resizing) .page-wrapper {
+    transition: margin-left 0.3s ease, transform 0.3s ease; /* Animation: slide away */
 }
-#icon-theme-dark {
-	display: var(--theme-toggle-dark);
+[dir=rtl] .js:not(.sidebar-resizing) .page-wrapper {
+    transition: margin-right 0.3s ease, transform 0.3s ease; /* Animation: slide away */
 }
 
-/* sidebar  */
-
-.sidebar-hidden #sidebar {
-	display: none;
-}
-#sidebar {
-	padding: .5em;
-	background: var(--sidebar-bg);
-	font-size: 0.875em;
-}
-#sidebar ol {
-	list-style: none;
-	margin: 0;
+.content {
+    overflow-y: auto;
+    padding: 0 5px 50px 5px;
 }
-#sidebar ol.chapter {
-	padding: 0;
-	line-height: 2.2em;
+.content main {
+    margin-inline-start: auto;
+    margin-inline-end: auto;
+    max-width: var(--content-max-width);
 }
-#sidebar ol.section {
-	padding-left: 20px;
-	line-height: 1.9em;
+.content p { line-height: 1.45em; }
+.content ol { line-height: 1.45em; }
+.content ul { line-height: 1.45em; }
+.content a { text-decoration: none; }
+.content a:hover { text-decoration: underline; }
+.content img, .content video { max-width: 100%; }
+.content .header:link,
+.content .header:visited {
+    color: var(--fg);
 }
-#sidebar a {
-	color: var(--sidebar-fg);
-	display: block;
-}
-#sidebar a:hover {
-	color: var(--sidebar-active);
-	text-decoration: none;
-}
-#sidebar a.active {
-	display: block;
-	padding: 0.5em;
-	width: 100%;
-	background-color: var(--sidebar-active);
-	color: var(--bg);
-}
-#sidebar a.active::after {
-	content: "" / " selected";
-}
-
-#sidebar-toggle {
- 	display: none;
-}
-
-/* search */
-
-#searchbar {
-	width: 100%;
-	padding: 10px 16px;
-	margin: 5px 0;
-	border-radius: 3px;
-	border: 1px solid var(--searchbar-border-color);
-}
-#searchresults-header {
-	font-weight: bold;
-	font-size: 1em;
-	padding: 18px 0 0 5px;
-}
-ul#searchresults {
-	list-style: none;
-	padding-left: 20px;
-}
-ul#searchresults li {
-	margin: 10px 0px;
-	padding: 2px;
-	border-radius: 2px;
-}
-ul#searchresults span.teaser {
-	display: block;
-	clear: both;
-	margin: 5px 0 0 20px;
-	font-size: 0.8em;
-}
-
-/* chapter navigation */
-
-#nav-wide-wrapper {
-	max-width: 800px;
-	margin: 0 auto;
-	margin-top: 50px;
-}
-.previous {
-	float: left;
-}
-.next {
-	float: right;
-	right: 15px;
-}
-.nav-chapters {
-	fill: var(--nav-arrow-fg);
-	text-align: center;
-	text-decoration: none;
-	display: block;
-	max-width: 150px;
-	min-width: 90px;
-}
-.nav-chapters:hover {
-	text-decoration: none;
-	fill: var(--nav-fg-hover);
+.content .header:link,
+.content .header:visited:hover {
+    text-decoration: none;
 }
 
-.nav-chapters svg {
-	margin: 0 auto;
-	width: 1.5em;
-}
-.mobile-nav-chapters {
-    fill: var(--nav-arrow-fg);
+table {
+    margin: 0 auto;
+    border-collapse: collapse;
 }
-.mobile-nav-chapters:hover {
-	fill: var(--nav-fg-hover);
+table td {
+    padding: 3px 20px;
+    border: 1px var(--table-border-color) solid;
 }
-
-/* layout */
-
-body {
-	box-sizing: border-box;
+table thead {
+    background: var(--table-header-bg);
 }
-#content {
-	display: flex;
-	flex-direction: row;
-	width: 100%;
+table thead td {
+    font-weight: 700;
+    border: none;
 }
-#page-wrapper {
-	--content-padding: 10px;
-	padding: 0 var(--content-padding);
-	width: calc(100% - var(--content-padding) * 2);
+table thead th {
+    padding: 3px 20px;
 }
-#search-wrapper,
-#page-wrapper main {
-	width: 100%;
-	max-width: 800px;
-	margin: 0 auto;
+table thead tr {
+    border: 1px var(--table-header-bg) solid;
 }
-#sidebar {
-	max-width: 300px;
-	flex-shrink: 0;
+/* Alternate background colors for rows */
+table tbody tr:nth-child(2n) {
+    background: var(--table-alternate-bg);
 }
 
-/* 300px + 800px + 2*90px + 15px */
-@media only screen and (min-width: 1295px) {
-	.sidebar-visible #nav-wide-wrapper {
-		max-width: none;
-		margin: 0;
-	}
-	.sidebar-visible .nav-chapters {
-		background: none;
-		position: fixed;
-		top: 50px;
-		bottom: 0;
-		margin: 0;
-		justify-content: center;
-		align-content: center;
-		display: flex;
-		flex-direction: column;
-	}
-}
-/* 800px + 2*90px + 15px */
-@media only screen and (min-width: 995px) {
-	.sidebar-hidden #nav-wide-wrapper {
-		max-width: none;
-		margin: 0;
-	}
-	.sidebar-hidden .nav-chapters {
-		background: none;
-		position: fixed;
-		top: 50px;
-		bottom: 0;
-		margin: 0;
-		justify-content: center;
-		align-content: center;
-		display: flex;
-		flex-direction: column;
-	}
-	table {
-		display: table;
-	}
+
+blockquote {
+    margin: 20px 0;
+    padding: 0 20px;
+    color: var(--fg);
+    background-color: var(--quote-bg);
+    border-block-start: .1em solid var(--quote-border);
+    border-block-end: .1em solid var(--quote-border);
+}
+
+.warning {
+    margin: 20px;
+    padding: 0 20px;
+    border-inline-start: 2px solid var(--warning-border);
+}
+
+.warning:before {
+    position: absolute;
+    width: 3rem;
+    height: 3rem;
+    margin-inline-start: calc(-1.5rem - 21px);
+    content: "ⓘ";
+    text-align: center;
+    background-color: var(--bg);
+    color: var(--warning-border);
+    font-weight: bold;
+    font-size: 2rem;
+}
+
+blockquote .warning:before {
+    background-color: var(--quote-bg);
+}
+
+kbd {
+    background-color: var(--table-border-color);
+    border-radius: 4px;
+    border: solid 1px var(--theme-popup-border);
+    box-shadow: inset 0 -1px 0 var(--theme-hover);
+    display: inline-block;
+    font-size: var(--code-font-size);
+    font-family: var(--mono-font);
+    line-height: 10px;
+    padding: 4px 5px;
+    vertical-align: middle;
+}
+
+sup {
+    /* Set the line-height for superscript and footnote references so that there
+       isn't an awkward space appearing above lines that contain the footnote.
+
+       See https://github.com/rust-lang/mdBook/pull/2443#discussion_r1813773583
+       for an explanation.
+    */
+    line-height: 0;
+}
+
+:not(.footnote-definition) + .footnote-definition,
+.footnote-definition + :not(.footnote-definition) {
+    margin-block-start: 2em;
+}
+.footnote-definition {
+    font-size: 0.9em;
+    margin: 0.5em 0;
+}
+.footnote-definition p {
+    display: inline;
+}
+
+.tooltiptext {
+    position: absolute;
+    visibility: hidden;
+    color: #fff;
+    background-color: #333;
+    transform: translateX(-50%); /* Center by moving tooltip 50% of its width left */
+    left: -8px; /* Half of the width of the icon */
+    top: -35px;
+    font-size: 0.8em;
+    text-align: center;
+    border-radius: 6px;
+    padding: 5px 8px;
+    margin: 5px;
+    z-index: 1000;
+}
+.tooltipped .tooltiptext {
+    visibility: visible;
+}
+
+.chapter li.part-title {
+    color: var(--sidebar-fg);
+    margin: 5px 0px;
+    font-weight: bold;
+}
+
+.result-no-output {
+    font-style: italic;
 }
diff --git a/src/theme/css/print.css b/src/theme/css/print.css
index 2970c2b6c..80ec3a544 100644
--- a/src/theme/css/print.css
+++ b/src/theme/css/print.css
@@ -1,15 +1,14 @@
 
 #sidebar,
 #menu-bar,
-#void-nav,
 .nav-chapters,
 .mobile-nav-chapters {
     display: none;
 }
 
 #page-wrapper.page-wrapper {
-    transform: none;
-    margin-left: 0px;
+    transform: none !important;
+    margin-inline-start: 0px;
     overflow-y: initial;
 }
 
@@ -24,19 +23,7 @@
 }
 
 code {
-    background-color: #ddd;
-    border-radius: 5px;
-
-    /* Force background to be printed in Chrome */
-    -webkit-print-color-adjust: exact;
-}
-
-
-pre {
-    background-color: #ddd;
-
-    /* Force background to be printed in Chrome */
-    -webkit-print-color-adjust: exact;
+    direction: ltr !important;
 }
 
 pre > .buttons {
@@ -58,22 +45,6 @@ pre, code {
     white-space: pre-wrap;
 }
 
-svg {
+.fa {
     display: none !important;
 }
-
-table {
-    color: black;
-    border-color: black;
-    background-color: unset;
-}
-
-table thead tr {
-    color: black;
-    background-color: unset;
-}
-
-table tbody tr {
-    background-color: unset;
-}
-
diff --git a/src/theme/css/variables.css b/src/theme/css/variables.css
index ea306becc..12d1db7a3 100644
--- a/src/theme/css/variables.css
+++ b/src/theme/css/variables.css
@@ -2,106 +2,308 @@
 /* Globals */
 
 :root {
-	--sidebar-width: 300px;
-	--page-padding: 15px;
-	--content-max-width: 750px;
-	--menu-bar-height: 50px;
-	--void-green: #478061;
-	--void-dark-green: #62b086;
-	--void-light: #fafafa;
-	--void-dark: #252525;
+    --sidebar-width: 300px;
+    --sidebar-resize-indicator-width: 8px;
+    --sidebar-resize-indicator-space: 2px;
+    --page-padding: 15px;
+    --content-max-width: 750px;
+    --menu-bar-height: 50px;
+    --mono-font: "Source Code Pro", Consolas, "Ubuntu Mono", Menlo, "DejaVu Sans Mono", monospace, monospace;
+    --code-font-size: 0.875em /* please adjust the ace font size accordingly in editor.js */
 }
 
 /* Themes */
 
-.void-light {
-	--bg: #ffffff;
-	--fg: #333;
+.ayu {
+    --bg: hsl(210, 25%, 8%);
+    --fg: #c5c5c5;
 
-	--sidebar-bg: var(--void-light);
-	--sidebar-fg: var(--fg);
-	--sidebar-active: var(--links);
+    --sidebar-bg: #14191f;
+    --sidebar-fg: #c8c9db;
+    --sidebar-non-existant: #5c6773;
+    --sidebar-active: #ffb454;
+    --sidebar-spacer: #2d334f;
 
-	--nav-bg: var(--void-green);
-	--nav-fg: var(--bg);
-	--nav-arrow-fg: var(--fg);
-	--nav-fg-hover: #000;
+    --scrollbar: var(--sidebar-fg);
 
-	--scrollbar: var(--sidebar-fg);
+    --icons: #737480;
+    --icons-hover: #b7b9cc;
 
-	--icons: #737480;
-	--icons-hover: #b7b9cc;
+    --links: #0096cf;
 
-	--links: var(--void-green);
-	--links-hover: var(--fg);
+    --inline-code-color: #ffb454;
 
-	--inline-code-color: #fdf6e3;
-	--code-border: #ccc;
+    --theme-popup-bg: #14191f;
+    --theme-popup-border: #5c6773;
+    --theme-hover: #191f26;
 
-	--theme-toggle-light: none;
-	--theme-toggle-dark: inherit;
+    --quote-bg: hsl(226, 15%, 17%);
+    --quote-border: hsl(226, 15%, 22%);
 
-	--quote-bg: #ebf4ef;
-	--quote-border: #d1e6da;
-	--quote-code-bg: var(--inline-code-color);
+    --warning-border: #ff8e00;
 
-	--table-border-color: var(--void-green);
-	--table-header-bg: var(--void-green);
-	--table-header-fg: #fff;
-	--table-alternate-bg: var(--void-light);
+    --table-border-color: hsl(210, 25%, 13%);
+    --table-header-bg: hsl(210, 25%, 28%);
+    --table-alternate-bg: hsl(210, 25%, 11%);
 
-	--searchbar-border-color: #aaa;
-	--searchbar-bg: var(--bg);
-	--searchbar-fg: var(--fg);
-	--searchbar-shadow-color: #d4c89f;
-	--searchresults-header-fg: #666;
-	--searchresults-border-color: #888;
-	--searchresults-li-bg: #252932;
-	--search-mark-bg: #e3b171;
+    --searchbar-border-color: #848484;
+    --searchbar-bg: #424242;
+    --searchbar-fg: #fff;
+    --searchbar-shadow-color: #d4c89f;
+    --searchresults-header-fg: #666;
+    --searchresults-border-color: #888;
+    --searchresults-li-bg: #252932;
+    --search-mark-bg: #e3b171;
+
+    --color-scheme: dark;
+
+    /* Same as `--icons` */
+    --copy-button-filter: invert(45%) sepia(6%) saturate(621%) hue-rotate(198deg) brightness(99%) contrast(85%);
+    /* Same as `--sidebar-active` */
+    --copy-button-filter-hover: invert(68%) sepia(55%) saturate(531%) hue-rotate(341deg) brightness(104%) contrast(101%);
+}
+
+.coal {
+    --bg: hsl(200, 7%, 8%);
+    --fg: #98a3ad;
+
+    --sidebar-bg: #292c2f;
+    --sidebar-fg: #a1adb8;
+    --sidebar-non-existant: #505254;
+    --sidebar-active: #3473ad;
+    --sidebar-spacer: #393939;
+
+    --scrollbar: var(--sidebar-fg);
+
+    --icons: #43484d;
+    --icons-hover: #b3c0cc;
+
+    --links: #2b79a2;
+
+    --inline-code-color: #c5c8c6;
+
+    --theme-popup-bg: #141617;
+    --theme-popup-border: #43484d;
+    --theme-hover: #1f2124;
+
+    --quote-bg: hsl(234, 21%, 18%);
+    --quote-border: hsl(234, 21%, 23%);
+
+    --warning-border: #ff8e00;
+
+    --table-border-color: hsl(200, 7%, 13%);
+    --table-header-bg: hsl(200, 7%, 28%);
+    --table-alternate-bg: hsl(200, 7%, 11%);
+
+    --searchbar-border-color: #aaa;
+    --searchbar-bg: #b7b7b7;
+    --searchbar-fg: #000;
+    --searchbar-shadow-color: #aaa;
+    --searchresults-header-fg: #666;
+    --searchresults-border-color: #98a3ad;
+    --searchresults-li-bg: #2b2b2f;
+    --search-mark-bg: #355c7d;
+
+    --color-scheme: dark;
+
+    /* Same as `--icons` */
+    --copy-button-filter: invert(26%) sepia(8%) saturate(575%) hue-rotate(169deg) brightness(87%) contrast(82%);
+    /* Same as `--sidebar-active` */
+    --copy-button-filter-hover: invert(36%) sepia(70%) saturate(503%) hue-rotate(167deg) brightness(98%) contrast(89%);
+}
+
+.light, html:not(.js) {
+    --bg: hsl(0, 0%, 100%);
+    --fg: hsl(0, 0%, 0%);
+
+    --sidebar-bg: #fafafa;
+    --sidebar-fg: hsl(0, 0%, 0%);
+    --sidebar-non-existant: #aaaaaa;
+    --sidebar-active: #1f1fff;
+    --sidebar-spacer: #f4f4f4;
+
+    --scrollbar: #8F8F8F;
+
+    --icons: #747474;
+    --icons-hover: #000000;
+
+    --links: #20609f;
+
+    --inline-code-color: #301900;
+
+    --theme-popup-bg: #fafafa;
+    --theme-popup-border: #cccccc;
+    --theme-hover: #e6e6e6;
+
+    --quote-bg: hsl(197, 37%, 96%);
+    --quote-border: hsl(197, 37%, 91%);
+
+    --warning-border: #ff8e00;
+
+    --table-border-color: hsl(0, 0%, 95%);
+    --table-header-bg: hsl(0, 0%, 80%);
+    --table-alternate-bg: hsl(0, 0%, 97%);
+
+    --searchbar-border-color: #aaa;
+    --searchbar-bg: #fafafa;
+    --searchbar-fg: #000;
+    --searchbar-shadow-color: #aaa;
+    --searchresults-header-fg: #666;
+    --searchresults-border-color: #888;
+    --searchresults-li-bg: #e4f2fe;
+    --search-mark-bg: #a2cff5;
+
+    --color-scheme: light;
+
+    /* Same as `--icons` */
+    --copy-button-filter: invert(45.49%);
+    /* Same as `--sidebar-active` */
+    --copy-button-filter-hover: invert(14%) sepia(93%) saturate(4250%) hue-rotate(243deg) brightness(99%) contrast(130%);
 }
 
-.void-dark {
-	--bg: #222;
-	--fg: #ccc;
+.navy {
+    --bg: hsl(226, 23%, 11%);
+    --fg: #bcbdd0;
+
+    --sidebar-bg: #282d3f;
+    --sidebar-fg: #c8c9db;
+    --sidebar-non-existant: #505274;
+    --sidebar-active: #2b79a2;
+    --sidebar-spacer: #2d334f;
+
+    --scrollbar: var(--sidebar-fg);
+
+    --icons: #737480;
+    --icons-hover: #b7b9cc;
+
+    --links: #2b79a2;
+
+    --inline-code-color: #c5c8c6;
+
+    --theme-popup-bg: #161923;
+    --theme-popup-border: #737480;
+    --theme-hover: #282e40;
+
+    --quote-bg: hsl(226, 15%, 17%);
+    --quote-border: hsl(226, 15%, 22%);
+
+    --warning-border: #ff8e00;
+
+    --table-border-color: hsl(226, 23%, 16%);
+    --table-header-bg: hsl(226, 23%, 31%);
+    --table-alternate-bg: hsl(226, 23%, 14%);
+
+    --searchbar-border-color: #aaa;
+    --searchbar-bg: #aeaec6;
+    --searchbar-fg: #000;
+    --searchbar-shadow-color: #aaa;
+    --searchresults-header-fg: #5f5f71;
+    --searchresults-border-color: #5c5c68;
+    --searchresults-li-bg: #242430;
+    --search-mark-bg: #a2cff5;
+
+    --color-scheme: dark;
+
+    /* Same as `--icons` */
+    --copy-button-filter: invert(51%) sepia(10%) saturate(393%) hue-rotate(198deg) brightness(86%) contrast(87%);
+    /* Same as `--sidebar-active` */
+    --copy-button-filter-hover: invert(46%) sepia(20%) saturate(1537%) hue-rotate(156deg) brightness(85%) contrast(90%);
+}
+
+.rust {
+    --bg: hsl(60, 9%, 87%);
+    --fg: #262625;
+
+    --sidebar-bg: #3b2e2a;
+    --sidebar-fg: #c8c9db;
+    --sidebar-non-existant: #505254;
+    --sidebar-active: #e69f67;
+    --sidebar-spacer: #45373a;
+
+    --scrollbar: var(--sidebar-fg);
+
+    --icons: #737480;
+    --icons-hover: #262625;
+
+    --links: #2b79a2;
+
+    --inline-code-color: #6e6b5e;
+
+    --theme-popup-bg: #e1e1db;
+    --theme-popup-border: #b38f6b;
+    --theme-hover: #99908a;
+
+    --quote-bg: hsl(60, 5%, 75%);
+    --quote-border: hsl(60, 5%, 70%);
+
+    --warning-border: #ff8e00;
+
+    --table-border-color: hsl(60, 9%, 82%);
+    --table-header-bg: #b3a497;
+    --table-alternate-bg: hsl(60, 9%, 84%);
+
+    --searchbar-border-color: #aaa;
+    --searchbar-bg: #fafafa;
+    --searchbar-fg: #000;
+    --searchbar-shadow-color: #aaa;
+    --searchresults-header-fg: #666;
+    --searchresults-border-color: #888;
+    --searchresults-li-bg: #dec2a2;
+    --search-mark-bg: #e69f67;
+
+    /* Same as `--icons` */
+    --copy-button-filter: invert(51%) sepia(10%) saturate(393%) hue-rotate(198deg) brightness(86%) contrast(87%);
+    /* Same as `--sidebar-active` */
+    --copy-button-filter-hover: invert(77%) sepia(16%) saturate(1798%) hue-rotate(328deg) brightness(98%) contrast(83%);
+}
+
+@media (prefers-color-scheme: dark) {
+    html:not(.js) {
+        --bg: hsl(200, 7%, 8%);
+        --fg: #98a3ad;
+
+        --sidebar-bg: #292c2f;
+        --sidebar-fg: #a1adb8;
+        --sidebar-non-existant: #505254;
+        --sidebar-active: #3473ad;
+        --sidebar-spacer: #393939;
+
+        --scrollbar: var(--sidebar-fg);
 
-	--sidebar-bg: #252525;
-	--sidebar-fg: var(--fg);
-	--sidebar-active: var(--links);
+        --icons: #43484d;
+        --icons-hover: #b3c0cc;
 
-	--nav-bg: #295340;
-	--nav-fg: var(--fg);
-	--nav-arrow-fg: var(--fg);
-	--nav-fg-hover: #fff;
+        --links: #2b79a2;
 
-	--scrollbar: var(--sidebar-fg);
+        --inline-code-color: #c5c8c6;
 
-	--icons: #737480;
-	--icons-hover: #b7b9cc;
+        --theme-popup-bg: #141617;
+        --theme-popup-border: #43484d;
+        --theme-hover: #1f2124;
 
-	--links: var(--void-dark-green);
-	--links-hover: var(--fg);
+        --quote-bg: hsl(234, 21%, 18%);
+        --quote-border: hsl(234, 21%, 23%);
 
-	--inline-code-color: #353535;
-	--code-border: #111;
+        --warning-border: #ff8e00;
 
-	--theme-toggle-light: inherit;
-	--theme-toggle-dark: none;
+        --table-border-color: hsl(200, 7%, 13%);
+        --table-header-bg: hsl(200, 7%, 28%);
+        --table-alternate-bg: hsl(200, 7%, 11%);
 
-	--quote-bg: #293d35;
-	--quote-border: #22362e;
-	--quote-code-bg: #2a2a2a;
+        --searchbar-border-color: #aaa;
+        --searchbar-bg: #b7b7b7;
+        --searchbar-fg: #000;
+        --searchbar-shadow-color: #aaa;
+        --searchresults-header-fg: #666;
+        --searchresults-border-color: #98a3ad;
+        --searchresults-li-bg: #2b2b2f;
+        --search-mark-bg: #355c7d;
 
-	--table-border-color: var(--void-green);
-	--table-header-bg: var(--void-green);
-	--table-header-fg: #fff;
-	--table-alternate-bg: #2c2c2c;
+        --color-scheme: dark;
 
-	--searchbar-border-color: #aaa;
-	--searchbar-bg: var(--bg);
-	--searchbar-fg: var(--fg);
-	--searchbar-shadow-color: #d4c89f;
-	--searchresults-header-fg: #666;
-	--searchresults-border-color: #888;
-	--searchresults-li-bg: #252932;
-	--search-mark-bg: #e3b171;
+        /* Same as `--icons` */
+        --copy-button-filter: invert(26%) sepia(8%) saturate(575%) hue-rotate(169deg) brightness(87%) contrast(82%);
+        /* Same as `--sidebar-active` */
+        --copy-button-filter-hover: invert(36%) sepia(70%) saturate(503%) hue-rotate(167deg) brightness(98%) contrast(89%);
+    }
 }
diff --git a/src/theme/index.hbs b/src/theme/index.hbs
index 6090ed837..7775f262d 100644
--- a/src/theme/index.hbs
+++ b/src/theme/index.hbs
@@ -1,253 +1,325 @@
 <!DOCTYPE HTML>
-<html lang="{{ language }}" class="sidebar-visible no-js {{ default_theme }}">
-	<head>
-		<!-- Book generated using mdBook -->
-		<meta charset="UTF-8">
-		<title>{{ title }}</title>
-		{{#if is_print }}
-		<meta name="robots" content="noindex" />
-		{{/if}}
-		{{#if base_url}}
-		<base href="{{ base_url }}">
-		{{/if}}
-
-		<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
-		<meta name="description" content="{{ description }}">
-		<meta name="viewport" content="width=device-width, initial-scale=1">
-		<meta name="theme-color" content="#ffffff" />
-
-		<link rel="shortcut icon" href="{{ path_to_root }}favicon.png">
-		<link rel="stylesheet" href="{{ path_to_root }}css/variables.css">
-		<link rel="stylesheet" href="{{ path_to_root }}css/general.css">
-		<link rel="stylesheet" href="{{ path_to_root }}css/chrome.css">
-		<link rel="stylesheet" href="{{ path_to_root }}css/print.css" media="print">
-	</head>
-	<body>
-		<!-- Provide site root to javascript -->
-		<script type="text/javascript">
-			var path_to_root = "{{ path_to_root }}";
-			var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "{{ preferred_dark_theme }}" : "{{ default_theme }}";
-		</script>
-		<!-- Work around some values being stored in localStorage wrapped in quotes -->
-		<script type="text/javascript">
-			try {
-				var theme = localStorage.getItem('mdbook-theme');
-				var sidebar = localStorage.getItem('mdbook-sidebar');
-
-				if (theme.startsWith('"') && theme.endsWith('"')) {
-					localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
-				}
-				if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
-					localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
-				}
-			} catch (e) { }
-		</script>
-
-		<!-- Set the theme before any content is loaded, prevents flash -->
-		<script type="text/javascript">
-			var theme;
-			try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
-			if (theme === null || theme === undefined) { theme = default_theme; }
-			var html = document.querySelector('html');
-			html.classList.remove('no-js')
-			html.classList.remove('{{ default_theme }}')
-			html.classList.add(theme);
-			html.classList.add('js');
-		</script>
-
-		<!-- Hide / unhide sidebar before it is displayed -->
-		<script type="text/javascript">
-			var html = document.querySelector('html');
-			var sidebar = 'hidden';
-			if (document.body.clientWidth >= 1080) {
-				try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
-				sidebar = sidebar || 'visible';
-			}
-			html.classList.remove('sidebar-visible');
-			html.classList.add("sidebar-" + sidebar);
-		</script>
-
-		<header>
-			<nav id="void-nav">
-				<ul>
-					<li><a id="skip-to-content" tabindex="1" href="#main">Skip to content</a></li>
-					<li>
-						<a id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
-							<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20">
-								<path d="M1 3v2h18V3zm0 8h18V9H1zm0 6h18v-2H1z"/>
-							</svg>
-						</a>
-					</li>
-					<li>
-						<a id="theme-toggle" class="icon-button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
-							<svg id="icon-theme-light" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
-								<path d="M256 159.1c-53.02 0-95.1 42.98-95.1 95.1S202.1 351.1 256 351.1s95.1-42.98 95.1-95.1S309 159.1 256 159.1zM509.3 347L446.1 255.1l63.15-91.01c6.332-9.125 1.104-21.74-9.826-23.72l-109-19.7l-19.7-109c-1.975-10.93-14.59-16.16-23.72-9.824L256 65.89L164.1 2.736c-9.125-6.332-21.74-1.107-23.72 9.824L121.6 121.6L12.56 141.3C1.633 143.2-3.596 155.9 2.736 164.1L65.89 256l-63.15 91.01c-6.332 9.125-1.105 21.74 9.824 23.72l109 19.7l19.7 109c1.975 10.93 14.59 16.16 23.72 9.824L256 446.1l91.01 63.15c9.127 6.334 21.75 1.107 23.72-9.822l19.7-109l109-19.7C510.4 368.8 515.6 356.1 509.3 347zM256 383.1c-70.69 0-127.1-57.31-127.1-127.1c0-70.69 57.31-127.1 127.1-127.1s127.1 57.3 127.1 127.1C383.1 326.7 326.7 383.1 256 383.1z"/>
-							</svg>
-							<svg id="icon-theme-dark" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
-								<path d="M283.211 512c78.962 0 151.079-35.925 198.857-94.792 7.068-8.708-.639-21.43-11.562-19.35-124.203 23.654-238.262-71.576-238.262-196.954 0-72.222 38.662-138.635 101.498-174.394 9.686-5.512 7.25-20.197-3.756-22.23A258.156 258.156 0 0 0 283.211 0c-141.309 0-256 114.511-256 256 0 141.309 114.511 256 256 256z"/>
-							</svg>
-						</a>
-					</li>
-					{{#if print_enable}}
-					<li>
-						<a href="{{ path_to_root }}print.html" title="Print this book" aria-label="Print this book">
-							<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
-								<path d="M448 192V77.25c0-8.49-3.37-16.62-9.37-22.63L393.37 9.37c-6-6-14.14-9.37-22.63-9.37H96C78.33 0 64 14.33 64 32v160c-35.35 0-64 28.65-64 64v112c0 8.84 7.16 16 16 16h48v96c0 17.67 14.33 32 32 32h320c17.67 0 32-14.33 32-32v-96h48c8.84 0 16-7.16 16-16V256c0-35.35-28.65-64-64-64zm-64 256H128v-96h256v96zm0-224H128V64h192v48c0 8.84 7.16 16 16 16h48v96zm48 72c-13.25 0-24-10.75-24-24 0-13.26 10.75-24 24-24s24 10.74 24 24c0 13.25-10.75 24-24 24z"/>
-							</svg>
-						</a>
-					</li>
-					{{/if}}
-					{{#if git_repository_edit_url}}
-					<li>
-						<a href="{{git_repository_edit_url}}" title="Suggest an edit" aria-label="Suggest an edit">
-							<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512">
-								<path d="M402.6 83.2l90.2 90.2c3.8 3.8 3.8 10 0 13.8L274.4 405.6l-92.8 10.3c-12.4 1.4-22.9-9.1-21.5-21.5l10.3-92.8L388.8 83.2c3.8-3.8 10-3.8 13.8 0zm162-22.9l-48.8-48.8c-15.2-15.2-39.9-15.2-55.2 0l-35.4 35.4c-3.8 3.8-3.8 10 0 13.8l90.2 90.2c3.8 3.8 10 3.8 13.8 0l35.4-35.4c15.2-15.3 15.2-40 0-55.2zM384 346.2V448H64V128h229.8c3.2 0 6.2-1.3 8.5-3.5l40-40c7.6-7.6 2.2-20.5-8.5-20.5H48C21.5 64 0 85.5 0 112v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V306.2c0-10.7-12.9-16-20.5-8.5l-40 40c-2.2 2.3-3.5 5.3-3.5 8.5z"/>
-							</svg>
-						</a>
-					</li>
-					{{/if}}
-					{{#if search_enabled}}
-					<li>
-						<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
-							<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20">
-								<path d="M7.5 13c3.04 0 5.5-2.46 5.5-5.5S10.54 2 7.5 2 2 4.46 2 7.5 4.46 13 7.5 13zm4.55.46C10.79 14.43 9.21 15 7.5 15 3.36 15 0 11.64 0 7.5S3.36 0 7.5 0C11.64 0 15 3.36 15 7.5c0 1.71-.57 3.29-1.54 4.55l6.49 6.49-1.41 1.41-6.49-6.49z"/>
-							</svg>
-						</button>
-					</li>
-					<noscript>
-						<li class="js-unavailable">Search functionality requires JavaScript</li>
-					</noscript>
-					{{/if}}
-				</ul>
-				<ul id="nav-right">
-					<li><a href="https://www.voidlinux.org">Home</a></li>
-					<li><a href="https://www.voidlinux.org/news/">News</a></li>
-					<li><a href="https://www.voidlinux.org/download/">Download</a></li>
-					<li><a href="https://www.voidlinux.org/packages/">Packages</a></li>
-					<li><a href="https://docs.voidlinux.org">Documentation</a></li>
-					<li><a href="https://man.voidlinux.org/">Manual Pages</a></li>
-					<li><a href="https://github.com/void-linux">GitHub</a></li>
-				</ul>
-			</nav>
-		</header>
-
-		<div id="content">
-			<!-- Hide / unhide sidebar before it is displayed -->
-			<script type="text/javascript">
-				var html = document.querySelector('html');
-				var sidebar = 'hidden';
-				if (document.body.clientWidth >= 1080) {
-					try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
-					sidebar = sidebar || 'visible';
-				}
-				html.classList.remove('sidebar-visible');
-				html.classList.add("sidebar-" + sidebar);
-			</script>
-
-			<nav id="sidebar" aria-label="Table of contents">
-				{{#toc}}{{/toc}}
-			</nav>
-
-			<div id="page-wrapper" class="page-wrapper">
-
-
-					{{#if search_enabled}}
-					<div id="search-wrapper" class="hidden">
-						<form id="searchbar-outer" class="searchbar-outer">
-							<input type="search" name="search" id="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
-						</form>
-						<div id="searchresults-outer" class="searchresults-outer hidden">
-							<div id="searchresults-header" class="searchresults-header"></div>
-							<ul id="searchresults">
-							</ul>
-						</div>
-					</div>
-					{{/if}}
-
-					<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
-					<script type="text/javascript">
-						document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
-						document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
-						Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
-							link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
-						});
-					</script>
-
-					<main id="main">
-						{{{ content }}}
-					</main>
-
-					<nav class="nav-wrapper" aria-label="Page navigation">
-						<!-- Mobile navigation buttons -->
-						{{#previous}}
-							<a rel="prev" href="{{ path_to_root }}{{link}}" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
-								<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20">
-									<path d="M4 10l9 9 1.4-1.5L7 10l7.4-7.5L13 1z"/>
-								</svg>
-							</a>
-						{{/previous}}
-
-						{{#next}}
-							<a rel="next" href="{{ path_to_root }}{{link}}" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
-								<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20">
-									<path d="M7 1L5.6 2.5 13 10l-7.4 7.5L7 19l9-9z"/>
-								</svg>
-							</a>
-						{{/next}}
-
-						<div style="clear: both"></div>
-					</nav>
-
-				<nav class="nav-wide-wrapper" aria-label="Page navigation">
-					{{#previous}}
-						<a rel="prev" href="{{ path_to_root }}{{link}}" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
-							<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20">
-								<path d="M4 10l9 9 1.4-1.5L7 10l7.4-7.5L13 1z"/>
-							</svg>
-						</a>
-					{{/previous}}
-
-					{{#next}}
-						<a rel="next" href="{{ path_to_root }}{{link}}" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
-							<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20">
-								<path d="M7 1L5.6 2.5 13 10l-7.4 7.5L7 19l9-9z"/>
-							</svg>
-						</a>
-					{{/next}}
-				</nav>
-			</div>
-		</div>
-
-		{{#if livereload}}
-		<!-- Livereload script (if served using the cli tool) -->
-		<script type="text/javascript">
-			var socket = new WebSocket("{{{livereload}}}");
-			socket.onmessage = function (event) {
-				if (event.data === "reload") {
-					socket.close();
-					location.reload(true); // force reload from server (not from cache)
-				}
-			};
-
-			window.onbeforeunload = function() {
-				socket.close();
-			}
-		</script>
-		{{/if}}
-
-		{{#if search_js}}
-		<script src="{{ path_to_root }}elasticlunr.min.js" type="text/javascript" charset="utf-8"></script>
-		<script src="{{ path_to_root }}mark.min.js" type="text/javascript" charset="utf-8"></script>
-		<script src="{{ path_to_root }}searcher.js" type="text/javascript" charset="utf-8"></script>
-		{{/if}}
-
-		<script src="{{ path_to_root }}book.js" type="text/javascript" charset="utf-8"></script>
-		{{#if is_print}}
-		<script type="text/javascript">
-		window.addEventListener('load', function() {
-			window.setTimeout(window.print, 100);
-		});
-		</script>
-		{{/if}}
-	</body>
+<html lang="{{ language }}" class="{{ default_theme }} sidebar-visible" dir="{{ text_direction }}">
+    <head>
+        <!-- Book generated using mdBook -->
+        <meta charset="UTF-8">
+        <title>{{ title }}</title>
+        {{#if is_print }}
+        <meta name="robots" content="noindex">
+        {{/if}}
+        {{#if base_url}}
+        <base href="{{ base_url }}">
+        {{/if}}
+
+
+        <!-- Custom HTML head -->
+        {{> head}}
+
+        <meta name="description" content="{{ description }}">
+        <meta name="viewport" content="width=device-width, initial-scale=1">
+        <meta name="theme-color" content="#ffffff">
+
+        {{#if favicon_svg}}
+        <link rel="icon" href="{{ path_to_root }}favicon.svg">
+        {{/if}}
+        {{#if favicon_png}}
+        <link rel="shortcut icon" href="{{ path_to_root }}favicon.png">
+        {{/if}}
+        <link rel="stylesheet" href="{{ path_to_root }}css/variables.css">
+        <link rel="stylesheet" href="{{ path_to_root }}css/general.css">
+        <link rel="stylesheet" href="{{ path_to_root }}css/chrome.css">
+        {{#if print_enable}}
+        <link rel="stylesheet" href="{{ path_to_root }}css/print.css" media="print">
+        {{/if}}
+
+        <!-- Fonts -->
+        <link rel="stylesheet" href="{{ path_to_root }}FontAwesome/css/font-awesome.css">
+        {{#if copy_fonts}}
+        <link rel="stylesheet" href="{{ path_to_root }}fonts/fonts.css">
+        {{/if}}
+
+        <!-- Highlight.js Stylesheets -->
+        <link rel="stylesheet" href="{{ path_to_root }}highlight.css">
+        <link rel="stylesheet" href="{{ path_to_root }}tomorrow-night.css">
+        <link rel="stylesheet" href="{{ path_to_root }}ayu-highlight.css">
+
+        <!-- Custom theme stylesheets -->
+        {{#each additional_css}}
+        <link rel="stylesheet" href="{{ ../path_to_root }}{{ this }}">
+        {{/each}}
+
+        {{#if mathjax_support}}
+        <!-- MathJax -->
+        <script async src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
+        {{/if}}
+
+        <!-- Provide site root to javascript -->
+        <script>
+            var path_to_root = "{{ path_to_root }}";
+            var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "{{ preferred_dark_theme }}" : "{{ default_theme }}";
+        </script>
+        <!-- Start loading toc.js asap -->
+        <script src="{{ path_to_root }}toc.js"></script>
+    </head>
+    <body>
+    <div id="body-container">
+        <!-- Work around some values being stored in localStorage wrapped in quotes -->
+        <script>
+            try {
+                var theme = localStorage.getItem('mdbook-theme');
+                var sidebar = localStorage.getItem('mdbook-sidebar');
+
+                if (theme.startsWith('"') && theme.endsWith('"')) {
+                    localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
+                }
+
+                if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
+                    localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
+                }
+            } catch (e) { }
+        </script>
+
+        <!-- Set the theme before any content is loaded, prevents flash -->
+        <script>
+            var theme;
+            try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
+            if (theme === null || theme === undefined) { theme = default_theme; }
+            const html = document.documentElement;
+            html.classList.remove('{{ default_theme }}')
+            html.classList.add(theme);
+            html.classList.add("js");
+        </script>
+
+        <input type="checkbox" id="sidebar-toggle-anchor" class="hidden">
+
+        <!-- Hide / unhide sidebar before it is displayed -->
+        <script>
+            var sidebar = null;
+            var sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
+            if (document.body.clientWidth >= 1080) {
+                try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
+                sidebar = sidebar || 'visible';
+            } else {
+                sidebar = 'hidden';
+            }
+            sidebar_toggle.checked = sidebar === 'visible';
+            html.classList.remove('sidebar-visible');
+            html.classList.add("sidebar-" + sidebar);
+        </script>
+
+        <nav id="sidebar" class="sidebar" aria-label="Table of contents">
+            <!-- populated by js -->
+            <mdbook-sidebar-scrollbox class="sidebar-scrollbox"></mdbook-sidebar-scrollbox>
+            <noscript>
+                <iframe class="sidebar-iframe-outer" src="{{ path_to_root }}toc.html"></iframe>
+            </noscript>
+            <div id="sidebar-resize-handle" class="sidebar-resize-handle">
+                <div class="sidebar-resize-indicator"></div>
+            </div>
+        </nav>
+
+        <div id="page-wrapper" class="page-wrapper">
+
+            <div class="page">
+                {{> header}}
+                <div id="menu-bar-hover-placeholder"></div>
+                <div id="menu-bar" class="menu-bar sticky">
+                    <div class="left-buttons">
+                        <label id="sidebar-toggle" class="icon-button" for="sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
+                            <i class="fa fa-bars"></i>
+                        </label>
+                        <button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
+                            <i class="fa fa-paint-brush"></i>
+                        </button>
+                        <ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
+                            <li role="none"><button role="menuitem" class="theme" id="light">Light</button></li>
+                            <li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
+                            <li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
+                            <li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
+                            <li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
+                        </ul>
+                        {{#if search_enabled}}
+                        <button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
+                            <i class="fa fa-search"></i>
+                        </button>
+                        {{/if}}
+                    </div>
+
+                    <h1 class="menu-title">{{ book_title }}</h1>
+
+                    <div class="right-buttons">
+                        {{#if print_enable}}
+                        <a href="{{ path_to_root }}print.html" title="Print this book" aria-label="Print this book">
+                            <i id="print-button" class="fa fa-print"></i>
+                        </a>
+                        {{/if}}
+                        {{#if git_repository_url}}
+                        <a href="{{git_repository_url}}" title="Git repository" aria-label="Git repository">
+                            <i id="git-repository-button" class="fa {{git_repository_icon}}"></i>
+                        </a>
+                        {{/if}}
+                        {{#if git_repository_edit_url}}
+                        <a href="{{git_repository_edit_url}}" title="Suggest an edit" aria-label="Suggest an edit">
+                            <i id="git-edit-button" class="fa fa-edit"></i>
+                        </a>
+                        {{/if}}
+
+                    </div>
+                </div>
+
+                {{#if search_enabled}}
+                <div id="search-wrapper" class="hidden">
+                    <form id="searchbar-outer" class="searchbar-outer">
+                        <input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
+                    </form>
+                    <div id="searchresults-outer" class="searchresults-outer hidden">
+                        <div id="searchresults-header" class="searchresults-header"></div>
+                        <ul id="searchresults">
+                        </ul>
+                    </div>
+                </div>
+                {{/if}}
+
+                <!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
+                <script>
+                    document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
+                    document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
+                    Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
+                        link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
+                    });
+                </script>
+
+                <div id="content" class="content">
+                    <main>
+                        {{{ content }}}
+                    </main>
+
+                    <nav class="nav-wrapper" aria-label="Page navigation">
+                        <!-- Mobile navigation buttons -->
+                        {{#previous}}
+                            <a rel="prev" href="{{ path_to_root }}{{link}}" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
+                                <i class="fa fa-angle-left"></i>
+                            </a>
+                        {{/previous}}
+
+                        {{#next}}
+                            <a rel="next prefetch" href="{{ path_to_root }}{{link}}" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
+                                <i class="fa fa-angle-right"></i>
+                            </a>
+                        {{/next}}
+
+                        <div style="clear: both"></div>
+                    </nav>
+                </div>
+            </div>
+
+            <nav class="nav-wide-wrapper" aria-label="Page navigation">
+                {{#previous}}
+                    <a rel="prev" href="{{ path_to_root }}{{link}}" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
+                        <i class="fa fa-angle-left"></i>
+                    </a>
+                {{/previous}}
+
+                {{#next}}
+                    <a rel="next prefetch" href="{{ path_to_root }}{{link}}" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
+                        <i class="fa fa-angle-right"></i>
+                    </a>
+                {{/next}}
+            </nav>
+
+        </div>
+
+        {{#if live_reload_endpoint}}
+        <!-- Livereload script (if served using the cli tool) -->
+        <script>
+            const wsProtocol = location.protocol === 'https:' ? 'wss:' : 'ws:';
+            const wsAddress = wsProtocol + "//" + location.host + "/" + "{{{live_reload_endpoint}}}";
+            const socket = new WebSocket(wsAddress);
+            socket.onmessage = function (event) {
+                if (event.data === "reload") {
+                    socket.close();
+                    location.reload();
+                }
+            };
+
+            window.onbeforeunload = function() {
+                socket.close();
+            }
+        </script>
+        {{/if}}
+
+        {{#if google_analytics}}
+        <!-- Google Analytics Tag -->
+        <script>
+            var localAddrs = ["localhost", "127.0.0.1", ""];
+
+            // make sure we don't activate google analytics if the developer is
+            // inspecting the book locally...
+            if (localAddrs.indexOf(document.location.hostname) === -1) {
+                (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
+                (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
+                m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
+                })(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
+
+                ga('create', '{{google_analytics}}', 'auto');
+                ga('send', 'pageview');
+            }
+        </script>
+        {{/if}}
+
+        {{#if playground_line_numbers}}
+        <script>
+            window.playground_line_numbers = true;
+        </script>
+        {{/if}}
+
+        {{#if playground_copyable}}
+        <script>
+            window.playground_copyable = true;
+        </script>
+        {{/if}}
+
+        {{#if playground_js}}
+        <script src="{{ path_to_root }}ace.js"></script>
+        <script src="{{ path_to_root }}editor.js"></script>
+        <script src="{{ path_to_root }}mode-rust.js"></script>
+        <script src="{{ path_to_root }}theme-dawn.js"></script>
+        <script src="{{ path_to_root }}theme-tomorrow_night.js"></script>
+        {{/if}}
+
+        {{#if search_js}}
+        <script src="{{ path_to_root }}elasticlunr.min.js"></script>
+        <script src="{{ path_to_root }}mark.min.js"></script>
+        <script src="{{ path_to_root }}searcher.js"></script>
+        {{/if}}
+
+        <script src="{{ path_to_root }}clipboard.min.js"></script>
+        <script src="{{ path_to_root }}highlight.js"></script>
+        <script src="{{ path_to_root }}book.js"></script>
+
+        <!-- Custom JS scripts -->
+        {{#each additional_js}}
+        <script src="{{ ../path_to_root }}{{this}}"></script>
+        {{/each}}
+
+        {{#if is_print}}
+        {{#if mathjax_support}}
+        <script>
+        window.addEventListener('load', function() {
+            MathJax.Hub.Register.StartupHook('End', function() {
+                window.setTimeout(window.print, 100);
+            });
+        });
+        </script>
+        {{else}}
+        <script>
+        window.addEventListener('load', function() {
+            window.setTimeout(window.print, 100);
+        });
+        </script>
+        {{/if}}
+        {{/if}}
+
+    </div>
+    </body>
 </html>

From 2431bf047d992785b286b72653a520d813309123 Mon Sep 17 00:00:00 2001
From: meator <meator.dev@gmail.com>
Date: Sun, 4 May 2025 10:07:56 +0200
Subject: [PATCH 2/3] Reapply void-docs theme changes

The contents of this commit should closely follow the patch linked
in the "Void's changes to mdBook's default theme" section of
https://github.com/void-linux/void-docs/issues/840

Some things had to be adapted to the newer v0.4.43 base. Some changes
include:

- The warning and kbd elements were left intact in general.css
- -webkit-print-color-adjust was set in the pre element to match
  void-docs' old theme even though the new theme's code element no
  longer includes it in print.css
- Default code fonts were left as-is (these weren't present here in the
  void-docs original theme) in variables.css
- Warning border was left as-is (this element wasn't present in older
  versions of mdBook) in variables.css
- copy-button-filter variables were left as-is in variables.css
- variables.css no doesn't include special prefers-color-scheme: dark
  noscript logic (void-docs original theme didn't have it)
---
 src/theme/book.js           | 582 +-----------------------------------
 src/theme/css/chrome.css    |  11 +-
 src/theme/css/general.css   | 395 +++++++++++++++---------
 src/theme/css/print.css     |  26 +-
 src/theme/css/variables.css | 308 ++++---------------
 src/theme/index.hbs         | 312 ++++++++-----------
 6 files changed, 480 insertions(+), 1154 deletions(-)

diff --git a/src/theme/book.js b/src/theme/book.js
index 178f1e902..5d311a34c 100644
--- a/src/theme/book.js
+++ b/src/theme/book.js
@@ -3,443 +3,17 @@
 // Fix back button cache problem
 window.onunload = function () { };
 
-// Global variable, shared between modules
-function playground_text(playground, hidden = true) {
-    let code_block = playground.querySelector("code");
-
-    if (window.ace && code_block.classList.contains("editable")) {
-        let editor = window.ace.edit(code_block);
-        return editor.getValue();
-    } else if (hidden) {
-        return code_block.textContent;
-    } else {
-        return code_block.innerText;
-    }
-}
-
-(function codeSnippets() {
-    function fetch_with_timeout(url, options, timeout = 6000) {
-        return Promise.race([
-            fetch(url, options),
-            new Promise((_, reject) => setTimeout(() => reject(new Error('timeout')), timeout))
-        ]);
-    }
-
-    var playgrounds = Array.from(document.querySelectorAll(".playground"));
-    if (playgrounds.length > 0) {
-        fetch_with_timeout("https://play.rust-lang.org/meta/crates", {
-            headers: {
-                'Content-Type': "application/json",
-            },
-            method: 'POST',
-            mode: 'cors',
-        })
-        .then(response => response.json())
-        .then(response => {
-            // get list of crates available in the rust playground
-            let playground_crates = response.crates.map(item => item["id"]);
-            playgrounds.forEach(block => handle_crate_list_update(block, playground_crates));
-        });
-    }
-
-    function handle_crate_list_update(playground_block, playground_crates) {
-        // update the play buttons after receiving the response
-        update_play_button(playground_block, playground_crates);
-
-        // and install on change listener to dynamically update ACE editors
-        if (window.ace) {
-            let code_block = playground_block.querySelector("code");
-            if (code_block.classList.contains("editable")) {
-                let editor = window.ace.edit(code_block);
-                editor.addEventListener("change", function (e) {
-                    update_play_button(playground_block, playground_crates);
-                });
-                // add Ctrl-Enter command to execute rust code
-                editor.commands.addCommand({
-                    name: "run",
-                    bindKey: {
-                        win: "Ctrl-Enter",
-                        mac: "Ctrl-Enter"
-                    },
-                    exec: _editor => run_rust_code(playground_block)
-                });
-            }
-        }
-    }
-
-    // updates the visibility of play button based on `no_run` class and
-    // used crates vs ones available on https://play.rust-lang.org
-    function update_play_button(pre_block, playground_crates) {
-        var play_button = pre_block.querySelector(".play-button");
-
-        // skip if code is `no_run`
-        if (pre_block.querySelector('code').classList.contains("no_run")) {
-            play_button.classList.add("hidden");
-            return;
-        }
-
-        // get list of `extern crate`'s from snippet
-        var txt = playground_text(pre_block);
-        var re = /extern\s+crate\s+([a-zA-Z_0-9]+)\s*;/g;
-        var snippet_crates = [];
-        var item;
-        while (item = re.exec(txt)) {
-            snippet_crates.push(item[1]);
-        }
-
-        // check if all used crates are available on play.rust-lang.org
-        var all_available = snippet_crates.every(function (elem) {
-            return playground_crates.indexOf(elem) > -1;
-        });
-
-        if (all_available) {
-            play_button.classList.remove("hidden");
+(function theme() {
+    var html = document.querySelector("html");
+    var themeToggleButton = document.getElementById("theme-toggle");
+
+    themeToggleButton.addEventListener('click', function sidebarToggle() {
+        if (html.classList.contains("void-light")) {
+            html.classList.replace("void-light", "void-dark");
+            localStorage.setItem('mdbook-theme', "void-dark");
         } else {
-            play_button.classList.add("hidden");
-        }
-    }
-
-    function run_rust_code(code_block) {
-        var result_block = code_block.querySelector(".result");
-        if (!result_block) {
-            result_block = document.createElement('code');
-            result_block.className = 'result hljs language-bash';
-
-            code_block.append(result_block);
-        }
-
-        let text = playground_text(code_block);
-        let classes = code_block.querySelector('code').classList;
-        let edition = "2015";
-        if(classes.contains("edition2018")) {
-            edition = "2018";
-        } else if(classes.contains("edition2021")) {
-            edition = "2021";
-        }
-        var params = {
-            version: "stable",
-            optimize: "0",
-            code: text,
-            edition: edition
-        };
-
-        if (text.indexOf("#![feature") !== -1) {
-            params.version = "nightly";
-        }
-
-        result_block.innerText = "Running...";
-
-        fetch_with_timeout("https://play.rust-lang.org/evaluate.json", {
-            headers: {
-                'Content-Type': "application/json",
-            },
-            method: 'POST',
-            mode: 'cors',
-            body: JSON.stringify(params)
-        })
-        .then(response => response.json())
-        .then(response => {
-            if (response.result.trim() === '') {
-                result_block.innerText = "No output";
-                result_block.classList.add("result-no-output");
-            } else {
-                result_block.innerText = response.result;
-                result_block.classList.remove("result-no-output");
-            }
-        })
-        .catch(error => result_block.innerText = "Playground Communication: " + error.message);
-    }
-
-    // Syntax highlighting Configuration
-    hljs.configure({
-        tabReplace: '    ', // 4 spaces
-        languages: [],      // Languages used for auto-detection
-    });
-
-    let code_nodes = Array
-        .from(document.querySelectorAll('code'))
-        // Don't highlight `inline code` blocks in headers.
-        .filter(function (node) {return !node.parentElement.classList.contains("header"); });
-
-    if (window.ace) {
-        // language-rust class needs to be removed for editable
-        // blocks or highlightjs will capture events
-        code_nodes
-            .filter(function (node) {return node.classList.contains("editable"); })
-            .forEach(function (block) { block.classList.remove('language-rust'); });
-
-        code_nodes
-            .filter(function (node) {return !node.classList.contains("editable"); })
-            .forEach(function (block) { hljs.highlightBlock(block); });
-    } else {
-        code_nodes.forEach(function (block) { hljs.highlightBlock(block); });
-    }
-
-    // Adding the hljs class gives code blocks the color css
-    // even if highlighting doesn't apply
-    code_nodes.forEach(function (block) { block.classList.add('hljs'); });
-
-    Array.from(document.querySelectorAll("code.hljs")).forEach(function (block) {
-
-        var lines = Array.from(block.querySelectorAll('.boring'));
-        // If no lines were hidden, return
-        if (!lines.length) { return; }
-        block.classList.add("hide-boring");
-
-        var buttons = document.createElement('div');
-        buttons.className = 'buttons';
-        buttons.innerHTML = "<button class=\"fa fa-eye\" title=\"Show hidden lines\" aria-label=\"Show hidden lines\"></button>";
-
-        // add expand button
-        var pre_block = block.parentNode;
-        pre_block.insertBefore(buttons, pre_block.firstChild);
-
-        pre_block.querySelector('.buttons').addEventListener('click', function (e) {
-            if (e.target.classList.contains('fa-eye')) {
-                e.target.classList.remove('fa-eye');
-                e.target.classList.add('fa-eye-slash');
-                e.target.title = 'Hide lines';
-                e.target.setAttribute('aria-label', e.target.title);
-
-                block.classList.remove('hide-boring');
-            } else if (e.target.classList.contains('fa-eye-slash')) {
-                e.target.classList.remove('fa-eye-slash');
-                e.target.classList.add('fa-eye');
-                e.target.title = 'Show hidden lines';
-                e.target.setAttribute('aria-label', e.target.title);
-
-                block.classList.add('hide-boring');
-            }
-        });
-    });
-
-    if (window.playground_copyable) {
-        Array.from(document.querySelectorAll('pre code')).forEach(function (block) {
-            var pre_block = block.parentNode;
-            if (!pre_block.classList.contains('playground')) {
-                var buttons = pre_block.querySelector(".buttons");
-                if (!buttons) {
-                    buttons = document.createElement('div');
-                    buttons.className = 'buttons';
-                    pre_block.insertBefore(buttons, pre_block.firstChild);
-                }
-
-                var clipButton = document.createElement('button');
-                clipButton.className = 'clip-button';
-                clipButton.title = 'Copy to clipboard';
-                clipButton.setAttribute('aria-label', clipButton.title);
-                clipButton.innerHTML = '<i class=\"tooltiptext\"></i>';
-
-                buttons.insertBefore(clipButton, buttons.firstChild);
-            }
-        });
-    }
-
-    // Process playground code blocks
-    Array.from(document.querySelectorAll(".playground")).forEach(function (pre_block) {
-        // Add play button
-        var buttons = pre_block.querySelector(".buttons");
-        if (!buttons) {
-            buttons = document.createElement('div');
-            buttons.className = 'buttons';
-            pre_block.insertBefore(buttons, pre_block.firstChild);
-        }
-
-        var runCodeButton = document.createElement('button');
-        runCodeButton.className = 'fa fa-play play-button';
-        runCodeButton.hidden = true;
-        runCodeButton.title = 'Run this code';
-        runCodeButton.setAttribute('aria-label', runCodeButton.title);
-
-        buttons.insertBefore(runCodeButton, buttons.firstChild);
-        runCodeButton.addEventListener('click', function (e) {
-            run_rust_code(pre_block);
-        });
-
-        if (window.playground_copyable) {
-            var copyCodeClipboardButton = document.createElement('button');
-            copyCodeClipboardButton.className = 'clip-button';
-            copyCodeClipboardButton.innerHTML = '<i class="tooltiptext"></i>';
-            copyCodeClipboardButton.title = 'Copy to clipboard';
-            copyCodeClipboardButton.setAttribute('aria-label', copyCodeClipboardButton.title);
-
-            buttons.insertBefore(copyCodeClipboardButton, buttons.firstChild);
-        }
-
-        let code_block = pre_block.querySelector("code");
-        if (window.ace && code_block.classList.contains("editable")) {
-            var undoChangesButton = document.createElement('button');
-            undoChangesButton.className = 'fa fa-history reset-button';
-            undoChangesButton.title = 'Undo changes';
-            undoChangesButton.setAttribute('aria-label', undoChangesButton.title);
-
-            buttons.insertBefore(undoChangesButton, buttons.firstChild);
-
-            undoChangesButton.addEventListener('click', function () {
-                let editor = window.ace.edit(code_block);
-                editor.setValue(editor.originalCode);
-                editor.clearSelection();
-            });
-        }
-    });
-})();
-
-(function themes() {
-    var html = document.querySelector('html');
-    var themeToggleButton = document.getElementById('theme-toggle');
-    var themePopup = document.getElementById('theme-list');
-    var themeColorMetaTag = document.querySelector('meta[name="theme-color"]');
-    var themeIds = [];
-    themePopup.querySelectorAll('button.theme').forEach(function (el) {
-        themeIds.push(el.id);
-    });
-    var stylesheets = {
-        ayuHighlight: document.querySelector("[href$='ayu-highlight.css']"),
-        tomorrowNight: document.querySelector("[href$='tomorrow-night.css']"),
-        highlight: document.querySelector("[href$='highlight.css']"),
-    };
-
-    function showThemes() {
-        themePopup.style.display = 'block';
-        themeToggleButton.setAttribute('aria-expanded', true);
-        themePopup.querySelector("button#" + get_theme()).focus();
-    }
-
-    function updateThemeSelected() {
-        themePopup.querySelectorAll('.theme-selected').forEach(function (el) {
-            el.classList.remove('theme-selected');
-        });
-        themePopup.querySelector("button#" + get_theme()).classList.add('theme-selected');
-    }
-
-    function hideThemes() {
-        themePopup.style.display = 'none';
-        themeToggleButton.setAttribute('aria-expanded', false);
-        themeToggleButton.focus();
-    }
-
-    function get_theme() {
-        var theme;
-        try { theme = localStorage.getItem('mdbook-theme'); } catch (e) { }
-        if (theme === null || theme === undefined || !themeIds.includes(theme)) {
-            return default_theme;
-        } else {
-            return theme;
-        }
-    }
-
-    function set_theme(theme, store = true) {
-        let ace_theme;
-
-        if (theme == 'coal' || theme == 'navy') {
-            stylesheets.ayuHighlight.disabled = true;
-            stylesheets.tomorrowNight.disabled = false;
-            stylesheets.highlight.disabled = true;
-
-            ace_theme = "ace/theme/tomorrow_night";
-        } else if (theme == 'ayu') {
-            stylesheets.ayuHighlight.disabled = false;
-            stylesheets.tomorrowNight.disabled = true;
-            stylesheets.highlight.disabled = true;
-            ace_theme = "ace/theme/tomorrow_night";
-        } else {
-            stylesheets.ayuHighlight.disabled = true;
-            stylesheets.tomorrowNight.disabled = true;
-            stylesheets.highlight.disabled = false;
-            ace_theme = "ace/theme/dawn";
-        }
-
-        setTimeout(function () {
-            themeColorMetaTag.content = getComputedStyle(document.documentElement).backgroundColor;
-        }, 1);
-
-        if (window.ace && window.editors) {
-            window.editors.forEach(function (editor) {
-                editor.setTheme(ace_theme);
-            });
-        }
-
-        var previousTheme = get_theme();
-
-        if (store) {
-            try { localStorage.setItem('mdbook-theme', theme); } catch (e) { }
-        }
-
-        html.classList.remove(previousTheme);
-        html.classList.add(theme);
-        updateThemeSelected();
-    }
-
-    // Set theme
-    var theme = get_theme();
-
-    set_theme(theme, false);
-
-    themeToggleButton.addEventListener('click', function () {
-        if (themePopup.style.display === 'block') {
-            hideThemes();
-        } else {
-            showThemes();
-        }
-    });
-
-    themePopup.addEventListener('click', function (e) {
-        var theme;
-        if (e.target.className === "theme") {
-            theme = e.target.id;
-        } else if (e.target.parentElement.className === "theme") {
-            theme = e.target.parentElement.id;
-        } else {
-            return;
-        }
-        set_theme(theme);
-    });
-
-    themePopup.addEventListener('focusout', function(e) {
-        // e.relatedTarget is null in Safari and Firefox on macOS (see workaround below)
-        if (!!e.relatedTarget && !themeToggleButton.contains(e.relatedTarget) && !themePopup.contains(e.relatedTarget)) {
-            hideThemes();
-        }
-    });
-
-    // Should not be needed, but it works around an issue on macOS & iOS: https://github.com/rust-lang/mdBook/issues/628
-    document.addEventListener('click', function(e) {
-        if (themePopup.style.display === 'block' && !themeToggleButton.contains(e.target) && !themePopup.contains(e.target)) {
-            hideThemes();
-        }
-    });
-
-    document.addEventListener('keydown', function (e) {
-        if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) { return; }
-        if (!themePopup.contains(e.target)) { return; }
-
-        switch (e.key) {
-            case 'Escape':
-                e.preventDefault();
-                hideThemes();
-                break;
-            case 'ArrowUp':
-                e.preventDefault();
-                var li = document.activeElement.parentElement;
-                if (li && li.previousElementSibling) {
-                    li.previousElementSibling.querySelector('button').focus();
-                }
-                break;
-            case 'ArrowDown':
-                e.preventDefault();
-                var li = document.activeElement.parentElement;
-                if (li && li.nextElementSibling) {
-                    li.nextElementSibling.querySelector('button').focus();
-                }
-                break;
-            case 'Home':
-                e.preventDefault();
-                themePopup.querySelector('li:first-child button').focus();
-                break;
-            case 'End':
-                e.preventDefault();
-                themePopup.querySelector('li:last-child button').focus();
-                break;
+            html.classList.replace("void-dark", "void-light");
+            localStorage.setItem('mdbook-theme', "void-light");
         }
     });
 })();
@@ -449,7 +23,6 @@ function playground_text(playground, hidden = true) {
     var sidebar = document.getElementById("sidebar");
     var sidebarLinks = document.querySelectorAll('#sidebar a');
     var sidebarToggleButton = document.getElementById("sidebar-toggle");
-    var sidebarResizeHandle = document.getElementById("sidebar-resize-handle");
     var firstContact = null;
 
     function showSidebar() {
@@ -477,11 +50,6 @@ function playground_text(playground, hidden = true) {
     // Toggle sidebar
     sidebarToggleButton.addEventListener('click', function sidebarToggle() {
         if (body.classList.contains("sidebar-hidden")) {
-            var current_width = parseInt(
-                document.documentElement.style.getPropertyValue('--sidebar-width'), 10);
-            if (current_width < 150) {
-                document.documentElement.style.setProperty('--sidebar-width', '150px');
-            }
             showSidebar();
         } else if (body.classList.contains("sidebar-visible")) {
             hideSidebar();
@@ -494,32 +62,6 @@ function playground_text(playground, hidden = true) {
         }
     });
 
-    sidebarResizeHandle.addEventListener('mousedown', initResize, false);
-
-    function initResize(e) {
-        window.addEventListener('mousemove', resize, false);
-        window.addEventListener('mouseup', stopResize, false);
-        body.classList.add('sidebar-resizing');
-    }
-    function resize(e) {
-        var pos = (e.clientX - sidebar.offsetLeft);
-        if (pos < 20) {
-            hideSidebar();
-        } else {
-            if (body.classList.contains("sidebar-hidden")) {
-                showSidebar();
-            }
-            pos = Math.min(pos, window.innerWidth - 100);
-            document.documentElement.style.setProperty('--sidebar-width', pos + 'px');
-        }
-    }
-    //on mouseup remove windows functions mousemove & mouseup
-    function stopResize(e) {
-        body.classList.remove('sidebar-resizing');
-        window.removeEventListener('mousemove', resize, false);
-        window.removeEventListener('mouseup', stopResize, false);
-    }
-
     document.addEventListener('touchstart', function (e) {
         firstContact = {
             x: e.touches[0].clientX,
@@ -584,107 +126,3 @@ function playground_text(playground, hidden = true) {
         }
     });
 })();
-
-(function clipboard() {
-    var clipButtons = document.querySelectorAll('.clip-button');
-
-    function hideTooltip(elem) {
-        elem.firstChild.innerText = "";
-        elem.className = 'clip-button';
-    }
-
-    function showTooltip(elem, msg) {
-        elem.firstChild.innerText = msg;
-        elem.className = 'clip-button tooltipped';
-    }
-
-    var clipboardSnippets = new ClipboardJS('.clip-button', {
-        text: function (trigger) {
-            hideTooltip(trigger);
-            let playground = trigger.closest("pre");
-            return playground_text(playground, false);
-        }
-    });
-
-    Array.from(clipButtons).forEach(function (clipButton) {
-        clipButton.addEventListener('mouseout', function (e) {
-            hideTooltip(e.currentTarget);
-        });
-    });
-
-    clipboardSnippets.on('success', function (e) {
-        e.clearSelection();
-        showTooltip(e.trigger, "Copied!");
-    });
-
-    clipboardSnippets.on('error', function (e) {
-        showTooltip(e.trigger, "Clipboard error!");
-    });
-})();
-
-(function scrollToTop () {
-    var menuTitle = document.querySelector('.menu-title');
-
-    menuTitle.addEventListener('click', function () {
-        document.scrollingElement.scrollTo({ top: 0, behavior: 'smooth' });
-    });
-})();
-
-(function controllMenu() {
-    var menu = document.getElementById('menu-bar');
-
-    (function controllPosition() {
-        var scrollTop = document.scrollingElement.scrollTop;
-        var prevScrollTop = scrollTop;
-        var minMenuY = -menu.clientHeight - 50;
-        // When the script loads, the page can be at any scroll (e.g. if you reforesh it).
-        menu.style.top = scrollTop + 'px';
-        // Same as parseInt(menu.style.top.slice(0, -2), but faster
-        var topCache = menu.style.top.slice(0, -2);
-        menu.classList.remove('sticky');
-        var stickyCache = false; // Same as menu.classList.contains('sticky'), but faster
-        document.addEventListener('scroll', function () {
-            scrollTop = Math.max(document.scrollingElement.scrollTop, 0);
-            // `null` means that it doesn't need to be updated
-            var nextSticky = null;
-            var nextTop = null;
-            var scrollDown = scrollTop > prevScrollTop;
-            var menuPosAbsoluteY = topCache - scrollTop;
-            if (scrollDown) {
-                nextSticky = false;
-                if (menuPosAbsoluteY > 0) {
-                    nextTop = prevScrollTop;
-                }
-            } else {
-                if (menuPosAbsoluteY > 0) {
-                    nextSticky = true;
-                } else if (menuPosAbsoluteY < minMenuY) {
-                    nextTop = prevScrollTop + minMenuY;
-                }
-            }
-            if (nextSticky === true && stickyCache === false) {
-                menu.classList.add('sticky');
-                stickyCache = true;
-            } else if (nextSticky === false && stickyCache === true) {
-                menu.classList.remove('sticky');
-                stickyCache = false;
-            }
-            if (nextTop !== null) {
-                menu.style.top = nextTop + 'px';
-                topCache = nextTop;
-            }
-            prevScrollTop = scrollTop;
-        }, { passive: true });
-    })();
-    (function controllBorder() {
-        function updateBorder() {
-            if (menu.offsetTop === 0) {
-                menu.classList.remove('bordered');
-            } else {
-                menu.classList.add('bordered');
-            }
-        }
-        updateBorder();
-        document.addEventListener('scroll', updateBorder, { passive: true });
-    })();
-})();
diff --git a/src/theme/css/chrome.css b/src/theme/css/chrome.css
index 4cd73086d..f1cdc2c8d 100644
--- a/src/theme/css/chrome.css
+++ b/src/theme/css/chrome.css
@@ -153,8 +153,7 @@ html:not(.js) .left-buttons button {
 
 .nav-chapters:hover {
     text-decoration: none;
-    background-color: var(--theme-hover);
-    transition: background-color 0.15s, color 0.15s;
+    transition: color 0.15s, color 0.15s;
 }
 
 .nav-wrapper {
@@ -294,10 +293,6 @@ pre > .buttons button.clip-button:hover::before {
         display: none;
     }
 }
-pre > code {
-    display: block;
-    padding: 1rem;
-}
 
 /* FIXME: ACE editors overlap their buttons because ACE does absolute
    positioning within the code block which breaks padding. The only solution I
@@ -449,7 +444,7 @@ html:not(.sidebar-resizing) .sidebar {
 .sidebar code {
     line-height: 2em;
 }
-.sidebar .sidebar-scrollbox {
+/*.sidebar .sidebar-scrollbox {
     overflow-y: auto;
     position: absolute;
     top: 0;
@@ -457,7 +452,7 @@ html:not(.sidebar-resizing) .sidebar {
     left: 0;
     right: 0;
     padding: 10px 10px;
-}
+}*/
 .sidebar .sidebar-resize-handle {
     position: absolute;
     cursor: col-resize;
diff --git a/src/theme/css/general.css b/src/theme/css/general.css
index 0862b5167..50e71dde0 100644
--- a/src/theme/css/general.css
+++ b/src/theme/css/general.css
@@ -2,28 +2,44 @@
 
 :root {
     /* Browser default font-size is 16px, this way 1 rem = 10px */
-    font-size: 62.5%;
     color-scheme: var(--color-scheme);
 }
 
-html {
-    font-family: "Open Sans", sans-serif;
+body {
+    font-family: 'Ubuntu', sans-serif;
+    font-size: 1rem;
+    line-height: 1.5;
     color: var(--fg);
+    margin: 0;
     background-color: var(--bg);
-    text-size-adjust: none;
-    -webkit-text-size-adjust: none;
 }
-
-body {
-    margin: 0;
-    font-size: 1.6rem;
-    overflow-x: hidden;
+h1, h2, h3, h4, h5, h6 { color: var(--fg); }
+a, a:visited {
+    color: var(--links);
+    text-decoration: none;
+}
+a:hover, a:visited:hover {
+    color: var(--links-hover);
+    text-decoration: underline;
 }
 
 code {
-    font-family: var(--mono-font) !important;
-    font-size: var(--code-font-size);
-    direction: ltr !important;
+    background: var(--inline-code-color);
+    padding: 2px 4px;
+    border-radius: 4px;
+    white-space: pre-wrap;
+    overflow-wrap: break-word;
+}
+pre code {
+    padding: 0;
+    border-radius: 0;
+}
+pre {
+    padding: .5em;
+    margin: 1em 0;
+    background: var(--inline-code-color);
+    border: 1px solid var(--code-border);
+    border-radius: 4px;
 }
 
 /* make long words/inline code not x overflow */
@@ -36,122 +52,138 @@ main {
     overflow-x: auto;
 }
 
-/* Don't change font size in headers. */
-h1 code, h2 code, h3 code, h4 code, h5 code, h6 code {
-    font-size: unset;
-}
-
-.left { float: left; }
-.right { float: right; }
-.boring { opacity: 0.6; }
-.hide-boring .boring { display: none; }
-.hidden { display: none !important; }
-
-h2, h3 { margin-block-start: 2.5em; }
-h4, h5 { margin-block-start: 2em; }
-
-.header + .header h3,
-.header + .header h4,
-.header + .header h5 {
-    margin-block-start: 1em;
-}
-
-h1:target::before,
-h2:target::before,
-h3:target::before,
-h4:target::before,
-h5:target::before,
-h6:target::before {
-    display: inline-block;
-    content: "»";
-    margin-inline-start: -30px;
-    width: 30px;
-}
-
-/* This is broken on Safari as of version 14, but is fixed
-   in Safari Technology Preview 117 which I think will be Safari 14.2.
-   https://bugs.webkit.org/show_bug.cgi?id=218076
-*/
-:target {
-    /* Safari does not support logical properties */
-    scroll-margin-top: calc(var(--menu-bar-height) + 0.5em);
+blockquote {
+    margin: 20px 0;
+    padding: 0 20px;
+    padding-left: 1em;
+    background: var(--quote-bg);
+    border: 1px solid var(--quote-border);
+    border-left: none;
+    border-right: none;
 }
 
-.page {
-    outline: 0;
-    padding: 0 var(--page-padding);
-    margin-block-start: calc(0px - var(--menu-bar-height)); /* Compensate for the #menu-bar-hover-placeholder */
-}
-.page-wrapper {
-    box-sizing: border-box;
-    background-color: var(--bg);
-}
-.no-js .page-wrapper,
-.js:not(.sidebar-resizing) .page-wrapper {
-    transition: margin-left 0.3s ease, transform 0.3s ease; /* Animation: slide away */
-}
-[dir=rtl] .js:not(.sidebar-resizing) .page-wrapper {
-    transition: margin-right 0.3s ease, transform 0.3s ease; /* Animation: slide away */
+blockquote code {
+    background: var(--quote-code-bg);
 }
 
-.content {
-    overflow-y: auto;
-    padding: 0 5px 50px 5px;
-}
-.content main {
-    margin-inline-start: auto;
-    margin-inline-end: auto;
-    max-width: var(--content-max-width);
-}
-.content p { line-height: 1.45em; }
-.content ol { line-height: 1.45em; }
-.content ul { line-height: 1.45em; }
-.content a { text-decoration: none; }
-.content a:hover { text-decoration: underline; }
-.content img, .content video { max-width: 100%; }
-.content .header:link,
-.content .header:visited {
-    color: var(--fg);
-}
-.content .header:link,
-.content .header:visited:hover {
-    text-decoration: none;
+li.js-unavailable {
+    background-color: #f6cf68;
+    border-radius: 10px;
+    margin-left: 1em;
+    padding-left: 1em;
+    padding-right: 1em;
 }
 
 table {
-    margin: 0 auto;
     border-collapse: collapse;
+    display: block;
+    overflow-y: auto;
+    border: 1px var(--table-border-color) solid;
 }
 table td {
     padding: 3px 20px;
-    border: 1px var(--table-border-color) solid;
 }
 table thead {
     background: var(--table-header-bg);
+    color: var(--table-header-fg);
 }
 table thead td {
     font-weight: 700;
+}
+table tbody tr:nth-child(2n) {
+    /* Alternate background colors for rows */
+    background: var(--table-alternate-bg);
+}
+
+svg {
+    position: relative;
+    top: .125em;
+    width: 1em;
+    height: auto;
+}
+
+.hidden {
+    display: none;
+}
+
+.icon-button {
     border: none;
+    background: none;
+    cursor: pointer;
+    padding: 1em;
 }
-table thead th {
-    padding: 3px 20px;
+
+/* void navigation */
+
+#void-nav {
+    width: 100%;
+    min-height: 50px;
+    background: var(--nav-bg);
+    font-size: 14px;
+
+    display: flex;
+    flex-direction: row;
+    flex-wrap: wrap;
+}
+#void-nav a,
+#void-nav button,
+#void-nav label {
+    fill: var(--nav-fg);
+    height: 50px;
+    min-height: 100%;
+    display: block;
+    line-height: 50px;
+    padding: 0 15px;
+    font-size: 1.2em;
+}
+#void-nav ul {
+    list-style: none;
+    margin: 0;
+    padding: 0;
+}
+
+#void-nav ul#nav-right {
+    margin-left: auto;
+}
+
+#void-nav ul li {
+    display: inline-block;
 }
-table thead tr {
-    border: 1px var(--table-header-bg) solid;
+#void-nav ul li a {
+    color: var(--nav-fg);
+    display: block;
+    padding: 0 15px;
+    line-height: 50px;
+    font-size: 1.2em;
+    text-decoration: none
+}
+#void-nav ul li a:hover,
+#void-nav ul li a:focus,
+#void-nav button:hover,
+#void-nav button:focus,
+#void-nav label:hover,
+#void-nav label:focus {
+    background: #000;
 }
-/* Alternate background colors for rows */
-table tbody tr:nth-child(2n) {
-    background: var(--table-alternate-bg);
+
+#skip-to-content {
+    position: absolute;
+    left: -999px;
+    top: -999px;
 }
 
+#skip-to-content:active,
+#skip-to-content:focus {
+    position: relative;
+    left: 0;
+    top: 0;
+}
 
-blockquote {
-    margin: 20px 0;
-    padding: 0 20px;
-    color: var(--fg);
-    background-color: var(--quote-bg);
-    border-block-start: .1em solid var(--quote-border);
-    border-block-end: .1em solid var(--quote-border);
+#icon-theme-light {
+    display: var(--theme-toggle-light);
+}
+#icon-theme-dark {
+    display: var(--theme-toggle-dark);
 }
 
 .warning {
@@ -200,43 +232,136 @@ sup {
     line-height: 0;
 }
 
-:not(.footnote-definition) + .footnote-definition,
-.footnote-definition + :not(.footnote-definition) {
-    margin-block-start: 2em;
+/* search */
+
+#searchbar {
+    width: 100%;
+    padding: 10px 16px;
+    margin: 5px 0;
+    border-radius: 3px;
+    border: 1px solid var(--searchbar-border-color);
+}
+#searchresults-header {
+    font-weight: bold;
+    font-size: 1em;
+    padding: 18px 0 0 5px;
+}
+ul#searchresults {
+    list-style: none;
+    padding-left: 20px;
+}
+ul#searchresults li {
+    margin: 10px 0px;
+    padding: 2px;
+    border-radius: 2px;
+}
+ul#searchresults span.teaser {
+    display: block;
+    clear: both;
+    margin: 5px 0 0 20px;
+    font-size: 0.8em;
 }
-.footnote-definition {
-    font-size: 0.9em;
-    margin: 0.5em 0;
+
+/* chapter navigation */
+
+#nav-wide-wrapper {
+    max-width: 800px;
+    margin: 0 auto;
+    margin-top: 50px;
 }
-.footnote-definition p {
-    display: inline;
+.previous {
+    float: left;
 }
-
-.tooltiptext {
-    position: absolute;
-    visibility: hidden;
-    color: #fff;
-    background-color: #333;
-    transform: translateX(-50%); /* Center by moving tooltip 50% of its width left */
-    left: -8px; /* Half of the width of the icon */
-    top: -35px;
-    font-size: 0.8em;
+.next {
+    float: right;
+    right: 15px;
+}
+.nav-chapters {
+    fill: var(--nav-arrow-fg);
     text-align: center;
-    border-radius: 6px;
-    padding: 5px 8px;
-    margin: 5px;
-    z-index: 1000;
+    text-decoration: none;
+    display: block;
+    max-width: 150px;
+    min-width: 90px;
 }
-.tooltipped .tooltiptext {
-    visibility: visible;
+.nav-chapters:hover {
+    text-decoration: none;
+    fill: var(--nav-fg-hover);
 }
 
-.chapter li.part-title {
-    color: var(--sidebar-fg);
-    margin: 5px 0px;
-    font-weight: bold;
+.nav-chapters svg {
+    margin: 0 auto;
+    width: 1.5em;
+}
+.mobile-nav-chapters {
+    fill: var(--nav-arrow-fg);
+}
+.mobile-nav-chapters:hover {
+    fill: var(--nav-fg-hover);
+}
+
+/* layout */
+
+body {
+    box-sizing: border-box;
+}
+#content {
+    display: flex;
+    flex-direction: row;
+    width: 100%;
+}
+#page-wrapper {
+    --content-padding: 10px;
+    padding: 0 var(--content-padding);
+    width: calc(100% - var(--content-padding) * 2);
+}
+#search-wrapper,
+#page-wrapper main {
+    width: 100%;
+    max-width: 800px;
+    margin: 0 auto;
+}
+#sidebar {
+    max-width: 300px;
+    flex-shrink: 0;
 }
 
-.result-no-output {
-    font-style: italic;
+/* 300px + 800px + 2*90px + 15px */
+@media only screen and (min-width: 1295px) {
+    .sidebar-visible #nav-wide-wrapper {
+        max-width: none;
+        margin: 0;
+    }
+    .sidebar-visible .nav-chapters {
+        background: none;
+        position: fixed;
+        top: 50px;
+        bottom: 0;
+        margin: 0;
+        justify-content: center;
+        align-content: center;
+        display: flex;
+        flex-direction: column;
+    }
+}
+/* 800px + 2*90px + 15px */
+@media only screen and (min-width: 995px) {
+    .sidebar-hidden #nav-wide-wrapper {
+        max-width: none;
+        margin: 0;
+    }
+    .sidebar-hidden .nav-chapters {
+        background: none;
+        position: fixed;
+        top: 50px;
+        bottom: 0;
+        margin: 0;
+        justify-content: center;
+        align-content: center;
+        display: flex;
+        flex-direction: column;
+    }
+    table {
+        display: table;
+    }
 }
diff --git a/src/theme/css/print.css b/src/theme/css/print.css
index 80ec3a544..8921294f8 100644
--- a/src/theme/css/print.css
+++ b/src/theme/css/print.css
@@ -1,6 +1,7 @@
 
 #sidebar,
 #menu-bar,
+#void-nav,
 .nav-chapters,
 .mobile-nav-chapters {
     display: none;
@@ -24,6 +25,14 @@
 
 code {
     direction: ltr !important;
+    background-color: #ddd;
+}
+
+pre {
+    background-color: #ddd;
+
+    /* Force background to be printed in Chrome */
+    -webkit-print-color-adjust: exact;
 }
 
 pre > .buttons {
@@ -45,6 +54,21 @@ pre, code {
     white-space: pre-wrap;
 }
 
-.fa {
+svg {
     display: none !important;
 }
+
+table {
+    color: black;
+    border-color: black;
+    background-color: unset;
+}
+
+table thead tr {
+    color: black;
+    background-color: unset;
+}
+
+table tbody tr {
+    background-color: unset;
+}
diff --git a/src/theme/css/variables.css b/src/theme/css/variables.css
index 12d1db7a3..4ce5490eb 100644
--- a/src/theme/css/variables.css
+++ b/src/theme/css/variables.css
@@ -10,52 +10,62 @@
     --menu-bar-height: 50px;
     --mono-font: "Source Code Pro", Consolas, "Ubuntu Mono", Menlo, "DejaVu Sans Mono", monospace, monospace;
     --code-font-size: 0.875em /* please adjust the ace font size accordingly in editor.js */
+    --void-green: #478061;
+    --void-dark-green: #62b086;
+    --void-light: #fafafa;
+    --void-dark: #252525;
 }
 
 /* Themes */
 
-.ayu {
-    --bg: hsl(210, 25%, 8%);
-    --fg: #c5c5c5;
+.void-light {
+    --bg: #ffffff;
+    --fg: #333;
 
-    --sidebar-bg: #14191f;
-    --sidebar-fg: #c8c9db;
-    --sidebar-non-existant: #5c6773;
-    --sidebar-active: #ffb454;
-    --sidebar-spacer: #2d334f;
+    --sidebar-bg: var(--void-light);
+    --sidebar-fg: var(--fg);
+    --sidebar-active: var(--links);
+
+    --nav-bg: var(--void-green);
+    --nav-fg: var(--bg);
+    --nav-arrow-fg: var(--fg);
+    --nav-fg-hover: #000;
 
     --scrollbar: var(--sidebar-fg);
 
     --icons: #737480;
     --icons-hover: #b7b9cc;
 
-    --links: #0096cf;
+    --links: var(--void-green);
+    --links-hover: var(--fg)
 
-    --inline-code-color: #ffb454;
+    --inline-code-color: #fdf6e3;
+    --code-border: #ccc;
 
-    --theme-popup-bg: #14191f;
-    --theme-popup-border: #5c6773;
-    --theme-hover: #191f26;
+    --theme-toggle-light: none;
+    --theme-toggle-dark: inherit;
 
-    --quote-bg: hsl(226, 15%, 17%);
-    --quote-border: hsl(226, 15%, 22%);
+    --quote-bg: #ebf4ef;
+    --quote-border: #d1e6da;
+    --quote-code-bg: var(--inline-code-color);
 
     --warning-border: #ff8e00;
 
-    --table-border-color: hsl(210, 25%, 13%);
-    --table-header-bg: hsl(210, 25%, 28%);
-    --table-alternate-bg: hsl(210, 25%, 11%);
+    --table-border-color: var(--void-green);
+    --table-header-bg: var(--void-green);
+    --table-header-fg: #fff;
+    --table-alternate-bg: var(--void-light);
 
-    --searchbar-border-color: #848484;
-    --searchbar-bg: #424242;
-    --searchbar-fg: #fff;
+    --searchbar-border-color: #aaa;
+    --searchbar-bg: var(--bg);
+    --searchbar-fg: var(--fg);
     --searchbar-shadow-color: #d4c89f;
     --searchresults-header-fg: #666;
     --searchresults-border-color: #888;
     --searchresults-li-bg: #252932;
     --search-mark-bg: #e3b171;
 
-    --color-scheme: dark;
+    --color-scheme: light;
 
     /* Same as `--icons` */
     --copy-button-filter: invert(45%) sepia(6%) saturate(621%) hue-rotate(198deg) brightness(99%) contrast(85%);
@@ -63,247 +73,57 @@
     --copy-button-filter-hover: invert(68%) sepia(55%) saturate(531%) hue-rotate(341deg) brightness(104%) contrast(101%);
 }
 
-.coal {
-    --bg: hsl(200, 7%, 8%);
-    --fg: #98a3ad;
-
-    --sidebar-bg: #292c2f;
-    --sidebar-fg: #a1adb8;
-    --sidebar-non-existant: #505254;
-    --sidebar-active: #3473ad;
-    --sidebar-spacer: #393939;
-
-    --scrollbar: var(--sidebar-fg);
-
-    --icons: #43484d;
-    --icons-hover: #b3c0cc;
-
-    --links: #2b79a2;
-
-    --inline-code-color: #c5c8c6;
-
-    --theme-popup-bg: #141617;
-    --theme-popup-border: #43484d;
-    --theme-hover: #1f2124;
-
-    --quote-bg: hsl(234, 21%, 18%);
-    --quote-border: hsl(234, 21%, 23%);
-
-    --warning-border: #ff8e00;
-
-    --table-border-color: hsl(200, 7%, 13%);
-    --table-header-bg: hsl(200, 7%, 28%);
-    --table-alternate-bg: hsl(200, 7%, 11%);
-
-    --searchbar-border-color: #aaa;
-    --searchbar-bg: #b7b7b7;
-    --searchbar-fg: #000;
-    --searchbar-shadow-color: #aaa;
-    --searchresults-header-fg: #666;
-    --searchresults-border-color: #98a3ad;
-    --searchresults-li-bg: #2b2b2f;
-    --search-mark-bg: #355c7d;
-
-    --color-scheme: dark;
-
-    /* Same as `--icons` */
-    --copy-button-filter: invert(26%) sepia(8%) saturate(575%) hue-rotate(169deg) brightness(87%) contrast(82%);
-    /* Same as `--sidebar-active` */
-    --copy-button-filter-hover: invert(36%) sepia(70%) saturate(503%) hue-rotate(167deg) brightness(98%) contrast(89%);
-}
-
-.light, html:not(.js) {
-    --bg: hsl(0, 0%, 100%);
-    --fg: hsl(0, 0%, 0%);
-
-    --sidebar-bg: #fafafa;
-    --sidebar-fg: hsl(0, 0%, 0%);
-    --sidebar-non-existant: #aaaaaa;
-    --sidebar-active: #1f1fff;
-    --sidebar-spacer: #f4f4f4;
-
-    --scrollbar: #8F8F8F;
-
-    --icons: #747474;
-    --icons-hover: #000000;
-
-    --links: #20609f;
-
-    --inline-code-color: #301900;
-
-    --theme-popup-bg: #fafafa;
-    --theme-popup-border: #cccccc;
-    --theme-hover: #e6e6e6;
-
-    --quote-bg: hsl(197, 37%, 96%);
-    --quote-border: hsl(197, 37%, 91%);
-
-    --warning-border: #ff8e00;
-
-    --table-border-color: hsl(0, 0%, 95%);
-    --table-header-bg: hsl(0, 0%, 80%);
-    --table-alternate-bg: hsl(0, 0%, 97%);
-
-    --searchbar-border-color: #aaa;
-    --searchbar-bg: #fafafa;
-    --searchbar-fg: #000;
-    --searchbar-shadow-color: #aaa;
-    --searchresults-header-fg: #666;
-    --searchresults-border-color: #888;
-    --searchresults-li-bg: #e4f2fe;
-    --search-mark-bg: #a2cff5;
+.void-dark {
+    --bg: #222;
+    --fg: #ccc;
 
-    --color-scheme: light;
-
-    /* Same as `--icons` */
-    --copy-button-filter: invert(45.49%);
-    /* Same as `--sidebar-active` */
-    --copy-button-filter-hover: invert(14%) sepia(93%) saturate(4250%) hue-rotate(243deg) brightness(99%) contrast(130%);
-}
+    --sidebar-bg: #252525;
+    --sidebar-fg: var(--fg);
+    --sidebar-active: var(--links);
 
-.navy {
-    --bg: hsl(226, 23%, 11%);
-    --fg: #bcbdd0;
-
-    --sidebar-bg: #282d3f;
-    --sidebar-fg: #c8c9db;
-    --sidebar-non-existant: #505274;
-    --sidebar-active: #2b79a2;
-    --sidebar-spacer: #2d334f;
+    --nav-bg: #295340;
+    --nav-fg: var(--fg);
+    --nav-arrow-fg: var(--fg);
+    --nav-fg-hover: #fff;
 
     --scrollbar: var(--sidebar-fg);
 
     --icons: #737480;
     --icons-hover: #b7b9cc;
 
-    --links: #2b79a2;
-
-    --inline-code-color: #c5c8c6;
-
-    --theme-popup-bg: #161923;
-    --theme-popup-border: #737480;
-    --theme-hover: #282e40;
-
-    --quote-bg: hsl(226, 15%, 17%);
-    --quote-border: hsl(226, 15%, 22%);
-
-    --warning-border: #ff8e00;
-
-    --table-border-color: hsl(226, 23%, 16%);
-    --table-header-bg: hsl(226, 23%, 31%);
-    --table-alternate-bg: hsl(226, 23%, 14%);
-
-    --searchbar-border-color: #aaa;
-    --searchbar-bg: #aeaec6;
-    --searchbar-fg: #000;
-    --searchbar-shadow-color: #aaa;
-    --searchresults-header-fg: #5f5f71;
-    --searchresults-border-color: #5c5c68;
-    --searchresults-li-bg: #242430;
-    --search-mark-bg: #a2cff5;
-
-    --color-scheme: dark;
-
-    /* Same as `--icons` */
-    --copy-button-filter: invert(51%) sepia(10%) saturate(393%) hue-rotate(198deg) brightness(86%) contrast(87%);
-    /* Same as `--sidebar-active` */
-    --copy-button-filter-hover: invert(46%) sepia(20%) saturate(1537%) hue-rotate(156deg) brightness(85%) contrast(90%);
-}
-
-.rust {
-    --bg: hsl(60, 9%, 87%);
-    --fg: #262625;
-
-    --sidebar-bg: #3b2e2a;
-    --sidebar-fg: #c8c9db;
-    --sidebar-non-existant: #505254;
-    --sidebar-active: #e69f67;
-    --sidebar-spacer: #45373a;
-
-    --scrollbar: var(--sidebar-fg);
-
-    --icons: #737480;
-    --icons-hover: #262625;
-
-    --links: #2b79a2;
+    --links: var(--void-dark-green);
+    --links-hover: var(--fg);
 
-    --inline-code-color: #6e6b5e;
+    --inline-code-color: #353535;
+    --code-border: #111;
 
-    --theme-popup-bg: #e1e1db;
-    --theme-popup-border: #b38f6b;
-    --theme-hover: #99908a;
+    --theme-toggle-light: inherit;
+    --theme-toggle-dark: none;
 
-    --quote-bg: hsl(60, 5%, 75%);
-    --quote-border: hsl(60, 5%, 70%);
+    --quote-bg: #293d35;
+    --quote-border: #22362e;
+    --quote-code-bg: #2a2a2a;
 
     --warning-border: #ff8e00;
 
-    --table-border-color: hsl(60, 9%, 82%);
-    --table-header-bg: #b3a497;
-    --table-alternate-bg: hsl(60, 9%, 84%);
+    --table-border-color: var(--void-green);
+    --table-header-bg: var(--void-green);
+    --table-header-fg: #fff;
+    --table-alternate-bg: #2c2c2c;
 
     --searchbar-border-color: #aaa;
-    --searchbar-bg: #fafafa;
-    --searchbar-fg: #000;
-    --searchbar-shadow-color: #aaa;
+    --searchbar-bg: var(--bg);
+    --searchbar-fg: var(--fg);
+    --searchbar-shadow-color: #d4c89f;
     --searchresults-header-fg: #666;
     --searchresults-border-color: #888;
-    --searchresults-li-bg: #dec2a2;
-    --search-mark-bg: #e69f67;
+    --searchresults-li-bg: #252932;
+    --search-mark-bg: #e3b171;
+
+    --color-scheme: dark;
 
     /* Same as `--icons` */
-    --copy-button-filter: invert(51%) sepia(10%) saturate(393%) hue-rotate(198deg) brightness(86%) contrast(87%);
+    --copy-button-filter: invert(45%) sepia(6%) saturate(621%) hue-rotate(198deg) brightness(99%) contrast(85%);
     /* Same as `--sidebar-active` */
-    --copy-button-filter-hover: invert(77%) sepia(16%) saturate(1798%) hue-rotate(328deg) brightness(98%) contrast(83%);
-}
-
-@media (prefers-color-scheme: dark) {
-    html:not(.js) {
-        --bg: hsl(200, 7%, 8%);
-        --fg: #98a3ad;
-
-        --sidebar-bg: #292c2f;
-        --sidebar-fg: #a1adb8;
-        --sidebar-non-existant: #505254;
-        --sidebar-active: #3473ad;
-        --sidebar-spacer: #393939;
-
-        --scrollbar: var(--sidebar-fg);
-
-        --icons: #43484d;
-        --icons-hover: #b3c0cc;
-
-        --links: #2b79a2;
-
-        --inline-code-color: #c5c8c6;
-
-        --theme-popup-bg: #141617;
-        --theme-popup-border: #43484d;
-        --theme-hover: #1f2124;
-
-        --quote-bg: hsl(234, 21%, 18%);
-        --quote-border: hsl(234, 21%, 23%);
-
-        --warning-border: #ff8e00;
-
-        --table-border-color: hsl(200, 7%, 13%);
-        --table-header-bg: hsl(200, 7%, 28%);
-        --table-alternate-bg: hsl(200, 7%, 11%);
-
-        --searchbar-border-color: #aaa;
-        --searchbar-bg: #b7b7b7;
-        --searchbar-fg: #000;
-        --searchbar-shadow-color: #aaa;
-        --searchresults-header-fg: #666;
-        --searchresults-border-color: #98a3ad;
-        --searchresults-li-bg: #2b2b2f;
-        --search-mark-bg: #355c7d;
-
-        --color-scheme: dark;
-
-        /* Same as `--icons` */
-        --copy-button-filter: invert(26%) sepia(8%) saturate(575%) hue-rotate(169deg) brightness(87%) contrast(82%);
-        /* Same as `--sidebar-active` */
-        --copy-button-filter-hover: invert(36%) sepia(70%) saturate(503%) hue-rotate(167deg) brightness(98%) contrast(89%);
-    }
+    --copy-button-filter-hover: invert(68%) sepia(55%) saturate(531%) hue-rotate(341deg) brightness(104%) contrast(101%);
 }
diff --git a/src/theme/index.hbs b/src/theme/index.hbs
index 7775f262d..776b34537 100644
--- a/src/theme/index.hbs
+++ b/src/theme/index.hbs
@@ -12,54 +12,21 @@
         {{/if}}
 
 
-        <!-- Custom HTML head -->
-        {{> head}}
-
         <meta name="description" content="{{ description }}">
         <meta name="viewport" content="width=device-width, initial-scale=1">
         <meta name="theme-color" content="#ffffff">
 
-        {{#if favicon_svg}}
-        <link rel="icon" href="{{ path_to_root }}favicon.svg">
-        {{/if}}
-        {{#if favicon_png}}
         <link rel="shortcut icon" href="{{ path_to_root }}favicon.png">
-        {{/if}}
         <link rel="stylesheet" href="{{ path_to_root }}css/variables.css">
         <link rel="stylesheet" href="{{ path_to_root }}css/general.css">
         <link rel="stylesheet" href="{{ path_to_root }}css/chrome.css">
-        {{#if print_enable}}
         <link rel="stylesheet" href="{{ path_to_root }}css/print.css" media="print">
-        {{/if}}
-
-        <!-- Fonts -->
-        <link rel="stylesheet" href="{{ path_to_root }}FontAwesome/css/font-awesome.css">
-        {{#if copy_fonts}}
-        <link rel="stylesheet" href="{{ path_to_root }}fonts/fonts.css">
-        {{/if}}
-
-        <!-- Highlight.js Stylesheets -->
-        <link rel="stylesheet" href="{{ path_to_root }}highlight.css">
-        <link rel="stylesheet" href="{{ path_to_root }}tomorrow-night.css">
-        <link rel="stylesheet" href="{{ path_to_root }}ayu-highlight.css">
-
-        <!-- Custom theme stylesheets -->
-        {{#each additional_css}}
-        <link rel="stylesheet" href="{{ ../path_to_root }}{{ this }}">
-        {{/each}}
-
-        {{#if mathjax_support}}
-        <!-- MathJax -->
-        <script async src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
-        {{/if}}
 
         <!-- Provide site root to javascript -->
         <script>
             var path_to_root = "{{ path_to_root }}";
             var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "{{ preferred_dark_theme }}" : "{{ default_theme }}";
         </script>
-        <!-- Start loading toc.js asap -->
-        <script src="{{ path_to_root }}toc.js"></script>
     </head>
     <body>
     <div id="body-container">
@@ -92,85 +59,93 @@
 
         <input type="checkbox" id="sidebar-toggle-anchor" class="hidden">
 
-        <!-- Hide / unhide sidebar before it is displayed -->
-        <script>
-            var sidebar = null;
-            var sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
-            if (document.body.clientWidth >= 1080) {
-                try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
-                sidebar = sidebar || 'visible';
-            } else {
-                sidebar = 'hidden';
-            }
-            sidebar_toggle.checked = sidebar === 'visible';
-            html.classList.remove('sidebar-visible');
-            html.classList.add("sidebar-" + sidebar);
-        </script>
-
-        <nav id="sidebar" class="sidebar" aria-label="Table of contents">
-            <!-- populated by js -->
-            <mdbook-sidebar-scrollbox class="sidebar-scrollbox"></mdbook-sidebar-scrollbox>
-            <noscript>
-                <iframe class="sidebar-iframe-outer" src="{{ path_to_root }}toc.html"></iframe>
-            </noscript>
-            <div id="sidebar-resize-handle" class="sidebar-resize-handle">
-                <div class="sidebar-resize-indicator"></div>
-            </div>
-        </nav>
-
-        <div id="page-wrapper" class="page-wrapper">
-
-            <div class="page">
-                {{> header}}
-                <div id="menu-bar-hover-placeholder"></div>
-                <div id="menu-bar" class="menu-bar sticky">
-                    <div class="left-buttons">
-                        <label id="sidebar-toggle" class="icon-button" for="sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
-                            <i class="fa fa-bars"></i>
-                        </label>
-                        <button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
-                            <i class="fa fa-paint-brush"></i>
-                        </button>
-                        <ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
-                            <li role="none"><button role="menuitem" class="theme" id="light">Light</button></li>
-                            <li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
-                            <li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
-                            <li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
-                            <li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
-                        </ul>
-                        {{#if search_enabled}}
-                        <button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
-                            <i class="fa fa-search"></i>
-                        </button>
-                        {{/if}}
-                    </div>
-
-                    <h1 class="menu-title">{{ book_title }}</h1>
-
-                    <div class="right-buttons">
-                        {{#if print_enable}}
-                        <a href="{{ path_to_root }}print.html" title="Print this book" aria-label="Print this book">
-                            <i id="print-button" class="fa fa-print"></i>
+        <header>
+            <nav id="void-nav">
+                <ul>
+                    <li><a id="skip-to-content" tabindex="1" href="#main">Skip to content</a></li>
+                    <li>
+                        <a id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
+                            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20">
+                                <path d="M1 3v2h18V3zm0 8h18V9H1zm0 6h18v-2H1z"/>
+                            </svg>
                         </a>
-                        {{/if}}
-                        {{#if git_repository_url}}
-                        <a href="{{git_repository_url}}" title="Git repository" aria-label="Git repository">
-                            <i id="git-repository-button" class="fa {{git_repository_icon}}"></i>
+                    </li>
+                    <li>
+                        <a id="theme-toggle" class="icon-button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
+                            <svg id="icon-theme-light" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
+                                <path d="M256 159.1c-53.02 0-95.1 42.98-95.1 95.1S202.1 351.1 256 351.1s95.1-42.98 95.1-95.1S309 159.1 256 159.1zM509.3 347L446.1 255.1l63.15-91.01c6.332-9.125 1.104-21.74-9.826-23.72l-109-19.7l-19.7-109c-1.975-10.93-14.59-16.16-23.72-9.824L256 65.89L164.1 2.736c-9.125-6.332-21.74-1.107-23.72 9.824L121.6 121.6L12.56 141.3C1.633 143.2-3.596 155.9 2.736 164.1L65.89 256l-63.15 91.01c-6.332 9.125-1.105 21.74 9.824 23.72l109 19.7l19.7 109c1.975 10.93 14.59 16.16 23.72 9.824L256 446.1l91.01 63.15c9.127 6.334 21.75 1.107 23.72-9.822l19.7-109l109-19.7C510.4 368.8 515.6 356.1 509.3 347zM256 383.1c-70.69 0-127.1-57.31-127.1-127.1c0-70.69 57.31-127.1 127.1-127.1s127.1 57.3 127.1 127.1C383.1 326.7 326.7 383.1 256 383.1z"/>
+                            </svg>
+                            <svg id="icon-theme-dark" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
+                                <path d="M283.211 512c78.962 0 151.079-35.925 198.857-94.792 7.068-8.708-.639-21.43-11.562-19.35-124.203 23.654-238.262-71.576-238.262-196.954 0-72.222 38.662-138.635 101.498-174.394 9.686-5.512 7.25-20.197-3.756-22.23A258.156 258.156 0 0 0 283.211 0c-141.309 0-256 114.511-256 256 0 141.309 114.511 256 256 256z"/>
+                            </svg>
                         </a>
-                        {{/if}}
-                        {{#if git_repository_edit_url}}
+                    </li>
+                    {{#if print_enable}}
+                    <li>
+                        <a href="{{ path_to_root }}print.html" title="Print this book" aria-label="Print this book">
+                            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
+                                <path d="M448 192V77.25c0-8.49-3.37-16.62-9.37-22.63L393.37 9.37c-6-6-14.14-9.37-22.63-9.37H96C78.33 0 64 14.33 64 32v160c-35.35 0-64 28.65-64 64v112c0 8.84 7.16 16 16 16h48v96c0 17.67 14.33 32 32 32h320c17.67 0 32-14.33 32-32v-96h48c8.84 0 16-7.16 16-16V256c0-35.35-28.65-64-64-64zm-64 256H128v-96h256v96zm0-224H128V64h192v48c0 8.84 7.16 16 16 16h48v96zm48 72c-13.25 0-24-10.75-24-24 0-13.26 10.75-24 24-24s24 10.74 24 24c0 13.25-10.75 24-24 24z"/>
+                            </svg>
+                        </a>
+                    </li>
+                    {{/if}}
+                    {{#if git_repository_edit_url}}
+                    <li>
                         <a href="{{git_repository_edit_url}}" title="Suggest an edit" aria-label="Suggest an edit">
-                            <i id="git-edit-button" class="fa fa-edit"></i>
+                            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512">
+                                <path d="M402.6 83.2l90.2 90.2c3.8 3.8 3.8 10 0 13.8L274.4 405.6l-92.8 10.3c-12.4 1.4-22.9-9.1-21.5-21.5l10.3-92.8L388.8 83.2c3.8-3.8 10-3.8 13.8 0zm162-22.9l-48.8-48.8c-15.2-15.2-39.9-15.2-55.2 0l-35.4 35.4c-3.8 3.8-3.8 10 0 13.8l90.2 90.2c3.8 3.8 10 3.8 13.8 0l35.4-35.4c15.2-15.3 15.2-40 0-55.2zM384 346.2V448H64V128h229.8c3.2 0 6.2-1.3 8.5-3.5l40-40c7.6-7.6 2.2-20.5-8.5-20.5H48C21.5 64 0 85.5 0 112v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V306.2c0-10.7-12.9-16-20.5-8.5l-40 40c-2.2 2.3-3.5 5.3-3.5 8.5z"/>
+                            </svg>
                         </a>
-                        {{/if}}
+                    </li>
+                    {{/if}}
+                    {{#if search_enabled}}
+                    <li>
+                        <button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
+                            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20">
+                                <path d="M7.5 13c3.04 0 5.5-2.46 5.5-5.5S10.54 2 7.5 2 2 4.46 2 7.5 4.46 13 7.5 13zm4.55.46C10.79 14.43 9.21 15 7.5 15 3.36 15 0 11.64 0 7.5S3.36 0 7.5 0C11.64 0 15 3.36 15 7.5c0 1.71-.57 3.29-1.54 4.55l6.49 6.49-1.41 1.41-6.49-6.49z"/>
+                            </svg>
+                        </button>
+                    </li>
+                    <noscript>
+                        <li class="js-unavailable">Search functionality requires JavaScript</li>
+                    </noscript>
+                    {{/if}}
+                </ul>
+                <ul id="nav-right">
+                    <li><a href="https://www.voidlinux.org">Home</a></li>
+                    <li><a href="https://www.voidlinux.org/news/">News</a></li>
+                    <li><a href="https://www.voidlinux.org/download/">Download</a></li>
+                    <li><a href="https://www.voidlinux.org/packages/">Packages</a></li>
+                    <li><a href="https://docs.voidlinux.org">Documentation</a></li>
+                    <li><a href="https://man.voidlinux.org/">Manual Pages</a></li>
+                    <li><a href="https://github.com/void-linux">GitHub</a></li>
+                </ul>
+            </nav>
+        </header>
+
+        <div id="content">
+            <!-- Hide / unhide sidebar before it is displayed -->
+            <script type="text/javascript">
+                var html = document.querySelector('html');
+                var sidebar = 'hidden';
+                if (document.body.clientWidth >= 1080) {
+                    try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
+                    sidebar = sidebar || 'visible';
+                }
+                html.classList.remove('sidebar-visible');
+                html.classList.add("sidebar-" + sidebar);
+            </script>
 
-                    </div>
-                </div>
+            <nav id="sidebar" aria-label="Table of contents">
+                {{#toc}}{{/toc}}
+            </nav>
+
+            <div id="page-wrapper" class="page-wrapper">
 
                 {{#if search_enabled}}
                 <div id="search-wrapper" class="hidden">
                     <form id="searchbar-outer" class="searchbar-outer">
-                        <input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
+                        <input type="search" name="search" id="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
                     </form>
                     <div id="searchresults-outer" class="searchresults-outer hidden">
                         <div id="searchresults-header" class="searchresults-header"></div>
@@ -189,44 +164,49 @@
                     });
                 </script>
 
-                <div id="content" class="content">
-                    <main>
-                        {{{ content }}}
-                    </main>
-
-                    <nav class="nav-wrapper" aria-label="Page navigation">
-                        <!-- Mobile navigation buttons -->
-                        {{#previous}}
-                            <a rel="prev" href="{{ path_to_root }}{{link}}" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
-                                <i class="fa fa-angle-left"></i>
-                            </a>
-                        {{/previous}}
-
-                        {{#next}}
-                            <a rel="next prefetch" href="{{ path_to_root }}{{link}}" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
-                                <i class="fa fa-angle-right"></i>
-                            </a>
-                        {{/next}}
+                <main id="main">
+                    {{{ content }}}
+                </main>
+
+                <nav class="nav-wrapper" aria-label="Page navigation">
+                    <!-- Mobile navigation buttons -->
+                    {{#previous}}
+                        <a rel="prev" href="{{ path_to_root }}{{link}}" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
+                            <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20">
+                                <path d="M4 10l9 9 1.4-1.5L7 10l7.4-7.5L13 1z"/>
+                            </svg>
+                        </a>
+                    {{/previous}}
 
-                        <div style="clear: both"></div>
-                    </nav>
-                </div>
-            </div>
+                    {{#next}}
+                        <a rel="next prefetch" href="{{ path_to_root }}{{link}}" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
+                            <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20">
+                                <path d="M7 1L5.6 2.5 13 10l-7.4 7.5L7 19l9-9z"/>
+                            </svg>
+                        </a>
+                    {{/next}}
 
-            <nav class="nav-wide-wrapper" aria-label="Page navigation">
-                {{#previous}}
-                    <a rel="prev" href="{{ path_to_root }}{{link}}" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
-                        <i class="fa fa-angle-left"></i>
-                    </a>
-                {{/previous}}
+                    <div style="clear: both"></div>
+                </nav>
 
-                {{#next}}
-                    <a rel="next prefetch" href="{{ path_to_root }}{{link}}" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
-                        <i class="fa fa-angle-right"></i>
-                    </a>
-                {{/next}}
-            </nav>
+                <nav class="nav-wide-wrapper" aria-label="Page navigation">
+                    {{#previous}}
+                        <a rel="prev" href="{{ path_to_root }}{{link}}" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
+                            <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20">
+                                <path d="M4 10l9 9 1.4-1.5L7 10l7.4-7.5L13 1z"/>
+                            </svg>
+                        </a>
+                    {{/previous}}
 
+                    {{#next}}
+                        <a rel="next" href="{{ path_to_root }}{{link}}" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
+                            <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20">
+                                <path d="M7 1L5.6 2.5 13 10l-7.4 7.5L7 19l9-9z"/>
+                            </svg>
+                        </a>
+                    {{/next}}
+                </nav>
+            </div>
         </div>
 
         {{#if live_reload_endpoint}}
@@ -238,7 +218,7 @@
             socket.onmessage = function (event) {
                 if (event.data === "reload") {
                     socket.close();
-                    location.reload();
+                    location.reload(true); // force reload from server (not from cache)
                 }
             };
 
@@ -248,77 +228,21 @@
         </script>
         {{/if}}
 
-        {{#if google_analytics}}
-        <!-- Google Analytics Tag -->
-        <script>
-            var localAddrs = ["localhost", "127.0.0.1", ""];
-
-            // make sure we don't activate google analytics if the developer is
-            // inspecting the book locally...
-            if (localAddrs.indexOf(document.location.hostname) === -1) {
-                (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
-                (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
-                m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
-                })(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
-
-                ga('create', '{{google_analytics}}', 'auto');
-                ga('send', 'pageview');
-            }
-        </script>
-        {{/if}}
-
-        {{#if playground_line_numbers}}
-        <script>
-            window.playground_line_numbers = true;
-        </script>
-        {{/if}}
-
-        {{#if playground_copyable}}
-        <script>
-            window.playground_copyable = true;
-        </script>
-        {{/if}}
-
-        {{#if playground_js}}
-        <script src="{{ path_to_root }}ace.js"></script>
-        <script src="{{ path_to_root }}editor.js"></script>
-        <script src="{{ path_to_root }}mode-rust.js"></script>
-        <script src="{{ path_to_root }}theme-dawn.js"></script>
-        <script src="{{ path_to_root }}theme-tomorrow_night.js"></script>
-        {{/if}}
-
         {{#if search_js}}
         <script src="{{ path_to_root }}elasticlunr.min.js"></script>
         <script src="{{ path_to_root }}mark.min.js"></script>
         <script src="{{ path_to_root }}searcher.js"></script>
         {{/if}}
 
-        <script src="{{ path_to_root }}clipboard.min.js"></script>
-        <script src="{{ path_to_root }}highlight.js"></script>
         <script src="{{ path_to_root }}book.js"></script>
 
-        <!-- Custom JS scripts -->
-        {{#each additional_js}}
-        <script src="{{ ../path_to_root }}{{this}}"></script>
-        {{/each}}
-
         {{#if is_print}}
-        {{#if mathjax_support}}
-        <script>
-        window.addEventListener('load', function() {
-            MathJax.Hub.Register.StartupHook('End', function() {
-                window.setTimeout(window.print, 100);
-            });
-        });
-        </script>
-        {{else}}
         <script>
         window.addEventListener('load', function() {
             window.setTimeout(window.print, 100);
         });
         </script>
         {{/if}}
-        {{/if}}
 
     </div>
     </body>

From 0a4bb7a7ee452a1ddd5ddc82b479d554e00530e9 Mon Sep 17 00:00:00 2001
From: meator <meator.dev@gmail.com>
Date: Sun, 4 May 2025 15:02:53 +0200
Subject: [PATCH 3/3] UNFINISHED

---
 src/theme/book.js         | 32 ++++++++++++++++++++++++++++++
 src/theme/css/general.css |  5 -----
 src/theme/index.hbs       | 41 ++++++++++++++++++++++++---------------
 3 files changed, 57 insertions(+), 21 deletions(-)

diff --git a/src/theme/book.js b/src/theme/book.js
index 5d311a34c..f5b48662a 100644
--- a/src/theme/book.js
+++ b/src/theme/book.js
@@ -23,6 +23,7 @@ window.onunload = function () { };
     var sidebar = document.getElementById("sidebar");
     var sidebarLinks = document.querySelectorAll('#sidebar a');
     var sidebarToggleButton = document.getElementById("sidebar-toggle");
+    var sidebarResizeHandle = document.getElementById("sidebar-resize-handle");
     var firstContact = null;
 
     function showSidebar() {
@@ -50,6 +51,11 @@ window.onunload = function () { };
     // Toggle sidebar
     sidebarToggleButton.addEventListener('click', function sidebarToggle() {
         if (body.classList.contains("sidebar-hidden")) {
+            var current_width = parseInt(
+                document.documentElement.style.getPropertyValue('--sidebar-width'), 10);
+            if (current_width < 150) {
+                document.documentElement.style.setProperty('--sidebar-width', '150px');
+            }
             showSidebar();
         } else if (body.classList.contains("sidebar-visible")) {
             hideSidebar();
@@ -62,6 +68,32 @@ window.onunload = function () { };
         }
     });
 
+    sidebarResizeHandle.addEventListener('mousedown', initResize, false);
+
+    function initResize(e) {
+        window.addEventListener('mousemove', resize, false);
+        window.addEventListener('mouseup', stopResize, false);
+        body.classList.add('sidebar-resizing');
+    }
+    function resize(e) {
+        var pos = (e.clientX - sidebar.offsetLeft);
+        if (pos < 20) {
+            hideSidebar();
+        } else {
+            if (body.classList.contains("sidebar-hidden")) {
+                showSidebar();
+            }
+            pos = Math.min(pos, window.innerWidth - 100);
+            document.documentElement.style.setProperty('--sidebar-width', pos + 'px');
+        }
+    }
+    //on mouseup remove windows functions mousemove & mouseup
+    function stopResize(e) {
+        body.classList.remove('sidebar-resizing');
+        window.removeEventListener('mousemove', resize, false);
+        window.removeEventListener('mouseup', stopResize, false);
+    }
+
     document.addEventListener('touchstart', function (e) {
         firstContact = {
             x: e.touches[0].clientX,
diff --git a/src/theme/css/general.css b/src/theme/css/general.css
index 50e71dde0..737796d01 100644
--- a/src/theme/css/general.css
+++ b/src/theme/css/general.css
@@ -264,11 +264,6 @@ ul#searchresults span.teaser {
 
 /* chapter navigation */
 
-#nav-wide-wrapper {
-    max-width: 800px;
-    margin: 0 auto;
-    margin-top: 50px;
-}
 .previous {
     float: left;
 }
diff --git a/src/theme/index.hbs b/src/theme/index.hbs
index 776b34537..2c146da23 100644
--- a/src/theme/index.hbs
+++ b/src/theme/index.hbs
@@ -27,6 +27,8 @@
             var path_to_root = "{{ path_to_root }}";
             var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "{{ preferred_dark_theme }}" : "{{ default_theme }}";
         </script>
+        <!-- Start loading toc.js asap -->
+        <script src="{{ path_to_root }}toc.js"></script>
     </head>
     <body>
     <div id="body-container">
@@ -59,6 +61,29 @@
 
         <input type="checkbox" id="sidebar-toggle-anchor" class="hidden">
 
+        <!-- Hide / unhide sidebar before it is displayed -->
+        <script type="text/javascript">
+            var html = document.querySelector('html');
+            var sidebar = 'hidden';
+            if (document.body.clientWidth >= 1080) {
+                try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
+                sidebar = sidebar || 'visible';
+            }
+            html.classList.remove('sidebar-visible');
+            html.classList.add("sidebar-" + sidebar);
+        </script>
+
+        <nav id="sidebar" class="sidebar" aria-label="Table of contents">
+            <!-- populated by js -->
+            <mdbook-sidebar-scrollbox class="sidebar-scrollbox"></mdbook-sidebar-scrollbox>
+            <noscript>
+                <iframe class="sidebar-iframe-outer" src="{{ path_to_root }}toc.html"></iframe>
+            </noscript>
+            <div id="sidebar-resize-handle" class="sidebar-resize-handle">
+                <div class="sidebar-resize-indicator"></div>
+            </div>
+        </nav>
+
         <header>
             <nav id="void-nav">
                 <ul>
@@ -124,22 +149,6 @@
         </header>
 
         <div id="content">
-            <!-- Hide / unhide sidebar before it is displayed -->
-            <script type="text/javascript">
-                var html = document.querySelector('html');
-                var sidebar = 'hidden';
-                if (document.body.clientWidth >= 1080) {
-                    try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
-                    sidebar = sidebar || 'visible';
-                }
-                html.classList.remove('sidebar-visible');
-                html.classList.add("sidebar-" + sidebar);
-            </script>
-
-            <nav id="sidebar" aria-label="Table of contents">
-                {{#toc}}{{/toc}}
-            </nav>
-
             <div id="page-wrapper" class="page-wrapper">
 
                 {{#if search_enabled}}