# Guía de Desarrollo - Sistema de Temas

## Introducción

Esta guía está dirigida a desarrolladores que trabajan en Analítica Núcleo y necesitan entender cómo funciona el sistema de temas y cómo mantener la consistencia visual en toda la aplicación.

## Principios Fundamentales

### 1. Siempre Usa Variables CSS

**✅ CORRECTO:**
```vue
<div class="bg-[var(--brand-surface)] border-[var(--brand-border)] text-[var(--brand-text)]">
  Contenido
</div>
```

**❌ INCORRECTO:**
```vue
<div class="bg-[#1f180f] border-[#3a2a16] text-[#fef9f0]">
  Contenido
</div>
```

**❌ INCORRECTO:**
```vue
<div class="bg-gray-900 border-gray-800 text-white">
  Contenido
</div>
```

### 2. Usa las Clases Utilitarias de Marca

Para elementos comunes, usa las clases predefinidas en lugar de duplicar estilos:

```vue
<!-- ✅ CORRECTO -->
<div class="brand-card">
  <h2 class="brand-section-title">Título</h2>
  <div class="brand-divider"></div>
</div>

<!-- ❌ INCORRECTO -->
<div class="rounded-lg bg-gradient-to-br from-[#1f180f] to-[#14100b] border border-[#3a2a16]">
  <h2 class="text-lg font-semibold text-[#e0c080]">Título</h2>
  <div class="h-px bg-[#3a2a16] my-4"></div>
</div>
```

## Variables de Tema Disponibles

| Variable CSS | Uso | Ejemplo |
|--------------|-----|---------|
| `--brand-bg` | Fondo principal de la aplicación | `bg-[var(--brand-bg)]` |
| `--brand-surface` | Fondos de elementos elevados (cards, modales) | `bg-[var(--brand-surface)]` |
| `--brand-border` | Bordes de elementos | `border-[var(--brand-border)]` |
| `--brand-primary` | Color principal (enlaces, botones) | `text-[var(--brand-primary)]` |
| `--brand-primary-strong` | Variante más intensa del primario | `bg-[var(--brand-primary-strong)]` |
| `--brand-accent` | Color de acento para highlights | `text-[var(--brand-accent)]` |
| `--brand-text` | Texto principal | `text-[var(--brand-text)]` |
| `--brand-text-muted` | Texto secundario/menos prominente | `text-[var(--brand-text-muted)]` |

## Clases Utilitarias de Marca

### `.brand-shell`
Contenedor principal para layouts con gradiente radial.

```vue
<div class="brand-shell">
  <!-- Contenido de la página -->
</div>
```

### `.brand-card`
Tarjetas con estilos consistentes.

```vue
<div class="brand-card">
  <h3>Título de la Card</h3>
  <p>Contenido</p>
</div>
```

### `.brand-divider`
Divisor horizontal decorativo.

```vue
<div class="brand-divider"></div>
```

### `.brand-chip` y `.brand-pill`
Para pequeños tags o badges.

```vue
<span class="brand-chip">Estado</span>
<span class="brand-pill">Badge</span>
```

### `.brand-table`
Estilos para tablas.

```vue
<table class="brand-table">
  <!-- ... -->
</table>
```

## Patrones de Uso Común

### Cards con Bordes y Sombras

```vue
<UCard class="brand-card border border-transparent">
  <template #header>
    <div class="flex items-center gap-2">
      <UIcon name="i-lucide-star" class="size-5 text-[var(--brand-accent)]" />
      <h3 class="text-[var(--brand-text)]">Título</h3>
    </div>
  </template>

  <p class="text-[var(--brand-text-muted)]">
    Descripción del contenido
  </p>
</UCard>
```

### Botones con Hover Personalizado

```vue
<button class="px-4 py-2 rounded-lg bg-[var(--brand-surface)] border border-[var(--brand-border)] text-[var(--brand-text)] hover:bg-[var(--brand-primary)]/10 hover:border-[var(--brand-primary)] transition-colors">
  Botón
</button>
```

### Inputs y Formularios

```vue
<UInput
  v-model="value"
  placeholder="Ingresa un valor"
  :ui="{
    base: 'bg-[var(--brand-surface)] border-[var(--brand-border)] text-[var(--brand-text)]',
    placeholder: 'placeholder:text-[var(--brand-text-muted)]'
  }"
/>
```

