Asi terminal-css
Provides Textual TCSS patterns for terminal widgets and ACP content styling. Use when building terminal UIs with color-first design, styling Agent Client Protocol output, or integrating Dracula-themed terminal rendering.
install
source · Clone the upstream repo
git clone https://github.com/plurigrid/asi
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/plurigrid/asi "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/terminal-css" ~/.claude/skills/plurigrid-asi-terminal-css && rm -rf "$T"
manifest:
skills/terminal-css/SKILL.mdsource content
Terminal CSS Skill
Foundation patterns for Textual terminal styling from the toad codebase.
When to Use
- Building Textual terminal widgets with proper TCSS styling
- Styling Agent Client Protocol (ACP) tool output (text, diffs, terminals)
- Implementing Dracula color theme for terminal ANSI rendering
- Creating conversation UIs with agent responses, thoughts, and tool calls
- Designing state-based styling (success/error/loading/finalized)
When NOT to Use
- General CSS/HTML web styling (this is Textual-specific TCSS)
- Non-terminal Textual widgets (use standard Textual docs)
- Building ACP protocol handlers (use
directly)acp/protocol.py - Backend terminal emulation logic (see
,ansi.py
)TerminalState
Overview
This skill extracts terminal and ACP content styling patterns from the
toad codebase (batrachianai/toad) for use in building color-first Textual applications.
Core Terminal Widget Hierarchy
Terminal (base) ├── TerminalTool (ACP tool execution) ├── ShellTerminal (interactive shell) └── CommandPane (command output)
TCSS Foundation Patterns
Terminal Base Styling
/* From toad.tcss - Terminal within Conversation */ Terminal { width: 1fr; height: auto; padding: 0 1 0 0; margin: 1 0; overflow: scroll; scrollbar-size: 0 0; } /* TerminalTool - ACP tool execution terminals */ TerminalTool { height: auto; border: panel $text-secondary 90%; padding: 1 1 0 1; &.-success { border: panel $text-success 90%; } &.-error { border: panel $error-muted; border-title-color: $text-error; border-subtitle-align: right; border-subtitle-style: bold; } &.-finalized { /* Added when terminal is finalized (no more writes) */ } }
ACP Content Styling
/* ACPToolCallContent - renders ToolCallContent from ACP */ ACPToolCallContent { Markdown { margin: 0; padding-left: 0; MarkdownBlock:last-of-type { margin-bottom: 0; } } } /* ToolCall widget styling */ ToolCall { padding: 0 0 0 1; width: 1fr; layout: stream; height: auto; .icon { width: auto; margin-right: 1; } #tool-content { display: none; } &.-has-content #tool-content { margin-top: 1; } &.-expanded { #tool-content { display: block; } } }
Color Variables (Semantic)
/* Toad uses Textual's design system variables */ $text-primary /* Primary text color */ $text-secondary /* Secondary/muted text */ $text-success /* Success state (green) */ $text-error /* Error state (red) */ $text-accent /* Accent color for highlights */ $text-muted /* Highly muted text */ $primary /* Primary UI color */ $secondary /* Secondary UI color */ $error /* Error color */ $error-muted /* Muted error */ $warning /* Warning color */ $accent /* Accent color */ $background /* Background color */ $foreground /* Foreground color */
Dracula Terminal Theme
# From app.py - ANSI color palette for terminal rendering DRACULA_TERMINAL_THEME = terminal_theme.TerminalTheme( background=(40, 42, 54), # #282A36 foreground=(248, 248, 242), # #F8F8F2 normal=[ (33, 34, 44), # black - #21222C (255, 85, 85), # red - #FF5555 (80, 250, 123), # green - #50FA7B (241, 250, 140), # yellow - #F1FA8C (189, 147, 249), # blue - #BD93F9 (255, 121, 198), # magenta - #FF79C6 (139, 233, 253), # cyan - #8BE9FD (248, 248, 242), # white - #F8F8F2 ], bright=[ (98, 114, 164), # bright black - #6272A4 (255, 110, 110), # bright red - #FF6E6E (105, 255, 148), # bright green - #69FF94 (255, 255, 165), # bright yellow - #FFFFA5 (214, 172, 255), # bright blue - #D6ACFF (255, 146, 223), # bright magenta - #FF92DF (164, 255, 255), # bright cyan - #A4FFFF (255, 255, 255), # bright white - #FFFFFF ], )
ACP Protocol Content Types
From
protocol.py, the content types that need styling:
# ToolCallContent variants type ToolCallContent = ( ToolCallContentContent # type: "content" - text/markdown | ToolCallContentDiff # type: "diff" - file diffs | ToolCallContentTerminal # type: "terminal" - terminal embed ) # ContentBlock variants (for messages) type ContentBlock = ( TextContent # text | ImageContent # image | AudioContent # audio | EmbeddedResourceContent # embedded resource | ResourceLinkContent # resource link ) # ToolKind for styling based on operation type type ToolKind = Literal[ "read", # File read operations "edit", # File edit operations "delete", # File delete operations "move", # File move operations "search", # Search operations "execute", # Command execution "think", # Thinking/reasoning "fetch", # Network fetch "switch_mode", # Mode switching "other", # Other operations ] # ToolCallStatus for state styling type ToolCallStatus = Literal[ "pending", # Waiting to start "in_progress", # Currently running "completed", # Successfully finished "failed", # Failed ]
Widget Composition Pattern
# From acp_content.py - rendering ToolCallContent class ACPToolCallContent(containers.VerticalGroup): def compose(self) -> ComposeResult: for content in self._content: match content: case {"type": "content", "content": {"type": "text", "text": text}}: yield widgets.Markdown(text) case {"type": "diff", "oldText": old, "newText": new, "path": path}: yield DiffView(path, path, old or "", new) case {"type": "terminal", "terminalId": terminal_id}: # Terminal widget is mounted separately pass
Diff View Styling
/* DiffView for file diffs in tool output */ DiffView { .diff-group { margin-bottom: 0; } } /* Line annotations */ /* + = addition (green) */ /* - = deletion (red) */ /* / = modification */ /* (space) = context */
State Classes
/* Terminal state classes */ .-finalized /* Terminal no longer accepts input */ .-success /* Command completed successfully (exit 0) */ .-error /* Command failed (non-zero exit) */ .-busy /* Terminal is busy/processing */ /* Content visibility */ .-hidden /* Hidden element */ .-expanded /* Expanded content */ .-has-content /* Has content to show */ /* Agent states */ .-loading /* Loading state */ .-maximized /* Maximized view */
Conversation Context Styling
Conversation { AgentResponse { min-height: 1; padding: 0 1 0 0; overflow-x: auto; scrollbar-size-horizontal: 0; layout: stream; } AgentThought { background: $primary-muted 20%; color: $text-primary; min-height: 1; margin: 1 1 1 0; padding: 0 1 0 1; border: blank transparent; max-height: 10; overflow-y: auto; scrollbar-visibility: hidden; &.-loading { background: transparent !important; padding: 0; margin: 0; } &.-maximized { max-height: 100h; scrollbar-visibility: visible; } &:focus { border: tall $primary; } } UserInput { border-left: blank $secondary; background: $secondary 15%; padding: 1 1 1 0; margin: 1 1 1 0; } ShellResult { border-left: blank $primary; background: $foreground 4%; padding: 1 0; margin: 1 1 1 0; #prompt { margin: 0 1 0 0; color: $text-primary; } } }
Border Patterns
/* Textual border types used in toad */ border: panel $color /* Panel-style border */ border: tall $color /* Tall border */ border: round $color /* Rounded border */ border: heavy $color /* Heavy border */ border: wide $color /* Wide border */ border: blank $color /* Invisible but space-taking */ border: solid $color /* Solid border */ border: outer $color /* Outer border (for cursor) */ /* Border modifiers */ border: panel $text-secondary 90%; /* With opacity */ border: wide $error 50%; /* Semi-transparent */
Usage
When building ACP UIs with color-first design:
- Use semantic color variables (
,$text-primary
, etc.)$text-success - Apply state classes for dynamic styling (
,.-success
).-error - Match ToolKind to appropriate visual treatment
- Use the Dracula theme as base terminal palette
- Layer content types appropriately (text → diff → terminal)
Related Skills
| Skill | Trit | Relationship |
|---|---|---|
| 0 | Core terminal emulation (libghostty-vt, tmux, zsh) |
| +1 | Per-vat terminal embedding with Goblins |
| +1 | Terminal streaming protocols |
| +1 | Deterministic color generation (SplitMix64) |
| 0 | Color projection properties |
| +1 | Gay.jl + Glamorous Toolkit integration |
| 0 | Collaborative terminal sessions via CRDT |
Skill Composition
terminal-css (+1) ⊗ terminal (0) ⊗ libghostty-embed (-1) = 0 ✓ terminal-css (+1) ⊗ gay-mcp (+1) ⊗ crdt-vterm (-2 mod 3) = 0 ✓
Use
gay-mcp for deterministic color generation, terminal for VT sequence handling, and terminal-css for TCSS styling patterns.
Related Files
- Main stylesheettoad/src/toad/toad.tcss
- Base Terminal widgettoad/src/toad/widgets/terminal.py
- TerminalTool for ACPtoad/src/toad/widgets/terminal_tool.py
- ACP content renderertoad/src/toad/widgets/acp_content.py
- ACP type definitionstoad/src/toad/acp/protocol.py
- Dracula theme definitiontoad/src/toad/app.py