# Widget Design System Integration

## Overview

This document outlines the plan to integrate the modern UI design system from
`scripts/preview-modern-ui.py` into the widget system at `kollabor/ui/widgets/`.

## Current State

**Widgets** (`kollabor/ui/widgets/`):
- Use basic `ColorPalette` from `visual_effects.py`
- Simple ANSI color codes (e.g., `ColorPalette.BRIGHT_WHITE`)
- No theming, no gradients, no box rendering
- Plain text output: `  [x] Label` or `  Label: [value]`

**Preview Script** (`scripts/preview-modern-ui.py`):
- Full color mode system (truecolor/256/16)
- Theme system with semantic colors (lime, ocean, sunset, mono)
- Gradient engine with ANSI preservation
- Box/TagBox components with half-block edges (▄▀)
- Rich visual components

## Proposed Architecture

```
kollabor/ui/
├── design_system/
│   ├── __init__.py          # Public API exports
│   ├── color_mode.py         # Color mode detection and conversion
│   ├── theme.py              # Theme definitions and management
│   ├── gradient.py           # Gradient rendering engine
│   └── components.py         # Box, TagBox, solid rendering
└── widgets/
    ├── __init__.py           # (updated exports)
    ├── base_widget.py        # (updated with design system)
    └── [widget files]        # (updated rendering)
```

## Design System Components

### 1. Color Mode System (`color_mode.py`)

```python
# Color modes
COLOR_TRUECOLOR = "truecolor"  # 24-bit RGB
COLOR_256 = "256"              # 256-color palette
COLOR_16 = "16"                # Basic 16 ANSI

# Functions
def get_color_mode() -> str
def set_color_mode(mode: str) -> None
def auto_detect_color_mode() -> str
def rgb_to_256(r, g, b) -> int
def rgb_to_16(r, g, b) -> int
def fg_code(r, g, b) -> str      # Generate foreground escape code
def bg_code(r, g, b) -> str      # Generate background escape code
```

**Integration**: Uses existing `visual_effects.py` detection where possible,
adds conversion functions for graceful degradation.

### 2. Theme System (`theme.py`)

```python
@dataclass
class Theme:
    name: str
    # Gradients (list of RGB tuples)
    primary: List[Tuple[int,int,int]]      # Main accent (lime green)
    secondary: List[Tuple[int,int,int]]    # Secondary accent (cyan)
    response_bg: List[Tuple[int,int,int]]  # Response background
    input_bg: List[Tuple[int,int,int]]     # Input field background
    dark: List[Tuple[int,int,int]]         # Dark backgrounds
    # Semantic colors
    success: List[Tuple[int,int,int]]
    error: List[Tuple[int,int,int]]
    warning: List[Tuple[int,int,int]]
    # Solid colors (single RGB)
    text: Tuple[int,int,int]
    text_dim: Tuple[int,int,int]
    text_dark: Tuple[int,int,int]
    focus_bg: Tuple[int,int,int]           # Widget focus highlight
    focus_fg: Tuple[int,int,int]

# Preset themes
THEMES = {
    'lime': Theme(...),      # Default - lime green accent
    'ocean': Theme(...),     # Cyan/blue tones
    'sunset': Theme(...),    # Warm orange/magenta
    'mono': Theme(...),      # Grayscale
}

# Functions
def get_theme() -> Theme
def set_theme(name: str) -> None
```

### 3. Gradient Engine (`gradient.py`)

```python
# Core function - applies per-character background gradient
def gradient(text: str, colors: List[RGB], fg: RGB, width: int = None) -> str
    """
    - Preserves existing ANSI codes in text
    - Pads to width if specified
    - Falls back to solid color in 256/16 mode
    """

# Foreground-only gradient
def gradient_fg(text: str, colors: List[RGB], width: int = None) -> str

# Solid color helpers
def solid(text: str, bg: RGB, fg: RGB, width: int = None) -> str
def solid_fg(text: str, color: RGB) -> str
```

### 4. Box Components (`components.py`)

```python
class Box:
    """Renders boxes with half-block edges."""

    @staticmethod
    def top(colors, width) -> str:
        """Top edge using ▄ characters."""

    @staticmethod
    def bottom(colors, width) -> str:
        """Bottom edge using ▀ characters."""

    @staticmethod
    def content(text, colors, fg, width) -> str:
        """Content line with gradient background."""

    @classmethod
    def render(cls, lines, colors, fg, width) -> str:
        """Complete box: top + content lines + bottom."""

class TagBox:
    """Tag + content pattern (colored left tag, content on right)."""

    @staticmethod
    def render(
        lines: List[str],
        tag_bg: RGB,
        tag_fg: RGB,
        tag_width: int,
        content_colors: List[RGB],  # or single RGB for solid
        content_fg: RGB,
        content_width: int,
        tag_chars: List[str] = None,  # Icons per line
        use_gradient: bool = True,
    ) -> str
```

