Files
analiticaNucleo/nuxt4-app/app/pages/settings.vue
josedario87 cac84adc7d
All checks were successful
build-and-deploy / build-and-deploy (push) Successful in 49s
Feat: Extender sistema de temas con colores de café y estados
Cambios:
- Agregar documentación completa del sistema de temas en /settings
- Extender ThemeColors con 7 nuevas variables:
  * coffeeUva, coffeeOreado, coffeeMojado, coffeeVerde
  * statusPendiente, statusPagado, statusAnulado
- Actualizar useTheme.ts para aplicar nuevas variables CSS
- Actualizar main.css con definiciones de nuevas variables
- Actualizar temas predefinidos (azul, verde, carbón)
- Mantener colores de café y estados consistentes en todos los temas

Las nuevas variables permiten personalizar:
- Colores de identificación de tipos de café en gráficas
- Colores de estados de pago en tablas y badges
2025-10-30 17:31:50 -06:00

802 lines
33 KiB
Vue

<script setup lang="ts">
import { ref, watch } from 'vue'
import type { ThemeColors } from '~/composables/useTheme'
definePageMeta({
layout: 'dashboard',
title: 'Configuración'
})
// Usar el composable de temas
const {
theme,
defaultTheme,
applyTheme,
saveTheme: saveThemeComposable,
resetTheme: resetThemeComposable,
exportTheme,
importTheme
} = useTheme()
// Temas predefinidos
const presetThemes: Record<string, ThemeColors> = {
cafe: { ...defaultTheme },
azul: {
bg: '#0a0e1a',
surface: '#151a28',
border: '#2d3748',
primary: '#60a5fa',
primaryStrong: '#3b82f6',
accent: '#93c5fd',
text: '#f0f4f8',
textMuted: '#cbd5e1',
// Colores de café (mantener consistentes)
coffeeUva: '#a855f7',
coffeeOreado: '#f97316',
coffeeMojado: '#06b6d4',
coffeeVerde: '#22c55e',
// Colores de estados (mantener consistentes)
statusPendiente: '#f59e0b',
statusPagado: '#10b981',
statusAnulado: '#6b7280'
},
verde: {
bg: '#0f1a14',
surface: '#1a2820',
border: '#2d4033',
primary: '#86efac',
primaryStrong: '#4ade80',
accent: '#bbf7d0',
text: '#f0fdf4',
textMuted: '#d1fae5',
// Colores de café (mantener consistentes)
coffeeUva: '#a855f7',
coffeeOreado: '#f97316',
coffeeMojado: '#06b6d4',
coffeeVerde: '#22c55e',
// Colores de estados (mantener consistentes)
statusPendiente: '#f59e0b',
statusPagado: '#10b981',
statusAnulado: '#6b7280'
},
carbon: {
bg: '#0f0f0f',
surface: '#1a1a1a',
border: '#333333',
primary: '#a3a3a3',
primaryStrong: '#737373',
accent: '#d4d4d4',
text: '#fafafa',
textMuted: '#d4d4d4',
// Colores de café (mantener consistentes)
coffeeUva: '#a855f7',
coffeeOreado: '#f97316',
coffeeMojado: '#06b6d4',
coffeeVerde: '#22c55e',
// Colores de estados (mantener consistentes)
statusPendiente: '#f59e0b',
statusPagado: '#10b981',
statusAnulado: '#6b7280'
}
}
// Aplicar preset de tema
const applyPreset = (presetName: keyof typeof presetThemes) => {
const preset = presetThemes[presetName]
theme.value = { ...preset }
applyTheme(theme.value)
useToast().add({
title: 'Tema aplicado',
description: `Se aplicó el tema ${presetName}`,
color: 'blue'
})
}
// Guardar tema con feedback
const handleSaveTheme = () => {
const success = saveThemeComposable()
if (success) {
useToast().add({
title: 'Tema guardado',
description: 'Los cambios se aplicaron correctamente',
color: 'green'
})
} else {
useToast().add({
title: 'Error al guardar',
description: 'No se pudo guardar el tema',
color: 'red'
})
}
}
// Resetear al tema por defecto
const handleResetTheme = () => {
resetThemeComposable()
useToast().add({
title: 'Tema reseteado',
description: 'Se restauraron los colores por defecto',
color: 'blue'
})
}
// Exportar tema al portapapeles
const handleExportTheme = async () => {
try {
const themeJson = exportTheme()
await navigator.clipboard.writeText(themeJson)
useToast().add({
title: 'Tema exportado',
description: 'El JSON del tema se copió al portapapeles',
color: 'green'
})
} catch (error) {
useToast().add({
title: 'Error al exportar',
description: 'No se pudo copiar al portapapeles',
color: 'red'
})
}
}
// Importar tema desde JSON
const importJsonInput = ref('')
const showImportModal = ref(false)
const handleImportTheme = () => {
const success = importTheme(importJsonInput.value, false)
if (success) {
useToast().add({
title: 'Tema importado',
description: 'El tema se aplicó correctamente',
color: 'green'
})
showImportModal.value = false
importJsonInput.value = ''
} else {
useToast().add({
title: 'Error al importar',
description: 'El JSON proporcionado no es válido',
color: 'red'
})
}
}
// Vista previa en tiempo real (activada por defecto)
const livePreview = ref(true)
watch(() => theme.value, (newTheme) => {
if (livePreview.value) {
applyTheme(newTheme)
}
}, { deep: true })
</script>
<template>
<UDashboardLayout>
<UDashboardPanel grow>
<UDashboardNavbar
title="Configuración"
description="Personaliza tu experiencia y preferencias del sistema"
/>
<UDashboardPanelContent>
<div class="max-w-4xl mx-auto space-y-8">
<!-- Configuración de Tema -->
<UCard
:ui="{
base: 'bg-[var(--brand-surface)]',
ring: 'ring-1 ring-[var(--brand-border)]',
body: { base: '', padding: 'px-4 py-5 sm:p-6' },
header: { base: 'border-b border-[var(--brand-border)]', padding: 'px-4 py-5 sm:px-6' }
}"
>
<template #header>
<div class="flex items-center justify-between">
<div class="flex items-center gap-3">
<div class="w-10 h-10 rounded-lg bg-[var(--brand-primary)]/20 flex items-center justify-center">
<UIcon name="i-lucide-palette" class="size-5 text-[var(--brand-primary)]" />
</div>
<div>
<h3 class="font-semibold text-[var(--brand-text)]">
Tema y Apariencia
</h3>
<p class="text-sm text-[var(--brand-text-muted)]">
Personaliza los colores de la interfaz
</p>
</div>
</div>
<UToggle v-model="livePreview" label="Vista previa en vivo" />
</div>
</template>
<!-- Temas Predefinidos -->
<div class="mb-6 pb-6 border-b border-[var(--brand-border)]">
<label class="block text-sm font-medium text-[var(--brand-text)] mb-3">
Temas Predefinidos
</label>
<div class="grid grid-cols-2 md:grid-cols-4 gap-3">
<button
@click="applyPreset('cafe')"
class="p-4 rounded-lg border-2 border-[var(--brand-border)] hover:border-[var(--brand-primary)] transition-colors group"
>
<div class="flex gap-2 mb-2">
<div class="w-6 h-6 rounded" style="background: #e0c080" />
<div class="w-6 h-6 rounded" style="background: #1f180f" />
</div>
<p class="text-xs text-[var(--brand-text)] font-medium group-hover:text-[var(--brand-primary)]">Café</p>
</button>
<button
@click="applyPreset('azul')"
class="p-4 rounded-lg border-2 border-[var(--brand-border)] hover:border-[var(--brand-primary)] transition-colors group"
>
<div class="flex gap-2 mb-2">
<div class="w-6 h-6 rounded" style="background: #60a5fa" />
<div class="w-6 h-6 rounded" style="background: #151a28" />
</div>
<p class="text-xs text-[var(--brand-text)] font-medium group-hover:text-[var(--brand-primary)]">Azul</p>
</button>
<button
@click="applyPreset('verde')"
class="p-4 rounded-lg border-2 border-[var(--brand-border)] hover:border-[var(--brand-primary)] transition-colors group"
>
<div class="flex gap-2 mb-2">
<div class="w-6 h-6 rounded" style="background: #86efac" />
<div class="w-6 h-6 rounded" style="background: #1a2820" />
</div>
<p class="text-xs text-[var(--brand-text)] font-medium group-hover:text-[var(--brand-primary)]">Verde</p>
</button>
<button
@click="applyPreset('carbon')"
class="p-4 rounded-lg border-2 border-[var(--brand-border)] hover:border-[var(--brand-primary)] transition-colors group"
>
<div class="flex gap-2 mb-2">
<div class="w-6 h-6 rounded" style="background: #a3a3a3" />
<div class="w-6 h-6 rounded" style="background: #1a1a1a" />
</div>
<p class="text-xs text-[var(--brand-text)] font-medium group-hover:text-[var(--brand-primary)]">Carbón</p>
</button>
</div>
</div>
<div class="space-y-6">
<!-- Fondo Principal -->
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<div>
<label class="block text-sm font-medium text-[var(--brand-text)] mb-2">
Fondo Principal
</label>
<div class="flex gap-2">
<input
v-model="theme.bg"
type="color"
class="h-10 w-20 rounded-lg border border-[var(--brand-border)] cursor-pointer"
/>
<UInput
v-model="theme.bg"
placeholder="#14100b"
class="flex-1"
/>
</div>
</div>
<div>
<label class="block text-sm font-medium text-[var(--brand-text)] mb-2">
Fondo Secundario (Surface)
</label>
<div class="flex gap-2">
<input
v-model="theme.surface"
type="color"
class="h-10 w-20 rounded-lg border border-[var(--brand-border)] cursor-pointer"
/>
<UInput
v-model="theme.surface"
placeholder="#1f180f"
class="flex-1"
/>
</div>
</div>
</div>
<!-- Bordes y Primario -->
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<div>
<label class="block text-sm font-medium text-[var(--brand-text)] mb-2">
Color de Bordes
</label>
<div class="flex gap-2">
<input
v-model="theme.border"
type="color"
class="h-10 w-20 rounded-lg border border-[var(--brand-border)] cursor-pointer"
/>
<UInput
v-model="theme.border"
placeholder="#3a2a16"
class="flex-1"
/>
</div>
</div>
<div>
<label class="block text-sm font-medium text-[var(--brand-text)] mb-2">
Color Primario
</label>
<div class="flex gap-2">
<input
v-model="theme.primary"
type="color"
class="h-10 w-20 rounded-lg border border-[var(--brand-border)] cursor-pointer"
/>
<UInput
v-model="theme.primary"
placeholder="#e0c080"
class="flex-1"
/>
</div>
</div>
</div>
<!-- Primario Fuerte y Acento -->
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<div>
<label class="block text-sm font-medium text-[var(--brand-text)] mb-2">
Color Primario Fuerte
</label>
<div class="flex gap-2">
<input
v-model="theme.primaryStrong"
type="color"
class="h-10 w-20 rounded-lg border border-[var(--brand-border)] cursor-pointer"
/>
<UInput
v-model="theme.primaryStrong"
placeholder="#c08040"
class="flex-1"
/>
</div>
</div>
<div>
<label class="block text-sm font-medium text-[var(--brand-text)] mb-2">
Color de Acento
</label>
<div class="flex gap-2">
<input
v-model="theme.accent"
type="color"
class="h-10 w-20 rounded-lg border border-[var(--brand-border)] cursor-pointer"
/>
<UInput
v-model="theme.accent"
placeholder="#ffe0a0"
class="flex-1"
/>
</div>
</div>
</div>
<!-- Texto y Texto Muted -->
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<div>
<label class="block text-sm font-medium text-[var(--brand-text)] mb-2">
Color de Texto
</label>
<div class="flex gap-2">
<input
v-model="theme.text"
type="color"
class="h-10 w-20 rounded-lg border border-[var(--brand-border)] cursor-pointer"
/>
<UInput
v-model="theme.text"
placeholder="#fef9f0"
class="flex-1"
/>
</div>
</div>
<div>
<label class="block text-sm font-medium text-[var(--brand-text)] mb-2">
Color de Texto Secundario
</label>
<div class="flex gap-2">
<input
v-model="theme.textMuted"
type="color"
class="h-10 w-20 rounded-lg border border-[var(--brand-border)] cursor-pointer"
/>
<UInput
v-model="theme.textMuted"
placeholder="#d8c7a6"
class="flex-1"
/>
</div>
</div>
</div>
<!-- Acciones -->
<div class="space-y-3 pt-4 border-t border-[var(--brand-border)]">
<!-- Botones principales -->
<div class="flex justify-between items-center">
<UButton
color="neutral"
variant="ghost"
icon="i-lucide-rotate-ccw"
@click="handleResetTheme"
>
Restaurar por defecto
</UButton>
<UButton
color="primary"
icon="i-lucide-save"
@click="handleSaveTheme"
>
Guardar cambios
</UButton>
</div>
<!-- Botones de import/export -->
<div class="flex gap-2">
<UButton
color="neutral"
variant="outline"
icon="i-lucide-download"
@click="handleExportTheme"
class="flex-1"
>
Exportar tema
</UButton>
<UButton
color="neutral"
variant="outline"
icon="i-lucide-upload"
@click="showImportModal = true"
class="flex-1"
>
Importar tema
</UButton>
</div>
</div>
</div>
</UCard>
<!-- Modal de Importar Tema -->
<UModal v-model="showImportModal" title="Importar Tema">
<div class="p-4 space-y-4">
<div>
<label class="block text-sm font-medium text-[var(--brand-text)] mb-2">
Pega el JSON del tema
</label>
<UTextarea
v-model="importJsonInput"
:rows="10"
placeholder='{\n "bg": "#14100b",\n "surface": "#1f180f",\n ...\n}'
class="font-mono text-xs"
/>
</div>
<div class="flex justify-end gap-2">
<UButton
color="neutral"
variant="ghost"
@click="showImportModal = false"
>
Cancelar
</UButton>
<UButton
color="primary"
@click="handleImportTheme"
>
Importar
</UButton>
</div>
</div>
</UModal>
<!-- Vista previa de colores -->
<UCard
:ui="{
base: 'bg-[var(--brand-surface)]',
ring: 'ring-1 ring-[var(--brand-border)]',
body: { base: '', padding: 'px-4 py-5 sm:p-6' },
header: { base: 'border-b border-[var(--brand-border)]', padding: 'px-4 py-5 sm:px-6' }
}"
>
<template #header>
<div class="flex items-center gap-3">
<UIcon name="i-lucide-eye" class="size-5 text-[var(--brand-primary)]" />
<h3 class="font-semibold text-[var(--brand-text)]">
Vista Previa
</h3>
</div>
</template>
<div class="grid grid-cols-2 md:grid-cols-4 gap-4">
<div class="space-y-2">
<div class="h-20 rounded-lg border-2 border-[var(--brand-border)]" :style="{ backgroundColor: theme.bg }" />
<p class="text-xs text-center text-[var(--brand-text-muted)]">Fondo Principal</p>
</div>
<div class="space-y-2">
<div class="h-20 rounded-lg border-2 border-[var(--brand-border)]" :style="{ backgroundColor: theme.surface }" />
<p class="text-xs text-center text-[var(--brand-text-muted)]">Surface</p>
</div>
<div class="space-y-2">
<div class="h-20 rounded-lg border-2 border-[var(--brand-border)]" :style="{ backgroundColor: theme.primary }" />
<p class="text-xs text-center text-[var(--brand-text-muted)]">Primario</p>
</div>
<div class="space-y-2">
<div class="h-20 rounded-lg border-2 border-[var(--brand-border)]" :style="{ backgroundColor: theme.accent }" />
<p class="text-xs text-center text-[var(--brand-text-muted)]">Acento</p>
</div>
</div>
</UCard>
<!-- Documentación del Sistema de Temas -->
<UCard
:ui="{
base: 'bg-[var(--brand-surface)]',
ring: 'ring-1 ring-[var(--brand-border)]',
body: { base: '', padding: 'px-4 py-5 sm:p-6' },
header: { base: 'border-b border-[var(--brand-border)]', padding: 'px-4 py-5 sm:px-6' }
}"
>
<template #header>
<div class="flex items-center gap-3">
<div class="w-10 h-10 rounded-lg bg-[var(--brand-accent)]/20 flex items-center justify-center">
<UIcon name="i-lucide-book-open" class="size-5 text-[var(--brand-accent)]" />
</div>
<div>
<h3 class="font-semibold text-[var(--brand-text)]">
Cómo funciona el Sistema de Temas
</h3>
<p class="text-xs text-[var(--brand-text-muted)]">
Guía completa de personalización
</p>
</div>
</div>
</template>
<div class="space-y-6">
<!-- Introducción -->
<div>
<h4 class="text-sm font-semibold text-[var(--brand-primary)] mb-2">
¿Qué es el Sistema de Temas?
</h4>
<p class="text-sm text-[var(--brand-text-muted)] leading-relaxed">
El sistema de temas te permite personalizar completamente la apariencia de Analítica Núcleo.
Cada color que cambies se aplicará <strong class="text-[var(--brand-text)]">instantáneamente</strong> en
toda la aplicación: menús, tablas, gráficas, botones y más.
</p>
</div>
<div class="brand-divider"></div>
<!-- Variables de Color -->
<div>
<h4 class="text-sm font-semibold text-[var(--brand-primary)] mb-3">
Variables de Color
</h4>
<div class="space-y-3">
<!-- Fondo Principal -->
<div class="flex items-start gap-3">
<div class="w-6 h-6 rounded border-2 border-[var(--brand-border)] mt-0.5" :style="{ backgroundColor: theme.bg }"></div>
<div class="flex-1">
<p class="text-sm font-medium text-[var(--brand-text)]">Fondo Principal</p>
<p class="text-xs text-[var(--brand-text-muted)]">Color de fondo base de toda la aplicación</p>
</div>
</div>
<!-- Surface -->
<div class="flex items-start gap-3">
<div class="w-6 h-6 rounded border-2 border-[var(--brand-border)] mt-0.5" :style="{ backgroundColor: theme.surface }"></div>
<div class="flex-1">
<p class="text-sm font-medium text-[var(--brand-text)]">Fondo Secundario (Surface)</p>
<p class="text-xs text-[var(--brand-text-muted)]">Usado en cards, modales y elementos elevados</p>
</div>
</div>
<!-- Border -->
<div class="flex items-start gap-3">
<div class="w-6 h-6 rounded border-2 border-[var(--brand-border)] mt-0.5" :style="{ backgroundColor: theme.border }"></div>
<div class="flex-1">
<p class="text-sm font-medium text-[var(--brand-text)]">Color de Bordes</p>
<p class="text-xs text-[var(--brand-text-muted)]">Bordes de todos los elementos y separadores</p>
</div>
</div>
<!-- Primary -->
<div class="flex items-start gap-3">
<div class="w-6 h-6 rounded border-2 border-[var(--brand-border)] mt-0.5" :style="{ backgroundColor: theme.primary }"></div>
<div class="flex-1">
<p class="text-sm font-medium text-[var(--brand-text)]">Color Primario</p>
<p class="text-xs text-[var(--brand-text-muted)]">Enlaces, títulos destacados y elementos interactivos</p>
</div>
</div>
<!-- Primary Strong -->
<div class="flex items-start gap-3">
<div class="w-6 h-6 rounded border-2 border-[var(--brand-border)] mt-0.5" :style="{ backgroundColor: theme.primaryStrong }"></div>
<div class="flex-1">
<p class="text-sm font-medium text-[var(--brand-text)]">Color Primario Fuerte</p>
<p class="text-xs text-[var(--brand-text-muted)]">Variante más intensa para hover y énfasis</p>
</div>
</div>
<!-- Accent -->
<div class="flex items-start gap-3">
<div class="w-6 h-6 rounded border-2 border-[var(--brand-border)] mt-0.5" :style="{ backgroundColor: theme.accent }"></div>
<div class="flex-1">
<p class="text-sm font-medium text-[var(--brand-text)]">Color de Acento</p>
<p class="text-xs text-[var(--brand-text-muted)]">Highlights, badges y elementos de énfasis</p>
</div>
</div>
<!-- Text -->
<div class="flex items-start gap-3">
<div class="w-6 h-6 rounded border-2 border-[var(--brand-border)] mt-0.5" :style="{ backgroundColor: theme.text }"></div>
<div class="flex-1">
<p class="text-sm font-medium text-[var(--brand-text)]">Color de Texto</p>
<p class="text-xs text-[var(--brand-text-muted)]">Texto principal con alta legibilidad</p>
</div>
</div>
<!-- Text Muted -->
<div class="flex items-start gap-3">
<div class="w-6 h-6 rounded border-2 border-[var(--brand-border)] mt-0.5" :style="{ backgroundColor: theme.textMuted }"></div>
<div class="flex-1">
<p class="text-sm font-medium text-[var(--brand-text)]">Color de Texto Secundario</p>
<p class="text-xs text-[var(--brand-text-muted)]">Descripciones, subtítulos y texto menos prominente</p>
</div>
</div>
</div>
</div>
<div class="brand-divider"></div>
<!-- Cómo usar -->
<div>
<h4 class="text-sm font-semibold text-[var(--brand-primary)] mb-3">
Cómo Personalizar
</h4>
<div class="space-y-2">
<div class="flex items-start gap-2">
<UIcon name="i-lucide-check" class="size-4 text-[var(--brand-accent)] mt-0.5" />
<p class="text-sm text-[var(--brand-text-muted)]">
<strong class="text-[var(--brand-text)]">Temas Predefinidos:</strong> Haz clic en uno de los botones (Café, Azul, Verde, Carbón) para aplicar un tema completo
</p>
</div>
<div class="flex items-start gap-2">
<UIcon name="i-lucide-check" class="size-4 text-[var(--brand-accent)] mt-0.5" />
<p class="text-sm text-[var(--brand-text-muted)]">
<strong class="text-[var(--brand-text)]">Personalización Individual:</strong> Usa los selectores de color para ajustar cada variable a tu gusto
</p>
</div>
<div class="flex items-start gap-2">
<UIcon name="i-lucide-check" class="size-4 text-[var(--brand-accent)] mt-0.5" />
<p class="text-sm text-[var(--brand-text-muted)]">
<strong class="text-[var(--brand-text)]">Vista Previa en Vivo:</strong> Los cambios se aplican instantáneamente para que veas el resultado
</p>
</div>
<div class="flex items-start gap-2">
<UIcon name="i-lucide-check" class="size-4 text-[var(--brand-accent)] mt-0.5" />
<p class="text-sm text-[var(--brand-text-muted)]">
<strong class="text-[var(--brand-text)]">Guardar Cambios:</strong> No olvides hacer clic en "Guardar cambios" para que tu tema persista
</p>
</div>
</div>
</div>
<div class="brand-divider"></div>
<!-- Tips -->
<div>
<h4 class="text-sm font-semibold text-[var(--brand-primary)] mb-3">
Consejos y Mejores Prácticas
</h4>
<div class="space-y-2">
<div class="flex items-start gap-2">
<UIcon name="i-lucide-lightbulb" class="size-4 text-[var(--brand-accent)] mt-0.5" />
<p class="text-sm text-[var(--brand-text-muted)]">
<strong class="text-[var(--brand-text)]">Contraste:</strong> Asegúrate de que el texto tenga buen contraste con el fondo para facilitar la lectura
</p>
</div>
<div class="flex items-start gap-2">
<UIcon name="i-lucide-lightbulb" class="size-4 text-[var(--brand-accent)] mt-0.5" />
<p class="text-sm text-[var(--brand-text-muted)]">
<strong class="text-[var(--brand-text)]">Armonía:</strong> El "Color Primario Fuerte" debería ser una versión más intensa del "Color Primario"
</p>
</div>
<div class="flex items-start gap-2">
<UIcon name="i-lucide-lightbulb" class="size-4 text-[var(--brand-accent)] mt-0.5" />
<p class="text-sm text-[var(--brand-text-muted)]">
<strong class="text-[var(--brand-text)]">Exportar:</strong> Usa "Exportar tema" para hacer backup de tu configuración o compartirla
</p>
</div>
<div class="flex items-start gap-2">
<UIcon name="i-lucide-lightbulb" class="size-4 text-[var(--brand-accent)] mt-0.5" />
<p class="text-sm text-[var(--brand-text-muted)]">
<strong class="text-[var(--brand-text)]">Resetear:</strong> Si no te gusta el resultado, usa "Restaurar por defecto" para volver al tema Café original
</p>
</div>
</div>
</div>
<div class="brand-divider"></div>
<!-- Alcance -->
<div class="bg-[var(--brand-primary)]/5 border border-[var(--brand-primary)]/20 rounded-lg p-4">
<div class="flex items-start gap-3">
<UIcon name="i-lucide-info" class="size-5 text-[var(--brand-primary)] mt-0.5" />
<div>
<p class="text-sm font-medium text-[var(--brand-text)] mb-1">
Alcance del Sistema de Temas
</p>
<p class="text-xs text-[var(--brand-text-muted)] leading-relaxed">
El tema se aplica a <strong class="text-[var(--brand-text)]">toda la aplicación</strong>: sidebar,
menús, tablas, cards, gráficas, botones, inputs y más. Los únicos colores que NO cambian son
los semánticos (estados de éxito/error/advertencia) y los identificadores de tipos de café
(Uva/Oreado/Mojado/Verde) que mantienen sus colores específicos para mejor identificación.
</p>
</div>
</div>
</div>
</div>
</UCard>
<!-- Otras configuraciones (placeholder) -->
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<UCard
:ui="{
base: 'bg-[var(--brand-surface)]',
ring: 'ring-1 ring-[var(--brand-border)]',
body: { base: '', padding: 'px-4 py-5 sm:p-6' },
header: { base: 'border-b border-[var(--brand-border)]', padding: 'px-4 py-5 sm:px-6' }
}"
>
<template #header>
<div class="flex items-center gap-3">
<div class="w-10 h-10 rounded-lg bg-[var(--brand-primary)]/20 flex items-center justify-center">
<UIcon name="i-lucide-bell" class="size-5 text-[var(--brand-accent)]" />
</div>
<h3 class="font-semibold text-[var(--brand-text)]">
Notificaciones
</h3>
</div>
</template>
<p class="text-sm text-[var(--brand-text-muted)]">
Gestión de alertas y comunicaciones (Próximamente)
</p>
</UCard>
<UCard
:ui="{
base: 'bg-[var(--brand-surface)]',
ring: 'ring-1 ring-[var(--brand-border)]',
body: { base: '', padding: 'px-4 py-5 sm:p-6' },
header: { base: 'border-b border-[var(--brand-border)]', padding: 'px-4 py-5 sm:px-6' }
}"
>
<template #header>
<div class="flex items-center gap-3">
<div class="w-10 h-10 rounded-lg bg-[var(--brand-primary)]/20 flex items-center justify-center">
<UIcon name="i-lucide-shield" class="size-5 text-[var(--brand-accent)]" />
</div>
<h3 class="font-semibold text-[var(--brand-text)]">
Privacidad
</h3>
</div>
</template>
<p class="text-sm text-[var(--brand-text-muted)]">
Control de datos y seguridad (Próximamente)
</p>
</UCard>
</div>
</div>
</UDashboardPanelContent>
</UDashboardPanel>
</UDashboardLayout>
</template>