Zorvia Theme Implementation Guide
This document provides implementation details for the Zorvia TUI and CLI theme system, inspired by GuestKit's design patterns.
File Structureâ
zorvia/
âââ src/
â âââ tui/
â âââ mod.rs # Module exports
â âââ theme.rs # Theme colors and styles (400+ lines)
â âââ config.rs # Configuration system (250+ lines)
â âââ colors.rs # CLI color helpers (150+ lines)
âââ examples/
â âââ tui.toml # Sample configuration file
âââ scripts/
â âââ test_theme.sh # Terminal color test script
âââ docs/THEME.md # This guide
Total: ~800 lines of theme infrastructure code
Quick Startâ
1. Test Theme Colorsâ
Run the color test script to see all theme colors in your terminal:
./scripts/test_theme.sh
This will display:
- All color swatches with hex codes
- VM status symbols with colors
- Sample VM list with themed output
- Resource usage bars
- Border examples
2. Using the Theme in TUI Codeâ
use zorvia::tui::Theme;
let theme = Theme::default();
// Get VM status styling
let style = theme.vm_status_style("running");
// Get VM status symbol with color
let (symbol, style) = theme.vm_status_symbol("running");
// symbol = "â", style = green color
// Get common styles
let title_style = theme.title_style(); // Purple + Bold
let label_style = theme.label_style(); // Light purple
let value_style = theme.value_style(); // White + Bold
let border_style = theme.border_style(); // Dark purple
// Resource-specific styles
let cpu_style = theme.cpu_style(); // Green
let memory_style = theme.memory_style(); // Blue
let disk_style = theme.disk_style(); // Magenta
let network_style = theme.network_style(); // Cyan
// Namespace coloring
let ns_style = theme.namespace_style("default"); // Blue
let ns_style = theme.namespace_style("kube-system"); // Red
let ns_style = theme.namespace_style("my-app"); // Green
// Resource usage with dynamic coloring
let usage_style = theme.resource_usage_style(50.0); // Green (< 70%)
let usage_style = theme.resource_usage_style(85.0); // Orange (70-90%)
let usage_style = theme.resource_usage_style(95.0); // Red (> 90%)
3. Using CLI Colorsâ
For standard CLI output (not TUI), use the color helpers:
use zorvia::tui::colors::cli;
use zorvia::tui::colors::{vm_status_symbol, resource_bar};
// Format text with colors
println!("{}", cli::header("Zorvia Dashboard"));
println!("VM: {}", cli::vm_name("web-server"));
println!("Namespace: {}", cli::namespace("default"));
println!("Status: {}", cli::vm_status("running"));
// Success/Error/Warning messages
println!("{}", cli::success("VM created successfully"));
println!("{}", cli::error("Failed to delete VM"));
println!("{}", cli::warning("VM is using high memory"));
println!("{}", cli::info("Connecting to cluster..."));
// Resources
println!("CPU: {}", cli::resource("4", "cpu"));
println!("Memory: {}", cli::resource("8Gi", "memory"));
// Status symbol
println!("{} Running", vm_status_symbol("running")); // â Running (green)
// Resource bar
let bar = resource_bar(75.0, 20);
println!("CPU: [{}] 75%", bar);
zorvia vm status (no VM name) does not use these helpers. That view matches Cilium's cilium status: raw ANSI (\x1b[31â36m) on the interlocking /¯¯\ logo, plus emoji summaries (â
OK, â N errors, â ī¸ N warnings, âšī¸ disabled). Per-VM zorvia vm status <name> does use cli:: colors. See ADVANCED_FEATURES.md.
One color crate, one deliberate exception: colored is the only color crate for CLI/TUI output (owo-colors was removed â it had no usage independent of colored, both provided overlapping methods on the same types). platform_status's raw ANSI (above) is the one intentional exception, kept exactly as Cilium's own output is byte-for-byte; do not migrate it to colored. Top-level errors (an Err bubbling all the way out of zorvia::run()) render through miette's fancy diagnostic formatter (colored box, Ã marker) instead of a bare Error: ... line â see src/main.rs. This only wraps the final print site; every handler underneath still returns plain anyhow::Result.
--help styling: Cli (src/cli/mod.rs) sets clap::builder::Styles (magenta headers/usage, green literals, cyan placeholders â the same header/value palette tui::colors::cli uses) so zorvia --help and every subcommand's --help are colored by clap itself, not a hand-rolled wrapper. The ~180 commands are grouped into 25 nested subcommand categories (zorvia vm create, zorvia migration migrate, etc. â see the CHANGELOG's "CLI restructured" entry for the full list and rationale) so --help shows one line per group instead of one long flat list; zorvia commands mirrors the same grouping.
4. Loading Configurationâ
use zorvia::tui::TuiConfig;
// Load from default location (~/.config/zorvia/tui.toml)
let config = TuiConfig::load().unwrap_or_default();
// Access settings
if config.ui.show_splash {
// Show splash screen for splash_duration_ms
}
if config.behavior.confirm_delete {
// Show confirmation prompt before deleting
}
if config.keybindings.vim_mode {
// Enable hjkl navigation
}
// Save configuration
config.save()?;
Configuration Fileâ
Users can customize the TUI by creating ~/.config/zorvia/tui.toml:
[theme]
name = "default"
[ui]
show_splash = true
splash_duration_ms = 800
show_stats_bar = true
default_view = "dashboard"
auto_refresh_interval = 5
table_style = "rounded"
[behavior]
confirm_delete = true
confirm_stop = false
confirm_restart = false
search_case_sensitive = false
search_regex = false
scroll_amount = 10
max_list_items = 1000
[keybindings]
vim_mode = true
quick_jump = true
See examples/tui.toml for a complete example with comments.
Color Palette Referenceâ
Primary Colors (Purple Theme)â
- PRIMARY:
#8856DE(136, 86, 222) - Main brand color - DARK_PRIMARY:
#6A3CB4(106, 60, 180) - Borders, secondary - LIGHT_PRIMARY:
#A573FF(165, 115, 255) - Labels, highlights
Status Colorsâ
- SUCCESS:
#32CD32(50, 205, 50) - LimeGreen - WARNING:
#FFA500(255, 165, 0) - Orange - ERROR:
#DC322F(220, 50, 47) - Red - INFO:
#6496FF(100, 150, 255) - Soft Blue
VM State Colorsâ
- VM_RUNNING:
#32CD32(green) with symbolâ - VM_PENDING:
#FFC864(yellow) with symbolâ - VM_STOPPED:
#969696(gray) with symbolâ - VM_FAILED:
#DC322F(red) with symbolâ - VM_MIGRATING:
#64C8FF(cyan) with symbolâŗ - VM_PAUSED:
#FFA500(orange) with symbolâ¸
Resource Colorsâ
- CPU:
#64C864(100, 200, 100) - Green - MEMORY:
#6496FF(100, 150, 255) - Blue - DISK:
#DC78FF(220, 120, 255) - Magenta - NETWORK:
#64DCDC(100, 220, 220) - Cyan
Text Colorsâ
- TEXT_PRIMARY:
#DCDCDC(220, 220, 220) - Soft white - TEXT_SECONDARY:
#B4B4B4(180, 180, 180) - Dimmed - TEXT_MUTED:
#787878(120, 120, 120) - Muted
Namespace Colorsâ
- Default namespace:
#6496FF(blue) - System namespaces (kube-*):
#FF6464(red) - User namespaces:
#96FF96(green)
OS Colors (for Templates)â
- Ubuntu:
#E95420(233, 84, 32) - Fedora:
#3369AD(51, 105, 173) - CentOS:
#9C429D(156, 66, 157) - Debian:
#D70A53(215, 10, 83) - Windows:
#0078D4(0, 120, 212) - RHEL:
#EE0000(238, 0, 0)
Design Patterns from GuestKitâ
1. Centralized Color Constantsâ
All colors are defined in one place (theme.rs) and reused throughout the application.
2. Style Helper Methodsâ
Common style combinations (title, label, value) are pre-defined as helper methods.
3. Dynamic Coloringâ
Colors change based on state (VM status, resource usage percentage, namespace type).
4. Consistent Typographyâ
Typography modifiers (BOLD, UNDERLINED, ITALIC) are used consistently:
- BOLD: Titles, important values, active states
- UNDERLINED: Active tabs, highlighted selections
- ITALIC: Help text, disclaimers
5. Symbol + Color + Textâ
Status indicators use three signals for accessibility:
- Symbol: Visual shape (â, â, â)
- Color: Semantic meaning (green=good, red=bad)
- Text: Explicit state name ("Running", "Failed")
6. Configuration Systemâ
Theme is configurable via TOML file at ~/.config/zorvia/tui.toml.
7. OS-Specific Brandingâ
Template views use OS-specific brand colors (Ubuntu orange, Fedora blue, etc.).
Testingâ
Unit Testsâ
The theme module includes unit tests:
cargo test --lib tui::theme
cargo test --lib tui::config
cargo test --lib tui::colors
Visual Testingâ
Run the color test script:
./scripts/test_theme.sh
Verify that:
- All colors render correctly in your terminal
- RGB values match the design specification
- Status symbols display properly
- Borders and separators are visible
Integration Testingâ
When building TUI views:
- Use the test script to verify colors
- Test in different terminal emulators
- Test with different terminal color schemes (light/dark)
- Verify accessibility (contrast ratios)
Future Enhancementsâ
Phase 1 (Current)â
- â Core theme system with color constants
- â Configuration file support
- â CLI color helpers
- â VM status styling
- â Resource coloring
- â Namespace coloring
Phase 2 (Next)â
- Actual TUI views implementation
- Layout system with ratatui
- Keyboard navigation
- Modal dialogs
- Help overlay
Phase 3 (Future)â
- Multiple theme support (dark, light, kubernetes)
- Custom theme creation
- Theme marketplace
- Colorblind modes
- ASCII-only mode
Dependenciesâ
All theme dependencies are already added to Cargo.toml:
# TUI framework
ratatui = "0.28"
crossterm = "0.28"
# CLI colors (the only color crate -- see the note above on why owo-colors was removed)
colored = "3.1"
# Configuration
toml = "0.8"
dirs = "5.0"
# Enhanced errors -- renders a fancy diagnostic box for any top-level error (src/main.rs)
miette = { version = "7.0", features = ["fancy"] }
# Interactive input
rustyline = "17.0"
Examplesâ
Example: VM List with Themeâ
use ratatui::widgets::{Block, Borders, List, ListItem};
use zorvia::tui::Theme;
let theme = Theme::default();
// Create list items with themed colors
let items: Vec<ListItem> = vms
.iter()
.map(|vm| {
let (symbol, symbol_style) = theme.vm_status_symbol(&vm.status);
let name_style = theme.value_style();
let ns_style = theme.namespace_style(&vm.namespace);
let content = format!(
"{} {} ({})",
symbol,
vm.name,
vm.namespace
);
ListItem::new(content).style(name_style)
})
.collect();
// Create themed block
let block = Block::default()
.title("Virtual Machines")
.title_style(theme.title_style())
.borders(Borders::ALL)
.border_style(theme.border_style());
let list = List::new(items).block(block);
Example: Resource Gaugeâ
use ratatui::widgets::Gauge;
use zorvia::tui::Theme;
let theme = Theme::default();
let cpu_usage = 75.0;
let gauge_style = theme.resource_usage_style(cpu_usage);
let gauge = Gauge::default()
.block(
Block::default()
.title("CPU Usage")
.title_style(theme.title_style())
.borders(Borders::ALL)
.border_style(theme.border_style())
)
.gauge_style(gauge_style)
.percent(cpu_usage as u16)
.label(format!("{}%", cpu_usage));
Best Practicesâ
- Always use theme constants - Never hardcode RGB values
- Use style helpers - Prefer
theme.title_style()over manual Style creation - Test colors - Run
test_theme.shafter theme changes - Consider accessibility - Use symbol + color + text for status
- Respect user config - Load and honor TuiConfig settings
- Consistent modifiers - Follow the typography guidelines
- Resource-specific colors - Use dedicated colors for CPU, memory, disk, network
Documentationâ
- docs/THEME.md: This file â implementation guide
- examples/tui.toml: Sample configuration with comments
- src/tui/theme.rs: API documentation in code comments
- src/tui/config.rs: Configuration structure documentation
Inspiration Sourcesâ
- GuestKit: Color palette system, configuration architecture, view patterns
- Kubernetes: Purple brand color inspiration
- k9s: Keyboard navigation, real-time updates
- lazydocker: Status indicators, interactive patterns
- Ratatui examples: Component implementations
Supportâ
For questions or issues:
- Review this guide and
src/tui/theme.rs - Run
test_theme.shto verify color rendering - Check unit tests in theme.rs, config.rs, colors.rs
Changelogâ
v0.1.0 (Initial Implementation)â
- Core theme system with purple color palette
- Configuration system with TOML support
- CLI color helpers
- VM status styling with symbols
- Resource usage coloring
- Namespace-based coloring
- OS-specific template colors
- Test script for color verification
- Comprehensive documentation