This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/main by this push:
     new 9e4d264f6058 camel-jbang - TUI expand theme system to 13 named themes 
with live-preview picker
9e4d264f6058 is described below

commit 9e4d264f6058df95f4984ef1e221d2549ce0e272
Author: Claus Ibsen <[email protected]>
AuthorDate: Thu Jul 9 07:17:41 2026 +0200

    camel-jbang - TUI expand theme system to 13 named themes with live-preview 
picker
    
    camel-jbang - TUI use native accent colors per theme instead of Camel orange
    
    camel-jbang - TUI add Monochrome and CRT themes, tone down light theme 
accent
    
    camel-jbang - TUI fix hint-key contrast on themes with dark brand colors
    
    camel-jbang - TUI add MCP tools tui_get_themes and tui_set_theme
    
    Co-Authored-By: Claude Opus 4.6 <[email protected]>
    Signed-off-by: Claus Ibsen <[email protected]>
---
 .../dsl/jbang/core/commands/tui/ActionsPopup.java  |  58 +++--
 .../dsl/jbang/core/commands/tui/CamelMonitor.java  |   7 +-
 .../camel/dsl/jbang/core/commands/tui/Theme.java   |  46 +++-
 .../dsl/jbang/core/commands/tui/ThemeMode.java     |  54 +++-
 .../dsl/jbang/core/commands/tui/ThemePopup.java    | 276 +++++++++++++++++++++
 .../dsl/jbang/core/commands/tui/TuiIcons.java      |   1 +
 .../dsl/jbang/core/commands/tui/TuiMcpServer.java  |  49 ++++
 .../resources/tui/themes/catppuccin-latte.tcss     |  54 ++++
 .../themes/{light.tcss => catppuccin-mocha.tcss}   |  54 ++--
 .../src/main/resources/tui/themes/crt.tcss         |  54 ++++
 .../tui/themes/{light.tcss => dracula.tcss}        |  54 ++--
 .../tui/themes/{light.tcss => everforest.tcss}     |  54 ++--
 .../tui/themes/{light.tcss => gruvbox-dark.tcss}   |  54 ++--
 .../src/main/resources/tui/themes/kanagawa.tcss    |  54 ++++
 .../src/main/resources/tui/themes/light.tcss       |   4 +-
 .../src/main/resources/tui/themes/monochrome.tcss  |  54 ++++
 .../resources/tui/themes/{light.tcss => nord.tcss} |  54 ++--
 .../tui/themes/{light.tcss => rose-pine.tcss}      |  54 ++--
 .../tui/themes/{light.tcss => solarized-dark.tcss} |  54 ++--
 .../main/resources/tui/themes/solarized-light.tcss |  54 ++++
 .../src/main/resources/tui/themes/tokyo-night.tcss |  54 ++++
 .../tui/ThemeModeCompletionCandidatesTest.java     |   7 +-
 .../dsl/jbang/core/commands/tui/ThemeModeTest.java |  31 ++-
 .../dsl/jbang/core/commands/tui/ThemeTest.java     |  69 +++++-
 24 files changed, 1066 insertions(+), 238 deletions(-)

diff --git 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ActionsPopup.java
 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ActionsPopup.java
