diff --git a/docs/mesa3d_theme/layout.html b/docs/mesa3d_theme/layout.html
new file mode 100644
index 00000000000..e7312d773d3
--- /dev/null
+++ b/docs/mesa3d_theme/layout.html
@@ -0,0 +1,173 @@
+{% extends "basic/layout.html" %}
+
+{% block css %}
+
+ {{ css() }}
+{% endblock %}
+
+{% block extrahead %}
+
+{% endblock %}
+
+{% block body_tag %}
+
+{% endblock %}
+
+{% block relbar1 %}{% endblock %}
+{% block relbar2 %}{% endblock %}
+
+{% block header %}
+
+{% endblock %}
+
+{% block content %}
+
+
+
+ {% block body %}{% endblock %}
+
+
+ {% block navigation %}
+
+ {% endblock %}
+
+
+{% endblock %}
+
+{% block footer %}
+
+
+
+{% endblock %}
diff --git a/docs/mesa3d_theme/search.html b/docs/mesa3d_theme/search.html
new file mode 100644
index 00000000000..f369ed634a6
--- /dev/null
+++ b/docs/mesa3d_theme/search.html
@@ -0,0 +1,15 @@
+{% extends "basic/search.html" %}
+
+{% block scriptwarning %}
+
+
+
{{ _('Warning') }}
+
+{% trans %}Please activate JavaScript to enable the search
+functionality.{% endtrans %}
+
+
+{% endblock %}
+
+{% block searchbox %}
+{% endblock %}
diff --git a/docs/mesa3d_theme/static/chevron-up.svg b/docs/mesa3d_theme/static/chevron-up.svg
new file mode 100644
index 00000000000..0ab171b7d2e
--- /dev/null
+++ b/docs/mesa3d_theme/static/chevron-up.svg
@@ -0,0 +1,10 @@
+
diff --git a/docs/mesa3d_theme/static/link.svg b/docs/mesa3d_theme/static/link.svg
new file mode 100644
index 00000000000..e9e660d0a32
--- /dev/null
+++ b/docs/mesa3d_theme/static/link.svg
@@ -0,0 +1,10 @@
+
diff --git a/docs/mesa3d_theme/static/logo.svg b/docs/mesa3d_theme/static/logo.svg
new file mode 100644
index 00000000000..1028c6d94e9
--- /dev/null
+++ b/docs/mesa3d_theme/static/logo.svg
@@ -0,0 +1,9 @@
+
diff --git a/docs/mesa3d_theme/static/menu.css b/docs/mesa3d_theme/static/menu.css
new file mode 100644
index 00000000000..cacf8dabe76
--- /dev/null
+++ b/docs/mesa3d_theme/static/menu.css
@@ -0,0 +1,76 @@
+#menu {
+ height: max-content;
+}
+
+#menu .caption {
+ cursor: pointer;
+ margin-bottom: 0;
+}
+
+#menu a {
+ color: inherit;
+ text-overflow: ellipsis;
+ overflow: hidden;
+ display: block;
+ text-decoration: none;
+}
+
+#menu a[href^="#"] {
+ color: var(--bs-secondary-color);
+}
+
+#menu .caption,
+#menu li {
+ margin-top: 0.25rem;
+}
+
+#menu .caption-text,
+#menu li.current {
+ font-weight: bold;
+}
+
+#menu li.current > a {
+ color: var(--bs-body-color)
+}
+
+#menu li.current li {
+ font-weight: initial;
+}
+
+#menu ul {
+ list-style-type: none;
+ padding-left: 0;
+ padding-left: 1rem;
+ margin-bottom: 0.5rem;
+}
+
+#menu ul:last-of-type {
+ margin-bottom: 0;
+}
+
+#menu p.caption::after {
+ display: block;
+ content: '';
+ clear: both;
+}
+
+#menu .collapse-icon .caption-text:after {
+ content: ' ';
+ float: right;
+ display: block;
+ background-image: url('chevron-up.svg');
+ background-size: 1.5em 1.5em;
+ opacity: 0.25;
+ width: 1.5em;
+ height: 1.5em;
+}
+
+@media (prefers-reduced-motion: no-preference) {
+ #menu .collapse-icon .caption-text:after {
+ transition: transform 0.2s;
+ }
+}
+
+#menu .collapse-icon.collapsed .caption-text:after {
+ transform: rotate(180deg);
+}
diff --git a/docs/mesa3d_theme/static/rst.css b/docs/mesa3d_theme/static/rst.css
new file mode 100644
index 00000000000..421a982263d
--- /dev/null
+++ b/docs/mesa3d_theme/static/rst.css
@@ -0,0 +1,73 @@
+.headerlink {
+ color: transparent;
+ display: inline-block;
+ vertical-align: middle;
+ background-image: url('link.svg');
+ background-size: 1ex 1ex;
+ margin-left: 0.25rem;
+ opacity: 0.25;
+ width: 1ex;
+ height: 1ex;
+ user-select: none;
+}
+
+.headerlink:hover {
+ opacity: 0.5;
+}
+
+.highlight {
+ border-radius: var(--bs-border-radius-sm);
+ padding: .5rem;
+ color: var(--bs-dark);
+ margin-bottom: 1rem;
+}
+
+.highlight > pre {
+ margin-bottom: 0;
+}
+
+dd {
+ margin-left: 2rem;
+}
+
+.sig {
+ font-family: var(--bs-font-monospace);
+ color: var(--bs-code-color);
+}
+
+dt.sig {
+ color: var(--bs-heading-color, inherit);
+}
+
+dl > .sig.c {
+ background-color: var(--bs-secondary-bg);
+ color: var(--bs-secondary);
+ padding: 0.25rem 0.5rem;
+ border-radius: var(--bs-border-radius-sm);
+}
+
+dl > .sig.c .sig-name {
+ color: var(--bs-secondary-text);
+}
+
+main .container {
+ padding: 0;
+}
+
+li > p:last-of-type,
+th > p:last-of-type,
+td > p:last-of-type,
+.alert > p:last-of-type {
+ margin-bottom: 0;
+}
+
+div.code-block-caption {
+ font-size: .875em;
+ color: var(--bs-secondary-color);
+ margin-bottom: 0.5rem;
+}
+
+.alert a {
+ font-weight: 700;
+ color: var(--bs-alert-link-color);
+}
diff --git a/docs/mesa3d_theme/static/screen.css_t b/docs/mesa3d_theme/static/screen.css_t
new file mode 100644
index 00000000000..7da46e264f3
--- /dev/null
+++ b/docs/mesa3d_theme/static/screen.css_t
@@ -0,0 +1,98 @@
+@import url("menu.css");
+@import url("rst.css");
+
+html {
+ height: 100%;
+}
+
+.navbar {
+ flex: none;
+}
+
+
+h1, h2, h3, h4, h5, h6,
+.h1, .h2, .h3, .h4, .h5, .h6 {
+ font-weight: 600 !important;
+}
+
+footer {
+ flex: 1;
+}
+
+footer a:any-link {
+ color: inherit;
+ text-decoration: none;
+}
+
+{%- if docutils_version_info[:2] < (0, 18) %}
+
+a.brackets::before,
+span.brackets::before {
+ content: "[";
+}
+
+a.brackets::after,
+span.brackets::after {
+ content: "]";
+}
+
+span.brackets {
+ font-weight: normal;
+}
+
+dl.footnote,
+dl.citation {
+ margin-bottom: 0;
+}
+
+dl.footnote > dt,
+dl.citation > dt {
+ float: left;
+}
+dl.footnote > dd,
+dl.citation > dd {
+ margin-bottom: 0;
+}
+dl.footnote > dd:after,
+dl.citation > dd:after {
+ content: "";
+ clear: both;
+}
+dl.footnote > dd > p {
+ margin-left: 2rem;
+}
+dl.citation > dd > p {
+ margin-left: 4rem;
+}
+dl.footnote > dd > p:last-of-type,
+dl.citation > dd > p:last-of-type {
+ margin-bottom: 0;
+}
+
+{%- else %}
+
+aside.footnote > span,
+div.citation > span {
+ float: left;
+}
+aside.footnote > span:last-of-type,
+div.citation > span:last-of-type {
+ padding-right: 0.5rem;
+}
+aside.footnote > p {
+ margin-left: 2rem;
+}
+div.citation > p {
+ margin-left: 4rem;
+}
+aside.footnote > p:last-of-type,
+div.citation > p:last-of-type {
+ margin-bottom: 0;
+}
+aside.footnote > p:last-of-type:after,
+div.citation > p:last-of-type:after {
+ content: "";
+ clear: both;
+}
+
+{%- endif %}
diff --git a/docs/mesa3d_theme/theme.conf b/docs/mesa3d_theme/theme.conf
new file mode 100644
index 00000000000..6478dad3214
--- /dev/null
+++ b/docs/mesa3d_theme/theme.conf
@@ -0,0 +1,5 @@
+[theme]
+inherit = basic
+stylesheet = screen.css
+pygments_style = default
+pygments_dark_style = github-dark