diff --git a/src/components/nodes/SettingsTabBar.tsx b/src/components/nodes/SettingsTabBar.tsx
new file mode 100644
index 00000000..c4195864
--- /dev/null
+++ b/src/components/nodes/SettingsTabBar.tsx
@@ -0,0 +1,46 @@
+import React from "react";
+
+interface SettingsTabBarProps {
+ activeTab: "primary" | "fallback";
+ onTabChange: (tab: "primary" | "fallback") => void;
+ primaryLabel: string;
+ fallbackLabel: string;
+}
+
+export function SettingsTabBar({
+ activeTab,
+ onTabChange,
+ primaryLabel,
+ fallbackLabel,
+}: SettingsTabBarProps) {
+ return (
+
+
+
+
+ );
+}
diff --git a/src/components/nodes/__tests__/SettingsTabBar.test.tsx b/src/components/nodes/__tests__/SettingsTabBar.test.tsx
new file mode 100644
index 00000000..c21f08ff
--- /dev/null
+++ b/src/components/nodes/__tests__/SettingsTabBar.test.tsx
@@ -0,0 +1,67 @@
+import { describe, it, expect, vi } from "vitest";
+import { render, screen, fireEvent } from "@testing-library/react";
+import { SettingsTabBar } from "../SettingsTabBar";
+
+describe("SettingsTabBar", () => {
+ it("renders both tab labels", () => {
+ render(
+
+ );
+
+ expect(screen.getByText("Nano Banana")).toBeInTheDocument();
+ expect(screen.getByText("Flux Dev")).toBeInTheDocument();
+ });
+
+ it("highlights active tab", () => {
+ render(
+
+ );
+
+ const primaryTab = screen.getByText("Nano Banana");
+ const fallbackTab = screen.getByText("Flux Dev");
+
+ // Active tab should have bg-neutral-700 class
+ expect(primaryTab.className).toContain("bg-neutral-700");
+ expect(fallbackTab.className).not.toContain("bg-neutral-700");
+ });
+
+ it("calls onTabChange when clicking inactive tab", () => {
+ const onTabChange = vi.fn();
+ render(
+
+ );
+
+ fireEvent.click(screen.getByText("Flux Dev"));
+ expect(onTabChange).toHaveBeenCalledWith("fallback");
+ });
+
+ it("does not call onTabChange when clicking active tab", () => {
+ const onTabChange = vi.fn();
+ render(
+
+ );
+
+ fireEvent.click(screen.getByText("Nano Banana"));
+ expect(onTabChange).not.toHaveBeenCalled();
+ });
+});