tui-style-guide

TUI style guide for consistent terminal interface design

Best use case

tui-style-guide is best used when you need a repeatable AI agent workflow instead of a one-off prompt.

TUI style guide for consistent terminal interface design

Teams using tui-style-guide should expect a more consistent output, faster repeated execution, less prompt rewriting.

When to use this skill

  • You want a reusable workflow that can be run more than once with consistent structure.

When not to use this skill

  • You only need a quick one-off answer and do not need a reusable workflow.
  • You cannot install or maintain the underlying files, dependencies, or repository context.

Installation

Claude Code / Cursor / Codex

$curl -o ~/.claude/skills/tui-style-guide/SKILL.md --create-dirs "https://raw.githubusercontent.com/stevengonsalvez/agents-in-a-box/main/toolkit/packages/skills/tui-style-guide/SKILL.md"

Manual Installation

  1. Download SKILL.md from GitHub
  2. Place it in .claude/skills/tui-style-guide/SKILL.md inside your project
  3. Restart your AI agent — it will auto-discover the skill

How tui-style-guide Compares

Feature / Agenttui-style-guideStandard Approach
Platform SupportNot specifiedLimited / Varies
Context Awareness High Baseline
Installation ComplexityUnknownN/A

Frequently Asked Questions

What does this skill do?

TUI style guide for consistent terminal interface design

Where can I find the source code?

You can find the source code on GitHub using the link provided at the top of the page.

SKILL.md Source

# TUI Style Guide

Premium styling patterns for agents-in-a-box TUI components.

## Color Palette

### Primary Colors
```rust
// Core accent colors
const CORNFLOWER_BLUE: Color = Color::Rgb(100, 149, 237);  // Primary accent, borders, section titles
const GOLD: Color = Color::Rgb(255, 215, 0);               // Important CTAs, emphasis, highlights
const SELECTION_GREEN: Color = Color::Rgb(100, 200, 100);  // Active selections, success states
const WARNING_ORANGE: Color = Color::Rgb(255, 165, 0);     // Warnings, alternate modes

// Background colors
const DARK_BG: Color = Color::Rgb(25, 25, 35);             // Main UI background
const INPUT_BG: Color = Color::Rgb(35, 35, 45);            // Input field backgrounds
const PANEL_BG: Color = Color::Rgb(30, 30, 40);            // Panel/nested container backgrounds
const LIST_HIGHLIGHT_BG: Color = Color::Rgb(40, 40, 60);   // List item hover/selection

// Text colors
const SOFT_WHITE: Color = Color::Rgb(220, 220, 230);       // Primary text
const MUTED_GRAY: Color = Color::Rgb(120, 120, 140);       // Secondary text, hints
const MEDIUM_GRAY: Color = Color::Rgb(180, 180, 180);      // Tertiary text
const DARK_GRAY: Color = Color::Rgb(100, 100, 100);        // Disabled/faded text

// Accent/status colors
const PROGRESS_CYAN: Color = Color::Rgb(100, 200, 230);    // Loading/processing
const LIGHT_BLUE: Color = Color::Rgb(100, 200, 255);       // Info highlights
const SUBDUED_BORDER: Color = Color::Rgb(60, 60, 80);      // Separator lines, secondary borders
```

## Border Styles

### Standard Panel Border
```rust
Block::default()
    .borders(Borders::ALL)
    .border_type(BorderType::Rounded)
    .border_style(Style::default().fg(CORNFLOWER_BLUE))
    .style(Style::default().bg(DARK_BG))
```

### Active/Focused Border
```rust
.border_style(Style::default().fg(SELECTION_GREEN))
```

### Muted/Secondary Border
```rust
.border_style(Style::default().fg(SUBDUED_BORDER))
```

## Title Patterns

### Primary Title with Icon
```rust
.title(Line::from(vec![
    Span::styled(" folder_icon ", Style::default().fg(GOLD)),
    Span::styled("Section Title",
        Style::default().fg(GOLD).add_modifier(Modifier::BOLD))
]))
```

### Title with Count Badge
```rust
.title(Line::from(vec![
    Span::styled(" Section ", Style::default().fg(SOFT_WHITE)),
    Span::styled(
        format!("({})", count),
        Style::default().fg(CORNFLOWER_BLUE).add_modifier(Modifier::BOLD)
    )
]))
```

## List Item Patterns

### Selected Item
```rust
// Prefix
Span::styled("  > ", Style::default().fg(SELECTION_GREEN))
// Text
Span::styled(&item_text,
    Style::default()
        .fg(SELECTION_GREEN)
        .add_modifier(Modifier::BOLD))
```

### Unselected Item
```rust
// Prefix (spacing to align with selected)
Span::raw("    ")
// Text
Span::styled(&item_text, Style::default().fg(SOFT_WHITE))
```

### List Highlight Style
```rust
.highlight_style(Style::default().bg(LIST_HIGHLIGHT_BG))
.highlight_symbol("> ")
```