index acd322e03f8b..75be54bd7bf2 100644
--- 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ActionsPopup.java
+++ 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ActionsPopup.java
@@ -66,6 +66,7 @@ class ActionsPopup {
         BACK,
         SCREENSHOT,
         TOGGLE_THEME,
+        THEMES_SUBMENU,
         RESET_SCREEN,
         TAPE_RECORDING,
         TAPE_INSTRUCTIONS,
@@ -87,7 +88,7 @@ class ActionsPopup {
     private final Runnable burstCallback;
     private Runnable resetStatsAction;
     private Runnable resetScreenAction;
-    private Runnable themeToggleAction;
+    private Runnable themeRefreshAction;
     private Runnable openShellAction;
     private Runnable browseFilesAction;
     private Runnable switchIntegrationAction;
@@ -106,6 +107,7 @@ class ActionsPopup {
     private Rect actionsMenuRect;
 
     private final GotoTabPopup gotoTabPopup = new GotoTabPopup();
+    private final ThemePopup themePopup = new ThemePopup();
     private final DocViewerPopup docViewerPopup = new DocViewerPopup();
 
     private final ExampleBrowserPopup exampleBrowserPopup;
@@ -177,8 +179,9 @@ class ActionsPopup {
         this.resetScreenAction = resetScreenAction;
     }
 
-    void setThemeToggleAction(Runnable themeToggleAction) {
-        this.themeToggleAction = themeToggleAction;
+    void setThemeRefreshAction(Runnable themeRefreshAction) {
+        this.themeRefreshAction = themeRefreshAction;
+        themePopup.setThemeRefreshAction(themeRefreshAction);
     }
 
     void setOpenShellAction(Runnable openShellAction) {
@@ -264,7 +267,7 @@ class ActionsPopup {
         List<Action> flat = new ArrayList<>();
         flat.add(Action.BACK);
         flat.add(null);
-        flat.addAll(List.of(Action.SCREENSHOT, Action.TOGGLE_THEME, 
Action.RESET_SCREEN));
+        flat.addAll(List.of(Action.SCREENSHOT, Action.THEMES_SUBMENU, 
Action.RESET_SCREEN));
         flat.add(null);
         flat.addAll(List.of(Action.TAPE_RECORDING, Action.TAPE_INSTRUCTIONS, 
Action.CAPTION, Action.SHOW_KEYSTROKES));
         return flat;
@@ -312,7 +315,8 @@ class ActionsPopup {
     }
 
     boolean isVisible() {
-        return showActionsMenu || gotoTabPopup.isVisible() || 
exampleBrowserPopup.isVisible()
+        return showActionsMenu || themePopup.isVisible() || 
gotoTabPopup.isVisible()
+                || exampleBrowserPopup.isVisible()
                 || folderInputPopup.isVisible()
                 || runOptionsForm.isVisible()
                 || docViewerPopup.isVisible()
@@ -322,6 +326,9 @@ class ActionsPopup {
     }
 
     SelectionContext getSelectionContext() {
+        if (themePopup.isVisible()) {
+            return themePopup.getSelectionContext();
+        }
         if (gotoTabPopup.isVisible()) {
             return gotoTabPopup.getSelectionContext();
         }
@@ -353,7 +360,7 @@ class ActionsPopup {
             labels.add("..");
             labels.add("───");
             labels.add("Take Screenshot");
-            labels.add(Theme.isDark() ? "Light Theme" : "Dark Theme");
+            labels.add("Themes...");
             labels.add("Reset Screen");
             labels.add("───");
             labels.add(tapeRecordingActive.get() ? "Stop Tape Recording" : 
"Start Tape Recording");
@@ -403,6 +410,7 @@ class ActionsPopup {
     void close() {
         showActionsMenu = false;
         currentSubmenu = null;
+        themePopup.close();
         gotoTabPopup.close();
         exampleBrowserPopup.close();
         folderInputPopup.close();
@@ -507,6 +515,9 @@ class ActionsPopup {
         if (doctorPopup.handleKeyEvent(ke)) {
             return true;
         }
+        if (themePopup.handleKeyEvent(ke)) {
+            return true;
+        }
         if (gotoTabPopup.isVisible()) {
             boolean wasVisible = gotoTabPopup.isVisible();
             gotoTabPopup.handleKeyEvent(ke);
@@ -551,6 +562,9 @@ class ActionsPopup {
                     } else if (action == Action.BACK) {
                         currentSubmenu = null;
                         actionsMenuState.select(savedMainSelection);
+                    } else if (action == Action.THEMES_SUBMENU) {
+                        showActionsMenu = false;
+                        themePopup.open();
                     } else if (action == Action.SCREEN_SUBMENU) {
                         savedMainSelection = sel;
                         currentSubmenu = "screen";
@@ -633,8 +647,9 @@ class ActionsPopup {
                             resetScreenAction.run();
                         }
                     } else if (action == Action.TOGGLE_THEME) {
+                        Theme.toggle();
+                        refreshTheme();
                         showActionsMenu = false;
-                        toggleTheme();
                     } else if (action == Action.STOP_ALL) {
                         showActionsMenu = false;
                         stopAllPopup.open();
@@ -663,6 +678,9 @@ class ActionsPopup {
         if (!isVisible()) {
             return false;
         }
+        if (themePopup.isVisible()) {
+            return themePopup.handleMouseEvent(me);
+        }
         if (gotoTabPopup.isVisible()) {
             return gotoTabPopup.handleMouseEvent(me);
         }
@@ -726,6 +744,9 @@ class ActionsPopup {
     }
 
     void render(Frame frame, Rect area) {
+        if (themePopup.isVisible()) {
+            themePopup.render(frame, area);
+        }
         if (gotoTabPopup.isVisible()) {
             gotoTabPopup.render(frame, area);
         }
@@ -812,6 +833,10 @@ class ActionsPopup {
             exampleBrowserPopup.renderFooter(spans);
             return;
         }
+        if (themePopup.isVisible()) {
+            themePopup.renderFooter(spans);
+            return;
+        }
         if (gotoTabPopup.isVisible()) {
             hint(spans, "type", "filter");
             hint(spans, TuiIcons.HINT_SCROLL, "navigate");
@@ -920,15 +945,11 @@ class ActionsPopup {
         String tapeLabel = tapeRecordingActive.get()
                 ? TuiIcons.menuItem(TuiIcons.STOP, "Stop Tape Recording 
(Ctrl+R)")
                 : TuiIcons.menuItem(TuiIcons.RECORD, "Start Tape Recording 
(Ctrl+R)");
-        String themeLabel = Theme.isDark()
-                ? TuiIcons.menuItem(TuiIcons.LIGHT_THEME, "Light Theme")
-                : TuiIcons.menuItem(TuiIcons.DARK_THEME, "Dark Theme");
-
         List<ListItem> items = new ArrayList<>();
         items.add(ListItem.from("  .."));
         items.add(ListItem.from(divider).style(Style.EMPTY.dim()));
         items.add(ListItem.from(TuiIcons.menuItem(TuiIcons.SCREENSHOT, "Take 
Screenshot")));
-        items.add(ListItem.from(themeLabel));
+        items.add(ListItem.from(TuiIcons.menuItem(TuiIcons.THEMES, 
"Themes...")));
         items.add(ListItem.from(TuiIcons.menuItem(TuiIcons.CLEAN, "Reset 
Screen")));
         items.add(ListItem.from(divider).style(Style.EMPTY.dim()));
         items.add(ListItem.from(tapeLabel));
@@ -1185,7 +1206,10 @@ class ActionsPopup {
                     resetScreenAction.run();
                 }
             }
-            case TOGGLE_THEME -> toggleTheme();
+            case TOGGLE_THEME -> {
+                Theme.toggle();
+                refreshTheme();
+            }
             case SCREENSHOT -> screenshotAction.run();
             case SHOW_KEYSTROKES -> toggleKeystrokes.run();
             case TAPE_RECORDING -> toggleTapeRecording.run();
@@ -1206,11 +1230,9 @@ class ActionsPopup {
         return gotoTabPopup.consumePendingEntry();
     }
 
-    private void toggleTheme() {
-        if (themeToggleAction != null) {
-            themeToggleAction.run();
-        } else {
-            Theme.toggle();
+    private void refreshTheme() {
+        if (themeRefreshAction != null) {
+            themeRefreshAction.run();
         }
     }
 
diff --git 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/CamelMonitor.java
 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/CamelMonitor.java
index 37114e80abfb..0339c91c4361 100644
--- 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/CamelMonitor.java
+++ 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/CamelMonitor.java
@@ -110,7 +110,7 @@ public class CamelMonitor extends CamelCommand {
     int mcpPort = 8123;
 
     @CommandLine.Option(names = { "--theme" },
-                        description = "Color theme: dark or light (overrides 
persisted preference for this session)",
+                        description = "Color theme (overrides persisted 
preference for this session)",
                         completionCandidates = 
ThemeModeCompletionCandidates.class)
     String theme;
 
@@ -463,10 +463,7 @@ public class CamelMonitor extends CamelCommand {
             ctx.runner = tui;
             actionsPopup.setScheduler(tui.scheduler());
             actionsPopup.setResetScreenAction(() -> tui.terminal().clear());
-            actionsPopup.setThemeToggleAction(() -> {
-                Theme.toggle();
-                tui.terminal().clear();
-            });
+            actionsPopup.setThemeRefreshAction(() -> tui.terminal().clear());
             // Preload diagram data if an integration was auto-selected
             tabRegistry.routesTab().preloadDiagram();
             tabRegistry.diagramTab().preloadDiagram();
diff --git 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/Theme.java
 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/Theme.java
index 9d2a2b54b729..b03634569bef 100644
--- 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/Theme.java
+++ 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/Theme.java
@@ -108,6 +108,7 @@ public final class Theme {
     private static boolean testMode;
     private static StyleEngine engine;
     private static ThemeMode mode = ThemeMode.DARK;
+    private static ThemeMode previewOriginal;
 
     private Theme() {
     }
@@ -315,9 +316,49 @@ public final class Theme {
         return mode == ThemeMode.DARK;
     }
 
-    /** Flip the active theme mode, persist it (outside test mode), and 
activate it, returning the new mode. */
+    /** Cycle to the next theme in declaration order, persist it (outside test 
mode), and activate it. */
     public static synchronized String toggle() {
-        ThemeMode next = mode.toggle();
+        ThemeMode next = mode.next();
+        if (!testMode) {
+            persist(next);
+        }
+        activate(next, false);
+        return next.id();
+    }
+
+    /** Apply a theme as a live preview without persisting. Saves the original 
mode on the first call in a sequence. */
+    public static synchronized void preview(String modeId) {
+        if (previewOriginal == null) {
+            previewOriginal = mode;
+        }
+        activate(ThemeMode.parseOrDefault(modeId), false);
+    }
+
+    /** Restore the theme that was active before previewing started. No-op if 
not previewing. */
+    public static synchronized void revertPreview() {
+        if (previewOriginal != null) {
+            ThemeMode original = previewOriginal;
+            previewOriginal = null;
+            activate(original, false);
+        }
+    }
+
+    /** Persist the currently previewed theme and clear the preview state. */
+    public static synchronized void confirmPreview() {
+        previewOriginal = null;
+        if (!testMode) {
+            persist(mode);
+        }
+    }
+
+    /** The persisted theme mode id (unaffected by an in-progress preview). */
+    public static synchronized String persistedMode() {
+        return previewOriginal != null ? previewOriginal.id() : mode.id();
+    }
+
+    /** Apply and persist a specific theme. For programmatic / MCP use. */
+    public static synchronized String setTheme(String modeId) {
+        ThemeMode next = ThemeMode.parseOrDefault(modeId);
         if (!testMode) {
             persist(next);
         }
@@ -370,6 +411,7 @@ public final class Theme {
         persistedReadFallbackLogged = false;
         persistedWriteFallbackLogged = false;
         persistedModeLoaded = false;
+        previewOriginal = null;
         CACHE.clear();
         engine = null;
         initialized = false;
diff --git 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ThemeMode.java
 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ThemeMode.java
index 812505ae8233..a800053c8de0 100644
--- 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ThemeMode.java
+++ 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ThemeMode.java
@@ -21,31 +21,59 @@ import java.util.List;
 import java.util.Locale;
 import java.util.Optional;
 
-/** Canonical dark/light palette selector for the Camel TUI. */
+/** Named color theme selector for the Camel TUI. */
 enum ThemeMode {
 
-    DARK("dark"),
-    LIGHT("light");
+    DARK("dark", "Dark", false),
+    LIGHT("light", "Light", true),
+    DRACULA("dracula", "Dracula", false),
+    NORD("nord", "Nord", false),
+    SOLARIZED_DARK("solarized-dark", "Solarized Dark", false),
+    SOLARIZED_LIGHT("solarized-light", "Solarized Light", true),
+    GRUVBOX_DARK("gruvbox-dark", "Gruvbox Dark", false),
+    CATPPUCCIN_MOCHA("catppuccin-mocha", "Catppuccin Mocha", false),
+    CATPPUCCIN_LATTE("catppuccin-latte", "Catppuccin Latte", true),
+    TOKYO_NIGHT("tokyo-night", "Tokyo Night", false),
+    ROSE_PINE("rose-pine", "Rosé Pine", false),
+    KANAGAWA("kanagawa", "Kanagawa", false),
+    EVERFOREST("everforest", "Everforest", false),
+    MONOCHROME("monochrome", "Monochrome", false),
+    CRT("crt", "CRT", false);
 
     private final String id;
+    private final String label;
+    private final boolean light;
 
-    ThemeMode(String id) {
+    ThemeMode(String id, String label, boolean light) {
         this.id = id;
+        this.label = label;
+        this.light = light;
     }
 
-    /** Lowercase config / CLI value ({@code dark} or {@code light}). */
+    /** Lowercase config / CLI value (e.g. {@code dark}, {@code 
catppuccin-mocha}). */
     String id() {
         return id;
     }
 
+    /** Human-readable display name (e.g. {@code Catppuccin Mocha}). */
+    String label() {
+        return label;
+    }
+
+    /** Whether this is a light-background theme. */
+    boolean isLight() {
+        return light;
+    }
+
     /** Classpath resource path of this mode's stylesheet, e.g. {@code 
tui/themes/dark.tcss}. */
     String stylesheetResource() {
         return "tui/themes/" + id + ".tcss";
     }
 
-    // Only two modes exist today, so toggling is a simple flip; revisit this 
if a third mode is ever added.
-    ThemeMode toggle() {
-        return this == DARK ? LIGHT : DARK;
+    /** Returns the next theme in declaration order, wrapping around at the 
end. */
+    ThemeMode next() {
+        ThemeMode[] all = values();
+        return all[(ordinal() + 1) % all.length];
     }
 
     static Optional<ThemeMode> parse(String value) {
@@ -68,4 +96,14 @@ enum ThemeMode {
     static List<String> ids() {
         return Arrays.stream(values()).map(m -> m.id).toList();
     }
+
+    /** Dark themes in declaration order. */
+    static List<ThemeMode> darkThemes() {
+        return Arrays.stream(values()).filter(m -> !m.light).toList();
+    }
+
+    /** Light themes in declaration order. */
+    static List<ThemeMode> lightThemes() {
+        return Arrays.stream(values()).filter(m -> m.light).toList();
+    }
 }
diff --git 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ThemePopup.java
 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ThemePopup.java
new file mode 100644
index 000000000000..88ac5babaf0e
--- /dev/null
+++ 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ThemePopup.java
@@ -0,0 +1,276 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.dsl.jbang.core.commands.tui;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import dev.tamboui.layout.Rect;
+import dev.tamboui.style.Style;
+import dev.tamboui.terminal.Frame;
+import dev.tamboui.text.Span;
+import dev.tamboui.tui.event.KeyCode;
+import dev.tamboui.tui.event.KeyEvent;
+import dev.tamboui.tui.event.MouseEvent;
+import dev.tamboui.tui.event.MouseEventKind;
+import dev.tamboui.widgets.Clear;
+import dev.tamboui.widgets.block.Block;
+import dev.tamboui.widgets.block.BorderType;
+import dev.tamboui.widgets.block.Borders;
+import dev.tamboui.widgets.list.ListItem;
+import dev.tamboui.widgets.list.ListState;
+import dev.tamboui.widgets.list.ListWidget;
+import dev.tamboui.widgets.list.ScrollMode;
+
+import static org.apache.camel.dsl.jbang.core.commands.tui.TuiHelper.hint;
+import static org.apache.camel.dsl.jbang.core.commands.tui.TuiHelper.hintLast;
+
+/**
+ * Self-contained theme picker popup with live preview. Shows dark and light 
themes in separate sections; scrolling
+ * applies the theme instantly, Enter confirms and persists, Esc reverts to 
the original theme.
+ */
+class ThemePopup {
+
+    private boolean visible;
+    private final ListState listState = new ListState();
+    private Runnable themeRefreshAction;
+    private Rect popupRect;
+
+    void setThemeRefreshAction(Runnable action) {
+        this.themeRefreshAction = action;
+    }
+
+    void open() {
+        visible = true;
+        ThemeMode current = ThemeMode.parseOrDefault(Theme.mode());
+        listState.select(visualIndexForTheme(current));
+    }
+
+    void close() {
+        if (visible) {
+            Theme.revertPreview();
+            refreshTheme();
+        }
+        visible = false;
+    }
+
+    boolean isVisible() {
+        return visible;
+    }
+
+    boolean handleKeyEvent(KeyEvent ke) {
+        if (!visible) {
+            return false;
+        }
+        if (ke.isCancel()) {
+            Theme.revertPreview();
+            refreshTheme();
+            visible = false;
+        } else if (ke.isUp()) {
+            navigate(-1);
+            applyThemePreview();
+        } else if (ke.isDown()) {
+            navigate(1);
+            applyThemePreview();
+        } else if (ke.isHome() || ke.isKey(KeyCode.HOME)) {
+            listState.select(2);
+            applyThemePreview();
+        } else if (ke.isEnd() || ke.isKey(KeyCode.END)) {
+            listState.select(itemCount() - 1);
+            applyThemePreview();
+        } else if (ke.isConfirm()) {
+            Integer sel = listState.selected();
+            if (sel != null && sel == 0) {
+                Theme.revertPreview();
+                refreshTheme();
+                visible = false;
+            } else {
+                ThemeMode mode = themeAtVisualIndex(sel);
+                if (mode != null) {
+                    Theme.confirmPreview();
+                    refreshTheme();
+                    visible = false;
+                }
+            }
+        }
+        return true;
+    }
+
+    boolean handleMouseEvent(MouseEvent me) {
+        if (!visible) {
+            return false;
+        }
+        if (me.kind() == MouseEventKind.SCROLL_UP) {
+            handleKeyEvent(KeyEvent.ofKey(KeyCode.UP));
+            return true;
+        }
+        if (me.kind() == MouseEventKind.SCROLL_DOWN) {
+            handleKeyEvent(KeyEvent.ofKey(KeyCode.DOWN));
+            return true;
+        }
+        if (me.isClick()) {
+            if (popupRect != null && popupRect.contains(me.x(), me.y())) {
+                int idx = TuiHelper.listItemAt(popupRect, listState.offset(), 
itemCount(), me.x(), me.y());
+                if (idx >= 0 && !isDivider(idx)) {
+                    listState.select(idx);
+                    handleKeyEvent(KeyEvent.ofKey(KeyCode.ENTER));
+                }
+                return true;
+            }
+            handleKeyEvent(KeyEvent.ofKey(KeyCode.ESCAPE));
+            return true;
+        }
+        return true;
+    }
+
+    void render(Frame frame, Rect area) {
+        if (!visible) {
+            return;
+        }
+        int count = itemCount();
+        int popupW = 40;
+        int popupH = 2 + count;
+        int x = area.left() + Math.max(0, (area.width() - popupW) / 2);
+        int y = area.top() + 2;
+        Rect popup = new Rect(x, y, Math.min(popupW, area.width()), 
Math.min(popupH, area.height() - 2));
+        this.popupRect = popup;
+
+        frame.renderWidget(Clear.INSTANCE, popup);
+        String persisted = Theme.persistedMode();
+
+        List<ListItem> items = new ArrayList<>();
+        items.add(ListItem.from("  .."));
+        items.add(ListItem.from("  ──── Dark 
────────────────────").style(Style.EMPTY.dim()));
+        for (ThemeMode m : ThemeMode.darkThemes()) {
+            String check = m.id().equals(persisted) ? "  ✔" : "";
+            items.add(ListItem.from("  " + m.label() + check));
+        }
+        items.add(ListItem.from("  ──── Light 
───────────────────").style(Style.EMPTY.dim()));
+        for (ThemeMode m : ThemeMode.lightThemes()) {
+            String check = m.id().equals(persisted) ? "  ✔" : "";
+            items.add(ListItem.from("  " + m.label() + check));
+        }
+        ListWidget list = ListWidget.builder()
+                .items(items.toArray(ListItem[]::new))
+                .highlightStyle(Theme.selectionBg())
+                .highlightSymbol("")
+                .scrollMode(ScrollMode.NONE)
+                .block(Block.builder()
+                        .borderType(BorderType.ROUNDED).borders(Borders.ALL)
+                        .title(" Themes ")
+                        .build())
+                .build();
+        frame.renderStatefulWidget(list, popup, listState);
+    }
+
+    void renderFooter(List<Span> spans) {
+        hint(spans, TuiIcons.HINT_SCROLL, "preview");
+        hint(spans, "Enter", "apply");
+        hintLast(spans, "Esc", "back");
+    }
+
+    List<String> getLabels() {
+        List<String> labels = new ArrayList<>();
+        labels.add("..");
+        labels.add("── Dark ──");
+        for (ThemeMode m : ThemeMode.darkThemes()) {
+            labels.add(m.label());
+        }
+        labels.add("── Light ──");
+        for (ThemeMode m : ThemeMode.lightThemes()) {
+            labels.add(m.label());
+        }
+        return labels;
+    }
+
+    SelectionContext getSelectionContext() {
+        List<String> items = getLabels();
+        Integer sel = listState.selected();
+        return new SelectionContext("popup", items, sel != null ? sel : -1, 
itemCount(), "Themes");
+    }
+
+    // ---- Private helpers ----
+
+    private int itemCount() {
+        // BACK + dark-divider + darkThemes + light-divider + lightThemes
+        return 2 + ThemeMode.darkThemes().size() + 1 + 
ThemeMode.lightThemes().size();
+    }
+
+    private boolean isDivider(int index) {
+        int darkCount = ThemeMode.darkThemes().size();
+        return index == 1 || index == 2 + darkCount;
+    }
+
+    private void navigate(int direction) {
+        int total = itemCount();
+        Integer current = listState.selected();
+        int next = (current != null ? current : 0) + direction;
+        next = Math.max(0, Math.min(next, total - 1));
+        while (isDivider(next) && next > 0 && next < total - 1) {
+            next += direction;
+        }
+        next = Math.max(0, Math.min(next, total - 1));
+        if (!isDivider(next)) {
+            listState.select(next);
+        }
+    }
+
+    private void applyThemePreview() {
+        ThemeMode mode = themeAtVisualIndex(listState.selected());
+        if (mode != null) {
+            Theme.preview(mode.id());
+            refreshTheme();
+        }
+    }
+
+    private ThemeMode themeAtVisualIndex(Integer sel) {
+        if (sel == null) {
+            return null;
+        }
+        List<ThemeMode> dark = ThemeMode.darkThemes();
+        List<ThemeMode> light = ThemeMode.lightThemes();
+        int darkCount = dark.size();
+        if (sel >= 2 && sel < 2 + darkCount) {
+            return dark.get(sel - 2);
+        }
+        int lightStart = 2 + darkCount + 1;
+        if (sel >= lightStart && sel < lightStart + light.size()) {
+            return light.get(sel - lightStart);
+        }
+        return null;
+    }
+
+    private int visualIndexForTheme(ThemeMode target) {
+        List<ThemeMode> dark = ThemeMode.darkThemes();
+        int darkIdx = dark.indexOf(target);
+        if (darkIdx >= 0) {
+            return 2 + darkIdx;
+        }
+        List<ThemeMode> light = ThemeMode.lightThemes();
+        int lightIdx = light.indexOf(target);
+        if (lightIdx >= 0) {
+            return 2 + dark.size() + 1 + lightIdx;
+        }
+        return 2;
+    }
+
+    private void refreshTheme() {
+        if (themeRefreshAction != null) {
+            themeRefreshAction.run();
+        }
+    }
+}
diff --git 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/TuiIcons.java
 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/TuiIcons.java
index 3a21a76dd939..6c89c4ce9f46 100644
--- 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/TuiIcons.java
+++ 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/TuiIcons.java
@@ -62,6 +62,7 @@ final class TuiIcons {
     static final String CLEAN = "🧹";
     static final String LIGHT_THEME = "🌞";
     static final String DARK_THEME = "🌙";
+    static final String THEMES = "🎨";
     static final String SCREENSHOT = "📸";
     static final String CAPTION = "💬";
     static final String MCP_BRAIN = "🧠";
diff --git 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/TuiMcpServer.java
 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/TuiMcpServer.java
index f8805af0363d..a286a3e63b38 100644
--- 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/TuiMcpServer.java
+++ 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/TuiMcpServer.java
@@ -402,6 +402,16 @@ class TuiMcpServer {
                               + "tape-recording, doctor, caption, mcp-info, 
mcp-log, toggle-theme.",
                 Map.of("action", propDef("string", "Action name in kebab-case 
(e.g. 'reset-stats', 'screenshot')")),
                 List.of("action")));
+        toolList.add(toolDef(
+                "tui_get_themes",
+                "Returns available TUI themes grouped by dark and light, "
+                                  + "with the currently active theme marked.",
+                Map.of()));
+        toolList.add(toolDef(
+                "tui_set_theme",
+                "Switches the TUI to a named theme. Use tui_get_themes to list 
available theme IDs.",
+                Map.of("theme", propDef("string", "Theme ID (e.g. 'dracula', 
'nord', 'catppuccin-mocha')")),
+                List.of("theme")));
         toolList.add(toolDef(
                 "tui_get_log",
                 "Returns recent log lines as structured data with optional 
filtering. "
@@ -607,6 +617,8 @@ class TuiMcpServer {
                 case "tui_draw_clear" -> callDrawClear();
                 case "tui_get_table" -> callGetTable(args);
                 case "tui_action" -> callAction(args);
+                case "tui_get_themes" -> callGetThemes();
+                case "tui_set_theme" -> callSetTheme(args);
                 case "tui_get_log" -> callGetLog(args);
                 case "tui_get_errors" -> callGetErrors();
                 case "tui_get_diagram" -> callGetDiagram();
@@ -1170,6 +1182,43 @@ class TuiMcpServer {
                + "tape-recording, doctor, caption, mcp-info, mcp-log, 
toggle-theme";
     }
 
+    private String callGetThemes() {
+        JsonObject result = new JsonObject();
+        result.put("current", Theme.mode());
+        JsonArray dark = new JsonArray();
+        for (ThemeMode m : ThemeMode.darkThemes()) {
+            JsonObject t = new JsonObject();
+            t.put("id", m.id());
+            t.put("label", m.label());
+            t.put("active", m.id().equals(Theme.mode()));
+            dark.add(t);
+        }
+        JsonArray light = new JsonArray();
+        for (ThemeMode m : ThemeMode.lightThemes()) {
+            JsonObject t = new JsonObject();
+            t.put("id", m.id());
+            t.put("label", m.label());
+            t.put("active", m.id().equals(Theme.mode()));
+            light.add(t);
+        }
+        result.put("dark", dark);
+        result.put("light", light);
+        return Jsoner.serialize(result);
+    }
+
+    private String callSetTheme(Map<String, Object> args) {
+        String themeId = (String) args.get("theme");
+        if (themeId == null || themeId.isBlank()) {
+            return "Error: theme is required. Use tui_get_themes to list 
available IDs.";
+        }
+        if (!Theme.isValidMode(themeId)) {
+            return "Error: unknown theme '" + themeId + "'. Use tui_get_themes 
to list available IDs.";
+        }
+        Theme.setTheme(themeId);
+        facade.executeAction("reset-screen");
+        return "Theme switched to '" + themeId + "'";
+    }
+
     private String callGetLog(Map<String, Object> args) {
         int limit = 50;
         if (args.get("limit") instanceof Number n) {
diff --git 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/resources/tui/themes/catppuccin-latte.tcss
 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/resources/tui/themes/catppuccin-latte.tcss
new file mode 100644
index 000000000000..295d336a3db3
--- /dev/null
+++ 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/resources/tui/themes/catppuccin-latte.tcss
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/* Camel TUI Catppuccin Latte theme. Soothing pastel light palette. */
+
+$brand: #8839EF;
+$latte-bg: #EFF1F5;
+$latte-fg: #4C4F69;
+
+#accent         { color: $brand; }
+#accent-bg      { color: white; background: $brand; text-style: bold; }
+#hint-key       { color: white; background: #7C3AED; text-style: bold; }
+#border         { color: #BCC0CC; }
+#border-focused { color: $brand; }
+#title          { color: $brand; text-style: bold; }
+#success        { color: #40A02B; }
+#warning        { color: #DF8E1D; }
+#error          { color: #D20F39; }
+#muted          { color: #9CA0B0; }
+#selection      { color: white; background: #1E66F5; text-style: bold; }
+#info           { color: #1E66F5; }
+#notice         { color: #8839EF; }
+#row-alt        { background: #E6E9EF; }
+#base-bg        { background: $latte-bg; }
+#base-fg        { color: $latte-fg; }
+
+/* Content tokens — labels, change indicators, search highlight */
+#label          { color: #DF8E1D; }
+#change         { color: #DF8E1D; }
+#search-match   { color: #4C4F69; background: #DF8E1D; }
+#mnemonic       { color: #DF8E1D; text-style: bold underline; }
+
+/* Diagram tokens */
+#diagram-border  { color: #8C8FA1; }
+#diagram-id      { color: $latte-fg; }
+#diagram-from    { color: #40A02B; }
+#diagram-to      { color: #179299; }
+#diagram-choice  { color: #DF8E1D; }
+#diagram-action  { color: #8839EF; }
+#diagram-eip     { color: #7287FD; }
+#diagram-default { color: #9CA0B0; }
diff --git 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/resources/tui/themes/light.tcss
 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/resources/tui/themes/catppuccin-mocha.tcss
similarity index 51%
copy from 
dsl/camel-jbang/camel-jbang-plugin-tui/src/main/resources/tui/themes/light.tcss
copy to 
dsl/camel-jbang/camel-jbang-plugin-tui/src/main/resources/tui/themes/catppuccin-mocha.tcss
index a6a9a285a348..e704f5f4828f 100644
--- 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/resources/tui/themes/light.tcss
+++ 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/resources/tui/themes/catppuccin-mocha.tcss
@@ -14,41 +14,41 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-/* Camel TUI light theme. Brand orange stays truecolor; status hues darkened 
for light terminals. */
+/* Camel TUI Catppuccin Mocha theme. Soothing pastel dark palette. */
 
-$brand: #F69123;
-$light-bg: #FFFFFF;
-$light-fg: #24292E;
+$brand: #CBA6F7;
+$mocha-bg: #1E1E2E;
+$mocha-fg: #CDD6F4;
 
 #accent         { color: $brand; }
 #accent-bg      { color: white; background: $brand; text-style: bold; }
 #hint-key       { color: black; background: $brand; text-style: bold; }
-#border         { color: #C0C0C0; }
+#border         { color: #45475A; }
 #border-focused { color: $brand; }
 #title          { color: $brand; text-style: bold; }
-#success        { color: #22863A; }
-#warning        { color: #B08800; }
-#error          { color: #D73A49; }
-#muted          { color: #6A737D; }
-#selection      { color: white; background: #0366D6; text-style: bold; }
-#info           { color: #0366D6; }
-#notice         { color: #6F42C1; }
-#row-alt        { background: #F6F8FA; }
-#base-bg        { background: $light-bg; }
-#base-fg        { color: $light-fg; }
+#success        { color: #A6E3A1; }
+#warning        { color: #F9E2AF; }
+#error          { color: #F38BA8; }
+#muted          { color: #6C7086; }
+#selection      { color: white; background: #45475A; text-style: bold; }
+#info           { color: #89B4FA; }
+#notice         { color: #CBA6F7; }
+#row-alt        { background: #252536; }
+#base-bg        { background: $mocha-bg; }
+#base-fg        { color: $mocha-fg; }
 
 /* Content tokens — labels, change indicators, search highlight */
-#label          { color: #735C00; }
-#change         { color: #B08800; }
-#search-match   { color: black; background: #FFD33D; }
-#mnemonic       { color: #735C00; text-style: bold underline; }
+#label          { color: #F9E2AF; }
+#change         { color: #F9E2AF; }
+#search-match   { color: black; background: #F9E2AF; }
+#mnemonic       { color: #F9E2AF; text-style: bold underline; }
 
 /* Diagram tokens */
-#diagram-border  { color: #808080; }
-#diagram-id      { color: $light-fg; }
-#diagram-from    { color: #22863A; }
-#diagram-to      { color: #0366D6; }
-#diagram-choice  { color: #B08800; }
-#diagram-action  { color: #6F42C1; }
-#diagram-eip     { color: #5A32A3; }
-#diagram-default { color: #6A737D; }
+#diagram-border  { color: #6C7086; }
+#diagram-id      { color: $mocha-fg; }
+#diagram-from    { color: #A6E3A1; }
+#diagram-to      { color: #94E2D5; }
+#diagram-choice  { color: #F9E2AF; }
+#diagram-action  { color: #CBA6F7; }
+#diagram-eip     { color: #B4BEFE; }
+#diagram-default { color: #6C7086; }
diff --git 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/resources/tui/themes/crt.tcss 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/resources/tui/themes/crt.tcss
new file mode 100644
index 000000000000..b391f99c4a8f
--- /dev/null
+++ 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/resources/tui/themes/crt.tcss
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/* Camel TUI CRT theme — retro green terminal. */
+
+$brand: #33FF33;
+$dark-bg: #0A0A0A;
+$dark-fg: #33CC33;
+
+#accent         { color: $brand; }
+#accent-bg      { color: black; background: $brand; text-style: bold; }
+#hint-key       { color: black; background: #33CC33; text-style: bold; }
+#border         { color: #1A661A; }
+#border-focused { color: $brand; }
+#title          { color: $brand; text-style: bold; }
+#success        { color: #33FF33; }
+#warning        { color: #66FF66; text-style: bold; }
+#error          { color: #BBFFBB; text-style: bold; }
+#muted          { color: #1A661A; }
+#selection      { color: black; background: #33CC33; text-style: bold; }
+#info           { color: #44DD44; }
+#notice         { color: #22AA22; }
+#row-alt        { background: #0F130F; }
+#base-bg        { background: $dark-bg; }
+#base-fg        { color: $dark-fg; }
+
+/* Content tokens */
+#label          { color: #66FF66; }
+#change         { color: #66FF66; }
+#search-match   { color: black; background: #66FF66; }
+#mnemonic       { color: #66FF66; text-style: bold underline; }
+
+/* Diagram tokens */
+#diagram-border  { color: #1A661A; }
+#diagram-id      { color: $dark-fg; }
+#diagram-from    { color: #44DD44; }
+#diagram-to      { color: #22AA22; }
+#diagram-choice  { color: #66FF66; }
+#diagram-action  { color: #119911; }
+#diagram-eip     { color: #33CC33; }
+#diagram-default { color: #1A661A; }
diff --git 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/resources/tui/themes/light.tcss
 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/resources/tui/themes/dracula.tcss
similarity index 53%
copy from 
dsl/camel-jbang/camel-jbang-plugin-tui/src/main/resources/tui/themes/light.tcss
copy to 
dsl/camel-jbang/camel-jbang-plugin-tui/src/main/resources/tui/themes/dracula.tcss
index a6a9a285a348..d7e616fd87c5 100644
--- 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/resources/tui/themes/light.tcss
+++ 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/resources/tui/themes/dracula.tcss
@@ -14,41 +14,41 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-/* Camel TUI light theme. Brand orange stays truecolor; status hues darkened 
for light terminals. */
+/* Camel TUI Dracula theme. Dark theme based on the Dracula color palette. */
 
-$brand: #F69123;
-$light-bg: #FFFFFF;
-$light-fg: #24292E;
+$brand: #BD93F9;
+$dracula-bg: #282A36;
+$dracula-fg: #F8F8F2;
 
 #accent         { color: $brand; }
 #accent-bg      { color: white; background: $brand; text-style: bold; }
 #hint-key       { color: black; background: $brand; text-style: bold; }
-#border         { color: #C0C0C0; }
+#border         { color: #6272A4; }
 #border-focused { color: $brand; }
 #title          { color: $brand; text-style: bold; }
-#success        { color: #22863A; }
-#warning        { color: #B08800; }
-#error          { color: #D73A49; }
-#muted          { color: #6A737D; }
-#selection      { color: white; background: #0366D6; text-style: bold; }
-#info           { color: #0366D6; }
-#notice         { color: #6F42C1; }
-#row-alt        { background: #F6F8FA; }
-#base-bg        { background: $light-bg; }
-#base-fg        { color: $light-fg; }
+#success        { color: #50FA7B; }
+#warning        { color: #F1FA8C; }
+#error          { color: #FF5555; }
+#muted          { color: #6272A4; }
+#selection      { color: white; background: #44475A; text-style: bold; }
+#info           { color: #8BE9FD; }
+#notice         { color: #BD93F9; }
+#row-alt        { background: #2D2F3B; }
+#base-bg        { background: $dracula-bg; }
+#base-fg        { color: $dracula-fg; }
 
 /* Content tokens — labels, change indicators, search highlight */
-#label          { color: #735C00; }
-#change         { color: #B08800; }
-#search-match   { color: black; background: #FFD33D; }
-#mnemonic       { color: #735C00; text-style: bold underline; }
+#label          { color: #F1FA8C; }
+#change         { color: #F1FA8C; }
+#search-match   { color: black; background: #F1FA8C; }
+#mnemonic       { color: #F1FA8C; text-style: bold underline; }
 
 /* Diagram tokens */
-#diagram-border  { color: #808080; }
-#diagram-id      { color: $light-fg; }
-#diagram-from    { color: #22863A; }
-#diagram-to      { color: #0366D6; }
-#diagram-choice  { color: #B08800; }
-#diagram-action  { color: #6F42C1; }
-#diagram-eip     { color: #5A32A3; }
-#diagram-default { color: #6A737D; }
+#diagram-border  { color: #6272A4; }
+#diagram-id      { color: $dracula-fg; }
+#diagram-from    { color: #50FA7B; }
+#diagram-to      { color: #8BE9FD; }
+#diagram-choice  { color: #F1FA8C; }
+#diagram-action  { color: #FF79C6; }
+#diagram-eip     { color: #BD93F9; }
+#diagram-default { color: #6272A4; }
diff --git 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/resources/tui/themes/light.tcss
 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/resources/tui/themes/everforest.tcss
similarity index 51%
copy from 
dsl/camel-jbang/camel-jbang-plugin-tui/src/main/resources/tui/themes/light.tcss
copy to 
dsl/camel-jbang/camel-jbang-plugin-tui/src/main/resources/tui/themes/everforest.tcss
index a6a9a285a348..72fe0546c831 100644
--- 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/resources/tui/themes/light.tcss
+++ 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/resources/tui/themes/everforest.tcss
@@ -14,41 +14,41 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-/* Camel TUI light theme. Brand orange stays truecolor; status hues darkened 
for light terminals. */
+/* Camel TUI Everforest theme. Comfortable green-toned dark palette inspired 
by natural forests. */
 
-$brand: #F69123;
-$light-bg: #FFFFFF;
-$light-fg: #24292E;
+$brand: #A7C080;
+$everforest-bg: #2D353B;
+$everforest-fg: #D3C6AA;
 
 #accent         { color: $brand; }
 #accent-bg      { color: white; background: $brand; text-style: bold; }
 #hint-key       { color: black; background: $brand; text-style: bold; }
-#border         { color: #C0C0C0; }
+#border         { color: #7A8478; }
 #border-focused { color: $brand; }
 #title          { color: $brand; text-style: bold; }
-#success        { color: #22863A; }
-#warning        { color: #B08800; }
-#error          { color: #D73A49; }
-#muted          { color: #6A737D; }
-#selection      { color: white; background: #0366D6; text-style: bold; }
-#info           { color: #0366D6; }
-#notice         { color: #6F42C1; }
-#row-alt        { background: #F6F8FA; }
-#base-bg        { background: $light-bg; }
-#base-fg        { color: $light-fg; }
+#success        { color: #A7C080; }
+#warning        { color: #DBBC7F; }
+#error          { color: #E67E80; }
+#muted          { color: #7A8478; }
+#selection      { color: white; background: #343F44; text-style: bold; }
+#info           { color: #7FBBB3; }
+#notice         { color: #D699B6; }
+#row-alt        { background: #343F44; }
+#base-bg        { background: $everforest-bg; }
+#base-fg        { color: $everforest-fg; }
 
 /* Content tokens — labels, change indicators, search highlight */
-#label          { color: #735C00; }
-#change         { color: #B08800; }
-#search-match   { color: black; background: #FFD33D; }
-#mnemonic       { color: #735C00; text-style: bold underline; }
+#label          { color: #DBBC7F; }
+#change         { color: #DBBC7F; }
+#search-match   { color: black; background: #DBBC7F; }
+#mnemonic       { color: #DBBC7F; text-style: bold underline; }
 
 /* Diagram tokens */
-#diagram-border  { color: #808080; }
-#diagram-id      { color: $light-fg; }
-#diagram-from    { color: #22863A; }
-#diagram-to      { color: #0366D6; }
-#diagram-choice  { color: #B08800; }
-#diagram-action  { color: #6F42C1; }
-#diagram-eip     { color: #5A32A3; }
-#diagram-default { color: #6A737D; }
+#diagram-border  { color: #7A8478; }
+#diagram-id      { color: $everforest-fg; }
+#diagram-from    { color: #A7C080; }
+#diagram-to      { color: #7FBBB3; }
+#diagram-choice  { color: #DBBC7F; }
+#diagram-action  { color: #E69875; }
+#diagram-eip     { color: #D699B6; }
+#diagram-default { color: #7A8478; }
diff --git 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/resources/tui/themes/light.tcss
 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/resources/tui/themes/gruvbox-dark.tcss
similarity index 51%
copy from 
dsl/camel-jbang/camel-jbang-plugin-tui/src/main/resources/tui/themes/light.tcss
copy to 
dsl/camel-jbang/camel-jbang-plugin-tui/src/main/resources/tui/themes/gruvbox-dark.tcss
index a6a9a285a348..ef54c4a452ca 100644
--- 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/resources/tui/themes/light.tcss
+++ 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/resources/tui/themes/gruvbox-dark.tcss
@@ -14,41 +14,41 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-/* Camel TUI light theme. Brand orange stays truecolor; status hues darkened 
for light terminals. */
+/* Camel TUI Gruvbox Dark theme. Retro groove palette with warm earthy tones. 
*/
 
-$brand: #F69123;
-$light-bg: #FFFFFF;
-$light-fg: #24292E;
+$brand: #FE8019;
+$gruvbox-bg: #282828;
+$gruvbox-fg: #EBDBB2;
 
 #accent         { color: $brand; }
 #accent-bg      { color: white; background: $brand; text-style: bold; }
 #hint-key       { color: black; background: $brand; text-style: bold; }
-#border         { color: #C0C0C0; }
+#border         { color: #504945; }
 #border-focused { color: $brand; }
 #title          { color: $brand; text-style: bold; }
-#success        { color: #22863A; }
-#warning        { color: #B08800; }
-#error          { color: #D73A49; }
-#muted          { color: #6A737D; }
-#selection      { color: white; background: #0366D6; text-style: bold; }
-#info           { color: #0366D6; }
-#notice         { color: #6F42C1; }
-#row-alt        { background: #F6F8FA; }
-#base-bg        { background: $light-bg; }
-#base-fg        { color: $light-fg; }
+#success        { color: #B8BB26; }
+#warning        { color: #FABD2F; }
+#error          { color: #FB4934; }
+#muted          { color: #A89984; }
+#selection      { color: white; background: #504945; text-style: bold; }
+#info           { color: #83A598; }
+#notice         { color: #D3869B; }
+#row-alt        { background: #32302F; }
+#base-bg        { background: $gruvbox-bg; }
+#base-fg        { color: $gruvbox-fg; }
 
 /* Content tokens — labels, change indicators, search highlight */
-#label          { color: #735C00; }
-#change         { color: #B08800; }
-#search-match   { color: black; background: #FFD33D; }
-#mnemonic       { color: #735C00; text-style: bold underline; }
+#label          { color: #FABD2F; }
+#change         { color: #FABD2F; }
+#search-match   { color: black; background: #FABD2F; }
+#mnemonic       { color: #FABD2F; text-style: bold underline; }
 
 /* Diagram tokens */
-#diagram-border  { color: #808080; }
-#diagram-id      { color: $light-fg; }
-#diagram-from    { color: #22863A; }
-#diagram-to      { color: #0366D6; }
-#diagram-choice  { color: #B08800; }
-#diagram-action  { color: #6F42C1; }
-#diagram-eip     { color: #5A32A3; }
-#diagram-default { color: #6A737D; }
+#diagram-border  { color: #A89984; }
+#diagram-id      { color: $gruvbox-fg; }
+#diagram-from    { color: #B8BB26; }
+#diagram-to      { color: #83A598; }
+#diagram-choice  { color: #FABD2F; }
+#diagram-action  { color: #D3869B; }
+#diagram-eip     { color: #8EC07C; }
+#diagram-default { color: #A89984; }
diff --git 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/resources/tui/themes/kanagawa.tcss
 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/resources/tui/themes/kanagawa.tcss
new file mode 100644
index 000000000000..fa12fdd01a4d
--- /dev/null
+++ 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/resources/tui/themes/kanagawa.tcss
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/* Camel TUI Kanagawa theme. Dark theme inspired by Katsushika Hokusai's 
famous wave painting. */
+
+$brand: #7E9CD8;
+$kanagawa-bg: #1F1F28;
+$kanagawa-fg: #DCD7BA;
+
+#accent         { color: $brand; }
+#accent-bg      { color: white; background: $brand; text-style: bold; }
+#hint-key       { color: white; background: $brand; text-style: bold; }
+#border         { color: #727169; }
+#border-focused { color: $brand; }
+#title          { color: $brand; text-style: bold; }
+#success        { color: #98BB6C; }
+#warning        { color: #E6C384; }
+#error          { color: #E46876; }
+#muted          { color: #727169; }
+#selection      { color: white; background: #2A2A37; text-style: bold; }
+#info           { color: #7E9CD8; }
+#notice         { color: #957FB8; }
+#row-alt        { background: #2A2A37; }
+#base-bg        { background: $kanagawa-bg; }
+#base-fg        { color: $kanagawa-fg; }
+
+/* Content tokens — labels, change indicators, search highlight */
+#label          { color: #E6C384; }
+#change         { color: #E6C384; }
+#search-match   { color: black; background: #E6C384; }
+#mnemonic       { color: #E6C384; text-style: bold underline; }
+
+/* Diagram tokens */
+#diagram-border  { color: #727169; }
+#diagram-id      { color: $kanagawa-fg; }
+#diagram-from    { color: #98BB6C; }
+#diagram-to      { color: #7E9CD8; }
+#diagram-choice  { color: #E6C384; }
+#diagram-action  { color: #D27E99; }
+#diagram-eip     { color: #957FB8; }
+#diagram-default { color: #727169; }
diff --git 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/resources/tui/themes/light.tcss
 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/resources/tui/themes/light.tcss
index a6a9a285a348..a00d708b39d5 100644
--- 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/resources/tui/themes/light.tcss
+++ 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/resources/tui/themes/light.tcss
@@ -16,13 +16,13 @@
  */
 /* Camel TUI light theme. Brand orange stays truecolor; status hues darkened 
for light terminals. */
 
-$brand: #F69123;
+$brand: #D97706;
 $light-bg: #FFFFFF;
 $light-fg: #24292E;
 
 #accent         { color: $brand; }
 #accent-bg      { color: white; background: $brand; text-style: bold; }
-#hint-key       { color: black; background: $brand; text-style: bold; }
+#hint-key       { color: black; background: #F0A030; text-style: bold; }
 #border         { color: #C0C0C0; }
 #border-focused { color: $brand; }
 #title          { color: $brand; text-style: bold; }
diff --git 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/resources/tui/themes/monochrome.tcss
 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/resources/tui/themes/monochrome.tcss
new file mode 100644
index 000000000000..1c48b34ce09d
--- /dev/null
+++ 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/resources/tui/themes/monochrome.tcss
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/* Camel TUI monochrome theme — no color, brightness only. */
+
+$brand: #FFFFFF;
+$dark-bg: #1A1A1A;
+$dark-fg: #C8C8C8;
+
+#accent         { color: $brand; }
+#accent-bg      { color: black; background: $brand; text-style: bold; }
+#hint-key       { color: black; background: #B0B0B0; text-style: bold; }
+#border         { color: #404040; }
+#border-focused { color: $brand; }
+#title          { color: $brand; text-style: bold; }
+#success        { color: #A0A0A0; }
+#warning        { color: #D0D0D0; }
+#error          { color: #FFFFFF; text-style: bold; }
+#muted          { color: #606060; }
+#selection      { color: white; background: #505050; text-style: bold; }
+#info           { color: #B0B0B0; }
+#notice         { color: #909090; }
+#row-alt        { background: #222222; }
+#base-bg        { background: $dark-bg; }
+#base-fg        { color: $dark-fg; }
+
+/* Content tokens */
+#label          { color: #D0D0D0; }
+#change         { color: #D0D0D0; }
+#search-match   { color: black; background: #D0D0D0; }
+#mnemonic       { color: #D0D0D0; text-style: bold underline; }
+
+/* Diagram tokens */
+#diagram-border  { color: #606060; }
+#diagram-id      { color: $dark-fg; }
+#diagram-from    { color: #B0B0B0; }
+#diagram-to      { color: #909090; }
+#diagram-choice  { color: #D0D0D0; }
+#diagram-action  { color: #808080; }
+#diagram-eip     { color: #707070; }
+#diagram-default { color: #606060; }
diff --git 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/resources/tui/themes/light.tcss
 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/resources/tui/themes/nord.tcss
similarity index 51%
copy from 
dsl/camel-jbang/camel-jbang-plugin-tui/src/main/resources/tui/themes/light.tcss
copy to 
dsl/camel-jbang/camel-jbang-plugin-tui/src/main/resources/tui/themes/nord.tcss
index a6a9a285a348..b32e287beeee 100644
--- 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/resources/tui/themes/light.tcss
+++ 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/resources/tui/themes/nord.tcss
@@ -14,41 +14,41 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-/* Camel TUI light theme. Brand orange stays truecolor; status hues darkened 
for light terminals. */
+/* Camel TUI Nord theme. Muted arctic palette inspired by the Nord color 
scheme. */
 
-$brand: #F69123;
-$light-bg: #FFFFFF;
-$light-fg: #24292E;
+$brand: #88C0D0;
+$nord-bg: #2E3440;
+$nord-fg: #D8DEE9;
 
 #accent         { color: $brand; }
 #accent-bg      { color: white; background: $brand; text-style: bold; }
 #hint-key       { color: black; background: $brand; text-style: bold; }
-#border         { color: #C0C0C0; }
+#border         { color: #4C566A; }
 #border-focused { color: $brand; }
 #title          { color: $brand; text-style: bold; }
-#success        { color: #22863A; }
-#warning        { color: #B08800; }
-#error          { color: #D73A49; }
-#muted          { color: #6A737D; }
-#selection      { color: white; background: #0366D6; text-style: bold; }
-#info           { color: #0366D6; }
-#notice         { color: #6F42C1; }
-#row-alt        { background: #F6F8FA; }
-#base-bg        { background: $light-bg; }
-#base-fg        { color: $light-fg; }
+#success        { color: #A3BE8C; }
+#warning        { color: #EBCB8B; }
+#error          { color: #BF616A; }
+#muted          { color: #4C566A; }
+#selection      { color: white; background: #3B4252; text-style: bold; }
+#info           { color: #88C0D0; }
+#notice         { color: #B48EAD; }
+#row-alt        { background: #333947; }
+#base-bg        { background: $nord-bg; }
+#base-fg        { color: $nord-fg; }
 
 /* Content tokens — labels, change indicators, search highlight */
-#label          { color: #735C00; }
-#change         { color: #B08800; }
-#search-match   { color: black; background: #FFD33D; }
-#mnemonic       { color: #735C00; text-style: bold underline; }
+#label          { color: #EBCB8B; }
+#change         { color: #EBCB8B; }
+#search-match   { color: black; background: #EBCB8B; }
+#mnemonic       { color: #EBCB8B; text-style: bold underline; }
 
 /* Diagram tokens */
-#diagram-border  { color: #808080; }
-#diagram-id      { color: $light-fg; }
-#diagram-from    { color: #22863A; }
-#diagram-to      { color: #0366D6; }
-#diagram-choice  { color: #B08800; }
-#diagram-action  { color: #6F42C1; }
-#diagram-eip     { color: #5A32A3; }
-#diagram-default { color: #6A737D; }
+#diagram-border  { color: #4C566A; }
+#diagram-id      { color: $nord-fg; }
+#diagram-from    { color: #A3BE8C; }
+#diagram-to      { color: #88C0D0; }
+#diagram-choice  { color: #EBCB8B; }
+#diagram-action  { color: #B48EAD; }
+#diagram-eip     { color: #5E81AC; }
+#diagram-default { color: #4C566A; }
diff --git 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/resources/tui/themes/light.tcss
 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/resources/tui/themes/rose-pine.tcss
similarity index 51%
copy from 
dsl/camel-jbang/camel-jbang-plugin-tui/src/main/resources/tui/themes/light.tcss
copy to 
dsl/camel-jbang/camel-jbang-plugin-tui/src/main/resources/tui/themes/rose-pine.tcss
index a6a9a285a348..1a4aab49fb32 100644
--- 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/resources/tui/themes/light.tcss
+++ 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/resources/tui/themes/rose-pine.tcss
@@ -14,41 +14,41 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-/* Camel TUI light theme. Brand orange stays truecolor; status hues darkened 
for light terminals. */
+/* Camel TUI Rosé Pine theme. Soho vibes with muted tones on a dark base. */
 
-$brand: #F69123;
-$light-bg: #FFFFFF;
-$light-fg: #24292E;
+$brand: #EBBCBA;
+$rosepine-bg: #191724;
+$rosepine-fg: #E0DEF4;
 
 #accent         { color: $brand; }
 #accent-bg      { color: white; background: $brand; text-style: bold; }
 #hint-key       { color: black; background: $brand; text-style: bold; }
-#border         { color: #C0C0C0; }
+#border         { color: #6E6A86; }
 #border-focused { color: $brand; }
 #title          { color: $brand; text-style: bold; }
-#success        { color: #22863A; }
-#warning        { color: #B08800; }
-#error          { color: #D73A49; }
-#muted          { color: #6A737D; }
-#selection      { color: white; background: #0366D6; text-style: bold; }
-#info           { color: #0366D6; }
-#notice         { color: #6F42C1; }
-#row-alt        { background: #F6F8FA; }
-#base-bg        { background: $light-bg; }
-#base-fg        { color: $light-fg; }
+#success        { color: #9CCFD8; }
+#warning        { color: #F6C177; }
+#error          { color: #EB6F92; }
+#muted          { color: #6E6A86; }
+#selection      { color: white; background: #26233A; text-style: bold; }
+#info           { color: #EBBCBA; }
+#notice         { color: #C4A7E7; }
+#row-alt        { background: #1F1D2E; }
+#base-bg        { background: $rosepine-bg; }
+#base-fg        { color: $rosepine-fg; }
 
 /* Content tokens — labels, change indicators, search highlight */
-#label          { color: #735C00; }
-#change         { color: #B08800; }
-#search-match   { color: black; background: #FFD33D; }
-#mnemonic       { color: #735C00; text-style: bold underline; }
+#label          { color: #F6C177; }
+#change         { color: #F6C177; }
+#search-match   { color: black; background: #F6C177; }
+#mnemonic       { color: #F6C177; text-style: bold underline; }
 
 /* Diagram tokens */
-#diagram-border  { color: #808080; }
-#diagram-id      { color: $light-fg; }
-#diagram-from    { color: #22863A; }
-#diagram-to      { color: #0366D6; }
-#diagram-choice  { color: #B08800; }
-#diagram-action  { color: #6F42C1; }
-#diagram-eip     { color: #5A32A3; }
-#diagram-default { color: #6A737D; }
+#diagram-border  { color: #6E6A86; }
+#diagram-id      { color: $rosepine-fg; }
+#diagram-from    { color: #9CCFD8; }
+#diagram-to      { color: #EBBCBA; }
+#diagram-choice  { color: #F6C177; }
+#diagram-action  { color: #EB6F92; }
+#diagram-eip     { color: #C4A7E7; }
+#diagram-default { color: #6E6A86; }
diff --git 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/resources/tui/themes/light.tcss
 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/resources/tui/themes/solarized-dark.tcss
similarity index 51%
copy from 
dsl/camel-jbang/camel-jbang-plugin-tui/src/main/resources/tui/themes/light.tcss
copy to 
dsl/camel-jbang/camel-jbang-plugin-tui/src/main/resources/tui/themes/solarized-dark.tcss
index a6a9a285a348..02c270178775 100644
--- 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/resources/tui/themes/light.tcss
+++ 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/resources/tui/themes/solarized-dark.tcss
@@ -14,41 +14,41 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-/* Camel TUI light theme. Brand orange stays truecolor; status hues darkened 
for light terminals. */
+/* Camel TUI Solarized Dark theme. Ethan Schoonover's precision color palette 
on a dark base. */
 
-$brand: #F69123;
-$light-bg: #FFFFFF;
-$light-fg: #24292E;
+$brand: #B58900;
+$solar-bg: #002B36;
+$solar-fg: #839496;
 
 #accent         { color: $brand; }
 #accent-bg      { color: white; background: $brand; text-style: bold; }
 #hint-key       { color: black; background: $brand; text-style: bold; }
-#border         { color: #C0C0C0; }
+#border         { color: #586E75; }
 #border-focused { color: $brand; }
 #title          { color: $brand; text-style: bold; }
-#success        { color: #22863A; }
-#warning        { color: #B08800; }
-#error          { color: #D73A49; }
-#muted          { color: #6A737D; }
-#selection      { color: white; background: #0366D6; text-style: bold; }
-#info           { color: #0366D6; }
-#notice         { color: #6F42C1; }
-#row-alt        { background: #F6F8FA; }
-#base-bg        { background: $light-bg; }
-#base-fg        { color: $light-fg; }
+#success        { color: #859900; }
+#warning        { color: #B58900; }
+#error          { color: #DC322F; }
+#muted          { color: #586E75; }
+#selection      { color: white; background: #073642; text-style: bold; }
+#info           { color: #268BD2; }
+#notice         { color: #6C71C4; }
+#row-alt        { background: #073642; }
+#base-bg        { background: $solar-bg; }
+#base-fg        { color: $solar-fg; }
 
 /* Content tokens — labels, change indicators, search highlight */
-#label          { color: #735C00; }
-#change         { color: #B08800; }
-#search-match   { color: black; background: #FFD33D; }
-#mnemonic       { color: #735C00; text-style: bold underline; }
+#label          { color: #B58900; }
+#change         { color: #B58900; }
+#search-match   { color: black; background: #B58900; }
+#mnemonic       { color: #B58900; text-style: bold underline; }
 
 /* Diagram tokens */
-#diagram-border  { color: #808080; }
-#diagram-id      { color: $light-fg; }
-#diagram-from    { color: #22863A; }
-#diagram-to      { color: #0366D6; }
-#diagram-choice  { color: #B08800; }
-#diagram-action  { color: #6F42C1; }
-#diagram-eip     { color: #5A32A3; }
-#diagram-default { color: #6A737D; }
+#diagram-border  { color: #586E75; }
+#diagram-id      { color: $solar-fg; }
+#diagram-from    { color: #859900; }
+#diagram-to      { color: #2AA198; }
+#diagram-choice  { color: #B58900; }
+#diagram-action  { color: #D33682; }
+#diagram-eip     { color: #6C71C4; }
+#diagram-default { color: #586E75; }
diff --git 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/resources/tui/themes/solarized-light.tcss
 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/resources/tui/themes/solarized-light.tcss
new file mode 100644
index 000000000000..b607d7083ad6
--- /dev/null
+++ 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/resources/tui/themes/solarized-light.tcss
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/* Camel TUI Solarized Light theme. Ethan Schoonover's precision color palette 
on a light base. */
+
+$brand: #268BD2;
+$solar-bg: #FDF6E3;
+$solar-fg: #657B83;
+
+#accent         { color: $brand; }
+#accent-bg      { color: white; background: $brand; text-style: bold; }
+#hint-key       { color: white; background: #268BD2; text-style: bold; }
+#border         { color: #93A1A1; }
+#border-focused { color: $brand; }
+#title          { color: $brand; text-style: bold; }
+#success        { color: #859900; }
+#warning        { color: #B58900; }
+#error          { color: #DC322F; }
+#muted          { color: #93A1A1; }
+#selection      { color: white; background: #268BD2; text-style: bold; }
+#info           { color: #268BD2; }
+#notice         { color: #6C71C4; }
+#row-alt        { background: #EEE8D5; }
+#base-bg        { background: $solar-bg; }
+#base-fg        { color: $solar-fg; }
+
+/* Content tokens — labels, change indicators, search highlight */
+#label          { color: #B58900; }
+#change         { color: #B58900; }
+#search-match   { color: #657B83; background: #B58900; }
+#mnemonic       { color: #B58900; text-style: bold underline; }
+
+/* Diagram tokens */
+#diagram-border  { color: #93A1A1; }
+#diagram-id      { color: $solar-fg; }
+#diagram-from    { color: #859900; }
+#diagram-to      { color: #2AA198; }
+#diagram-choice  { color: #B58900; }
+#diagram-action  { color: #D33682; }
+#diagram-eip     { color: #6C71C4; }
+#diagram-default { color: #93A1A1; }
diff --git 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/resources/tui/themes/tokyo-night.tcss
 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/resources/tui/themes/tokyo-night.tcss
new file mode 100644
index 000000000000..d84a93243c5b
--- /dev/null
+++ 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/resources/tui/themes/tokyo-night.tcss
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/* Camel TUI Tokyo Night theme. Cool blue-purple palette inspired by Tokyo 
city lights. */
+
+$brand: #7AA2F7;
+$tokyo-bg: #1A1B26;
+$tokyo-fg: #A9B1D6;
+
+#accent         { color: $brand; }
+#accent-bg      { color: white; background: $brand; text-style: bold; }
+#hint-key       { color: white; background: $brand; text-style: bold; }
+#border         { color: #3B3F52; }
+#border-focused { color: $brand; }
+#title          { color: $brand; text-style: bold; }
+#success        { color: #9ECE6A; }
+#warning        { color: #E0AF68; }
+#error          { color: #F7768E; }
+#muted          { color: #565F89; }
+#selection      { color: white; background: #283B5E; text-style: bold; }
+#info           { color: #7AA2F7; }
+#notice         { color: #BB9AF7; }
+#row-alt        { background: #1F2133; }
+#base-bg        { background: $tokyo-bg; }
+#base-fg        { color: $tokyo-fg; }
+
+/* Content tokens — labels, change indicators, search highlight */
+#label          { color: #E0AF68; }
+#change         { color: #E0AF68; }
+#search-match   { color: black; background: #E0AF68; }
+#mnemonic       { color: #E0AF68; text-style: bold underline; }
+
+/* Diagram tokens */
+#diagram-border  { color: #565F89; }
+#diagram-id      { color: $tokyo-fg; }
+#diagram-from    { color: #9ECE6A; }
+#diagram-to      { color: #2AC3DE; }
+#diagram-choice  { color: #E0AF68; }
+#diagram-action  { color: #BB9AF7; }
+#diagram-eip     { color: #73DACA; }
+#diagram-default { color: #565F89; }
diff --git 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/test/java/org/apache/camel/dsl/jbang/core/commands/tui/ThemeModeCompletionCandidatesTest.java
 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/test/java/org/apache/camel/dsl/jbang/core/commands/tui/ThemeModeCompletionCandidatesTest.java
index 266a0d083901..3288e9f4276d 100644
--- 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/test/java/org/apache/camel/dsl/jbang/core/commands/tui/ThemeModeCompletionCandidatesTest.java
+++ 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/test/java/org/apache/camel/dsl/jbang/core/commands/tui/ThemeModeCompletionCandidatesTest.java
@@ -26,10 +26,13 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
 class ThemeModeCompletionCandidatesTest {
 
     @Test
-    void offersDarkAndLightForShellCompletion() {
+    void offersAllThemeIdsForShellCompletion() {
         List<String> candidates = new ArrayList<>();
         new ThemeModeCompletionCandidates().forEach(candidates::add);
 
-        assertEquals(List.of("dark", "light"), candidates);
+        assertEquals(List.of(
+                "dark", "light", "dracula", "nord", "solarized-dark", 
"solarized-light",
+                "gruvbox-dark", "catppuccin-mocha", "catppuccin-latte", 
"tokyo-night",
+                "rose-pine", "kanagawa", "everforest", "monochrome", "crt"), 
candidates);
     }
 }
diff --git 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/test/java/org/apache/camel/dsl/jbang/core/commands/tui/ThemeModeTest.java
 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/test/java/org/apache/camel/dsl/jbang/core/commands/tui/ThemeModeTest.java
index e3a104eece5e..eb98f28b2b4e 100644
--- 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/test/java/org/apache/camel/dsl/jbang/core/commands/tui/ThemeModeTest.java
+++ 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/test/java/org/apache/camel/dsl/jbang/core/commands/tui/ThemeModeTest.java
@@ -59,26 +59,47 @@ class ThemeModeTest {
     }
 
     @Test
-    void toggleFlipsBetweenTheTwoModes() {
-        assertEquals(ThemeMode.LIGHT, ThemeMode.DARK.toggle());
-        assertEquals(ThemeMode.DARK, ThemeMode.LIGHT.toggle());
+    void nextCyclesToNextThemeInDeclarationOrder() {
+        assertEquals(ThemeMode.LIGHT, ThemeMode.DARK.next());
+        assertEquals(ThemeMode.DRACULA, ThemeMode.LIGHT.next());
+        assertEquals(ThemeMode.DARK, ThemeMode.CRT.next());
     }
 
     @Test
-    void idsListsBothCanonicalValuesInDeclarationOrder() {
-        assertEquals(List.of("dark", "light"), ThemeMode.ids());
+    void idsListsAllCanonicalValuesInDeclarationOrder() {
+        assertEquals(List.of(
+                "dark", "light", "dracula", "nord", "solarized-dark", 
"solarized-light",
+                "gruvbox-dark", "catppuccin-mocha", "catppuccin-latte", 
"tokyo-night",
+                "rose-pine", "kanagawa", "everforest", "monochrome", "crt"), 
ThemeMode.ids());
     }
 
     @Test
     void stylesheetResourcePointsAtTheModeSpecificTcssFile() {
         assertEquals("tui/themes/dark.tcss", 
ThemeMode.DARK.stylesheetResource());
         assertEquals("tui/themes/light.tcss", 
ThemeMode.LIGHT.stylesheetResource());
+        assertEquals("tui/themes/catppuccin-mocha.tcss", 
ThemeMode.CATPPUCCIN_MOCHA.stylesheetResource());
+        assertEquals("tui/themes/tokyo-night.tcss", 
ThemeMode.TOKYO_NIGHT.stylesheetResource());
     }
 
     @Test
     void idIsDistinctLowercaseCanonicalFormPerMode() {
         assertEquals("dark", ThemeMode.DARK.id());
         assertEquals("light", ThemeMode.LIGHT.id());
+        assertEquals("catppuccin-mocha", ThemeMode.CATPPUCCIN_MOCHA.id());
         assertNotEquals(ThemeMode.DARK.id(), ThemeMode.LIGHT.id());
     }
+
+    @Test
+    void labelReturnsHumanReadableDisplayName() {
+        assertEquals("Dark", ThemeMode.DARK.label());
+        assertEquals("Catppuccin Mocha", ThemeMode.CATPPUCCIN_MOCHA.label());
+        assertEquals("Rosé Pine", ThemeMode.ROSE_PINE.label());
+    }
+
+    @Test
+    void parseRecognizesAllThemeIds() {
+        for (ThemeMode m : ThemeMode.values()) {
+            assertEquals(Optional.of(m), ThemeMode.parse(m.id()));
+        }
+    }
 }
diff --git 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/test/java/org/apache/camel/dsl/jbang/core/commands/tui/ThemeTest.java
 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/test/java/org/apache/camel/dsl/jbang/core/commands/tui/ThemeTest.java
index 306f3feda389..eac4f2e90391 100644
--- 
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/test/java/org/apache/camel/dsl/jbang/core/commands/tui/ThemeTest.java
+++ 
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/test/java/org/apache/camel/dsl/jbang/core/commands/tui/ThemeTest.java
@@ -82,7 +82,7 @@ class ThemeTest {
     void lightPaletteDiffersForStatusTokensButKeepsBrand() {
         // Light theme: status hues are explicit dark hex; brand orange is 
unchanged.
         Theme.setMode("light");
-        assertEquals(Color.rgb(0xF6, 0x91, 0x23), Theme.accent());
+        assertEquals(Color.rgb(0xD9, 0x77, 0x06), Theme.accent());
         assertEquals(Style.EMPTY.fg(Color.rgb(0x22, 0x86, 0x3A)), 
Theme.success());
         assertEquals(Style.EMPTY.fg(Color.rgb(0xC0, 0xC0, 0xC0)), 
Theme.border());
         // Zebra background is theme-aware: light gray on light, unlike the 
dark gray used on dark.
@@ -93,7 +93,7 @@ class ThemeTest {
     }
 
     @Test
-    void toggleFlipsModeAndChangesThemeDependentToken() {
+    void toggleCyclesToNextThemeAndChangesToken() {
         Theme.setMode("dark");
         assertEquals("dark", Theme.mode());
         Style darkBorder = Theme.border();
@@ -106,12 +106,10 @@ class ThemeTest {
     }
 
     @Test
-    void toggleFlipsModeBackAndForth() {
+    void toggleCyclesThroughAllThemes() {
         Theme.setMode("dark");
         assertEquals("light", Theme.toggle());
-        assertEquals("light", Theme.mode());
-        assertEquals("dark", Theme.toggle());
-        assertEquals("dark", Theme.mode());
+        assertEquals("dracula", Theme.toggle());
     }
 
     @Test
@@ -142,9 +140,12 @@ class ThemeTest {
     }
 
     @Test
-    void isValidModeAcceptsDarkAndLightOnly() {
+    void isValidModeAcceptsAllKnownThemes() {
         assertTrue(Theme.isValidMode("dark"));
         assertTrue(Theme.isValidMode("LIGHT"));
+        assertTrue(Theme.isValidMode("dracula"));
+        assertTrue(Theme.isValidMode("catppuccin-mocha"));
+        assertTrue(Theme.isValidMode("tokyo-night"));
         assertFalse(Theme.isValidMode("sepia"));
         assertFalse(Theme.isValidMode(null));
     }
@@ -219,6 +220,60 @@ class ThemeTest {
         }
     }
 
+    @Test
+    void previewAppliesThemeWithoutPersisting() {
+        Theme.setMode("dark");
+        Theme.preview("dracula");
+        assertEquals("dracula", Theme.mode());
+        assertEquals("dark", Theme.persistedMode());
+    }
+
+    @Test
+    void revertPreviewRestoresOriginalTheme() {
+        Theme.setMode("dark");
+        Theme.preview("nord");
+        assertEquals("nord", Theme.mode());
+
+        Theme.revertPreview();
+        assertEquals("dark", Theme.mode());
+        assertEquals("dark", Theme.persistedMode());
+    }
+
+    @Test
+    void confirmPreviewClearsPreviewState() {
+        Theme.setMode("dark");
+        Theme.preview("tokyo-night");
+        Theme.confirmPreview();
+        assertEquals("tokyo-night", Theme.mode());
+        assertEquals("tokyo-night", Theme.persistedMode());
+    }
+
+    @Test
+    void previewSequenceTracksOnlyOriginal() {
+        Theme.setMode("dark");
+        Theme.preview("dracula");
+        Theme.preview("nord");
+        Theme.preview("catppuccin-mocha");
+        assertEquals("dark", Theme.persistedMode());
+
+        Theme.revertPreview();
+        assertEquals("dark", Theme.mode());
+    }
+
+    @Test
+    void allThemesLoadSuccessfully() {
+        for (ThemeMode m : ThemeMode.values()) {
+            Theme.resetForTesting();
+            Theme.setMode(m.id());
+            assertEquals(m.id(), Theme.mode());
+            assertNotNull(Theme.accent());
+            assertNotNull(Theme.baseBg());
+            assertNotNull(Theme.baseFg());
+            assertNotNull(Theme.success());
+            assertNotNull(Theme.error());
+        }
+    }
+
     @Test
     void accessorsNeverReturnNull() {
         // Resilience: even when resolution is exercised the palette is always 
usable.

Reply via email to