CAMBIOS EN ResumenMuestra.vue:
1. Header de acordeón ahora muestra DOS puntajes:
- Sumatoria Afectiva (Σ): suma de valores afectivos (1-9)
- SCAA Score: score calculado con fórmula completa
2. Layout:
- Ambos badges alineados a la derecha
- Centrados verticalmente en el header
- Sumatoria con color neutro (primary)
- SCAA con colores según valor (excelente/muy-bueno/bueno/regular/bajo)
3. Badges compactos:
- Label abreviado: "Σ" para Sumatoria, "SCAA" para SCAA Score
- Valores con 2 decimales para SCAA
- Responsive: se ajustan en mobile
4. Colores según SCAA Score:
- ≥90: Verde (excelente)
- ≥85: Azul (muy bueno)
- ≥80: Naranja (bueno)
- ≥70: Rojo (regular)
- <70: Gris (bajo)
- Reemplazar texto "Target:" por icono de diana (i-lucide-target)
- Mostrar icono con color primario + puntaje deseado
- Más visual e intuitivo
- Igualar opacidad de badges descriptivo y afectivo
- Cambiar todos los badges descriptivos de opacity: 0.4 a 0.7
- Ahora ambos badges tienen la misma tonalidad/visibilidad
- Aplica en todas las categorías (Fragancia, Aroma, Sabor, etc.)
- Hacer badges de filtro rectangulares
- Cambiar border-radius de subcategoria-chip de 9999px a 0.375rem
- Consistencia visual con el resto de badges y botones rectangulares
- Aplica a filtros de subcategorías debajo de tabs
- Cambiar color del backdrop/overlay del modal
- Usar color de fondo del usuario (var(--cata-bg))
- Aplicar opacidad de 0.85
- Mantener blur de 4px para efecto de profundidad
- Agregar puntaje target en footer del paso 2
- Mostrar "Target: [puntaje]" alineado a la izquierda
- Botones (Cancelar/Aplicar) alineados a la derecha
- Usar justify-between para distribución espaciada
- Mejorar experiencia visual con colores personalizados del usuario
- Eliminar componente BotonNubeCaustica.vue (ya no necesario)
- Reemplazar botón especial por botón estándar con clase cata-button
- Arreglar estilos del modal para respetar colores personalizados del usuario
- Aplicar clases cata-bg a content, header, body y footer
- Aplicar clase cata-text al título mediante slot personalizado
- Aplicar clase cata-outline-box al content para bordes consistentes
- Agregar backdrop-blur-sm al overlay
- Mantener consistencia visual con el resto de la aplicación
- Agregar watcher que resetea el estado cuando el modal se abre
- Asegurar que puntajeDeseado siempre inicie en 40
- Eliminar setTimeout del método cerrar() (ya no necesario)
- Soluciona problema donde el botón Continuar no funcionaba con valor 40
- Eliminar descripción del modal
- Simplificar paso 1: solo input sin textos explicativos
- Simplificar paso 2: subtítulo compacto con [icono] + "Sobresale"/"Palidece" + x/t
- Eliminar texto de contador duplicado
- Eliminar sección de resumen de distribución
- Interfaz más limpia y directa
- Categorías que sobresalen: flecha arriba (i-heroicons-arrow-up-circle-solid)
- Categorías que palidecen: flecha abajo (i-heroicons-arrow-down-circle-solid)
- Mantener color del icono según el color de cada categoría
- Actualizar ModalAsignacionRapida a sintaxis correcta de Nuxt UI v4
- Usar v-model:open en lugar de v-model
- Usar slots #body y #footer directamente
- Eliminar UCard (deprecado)
- Aplicar clases cata-* para mantener consistencia con el resto de la app
- Usar cata-text para textos
- Usar cata-button para botones
- Usar cata-input para inputs
- Usar cata-outline-box para bordes
- Respetar colores personalizados del usuario mediante variables CSS
- selected-category usa var(--cata-primary)
- Soporte para modo oscuro con efectos de sombra
- Eliminar icono de estrella/rayo del BotonNubeCaustica
- Simplificar diseño dejando solo la nube con patrones cáusticos
- Eliminar animación sparkle asociada
- Integrar modal correctamente en FormularioMuestra
- Mover botón dentro del slot por defecto del modal
- Eliminar modal duplicado del template
- Crear ModalAsignacionRapida.vue con lógica de distribución por múltiplos de 8
- Input numérico (8-80) para puntaje total deseado
- Cálculo automático del múltiplo de 8 más cercano
- Si múltiplo < valor: permite seleccionar categorías que sobresalen (+1)
- Si múltiplo > valor: permite seleccionar categorías que palidecen (-1)
- Si múltiplo = valor: asignación directa sin ajustes
- Crear BotonNubeCaustica.vue con diseño especial
- Forma de nube usando SVG path
- Animación de patrones de luz cáustica con gradientes animados
- Efectos de brillo y ondas al hacer hover
- Icono de rayo mágico con animación sparkle
- Integrar funcionalidad en FormularioMuestra.vue
- Ubicar botón en esquina superior izquierda de sección Descriptiva/Afectiva
- Aplicar puntajes calculados a todas las categorías descriptivas
- Actualizar puntaje final automáticamente
- Corregir comentario: "Suma de valores descriptivos" (era "afectivos")
- Evitar deselección al presionar el mismo corazón/círculo ya seleccionado
- Cambiar iconos de corazón de Lucide a Heroicons para mejor distinción visual
- No seleccionado: i-heroicons-heart (outline)
- Seleccionado: i-heroicons-heart-solid (relleno)
- Eliminar clase CSS icono-filled innecesaria
- Incluir selector de Sensación en la Boca en la sección Organoléptica de Impresión Global
- Incluir selector de Gustos Predominantes en la sección Organoléptica de Impresión Global
- Mantener la misma funcionalidad y estilos que en la tab Organoléptica
- Reducir tamaño de iconos de 1.5rem a 1rem en SelectorIntensidad
- Reducir espaciado entre iconos y padding del contenedor
- Cambiar gap de grids de sliders de 4 a 2
- Implementar filtrado restrictivo por tipo (descriptiva/afectiva) y categoría
- Agregar computed properties individuales para cada slider
- Cuando se selecciona "Afectiva" + "Sensación en la Boca", solo se muestra ese slider específico
- Eliminar grid en desktop para categorías principales de SelectorFamilia
- Usar flex-wrap en todos los tamaños de pantalla (igual que subcategorías)
- Mantener solo incremento de min-height en desktop (40px vs 32px)
- Resultado: categorías ahora fluyen en una sola fila con wrap cuando es necesario
CAMBIOS EN SENSACIONES EN BOCA:
- Reducir opciones a solo 5: Áspero, Aceitoso, Metálico, Deja seca la boca, Suave
- Cambiar de selección múltiple a selección única
- Actualizar tipo de sensacionEnBoca: SensacionBoca[] → SensacionBoca | null
CAMBIOS EN CHECKBOXES (sensaciones y gustos):
- Hacer checkboxes tan compactos como subcategorías de SelectorFamilia
- Usar flex-wrap en todos los breakpoints (eliminar grid en desktop)
- Dimensiones ultra compactas:
* Desktop: min-height 32px, padding 0.375rem 0.5rem, font-size 0.75rem
* Mobile: min-height 28px, padding 0.25rem 0.375rem, font-size 0.6875rem
* Touch: min-height 36px para dispositivos táctiles
ARCHIVOS MODIFICADOS:
- app/types/catacion.ts: Actualizar SensacionBoca y SENSACIONES_BOCA
- app/composables/useCatacion.ts: Cambiar actualizarSensacionBoca a selección única
- app/components/cata/FormularioMuestra.vue: UI compacta y selección única
- app/components/cata/ResumenMuestra.vue: Adaptar a sensacionEnBoca única
- Cambiar layout de grid fijo a flex-wrap en mobile para sensaciones y gustos
- Mantener grid responsive en desktop (3 columnas para sensaciones, 5 para gustos)
- Reducir significativamente todas las dimensiones para mayor compactación:
* Desktop: min-height 36px, padding 0.375rem 0.5rem
* Mobile: min-height 28px, padding 0.25rem 0.375rem
* Font-size: 0.75rem desktop, 0.6875rem mobile
- Agregar animaciones y estados focus consistentes
- Touch-friendly en dispositivos táctiles (36px min-height)
- Alinear puntaje final a la derecha en ResumenMuestra (ml-auto)
- Cambiar estilo de accordion: underline simple sin gap entre items
- Ajustar ancho 100% en móviles sin padding lateral (px-0 sm:px-4)
- Eliminar headers redundantes en tabs específicas:
* Organoléptica: eliminar 'Características Organolépticas'
* Descriptiva/Afectiva: eliminar 'Intensidades Descriptivas y Afectivas'
* Defectos: eliminar 'Defectos y Uniformidad'
- Mantener headers en tab Impresión Global para mejor navegación
- Agregar función getCategoryIcon() en FormularioMuestra y ResumenMuestra
- Iconos Lucide para cada categoría:
* fragancia: flower-2, aroma: wind, sabor: candy
* saborResidual: timer, acidez: citrus, dulzor: cookie
* sensacionBoca: droplets, impresionGlobal: star
- Actualizar todos los títulos de sección con iconos
- Modificar chips de ResumenMuestra para mostrar solo icono + valor descriptivo
- Eliminar valores afectivos y emojis de chips
- Agregar estilos CSS para .chip-icon
- Agregar prop tabActiva a ResumenMuestra.vue
- Implementar computed properties para filtrado:
* mostrarChipsOrganolepticos (organoleptica + impresion-global)
* mostrarChipsIntensidades (descriptiva-afectiva + impresion-global)
* mostrarChipsDefectos (defectos + impresion-global)
- Envolver grupos de chips con template v-if según filtrado
- Pasar prop :tab-activa desde sesion.vue a ResumenMuestra
- En impresion-global se muestran TODOS los chips
- En otras tabs solo chips pertinentes a esa categoría
- Reducir font-size de chips de 0.75rem a 0.625rem (0.5625rem en mobile)
- Reducir padding de chips de 0.25/0.5rem a 0.15/0.35rem
- Reducir gaps: entre chips de 1rem a 0.5rem, en línea de 2rem a 1.5rem
- Reducir tamaño de puntaje final y nombre de muestra
- Abreviar todas las etiquetas de chips:
* F/A (Fragancia/Aroma), Sab (Sabor), Gus (Gustos), Sen (Sensación)
* Fra, Aro, Sb, S.R (Sabor Residual), Aci, Dul, Sn, Imp
* NoUnif (No Uniformes), Defec (Defectuosas)
- Eliminar espacios en arrays join (coma sin espacio)
- Optimizar responsive para mobile aún más compacto
- Cambiar 'cuerpo' por 'sensacionBoca' (propiedad correcta del tipo)
- Cambiar 'balance' por 'impresionGlobal' (propiedad correcta del tipo)
- Las propiedades ahora coinciden con la interfaz Intensidades definida en catacion.ts
- Agregar puntaje final con badge color-coded según rangos
- Agregar chips para categorías organolépticas (fragancia/aroma, sabor, gustos, sensación)
- Agregar chips para todos los valores de intensidad (afectiva ❤️ y descriptiva 📊)
- Agregar chips condicionales para tazas no uniformes (warning)
- Agregar chips condicionales para tazas defectuosas con tipo de defecto (error)
- Layout de dos líneas: header con #/nombre/puntaje y chips informativos
- Diseño compacto y responsive
Limpia la UI del selector de intensidad para una experiencia más minimalista:
- Eliminado atributo title que mostraba tooltips con el valor
- Eliminada sección completa de indicadores numéricos (min/valor/max)
- El componente ahora solo muestra los iconos interactivos
- Mantiene toda la funcionalidad (selección, hover, deselección)
La interfaz es ahora más limpia y el usuario puede confiar en el feedback visual de los iconos activos para conocer el valor seleccionado.
Crea nuevo componente SelectorIntensidad que reemplaza los sliders tradicionales por un selector tipo "rating" con iconos clicables:
Características del nuevo componente:
- Usa círculos (circle/circle-dot) para intensidad descriptiva
- Usa corazones (heart) para intensidad afectiva
- Los iconos se llenan hasta el valor seleccionado
- Efecto hover para preview
- Mismo rango: descriptiva (1-10), afectiva (1-15)
- Click en mismo valor lo deselecciona (vuelve a null)
- Soporte para colores personalizados
- Efectos de glow en modo oscuro
- Responsive (iconos más pequeños en móvil)
Cambios técnicos:
- Nuevo archivo: app/components/cata/SelectorIntensidad.vue
- Modificado: app/components/cata/FormularioMuestra.vue
- Reemplazado CataSliderIntensidad por CataSelectorIntensidad (global)
- Mantiene la misma interfaz de props y eventos que SliderIntensidad
- Mover sección Sensaciones en Boca de Impresión Global a Organoléptica
- Mover sección Gustos Predominantes de Impresión Global a Organoléptica
- Agregar v-if mostrarSensacionBocaOrganoleptica para filtrado por subcategoría
- Agregar v-if mostrarGustosPredominantes para filtrado por subcategoría
- Renombrar Detalles Adicionales a Notas Adicionales en Impresión Global
- Cambiar subcategoriaActiva a subcategoriasActivas (array) para permitir selección múltiple
- Agregar flex-wrap a barra de subcategorías en lugar de scroll horizontal
- Implementar toggleSubcategoria para agregar/quitar subcategorías
- Pasar subcategoriasActivas a FormularioMuestra como prop
- Agregar helpers deberMostrarSeccion para filtrar inputs
- Aplicar v-if a todas las secciones según subcategorías activas
- Botón Limpiar Todo para resetear filtros
- Agregar validación completa en loadCustomColors para detectar formato incompatible
- Proteger setCustomColors asegurando que la estructura existe antes de asignar
- Validar estructura en getCurrentColors y retornar defaults si no existe
- Validar estructura en hasCustomColors y retornar false si no existe
- Validar estructura en inicializar antes de aplicar colores
- Limpiar localStorage automáticamente si detecta formato antiguo o corrupto
Soluciona error: TypeError Cannot create property 'primary' on string
cuando localStorage contiene datos de versión anterior
- Modificar useColorCustomization para manejar tres colores (primary, foreground, background)
- Actualizar interfaz ThemeColors con los tres colores
- Agregar selectores de color para fuente y fondo en el modal
- Implementar vista previa con los tres colores aplicados
- Actualizar funciones setCustomColors y resetColors para manejar múltiples colores
- Mantener almacenamiento separado por tema (light/dark)
- Aplicar colores a variables --cata-fg y --cata-bg además de --cata-primary
- Agregar composable useCategoryColors con 8 colores coordinados (light/dark)
- Colores por categoría: Fragancia (lavanda), Aroma (verde menta), Sabor (rojo),
Sabor Residual (naranja), Acidez (amarillo), Dulzor (rosa), Sensación en Boca (azul),
Impresión Global (turquesa)
- Eliminar hints de texto de SliderIntensidad (showDescription = false por defecto)
- Aplicar colores dinámicos a headers y sliders de cada categoría
- Aumentar font-weight de headers a 700 (bold)
- Los colores se adaptan automáticamente al tema light/dark
- Mover trigger button al slot default de UModal
- Usar props title y description directamente en UModal
- Usar slots #body y #footer para el contenido del modal
- Mantener v-model:open para control de estado
- Eliminar wrapper div duplicado
- Seguir estructura correcta de Nuxt UI v4
- Crear composable useColorCustomization para manejar colores personalizados
- Agregar botón de paleta en CataUserInfo para acceder al color picker
- Implementar modal con selector de color (input color + text)
- Guardar preferencias en localStorage por tema (light/dark)
- Generar paleta de gradientes automáticamente desde color base
- Aplicar colores dinámicamente a variables CSS
- Incluir vista previa del color en el modal
- Botón para restablecer al color por defecto
- Persistencia de colores entre sesiones
- Inicialización automática en app.vue
- **Nuevas tabs reorganizadas:**
- Organoléptica: Selectores de familia de fragancia-aroma y sabor
- Descriptiva/Afectiva: Todos los sliders de intensidad (incluye impresión global)
- Defectos: Tazas no uniformes, defectuosas y tipo de defecto
- Impresión Global: Vista completa con todos los componentes
- **Selector de categorías mejorado:**
- Permitir selección múltiple de categorías padre
- Las subcategorías son la unión de las subcategorías de los padres seleccionados
- Permitir selección múltiple de subcategorías
- Actualizar resumen visual de selección
- **Tipos actualizados:**
- NotaSeleccionada ahora usa arrays para categorias y subcategorias
- TabCatacion actualizado con las nuevas tabs
- Funciones de actualización modificadas para trabajar con arrays
- **Correcciones TypeScript:**
- Usar JSON.parse(JSON.stringify()) para crear copias mutables de arrays readonly
- Resolver incompatibilidades de tipos entre readonly y mutable arrays
- Quitar efecto scale on hover/active de todos los botones cata-button
- Quitar efecto hover:scale del avatar en UserInfo
- Rediseñar toasts con estilo outline/terminal 100% acoplado al sistema
- Toasts usan variables CSS del sistema (--cata-bg, --cata-fg, --cata-primary)
- Texto con fuente mono y text-shadow en modo oscuro
- Efectos glow sutiles en modo oscuro según tipo de notificación
- Bordes outline coherentes con diseño del sistema de catación
- Rediseñar layout para ser más compacto y horizontal
- Usar badges de indicadores para mostrar valores afectivos de intensidades
- Mostrar progreso con barra visual en desktop
- Eliminar información redundante y simplificar estructura
- Mejorar responsive design para mobile
- Eliminar CataResumenMuestra.vue y CataFormularioMuestra.vue duplicados
- Usar componentes existentes en components/cata/ que ya se auto-registran como CataResumenMuestra y CataFormularioMuestra
- Resolver conflicto de nombres en Nuxt que impedía el build
- Crear componente CataResumenMuestra para mostrar resumen de cada muestra en el header del accordion
- Crear componente CataFormularioMuestra para mostrar formulario de edición de intensidades por tab
- Corregir uso de slots en UAccordion para mostrar correctamente el contenido
- Usar slot #default para customizar el header con CataResumenMuestra
- Usar slots personalizados por muestra para el body con CataFormularioMuestra
- Agregar estilos mejorados para los items del accordion
- Crear componente CataUserInfo con estilo mobile-first del sistema de catación
- Mover "/" para redirigir automáticamente a /cata
- Incluir información del usuario en página de catación
- Mantener estilo consistente con diseño outline/terminal del sistema
- Optimizar componente de usuario para mobile (compacto y funcional)
Agregar sistema completo de catación de café con las siguientes características:
- Tipos TypeScript completos para sesiones, muestras, intensidades y notas
- Composable useIndexedDB para gestión de sesión activa en cliente
- Composable useCatacion con lógica de negocio para actualización de muestras
- Componentes reutilizables:
* SliderIntensidad: Slider dual para valores descriptivos (1-10) y afectivos (1-15)
* SelectorFamilia: Selector jerárquico de familias de notas (3 niveles)
* SelectorTazas: Selector de tazas (1-5) para uniformidad y defectos
* ResumenMuestra: Header de accordion con progreso y estadísticas
* FormularioMuestra: Formulario completo con 3 tabs (Fragancia/Aroma, Sabor, Impresión Global)
- Páginas:
* /cata: Gestión de sesiones (crear nueva o continuar existente)
* /cata/sesion: Interfaz principal de catación con accordions y tabs
- Tema dual:
* Modo claro: Fondo blanco, texto negro, outlines azules
* Modo oscuro: Fondo negro, texto verde terminal, estilo monospace
- Diseño mobile-first responsive con CSS vanilla (sin @apply de Tailwind)
- Configuración PWA con almacenamiento en IndexedDB
Configuración PWA:
- Agregar estructura completa de Nuxt4 para PWA
- Configurar .env.example con variables de entorno
- Preparar aplicación para instalación offline
Configuración Claude Code:
- Agregar .claude/ con settings y hooks
- Configurar entorno de desarrollo con Claude
CI/CD:
- Agregar .gitea/workflows para Gitea Actions
- Preparar pipeline de despliegue automático
Docker:
- Actualizar docker-compose.yml con servicios PWA
- Configurar networking entre servicios
Git:
- Actualizar .gitignore para excluir archivos de build
- Ignorar node_modules y archivos temporales