# Neon Design System — Theme Tokens

> Referencia completa de todos los tokens visuales del sistema.
> Definidos en `ui/theme.slint` (dark) y `ui/theme_light.slint` (light).

---

## Theme Switch

```slint
global Theme {
    in-out property <bool> dark-mode: true;
}
```

Controlado desde Rust:
```rust
window.global::<Theme>().set_dark_mode(true);
```

---

## Surface Colors

| Token | Dark | Light | Uso |
|-------|------|-------|-----|
| bg-base | `#0a0e17` | `#f2f5fa` | Fondo de página |
| bg-elevated | `#111827` | `#e8edf5` | Cards, paneles, sidebars |
| bg-surface | `#1a2235` | `#ffffff` | Inputs, dropdowns |
| bg-hover | `#243044` | `#dfe6f0` | Hover states |
| bg-selected | `#1e2d4a` | `#c8d6e8` | Selected rows |
| bg-row-alt | `#0f1625` | `#f0f4fa` | Zebra stripe |
| bg-overlay | `#0a0e17e6` | `#0a0e1799` | Modal backdrop |
| bg-glass | `#11182788` | `#ffffffaa` | Glassmorphism |
| bg-tooltip | `#1a2235` | `#ffffff` | Tooltip background |

---

## Border Colors

| Token | Dark | Uso |
|-------|------|-----|
| border | `#2a344a` | Default divider |
| border-bright | `#3a4660` | Emphasised rule |
| border-focus | `#00f0ff` | Focus ring (neon cyan) |
| border-glass | `#ffffff15` | Glass edge |

---

## Text Colors

| Token | Dark | Uso |
|-------|------|-----|
| text-primary | `#e2e8f0` | Body copy |
| text-muted | `#94a3b8` | Secondary labels |
| text-dim | `#64748b` | Hints, placeholders |
| text-inverse | `#0a0e17` | On bright accents |

---

## Neon Accents

| Token | Dark | Light | Uso |
|-------|------|-------|-----|
| neon-cyan | `#00f0ff` | `#0077aa` | Primary interactive |
| neon-magenta | `#ff2d95` | `#cc2277` | Special / alert |
| neon-green | `#00ff88` | `#009955` | Success / active |
| neon-purple | `#8b5cf6` | `#6633cc` | Info / secondary |
| neon-amber | `#ffb020` | `#cc8800` | Warning |
| neon-red | `#ff4455` | `#cc2233` | Danger / error |

---

## Glow (27% alpha composites)

| Token | Valor |
|-------|-------|
| glow-cyan | `#00f0ff44` |
| glow-magenta | `#ff2d9544` |
| glow-green | `#00ff8844` |
| glow-purple | `#8b5cf644` |

---

## Semantic Aliases

| Token | Mapeo |
|-------|-------|
| accent-primary | neon-cyan |
| accent-danger | neon-red |
| accent-success | neon-green |
| accent-warning | neon-amber |
| accent-info | neon-purple |
| text-link | neon-cyan |
| bg-danger-hover | `#2d1117` |

---

## Spacing (4px base grid)

| Token | Valor | Uso |
|-------|-------|-----|
| sp-1 | 4px | Tight gaps in toolbars |
| sp-2 | 8px | Between icon and label |
| sp-3 | 12px | Panel padding |
| sp-4 | 16px | Default section gap |
| sp-5 | 20px | Between sections |
| sp-6 | 24px | Between views |
| sp-8 | 32px | Major section breaks |
| sp-10 | 40px | Page margins |
| sp-12 | 48px | Top/bottom on dialogs |

---

## Radius

| Token | Valor | Uso |
|-------|-------|-----|
| radius-sm | 4px | Buttons, inputs |
| radius-md | 6px | Cards, sections |
| radius-lg | 8px | Modals, dialogs |
| radius-xl | 12px | Large panels |
| radius-full | 100px | Pills, tags |

---

## Typography

| Token | Valor | Uso |
|-------|-------|-----|
| font-xs | 11px | Labels, secondary data |
| font-sm | 12px | Captions, timestamps |
| font-base | 13px | Body text, button labels |
| font-lg | 15px | Section headers |
| font-xl | 18px | Panel titles |
| font-2xl | 22px | Dialog headers |
| font-3xl | 28px | Page titles |

---

## Font Families

| Token | Valor |
|-------|-------|
| font-sans | `-apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif` |
| font-mono | `'SF Mono', 'Cascadia Code', 'Fira Code', 'Consolas', monospace` |

---

## Elevation (simulated via border)

| Token | Valor | Uso |
|-------|-------|-----|
| elevation-flat | 0px | Sin profundidad |
| elevation-low | 1px | Cards, sections |
| elevation-md | 2px | Modals, dialogs |
| elevation-high | 3px | Tooltips, popups |

---

## Shadow Blurs

| Token | Valor |
|-------|-------|
| shadow-blur-sm | 4px |
| shadow-blur-md | 10px |
| shadow-blur-lg | 20px |
| shadow-offset-y | 2px |

---

## Z-Index Guidance

Slint no tiene `z-index`. La superposición se determina por orden en el árbol.

| Capa | Elementos |
|------|-----------|
| z-root (0) | bg-base, fondos de página |
| z-panels (1) | bg-elevated, sidebars, panels |
| z-cards (2) | bg-surface, cards, inputs |
| z-overlay (3) | bg-overlay, modal backdrop |
| z-modal (4) | modales, diálogos |
| z-popup (5) | tooltips, dropdowns, notificaciones |

---

## WCAG AA Contrast (Dark Theme)

| Pair | Ratio | Pass? |
|------|-------|-------|
| text-primary (#e2e8f0) on bg-base (#0a0e17) | ~14:1 | ✅ AAA |
| text-muted (#94a3b8) on bg-base (#0a0e17) | ~5.9:1 | ✅ AA |
| text-dim (#64748b) on bg-base (#0a0e17) | ~5.5:1 | ✅ AA |

---

## Animation Durations

```slint
// En theme.slint
duration-fastest:  50ms
duration-faster:  100ms
duration-fast:    150ms
duration-normal:  200ms
duration-slow:    300ms
duration-slower:  400ms
duration-slowest: 500ms

transition-fast:  150ms  // hover/press
transition-base:  200ms
transition-slow:  300ms
```

Uso: `animate opacity { duration: Theme.duration-normal; }`

## Animation Presets (AnimationPresets global)

| Preset         | Duración | Propósito                          |
|----------------|----------|------------------------------------|
| `fade-in`      | 200ms    | Modales, overlays                  |
| `slide-up`     | 300ms    | Drawer slide-in                    |
| `slide-down`   | 300ms    | Modal desde arriba                 |
| `scale-in`     | 250ms    | Tooltips, popovers, dropdown menus |
| `fade-out`     | 150ms    | Exit animations                    |
| `slide-out`    | 200ms    | Exit slide                         |
| `panel-slide`  | 150ms    | Sidebar collapse/expand            |
| `hover-glow`   | 150ms    | Background/border hover transitions|
| `tab-switch`   | 100ms    | Tab underline shift                |

Uso: `animate opacity { duration: AnimationPresets.fade-in; }`

### Nota sobre animaciones en Slint

Slint 1.9+ solo soporta `animate` lineal en propiedades `length` y `color`. No hay easing curves custom. La animación de fade-in (opacity) funciona en entrada pero NO en salida cuando el elemento se oculta vía `visible: false` — el exit es instantáneo. Esto es una limitación conocida de Slint.