## Status Indicators

### Icon Patterns
| Status | Icon | Color |
|--------|------|-------|
| Running | Green circle | Green |
| Stopped | Red circle | Red |
| Idle | Yellow circle | Yellow |
| Error | X mark | Red |
| Success | Checkmark | Green |
| Warning | Warning sign | Orange |
| Info | Info sign | Cyan |
| Loading | Refresh | Cyan |

### Status Badge Style
```rust
Span::styled(
    format!("[{}]", status_symbol),
    Style::default()
        .fg(status_color)
        .add_modifier(Modifier::BOLD)
)
```

## File/Folder Icons

```rust
fn get_file_icon(filename: &str) -> &'static str {
    match filename {
        f if f.ends_with(".rs") => "rust",
        f if f.ends_with(".py") => "python",
        f if f.ends_with(".js") || f.ends_with(".jsx") => "js",
        f if f.ends_with(".ts") || f.ends_with(".tsx") => "ts",
        f if f.ends_with(".md") => "markdown",
        f if f.ends_with(".json") => "json",
        f if f.ends_with(".toml") || f.ends_with(".yaml") || f.ends_with(".yml") => "config",
        f if f.ends_with(".sh") || f.ends_with(".bash") => "shell",
        f if f.ends_with(".html") => "html",
        f if f.ends_with(".css") || f.ends_with(".scss") => "css",
        f if f.ends_with(".go") => "go",
        f if f.ends_with(".java") => "java",
        _ => "file",
    }
}

// Folder icons
const FOLDER_ICON: &str = "folder";
const FOLDER_OPEN_ICON: &str = "folder-open";
```

## Tree Characters

```rust
// Expand/collapse indicators
const EXPANDED: &str = "v";
const COLLAPSED: &str = ">";
const LEAF: &str = ">";

// Tree lines
const TREE_BRANCH: &str = "|-";
const TREE_LAST: &str = "`-";
const TREE_VERTICAL: &str = "|";
```

## Keyboard Help Text

### Standard Format
```rust
Line::from(vec![
    Span::styled("Up/Down", Style::default().fg(GOLD).add_modifier(Modifier::BOLD)),
    Span::styled(" Navigate", Style::default().fg(MUTED_GRAY)),
    Span::styled("  |  ", Style::default().fg(SUBDUED_BORDER)),
    Span::styled("Enter", Style::default().fg(GOLD).add_modifier(Modifier::BOLD)),
    Span::styled(" Select", Style::default().fg(MUTED_GRAY)),
])
```

## Input Fields

### Active Input
```rust
Block::default()
    .borders(Borders::ALL)
    .border_type(BorderType::Rounded)
    .border_style(Style::default().fg(SELECTION_GREEN))
    .style(Style::default().bg(INPUT_BG))

// Cursor character
Span::styled("_", Style::default().fg(SELECTION_GREEN))
```

## Mode/Card Selection

### Selected Card
```rust
Block::default()
    .borders(Borders::ALL)
    .border_type(BorderType::Rounded)
    .border_style(Style::default().fg(SELECTION_GREEN))
    .style(Style::default().bg(Color::Rgb(35, 45, 35)))  // Green tint
```

### Unselected Card
```rust
Block::default()
    .borders(Borders::ALL)
    .border_type(BorderType::Rounded)
    .border_style(Style::default().fg(Color::Rgb(70, 70, 90)))
    .style(Style::default().bg(PANEL_BG))
```

## Git Status Colors

```rust
const GIT_ADDED: Color = Color::Green;
const GIT_MODIFIED: Color = Color::Yellow;
const GIT_DELETED: Color = Color::Red;
const GIT_RENAMED: Color = Color::Blue;
const GIT_UNTRACKED: Color = Color::Magenta;
```

## Diff View Colors

```rust
// Line prefixes
const DIFF_ADDITION: Color = Color::Green;      // Lines starting with +
const DIFF_DELETION: Color = Color::Red;        // Lines starting with -
const DIFF_HUNK: Color = Color::Cyan;           // @@ lines
const DIFF_FILE_HEADER: Color = Color::Yellow;  // +++ and --- lines
const DIFF_CONTEXT: Color = Color::White;       // Unchanged lines
```

## Markdown Viewer Colors

```rust
const MD_HEADING1: Style = Style::default()
    .fg(Color::Cyan)
    .add_modifier(Modifier::BOLD | Modifier::UNDERLINED);
const MD_HEADING2: Style = Style::default()
    .fg(Color::Cyan)
    .add_modifier(Modifier::BOLD);
const MD_HEADING3: Style = Style::default()
    .fg(Color::Blue)
    .add_modifier(Modifier::BOLD);
const MD_CODE_BLOCK: Style = Style::default()
    .fg(Color::Green)
    .bg(Color::Rgb(30, 30, 30));
const MD_CODE_HEADER: Style = Style::default()
    .fg(Color::Yellow)
    .add_modifier(Modifier::BOLD);
