diff --git a/libraries/templatetags/branch_url_tag.py b/libraries/templatetags/branch_url_tag.py
index baf8e97db..1433561be 100644
--- a/libraries/templatetags/branch_url_tag.py
+++ b/libraries/templatetags/branch_url_tag.py
@@ -6,5 +6,4 @@
@register.simple_tag()
def branch_url_tag(view: str, branch: str, kwargs: dict):
- kwargs["version_slug"] = branch
- return reverse(view, kwargs=kwargs)
+ return reverse(view, kwargs={**kwargs, "version_slug": branch})
diff --git a/static/css/v3/branch-buttons.css b/static/css/v3/branch-buttons.css
new file mode 100644
index 000000000..bcd7b9915
--- /dev/null
+++ b/static/css/v3/branch-buttons.css
@@ -0,0 +1,86 @@
+/*
+ Branch Buttons — small Master ("M") / Develop ("D") version-switch links.
+ Depends on: foundations.css, semantics.css, spacing.css, border-radius.css
+*/
+
+.branch-buttons {
+ display: flex;
+ align-items: center;
+ gap: var(--space-s);
+}
+
+.branch-button {
+ position: relative;
+ display: inline-block;
+ flex-shrink: 0;
+ width: 29px;
+ height: 28px;
+ color: var(--color-text-primary);
+ text-decoration: none;
+}
+
+.branch-button__square {
+ position: absolute;
+ top: 4px;
+ left: 5px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 24px;
+ height: 24px;
+ background-color: var(--color-surface-weak);
+ border: 1px solid var(--color-stroke-weak);
+ border-radius: var(--border-radius-s);
+ transition: border-color 0.15s ease;
+}
+
+.branch-button__icon {
+ width: 16px;
+ height: 16px;
+ color: var(--color-text-primary);
+}
+
+.branch-button__badge {
+ position: absolute;
+ top: 0;
+ left: 0;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ min-width: 12px;
+ padding: 2px;
+ border-radius: 60px;
+ background-color: var(--color-button-accent);
+ color: var(--color-text-on-accent);
+ font-size: 8px;
+ line-height: 1;
+ letter-spacing: -0.08px;
+ text-align: center;
+}
+
+.branch-button:hover .branch-button__square {
+ border-color: var(--color-stroke-brand-accent);
+}
+
+.branch-button:focus-visible {
+ outline: 2px solid var(--color-stroke-brand-accent);
+ outline-offset: 2px;
+ border-radius: var(--border-radius-s);
+}
+
+/* Sub-page hero: far right, bottom-aligned with the actions row; right edge
+ inset to line up with the content cards below. */
+.hero-library__main > .branch-buttons {
+ align-self: flex-end;
+ flex-shrink: 0;
+ margin-right: var(--space-large);
+}
+
+/* Mobile: stacks below the actions row, left-aligned with the cards. */
+@media (max-width: 767px) {
+ .hero-library__main > .branch-buttons {
+ align-self: flex-start;
+ margin-right: 0;
+ margin-top: var(--space-large);
+ }
+}
diff --git a/static/css/v3/components.css b/static/css/v3/components.css
index 290733966..2e77e0792 100644
--- a/static/css/v3/components.css
+++ b/static/css/v3/components.css
@@ -42,6 +42,7 @@
@import "./user-card.css";
@import "./post-filter.css";
@import "./library-filter.css";
+@import "./branch-buttons.css";
@import "./contributors-list.css";
@import "./card-group.css";
@import "./post-card.css";
diff --git a/static/css/v3/library-page.css b/static/css/v3/library-page.css
index c1f8b41e0..8abc60cb3 100644
--- a/static/css/v3/library-page.css
+++ b/static/css/v3/library-page.css
@@ -18,6 +18,23 @@
padding: 0 var(--space-large);
}
+/* Filter toolbar row: filters fill the row, branch buttons sit at the far right,
+ bottom-aligned with the filter dropdowns. */
+.library-page__filter-row {
+ display: flex;
+ align-items: flex-end;
+ gap: var(--space-medium);
+}
+
+.library-page__filter-row .library-filter {
+ flex: 1 1 auto;
+ min-width: 0;
+}
+
+.library-page__filter-row .branch-buttons {
+ flex: 0 0 auto;
+}
+
/* === Hero === */
.library-page-hero {
diff --git a/templates/includes/icon.html b/templates/includes/icon.html
index cb5357ea2..463cbb41a 100644
--- a/templates/includes/icon.html
+++ b/templates/includes/icon.html
@@ -139,6 +139,8 @@