Estandares de Diseno de UI - Compulandia Integrador¶
Version: 1.0 Ultima actualizacion: Enero 2026
1. Filosofia de Diseno¶
Principio Fundamental: Simplicidad sobre Decoracion¶
El Integrador es una herramienta de trabajo para operadores que procesan cientos de productos diariamente. Cada elemento visual debe justificar su existencia reduciendo friccion o mejorando la comprension.
Inspiracion¶
- Medusa Admin: Espacios amplios, tipografia clara, minimalismo funcional
- shadcn/ui: Componentes neutros, bordes sutiles, estados claros
- Linear: Densidad informativa sin sobrecarga visual
Objetivo Principal¶
Reducir la carga cognitiva del operador eliminando ruido visual innecesario y priorizando el contenido sobre la decoracion.
Anti-patrones a Evitar¶
- Iconos decorativos en cada titulo/label
- Cards anidadas dentro de cards
- Multiples colores de fondo en contenedores
- Bordes de colores llamativos (
border-primary,border-warning) - Headers de cards con fondos de color
- Alertas y badges excesivos
2. Paleta de Colores¶
Colores Primarios¶
/* Fondos */
--bg-page: #ffffff;
--bg-surface: #fafafa;
--bg-muted: #f5f5f5;
/* Textos */
--text-primary: #111827;
--text-secondary: #6b7280;
--text-muted: #9ca3af;
/* Bordes */
--border-default: #e5e7eb;
--border-subtle: #f3f4f6;
Colores de Acento (usar con moderacion)¶
/* Solo para acciones principales y estados */
--accent-primary: #3b82f6; /* Boton primario */
--accent-success: #10b981; /* Confirmaciones, estados activos */
--accent-warning: #f59e0b; /* Advertencias leves */
--accent-danger: #ef4444; /* Errores, acciones destructivas */
Reglas de Uso¶
| Contexto | Color Permitido |
|---|---|
| Fondo de pagina | Blanco (#fff) |
| Fondo de card | Blanco o gris muy claro (#fafafa) |
| Headers de card | Sin fondo de color (solo texto) |
| Bordes de card | Gris sutil (#e5e7eb) o ninguno |
| Texto de titulos | Negro/gris oscuro (#111827) |
| Iconos en labels | Evitar salvo navegacion |
| Botones primarios | Azul (#3b82f6) - solo accion principal |
| Botones secundarios | Gris/outline |
Ejemplo: Antes vs Despues¶
Antes (evitar):
<div class="card border-primary shadow-sm">
<div class="card-header bg-primary bg-opacity-10">
<strong><i class="fas fa-fingerprint me-2"></i>Identificadores</strong>
</div>
...
</div>
Despues (preferir):
<div class="space-y-4">
<h3 class="text-sm font-medium text-gray-700">Identificadores</h3>
...
</div>
3. Contenedores y Cards¶
Principio: Separacion por Espaciado, no por Bordes¶
El espaciado vertical y horizontal debe ser suficiente para agrupar contenido relacionado sin necesidad de bordes o fondos.
Cuando Usar Cards¶
- Para agrupar contenido semanticamente relacionado (ej: datos del proveedor)
- Para secciones que pueden expandirse/colapsarse
- Para items en listas donde cada uno es una unidad independiente
Cuando NO Usar Cards¶
- Para subdividir formularios
- Para agrupar campos de input
- Dentro de otras cards (evitar anidamiento)
Estilos de Card Permitidos¶
<!-- Card simple (preferido) -->
<div class="bg-white rounded-lg border border-gray-200">
<div class="p-4">
<!-- contenido -->
</div>
</div>
<!-- Card con titulo -->
<div class="bg-white rounded-lg border border-gray-200">
<div class="px-4 py-3 border-b border-gray-100">
<h3 class="text-sm font-medium text-gray-900">Titulo</h3>
</div>
<div class="p-4">
<!-- contenido -->
</div>
</div>
Evitar¶
<!-- NO: Card con borde de color -->
<div class="card border-primary">...</div>
<!-- NO: Card con header coloreado -->
<div class="card-header bg-warning bg-opacity-10">...</div>
<!-- NO: Cards anidadas -->
<div class="card">
<div class="card">...</div> <!-- Nunca anidar -->
</div>
Escala de Bordes¶
/* Sutil (preferido) */
border: 1px solid #e5e7eb;
/* Muy sutil */
border: 1px solid #f3f4f6;
/* Sin borde (usar shadow sutil si es necesario) */
box-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);
4. Tipografia y Labels¶
Jerarquia de Titulos¶
<!-- Titulo de pagina -->
<h1 class="text-xl font-semibold text-gray-900">Titulo Principal</h1>
<!-- Titulo de seccion -->
<h2 class="text-lg font-medium text-gray-900">Seccion</h2>
<!-- Titulo de subseccion -->
<h3 class="text-sm font-medium text-gray-700">Subseccion</h3>
<!-- Label de campo -->
<label class="text-sm text-gray-600">Nombre del Campo</label>
Reglas para Titulos¶
- Sin iconos decorativos: Los iconos solo se usan para navegacion o acciones
- Sin ":" al final: Los titulos no terminan en dos puntos
- Capitalizacion: Primera letra mayuscula, resto minusculas
- Longitud: Breves y descriptivos
Ejemplo: Labels de Formulario¶
Antes (evitar):
<label class="form-label fw-bold">
<i class="fas fa-tag text-primary me-1"></i>
Categoria del Producto:
</label>
Despues (preferir):
<label class="text-sm text-gray-600">Categoria</label>
Texto de Ayuda¶
<label class="text-sm text-gray-600">Nombre del producto</label>
<input type="text" class="..." />
<p class="mt-1 text-xs text-gray-500">Maximo 100 caracteres</p>
5. Formularios¶
Estructura General¶
<form class="space-y-6">
<!-- Seccion agrupada por proximidad, sin card -->
<div class="space-y-4">
<h3 class="text-sm font-medium text-gray-700">Datos basicos</h3>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<div>
<label class="text-sm text-gray-600">Campo 1</label>
<input type="text" class="..." />
</div>
<div>
<label class="text-sm text-gray-600">Campo 2</label>
<input type="text" class="..." />
</div>
</div>
</div>
<!-- Separador visual (espaciado) -->
<div class="border-t border-gray-100 pt-6">
<h3 class="text-sm font-medium text-gray-700">Otra seccion</h3>
<!-- ... -->
</div>
</form>
Estilos de Input¶
<!-- Input estandar -->
<input type="text"
class="w-full px-3 py-2 text-sm border border-gray-300 rounded-md
focus:outline-none focus:ring-1 focus:ring-blue-500 focus:border-blue-500
disabled:bg-gray-50 disabled:text-gray-500" />
<!-- Input con error -->
<input type="text"
class="w-full px-3 py-2 text-sm border border-red-300 rounded-md
focus:outline-none focus:ring-1 focus:ring-red-500" />
<p class="mt-1 text-xs text-red-600">Mensaje de error</p>
Botones en Formularios¶
<!-- Footer de formulario -->
<div class="flex justify-end gap-3 pt-6 border-t border-gray-100">
<button type="button" class="px-4 py-2 text-sm text-gray-700 bg-white border border-gray-300 rounded-md hover:bg-gray-50">
Cancelar
</button>
<button type="submit" class="px-4 py-2 text-sm text-white bg-blue-600 rounded-md hover:bg-blue-700">
Guardar
</button>
</div>
Reglas de Botones¶
| Tipo | Uso | Estilo |
|---|---|---|
| Primario | Una sola accion principal por vista | bg-blue-600 text-white |
| Secundario | Acciones alternativas | bg-white border text-gray-700 |
| Peligro | Acciones destructivas | bg-red-600 text-white |
| Ghost | Acciones terciarias | text-gray-600 hover:text-gray-900 |
6. Listas y Seleccion¶
Listas de Items Seleccionables¶
Antes (evitar):
<div class="list-group">
<label class="list-group-item list-group-item-action d-flex align-items-center
cursor-pointer active border-success">
<input type="checkbox" class="form-check-input me-3">
<div>
<i class="fas fa-plus-circle me-2 text-success"></i>
<strong>Opcion seleccionada</strong>
</div>
</label>
</div>
Despues (preferir):
<div class="space-y-2">
<label class="flex items-center gap-3 p-3 rounded-md cursor-pointer
hover:bg-gray-50 [&:has(input:checked)]:bg-blue-50
[&:has(input:checked)]:ring-1 [&:has(input:checked)]:ring-blue-200">
<input type="checkbox" class="w-4 h-4 text-blue-600 rounded border-gray-300">
<span class="text-sm text-gray-900">Opcion</span>
</label>
</div>
Estados de Seleccion¶
| Estado | Estilo |
|---|---|
| Normal | bg-white |
| Hover | bg-gray-50 |
| Seleccionado | bg-blue-50 ring-1 ring-blue-200 |
| Deshabilitado | opacity-50 cursor-not-allowed |
7. Modales¶
Estructura Basica¶
<div class="fixed inset-0 z-50 flex items-center justify-center">
<!-- Backdrop -->
<div class="absolute inset-0 bg-black/50"></div>
<!-- Modal -->
<div class="relative bg-white rounded-lg shadow-xl max-w-lg w-full mx-4">
<!-- Header (simple, sin fondo de color) -->
<div class="px-6 py-4 border-b border-gray-100">
<h2 class="text-lg font-medium text-gray-900">Titulo del Modal</h2>
<p class="mt-1 text-sm text-gray-500">Descripcion opcional</p>
</div>
<!-- Body -->
<div class="px-6 py-4">
<!-- contenido -->
</div>
<!-- Footer -->
<div class="px-6 py-4 border-t border-gray-100 flex justify-end gap-3">
<button class="px-4 py-2 text-sm text-gray-700 bg-white border rounded-md">
Cancelar
</button>
<button class="px-4 py-2 text-sm text-white bg-blue-600 rounded-md">
Confirmar
</button>
</div>
</div>
</div>
Reglas para Modales¶
- Header sin color de fondo: Solo texto
- Boton de cerrar:
xen esquina superior derecha, sutil - Acciones alineadas a la derecha: Cancelar primero, accion principal ultima
- Contenido directo: Evitar cards dentro del modal
- Ancho adecuado:
max-w-smpara confirmaciones,max-w-lgpara formularios,max-w-xlpara contenido complejo
8. Estados y Feedback¶
Mensajes de Estado¶
Preferir texto sobre bloques de color:
<!-- Exito -->
<p class="text-sm text-green-600">Guardado correctamente</p>
<!-- Error -->
<p class="text-sm text-red-600">Error al procesar</p>
<!-- Advertencia -->
<p class="text-sm text-amber-600">Revisa los campos marcados</p>
<!-- Info -->
<p class="text-sm text-blue-600">Procesando...</p>
Cuando usar alertas con fondo (solo para mensajes importantes):
<div class="p-3 text-sm text-red-700 bg-red-50 rounded-md">
Error critico que requiere atencion inmediata
</div>
Loading States¶
<!-- Spinner sutil -->
<div class="flex items-center gap-2 text-sm text-gray-500">
<svg class="w-4 h-4 animate-spin" viewBox="0 0 24 24">...</svg>
<span>Cargando...</span>
</div>
<!-- Skeleton (para contenido) -->
<div class="animate-pulse space-y-2">
<div class="h-4 bg-gray-200 rounded w-3/4"></div>
<div class="h-4 bg-gray-200 rounded w-1/2"></div>
</div>
Empty States¶
<div class="py-12 text-center">
<p class="text-sm text-gray-500">No hay productos que mostrar</p>
<button class="mt-4 text-sm text-blue-600 hover:text-blue-700">
Agregar primer producto
</button>
</div>
Badges y Tags¶
<!-- Badge simple -->
<span class="px-2 py-1 text-xs font-medium text-gray-700 bg-gray-100 rounded">
Pendiente
</span>
<!-- Badge con estado -->
<span class="px-2 py-1 text-xs font-medium text-green-700 bg-green-100 rounded">
Activo
</span>
9. Espaciado¶
Escala Base (4px)¶
/* Espaciado */
--space-1: 0.25rem; /* 4px */
--space-2: 0.5rem; /* 8px */
--space-3: 0.75rem; /* 12px */
--space-4: 1rem; /* 16px */
--space-6: 1.5rem; /* 24px */
--space-8: 2rem; /* 32px */
--space-12: 3rem; /* 48px */
Uso por Contexto¶
| Contexto | Espaciado |
|---|---|
| Entre elementos de lista | space-y-2 (8px) |
| Entre campos de formulario | space-y-4 (16px) |
| Entre secciones | space-y-6 (24px) o space-y-8 (32px) |
| Padding interno de card | p-4 (16px) o p-6 (24px) |
| Gap en grids | gap-4 (16px) |
Separadores¶
Preferir espaciado sobre lineas:
<!-- Con espaciado (preferido) -->
<div class="space-y-8">
<section>...</section>
<section>...</section>
</div>
<!-- Con linea sutil (cuando es necesario) -->
<div class="space-y-6">
<section>...</section>
<div class="border-t border-gray-100"></div>
<section>...</section>
</div>
10. Ejemplos Comparativos¶
Ejemplo 1: Card de Informacion¶
Antes:
<div class="card border-primary shadow-sm mb-2">
<div class="card-header bg-primary bg-opacity-10">
<strong><i class="fas fa-box me-2"></i>Producto del Proveedor</strong>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-4">
<strong>SKU:</strong> ABC123
</div>
</div>
</div>
</div>
Despues:
<div class="bg-white rounded-lg border border-gray-200 p-4">
<h3 class="text-sm font-medium text-gray-900 mb-3">Producto del proveedor</h3>
<dl class="grid grid-cols-3 gap-4 text-sm">
<div>
<dt class="text-gray-500">SKU</dt>
<dd class="font-medium text-gray-900">ABC123</dd>
</div>
</dl>
</div>
Ejemplo 2: Seccion de Formulario¶
Antes:
<div class="card border-primary shadow-sm mb-2">
<div class="card-body p-2">
<h6 class="card-title text-primary mb-2 fs-6">
<i class="fas fa-fingerprint me-1"></i> Identificadores
</h6>
<div class="row g-1">
<div class="col-md-3">
<label class="form-label"><i class="fas fa-barcode"></i> SKU</label>
<input type="text" class="form-control form-control-sm">
</div>
</div>
</div>
</div>
Despues:
<div class="space-y-4">
<h3 class="text-sm font-medium text-gray-700">Identificadores</h3>
<div class="grid grid-cols-4 gap-4">
<div>
<label class="block text-sm text-gray-600 mb-1">SKU</label>
<input type="text" class="w-full px-3 py-2 text-sm border border-gray-300 rounded-md">
</div>
</div>
</div>
Ejemplo 3: Header de Modal¶
Antes:
<div class="modal-header bg-light">
<div class="d-flex flex-column">
<h5 class="modal-title mb-1">
<i class="fas fa-box-open me-2"></i>
Confirmar Producto Pendiente
</h5>
<small class="text-muted">Paso 1 de 5</small>
</div>
<button type="button" class="btn-close"></button>
</div>
Despues:
<div class="px-6 py-4 border-b border-gray-100">
<div class="flex items-start justify-between">
<div>
<h2 class="text-lg font-medium text-gray-900">Confirmar producto pendiente</h2>
<p class="mt-1 text-sm text-gray-500">Paso 1 de 5</p>
</div>
<button class="p-1 text-gray-400 hover:text-gray-600 rounded">
<svg class="w-5 h-5">...</svg>
</button>
</div>
</div>
11. Checklist de Revision¶
Antes de hacer merge de un PR con cambios de UI, verificar:
Colores¶
- [ ] No hay
border-primary,border-warning, etc. en cards - [ ] No hay
bg-*-opacity-10en headers - [ ] Los fondos son blanco o gris muy claro
- [ ] Los colores de acento solo se usan para acciones y estados
Estructura¶
- [ ] No hay cards anidadas
- [ ] Las secciones se separan por espaciado, no por bordes
- [ ] Los formularios no estan subdivididos en cards
Tipografia¶
- [ ] Los titulos no tienen iconos decorativos
- [ ] Los labels son simples (sin iconos, sin ":")
- [ ] Se respeta la jerarquia de tamanos
Componentes¶
- [ ] Solo hay un boton primario por vista/modal
- [ ] Los modales tienen header simple (sin fondo)
- [ ] Las listas seleccionables no usan cards individuales
Espaciado¶
- [ ] Se usa la escala de 4px
- [ ] El espaciado es consistente entre secciones
- [ ] No hay separadores visuales innecesarios
12. Migracion Gradual¶
Este documento establece el estandar para nuevos desarrollos. La migracion de componentes existentes se hara de forma gradual siguiendo estas prioridades:
- Alta prioridad: Modales y formularios de uso frecuente
- Media prioridad: Vistas de listado y detalle
- Baja prioridad: Vistas administrativas de uso ocasional
Al modificar un componente existente por cualquier razon, aprovechar para alinearlo con estos estandares.