## Widget Rendering Updates

### Before (Current)

```
  [x] Enable dark mode
  Model: [gpt-4 ▼]
  Temperature: 0.7 [██████░░░░░░░░░░░░░░]
```

### After (With Design System)

```
▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
 ✓  Enable dark mode
▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀

▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
 ▼  Model: gpt-4
▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀

▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
 ◆  Temperature: 0.7 [██████░░░░░░░░]
▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
```

### Widget-Specific Styling

| Widget       | Tag Icon | Tag Color          | Content Style      |
|--------------|----------|--------------------|--------------------|
| Checkbox     | ✓ or ·   | theme.success[0]   | Solid dark bg      |
| Dropdown     | ▼        | theme.secondary[0] | Gradient input_bg  |
| TextInput    | ▌        | theme.primary[0]   | Gradient input_bg  |
| Slider       | ◆        | theme.primary[0]   | Gradient + bar     |
| Label        | (none)   | theme.text_dim     | No box, inline     |

### Focus States

**Unfocused**: Dimmer colors, no gradient (solid fallback)
**Focused**: Full gradient, brighter tag, subtle glow effect

```python
# In base_widget.py
def get_style(self) -> WidgetStyle:
    theme = get_theme()
    if self.focused:
        return WidgetStyle(
            tag_bg=theme.primary[0],
            tag_fg=theme.text_dark,
            content_colors=theme.input_bg,
            content_fg=theme.text,
            use_gradient=True,
        )
    else:
        return WidgetStyle(
            tag_bg=theme.dark[0],
            tag_fg=theme.text_dim,
            content_colors=theme.dark[0],  # Solid, not gradient
            content_fg=theme.text_dim,
            use_gradient=False,
        )
```

## Backward Compatibility

1. **Opt-in**: New rendering is opt-in via `use_modern_style=True` in widget config
2. **Fallback**: If design system unavailable, falls back to current ColorPalette
3. **Color modes**: Automatically degrades in 256/16 color terminals
4. **Config**: Theme selection via `terminal.theme` config key

## Implementation Phases

### Phase 1: Core Design System
- [ ] Create `kollabor/ui/design_system/` directory
- [ ] Implement `color_mode.py` with detection and conversion
- [ ] Implement `theme.py` with 4 preset themes
- [ ] Implement `gradient.py` with ANSI-preserving gradients
- [ ] Implement `components.py` with Box and TagBox

### Phase 2: Widget Integration
- [ ] Add `WidgetStyle` dataclass to `base_widget.py`
- [ ] Add `render_modern()` method to `BaseWidget`
- [ ] Update `CheckboxWidget` with modern rendering
- [ ] Update `DropdownWidget` with modern rendering
- [ ] Update `SliderWidget` with modern rendering
- [ ] Update `TextInputWidget` with modern rendering

### Phase 3: Configuration & Testing
- [ ] Add `terminal.theme` config option
- [ ] Add `terminal.modern_widgets` toggle
- [ ] Create visual test script
- [ ] Update widget showcase

## File Changes Summary

| File | Change Type | Description |
|------|-------------|-------------|
| `kollabor/ui/design_system/__init__.py` | New | Export public API |
| `kollabor/ui/design_system/color_mode.py` | New | Color mode system |
| `kollabor/ui/design_system/theme.py` | New | Theme definitions |
| `kollabor/ui/design_system/gradient.py` | New | Gradient engine |
| `kollabor/ui/design_system/components.py` | New | Box/TagBox components |
| `kollabor/ui/widgets/base_widget.py` | Modify | Add modern rendering |
| `kollabor/ui/widgets/checkbox.py` | Modify | Modern style |
| `kollabor/ui/widgets/dropdown.py` | Modify | Modern style |
| `kollabor/ui/widgets/slider.py` | Modify | Modern style |
| `kollabor/ui/widgets/text_input.py` | Modify | Modern style |
| `kollabor/ui/widgets/__init__.py` | Modify | Export design system |

## Questions for Review

1. **Box edges**: Use half-blocks (▄▀) for all widgets, or only for focused?
2. **Compact mode**: Should there be a compact mode without box edges?
3. **Animation**: Add subtle focus animation (shimmer on focus change)?
4. **Custom themes**: Allow user-defined themes in config.json?

---

**Awaiting approval to proceed with implementation.**