### Links con Hover

```vue
<NuxtLink
  to="/perfil"
  class="text-[var(--brand-accent)] hover:text-[var(--brand-primary)] hover:underline transition-colors"
>
  Ver perfil →
</NuxtLink>
```

### Personalización de Componentes Nuxt UI

Muchos componentes de Nuxt UI aceptan la prop `:ui` para personalización:

```vue
<UButton
  :ui="{
    base: 'bg-[var(--brand-surface)] hover:bg-[var(--brand-primary)]/10',
    padding: { sm: 'px-2.5 py-2' }
  }"
>
  Botón Personalizado
</UButton>
```

## Composable `useTheme()`

Para manipular el tema programáticamente, usa el composable `useTheme()`:

```vue
<script setup lang="ts">
const { theme, applyTheme, saveTheme, resetTheme, exportTheme, importTheme } = useTheme()

// Modificar un color
theme.value.primary = '#ff5733'

// Aplicar cambios
applyTheme()

// Guardar en localStorage
saveTheme()

// Resetear a valores por defecto
resetTheme()

// Exportar tema como JSON
const jsonTheme = exportTheme()

// Importar tema desde JSON
const success = importTheme(jsonString, true) // true = guardar automáticamente
</script>
```

## Checklist Pre-Commit

Antes de hacer commit de tu código, verifica:

- [ ] **No hay colores hardcoded** (`#ffffff`, `#000000`, etc.)
- [ ] **No hay clases gray-scale genéricas** (`bg-gray-900`, `text-gray-500`, etc.)
- [ ] **Todos los fondos usan** `--brand-bg` o `--brand-surface`
- [ ] **Todos los bordes usan** `--brand-border`
- [ ] **Todo el texto usa** `--brand-text` o `--brand-text-muted`
- [ ] **Los elementos interactivos usan** `--brand-primary` o `--brand-accent`
- [ ] **Los hover states usan transparencias** (ej: `hover:bg-[var(--brand-primary)]/10`)
- [ ] **Se usan clases utilitarias** cuando sea posible (`.brand-card`, `.brand-shell`, etc.)

## Casos Especiales

### Colores Semánticos (Success, Error, Warning)

Para colores que NO son parte del tema (éxito, error, advertencia), puedes usar colores de Tailwind:

```vue
<!-- Estados semánticos - OK usar colores fijos -->
<div class="text-green-400">Éxito</div>
<div class="text-red-400">Error</div>
<div class="text-yellow-400">Advertencia</div>
<div class="text-blue-400">Info</div>

<!-- Pero el fondo y borde deben respetar el tema -->
<div class="bg-[var(--brand-surface)] border-green-600/30 text-green-400">
  Operación exitosa
</div>
```

### Iconos

Los iconos deben usar colores del tema:

```vue
<!-- ✅ CORRECTO -->
<UIcon name="i-lucide-star" class="size-5 text-[var(--brand-primary)]" />
<UIcon name="i-lucide-info" class="size-4 text-[var(--brand-accent)]" />
<UIcon name="i-lucide-chevron-right" class="size-4 text-[var(--brand-text-muted)]" />

<!-- ❌ INCORRECTO -->
<UIcon name="i-lucide-star" class="size-5 text-amber-500" />
<UIcon name="i-lucide-info" class="size-4 text-blue-400" />
```

### Imágenes y Avatares con Bordes

```vue
<img
  src="/logo.png"
  class="rounded-full border-2 border-[var(--brand-accent)]/40 shadow-lg shadow-[var(--brand-primary-strong)]/25"
/>

<UAvatar
  src="https://example.com/avatar.jpg"
  :ui="{
    wrapper: 'ring-2 ring-[var(--brand-primary)]/40'
  }"
/>
```

### Hover y Focus States

Siempre usa transparencias para hover states para que funcionen con cualquier tema:

```vue
<!-- ✅ CORRECTO - Usa transparencia -->
<button class="hover:bg-[var(--brand-primary)]/10 focus:ring-2 focus:ring-[var(--brand-primary)]/50">
  Botón
</button>

<!-- ❌ INCORRECTO - Color sólido -->
<button class="hover:bg-[#e0c080] focus:ring-2 focus:ring-[#c08040]">
  Botón
</button>
```