const MD_LINK: Style = Style::default()
    .fg(Color::Blue)
    .add_modifier(Modifier::UNDERLINED);
const MD_BLOCKQUOTE: Style = Style::default()
    .fg(Color::Gray)
    .add_modifier(Modifier::ITALIC);
```

## Layout Guidelines

### Centered Modal (Standard)
- Width: 80% of terminal width
- Height: 70% of terminal height

### Split Pane Ratios
- Sessions/Logs: 40/60
- Equal split: 50/50

### Internal Spacing
- Panel margins: 1px
- Content padding: Use `Constraint::Length(N)` for headers/footers
- Flexible content: `Constraint::Min(0)`

## Common Imports

```rust
use ratatui::{
    layout::{Constraint, Direction, Layout, Rect},
    style::{Color, Modifier, Style},
    text::{Line, Span},
    widgets::{Block, Borders, BorderType, List, ListItem, ListState, Paragraph, Tabs, Wrap},
    Frame,
};
```

---

**Usage**: Reference this guide when styling new TUI components to maintain visual consistency across the application.

Related Skills

workflow

8
from stevengonsalvez/agents-in-a-box

Guide through structured delivery workflow with plan, implement, validate phases

webapp-testing

8
from stevengonsalvez/agents-in-a-box

Toolkit for interacting with and testing local web applications using Playwright. Supports verifying frontend functionality, debugging UI behavior, capturing browser screenshots, and viewing browser logs.

validate

8
from stevengonsalvez/agents-in-a-box

Verify implementation against specifications

ui-ux-pro-max

8
from stevengonsalvez/agents-in-a-box

UI/UX design intelligence. 67 styles, 96 palettes, 57 font pairings, 25 charts, 13 stacks (React, Next.js, Vue, Svelte, Astro, Nuxt, SwiftUI, React Native, Flutter, Tailwind, shadcn/ui, Jetpack Compose). Actions: plan, build, create, design, implement, review, fix, improve, optimize, enhance, refactor, check UI/UX code. Projects: website, landing page, dashboard, admin panel, e-commerce, SaaS, portfolio, blog, mobile app, .html, .tsx, .vue, .svelte. Elements: button, modal, navbar, sidebar, card, table, form, chart. Styles: glassmorphism, claymorphism, minimalism, brutalism, neumorphism, bento grid, dark mode, responsive, skeuomorphism, flat design. Topics: color palette, accessibility, animation, layout, typography, font pairing, spacing, hover, shadow, gradient.

token-usage

8
from stevengonsalvez/agents-in-a-box

Show Claude Code token usage across sessions — daily, weekly, per-project, and per-session breakdowns. Parses {{HOME_TOOL_DIR}}/projects/**/*.jsonl for consumption data. Use when the user asks about token usage, costs, how many tokens were used, session statistics, or wants a usage report.

tmux-status

8
from stevengonsalvez/agents-in-a-box

Show status of all tmux sessions including dev environments, spawned agents, and running processes

tmux-monitor

8
from stevengonsalvez/agents-in-a-box

Monitor and report status of all tmux sessions including dev environments, spawned agents, and running processes. Uses tmuxwatch for enhanced visibility.

tmux-message

8
from stevengonsalvez/agents-in-a-box

Reliable peer-to-peer message delivery to other Claude Code instances via tmux send-keys. Use as a fallback when claude-peers MCP send_message fails to surface in the receiver's inbox (delivered server-side but receiver never picks it up — observed behaviour). Also use when sending a directive to a known Claude Code TUI session by tmux session name or fuzzy hint, or when injecting a multi-line directive into a peer's prompt and submitting it. Trigger phrases — "claude-peers fallback", "tmux send-keys", "send to peer via tmux", "inject directive", "deliver to nanoclaw/hermes peer", "peer message". Tmux-only — won't reach peers running outside tmux.

test-driven-development

8
from stevengonsalvez/agents-in-a-box

Use when implementing any feature or bugfix, before writing implementation code. Enforces RED-GREEN-REFACTOR cycle with test-first approach.

test-ainb

8
from stevengonsalvez/agents-in-a-box

Run tests for the ainb (agents-in-a-box) Rust workspace via a 5-layer strategy — unit, insta snapshot, mock-plugin compositing, real-plugin spawn, vhs recording. Wraps cargo + insta + vhs into one CLI. Use when Stevie says "/test-ainb", "test ainb", "run ainb tests", "snapshot <component>", "regenerate vhs tapes", or any phrasing about validating ainb test layers. The skill autodetects which ainb-tui worktree the cwd sits in and dispatches to scripts/run.sh.

sync-learnings

8
from stevengonsalvez/agents-in-a-box

Sync user-level agent config changes back to toolkit repository (works for Claude, Codex, Copilot)

swarm-status

8
from stevengonsalvez/agents-in-a-box

Display comprehensive status dashboard for a swarm team