Files
Lucy 46360b6827 feat: agregar design system completo con 2 temas (Industrial + Moderno)
- Tokens CSS con variables para ambos temas (dark/light)
- 21 componentes reutilizables (buttons, cards, tables, modals, etc.)
- 10 pantallas POS (login, catálogo, POS, inventario, clientes, facturación, contabilidad, dashboard, configuración, reportes)
- Preview interactivo con selector de tema
- Generado por el equipo de Hugo (Milo-UX, Iris-UI, Zara-Frontend)
2026-04-01 01:41:04 +00:00

345 lines
11 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="es" data-theme="industrial">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Nexus Autoparts — Alerts & Toasts</title>
<link rel="stylesheet" href="../tokens/tokens.css">
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: var(--font-body);
background: var(--color-bg-base);
color: var(--color-text-primary);
padding: var(--space-8);
transition: var(--transition-normal);
}
.theme-switcher {
position: sticky; top: 0; z-index: var(--z-sticky);
display: flex; gap: var(--space-2);
padding: var(--space-3) var(--space-4);
background: var(--color-bg-elevated);
border-bottom: 1px solid var(--color-border);
margin: calc(-1 * var(--space-8)); margin-bottom: var(--space-8);
}
.theme-switcher button {
padding: var(--space-2) var(--space-4);
border: 1px solid var(--color-border);
background: var(--color-bg-base);
color: var(--color-text-primary);
border-radius: var(--radius-md);
cursor: pointer;
font-family: var(--font-body);
font-size: var(--text-body-sm);
transition: var(--transition-fast);
}
.theme-switcher button.active {
background: var(--color-primary);
color: var(--color-text-inverse);
border-color: var(--color-primary);
}
h1 { font-family: var(--font-heading); font-size: var(--text-h2); font-weight: var(--heading-weight-primary); margin-bottom: var(--space-2); color: var(--color-text-accent); }
.subtitle { color: var(--color-text-muted); font-size: var(--text-body); margin-bottom: var(--space-8); }
section { margin-bottom: var(--space-10); }
section h2 { font-family: var(--font-heading); font-size: var(--text-h4); font-weight: var(--heading-weight-secondary); color: var(--color-text-secondary); margin-bottom: var(--space-4); padding-bottom: var(--space-2); border-bottom: 1px solid var(--color-border); }
.label { font-size: var(--text-caption); color: var(--color-text-muted); text-transform: uppercase; letter-spacing: var(--tracking-widest); font-weight: var(--font-weight-semibold); margin-bottom: var(--space-2); }
.component-col { display: flex; flex-direction: column; gap: var(--space-4); margin-bottom: var(--space-6); max-width: 600px; }
/* ====== Alert Banners ====== */
.alert {
display: flex;
align-items: flex-start;
gap: var(--space-3);
padding: var(--space-4);
border: 1px solid;
border-radius: var(--radius-md);
font-size: var(--text-body-sm);
}
[data-theme="industrial"] .alert {
border-radius: 0;
clip-path: polygon(0 0, calc(100% - 8px) 0, 100% 8px, 100% 100%, 0 100%);
}
.alert-icon {
font-size: var(--text-body-lg);
flex-shrink: 0;
line-height: 1;
}
.alert-content { flex: 1; }
.alert-title {
font-weight: var(--font-weight-semibold);
margin-bottom: var(--space-1);
}
.alert-close {
background: none;
border: none;
color: inherit;
opacity: 0.6;
cursor: pointer;
font-size: var(--text-body);
padding: var(--space-1);
transition: var(--transition-fast);
}
.alert-close:hover { opacity: 1; }
.alert-success {
background: rgba(34, 197, 94, 0.08);
border-color: var(--color-success);
color: var(--color-success-dark);
}
[data-theme="industrial"] .alert-success { color: var(--color-success); }
.alert-warning {
background: rgba(234, 179, 8, 0.08);
border-color: var(--color-warning);
color: var(--color-warning-dark);
}
[data-theme="industrial"] .alert-warning { color: var(--color-warning); }
.alert-error {
background: rgba(239, 68, 68, 0.08);
border-color: var(--color-error);
color: var(--color-error-dark);
}
[data-theme="industrial"] .alert-error { color: var(--color-error); }
.alert-info {
background: var(--color-primary-muted);
border-color: var(--color-primary);
color: var(--color-primary);
}
/* ====== Toast Notifications ====== */
.toast-container {
display: flex;
flex-direction: column;
gap: var(--space-3);
max-width: 400px;
}
.toast {
display: flex;
align-items: center;
gap: var(--space-3);
padding: var(--space-3) var(--space-4);
background: var(--color-bg-elevated);
border: 1px solid var(--color-border);
border-radius: var(--radius-md);
box-shadow: var(--shadow-lg);
font-size: var(--text-body-sm);
position: relative;
overflow: hidden;
}
[data-theme="industrial"] .toast {
border-radius: 0;
clip-path: polygon(0 0, calc(100% - 6px) 0, 100% 6px, 100% 100%, 0 100%);
}
.toast::before {
content: '';
position: absolute;
left: 0;
top: 0;
bottom: 0;
width: 4px;
}
.toast-success::before { background: var(--color-success); }
.toast-warning::before { background: var(--color-warning); }
.toast-error::before { background: var(--color-error); }
.toast-info::before { background: var(--color-primary); }
.toast-icon {
font-size: var(--text-body-lg);
flex-shrink: 0;
}
.toast-content { flex: 1; }
.toast-title {
font-weight: var(--font-weight-semibold);
color: var(--color-text-primary);
}
.toast-message {
color: var(--color-text-muted);
font-size: var(--text-caption);
margin-top: 2px;
}
.toast-close {
background: none;
border: none;
color: var(--color-text-muted);
cursor: pointer;
font-size: var(--text-body-sm);
padding: var(--space-1);
transition: var(--transition-fast);
}
.toast-close:hover { color: var(--color-text-primary); }
.toast-progress {
position: absolute;
bottom: 0;
left: 0;
height: 3px;
border-radius: 0 0 var(--radius-md) var(--radius-md);
}
.toast-success .toast-progress { background: var(--color-success); width: 70%; }
.toast-warning .toast-progress { background: var(--color-warning); width: 45%; }
.toast-error .toast-progress { background: var(--color-error); width: 90%; }
.toast-info .toast-progress { background: var(--color-primary); width: 30%; }
/* ====== Inline Alert (minimal) ====== */
.inline-alert {
display: flex;
align-items: center;
gap: var(--space-2);
padding: var(--space-2) var(--space-3);
font-size: var(--text-body-sm);
border-left: 3px solid;
background: var(--color-bg-elevated);
}
.inline-alert-success { border-left-color: var(--color-success); color: var(--color-success); }
.inline-alert-warning { border-left-color: var(--color-warning); color: var(--color-warning); }
.inline-alert-error { border-left-color: var(--color-error); color: var(--color-error); }
</style>
</head>
<body>
<div class="theme-switcher">
<button class="active" onclick="setTheme('industrial')">🔧 Industrial</button>
<button onclick="setTheme('modern')">⚡ Moderno</button>
</div>
<h1>Alerts & Toasts</h1>
<p class="subtitle">Notificaciones, alertas y banners de feedback del sistema POS</p>
<!-- Alert Banners -->
<section>
<h2>Alert Banners</h2>
<div class="label">Mensajes de contexto completo</div>
<div class="component-col">
<div class="alert alert-success">
<span class="alert-icon"></span>
<div class="alert-content">
<div class="alert-title">Venta completada</div>
<div>La venta #VTA-2024-0847 se procesó correctamente. Total: $3,450.00 MXN</div>
</div>
<button class="alert-close"></button>
</div>
<div class="alert alert-warning">
<span class="alert-icon"></span>
<div class="alert-content">
<div class="alert-title">Stock bajo</div>
<div>El producto "Pastillas de freno Brembo P50 042" tiene solo 3 unidades. Reorden sugerido: 20 unidades.</div>
</div>
<button class="alert-close"></button>
</div>
<div class="alert alert-error">
<span class="alert-icon"></span>
<div class="alert-content">
<div class="alert-title">Error de conexión</div>
<div>No se pudo sincronizar el inventario con el servidor. Último sync: hace 15 min. Reintentando...</div>
</div>
<button class="alert-close"></button>
</div>
<div class="alert alert-info">
<span class="alert-icon"></span>
<div class="alert-content">
<div class="alert-title">Actualización disponible</div>
<div>Hay una nueva versión del catálogo de partes (v2.4.1). Se actualizará automáticamente esta noche.</div>
</div>
<button class="alert-close"></button>
</div>
</div>
</section>
<!-- Toast Notifications -->
<section>
<h2>Toast Notifications</h2>
<div class="label">Notificaciones flotantes tipo toast</div>
<div class="toast-container">
<div class="toast toast-success">
<span class="toast-icon"></span>
<div class="toast-content">
<div class="toast-title">Producto agregado</div>
<div class="toast-message">Filtro de aceite WIX 57060 — $189.00</div>
</div>
<button class="toast-close"></button>
<div class="toast-progress"></div>
</div>
<div class="toast toast-warning">
<span class="toast-icon"></span>
<div class="toast-content">
<div class="toast-title">Precio actualizado</div>
<div class="toast-message">El proveedor actualizó el precio de 12 productos</div>
</div>
<button class="toast-close"></button>
<div class="toast-progress"></div>
</div>
<div class="toast toast-error">
<span class="toast-icon"></span>
<div class="toast-content">
<div class="toast-title">Pago rechazado</div>
<div class="toast-message">La terminal reportó: tarjeta declinada</div>
</div>
<button class="toast-close"></button>
<div class="toast-progress"></div>
</div>
<div class="toast toast-info">
<span class="toast-icon"></span>
<div class="toast-content">
<div class="toast-title">Sincronizando catálogo</div>
<div class="toast-message">Actualizando 1.4M partes... 34% completado</div>
</div>
<button class="toast-close"></button>
<div class="toast-progress"></div>
</div>
</div>
</section>
<!-- Inline Alerts -->
<section>
<h2>Inline Alerts</h2>
<div class="label">Alertas mínimas inline para formularios y validación</div>
<div class="component-col">
<div class="inline-alert inline-alert-success">✓ Producto guardado exitosamente</div>
<div class="inline-alert inline-alert-warning">⚠ Este precio está 30% arriba del promedio</div>
<div class="inline-alert inline-alert-error">✕ SKU duplicado, ya existe en el sistema</div>
</div>
</section>
<script>
function setTheme(theme) {
document.documentElement.setAttribute('data-theme', theme);
document.querySelectorAll('.theme-switcher button').forEach(btn => {
btn.classList.toggle('active', btn.textContent.includes(theme === 'industrial' ? 'Industrial' : 'Moderno'));
});
}
</script>
</body>
</html>