## Ejemplos de Migración

### Antes (Incorrecto)

```vue
<template>
  <div class="bg-gray-900 border border-gray-800">
    <h2 class="text-white font-bold">Título</h2>
    <p class="text-gray-400 mt-2">
      Descripción
    </p>
    <button class="mt-4 px-4 py-2 bg-blue-600 hover:bg-blue-700 text-white rounded-lg">
      Acción
    </button>
  </div>
</template>
```

### Después (Correcto)

```vue
<template>
  <div class="bg-[var(--brand-surface)] border border-[var(--brand-border)]">
    <h2 class="text-[var(--brand-text)] font-bold">Título</h2>
    <p class="text-[var(--brand-text-muted)] mt-2">
      Descripción
    </p>
    <UButton
      class="mt-4"
      :ui="{
        base: 'bg-[var(--brand-primary)] hover:bg-[var(--brand-primary-strong)]'
      }"
    >
      Acción
    </UButton>
  </div>
</template>
```

## Errores Comunes y Soluciones

### Error 1: Mezclar Variables con Hardcoded Colors

**❌ No hagas esto:**
```vue
<div class="bg-[#1f180f] text-[var(--brand-text)]">
  Contenido
</div>
```

**✅ Haz esto:**
```vue
<div class="bg-[var(--brand-surface)] text-[var(--brand-text)]">
  Contenido
</div>
```

### Error 2: No Considerar el Contraste

Asegúrate de que el texto tenga suficiente contraste sobre su fondo:

**❌ Mal contraste:**
```vue
<div class="bg-[var(--brand-surface)]">
  <span class="text-[var(--brand-text-muted)]">Texto importante</span>
</div>
```

**✅ Buen contraste:**
```vue
<div class="bg-[var(--brand-surface)]">
  <span class="text-[var(--brand-text)]">Texto importante</span>
</div>
```

### Error 3: Duplicar Estilos en Lugar de Usar Clases

**❌ Duplicación:**
```vue
<div class="rounded-lg bg-gradient-to-br from-[var(--brand-surface)] to-[var(--brand-bg)] border border-[var(--brand-border)] p-6 shadow-xl">
  Card 1
</div>
<div class="rounded-lg bg-gradient-to-br from-[var(--brand-surface)] to-[var(--brand-bg)] border border-[var(--brand-border)] p-6 shadow-xl">
  Card 2
</div>
```

**✅ Reutilización:**
```vue
<div class="brand-card">Card 1</div>
<div class="brand-card">Card 2</div>
```

## Testing del Tema

Para probar que tu componente respeta el tema:

1. Ve a `/settings`
2. Cambia el tema a "Azul Corporativo" o "Verde Natural"
3. Navega a tu componente
4. Verifica que todos los colores cambien correctamente
5. Verifica que no haya elementos con colores hardcoded que no cambiaron

## Recursos Adicionales

- **Documentación del usuario:** `THEME_CUSTOMIZATION.md`
- **Composable de temas:** `app/composables/useTheme.ts`
- **Variables CSS:** `app/assets/css/main.css`
- **Configuración de Nuxt UI:** `app.config.ts`

## Preguntas Frecuentes

### ¿Puedo usar colores de Tailwind como `bg-blue-500`?

Solo para estados semánticos (éxito, error, advertencia) que NO forman parte del tema. Para todo lo demás, usa las variables de tema.

### ¿Cómo personalizo un componente de Nuxt UI?

Usa la prop `:ui` con las variables de tema:

```vue
<UCard :ui="{ base: 'bg-[var(--brand-surface)]' }">
  Contenido
</UCard>
```

### ¿Qué hago si necesito un color que no está en el tema?

Primero pregunta: ¿realmente necesito un color nuevo, o puedo usar uno existente? Si es absolutamente necesario, propón agregar una nueva variable al sistema de temas en lugar de hardcodear el color.

### ¿Cómo manejo dark mode?

No necesitas manejarlo manualmente. Las variables CSS ya están optimizadas para dark mode. Solo usa las variables y funcionará automáticamente.

---

**Última actualización:** 2025-10-30
**Mantenedor:** Claude Code para Núcleo Río Frío
**Versión:** 1.0.0
