diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml
index 5c8ff289d..f30c77573 100644
--- a/docs/mkdocs.yml
+++ b/docs/mkdocs.yml
@@ -398,4 +398,6 @@ extra_css:
- stylesheets/logos.css
- stylesheets/sticky_navigation.css
- stylesheets/agent_graph_widget.css
-
+ - language-switcher.css
+extra_javascript:
+ - language-switcher.js
\ No newline at end of file
diff --git a/docs/overrides/language-switcher.css b/docs/overrides/language-switcher.css
new file mode 100644
index 000000000..63453ffd9
--- /dev/null
+++ b/docs/overrides/language-switcher.css
@@ -0,0 +1,41 @@
+.lang-python,
+.lang-javascript {
+ display: none;
+}
+
+.language-switcher-global {
+ display: flex;
+ align-items: center;
+ padding-left: 0.5rem;
+ margin-right: 0.5rem;
+}
+
+/* Style the select to match the header */
+.language-switcher-global select {
+ appearance: none;
+ font: inherit;
+ border: none;
+ padding: 0.25rem 0.6rem;
+ cursor: pointer;
+ outline: none;
+ font-weight: bolder;
+}
+
+/* Hover/focus effect */
+.language-switcher-global select:hover,
+.language-switcher-global select:focus {
+ text-decoration: underline;
+}
+
+/* Theme-specific overrides */
+html[data-md-color-scheme="default"] .language-switcher-global select,
+html[data-md-color-scheme="default"] .language-switcher-global option {
+ color: #333;
+ background-color: transparent;
+}
+
+html[data-md-color-scheme="slate"] .language-switcher-global select,
+html[data-md-color-scheme="slate"] .language-switcher-global option {
+ color: #eee;
+ background-color: transparent;
+}
diff --git a/docs/overrides/language-switcher.js b/docs/overrides/language-switcher.js
new file mode 100644
index 000000000..51032723b
--- /dev/null
+++ b/docs/overrides/language-switcher.js
@@ -0,0 +1,38 @@
+function applyLanguageSwitching() {
+ const selector = document.getElementById("global-language-selector");
+
+ const langBlocks = {
+ python: document.querySelectorAll(".lang-python"),
+ javascript: document.querySelectorAll(".lang-javascript"),
+ };
+
+ const setLanguage = (lang) => {
+ for (const [key, blocks] of Object.entries(langBlocks)) {
+ blocks.forEach((block) => {
+ block.style.display = key === lang ? "block" : "none";
+ });
+ }
+ localStorage.setItem("preferredLang", lang);
+ };
+
+ const saved = localStorage.getItem("preferredLang") || "python";
+
+ if (selector) {
+ selector.value = saved;
+ selector.addEventListener("change", (e) => setLanguage(e.target.value));
+ }
+
+ setLanguage(saved);
+}
+
+// Run on initial load
+document.addEventListener("DOMContentLoaded", applyLanguageSwitching);
+
+// Re-run after client-side navigation (MkDocs Material)
+document.addEventListener("pjax:success", applyLanguageSwitching);
+
+// Optional: observe DOM changes (e.g., for late-loaded content)
+if (window.MutationObserver) {
+ const observer = new MutationObserver(() => applyLanguageSwitching());
+ observer.observe(document.body, { childList: true, subtree: true });
+}
diff --git a/docs/overrides/partials/header.html b/docs/overrides/partials/header.html
new file mode 100644
index 000000000..61874621a
--- /dev/null
+++ b/docs/overrides/partials/header.html
@@ -0,0 +1,70 @@
+{#-
+ This file was automatically generated - do not edit
+-#}
+{% set class = "md-header" %}
+{% if "navigation.tabs.sticky" in features %}
+ {% set class = class ~ " md-header--shadow md-header--lifted" %}
+{% elif "navigation.tabs" not in features %}
+ {% set class = class ~ " md-header--shadow" %}
+{% endif %}
+