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)
This commit is contained in:
Lucy
2026-04-01 01:41:04 +00:00
parent 5fc47473b6
commit 46360b6827
33 changed files with 32179 additions and 0 deletions

View File

@@ -0,0 +1,307 @@
<!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 — Accordion</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); }
/* ====== Accordion ====== */
.accordion {
max-width: 600px;
border: 1px solid var(--color-border);
border-radius: var(--radius-md);
overflow: hidden;
margin-bottom: var(--space-6);
}
[data-theme="industrial"] .accordion {
border-radius: 0;
}
.accordion-item {
border-bottom: 1px solid var(--color-border);
}
.accordion-item:last-child {
border-bottom: none;
}
.accordion-header {
display: flex;
align-items: center;
justify-content: space-between;
width: 100%;
padding: var(--space-4) var(--space-5);
background: var(--color-bg-elevated);
border: none;
cursor: pointer;
font-family: var(--font-body);
font-size: var(--text-body-sm);
font-weight: var(--font-weight-semibold);
color: var(--color-text-primary);
text-align: left;
transition: var(--transition-fast);
}
.accordion-header:hover {
background: var(--color-primary-muted);
}
.accordion-header.active {
color: var(--color-primary);
}
.accordion-icon {
font-size: var(--text-body-sm);
transition: var(--transition-fast);
color: var(--color-text-muted);
}
.accordion-header.active .accordion-icon {
transform: rotate(180deg);
color: var(--color-primary);
}
.accordion-body {
padding: 0 var(--space-5) var(--space-5);
background: var(--color-bg-elevated);
font-size: var(--text-body-sm);
color: var(--color-text-secondary);
line-height: var(--leading-body-sm);
display: none;
}
.accordion-body.open {
display: block;
}
.accordion-header-left {
display: flex;
align-items: center;
gap: var(--space-3);
}
.accordion-badge {
font-size: var(--text-caption);
background: var(--color-primary-muted);
color: var(--color-primary);
padding: 1px 8px;
border-radius: var(--radius-full);
font-weight: var(--font-weight-semibold);
}
/* Nested info in accordion body */
.info-grid {
display: grid;
grid-template-columns: auto 1fr;
gap: var(--space-2) var(--space-4);
font-size: var(--text-body-sm);
}
.info-label {
color: var(--color-text-muted);
}
.info-value {
color: var(--color-text-primary);
font-weight: var(--font-weight-semibold);
}
/* ====== Bordered Accordion ====== */
.accordion-bordered .accordion-item {
border: 1px solid var(--color-border);
border-radius: var(--radius-md);
margin-bottom: var(--space-2);
}
[data-theme="industrial"] .accordion-bordered .accordion-item {
border-radius: 0;
}
.accordion-bordered .accordion-item:last-child {
margin-bottom: 0;
}
.accordion-bordered .accordion-header {
border-radius: var(--radius-md);
}
[data-theme="industrial"] .accordion-bordered .accordion-header {
border-radius: 0;
}
</style>
</head>
<body>
<div class="theme-switcher">
<button class="active" onclick="setTheme('industrial')">🔧 Industrial</button>
<button onclick="setTheme('modern')">⚡ Moderno</button>
</div>
<h1>Accordion</h1>
<p class="subtitle">Secciones colapsables para organizar información del POS</p>
<!-- Product Details Accordion -->
<section>
<h2>Detalle de Producto</h2>
<div class="label">Información del producto en secciones colapsables</div>
<div class="accordion">
<div class="accordion-item">
<button class="accordion-header active" onclick="toggleAccordion(this)">
<div class="accordion-header-left">
<span>📋 Información General</span>
</div>
<span class="accordion-icon"></span>
</button>
<div class="accordion-body open">
<div class="info-grid">
<span class="info-label">Nombre</span>
<span class="info-value">Pastillas de freno Brembo P50 042</span>
<span class="info-label">SKU</span>
<span class="info-value">BRM-P50042</span>
<span class="info-label">OEM</span>
<span class="info-value">04465-33450</span>
<span class="info-label">Categoría</span>
<span class="info-value">Frenos</span>
<span class="info-label">Marca</span>
<span class="info-value">Brembo</span>
</div>
</div>
</div>
<div class="accordion-item">
<button class="accordion-header" onclick="toggleAccordion(this)">
<div class="accordion-header-left">
<span>💰 Precios y Costos</span>
</div>
<span class="accordion-icon"></span>
</button>
<div class="accordion-body">
<div class="info-grid">
<span class="info-label">Precio venta</span>
<span class="info-value" style="color: var(--color-primary);">$1,250.00</span>
<span class="info-label">Costo</span>
<span class="info-value">$780.00</span>
<span class="info-label">Margen</span>
<span class="info-value" style="color: var(--color-success);">37.6%</span>
<span class="info-label">Precio mayoreo</span>
<span class="info-value">$1,050.00 (10+ uds)</span>
</div>
</div>
</div>
<div class="accordion-item">
<button class="accordion-header" onclick="toggleAccordion(this)">
<div class="accordion-header-left">
<span>🚗 Compatibilidad</span>
<span class="accordion-badge">24 vehículos</span>
</div>
<span class="accordion-icon"></span>
</button>
<div class="accordion-body">
Toyota Corolla (2014-2022), Toyota Camry (2012-2020), Toyota RAV4 (2013-2021), Lexus ES (2013-2020), y 20 vehículos más.
</div>
</div>
<div class="accordion-item">
<button class="accordion-header" onclick="toggleAccordion(this)">
<div class="accordion-header-left">
<span>📦 Inventario</span>
</div>
<span class="accordion-icon"></span>
</button>
<div class="accordion-body">
<div class="info-grid">
<span class="info-label">Stock total</span>
<span class="info-value">12 unidades</span>
<span class="info-label">Sucursal Centro</span>
<span class="info-value">8 uds</span>
<span class="info-label">Sucursal Norte</span>
<span class="info-value">4 uds</span>
<span class="info-label">Ubicación</span>
<span class="info-value">Estante A-14</span>
<span class="info-label">Punto de reorden</span>
<span class="info-value">5 unidades</span>
</div>
</div>
</div>
</div>
</section>
<!-- FAQ Accordion (Bordered) -->
<section>
<h2>FAQ — Estilo Separado</h2>
<div class="label">Preguntas frecuentes o secciones independientes</div>
<div class="accordion accordion-bordered" style="border: none;">
<div class="accordion-item">
<button class="accordion-header active" onclick="toggleAccordion(this)">
<span>¿Cómo buscar un producto por número OEM?</span>
<span class="accordion-icon"></span>
</button>
<div class="accordion-body open">
Utiliza la barra de búsqueda principal e ingresa el número OEM completo o parcial. El sistema buscará automáticamente entre los 1.4M+ de partes registradas y mostrará coincidencias en tiempo real.
</div>
</div>
<div class="accordion-item">
<button class="accordion-header" onclick="toggleAccordion(this)">
<span>¿Cómo hacer un corte de caja?</span>
<span class="accordion-icon"></span>
</button>
<div class="accordion-body">
Ve a Contabilidad → Corte de Caja. El sistema calculará automáticamente las ventas del turno, desglosadas por método de pago. Ingresa el efectivo físico contado y el sistema detectará diferencias.
</div>
</div>
<div class="accordion-item">
<button class="accordion-header" onclick="toggleAccordion(this)">
<span>¿Cómo agregar un producto nuevo al inventario?</span>
<span class="accordion-icon"></span>
</button>
<div class="accordion-body">
Inventario → Nuevo Producto. Completa los campos requeridos (nombre, SKU, precio, categoría) y opcionalmente agrega compatibilidad con vehículos, imágenes y proveedores.
</div>
</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'));
});
}
function toggleAccordion(header) {
const body = header.nextElementSibling;
const isOpen = body.classList.contains('open');
// Close all in same accordion
const accordion = header.closest('.accordion');
accordion.querySelectorAll('.accordion-body').forEach(b => b.classList.remove('open'));
accordion.querySelectorAll('.accordion-header').forEach(h => h.classList.remove('active'));
if (!isOpen) {
body.classList.add('open');
header.classList.add('active');
}
}
</script>
</body>
</html>

View File

@@ -0,0 +1,344 @@
<!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>

View File

@@ -0,0 +1,262 @@
<!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 — Avatars</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-row { display: flex; flex-wrap: wrap; gap: var(--space-4); align-items: center; margin-bottom: var(--space-6); }
/* ====== Avatar Base ====== */
.avatar {
display: inline-flex;
align-items: center;
justify-content: center;
border-radius: var(--radius-full);
font-weight: var(--font-weight-bold);
color: var(--color-text-inverse);
background: var(--color-primary);
user-select: none;
flex-shrink: 0;
}
[data-theme="industrial"] .avatar {
border-radius: var(--radius-sm);
}
/* Sizes */
.avatar-xs { width: 24px; height: 24px; font-size: 10px; }
.avatar-sm { width: 32px; height: 32px; font-size: var(--text-caption); }
.avatar-md { width: 40px; height: 40px; font-size: var(--text-body-sm); }
.avatar-lg { width: 48px; height: 48px; font-size: var(--text-body); }
.avatar-xl { width: 64px; height: 64px; font-size: var(--text-h5); }
.avatar-2xl { width: 80px; height: 80px; font-size: var(--text-h4); }
/* Color variants */
.avatar-blue { background: #3b82f6; }
.avatar-green { background: var(--color-success); }
.avatar-red { background: var(--color-error); }
.avatar-purple { background: #8b5cf6; }
.avatar-gray { background: var(--color-neutral-500); }
/* Status indicator */
.avatar-wrapper {
position: relative;
display: inline-flex;
}
.avatar-status {
position: absolute;
bottom: 0;
right: 0;
width: 12px;
height: 12px;
border-radius: var(--radius-full);
border: 2px solid var(--color-bg-base);
}
.avatar-status-online { background: var(--color-success); }
.avatar-status-offline { background: var(--color-neutral-400); }
.avatar-status-busy { background: var(--color-error); }
.avatar-status-away { background: var(--color-warning); }
/* Avatar group */
.avatar-group {
display: flex;
}
.avatar-group .avatar {
border: 2px solid var(--color-bg-base);
margin-left: -8px;
}
.avatar-group .avatar:first-child {
margin-left: 0;
}
.avatar-group .avatar-more {
background: var(--color-surface-3);
color: var(--color-text-muted);
font-size: var(--text-caption);
}
/* User row (avatar + name) */
.user-row {
display: flex;
align-items: center;
gap: var(--space-3);
padding: var(--space-3);
background: var(--color-bg-elevated);
border: 1px solid var(--color-border);
border-radius: var(--radius-md);
max-width: 300px;
}
[data-theme="industrial"] .user-row { border-radius: 0; }
.user-info { flex: 1; }
.user-name { font-size: var(--text-body-sm); font-weight: var(--font-weight-semibold); color: var(--color-text-primary); }
.user-role { font-size: var(--text-caption); color: var(--color-text-muted); }
</style>
</head>
<body>
<div class="theme-switcher">
<button class="active" onclick="setTheme('industrial')">🔧 Industrial</button>
<button onclick="setTheme('modern')">⚡ Moderno</button>
</div>
<h1>Avatars</h1>
<p class="subtitle">Avatares de usuario con iniciales y estados para el POS</p>
<!-- Sizes -->
<section>
<h2>Tamaños</h2>
<div class="label">XS a 2XL</div>
<div class="component-row">
<div style="text-align: center;">
<div class="avatar avatar-xs">J</div>
<div style="font-size: var(--text-caption); color: var(--color-text-muted); margin-top: var(--space-1);">XS</div>
</div>
<div style="text-align: center;">
<div class="avatar avatar-sm">JR</div>
<div style="font-size: var(--text-caption); color: var(--color-text-muted); margin-top: var(--space-1);">SM</div>
</div>
<div style="text-align: center;">
<div class="avatar avatar-md">JR</div>
<div style="font-size: var(--text-caption); color: var(--color-text-muted); margin-top: var(--space-1);">MD</div>
</div>
<div style="text-align: center;">
<div class="avatar avatar-lg">JR</div>
<div style="font-size: var(--text-caption); color: var(--color-text-muted); margin-top: var(--space-1);">LG</div>
</div>
<div style="text-align: center;">
<div class="avatar avatar-xl">JR</div>
<div style="font-size: var(--text-caption); color: var(--color-text-muted); margin-top: var(--space-1);">XL</div>
</div>
<div style="text-align: center;">
<div class="avatar avatar-2xl">JR</div>
<div style="font-size: var(--text-caption); color: var(--color-text-muted); margin-top: var(--space-1);">2XL</div>
</div>
</div>
</section>
<!-- Colors -->
<section>
<h2>Colores</h2>
<div class="label">Variantes de color para diferenciar usuarios</div>
<div class="component-row">
<div class="avatar avatar-md">JR</div>
<div class="avatar avatar-md avatar-blue">ML</div>
<div class="avatar avatar-md avatar-green">CP</div>
<div class="avatar avatar-md avatar-red">AG</div>
<div class="avatar avatar-md avatar-purple">DH</div>
<div class="avatar avatar-md avatar-gray">??</div>
</div>
</section>
<!-- Status -->
<section>
<h2>Con Estado</h2>
<div class="label">Indicador de actividad del usuario en el POS</div>
<div class="component-row">
<div class="avatar-wrapper">
<div class="avatar avatar-lg">JR</div>
<span class="avatar-status avatar-status-online"></span>
</div>
<div class="avatar-wrapper">
<div class="avatar avatar-lg avatar-blue">ML</div>
<span class="avatar-status avatar-status-busy"></span>
</div>
<div class="avatar-wrapper">
<div class="avatar avatar-lg avatar-green">CP</div>
<span class="avatar-status avatar-status-away"></span>
</div>
<div class="avatar-wrapper">
<div class="avatar avatar-lg avatar-gray">AG</div>
<span class="avatar-status avatar-status-offline"></span>
</div>
</div>
</section>
<!-- Avatar Group -->
<section>
<h2>Grupo de Avatares</h2>
<div class="label">Usuarios asignados a una sucursal o pedido</div>
<div class="component-row">
<div class="avatar-group">
<div class="avatar avatar-md">JR</div>
<div class="avatar avatar-md avatar-blue">ML</div>
<div class="avatar avatar-md avatar-green">CP</div>
<div class="avatar avatar-md avatar-more">+3</div>
</div>
</div>
</section>
<!-- User Rows -->
<section>
<h2>Avatar en Contexto</h2>
<div class="label">Filas de usuario (sidebar, listas, etc.)</div>
<div style="display: flex; flex-direction: column; gap: var(--space-3);">
<div class="user-row">
<div class="avatar-wrapper">
<div class="avatar avatar-md">JR</div>
<span class="avatar-status avatar-status-online"></span>
</div>
<div class="user-info">
<div class="user-name">Juan Rodríguez</div>
<div class="user-role">Administrador</div>
</div>
</div>
<div class="user-row">
<div class="avatar-wrapper">
<div class="avatar avatar-md avatar-blue">ML</div>
<span class="avatar-status avatar-status-online"></span>
</div>
<div class="user-info">
<div class="user-name">María López</div>
<div class="user-role">Vendedor — Sucursal Centro</div>
</div>
</div>
<div class="user-row">
<div class="avatar-wrapper">
<div class="avatar avatar-md avatar-green">CP</div>
<span class="avatar-status avatar-status-away"></span>
</div>
<div class="user-info">
<div class="user-name">Carlos Pérez</div>
<div class="user-role">Bodeguero</div>
</div>
</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>

View File

@@ -0,0 +1,340 @@
<!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 — Badges & Tags</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); }
.component-row { display: flex; flex-wrap: wrap; gap: var(--space-3); align-items: center; margin-bottom: var(--space-6); }
.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); }
/* ====== Badge Base ====== */
.badge {
display: inline-flex;
align-items: center;
gap: var(--space-1);
padding: 2px var(--space-3);
font-size: var(--text-caption);
font-weight: var(--font-weight-semibold);
letter-spacing: var(--tracking-wide);
text-transform: uppercase;
border-radius: var(--radius-full);
white-space: nowrap;
}
[data-theme="industrial"] .badge {
border-radius: 0;
}
/* Status Badges */
.badge-success {
background: var(--color-success-light);
color: var(--color-success-dark);
}
[data-theme="industrial"] .badge-success {
background: rgba(34, 197, 94, 0.15);
color: var(--color-success);
}
.badge-warning {
background: var(--color-warning-light);
color: var(--color-warning-dark);
}
[data-theme="industrial"] .badge-warning {
background: rgba(234, 179, 8, 0.15);
color: var(--color-warning);
}
.badge-error {
background: var(--color-error-light);
color: var(--color-error-dark);
}
[data-theme="industrial"] .badge-error {
background: rgba(239, 68, 68, 0.15);
color: var(--color-error);
}
.badge-info {
background: var(--color-primary-muted);
color: var(--color-primary);
}
.badge-neutral {
background: var(--color-neutral-200);
color: var(--color-neutral-700);
}
[data-theme="industrial"] .badge-neutral {
background: var(--color-surface-3);
color: var(--color-text-secondary);
}
/* Dot indicator */
.badge-dot::before {
content: '';
width: 6px;
height: 6px;
border-radius: var(--radius-full);
background: currentColor;
}
/* ====== Tags ====== */
.tag {
display: inline-flex;
align-items: center;
gap: var(--space-2);
padding: var(--space-1) var(--space-3);
font-size: var(--text-body-sm);
background: var(--color-bg-elevated);
border: 1px solid var(--color-border);
border-radius: var(--radius-md);
color: var(--color-text-secondary);
cursor: default;
}
[data-theme="industrial"] .tag {
border-radius: 0;
}
.tag-accent {
border-color: var(--color-primary);
color: var(--color-primary);
background: var(--color-primary-muted);
}
/* Removable tag */
.tag-close {
width: 16px;
height: 16px;
display: flex;
align-items: center;
justify-content: center;
border: none;
background: transparent;
color: var(--color-text-muted);
cursor: pointer;
border-radius: var(--radius-full);
font-size: var(--text-caption);
line-height: 1;
transition: var(--transition-fast);
}
.tag-close:hover {
background: var(--color-error);
color: white;
}
/* ====== Labels ====== */
.status-label {
display: inline-flex;
align-items: center;
gap: var(--space-2);
padding: var(--space-2) var(--space-4);
font-size: var(--text-body-sm);
font-weight: var(--font-weight-semibold);
border-radius: var(--radius-md);
border: 1px solid;
}
[data-theme="industrial"] .status-label {
border-radius: 0;
}
.status-label-success {
background: rgba(34, 197, 94, 0.1);
border-color: var(--color-success);
color: var(--color-success);
}
.status-label-warning {
background: rgba(234, 179, 8, 0.1);
border-color: var(--color-warning);
color: var(--color-warning-dark);
}
[data-theme="industrial"] .status-label-warning {
color: var(--color-warning);
}
.status-label-error {
background: rgba(239, 68, 68, 0.1);
border-color: var(--color-error);
color: var(--color-error);
}
.status-label-info {
background: var(--color-primary-muted);
border-color: var(--color-primary);
color: var(--color-primary);
}
/* ====== Count Badge ====== */
.count-badge {
display: inline-flex;
align-items: center;
justify-content: center;
min-width: 20px;
height: 20px;
padding: 0 6px;
background: var(--color-primary);
color: var(--color-text-inverse);
font-size: var(--text-caption);
font-weight: var(--font-weight-bold);
border-radius: var(--radius-full);
}
.count-badge-sm {
min-width: 16px;
height: 16px;
font-size: 10px;
padding: 0 4px;
}
.count-badge-danger {
background: var(--color-error);
color: white;
}
</style>
</head>
<body>
<div class="theme-switcher">
<button class="active" onclick="setTheme('industrial')">🔧 Industrial</button>
<button onclick="setTheme('modern')">⚡ Moderno</button>
</div>
<h1>Badges & Tags</h1>
<p class="subtitle">Status badges, tags removibles y labels para el sistema POS</p>
<!-- Status Badges -->
<section>
<h2>Status Badges</h2>
<div class="label">Indicadores de estado de inventario y pedidos</div>
<div class="component-row">
<span class="badge badge-success">En stock</span>
<span class="badge badge-warning">Bajo stock</span>
<span class="badge badge-error">Agotado</span>
<span class="badge badge-info">Pedido</span>
<span class="badge badge-neutral">Inactivo</span>
</div>
<div class="label">Con indicador de punto</div>
<div class="component-row">
<span class="badge badge-dot badge-success">Disponible</span>
<span class="badge badge-dot badge-warning">Poco stock</span>
<span class="badge badge-dot badge-error">Sin existencia</span>
<span class="badge badge-dot badge-info">En tránsito</span>
<span class="badge badge-dot badge-neutral">Descontinuado</span>
</div>
</section>
<!-- Tags -->
<section>
<h2>Tags</h2>
<div class="label">Tags de categoría y filtro</div>
<div class="component-row">
<span class="tag">Frenos</span>
<span class="tag">Motor</span>
<span class="tag">Suspensión</span>
<span class="tag">Eléctrico</span>
<span class="tag tag-accent">OEM</span>
</div>
<div class="label">Tags removibles (filtros aplicados)</div>
<div class="component-row">
<span class="tag">Toyota <button class="tag-close" title="Eliminar"></button></span>
<span class="tag">2020 <button class="tag-close" title="Eliminar"></button></span>
<span class="tag tag-accent">Corolla <button class="tag-close" title="Eliminar"></button></span>
<span class="tag">Frenos <button class="tag-close" title="Eliminar"></button></span>
</div>
</section>
<!-- Labels -->
<section>
<h2>Status Labels</h2>
<div class="label">Labels de estado con borde (más prominentes)</div>
<div class="component-row">
<span class="status-label status-label-success">✓ Pagado</span>
<span class="status-label status-label-warning">⏳ Pendiente</span>
<span class="status-label status-label-error">✕ Cancelado</span>
<span class="status-label status-label-info">↗ Enviado</span>
</div>
</section>
<!-- Count Badges -->
<section>
<h2>Count Badges</h2>
<div class="label">Contadores numéricos para notificaciones y carrito</div>
<div class="component-row">
<span class="count-badge">3</span>
<span class="count-badge">12</span>
<span class="count-badge">99+</span>
<span class="count-badge count-badge-sm">5</span>
<span class="count-badge count-badge-danger">!</span>
</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>

View File

@@ -0,0 +1,458 @@
<!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 — Buttons</title>
<link rel="stylesheet" href="../tokens/tokens.css">
<style>
/* ====== Page Layout ====== */
* { 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);
}
.component-row {
display: flex;
flex-wrap: wrap;
gap: var(--space-4);
align-items: center;
margin-bottom: var(--space-6);
}
.component-row.vertical {
flex-direction: column;
align-items: flex-start;
}
.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);
}
/* ====== Button Base ====== */
.btn {
display: inline-flex;
align-items: center;
justify-content: center;
gap: var(--space-2);
padding: var(--space-3) var(--space-6);
font-family: var(--font-body);
font-size: var(--text-body);
font-weight: var(--font-weight-semibold);
line-height: 1;
border: 2px solid transparent;
border-radius: var(--radius-md);
cursor: pointer;
transition: var(--transition-fast);
text-decoration: none;
white-space: nowrap;
user-select: none;
}
.btn:focus-visible {
outline: none;
box-shadow: var(--shadow-focus);
}
.btn:active {
transform: scale(0.97);
}
.btn:disabled {
opacity: 0.5;
cursor: not-allowed;
transform: none;
}
/* ====== Sizes ====== */
.btn-sm {
padding: var(--space-2) var(--space-4);
font-size: var(--text-body-sm);
}
.btn-lg {
padding: var(--space-4) var(--space-8);
font-size: var(--text-body-lg);
}
.btn-xl {
padding: var(--space-5) var(--space-10);
font-size: var(--text-h5);
}
/* ====== Primary ====== */
.btn-primary {
background: var(--btn-primary-bg);
color: var(--btn-primary-text);
border-color: var(--btn-primary-border);
}
.btn-primary:hover:not(:disabled) {
background: var(--btn-primary-bg-hover);
}
.btn-primary:active:not(:disabled) {
background: var(--btn-primary-bg-active);
}
/* Industrial clip-path on primary buttons */
[data-theme="industrial"] .btn-primary {
clip-path: polygon(0 0, calc(100% - 10px) 0, 100% 10px, 100% 100%, 0 100%);
border-radius: 0;
}
/* ====== Secondary ====== */
.btn-secondary {
background: var(--btn-secondary-bg);
color: var(--btn-secondary-text);
border-color: var(--btn-secondary-border);
}
.btn-secondary:hover:not(:disabled) {
background: var(--btn-secondary-bg-hover);
}
/* ====== Danger ====== */
.btn-danger {
background: var(--btn-danger-bg);
color: var(--btn-danger-text);
border-color: transparent;
}
.btn-danger:hover:not(:disabled) {
background: var(--color-error-dark);
}
[data-theme="industrial"] .btn-danger {
clip-path: polygon(0 0, calc(100% - 10px) 0, 100% 10px, 100% 100%, 0 100%);
border-radius: 0;
}
/* ====== Ghost ====== */
.btn-ghost {
background: var(--btn-ghost-bg);
color: var(--btn-ghost-text);
border-color: var(--btn-ghost-border);
}
.btn-ghost:hover:not(:disabled) {
background: var(--color-surface-2);
}
/* ====== Icon Button ====== */
.btn-icon {
display: inline-flex;
align-items: center;
justify-content: center;
width: 40px;
height: 40px;
padding: 0;
border: 1px solid var(--color-border);
background: var(--color-bg-elevated);
color: var(--color-text-secondary);
border-radius: var(--radius-md);
cursor: pointer;
transition: var(--transition-fast);
font-size: 18px;
}
.btn-icon:hover:not(:disabled) {
background: var(--color-primary-muted);
color: var(--color-primary);
border-color: var(--color-primary);
}
.btn-icon:focus-visible {
outline: none;
box-shadow: var(--shadow-focus);
}
.btn-icon.btn-icon-sm {
width: 32px;
height: 32px;
font-size: 14px;
}
.btn-icon.btn-icon-lg {
width: 48px;
height: 48px;
font-size: 22px;
}
/* ====== Button Group ====== */
.btn-group {
display: inline-flex;
}
.btn-group .btn {
border-radius: 0;
}
.btn-group .btn:first-child {
border-radius: var(--radius-md) 0 0 var(--radius-md);
}
.btn-group .btn:last-child {
border-radius: 0 var(--radius-md) var(--radius-md) 0;
}
.btn-group .btn + .btn {
margin-left: -2px;
}
/* ====== Loading State ====== */
.btn-loading {
position: relative;
color: transparent !important;
pointer-events: none;
}
.btn-loading::after {
content: '';
position: absolute;
width: 16px;
height: 16px;
border: 2px solid currentColor;
border-right-color: transparent;
border-radius: var(--radius-full);
animation: spin 0.6s linear infinite;
}
.btn-primary.btn-loading::after {
border-color: var(--btn-primary-text);
border-right-color: transparent;
}
@keyframes spin {
to { transform: rotate(360deg); }
}
/* ====== Full Width ====== */
.btn-block {
width: 100%;
}
</style>
</head>
<body>
<!-- Theme Switcher -->
<div class="theme-switcher">
<button class="active" onclick="setTheme('industrial')">Industrial Robusto</button>
<button onclick="setTheme('modern')">Tecnico Moderno</button>
</div>
<h1>Buttons</h1>
<p class="subtitle">Componentes de boton para Nexus Autoparts POS. Todos los estilos, tamanos y estados.</p>
<!-- Primary Buttons -->
<section>
<h2>Primary Button</h2>
<p class="label">Accion principal — confirmar venta, agregar producto, guardar</p>
<div class="component-row">
<button class="btn btn-primary btn-sm">Pequeno</button>
<button class="btn btn-primary">Normal</button>
<button class="btn btn-primary btn-lg">Grande</button>
<button class="btn btn-primary btn-xl">Extra Grande</button>
</div>
<div class="component-row">
<button class="btn btn-primary" disabled>Deshabilitado</button>
<button class="btn btn-primary btn-loading">Cargando</button>
</div>
<div class="component-row">
<button class="btn btn-primary btn-block">Boton Full Width — Confirmar Venta</button>
</div>
</section>
<!-- Secondary Buttons -->
<section>
<h2>Secondary Button</h2>
<p class="label">Accion secundaria — cancelar, ver detalles, filtrar</p>
<div class="component-row">
<button class="btn btn-secondary btn-sm">Pequeno</button>
<button class="btn btn-secondary">Normal</button>
<button class="btn btn-secondary btn-lg">Grande</button>
</div>
<div class="component-row">
<button class="btn btn-secondary" disabled>Deshabilitado</button>
</div>
</section>
<!-- Danger Buttons -->
<section>
<h2>Danger Button</h2>
<p class="label">Accion destructiva — eliminar, cancelar venta, borrar cliente</p>
<div class="component-row">
<button class="btn btn-danger btn-sm">Eliminar</button>
<button class="btn btn-danger">Cancelar Venta</button>
<button class="btn btn-danger btn-lg">Borrar Inventario</button>
</div>
<div class="component-row">
<button class="btn btn-danger" disabled>Deshabilitado</button>
</div>
</section>
<!-- Ghost Buttons -->
<section>
<h2>Ghost Button</h2>
<p class="label">Accion terciaria — enlaces, acciones sutiles, navegacion</p>
<div class="component-row">
<button class="btn btn-ghost btn-sm">Pequeno</button>
<button class="btn btn-ghost">Normal</button>
<button class="btn btn-ghost btn-lg">Grande</button>
</div>
<div class="component-row">
<button class="btn btn-ghost" disabled>Deshabilitado</button>
</div>
</section>
<!-- Icon Buttons -->
<section>
<h2>Icon Button</h2>
<p class="label">Acciones con icono — editar, eliminar, configuracion, carrito</p>
<div class="component-row">
<button class="btn-icon btn-icon-sm" title="Editar">&#9998;</button>
<button class="btn-icon" title="Eliminar">&#10005;</button>
<button class="btn-icon btn-icon-lg" title="Carrito">&#128722;</button>
<button class="btn-icon" title="Configuracion">&#9881;</button>
<button class="btn-icon" title="Buscar">&#128269;</button>
<button class="btn-icon" title="Imprimir">&#128424;</button>
</div>
<div class="component-row">
<button class="btn-icon" disabled title="Deshabilitado">&#10005;</button>
</div>
</section>
<!-- Button with Icon + Text -->
<section>
<h2>Button con Icono + Texto</h2>
<p class="label">Combinacion de icono y texto para acciones comunes en POS</p>
<div class="component-row">
<button class="btn btn-primary"><span>&#10010;</span> Agregar Producto</button>
<button class="btn btn-secondary"><span>&#128269;</span> Buscar Parte</button>
<button class="btn btn-danger"><span>&#128465;</span> Eliminar</button>
<button class="btn btn-ghost"><span>&#128424;</span> Imprimir Ticket</button>
</div>
</section>
<!-- Button Group -->
<section>
<h2>Button Group</h2>
<p class="label">Grupo de botones para acciones relacionadas — vistas, filtros</p>
<div class="component-row">
<div class="btn-group">
<button class="btn btn-secondary">Lista</button>
<button class="btn btn-primary">Grid</button>
<button class="btn btn-secondary">Tabla</button>
</div>
</div>
<div class="component-row">
<div class="btn-group">
<button class="btn btn-ghost btn-sm">Hoy</button>
<button class="btn btn-ghost btn-sm">Semana</button>
<button class="btn btn-ghost btn-sm">Mes</button>
<button class="btn btn-ghost btn-sm">Ano</button>
</div>
</div>
</section>
<!-- Practical POS Examples -->
<section>
<h2>Ejemplos POS</h2>
<p class="label">Combinaciones reales de la interfaz del punto de venta</p>
<div class="component-row" style="background: var(--color-bg-elevated); padding: var(--space-6); border-radius: var(--radius-lg); border: 1px solid var(--color-border); width: 100%;">
<div style="display: flex; gap: var(--space-3); width: 100%; justify-content: flex-end;">
<button class="btn btn-ghost">Cancelar</button>
<button class="btn btn-secondary">Guardar Borrador</button>
<button class="btn btn-primary btn-lg">Cobrar $1,250.00</button>
</div>
</div>
<div class="component-row" style="background: var(--color-bg-elevated); padding: var(--space-6); border-radius: var(--radius-lg); border: 1px solid var(--color-border); width: 100%;">
<div style="display: flex; gap: var(--space-3); width: 100%; align-items: center;">
<button class="btn btn-primary"><span>&#10010;</span> Nueva Venta</button>
<button class="btn btn-secondary"><span>&#128269;</span> Buscar Cliente</button>
<div style="flex: 1;"></div>
<button class="btn-icon" title="Filtros">&#9776;</button>
<button class="btn-icon" title="Exportar">&#128230;</button>
</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.toLowerCase().includes(theme === 'industrial' ? 'industrial' : 'tecnico'));
});
}
</script>
</body>
</html>

View File

@@ -0,0 +1,489 @@
<!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 — Cards</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-text {
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-3);
}
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: var(--space-6);
}
/* ====== Card Base ====== */
.card {
background: var(--color-bg-elevated);
border: 1px solid var(--color-border);
border-radius: var(--radius-lg);
overflow: hidden;
transition: var(--transition-normal);
}
.card:hover {
box-shadow: var(--shadow-md);
border-color: var(--color-border-strong);
}
[data-theme="industrial"] .card {
border-radius: 0;
clip-path: polygon(0 0, calc(100% - 16px) 0, 100% 16px, 100% 100%, 0 100%);
}
.card-body { padding: var(--space-5); }
.card-footer {
padding: var(--space-3) var(--space-5);
border-top: 1px solid var(--color-border);
display: flex; align-items: center; justify-content: space-between;
}
/* ====== Product Card ====== */
.product-card .product-image {
width: 100%; height: 180px;
background: var(--color-surface-2);
display: flex; align-items: center; justify-content: center;
font-size: 48px; color: var(--color-text-muted);
}
.product-card .product-info { padding: var(--space-4) var(--space-5); }
.product-card .product-category {
font-size: var(--text-caption); text-transform: uppercase;
letter-spacing: var(--tracking-wider); color: var(--color-primary);
font-weight: var(--font-weight-semibold); margin-bottom: var(--space-1);
}
.product-card .product-name {
font-family: var(--font-heading);
font-size: var(--text-h5); font-weight: var(--heading-weight-secondary);
margin-bottom: var(--space-2); line-height: var(--leading-h5);
}
.product-card .product-sku {
font-family: var(--font-mono); font-size: var(--text-caption);
color: var(--color-text-muted); margin-bottom: var(--space-3);
}
.product-card .product-compat {
display: flex; flex-wrap: wrap; gap: var(--space-1); margin-bottom: var(--space-3);
}
.product-card .product-compat .compat-tag {
font-size: 11px; padding: 2px var(--space-2);
background: var(--color-primary-muted); color: var(--color-primary);
border-radius: var(--radius-sm); font-weight: var(--font-weight-semibold);
}
.product-card .product-pricing {
display: flex; align-items: baseline; gap: var(--space-2);
padding: var(--space-3) var(--space-5);
border-top: 1px solid var(--color-border);
}
.product-card .product-price {
font-family: var(--font-mono); font-size: var(--text-h4);
font-weight: var(--font-weight-bold); color: var(--color-text-accent);
}
.product-card .product-price-old {
font-family: var(--font-mono); font-size: var(--text-body-sm);
color: var(--color-text-muted); text-decoration: line-through;
}
.product-card .product-stock {
margin-left: auto; font-size: var(--text-caption);
font-weight: var(--font-weight-semibold);
}
.stock-ok { color: var(--color-success); }
.stock-low { color: var(--color-warning); }
.stock-out { color: var(--color-error); }
.product-card .product-actions {
padding: var(--space-3) var(--space-5);
border-top: 1px solid var(--color-border);
display: flex; gap: var(--space-2);
}
.product-card .product-actions .btn {
flex: 1;
}
/* ====== Client Card ====== */
.client-card .client-header {
display: flex; align-items: center; gap: var(--space-4);
padding: var(--space-5);
}
.client-card .client-avatar {
width: 52px; height: 52px;
background: var(--color-primary);
color: var(--color-text-inverse);
border-radius: var(--radius-full);
display: flex; align-items: center; justify-content: center;
font-family: var(--font-heading); font-size: var(--text-h5);
font-weight: var(--heading-weight-primary);
flex-shrink: 0;
}
[data-theme="industrial"] .client-card .client-avatar {
border-radius: var(--radius-sm);
}
.client-card .client-name {
font-family: var(--font-heading);
font-size: var(--text-h5); font-weight: var(--heading-weight-secondary);
}
.client-card .client-type {
font-size: var(--text-caption); color: var(--color-text-muted);
text-transform: uppercase; letter-spacing: var(--tracking-wider);
}
.client-card .client-stats {
display: grid; grid-template-columns: repeat(3, 1fr);
border-top: 1px solid var(--color-border);
}
.client-card .client-stat {
padding: var(--space-3); text-align: center;
border-right: 1px solid var(--color-border);
}
.client-card .client-stat:last-child { border-right: none; }
.client-card .stat-value {
font-family: var(--font-mono); font-size: var(--text-body-lg);
font-weight: var(--font-weight-bold); color: var(--color-text-accent);
}
.client-card .stat-label {
font-size: var(--text-caption); color: var(--color-text-muted);
}
.client-card .client-actions {
padding: var(--space-3) var(--space-5);
border-top: 1px solid var(--color-border);
display: flex; gap: var(--space-2); justify-content: flex-end;
}
/* ====== Summary / Dashboard Card ====== */
.summary-card .card-body {
display: flex; align-items: center; gap: var(--space-4);
}
.summary-card .summary-icon {
width: 56px; height: 56px;
background: var(--color-primary-muted);
color: var(--color-primary);
border-radius: var(--radius-md);
display: flex; align-items: center; justify-content: center;
font-size: 28px; flex-shrink: 0;
}
[data-theme="modern"] .summary-card .summary-icon {
border-radius: var(--radius-lg);
}
.summary-card .summary-content { flex: 1; }
.summary-card .summary-label {
font-size: var(--text-body-sm); color: var(--color-text-muted);
margin-bottom: var(--space-1);
}
.summary-card .summary-value {
font-family: var(--font-heading); font-size: var(--text-h3);
font-weight: var(--heading-weight-primary);
line-height: 1;
}
.summary-card .summary-change {
font-size: var(--text-caption); margin-top: var(--space-1);
font-weight: var(--font-weight-semibold);
}
.summary-card .summary-change.positive { color: var(--color-success); }
.summary-card .summary-change.negative { color: var(--color-error); }
/* ====== Buttons inside cards ====== */
.btn {
display: inline-flex; align-items: center; justify-content: center;
gap: var(--space-2);
padding: var(--space-2) var(--space-4);
font-family: var(--font-body); font-size: var(--text-body-sm);
font-weight: var(--font-weight-semibold);
border: 2px solid transparent; border-radius: var(--radius-md);
cursor: pointer; transition: var(--transition-fast);
text-decoration: none; white-space: nowrap;
}
.btn-primary {
background: var(--btn-primary-bg); color: var(--btn-primary-text);
}
.btn-primary:hover { background: var(--btn-primary-bg-hover); }
.btn-secondary {
background: var(--btn-secondary-bg); color: var(--btn-secondary-text);
border-color: var(--btn-secondary-border);
}
.btn-secondary:hover { background: var(--btn-secondary-bg-hover); }
.btn-ghost {
background: var(--btn-ghost-bg); color: var(--btn-ghost-text);
border-color: var(--btn-ghost-border);
}
.btn-ghost:hover { background: var(--color-surface-2); }
[data-theme="industrial"] .btn-primary {
clip-path: polygon(0 0, calc(100% - 8px) 0, 100% 8px, 100% 100%, 0 100%);
border-radius: 0;
}
</style>
</head>
<body>
<div class="theme-switcher">
<button class="active" onclick="setTheme('industrial')">Industrial Robusto</button>
<button onclick="setTheme('modern')">Tecnico Moderno</button>
</div>
<h1>Cards</h1>
<p class="subtitle">Tarjetas para producto, cliente y resumen/dashboard del sistema POS.</p>
<!-- Product Cards -->
<section>
<h2>Product Card</h2>
<p class="label-text">Tarjeta de producto para catalogo e inventario</p>
<div class="card-grid">
<!-- Product 1 - In Stock -->
<div class="card product-card">
<div class="product-image">&#9881;</div>
<div class="product-info">
<div class="product-category">Frenos</div>
<div class="product-name">Balatas Ceramicas Brembo</div>
<div class="product-sku">SKU: BRM-BLT-P68064N</div>
<div class="product-compat">
<span class="compat-tag">Nissan Sentra 2019-2024</span>
<span class="compat-tag">Nissan Versa 2020-2024</span>
<span class="compat-tag">+3 mas</span>
</div>
</div>
<div class="product-pricing">
<span class="product-price">$892.00</span>
<span class="product-price-old">$1,050.00</span>
<span class="product-stock stock-ok">24 en stock</span>
</div>
<div class="product-actions">
<button class="btn btn-primary">&#10010; Agregar</button>
<button class="btn btn-ghost">Ver detalle</button>
</div>
</div>
<!-- Product 2 - Low Stock -->
<div class="card product-card">
<div class="product-image">&#128736;</div>
<div class="product-info">
<div class="product-category">Motor</div>
<div class="product-name">Aceite Sintetico Mobil 1 5W-30</div>
<div class="product-sku">SKU: MOB-OIL-5W30-1L</div>
<div class="product-compat">
<span class="compat-tag">Universal</span>
</div>
</div>
<div class="product-pricing">
<span class="product-price">$345.00</span>
<span class="product-stock stock-low">3 en stock</span>
</div>
<div class="product-actions">
<button class="btn btn-primary">&#10010; Agregar</button>
<button class="btn btn-ghost">Ver detalle</button>
</div>
</div>
<!-- Product 3 - Out of Stock -->
<div class="card product-card">
<div class="product-image" style="opacity: 0.4;">&#128295;</div>
<div class="product-info">
<div class="product-category">Suspension</div>
<div class="product-name">Amortiguador Monroe Sensatrac</div>
<div class="product-sku">SKU: MNR-AMT-72321</div>
<div class="product-compat">
<span class="compat-tag">Chevrolet Aveo 2012-2018</span>
</div>
</div>
<div class="product-pricing">
<span class="product-price">$1,650.00</span>
<span class="product-stock stock-out">Sin stock</span>
</div>
<div class="product-actions">
<button class="btn btn-secondary" disabled>Sin stock</button>
<button class="btn btn-ghost">Ver detalle</button>
</div>
</div>
</div>
</section>
<!-- Client Cards -->
<section>
<h2>Client Card</h2>
<p class="label-text">Tarjeta de cliente con informacion y estadisticas</p>
<div class="card-grid">
<!-- Client 1 - Taller -->
<div class="card client-card">
<div class="client-header">
<div class="client-avatar">TM</div>
<div>
<div class="client-name">Taller Mecanico El Rapido</div>
<div class="client-type">Taller &#183; Mayoreo</div>
</div>
</div>
<div class="client-stats">
<div class="client-stat">
<div class="stat-value">$45.2K</div>
<div class="stat-label">Compras</div>
</div>
<div class="client-stat">
<div class="stat-value">127</div>
<div class="stat-label">Ordenes</div>
</div>
<div class="client-stat">
<div class="stat-value">$2.1K</div>
<div class="stat-label">Saldo</div>
</div>
</div>
<div class="client-actions">
<button class="btn btn-ghost">Historial</button>
<button class="btn btn-secondary">Nueva venta</button>
</div>
</div>
<!-- Client 2 - Refaccionaria -->
<div class="card client-card">
<div class="client-header">
<div class="client-avatar">RA</div>
<div>
<div class="client-name">Refacciones Alvarez</div>
<div class="client-type">Refaccionaria &#183; Credito</div>
</div>
</div>
<div class="client-stats">
<div class="client-stat">
<div class="stat-value">$128K</div>
<div class="stat-label">Compras</div>
</div>
<div class="client-stat">
<div class="stat-value">342</div>
<div class="stat-label">Ordenes</div>
</div>
<div class="client-stat">
<div class="stat-value">$8.5K</div>
<div class="stat-label">Saldo</div>
</div>
</div>
<div class="client-actions">
<button class="btn btn-ghost">Historial</button>
<button class="btn btn-secondary">Nueva venta</button>
</div>
</div>
<!-- Client 3 - Publico General -->
<div class="card client-card">
<div class="client-header">
<div class="client-avatar">JL</div>
<div>
<div class="client-name">Jose Luis Martinez</div>
<div class="client-type">Publico General</div>
</div>
</div>
<div class="client-stats">
<div class="client-stat">
<div class="stat-value">$3.4K</div>
<div class="stat-label">Compras</div>
</div>
<div class="client-stat">
<div class="stat-value">8</div>
<div class="stat-label">Ordenes</div>
</div>
<div class="client-stat">
<div class="stat-value">$0</div>
<div class="stat-label">Saldo</div>
</div>
</div>
<div class="client-actions">
<button class="btn btn-ghost">Historial</button>
<button class="btn btn-secondary">Nueva venta</button>
</div>
</div>
</div>
</section>
<!-- Summary / Dashboard Cards -->
<section>
<h2>Summary / Dashboard Card</h2>
<p class="label-text">Tarjetas de resumen para dashboard del dueno</p>
<div class="card-grid" style="grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));">
<div class="card summary-card">
<div class="card-body">
<div class="summary-icon">&#128176;</div>
<div class="summary-content">
<div class="summary-label">Ventas del dia</div>
<div class="summary-value">$24,580</div>
<div class="summary-change positive">+12.3% vs ayer</div>
</div>
</div>
</div>
<div class="card summary-card">
<div class="card-body">
<div class="summary-icon">&#128230;</div>
<div class="summary-content">
<div class="summary-label">Productos vendidos</div>
<div class="summary-value">147</div>
<div class="summary-change positive">+8 vs ayer</div>
</div>
</div>
</div>
<div class="card summary-card">
<div class="card-body">
<div class="summary-icon">&#128100;</div>
<div class="summary-content">
<div class="summary-label">Clientes atendidos</div>
<div class="summary-value">32</div>
<div class="summary-change negative">-5 vs ayer</div>
</div>
</div>
</div>
<div class="card summary-card">
<div class="card-body">
<div class="summary-icon">&#9888;</div>
<div class="summary-content">
<div class="summary-label">Productos stock bajo</div>
<div class="summary-value">18</div>
<div class="summary-change negative">+3 nuevos</div>
</div>
</div>
</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.toLowerCase().includes(theme === 'industrial' ? 'industrial' : 'tecnico'));
});
}
</script>
</body>
</html>

View File

@@ -0,0 +1,268 @@
<!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 — Chips</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-row { display: flex; flex-wrap: wrap; gap: var(--space-3); align-items: center; margin-bottom: var(--space-6); }
/* ====== Filter Chips ====== */
.chip {
display: inline-flex;
align-items: center;
gap: var(--space-2);
padding: var(--space-2) var(--space-4);
background: var(--color-bg-elevated);
border: 1px solid var(--color-border);
border-radius: var(--radius-full);
font-family: var(--font-body);
font-size: var(--text-body-sm);
color: var(--color-text-secondary);
cursor: pointer;
transition: var(--transition-fast);
user-select: none;
}
[data-theme="industrial"] .chip {
border-radius: 0;
}
.chip:hover {
border-color: var(--color-primary);
color: var(--color-primary);
}
.chip.active {
background: var(--color-primary);
border-color: var(--color-primary);
color: var(--color-text-inverse);
}
.chip .chip-icon {
font-size: var(--text-body-sm);
}
.chip .chip-close {
display: inline-flex;
align-items: center;
justify-content: center;
width: 16px;
height: 16px;
border-radius: var(--radius-full);
font-size: 10px;
transition: var(--transition-fast);
line-height: 1;
}
.chip.active .chip-close:hover {
background: rgba(0,0,0,0.2);
}
/* ====== Action Chips ====== */
.action-chip {
display: inline-flex;
align-items: center;
gap: var(--space-2);
padding: var(--space-2) var(--space-4);
background: transparent;
border: 1px solid var(--color-border);
border-radius: var(--radius-full);
font-family: var(--font-body);
font-size: var(--text-body-sm);
color: var(--color-text-secondary);
cursor: pointer;
transition: var(--transition-fast);
}
[data-theme="industrial"] .action-chip {
border-radius: 0;
}
.action-chip:hover {
background: var(--color-primary-muted);
border-color: var(--color-primary);
color: var(--color-primary);
}
.action-chip .action-icon {
font-size: var(--text-body);
}
/* ====== Choice Chips ====== */
.choice-chip {
display: inline-flex;
align-items: center;
gap: var(--space-2);
padding: var(--space-2) var(--space-4);
background: var(--color-bg-elevated);
border: 2px solid var(--color-border);
border-radius: var(--radius-md);
font-family: var(--font-body);
font-size: var(--text-body-sm);
color: var(--color-text-secondary);
cursor: pointer;
transition: var(--transition-fast);
font-weight: var(--font-weight-semibold);
}
[data-theme="industrial"] .choice-chip {
border-radius: 0;
}
.choice-chip:hover {
border-color: var(--color-primary);
}
.choice-chip.selected {
background: var(--color-primary-muted);
border-color: var(--color-primary);
color: var(--color-primary);
}
.choice-chip.selected::before {
content: '✓';
font-size: 12px;
}
/* Applied filters bar */
.filters-bar {
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);
flex-wrap: wrap;
}
[data-theme="industrial"] .filters-bar { border-radius: 0; }
.filters-label {
font-size: var(--text-body-sm);
color: var(--color-text-muted);
font-weight: var(--font-weight-semibold);
}
.filters-clear {
font-size: var(--text-body-sm);
color: var(--color-primary);
cursor: pointer;
background: none;
border: none;
font-family: var(--font-body);
margin-left: auto;
}
.filters-clear:hover { text-decoration: underline; }
</style>
</head>
<body>
<div class="theme-switcher">
<button class="active" onclick="setTheme('industrial')">🔧 Industrial</button>
<button onclick="setTheme('modern')">⚡ Moderno</button>
</div>
<h1>Chips</h1>
<p class="subtitle">Filter chips, action chips y choice chips para el sistema POS</p>
<!-- Filter Chips -->
<section>
<h2>Filter Chips</h2>
<div class="label">Filtros de categoría en catálogo</div>
<div class="component-row">
<span class="chip active">Todos <span class="chip-close"></span></span>
<span class="chip">🔧 Frenos</span>
<span class="chip active">⚙️ Motor <span class="chip-close"></span></span>
<span class="chip">🔌 Eléctrico</span>
<span class="chip">🏎️ Suspensión</span>
<span class="chip">💧 Lubricantes</span>
<span class="chip">🔩 Tornillería</span>
</div>
<div class="label">Filtros de marca</div>
<div class="component-row">
<span class="chip active">Brembo <span class="chip-close"></span></span>
<span class="chip">Bosch</span>
<span class="chip">Denso</span>
<span class="chip active">Wagner <span class="chip-close"></span></span>
<span class="chip">ACDelco</span>
<span class="chip">NGK</span>
<span class="chip">Monroe</span>
</div>
</section>
<!-- Action Chips -->
<section>
<h2>Action Chips</h2>
<div class="label">Acciones rápidas sobre un producto</div>
<div class="component-row">
<button class="action-chip"><span class="action-icon">🛒</span> Agregar a venta</button>
<button class="action-chip"><span class="action-icon">📋</span> Crear cotización</button>
<button class="action-chip"><span class="action-icon">📦</span> Pedir a proveedor</button>
<button class="action-chip"><span class="action-icon">🖨️</span> Imprimir etiqueta</button>
<button class="action-chip"><span class="action-icon">📤</span> Compartir</button>
</div>
</section>
<!-- Choice Chips -->
<section>
<h2>Choice Chips</h2>
<div class="label">Selección de tipo de parte (OEM vs Aftermarket)</div>
<div class="component-row">
<span class="choice-chip selected">OEM Original</span>
<span class="choice-chip">Aftermarket</span>
<span class="choice-chip">Remanufacturado</span>
</div>
<div class="label">Selección de rango de precio</div>
<div class="component-row">
<span class="choice-chip">$0 - $500</span>
<span class="choice-chip selected">$500 - $1,500</span>
<span class="choice-chip">$1,500 - $5,000</span>
<span class="choice-chip">$5,000+</span>
</div>
</section>
<!-- Applied Filters Bar -->
<section>
<h2>Barra de Filtros Aplicados</h2>
<div class="label">Resumen de filtros activos en el catálogo</div>
<div class="filters-bar">
<span class="filters-label">Filtros:</span>
<span class="chip active">Toyota <span class="chip-close"></span></span>
<span class="chip active">Corolla 2020 <span class="chip-close"></span></span>
<span class="chip active">Frenos <span class="chip-close"></span></span>
<span class="chip active">OEM <span class="chip-close"></span></span>
<button class="filters-clear">Limpiar todo</button>
</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>

View File

@@ -0,0 +1,485 @@
<!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 — Date/Time Pickers</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-row { display: flex; flex-wrap: wrap; gap: var(--space-6); align-items: flex-start; margin-bottom: var(--space-6); }
/* ====== Date Input ====== */
.date-input-group {
display: flex;
flex-direction: column;
gap: var(--space-1);
}
.date-label {
font-size: var(--text-body-sm);
font-weight: var(--font-weight-semibold);
color: var(--color-text-secondary);
}
.date-input {
padding: var(--space-3) var(--space-4);
background: var(--color-bg-elevated);
border: 1px solid var(--color-border);
border-radius: var(--radius-md);
color: var(--color-text-primary);
font-family: var(--font-body);
font-size: var(--text-body-sm);
transition: var(--transition-fast);
min-width: 200px;
}
[data-theme="industrial"] .date-input { border-radius: 0; }
.date-input:focus {
outline: none;
border-color: var(--color-primary);
box-shadow: var(--shadow-focus);
}
/* ====== Calendar Widget ====== */
.calendar {
background: var(--color-bg-elevated);
border: 1px solid var(--color-border);
border-radius: var(--radius-md);
box-shadow: var(--shadow-lg);
padding: var(--space-4);
max-width: 320px;
}
[data-theme="industrial"] .calendar {
border-radius: 0;
clip-path: polygon(0 0, calc(100% - 12px) 0, 100% 12px, 100% 100%, 0 100%);
}
.calendar-header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: var(--space-4);
}
.calendar-title {
font-family: var(--font-heading);
font-size: var(--text-body);
font-weight: var(--heading-weight-secondary);
color: var(--color-text-primary);
}
.calendar-nav {
display: flex;
gap: var(--space-1);
}
.calendar-nav-btn {
width: 28px;
height: 28px;
display: flex;
align-items: center;
justify-content: center;
background: transparent;
border: 1px solid var(--color-border);
border-radius: var(--radius-sm);
color: var(--color-text-muted);
cursor: pointer;
font-size: var(--text-caption);
transition: var(--transition-fast);
}
[data-theme="industrial"] .calendar-nav-btn { border-radius: 0; }
.calendar-nav-btn:hover {
border-color: var(--color-primary);
color: var(--color-primary);
}
.calendar-grid {
display: grid;
grid-template-columns: repeat(7, 1fr);
gap: 2px;
text-align: center;
}
.calendar-day-name {
font-size: var(--text-caption);
color: var(--color-text-muted);
font-weight: var(--font-weight-semibold);
text-transform: uppercase;
padding: var(--space-2);
}
.calendar-day {
width: 36px;
height: 36px;
display: flex;
align-items: center;
justify-content: center;
border-radius: var(--radius-md);
font-size: var(--text-body-sm);
color: var(--color-text-secondary);
cursor: pointer;
transition: var(--transition-fast);
border: none;
background: transparent;
font-family: var(--font-body);
}
[data-theme="industrial"] .calendar-day { border-radius: 0; }
.calendar-day:hover {
background: var(--color-primary-muted);
color: var(--color-primary);
}
.calendar-day.today {
border: 1px solid var(--color-primary);
color: var(--color-primary);
font-weight: var(--font-weight-semibold);
}
.calendar-day.selected {
background: var(--color-primary);
color: var(--color-text-inverse);
font-weight: var(--font-weight-semibold);
}
.calendar-day.range {
background: var(--color-primary-muted);
border-radius: 0;
}
.calendar-day.range-start {
background: var(--color-primary);
color: var(--color-text-inverse);
border-radius: var(--radius-md) 0 0 var(--radius-md);
}
.calendar-day.range-end {
background: var(--color-primary);
color: var(--color-text-inverse);
border-radius: 0 var(--radius-md) var(--radius-md) 0;
}
[data-theme="industrial"] .calendar-day.range-start,
[data-theme="industrial"] .calendar-day.range-end {
border-radius: 0;
}
.calendar-day.disabled {
color: var(--color-text-disabled);
cursor: not-allowed;
}
.calendar-day.other-month {
color: var(--color-text-disabled);
opacity: 0.5;
}
.calendar-footer {
display: flex;
justify-content: space-between;
align-items: center;
margin-top: var(--space-3);
padding-top: var(--space-3);
border-top: 1px solid var(--color-border);
}
.calendar-footer-btn {
padding: var(--space-1) var(--space-3);
font-family: var(--font-body);
font-size: var(--text-caption);
font-weight: var(--font-weight-semibold);
border: none;
border-radius: var(--radius-sm);
cursor: pointer;
transition: var(--transition-fast);
}
[data-theme="industrial"] .calendar-footer-btn { border-radius: 0; }
.calendar-today-btn {
background: transparent;
color: var(--color-primary);
}
.calendar-apply-btn {
background: var(--color-primary);
color: var(--color-text-inverse);
}
/* ====== Date Range ====== */
.date-range-wrapper {
display: flex;
align-items: center;
gap: var(--space-3);
}
.date-range-separator {
color: var(--color-text-muted);
font-size: var(--text-body-sm);
}
/* Quick presets */
.date-presets {
display: flex;
flex-wrap: wrap;
gap: var(--space-2);
}
.date-preset {
padding: var(--space-2) var(--space-3);
background: var(--color-bg-elevated);
border: 1px solid var(--color-border);
border-radius: var(--radius-md);
font-family: var(--font-body);
font-size: var(--text-caption);
color: var(--color-text-secondary);
cursor: pointer;
transition: var(--transition-fast);
}
[data-theme="industrial"] .date-preset { border-radius: 0; }
.date-preset:hover {
border-color: var(--color-primary);
color: var(--color-primary);
}
.date-preset.active {
background: var(--color-primary);
color: var(--color-text-inverse);
border-color: var(--color-primary);
}
</style>
</head>
<body>
<div class="theme-switcher">
<button class="active" onclick="setTheme('industrial')">🔧 Industrial</button>
<button onclick="setTheme('modern')">⚡ Moderno</button>
</div>
<h1>Date / Time Pickers</h1>
<p class="subtitle">Selectores de fecha y hora para reportes, cortes de caja y filtros</p>
<!-- Date Inputs -->
<section>
<h2>Inputs de Fecha y Hora</h2>
<div class="label">Campos nativos con estilo del design system</div>
<div class="component-row">
<div class="date-input-group">
<span class="date-label">Fecha</span>
<input type="date" class="date-input" value="2024-03-15">
</div>
<div class="date-input-group">
<span class="date-label">Hora</span>
<input type="time" class="date-input" value="14:30">
</div>
<div class="date-input-group">
<span class="date-label">Fecha y hora</span>
<input type="datetime-local" class="date-input" value="2024-03-15T14:30">
</div>
</div>
</section>
<!-- Date Range -->
<section>
<h2>Rango de Fechas</h2>
<div class="label">Para reportes y filtros de contabilidad</div>
<div class="date-range-wrapper" style="margin-bottom: var(--space-4);">
<div class="date-input-group">
<span class="date-label">Desde</span>
<input type="date" class="date-input" value="2024-03-01">
</div>
<span class="date-range-separator"></span>
<div class="date-input-group">
<span class="date-label">Hasta</span>
<input type="date" class="date-input" value="2024-03-15">
</div>
</div>
<div class="label">Presets rápidos</div>
<div class="date-presets">
<button class="date-preset">Hoy</button>
<button class="date-preset">Ayer</button>
<button class="date-preset active">Esta semana</button>
<button class="date-preset">Este mes</button>
<button class="date-preset">Mes pasado</button>
<button class="date-preset">Este año</button>
<button class="date-preset">Personalizado</button>
</div>
</section>
<!-- Calendar Widget -->
<section>
<h2>Calendario — Selección Simple</h2>
<div class="label">Widget de calendario para seleccionar una fecha</div>
<div class="calendar">
<div class="calendar-header">
<div class="calendar-nav">
<button class="calendar-nav-btn"></button>
</div>
<span class="calendar-title">Marzo 2024</span>
<div class="calendar-nav">
<button class="calendar-nav-btn"></button>
</div>
</div>
<div class="calendar-grid">
<span class="calendar-day-name">Lu</span>
<span class="calendar-day-name">Ma</span>
<span class="calendar-day-name">Mi</span>
<span class="calendar-day-name">Ju</span>
<span class="calendar-day-name">Vi</span>
<span class="calendar-day-name"></span>
<span class="calendar-day-name">Do</span>
<button class="calendar-day other-month">26</button>
<button class="calendar-day other-month">27</button>
<button class="calendar-day other-month">28</button>
<button class="calendar-day other-month">29</button>
<button class="calendar-day">1</button>
<button class="calendar-day">2</button>
<button class="calendar-day">3</button>
<button class="calendar-day">4</button>
<button class="calendar-day">5</button>
<button class="calendar-day">6</button>
<button class="calendar-day">7</button>
<button class="calendar-day">8</button>
<button class="calendar-day">9</button>
<button class="calendar-day">10</button>
<button class="calendar-day">11</button>
<button class="calendar-day">12</button>
<button class="calendar-day">13</button>
<button class="calendar-day">14</button>
<button class="calendar-day selected">15</button>
<button class="calendar-day">16</button>
<button class="calendar-day">17</button>
<button class="calendar-day">18</button>
<button class="calendar-day">19</button>
<button class="calendar-day">20</button>
<button class="calendar-day">21</button>
<button class="calendar-day">22</button>
<button class="calendar-day">23</button>
<button class="calendar-day">24</button>
<button class="calendar-day">25</button>
<button class="calendar-day">26</button>
<button class="calendar-day">27</button>
<button class="calendar-day">28</button>
<button class="calendar-day">29</button>
<button class="calendar-day">30</button>
<button class="calendar-day">31</button>
</div>
<div class="calendar-footer">
<button class="calendar-footer-btn calendar-today-btn">Hoy</button>
<button class="calendar-footer-btn calendar-apply-btn">Aplicar</button>
</div>
</div>
</section>
<!-- Calendar Range -->
<section>
<h2>Calendario — Rango de Fechas</h2>
<div class="label">Selección de rango para reportes de ventas</div>
<div class="calendar">
<div class="calendar-header">
<div class="calendar-nav">
<button class="calendar-nav-btn"></button>
</div>
<span class="calendar-title">Marzo 2024</span>
<div class="calendar-nav">
<button class="calendar-nav-btn"></button>
</div>
</div>
<div class="calendar-grid">
<span class="calendar-day-name">Lu</span>
<span class="calendar-day-name">Ma</span>
<span class="calendar-day-name">Mi</span>
<span class="calendar-day-name">Ju</span>
<span class="calendar-day-name">Vi</span>
<span class="calendar-day-name"></span>
<span class="calendar-day-name">Do</span>
<button class="calendar-day other-month">26</button>
<button class="calendar-day other-month">27</button>
<button class="calendar-day other-month">28</button>
<button class="calendar-day other-month">29</button>
<button class="calendar-day">1</button>
<button class="calendar-day">2</button>
<button class="calendar-day">3</button>
<button class="calendar-day">4</button>
<button class="calendar-day">5</button>
<button class="calendar-day">6</button>
<button class="calendar-day">7</button>
<button class="calendar-day range-start">8</button>
<button class="calendar-day range">9</button>
<button class="calendar-day range">10</button>
<button class="calendar-day range">11</button>
<button class="calendar-day range">12</button>
<button class="calendar-day range">13</button>
<button class="calendar-day range">14</button>
<button class="calendar-day range-end">15</button>
<button class="calendar-day">16</button>
<button class="calendar-day">17</button>
<button class="calendar-day">18</button>
<button class="calendar-day">19</button>
<button class="calendar-day">20</button>
<button class="calendar-day">21</button>
<button class="calendar-day">22</button>
<button class="calendar-day">23</button>
<button class="calendar-day">24</button>
<button class="calendar-day">25</button>
<button class="calendar-day">26</button>
<button class="calendar-day">27</button>
<button class="calendar-day">28</button>
<button class="calendar-day">29</button>
<button class="calendar-day">30</button>
<button class="calendar-day">31</button>
</div>
<div class="calendar-footer">
<span style="font-size: var(--text-caption); color: var(--color-text-muted);">8 Mar — 15 Mar (8 días)</span>
<button class="calendar-footer-btn calendar-apply-btn">Aplicar</button>
</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>

View File

@@ -0,0 +1,306 @@
<!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 — Dialogs</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); }
/* ====== Dialog Base ====== */
.dialog {
background: var(--color-bg-elevated);
border: 1px solid var(--color-border);
border-radius: var(--radius-lg);
box-shadow: var(--shadow-xl);
max-width: 440px;
width: 100%;
margin-bottom: var(--space-6);
overflow: hidden;
}
[data-theme="industrial"] .dialog {
border-radius: 0;
clip-path: polygon(0 0, calc(100% - 14px) 0, 100% 14px, 100% 100%, 0 100%);
}
.dialog-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: var(--space-4) var(--space-5);
border-bottom: 1px solid var(--color-border);
}
.dialog-title {
font-family: var(--font-heading);
font-size: var(--text-h5);
font-weight: var(--heading-weight-secondary);
color: var(--color-text-primary);
}
.dialog-close {
background: none;
border: none;
color: var(--color-text-muted);
cursor: pointer;
font-size: var(--text-body-lg);
padding: var(--space-1);
border-radius: var(--radius-sm);
transition: var(--transition-fast);
}
.dialog-close:hover {
background: var(--color-surface-2);
color: var(--color-text-primary);
}
.dialog-body {
padding: var(--space-5);
}
.dialog-body p {
font-size: var(--text-body-sm);
color: var(--color-text-secondary);
line-height: var(--leading-body-sm);
margin-bottom: var(--space-3);
}
.dialog-body p:last-child { margin-bottom: 0; }
.dialog-footer {
display: flex;
justify-content: flex-end;
gap: var(--space-3);
padding: var(--space-4) var(--space-5);
border-top: 1px solid var(--color-border);
}
.dialog-btn {
padding: var(--space-2) var(--space-5);
font-family: var(--font-body);
font-size: var(--text-body-sm);
font-weight: var(--font-weight-semibold);
border-radius: var(--radius-md);
cursor: pointer;
transition: var(--transition-fast);
border: 1px solid;
}
[data-theme="industrial"] .dialog-btn { border-radius: 0; }
.dialog-btn-primary {
background: var(--color-primary);
color: var(--color-text-inverse);
border-color: var(--color-primary);
}
.dialog-btn-primary:hover { background: var(--color-primary-hover); }
.dialog-btn-secondary {
background: transparent;
color: var(--color-text-secondary);
border-color: var(--color-border);
}
.dialog-btn-secondary:hover { background: var(--color-surface-2); }
.dialog-btn-danger {
background: var(--color-error);
color: white;
border-color: var(--color-error);
}
.dialog-btn-danger:hover { background: var(--color-error-dark); }
/* ====== Dialog Icon ====== */
.dialog-icon {
width: 48px;
height: 48px;
border-radius: var(--radius-full);
display: flex;
align-items: center;
justify-content: center;
font-size: var(--text-h3);
margin-bottom: var(--space-4);
}
.dialog-icon-warning { background: rgba(234, 179, 8, 0.15); }
.dialog-icon-error { background: rgba(239, 68, 68, 0.15); }
.dialog-icon-success { background: rgba(34, 197, 94, 0.15); }
.dialog-icon-info { background: var(--color-primary-muted); }
/* ====== Prompt Input ====== */
.dialog-input {
width: 100%;
padding: var(--space-3);
background: var(--color-bg-base);
border: 1px solid var(--color-border);
border-radius: var(--radius-md);
color: var(--color-text-primary);
font-family: var(--font-body);
font-size: var(--text-body-sm);
transition: var(--transition-fast);
}
[data-theme="industrial"] .dialog-input { border-radius: 0; }
.dialog-input:focus {
outline: none;
border-color: var(--color-primary);
box-shadow: var(--shadow-focus);
}
.dialog-input-label {
display: block;
font-size: var(--text-body-sm);
color: var(--color-text-secondary);
margin-bottom: var(--space-2);
font-weight: var(--font-weight-semibold);
}
</style>
</head>
<body>
<div class="theme-switcher">
<button class="active" onclick="setTheme('industrial')">🔧 Industrial</button>
<button onclick="setTheme('modern')">⚡ Moderno</button>
</div>
<h1>Dialogs</h1>
<p class="subtitle">Diálogos de confirmación y prompts del sistema POS</p>
<!-- Confirm Delete -->
<section>
<h2>Confirmación de Eliminación</h2>
<div class="label">Confirmar acción destructiva</div>
<div class="dialog">
<div class="dialog-header">
<span class="dialog-title">Eliminar producto</span>
<button class="dialog-close"></button>
</div>
<div class="dialog-body">
<div class="dialog-icon dialog-icon-error"></div>
<p><strong>¿Eliminar "Pastillas de freno Brembo P50 042"?</strong></p>
<p>Esta acción eliminará el producto del catálogo permanentemente. Se perderá el historial de ventas y movimientos asociados.</p>
</div>
<div class="dialog-footer">
<button class="dialog-btn dialog-btn-secondary">Cancelar</button>
<button class="dialog-btn dialog-btn-danger">Eliminar producto</button>
</div>
</div>
</section>
<!-- Confirm Sale -->
<section>
<h2>Confirmación de Venta</h2>
<div class="label">Confirmar cierre de venta</div>
<div class="dialog">
<div class="dialog-header">
<span class="dialog-title">Confirmar venta</span>
<button class="dialog-close"></button>
</div>
<div class="dialog-body">
<div class="dialog-icon dialog-icon-success"></div>
<p><strong>Total de la venta: $4,890.00 MXN</strong></p>
<p>5 productos · Cliente: Juan Rodríguez · Método de pago: Efectivo</p>
<p style="color: var(--color-text-muted);">Se generará ticket e imprimirá automáticamente.</p>
</div>
<div class="dialog-footer">
<button class="dialog-btn dialog-btn-secondary">Revisar</button>
<button class="dialog-btn dialog-btn-primary">Completar venta</button>
</div>
</div>
</section>
<!-- Stock Warning -->
<section>
<h2>Advertencia de Stock</h2>
<div class="label">Alerta al agregar producto sin stock suficiente</div>
<div class="dialog">
<div class="dialog-header">
<span class="dialog-title">Stock insuficiente</span>
<button class="dialog-close"></button>
</div>
<div class="dialog-body">
<div class="dialog-icon dialog-icon-warning"></div>
<p><strong>El producto tiene solo 2 unidades disponibles</strong></p>
<p>Estás intentando agregar 5 unidades de "Filtro de aceite WIX 57060" pero solo hay 2 en existencia.</p>
</div>
<div class="dialog-footer">
<button class="dialog-btn dialog-btn-secondary">Cancelar</button>
<button class="dialog-btn dialog-btn-primary">Agregar 2 disponibles</button>
</div>
</div>
</section>
<!-- Prompt Dialog -->
<section>
<h2>Prompt — Descuento Manual</h2>
<div class="label">Diálogo con entrada de datos</div>
<div class="dialog">
<div class="dialog-header">
<span class="dialog-title">Aplicar descuento</span>
<button class="dialog-close"></button>
</div>
<div class="dialog-body">
<p>Ingresa el porcentaje de descuento a aplicar sobre el subtotal de $4,890.00</p>
<label class="dialog-input-label">Porcentaje de descuento</label>
<input class="dialog-input" type="number" placeholder="Ej: 10" min="0" max="100" value="15">
<p style="margin-top: var(--space-2); color: var(--color-primary); font-weight: var(--font-weight-semibold);">
Nuevo total: $4,156.50 MXN (ahorro: $733.50)
</p>
</div>
<div class="dialog-footer">
<button class="dialog-btn dialog-btn-secondary">Cancelar</button>
<button class="dialog-btn dialog-btn-primary">Aplicar 15%</button>
</div>
</div>
</section>
<!-- PIN Auth Dialog -->
<section>
<h2>Prompt — Autorización PIN</h2>
<div class="label">Requiere PIN del supervisor</div>
<div class="dialog">
<div class="dialog-header">
<span class="dialog-title">Autorización requerida</span>
<button class="dialog-close"></button>
</div>
<div class="dialog-body">
<div class="dialog-icon dialog-icon-info">🔒</div>
<p><strong>Esta acción requiere autorización del supervisor</strong></p>
<p>Ingresa el PIN del supervisor para aplicar un descuento mayor al 10%.</p>
<label class="dialog-input-label">PIN del supervisor</label>
<input class="dialog-input" type="password" placeholder="••••" maxlength="4">
</div>
<div class="dialog-footer">
<button class="dialog-btn dialog-btn-secondary">Cancelar</button>
<button class="dialog-btn dialog-btn-primary">Autorizar</button>
</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>

View File

@@ -0,0 +1,331 @@
<!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 — Dropdowns</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-row { display: flex; flex-wrap: wrap; gap: var(--space-6); align-items: flex-start; margin-bottom: var(--space-6); }
/* ====== Dropdown Menu ====== */
.dropdown-wrapper {
position: relative;
display: inline-block;
}
.dropdown-trigger {
display: inline-flex;
align-items: center;
gap: var(--space-2);
padding: var(--space-3) var(--space-4);
background: var(--color-bg-elevated);
border: 1px solid var(--color-border);
border-radius: var(--radius-md);
color: var(--color-text-primary);
font-family: var(--font-body);
font-size: var(--text-body-sm);
font-weight: var(--font-weight-semibold);
cursor: pointer;
transition: var(--transition-fast);
}
[data-theme="industrial"] .dropdown-trigger { border-radius: 0; }
.dropdown-trigger:hover {
border-color: var(--color-primary);
}
.dropdown-arrow {
font-size: 10px;
transition: var(--transition-fast);
}
.dropdown-menu {
position: absolute;
top: calc(100% + var(--space-1));
left: 0;
min-width: 200px;
background: var(--color-bg-elevated);
border: 1px solid var(--color-border);
border-radius: var(--radius-md);
box-shadow: var(--shadow-lg);
z-index: var(--z-dropdown);
overflow: hidden;
padding: var(--space-1) 0;
}
[data-theme="industrial"] .dropdown-menu {
border-radius: 0;
clip-path: polygon(0 0, calc(100% - 8px) 0, 100% 8px, 100% 100%, 0 100%);
}
.dropdown-item {
display: flex;
align-items: center;
gap: var(--space-3);
padding: var(--space-2) var(--space-4);
font-size: var(--text-body-sm);
color: var(--color-text-secondary);
cursor: pointer;
transition: var(--transition-fast);
border: none;
background: none;
width: 100%;
text-align: left;
font-family: var(--font-body);
}
.dropdown-item:hover {
background: var(--color-primary-muted);
color: var(--color-primary);
}
.dropdown-item.active {
color: var(--color-primary);
font-weight: var(--font-weight-semibold);
}
.dropdown-item.danger {
color: var(--color-error);
}
.dropdown-item.danger:hover {
background: rgba(239, 68, 68, 0.08);
}
.dropdown-item .icon {
width: 18px;
text-align: center;
}
.dropdown-item .shortcut {
margin-left: auto;
font-size: var(--text-caption);
color: var(--color-text-muted);
font-family: var(--font-mono);
}
.dropdown-divider {
height: 1px;
background: var(--color-border);
margin: var(--space-1) 0;
}
.dropdown-header {
padding: var(--space-2) var(--space-4);
font-size: var(--text-caption);
color: var(--color-text-muted);
text-transform: uppercase;
letter-spacing: var(--tracking-widest);
font-weight: var(--font-weight-semibold);
}
/* ====== Select Dropdown ====== */
.select-wrapper {
position: relative;
display: inline-block;
min-width: 200px;
}
.select-custom {
width: 100%;
padding: var(--space-3) var(--space-4);
padding-right: var(--space-10);
background: var(--color-bg-elevated);
border: 1px solid var(--color-border);
border-radius: var(--radius-md);
color: var(--color-text-primary);
font-family: var(--font-body);
font-size: var(--text-body-sm);
cursor: pointer;
appearance: none;
transition: var(--transition-fast);
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%23888' d='M6 8L1 3h10z'/%3E%3C/svg%3E");
background-repeat: no-repeat;
background-position: right 12px center;
}
[data-theme="industrial"] .select-custom { border-radius: 0; }
.select-custom:focus {
border-color: var(--color-primary);
outline: none;
box-shadow: var(--shadow-focus);
}
.select-label {
display: block;
font-size: var(--text-caption);
color: var(--color-text-muted);
margin-bottom: var(--space-1);
font-weight: var(--font-weight-semibold);
}
/* ====== Context Menu ====== */
.context-menu {
min-width: 180px;
background: var(--color-bg-elevated);
border: 1px solid var(--color-border);
border-radius: var(--radius-md);
box-shadow: var(--shadow-lg);
overflow: hidden;
padding: var(--space-1) 0;
}
[data-theme="industrial"] .context-menu {
border-radius: 0;
}
</style>
</head>
<body>
<div class="theme-switcher">
<button class="active" onclick="setTheme('industrial')">🔧 Industrial</button>
<button onclick="setTheme('modern')">⚡ Moderno</button>
</div>
<h1>Dropdowns</h1>
<p class="subtitle">Select menus, dropdown menus y context menus del sistema POS</p>
<!-- Dropdown Menus -->
<section>
<h2>Dropdown Menus</h2>
<div class="label">Menús desplegables de acciones</div>
<div class="component-row">
<!-- Actions Dropdown -->
<div class="dropdown-wrapper">
<button class="dropdown-trigger">
Acciones <span class="dropdown-arrow"></span>
</button>
<div class="dropdown-menu">
<button class="dropdown-item"><span class="icon">📝</span> Editar producto</button>
<button class="dropdown-item"><span class="icon">📋</span> Duplicar</button>
<button class="dropdown-item"><span class="icon">🏷️</span> Cambiar precio</button>
<div class="dropdown-divider"></div>
<button class="dropdown-item"><span class="icon">📤</span> Exportar <span class="shortcut">Ctrl+E</span></button>
<button class="dropdown-item"><span class="icon">🖨️</span> Imprimir <span class="shortcut">Ctrl+P</span></button>
<div class="dropdown-divider"></div>
<button class="dropdown-item danger"><span class="icon">🗑️</span> Eliminar</button>
</div>
</div>
<!-- Sort Dropdown -->
<div class="dropdown-wrapper">
<button class="dropdown-trigger">
Ordenar por <span class="dropdown-arrow"></span>
</button>
<div class="dropdown-menu">
<div class="dropdown-header">Ordenar</div>
<button class="dropdown-item active">Nombre A-Z</button>
<button class="dropdown-item">Nombre Z-A</button>
<button class="dropdown-item">Precio: menor a mayor</button>
<button class="dropdown-item">Precio: mayor a menor</button>
<button class="dropdown-item">Stock: menor a mayor</button>
<button class="dropdown-item">Más reciente</button>
</div>
</div>
<!-- Filter Dropdown -->
<div class="dropdown-wrapper">
<button class="dropdown-trigger">
Filtrar <span class="dropdown-arrow"></span>
</button>
<div class="dropdown-menu">
<div class="dropdown-header">Categoría</div>
<button class="dropdown-item">Frenos</button>
<button class="dropdown-item">Motor</button>
<button class="dropdown-item">Suspensión</button>
<button class="dropdown-item">Eléctrico</button>
<div class="dropdown-divider"></div>
<div class="dropdown-header">Estado</div>
<button class="dropdown-item active">En stock</button>
<button class="dropdown-item">Bajo stock</button>
<button class="dropdown-item">Agotado</button>
</div>
</div>
</div>
</section>
<!-- Select Dropdowns -->
<section>
<h2>Select Dropdowns</h2>
<div class="label">Selectores de formulario nativos con estilo</div>
<div class="component-row">
<div class="select-wrapper">
<span class="select-label">Categoría</span>
<select class="select-custom">
<option>Todas las categorías</option>
<option>Frenos</option>
<option>Motor</option>
<option>Suspensión</option>
<option>Eléctrico</option>
<option>Transmisión</option>
<option>Carrocería</option>
</select>
</div>
<div class="select-wrapper">
<span class="select-label">Proveedor</span>
<select class="select-custom">
<option>Todos los proveedores</option>
<option>Brembo</option>
<option>Wagner</option>
<option>Bosch</option>
<option>Denso</option>
<option>ACDelco</option>
</select>
</div>
<div class="select-wrapper">
<span class="select-label">Sucursal</span>
<select class="select-custom">
<option>Todas las sucursales</option>
<option>Sucursal Centro</option>
<option>Sucursal Norte</option>
<option>Bodega Principal</option>
</select>
</div>
</div>
</section>
<!-- Context Menu -->
<section>
<h2>Context Menu</h2>
<div class="label">Menú contextual (clic derecho en producto)</div>
<div class="context-menu" style="display: inline-block;">
<button class="dropdown-item"><span class="icon">👁️</span> Ver detalle</button>
<button class="dropdown-item"><span class="icon">📝</span> Editar</button>
<button class="dropdown-item"><span class="icon">🛒</span> Agregar a venta</button>
<div class="dropdown-divider"></div>
<button class="dropdown-item"><span class="icon">📦</span> Ajustar inventario</button>
<button class="dropdown-item"><span class="icon">🏷️</span> Imprimir etiqueta</button>
<div class="dropdown-divider"></div>
<button class="dropdown-item danger"><span class="icon">🗑️</span> Eliminar producto</button>
</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>

View File

@@ -0,0 +1,268 @@
<!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 — Design System Components</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);
min-height: 100vh; transition: var(--transition-normal);
}
.theme-switcher {
position: sticky; top: 0; z-index: var(--z-sticky);
display: flex; gap: var(--space-2); align-items: center;
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);
}
.theme-switcher .logo {
font-family: var(--font-heading); font-weight: var(--heading-weight-primary);
font-size: var(--text-h5); color: var(--color-primary); margin-right: auto;
}
h1 { font-family: var(--font-heading); font-size: var(--text-h1);
font-weight: var(--heading-weight-primary); margin-bottom: var(--space-2);
color: var(--color-text-primary); line-height: var(--leading-h1); }
.accent { color: var(--color-text-accent); }
.subtitle { color: var(--color-text-muted); font-size: var(--text-body-lg);
margin-bottom: var(--space-10); max-width: 600px; line-height: var(--leading-body-lg); }
.grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: var(--space-6);
}
.card {
background: var(--color-bg-elevated);
border: 1px solid var(--color-border);
border-radius: var(--radius-lg);
padding: var(--space-6);
transition: var(--transition-normal);
text-decoration: none; color: inherit;
display: block;
}
.card:hover {
border-color: var(--color-primary);
box-shadow: var(--shadow-md);
transform: translateY(-2px);
}
[data-theme="industrial"] .card {
border-radius: 0;
clip-path: polygon(0 0, calc(100% - 14px) 0, 100% 14px, 100% 100%, 0 100%);
}
.card-icon {
font-size: 32px; margin-bottom: var(--space-3);
}
.card h3 {
font-family: var(--font-heading);
font-size: var(--text-h5); font-weight: var(--heading-weight-secondary);
margin-bottom: var(--space-2);
}
.card p {
font-size: var(--text-body-sm); color: var(--color-text-muted);
line-height: var(--leading-body-sm);
}
.card .status {
display: inline-block; margin-top: var(--space-3);
padding: 2px var(--space-2); font-size: 11px;
font-weight: var(--font-weight-semibold);
text-transform: uppercase; letter-spacing: var(--tracking-wider);
border-radius: var(--radius-sm);
}
.status-done { background: rgba(34,197,94,0.15); color: var(--color-success); }
.status-pending { background: rgba(234,179,8,0.15); color: var(--color-warning); }
.footer {
margin-top: var(--space-16);
padding-top: var(--space-6);
border-top: 1px solid var(--color-border);
color: var(--color-text-muted);
font-size: var(--text-body-sm);
}
</style>
</head>
<body>
<div class="theme-switcher">
<span class="logo">NEXUS AUTOPARTS</span>
<button class="active" onclick="setTheme('industrial')">Industrial Robusto</button>
<button onclick="setTheme('modern')">Tecnico Moderno</button>
</div>
<h1>Design System <span class="accent">Components</span></h1>
<p class="subtitle">Componentes reutilizables del sistema POS para refaccionarias. Cada componente soporta ambos temas.</p>
<div class="grid">
<a class="card" href="buttons.html">
<div class="card-icon">&#128280;</div>
<h3>Buttons</h3>
<p>Primary, secondary, danger, ghost, icon buttons. Todos los tamanos, estados y grupos.</p>
<span class="status status-done">Completo</span>
</a>
<a class="card" href="inputs.html">
<div class="card-icon">&#9999;</div>
<h3>Inputs</h3>
<p>Text, number, search, select, checkbox, radio y toggle. Validacion y estados.</p>
<span class="status status-done">Completo</span>
</a>
<a class="card" href="cards.html">
<div class="card-icon">&#128196;</div>
<h3>Cards</h3>
<p>Tarjetas de producto, cliente y resumen/dashboard con datos reales del POS.</p>
<span class="status status-done">Completo</span>
</a>
<a class="card" href="tables.html">
<div class="card-icon">&#128202;</div>
<h3>Tables</h3>
<p>Tablas de inventario y ventas con sorting, paginacion, filtros y acciones.</p>
<span class="status status-done">Completo</span>
</a>
<a class="card" href="modals.html">
<div class="card-icon">&#128448;</div>
<h3>Modals</h3>
<p>Modales de formulario con overlay real e interactivos.</p>
<span class="status status-done">Completo</span>
</a>
<a class="card" href="navigation.html">
<div class="card-icon">&#128209;</div>
<h3>Navigation</h3>
<p>Sidebar, breadcrumbs y tabs. Navegacion principal del sistema POS.</p>
<span class="status status-done">Completo</span>
</a>
<a class="card" href="badges.html">
<div class="card-icon">&#128276;</div>
<h3>Badges & Tags</h3>
<p>Status badges, tags removibles, labels y contadores numericos.</p>
<span class="status status-done">Completo</span>
</a>
<a class="card" href="alerts.html">
<div class="card-icon">&#9888;</div>
<h3>Alerts & Toasts</h3>
<p>Alert banners, toast notifications y alertas inline de validacion.</p>
<span class="status status-done">Completo</span>
</a>
<a class="card" href="search.html">
<div class="card-icon">&#128269;</div>
<h3>Search</h3>
<p>Barra de busqueda con autocompletado y busqueda por vehiculo.</p>
<span class="status status-done">Completo</span>
</a>
<a class="card" href="pagination.html">
<div class="card-icon">&#128218;</div>
<h3>Pagination</h3>
<p>Paginacion completa, simple y para datasets grandes (1.4M+ partes).</p>
<span class="status status-done">Completo</span>
</a>
<a class="card" href="dropdowns.html">
<div class="card-icon">&#128203;</div>
<h3>Dropdowns</h3>
<p>Dropdown menus de acciones, select menus y context menus.</p>
<span class="status status-done">Completo</span>
</a>
<a class="card" href="toggles.html">
<div class="card-icon">&#128280;</div>
<h3>Toggles & Switches</h3>
<p>Toggle switches, checkboxes y radio buttons con variantes de tamano.</p>
<span class="status status-done">Completo</span>
</a>
<a class="card" href="progress.html">
<div class="card-icon">&#9203;</div>
<h3>Progress & Loading</h3>
<p>Progress bars, spinners, dot loaders y skeleton loaders.</p>
<span class="status status-done">Completo</span>
</a>
<a class="card" href="avatars.html">
<div class="card-icon">&#128100;</div>
<h3>Avatars</h3>
<p>Avatares con iniciales, estados online/offline, grupos y contexto de usuario.</p>
<span class="status status-done">Completo</span>
</a>
<a class="card" href="tooltips.html">
<div class="card-icon">&#128172;</div>
<h3>Tooltips & Popovers</h3>
<p>Tooltips informativos, info icons y popovers interactivos con acciones.</p>
<span class="status status-done">Completo</span>
</a>
<a class="card" href="chips.html">
<div class="card-icon">&#127991;</div>
<h3>Chips</h3>
<p>Filter chips, action chips, choice chips y barra de filtros aplicados.</p>
<span class="status status-done">Completo</span>
</a>
<a class="card" href="dialogs.html">
<div class="card-icon">&#128488;</div>
<h3>Dialogs</h3>
<p>Confirmaciones, advertencias, prompts de descuento y autorizacion PIN.</p>
<span class="status status-done">Completo</span>
</a>
<a class="card" href="tabs.html">
<div class="card-icon">&#128209;</div>
<h3>Tabs (Contextuales)</h3>
<p>Tabs para inventario, contabilidad, detalle de producto y configuracion.</p>
<span class="status status-done">Completo</span>
</a>
<a class="card" href="accordion.html">
<div class="card-icon">&#128220;</div>
<h3>Accordion</h3>
<p>Secciones colapsables para detalle de producto y FAQ. Interactivo.</p>
<span class="status status-done">Completo</span>
</a>
<a class="card" href="datepicker.html">
<div class="card-icon">&#128197;</div>
<h3>Date/Time Pickers</h3>
<p>Inputs de fecha, calendario, rango de fechas y presets rapidos.</p>
<span class="status status-done">Completo</span>
</a>
</div>
<div class="footer">
Nexus Autoparts Design System v1.0 &#183; 20 de 20 componentes &#183; Tokens: tokens.css
</div>
<script>
function setTheme(theme) {
document.documentElement.setAttribute('data-theme', theme);
document.querySelectorAll('.theme-switcher button').forEach(btn => {
btn.classList.toggle('active', btn.textContent.toLowerCase().includes(theme === 'industrial' ? 'industrial' : 'tecnico'));
});
}
</script>
</body>
</html>

View File

@@ -0,0 +1,466 @@
<!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 — Inputs</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);
}
.component-row {
display: flex; flex-wrap: wrap; gap: var(--space-6);
align-items: flex-start; margin-bottom: var(--space-6);
}
.label-text {
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);
}
/* ====== Input Base ====== */
.form-group {
display: flex; flex-direction: column; min-width: 240px;
}
.form-group label {
font-size: var(--text-body-sm); font-weight: var(--font-weight-semibold);
color: var(--color-text-secondary); margin-bottom: var(--space-1);
}
.form-group .helper {
font-size: var(--text-caption); color: var(--color-text-muted);
margin-top: var(--space-1);
}
.form-group .error-msg {
font-size: var(--text-caption); color: var(--color-error);
margin-top: var(--space-1);
}
.input {
width: 100%;
padding: var(--space-3) var(--space-4);
font-family: var(--font-body);
font-size: var(--text-body);
color: var(--color-text-primary);
background: var(--color-bg-elevated);
border: 1px solid var(--color-border);
border-radius: var(--radius-md);
transition: var(--transition-fast);
outline: none;
}
.input::placeholder { color: var(--color-text-muted); }
.input:hover:not(:disabled) { border-color: var(--color-border-strong); }
.input:focus { border-color: var(--color-border-focus); box-shadow: var(--shadow-focus); }
.input:disabled { opacity: 0.5; cursor: not-allowed; }
.input.input-error { border-color: var(--color-error); }
.input.input-error:focus { box-shadow: 0 0 0 3px rgba(239,68,68,0.3); }
.input.input-success { border-color: var(--color-success); }
/* Number input with mono font for prices */
.input-mono {
font-family: var(--font-mono);
font-size: var(--text-mono);
letter-spacing: var(--tracking-wide);
}
/* ====== Search Input ====== */
.search-wrapper {
position: relative; width: 100%;
}
.search-wrapper .search-icon {
position: absolute; left: var(--space-3); top: 50%; transform: translateY(-50%);
color: var(--color-text-muted); font-size: 16px; pointer-events: none;
}
.search-wrapper .input {
padding-left: var(--space-10);
}
.search-wrapper .search-clear {
position: absolute; right: var(--space-3); top: 50%; transform: translateY(-50%);
background: none; border: none; color: var(--color-text-muted);
cursor: pointer; font-size: 16px; padding: var(--space-1);
border-radius: var(--radius-full); transition: var(--transition-fast);
}
.search-wrapper .search-clear:hover { color: var(--color-text-primary); }
/* ====== Select ====== */
.select {
width: 100%;
padding: var(--space-3) var(--space-4);
padding-right: var(--space-10);
font-family: var(--font-body);
font-size: var(--text-body);
color: var(--color-text-primary);
background: var(--color-bg-elevated);
border: 1px solid var(--color-border);
border-radius: var(--radius-md);
transition: var(--transition-fast);
outline: none;
appearance: none;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%23888888' d='M6 8L1 3h10z'/%3E%3C/svg%3E");
background-repeat: no-repeat;
background-position: right var(--space-3) center;
cursor: pointer;
}
.select:hover:not(:disabled) { border-color: var(--color-border-strong); }
.select:focus { border-color: var(--color-border-focus); box-shadow: var(--shadow-focus); }
.select:disabled { opacity: 0.5; cursor: not-allowed; }
/* ====== Checkbox ====== */
.checkbox-group {
display: flex; align-items: center; gap: var(--space-3); cursor: pointer;
user-select: none;
}
.checkbox-group input[type="checkbox"] {
appearance: none; width: 20px; height: 20px;
border: 2px solid var(--color-border-strong);
border-radius: var(--radius-sm); background: var(--color-bg-elevated);
cursor: pointer; transition: var(--transition-fast);
display: flex; align-items: center; justify-content: center;
flex-shrink: 0;
}
.checkbox-group input[type="checkbox"]:checked {
background: var(--color-primary); border-color: var(--color-primary);
}
.checkbox-group input[type="checkbox"]:checked::after {
content: '\2713'; color: var(--color-text-inverse);
font-size: 13px; font-weight: bold;
}
.checkbox-group input[type="checkbox"]:focus-visible {
box-shadow: var(--shadow-focus);
}
.checkbox-group input[type="checkbox"]:disabled {
opacity: 0.4; cursor: not-allowed;
}
.checkbox-group span {
font-size: var(--text-body); color: var(--color-text-primary);
}
/* ====== Radio ====== */
.radio-group {
display: flex; align-items: center; gap: var(--space-3); cursor: pointer;
user-select: none;
}
.radio-group input[type="radio"] {
appearance: none; width: 20px; height: 20px;
border: 2px solid var(--color-border-strong);
border-radius: var(--radius-full); background: var(--color-bg-elevated);
cursor: pointer; transition: var(--transition-fast);
flex-shrink: 0;
}
.radio-group input[type="radio"]:checked {
border-color: var(--color-primary);
background: var(--color-bg-elevated);
box-shadow: inset 0 0 0 4px var(--color-primary);
}
.radio-group input[type="radio"]:focus-visible {
box-shadow: var(--shadow-focus);
}
.radio-group input[type="radio"]:disabled {
opacity: 0.4; cursor: not-allowed;
}
.radio-group span {
font-size: var(--text-body); color: var(--color-text-primary);
}
/* ====== Toggle ====== */
.toggle {
display: flex; align-items: center; gap: var(--space-3);
cursor: pointer; user-select: none;
}
.toggle-track {
position: relative; width: 44px; height: 24px;
background: var(--color-border-strong);
border-radius: var(--radius-full);
transition: var(--transition-fast);
flex-shrink: 0;
}
.toggle-thumb {
position: absolute; top: 2px; left: 2px;
width: 20px; height: 20px;
background: white; border-radius: var(--radius-full);
transition: var(--transition-fast);
box-shadow: var(--shadow-sm);
}
.toggle input { display: none; }
.toggle input:checked + .toggle-track {
background: var(--color-primary);
}
.toggle input:checked + .toggle-track .toggle-thumb {
left: 22px;
}
.toggle-label {
font-size: var(--text-body); color: var(--color-text-primary);
}
/* ====== Input Sizes ====== */
.input-sm { padding: var(--space-2) var(--space-3); font-size: var(--text-body-sm); }
.input-lg { padding: var(--space-4) var(--space-5); font-size: var(--text-body-lg); }
</style>
</head>
<body>
<div class="theme-switcher">
<button class="active" onclick="setTheme('industrial')">Industrial Robusto</button>
<button onclick="setTheme('modern')">Tecnico Moderno</button>
</div>
<h1>Inputs</h1>
<p class="subtitle">Campos de formulario para el sistema POS. Text, number, search, select, checkbox, radio y toggle.</p>
<!-- Text Input -->
<section>
<h2>Text Input</h2>
<div class="component-row">
<div class="form-group">
<label>Nombre del cliente</label>
<input class="input" type="text" placeholder="Ej: Juan Perez">
<span class="helper">Nombre completo del cliente</span>
</div>
<div class="form-group">
<label>RFC</label>
<input class="input" type="text" placeholder="XAXX010101000" value="AAAS940812">
</div>
<div class="form-group">
<label>Email (error)</label>
<input class="input input-error" type="email" value="correo-invalido">
<span class="error-msg">Formato de email invalido</span>
</div>
</div>
<div class="component-row">
<div class="form-group">
<label>Campo deshabilitado</label>
<input class="input" type="text" value="No editable" disabled>
</div>
<div class="form-group">
<label>Campo valido</label>
<input class="input input-success" type="text" value="Dato correcto">
</div>
</div>
</section>
<!-- Number Input -->
<section>
<h2>Number Input (Precios / Cantidades)</h2>
<div class="component-row">
<div class="form-group">
<label>Precio unitario</label>
<input class="input input-mono" type="text" value="$1,250.00" placeholder="$0.00">
</div>
<div class="form-group">
<label>Cantidad</label>
<input class="input input-mono" type="number" value="5" min="1" max="999" style="width: 120px;">
</div>
<div class="form-group">
<label>SKU / Numero de parte</label>
<input class="input input-mono" type="text" placeholder="ACM-BRK-001" value="MOT-OIL-5W30">
</div>
</div>
</section>
<!-- Search Input -->
<section>
<h2>Search Input</h2>
<div class="component-row">
<div class="form-group" style="min-width: 400px;">
<label>Buscar producto</label>
<div class="search-wrapper">
<span class="search-icon">&#128269;</span>
<input class="input" type="text" placeholder="Buscar por nombre, SKU o numero OEM...">
</div>
</div>
</div>
<div class="component-row">
<div class="form-group" style="min-width: 400px;">
<label>Busqueda con valor</label>
<div class="search-wrapper">
<span class="search-icon">&#128269;</span>
<input class="input" type="text" value="Balata ceramica Brembo">
<button class="search-clear" title="Limpiar">&#10005;</button>
</div>
</div>
</div>
</section>
<!-- Select -->
<section>
<h2>Select</h2>
<div class="component-row">
<div class="form-group">
<label>Marca del vehiculo</label>
<select class="select">
<option value="">Selecciona marca...</option>
<option>Chevrolet</option>
<option>Ford</option>
<option>Nissan</option>
<option>Toyota</option>
<option>Volkswagen</option>
<option>Honda</option>
</select>
</div>
<div class="form-group">
<label>Ano del modelo</label>
<select class="select">
<option value="">Selecciona ano...</option>
<option>2026</option>
<option>2025</option>
<option>2024</option>
<option>2023</option>
<option>2022</option>
</select>
</div>
<div class="form-group">
<label>Metodo de pago</label>
<select class="select">
<option>Efectivo</option>
<option>Tarjeta</option>
<option>Transferencia</option>
<option>Credito</option>
</select>
</div>
</div>
<div class="component-row">
<div class="form-group">
<label>Select deshabilitado</label>
<select class="select" disabled>
<option>No disponible</option>
</select>
</div>
</div>
</section>
<!-- Checkbox -->
<section>
<h2>Checkbox</h2>
<div class="component-row" style="flex-direction: column; gap: var(--space-3);">
<label class="checkbox-group">
<input type="checkbox" checked> <span>Requiere factura (CFDI)</span>
</label>
<label class="checkbox-group">
<input type="checkbox"> <span>Aplicar descuento por volumen</span>
</label>
<label class="checkbox-group">
<input type="checkbox" checked> <span>Enviar ticket por WhatsApp</span>
</label>
<label class="checkbox-group">
<input type="checkbox" disabled> <span>Opcion deshabilitada</span>
</label>
</div>
</section>
<!-- Radio -->
<section>
<h2>Radio</h2>
<div class="component-row" style="flex-direction: column; gap: var(--space-3);">
<label class="radio-group">
<input type="radio" name="tipo-venta" checked> <span>Venta de mostrador</span>
</label>
<label class="radio-group">
<input type="radio" name="tipo-venta"> <span>Venta a taller</span>
</label>
<label class="radio-group">
<input type="radio" name="tipo-venta"> <span>Venta mayoreo</span>
</label>
<label class="radio-group">
<input type="radio" name="tipo-venta" disabled> <span>No disponible</span>
</label>
</div>
</section>
<!-- Toggle -->
<section>
<h2>Toggle</h2>
<div class="component-row" style="flex-direction: column; gap: var(--space-4);">
<label class="toggle">
<input type="checkbox" checked>
<div class="toggle-track"><div class="toggle-thumb"></div></div>
<span class="toggle-label">Modo oscuro</span>
</label>
<label class="toggle">
<input type="checkbox">
<div class="toggle-track"><div class="toggle-thumb"></div></div>
<span class="toggle-label">Notificaciones de stock bajo</span>
</label>
<label class="toggle">
<input type="checkbox" checked>
<div class="toggle-track"><div class="toggle-thumb"></div></div>
<span class="toggle-label">Imprimir ticket automaticamente</span>
</label>
</div>
</section>
<!-- Input Sizes -->
<section>
<h2>Tamanos</h2>
<div class="component-row">
<div class="form-group">
<label>Pequeno</label>
<input class="input input-sm" type="text" placeholder="Input sm">
</div>
<div class="form-group">
<label>Normal</label>
<input class="input" type="text" placeholder="Input normal">
</div>
<div class="form-group">
<label>Grande</label>
<input class="input input-lg" type="text" placeholder="Input lg">
</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.toLowerCase().includes(theme === 'industrial' ? 'industrial' : 'tecnico'));
});
}
// Toggle functionality
document.querySelectorAll('.toggle input').forEach(input => {
input.addEventListener('change', function() {
// Toggle already handled by CSS
});
});
</script>
</body>
</html>

View File

@@ -0,0 +1,592 @@
<!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 — Modals</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: calc(var(--z-modal) + 10);
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-text {
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-3);
}
.trigger-row {
display: flex; flex-wrap: wrap; gap: var(--space-3); margin-bottom: var(--space-6);
}
/* ====== Buttons ====== */
.btn {
display: inline-flex; align-items: center; justify-content: center;
gap: var(--space-2);
padding: var(--space-3) var(--space-6);
font-family: var(--font-body); font-size: var(--text-body);
font-weight: var(--font-weight-semibold); line-height: 1;
border: 2px solid transparent; border-radius: var(--radius-md);
cursor: pointer; transition: var(--transition-fast);
white-space: nowrap;
}
.btn:focus-visible { outline: none; box-shadow: var(--shadow-focus); }
.btn:active { transform: scale(0.97); }
.btn-primary {
background: var(--btn-primary-bg); color: var(--btn-primary-text);
}
.btn-primary:hover { background: var(--btn-primary-bg-hover); }
.btn-secondary {
background: var(--btn-secondary-bg); color: var(--btn-secondary-text);
border-color: var(--btn-secondary-border);
}
.btn-secondary:hover { background: var(--btn-secondary-bg-hover); }
.btn-danger {
background: var(--btn-danger-bg); color: var(--btn-danger-text);
}
.btn-danger:hover { background: var(--color-error-dark); }
.btn-ghost {
background: var(--btn-ghost-bg); color: var(--btn-ghost-text);
border-color: var(--btn-ghost-border);
}
.btn-ghost:hover { background: var(--color-surface-2); }
.btn-sm { padding: var(--space-2) var(--space-4); font-size: var(--text-body-sm); }
.btn-block { width: 100%; }
[data-theme="industrial"] .btn-primary,
[data-theme="industrial"] .btn-danger {
clip-path: polygon(0 0, calc(100% - 10px) 0, 100% 10px, 100% 100%, 0 100%);
border-radius: 0;
}
/* ====== Input ====== */
.input {
width: 100%; padding: var(--space-3) var(--space-4);
font-family: var(--font-body); font-size: var(--text-body);
color: var(--color-text-primary); background: var(--color-bg-base);
border: 1px solid var(--color-border); border-radius: var(--radius-md);
transition: var(--transition-fast); outline: none;
}
.input::placeholder { color: var(--color-text-muted); }
.input:focus { border-color: var(--color-border-focus); box-shadow: var(--shadow-focus); }
.input-mono { font-family: var(--font-mono); }
.select {
width: 100%; padding: var(--space-3) var(--space-4);
font-family: var(--font-body); font-size: var(--text-body);
color: var(--color-text-primary); background: var(--color-bg-base);
border: 1px solid var(--color-border); border-radius: var(--radius-md);
outline: none; appearance: none; cursor: pointer;
}
.form-group { display: flex; flex-direction: column; gap: var(--space-1); }
.form-group label {
font-size: var(--text-body-sm); font-weight: var(--font-weight-semibold);
color: var(--color-text-secondary);
}
textarea.input { resize: vertical; min-height: 80px; }
/* ====== Modal Overlay ====== */
.modal-overlay {
display: none;
position: fixed; inset: 0;
background: var(--overlay-backdrop);
z-index: var(--z-modal);
align-items: center; justify-content: center;
padding: var(--space-6);
animation: fadeIn 0.2s ease;
}
.modal-overlay.active { display: flex; }
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
@keyframes slideUp {
from { opacity: 0; transform: translateY(20px); }
to { opacity: 1; transform: translateY(0); }
}
/* ====== Modal ====== */
.modal {
background: var(--color-bg-overlay);
border: 1px solid var(--color-border);
border-radius: var(--radius-lg);
box-shadow: var(--shadow-xl);
width: 100%; max-width: 520px;
max-height: 90vh; overflow-y: auto;
animation: slideUp 0.25s ease;
}
[data-theme="industrial"] .modal {
border-radius: 0;
clip-path: polygon(0 0, calc(100% - 20px) 0, 100% 20px, 100% 100%, 0 100%);
}
.modal-header {
display: flex; align-items: center; justify-content: space-between;
padding: var(--space-5) var(--space-6);
border-bottom: 1px solid var(--color-border);
}
.modal-header h2 {
font-family: var(--font-heading);
font-size: var(--text-h4);
font-weight: var(--heading-weight-secondary);
margin: 0; padding: 0; border: none;
}
.modal-close {
display: flex; align-items: center; justify-content: center;
width: 32px; height: 32px;
background: none; border: 1px solid var(--color-border);
color: var(--color-text-muted); border-radius: var(--radius-md);
cursor: pointer; font-size: 16px; transition: var(--transition-fast);
}
.modal-close:hover {
color: var(--color-text-primary); border-color: var(--color-border-strong);
background: var(--color-surface-2);
}
.modal-body {
padding: var(--space-6);
}
.modal-footer {
display: flex; align-items: center; justify-content: flex-end;
gap: var(--space-3);
padding: var(--space-4) var(--space-6);
border-top: 1px solid var(--color-border);
}
/* Modal sizes */
.modal-sm { max-width: 380px; }
.modal-lg { max-width: 720px; }
/* ====== Inline Modal Preview ====== */
.modal-preview {
background: var(--color-surface-1);
border: 1px solid var(--color-border);
border-radius: var(--radius-lg);
padding: var(--space-6);
margin-bottom: var(--space-6);
}
.modal-preview .modal {
position: relative;
max-width: 100%;
animation: none;
}
/* ====== Confirmation Dialog Icon ====== */
.confirm-icon {
width: 64px; height: 64px;
border-radius: var(--radius-full);
display: flex; align-items: center; justify-content: center;
font-size: 32px; margin: 0 auto var(--space-4);
}
.confirm-icon-danger {
background: var(--color-error-light); color: var(--color-error);
}
.confirm-icon-warning {
background: var(--color-warning-light); color: var(--color-warning);
}
.confirm-icon-success {
background: var(--color-success-light); color: var(--color-success);
}
[data-theme="industrial"] .confirm-icon-danger { background: rgba(239,68,68,0.15); }
[data-theme="industrial"] .confirm-icon-warning { background: rgba(234,179,8,0.15); }
[data-theme="industrial"] .confirm-icon-success { background: rgba(34,197,94,0.15); }
.confirm-title {
font-family: var(--font-heading);
font-size: var(--text-h4);
font-weight: var(--heading-weight-secondary);
text-align: center; margin-bottom: var(--space-2);
}
.confirm-text {
font-size: var(--text-body);
color: var(--color-text-secondary);
text-align: center; margin-bottom: var(--space-6);
line-height: var(--leading-body);
}
.confirm-actions {
display: flex; gap: var(--space-3); justify-content: center;
}
</style>
</head>
<body>
<div class="theme-switcher">
<button class="active" onclick="setTheme('industrial')">Industrial Robusto</button>
<button onclick="setTheme('modern')">Tecnico Moderno</button>
</div>
<h1>Modals & Dialogs</h1>
<p class="subtitle">Modales, dialogs de confirmacion y formularios overlay para el sistema POS.</p>
<!-- Trigger Buttons -->
<section>
<h2>Abrir Modales (Demo Interactivo)</h2>
<p class="label-text">Haz clic para ver los modales en accion con overlay real</p>
<div class="trigger-row">
<button class="btn btn-primary" onclick="openModal('modal-product')">Agregar Producto</button>
<button class="btn btn-secondary" onclick="openModal('modal-client')">Nuevo Cliente</button>
<button class="btn btn-danger" onclick="openModal('modal-delete')">Eliminar Producto</button>
<button class="btn btn-ghost" onclick="openModal('modal-confirm-sale')">Confirmar Venta</button>
<button class="btn btn-ghost" onclick="openModal('modal-success')">Venta Exitosa</button>
</div>
</section>
<!-- Inline Previews -->
<section>
<h2>Modal: Agregar Producto</h2>
<p class="label-text">Formulario de producto con campos tipicos del inventario POS</p>
<div class="modal-preview">
<div class="modal" style="margin: 0 auto;">
<div class="modal-header">
<h2>Agregar Producto</h2>
<button class="modal-close">&#10005;</button>
</div>
<div class="modal-body">
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-4);">
<div class="form-group" style="grid-column: span 2;">
<label>Nombre del producto</label>
<input class="input" type="text" placeholder="Ej: Balatas Ceramicas Brembo">
</div>
<div class="form-group">
<label>SKU</label>
<input class="input input-mono" type="text" placeholder="BRM-BLT-001">
</div>
<div class="form-group">
<label>Numero OEM</label>
<input class="input input-mono" type="text" placeholder="P68064N">
</div>
<div class="form-group">
<label>Categoria</label>
<select class="select">
<option>Selecciona...</option>
<option>Frenos</option>
<option>Motor</option>
<option>Suspension</option>
<option>Encendido</option>
<option>Filtracion</option>
<option>Electrico</option>
</select>
</div>
<div class="form-group">
<label>Marca</label>
<select class="select">
<option>Selecciona...</option>
<option>Brembo</option>
<option>Bosch</option>
<option>Monroe</option>
<option>NGK</option>
<option>Gates</option>
<option>Mobil</option>
</select>
</div>
<div class="form-group">
<label>Precio de compra</label>
<input class="input input-mono" type="text" placeholder="$0.00">
</div>
<div class="form-group">
<label>Precio de venta</label>
<input class="input input-mono" type="text" placeholder="$0.00">
</div>
<div class="form-group">
<label>Stock inicial</label>
<input class="input input-mono" type="number" value="0" min="0">
</div>
<div class="form-group">
<label>Stock minimo (alerta)</label>
<input class="input input-mono" type="number" value="5" min="0">
</div>
<div class="form-group" style="grid-column: span 2;">
<label>Compatibilidad vehicular</label>
<textarea class="input" placeholder="Ej: Nissan Sentra 2019-2024, Nissan Versa 2020-2024"></textarea>
</div>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-ghost btn-sm">Cancelar</button>
<button class="btn btn-primary btn-sm">Guardar Producto</button>
</div>
</div>
</div>
</section>
<section>
<h2>Modal: Nuevo Cliente</h2>
<p class="label-text">Formulario rapido para registrar un cliente nuevo</p>
<div class="modal-preview">
<div class="modal" style="margin: 0 auto;">
<div class="modal-header">
<h2>Nuevo Cliente</h2>
<button class="modal-close">&#10005;</button>
</div>
<div class="modal-body">
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-4);">
<div class="form-group" style="grid-column: span 2;">
<label>Nombre / Razon Social</label>
<input class="input" type="text" placeholder="Nombre completo o razon social">
</div>
<div class="form-group">
<label>RFC</label>
<input class="input input-mono" type="text" placeholder="XAXX010101000">
</div>
<div class="form-group">
<label>Tipo de cliente</label>
<select class="select">
<option>Publico General</option>
<option>Taller Mecanico</option>
<option>Refaccionaria</option>
<option>Mayoreo</option>
</select>
</div>
<div class="form-group">
<label>Telefono</label>
<input class="input" type="tel" placeholder="(000) 000-0000">
</div>
<div class="form-group">
<label>Email</label>
<input class="input" type="email" placeholder="correo@ejemplo.com">
</div>
<div class="form-group" style="grid-column: span 2;">
<label>Direccion</label>
<input class="input" type="text" placeholder="Calle, numero, colonia, CP">
</div>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-ghost btn-sm">Cancelar</button>
<button class="btn btn-primary btn-sm">Registrar Cliente</button>
</div>
</div>
</div>
</section>
<section>
<h2>Dialog: Confirmacion de Eliminacion</h2>
<p class="label-text">Confirmacion destructiva — requiere accion explicita del usuario</p>
<div class="modal-preview">
<div class="modal modal-sm" style="margin: 0 auto;">
<div class="modal-body" style="padding: var(--space-8) var(--space-6);">
<div class="confirm-icon confirm-icon-danger">&#9888;</div>
<div class="confirm-title">Eliminar Producto</div>
<div class="confirm-text">
Estas a punto de eliminar <strong>Balatas Ceramicas Brembo</strong> (BRM-BLT-P68064N) del inventario. Esta accion no se puede deshacer.
</div>
<div class="confirm-actions">
<button class="btn btn-ghost">Cancelar</button>
<button class="btn btn-danger">Eliminar</button>
</div>
</div>
</div>
</div>
</section>
<section>
<h2>Dialog: Confirmar Venta</h2>
<p class="label-text">Confirmacion antes de procesar el cobro</p>
<div class="modal-preview">
<div class="modal modal-sm" style="margin: 0 auto;">
<div class="modal-body" style="padding: var(--space-8) var(--space-6);">
<div class="confirm-icon confirm-icon-warning">&#128176;</div>
<div class="confirm-title">Confirmar Cobro</div>
<div class="confirm-text">
Total a cobrar: <strong style="color: var(--color-text-accent); font-family: var(--font-mono); font-size: var(--text-h4);">$3,680.00</strong><br>
<span style="font-size: var(--text-body-sm);">4 productos &#183; Taller El Rapido &#183; Credito</span>
</div>
<div class="confirm-actions">
<button class="btn btn-ghost">Regresar</button>
<button class="btn btn-primary">Cobrar</button>
</div>
</div>
</div>
</div>
</section>
<section>
<h2>Dialog: Venta Exitosa</h2>
<p class="label-text">Feedback positivo despues de completar una venta</p>
<div class="modal-preview">
<div class="modal modal-sm" style="margin: 0 auto;">
<div class="modal-body" style="padding: var(--space-8) var(--space-6);">
<div class="confirm-icon confirm-icon-success">&#10003;</div>
<div class="confirm-title">Venta Completada</div>
<div class="confirm-text">
Folio: <strong style="font-family: var(--font-mono);">V-2026-0847</strong><br>
Ticket enviado por WhatsApp al cliente.
</div>
<div class="confirm-actions">
<button class="btn btn-ghost">Imprimir Ticket</button>
<button class="btn btn-primary">Nueva Venta</button>
</div>
</div>
</div>
</div>
</section>
<!-- Real Overlays (triggered by buttons) -->
<div class="modal-overlay" id="modal-product" onclick="closeModal(event, 'modal-product')">
<div class="modal" onclick="event.stopPropagation()">
<div class="modal-header">
<h2>Agregar Producto</h2>
<button class="modal-close" onclick="closeModalById('modal-product')">&#10005;</button>
</div>
<div class="modal-body">
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-4);">
<div class="form-group" style="grid-column: span 2;">
<label>Nombre del producto</label>
<input class="input" type="text" placeholder="Ej: Balatas Ceramicas Brembo">
</div>
<div class="form-group">
<label>SKU</label>
<input class="input input-mono" type="text" placeholder="BRM-BLT-001">
</div>
<div class="form-group">
<label>Precio de venta</label>
<input class="input input-mono" type="text" placeholder="$0.00">
</div>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-ghost btn-sm" onclick="closeModalById('modal-product')">Cancelar</button>
<button class="btn btn-primary btn-sm">Guardar</button>
</div>
</div>
</div>
<div class="modal-overlay" id="modal-client" onclick="closeModal(event, 'modal-client')">
<div class="modal" onclick="event.stopPropagation()">
<div class="modal-header">
<h2>Nuevo Cliente</h2>
<button class="modal-close" onclick="closeModalById('modal-client')">&#10005;</button>
</div>
<div class="modal-body">
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-4);">
<div class="form-group" style="grid-column: span 2;">
<label>Nombre / Razon Social</label>
<input class="input" type="text" placeholder="Nombre completo">
</div>
<div class="form-group">
<label>RFC</label>
<input class="input input-mono" type="text" placeholder="XAXX010101000">
</div>
<div class="form-group">
<label>Telefono</label>
<input class="input" type="tel" placeholder="(000) 000-0000">
</div>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-ghost btn-sm" onclick="closeModalById('modal-client')">Cancelar</button>
<button class="btn btn-primary btn-sm">Registrar</button>
</div>
</div>
</div>
<div class="modal-overlay" id="modal-delete" onclick="closeModal(event, 'modal-delete')">
<div class="modal modal-sm" onclick="event.stopPropagation()">
<div class="modal-body" style="padding: var(--space-8) var(--space-6);">
<div class="confirm-icon confirm-icon-danger">&#9888;</div>
<div class="confirm-title">Eliminar Producto</div>
<div class="confirm-text">Esta accion no se puede deshacer. El producto sera eliminado permanentemente.</div>
<div class="confirm-actions">
<button class="btn btn-ghost" onclick="closeModalById('modal-delete')">Cancelar</button>
<button class="btn btn-danger" onclick="closeModalById('modal-delete')">Eliminar</button>
</div>
</div>
</div>
</div>
<div class="modal-overlay" id="modal-confirm-sale" onclick="closeModal(event, 'modal-confirm-sale')">
<div class="modal modal-sm" onclick="event.stopPropagation()">
<div class="modal-body" style="padding: var(--space-8) var(--space-6);">
<div class="confirm-icon confirm-icon-warning">&#128176;</div>
<div class="confirm-title">Confirmar Cobro</div>
<div class="confirm-text">Total: <strong style="color: var(--color-text-accent); font-family: var(--font-mono); font-size: var(--text-h4);">$3,680.00</strong></div>
<div class="confirm-actions">
<button class="btn btn-ghost" onclick="closeModalById('modal-confirm-sale')">Regresar</button>
<button class="btn btn-primary" onclick="closeModalById('modal-confirm-sale')">Cobrar</button>
</div>
</div>
</div>
</div>
<div class="modal-overlay" id="modal-success" onclick="closeModal(event, 'modal-success')">
<div class="modal modal-sm" onclick="event.stopPropagation()">
<div class="modal-body" style="padding: var(--space-8) var(--space-6);">
<div class="confirm-icon confirm-icon-success">&#10003;</div>
<div class="confirm-title">Venta Completada</div>
<div class="confirm-text">Folio: <strong style="font-family: var(--font-mono);">V-2026-0847</strong></div>
<div class="confirm-actions">
<button class="btn btn-ghost" onclick="closeModalById('modal-success')">Imprimir</button>
<button class="btn btn-primary" onclick="closeModalById('modal-success')">Nueva Venta</button>
</div>
</div>
</div>
</div>
<script>
function setTheme(theme) {
document.documentElement.setAttribute('data-theme', theme);
document.querySelectorAll('.theme-switcher button').forEach(btn => {
btn.classList.toggle('active', btn.textContent.toLowerCase().includes(theme === 'industrial' ? 'industrial' : 'tecnico'));
});
}
function openModal(id) {
document.getElementById(id).classList.add('active');
document.body.style.overflow = 'hidden';
}
function closeModal(event, id) {
if (event.target === event.currentTarget) closeModalById(id);
}
function closeModalById(id) {
document.getElementById(id).classList.remove('active');
document.body.style.overflow = '';
}
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape') {
document.querySelectorAll('.modal-overlay.active').forEach(overlay => {
overlay.classList.remove('active');
});
document.body.style.overflow = '';
}
});
</script>
</body>
</html>

View File

@@ -0,0 +1,573 @@
<!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 — Navigation</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);
}
.component-row {
display: flex;
flex-wrap: wrap;
gap: var(--space-4);
align-items: center;
margin-bottom: var(--space-6);
}
.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);
}
/* ====== Sidebar ====== */
.sidebar-demo {
display: flex;
gap: var(--space-6);
margin-bottom: var(--space-6);
}
.sidebar {
width: 260px;
min-height: 500px;
background: var(--color-bg-elevated);
border-right: 1px solid var(--color-border);
border-radius: var(--radius-md);
overflow: hidden;
flex-shrink: 0;
}
.sidebar-header {
padding: var(--space-5) var(--space-4);
border-bottom: 1px solid var(--color-border);
display: flex;
align-items: center;
gap: var(--space-3);
}
.sidebar-logo {
width: 36px;
height: 36px;
background: var(--color-primary);
border-radius: var(--radius-md);
display: flex;
align-items: center;
justify-content: center;
font-weight: var(--font-weight-bold);
color: var(--color-text-inverse);
font-size: var(--text-body-lg);
}
[data-theme="industrial"] .sidebar-logo {
border-radius: 0;
clip-path: polygon(0 0, calc(100% - 6px) 0, 100% 6px, 100% 100%, 0 100%);
}
.sidebar-brand {
font-family: var(--font-heading);
font-weight: var(--heading-weight-primary);
font-size: var(--text-body-lg);
color: var(--color-text-accent);
}
.sidebar-section {
padding: var(--space-3) var(--space-3);
}
.sidebar-section-title {
font-size: var(--text-caption);
color: var(--color-text-muted);
text-transform: uppercase;
letter-spacing: var(--tracking-widest);
font-weight: var(--font-weight-semibold);
padding: var(--space-2) var(--space-3);
margin-bottom: var(--space-1);
}
.sidebar-item {
display: flex;
align-items: center;
gap: var(--space-3);
padding: var(--space-3) var(--space-3);
border-radius: var(--radius-md);
color: var(--color-text-secondary);
text-decoration: none;
font-size: var(--text-body-sm);
cursor: pointer;
transition: var(--transition-fast);
}
[data-theme="industrial"] .sidebar-item {
border-radius: 0;
}
.sidebar-item:hover {
background: var(--color-primary-muted);
color: var(--color-text-primary);
}
.sidebar-item.active {
background: var(--color-primary-muted);
color: var(--color-primary);
font-weight: var(--font-weight-semibold);
border-left: 3px solid var(--color-primary);
}
.sidebar-item .icon {
width: 20px;
text-align: center;
font-size: var(--text-body);
}
.sidebar-item .badge-count {
margin-left: auto;
background: var(--color-primary);
color: var(--color-text-inverse);
font-size: var(--text-caption);
padding: 2px 8px;
border-radius: var(--radius-full);
font-weight: var(--font-weight-semibold);
}
.sidebar-footer {
padding: var(--space-4);
border-top: 1px solid var(--color-border);
margin-top: auto;
}
.sidebar-user {
display: flex;
align-items: center;
gap: var(--space-3);
padding: var(--space-2);
}
.sidebar-avatar {
width: 32px;
height: 32px;
border-radius: var(--radius-full);
background: var(--color-primary);
display: flex;
align-items: center;
justify-content: center;
color: var(--color-text-inverse);
font-weight: var(--font-weight-bold);
font-size: var(--text-body-sm);
}
.sidebar-user-info {
flex: 1;
}
.sidebar-user-name {
font-size: var(--text-body-sm);
font-weight: var(--font-weight-semibold);
color: var(--color-text-primary);
}
.sidebar-user-role {
font-size: var(--text-caption);
color: var(--color-text-muted);
}
/* ====== Breadcrumbs ====== */
.breadcrumb {
display: flex;
align-items: center;
gap: var(--space-2);
list-style: none;
font-size: var(--text-body-sm);
padding: var(--space-3) var(--space-4);
background: var(--color-bg-elevated);
border-radius: var(--radius-md);
border: 1px solid var(--color-border);
}
[data-theme="industrial"] .breadcrumb {
border-radius: 0;
clip-path: polygon(0 0, calc(100% - 8px) 0, 100% 8px, 100% 100%, 0 100%);
}
.breadcrumb-item a {
color: var(--color-text-muted);
text-decoration: none;
transition: var(--transition-fast);
}
.breadcrumb-item a:hover {
color: var(--color-primary);
}
.breadcrumb-item.active {
color: var(--color-text-primary);
font-weight: var(--font-weight-semibold);
}
.breadcrumb-separator {
color: var(--color-text-disabled);
}
/* ====== Tabs ====== */
.tabs {
display: flex;
gap: 0;
border-bottom: 2px solid var(--color-border);
margin-bottom: var(--space-4);
}
.tab {
padding: var(--space-3) var(--space-5);
font-family: var(--font-body);
font-size: var(--text-body-sm);
font-weight: var(--font-weight-semibold);
color: var(--color-text-muted);
background: transparent;
border: none;
cursor: pointer;
position: relative;
transition: var(--transition-fast);
}
.tab:hover {
color: var(--color-text-primary);
}
.tab.active {
color: var(--color-primary);
}
.tab.active::after {
content: '';
position: absolute;
bottom: -2px;
left: 0;
right: 0;
height: 2px;
background: var(--color-primary);
}
.tab .tab-badge {
margin-left: var(--space-2);
font-size: var(--text-caption);
background: var(--color-primary-muted);
color: var(--color-primary);
padding: 1px 6px;
border-radius: var(--radius-full);
}
/* Tabs — Pill Variant */
.tabs-pills {
display: flex;
gap: var(--space-2);
padding: var(--space-1);
background: var(--color-bg-elevated);
border-radius: var(--radius-lg);
border: 1px solid var(--color-border);
}
[data-theme="industrial"] .tabs-pills {
border-radius: 0;
}
.tab-pill {
padding: var(--space-2) var(--space-4);
font-family: var(--font-body);
font-size: var(--text-body-sm);
font-weight: var(--font-weight-semibold);
color: var(--color-text-muted);
background: transparent;
border: none;
border-radius: var(--radius-md);
cursor: pointer;
transition: var(--transition-fast);
}
[data-theme="industrial"] .tab-pill {
border-radius: 0;
}
.tab-pill:hover {
color: var(--color-text-primary);
}
.tab-pill.active {
background: var(--color-primary);
color: var(--color-text-inverse);
}
/* Tab content */
.tab-content {
padding: var(--space-4);
background: var(--color-bg-elevated);
border: 1px solid var(--color-border);
border-top: none;
border-radius: 0 0 var(--radius-md) var(--radius-md);
color: var(--color-text-secondary);
font-size: var(--text-body-sm);
}
/* ====== Main content area ====== */
.main-content {
flex: 1;
min-width: 0;
}
</style>
</head>
<body>
<div class="theme-switcher">
<button class="active" onclick="setTheme('industrial')">🔧 Industrial</button>
<button onclick="setTheme('modern')">⚡ Moderno</button>
</div>
<h1>Navigation</h1>
<p class="subtitle">Sidebar, Breadcrumbs y Tabs — componentes de navegación del sistema POS</p>
<!-- ====== Sidebar ====== -->
<section>
<h2>Sidebar</h2>
<div class="label">Navegación principal del POS</div>
<div class="sidebar-demo">
<div class="sidebar">
<div class="sidebar-header">
<div class="sidebar-logo">N</div>
<span class="sidebar-brand">NEXUS</span>
</div>
<div class="sidebar-section">
<div class="sidebar-section-title">Principal</div>
<a class="sidebar-item active">
<span class="icon">📊</span>
Dashboard
</a>
<a class="sidebar-item">
<span class="icon">🛒</span>
Punto de Venta
<span class="badge-count">3</span>
</a>
<a class="sidebar-item">
<span class="icon">📦</span>
Inventario
</a>
<a class="sidebar-item">
<span class="icon">🔍</span>
Catálogo
</a>
</div>
<div class="sidebar-section">
<div class="sidebar-section-title">Gestión</div>
<a class="sidebar-item">
<span class="icon">👥</span>
Clientes
</a>
<a class="sidebar-item">
<span class="icon">📋</span>
Órdenes
<span class="badge-count">12</span>
</a>
<a class="sidebar-item">
<span class="icon">💰</span>
Contabilidad
</a>
<a class="sidebar-item">
<span class="icon">📈</span>
Reportes
</a>
</div>
<div class="sidebar-section">
<div class="sidebar-section-title">Sistema</div>
<a class="sidebar-item">
<span class="icon">⚙️</span>
Configuración
</a>
<a class="sidebar-item">
<span class="icon">👤</span>
Usuarios
</a>
</div>
<div class="sidebar-footer">
<div class="sidebar-user">
<div class="sidebar-avatar">JR</div>
<div class="sidebar-user-info">
<div class="sidebar-user-name">Juan Rodríguez</div>
<div class="sidebar-user-role">Administrador</div>
</div>
</div>
</div>
</div>
<div class="main-content">
<div style="padding: var(--space-4); color: var(--color-text-muted); font-style: italic;">
← Sidebar de navegación principal con secciones, badges y perfil de usuario.
</div>
</div>
</div>
</section>
<!-- ====== Breadcrumbs ====== -->
<section>
<h2>Breadcrumbs</h2>
<div class="label">Navegación jerárquica</div>
<div class="component-row" style="flex-direction: column; align-items: flex-start; gap: var(--space-4);">
<nav class="breadcrumb">
<span class="breadcrumb-item"><a href="#">Inicio</a></span>
<span class="breadcrumb-separator"></span>
<span class="breadcrumb-item"><a href="#">Inventario</a></span>
<span class="breadcrumb-separator"></span>
<span class="breadcrumb-item active">Filtros de aceite</span>
</nav>
<nav class="breadcrumb">
<span class="breadcrumb-item"><a href="#">Inicio</a></span>
<span class="breadcrumb-separator"></span>
<span class="breadcrumb-item"><a href="#">Catálogo</a></span>
<span class="breadcrumb-separator"></span>
<span class="breadcrumb-item"><a href="#">Toyota</a></span>
<span class="breadcrumb-separator"></span>
<span class="breadcrumb-item"><a href="#">Corolla 2020</a></span>
<span class="breadcrumb-separator"></span>
<span class="breadcrumb-item active">Frenos</span>
</nav>
<nav class="breadcrumb">
<span class="breadcrumb-item"><a href="#">Inicio</a></span>
<span class="breadcrumb-separator"></span>
<span class="breadcrumb-item active">Dashboard</span>
</nav>
</div>
</section>
<!-- ====== Tabs ====== -->
<section>
<h2>Tabs — Línea</h2>
<div class="label">Navegación por pestañas (inventario, contabilidad, etc.)</div>
<div class="tabs">
<button class="tab active">Todos <span class="tab-badge">1,240</span></button>
<button class="tab">En stock <span class="tab-badge">980</span></button>
<button class="tab">Bajo stock <span class="tab-badge">45</span></button>
<button class="tab">Agotados <span class="tab-badge">15</span></button>
<button class="tab">Pedidos</button>
</div>
<div class="tab-content">
Contenido de la pestaña activa. Aquí se mostraría la tabla de inventario filtrada.
</div>
</section>
<section>
<h2>Tabs — Pills</h2>
<div class="label">Variante con fondo de selección</div>
<div class="tabs-pills">
<button class="tab-pill active">General</button>
<button class="tab-pill">Precios</button>
<button class="tab-pill">Compatibilidad</button>
<button class="tab-pill">Historial</button>
</div>
</section>
<section>
<h2>Tabs — Contexto Contabilidad</h2>
<div class="label">Navegación entre módulos financieros</div>
<div class="tabs">
<button class="tab active">Ventas</button>
<button class="tab">Compras</button>
<button class="tab">Cuentas por Cobrar</button>
<button class="tab">Cuentas por Pagar</button>
<button class="tab">Corte de Caja</button>
<button class="tab">Reportes</button>
</div>
<div class="tab-content">
Módulo de contabilidad con tabs contextuales para cada sección financiera del POS.
</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>

View File

@@ -0,0 +1,278 @@
<!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 — Pagination</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); }
/* ====== Pagination ====== */
.pagination {
display: flex;
align-items: center;
gap: var(--space-1);
margin-bottom: var(--space-6);
}
.page-btn {
display: inline-flex;
align-items: center;
justify-content: center;
min-width: 36px;
height: 36px;
padding: 0 var(--space-2);
background: var(--color-bg-elevated);
border: 1px solid var(--color-border);
border-radius: var(--radius-md);
color: var(--color-text-secondary);
font-family: var(--font-body);
font-size: var(--text-body-sm);
font-weight: var(--font-weight-semibold);
cursor: pointer;
transition: var(--transition-fast);
text-decoration: none;
}
[data-theme="industrial"] .page-btn {
border-radius: 0;
}
.page-btn:hover:not(:disabled):not(.active) {
background: var(--color-primary-muted);
border-color: var(--color-primary);
color: var(--color-primary);
}
.page-btn.active {
background: var(--color-primary);
color: var(--color-text-inverse);
border-color: var(--color-primary);
}
.page-btn:disabled {
opacity: 0.4;
cursor: not-allowed;
}
.page-ellipsis {
display: inline-flex;
align-items: center;
justify-content: center;
min-width: 36px;
height: 36px;
color: var(--color-text-muted);
font-size: var(--text-body-sm);
}
/* ====== Pagination with info ====== */
.pagination-wrapper {
display: flex;
align-items: center;
justify-content: space-between;
flex-wrap: wrap;
gap: var(--space-4);
padding: var(--space-4);
background: var(--color-bg-elevated);
border: 1px solid var(--color-border);
border-radius: var(--radius-md);
margin-bottom: var(--space-6);
}
[data-theme="industrial"] .pagination-wrapper {
border-radius: 0;
}
.pagination-info {
font-size: var(--text-body-sm);
color: var(--color-text-muted);
}
.pagination-info strong {
color: var(--color-text-primary);
}
.pagination-per-page {
display: flex;
align-items: center;
gap: var(--space-2);
font-size: var(--text-body-sm);
color: var(--color-text-muted);
}
.pagination-per-page select {
padding: var(--space-1) var(--space-3);
background: var(--color-bg-base);
border: 1px solid var(--color-border);
border-radius: var(--radius-sm);
color: var(--color-text-primary);
font-family: var(--font-body);
font-size: var(--text-body-sm);
cursor: pointer;
}
[data-theme="industrial"] .pagination-per-page select {
border-radius: 0;
}
/* ====== Simple Pagination ====== */
.pagination-simple {
display: flex;
align-items: center;
gap: var(--space-4);
}
.pagination-simple-text {
font-size: var(--text-body-sm);
color: var(--color-text-muted);
}
</style>
</head>
<body>
<div class="theme-switcher">
<button class="active" onclick="setTheme('industrial')">🔧 Industrial</button>
<button onclick="setTheme('modern')">⚡ Moderno</button>
</div>
<h1>Pagination</h1>
<p class="subtitle">Paginación para tablas e inventario del sistema POS</p>
<!-- Full Pagination -->
<section>
<h2>Paginación Completa</h2>
<div class="label">Navegación de páginas con números</div>
<div class="pagination">
<button class="page-btn" disabled>← Anterior</button>
<button class="page-btn">1</button>
<button class="page-btn">2</button>
<button class="page-btn active">3</button>
<button class="page-btn">4</button>
<button class="page-btn">5</button>
<span class="page-ellipsis"></span>
<button class="page-btn">42</button>
<button class="page-btn">Siguiente →</button>
</div>
</section>
<!-- Pagination with Context -->
<section>
<h2>Paginación con Contexto</h2>
<div class="label">Información de registros y resultados por página</div>
<div class="pagination-wrapper">
<div class="pagination-info">
Mostrando <strong>41-60</strong> de <strong>1,247</strong> productos
</div>
<div class="pagination">
<button class="page-btn"></button>
<button class="page-btn">1</button>
<button class="page-btn">2</button>
<button class="page-btn active">3</button>
<button class="page-btn">4</button>
<button class="page-btn">5</button>
<span class="page-ellipsis"></span>
<button class="page-btn">63</button>
<button class="page-btn"></button>
</div>
<div class="pagination-per-page">
<span>Mostrar</span>
<select>
<option>10</option>
<option selected>20</option>
<option>50</option>
<option>100</option>
</select>
<span>por página</span>
</div>
</div>
</section>
<!-- Simple Pagination -->
<section>
<h2>Paginación Simple</h2>
<div class="label">Para listas cortas o navegación rápida</div>
<div class="pagination-simple">
<button class="page-btn">← Anterior</button>
<span class="pagination-simple-text">Página 3 de 12</span>
<button class="page-btn">Siguiente →</button>
</div>
</section>
<!-- Large Dataset Pagination -->
<section>
<h2>Paginación — Dataset Grande</h2>
<div class="label">Para el catálogo de 1.4M+ partes</div>
<div class="pagination-wrapper">
<div class="pagination-info">
Mostrando <strong>10,001-10,050</strong> de <strong>1,423,847</strong> partes
</div>
<div class="pagination">
<button class="page-btn"></button>
<button class="page-btn">1</button>
<span class="page-ellipsis"></span>
<button class="page-btn">199</button>
<button class="page-btn active">200</button>
<button class="page-btn">201</button>
<span class="page-ellipsis"></span>
<button class="page-btn">28,477</button>
<button class="page-btn"></button>
</div>
<div class="pagination-per-page">
<span>Mostrar</span>
<select>
<option>25</option>
<option selected>50</option>
<option>100</option>
</select>
<span>por página</span>
</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>

View File

@@ -0,0 +1,421 @@
<!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 — Progress & Loading</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: 500px; }
/* ====== Progress Bar ====== */
.progress-wrapper {
display: flex;
flex-direction: column;
gap: var(--space-1);
}
.progress-header {
display: flex;
justify-content: space-between;
align-items: center;
}
.progress-label {
font-size: var(--text-body-sm);
color: var(--color-text-secondary);
}
.progress-value {
font-size: var(--text-body-sm);
font-weight: var(--font-weight-semibold);
color: var(--color-text-primary);
font-family: var(--font-mono);
}
.progress-bar {
width: 100%;
height: 8px;
background: var(--color-surface-2);
border-radius: var(--radius-full);
overflow: hidden;
}
[data-theme="industrial"] .progress-bar {
border-radius: 0;
}
.progress-fill {
height: 100%;
border-radius: var(--radius-full);
transition: width 0.5s ease;
}
[data-theme="industrial"] .progress-fill {
border-radius: 0;
}
.progress-fill-primary { background: var(--color-primary); }
.progress-fill-success { background: var(--color-success); }
.progress-fill-warning { background: var(--color-warning); }
.progress-fill-error { background: var(--color-error); }
.progress-bar-lg { height: 12px; }
.progress-bar-sm { height: 4px; }
/* Striped animation */
.progress-fill-striped {
background-image: linear-gradient(
45deg,
rgba(255,255,255,0.15) 25%,
transparent 25%,
transparent 50%,
rgba(255,255,255,0.15) 50%,
rgba(255,255,255,0.15) 75%,
transparent 75%,
transparent
);
background-size: 20px 20px;
animation: progress-stripes 1s linear infinite;
}
@keyframes progress-stripes {
0% { background-position: 20px 0; }
100% { background-position: 0 0; }
}
/* ====== Spinners ====== */
.spinner-row {
display: flex;
gap: var(--space-8);
align-items: center;
margin-bottom: var(--space-6);
}
.spinner {
width: 32px;
height: 32px;
border: 3px solid var(--color-border);
border-top-color: var(--color-primary);
border-radius: var(--radius-full);
animation: spin 0.8s linear infinite;
}
.spinner-sm { width: 20px; height: 20px; border-width: 2px; }
.spinner-lg { width: 48px; height: 48px; border-width: 4px; }
@keyframes spin {
to { transform: rotate(360deg); }
}
/* Dot loader */
.dot-loader {
display: flex;
gap: 6px;
align-items: center;
}
.dot-loader span {
width: 8px;
height: 8px;
background: var(--color-primary);
border-radius: var(--radius-full);
animation: dot-bounce 1.4s ease-in-out infinite;
}
.dot-loader span:nth-child(2) { animation-delay: 0.2s; }
.dot-loader span:nth-child(3) { animation-delay: 0.4s; }
@keyframes dot-bounce {
0%, 80%, 100% { transform: scale(0.5); opacity: 0.4; }
40% { transform: scale(1); opacity: 1; }
}
/* Pulse loader */
.pulse-loader {
width: 32px;
height: 32px;
border-radius: var(--radius-full);
background: var(--color-primary);
animation: pulse 1.5s ease-in-out infinite;
}
@keyframes pulse {
0% { transform: scale(0.8); opacity: 1; }
50% { transform: scale(1.2); opacity: 0.4; }
100% { transform: scale(0.8); opacity: 1; }
}
/* ====== Skeleton Loaders ====== */
.skeleton {
background: var(--color-surface-2);
border-radius: var(--radius-md);
position: relative;
overflow: hidden;
}
[data-theme="industrial"] .skeleton {
border-radius: 0;
}
.skeleton::after {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(
90deg,
transparent,
rgba(255,255,255,0.08),
transparent
);
animation: skeleton-shimmer 1.5s ease-in-out infinite;
}
[data-theme="modern"] .skeleton::after {
background: linear-gradient(
90deg,
transparent,
rgba(255,255,255,0.5),
transparent
);
}
@keyframes skeleton-shimmer {
100% { left: 100%; }
}
.skeleton-card {
padding: var(--space-4);
background: var(--color-bg-elevated);
border: 1px solid var(--color-border);
border-radius: var(--radius-md);
max-width: 300px;
}
[data-theme="industrial"] .skeleton-card {
border-radius: 0;
}
.skeleton-img {
width: 100%;
height: 120px;
margin-bottom: var(--space-3);
}
.skeleton-line {
height: 14px;
margin-bottom: var(--space-2);
}
.skeleton-line-short { width: 60%; }
.skeleton-line-medium { width: 80%; }
.skeleton-line-full { width: 100%; }
.skeleton-circle {
width: 40px;
height: 40px;
border-radius: var(--radius-full);
}
/* Table skeleton */
.skeleton-table {
width: 100%;
max-width: 500px;
}
.skeleton-table-row {
display: flex;
gap: var(--space-3);
padding: var(--space-3) 0;
border-bottom: 1px solid var(--color-border);
}
.skeleton-table-cell {
height: 14px;
flex: 1;
}
</style>
</head>
<body>
<div class="theme-switcher">
<button class="active" onclick="setTheme('industrial')">🔧 Industrial</button>
<button onclick="setTheme('modern')">⚡ Moderno</button>
</div>
<h1>Progress & Loading</h1>
<p class="subtitle">Barras de progreso, spinners y skeleton loaders del sistema POS</p>
<!-- Progress Bars -->
<section>
<h2>Progress Bars</h2>
<div class="label">Indicadores de progreso con semántica</div>
<div class="component-col">
<div class="progress-wrapper">
<div class="progress-header">
<span class="progress-label">Sincronización de catálogo</span>
<span class="progress-value">73%</span>
</div>
<div class="progress-bar">
<div class="progress-fill progress-fill-primary" style="width: 73%;"></div>
</div>
</div>
<div class="progress-wrapper">
<div class="progress-header">
<span class="progress-label">Stock saludable</span>
<span class="progress-value">92%</span>
</div>
<div class="progress-bar">
<div class="progress-fill progress-fill-success" style="width: 92%;"></div>
</div>
</div>
<div class="progress-wrapper">
<div class="progress-header">
<span class="progress-label">Capacidad de bodega</span>
<span class="progress-value">68%</span>
</div>
<div class="progress-bar">
<div class="progress-fill progress-fill-warning" style="width: 68%;"></div>
</div>
</div>
<div class="progress-wrapper">
<div class="progress-header">
<span class="progress-label">Productos agotados</span>
<span class="progress-value">15%</span>
</div>
<div class="progress-bar">
<div class="progress-fill progress-fill-error" style="width: 15%;"></div>
</div>
</div>
</div>
<div class="label">Barra animada (en proceso)</div>
<div class="component-col">
<div class="progress-wrapper">
<div class="progress-header">
<span class="progress-label">Importando productos...</span>
<span class="progress-value">45%</span>
</div>
<div class="progress-bar progress-bar-lg">
<div class="progress-fill progress-fill-primary progress-fill-striped" style="width: 45%;"></div>
</div>
</div>
</div>
<div class="label">Tamaños</div>
<div class="component-col">
<div class="progress-bar progress-bar-sm">
<div class="progress-fill progress-fill-primary" style="width: 60%;"></div>
</div>
<div class="progress-bar">
<div class="progress-fill progress-fill-primary" style="width: 60%;"></div>
</div>
<div class="progress-bar progress-bar-lg">
<div class="progress-fill progress-fill-primary" style="width: 60%;"></div>
</div>
</div>
</section>
<!-- Spinners -->
<section>
<h2>Loading Spinners</h2>
<div class="label">Indicadores de carga</div>
<div class="spinner-row">
<div>
<div class="spinner spinner-sm"></div>
<div style="font-size: var(--text-caption); color: var(--color-text-muted); margin-top: var(--space-2); text-align: center;">SM</div>
</div>
<div>
<div class="spinner"></div>
<div style="font-size: var(--text-caption); color: var(--color-text-muted); margin-top: var(--space-2); text-align: center;">MD</div>
</div>
<div>
<div class="spinner spinner-lg"></div>
<div style="font-size: var(--text-caption); color: var(--color-text-muted); margin-top: var(--space-2); text-align: center;">LG</div>
</div>
<div>
<div class="dot-loader">
<span></span><span></span><span></span>
</div>
<div style="font-size: var(--text-caption); color: var(--color-text-muted); margin-top: var(--space-2); text-align: center;">Dots</div>
</div>
<div>
<div class="pulse-loader"></div>
<div style="font-size: var(--text-caption); color: var(--color-text-muted); margin-top: var(--space-2); text-align: center;">Pulse</div>
</div>
</div>
</section>
<!-- Skeleton Loaders -->
<section>
<h2>Skeleton Loaders</h2>
<div class="label">Placeholders de carga para tarjetas de producto</div>
<div style="display: flex; gap: var(--space-4); flex-wrap: wrap; margin-bottom: var(--space-6);">
<div class="skeleton-card">
<div class="skeleton skeleton-img"></div>
<div class="skeleton skeleton-line skeleton-line-full"></div>
<div class="skeleton skeleton-line skeleton-line-medium"></div>
<div class="skeleton skeleton-line skeleton-line-short"></div>
</div>
<div class="skeleton-card">
<div class="skeleton skeleton-img"></div>
<div class="skeleton skeleton-line skeleton-line-full"></div>
<div class="skeleton skeleton-line skeleton-line-medium"></div>
<div class="skeleton skeleton-line skeleton-line-short"></div>
</div>
</div>
<div class="label">Skeleton de tabla</div>
<div class="skeleton-table">
<div class="skeleton-table-row">
<div class="skeleton skeleton-table-cell" style="flex: 0.3;"></div>
<div class="skeleton skeleton-table-cell" style="flex: 1;"></div>
<div class="skeleton skeleton-table-cell" style="flex: 0.5;"></div>
<div class="skeleton skeleton-table-cell" style="flex: 0.4;"></div>
</div>
<div class="skeleton-table-row">
<div class="skeleton skeleton-table-cell" style="flex: 0.3;"></div>
<div class="skeleton skeleton-table-cell" style="flex: 1;"></div>
<div class="skeleton skeleton-table-cell" style="flex: 0.5;"></div>
<div class="skeleton skeleton-table-cell" style="flex: 0.4;"></div>
</div>
<div class="skeleton-table-row">
<div class="skeleton skeleton-table-cell" style="flex: 0.3;"></div>
<div class="skeleton skeleton-table-cell" style="flex: 1;"></div>
<div class="skeleton skeleton-table-cell" style="flex: 0.5;"></div>
<div class="skeleton skeleton-table-cell" style="flex: 0.4;"></div>
</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>

View File

@@ -0,0 +1,412 @@
<!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 — Search Bar</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); }
/* ====== Search Bar ====== */
.search-bar {
display: flex;
align-items: center;
background: var(--color-bg-elevated);
border: 2px solid var(--color-border);
border-radius: var(--radius-lg);
padding: var(--space-1);
transition: var(--transition-fast);
max-width: 700px;
}
[data-theme="industrial"] .search-bar {
border-radius: 0;
clip-path: polygon(0 0, calc(100% - 10px) 0, 100% 10px, 100% 100%, 0 100%);
}
.search-bar:focus-within {
border-color: var(--color-primary);
box-shadow: var(--shadow-focus);
}
.search-icon {
padding: var(--space-2) var(--space-3);
color: var(--color-text-muted);
font-size: var(--text-body-lg);
}
.search-input {
flex: 1;
border: none;
background: transparent;
color: var(--color-text-primary);
font-family: var(--font-body);
font-size: var(--text-body);
padding: var(--space-3);
outline: none;
}
.search-input::placeholder {
color: var(--color-text-muted);
}
.search-shortcut {
padding: var(--space-1) var(--space-2);
background: var(--color-surface-2);
border: 1px solid var(--color-border);
border-radius: var(--radius-sm);
font-size: var(--text-caption);
color: var(--color-text-muted);
font-family: var(--font-mono);
margin-right: var(--space-2);
}
.search-btn {
padding: var(--space-3) var(--space-5);
background: var(--color-primary);
color: var(--color-text-inverse);
border: none;
border-radius: var(--radius-md);
font-family: var(--font-body);
font-size: var(--text-body-sm);
font-weight: var(--font-weight-semibold);
cursor: pointer;
transition: var(--transition-fast);
}
[data-theme="industrial"] .search-btn {
border-radius: 0;
clip-path: polygon(0 0, calc(100% - 6px) 0, 100% 6px, 100% 100%, 0 100%);
}
.search-btn:hover {
background: var(--color-primary-hover);
}
/* ====== Search with Dropdown ====== */
.search-wrapper {
position: relative;
max-width: 700px;
}
.search-dropdown {
position: absolute;
top: calc(100% + var(--space-2));
left: 0;
right: 0;
background: var(--color-bg-elevated);
border: 1px solid var(--color-border);
border-radius: var(--radius-md);
box-shadow: var(--shadow-lg);
z-index: var(--z-dropdown);
overflow: hidden;
}
[data-theme="industrial"] .search-dropdown {
border-radius: 0;
clip-path: polygon(0 0, calc(100% - 8px) 0, 100% 8px, 100% 100%, 0 100%);
}
.search-dropdown-header {
padding: var(--space-2) var(--space-4);
font-size: var(--text-caption);
color: var(--color-text-muted);
text-transform: uppercase;
letter-spacing: var(--tracking-widest);
font-weight: var(--font-weight-semibold);
border-bottom: 1px solid var(--color-border);
}
.search-result {
display: flex;
align-items: center;
gap: var(--space-3);
padding: var(--space-3) var(--space-4);
cursor: pointer;
transition: var(--transition-fast);
}
.search-result:hover {
background: var(--color-primary-muted);
}
.search-result-icon {
width: 40px;
height: 40px;
background: var(--color-surface-2);
border-radius: var(--radius-md);
display: flex;
align-items: center;
justify-content: center;
font-size: var(--text-body-lg);
flex-shrink: 0;
}
[data-theme="industrial"] .search-result-icon {
border-radius: 0;
}
.search-result-info { flex: 1; }
.search-result-title {
font-size: var(--text-body-sm);
font-weight: var(--font-weight-semibold);
color: var(--color-text-primary);
}
.search-result-title mark {
background: var(--color-primary-muted);
color: var(--color-primary);
padding: 0 2px;
border-radius: 2px;
}
.search-result-meta {
font-size: var(--text-caption);
color: var(--color-text-muted);
}
.search-result-price {
font-family: var(--font-mono);
font-weight: var(--font-weight-bold);
color: var(--color-primary);
font-size: var(--text-body-sm);
}
.search-result-stock {
font-size: var(--text-caption);
color: var(--color-success);
}
.search-dropdown-footer {
padding: var(--space-2) var(--space-4);
font-size: var(--text-caption);
color: var(--color-text-muted);
border-top: 1px solid var(--color-border);
text-align: center;
}
/* ====== Vehicle Search ====== */
.vehicle-search {
display: flex;
gap: var(--space-3);
flex-wrap: wrap;
max-width: 700px;
}
.vehicle-select {
flex: 1;
min-width: 150px;
padding: var(--space-3) var(--space-4);
background: var(--color-bg-elevated);
border: 1px solid var(--color-border);
border-radius: var(--radius-md);
color: var(--color-text-primary);
font-family: var(--font-body);
font-size: var(--text-body-sm);
cursor: pointer;
transition: var(--transition-fast);
appearance: none;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%23888' d='M6 8L1 3h10z'/%3E%3C/svg%3E");
background-repeat: no-repeat;
background-position: right 12px center;
padding-right: var(--space-8);
}
[data-theme="industrial"] .vehicle-select {
border-radius: 0;
}
.vehicle-select:focus {
border-color: var(--color-primary);
outline: none;
box-shadow: var(--shadow-focus);
}
.vehicle-search-btn {
padding: var(--space-3) var(--space-6);
background: var(--color-primary);
color: var(--color-text-inverse);
border: none;
border-radius: var(--radius-md);
font-family: var(--font-body);
font-size: var(--text-body-sm);
font-weight: var(--font-weight-semibold);
cursor: pointer;
transition: var(--transition-fast);
}
[data-theme="industrial"] .vehicle-search-btn {
border-radius: 0;
clip-path: polygon(0 0, calc(100% - 8px) 0, 100% 8px, 100% 100%, 0 100%);
}
.vehicle-search-btn:hover { background: var(--color-primary-hover); }
</style>
</head>
<body>
<div class="theme-switcher">
<button class="active" onclick="setTheme('industrial')">🔧 Industrial</button>
<button onclick="setTheme('modern')">⚡ Moderno</button>
</div>
<h1>Search</h1>
<p class="subtitle">Barras de búsqueda con autocompletado para el catálogo POS</p>
<!-- Basic Search -->
<section>
<h2>Búsqueda General</h2>
<div class="label">Barra de búsqueda principal del catálogo</div>
<div class="search-bar" style="margin-bottom: var(--space-6);">
<span class="search-icon">🔍</span>
<input class="search-input" type="text" placeholder="Buscar por nombre, SKU, OEM, marca...">
<span class="search-shortcut">Ctrl+K</span>
<button class="search-btn">Buscar</button>
</div>
</section>
<!-- Search with Autocomplete -->
<section>
<h2>Búsqueda con Autocompletado</h2>
<div class="label">Resultados en tiempo real mientras el usuario escribe</div>
<div class="search-wrapper" style="margin-bottom: var(--space-6);">
<div class="search-bar">
<span class="search-icon">🔍</span>
<input class="search-input" type="text" value="pastillas de freno" placeholder="Buscar...">
<button class="search-btn">Buscar</button>
</div>
<div class="search-dropdown">
<div class="search-dropdown-header">Productos (4 resultados)</div>
<div class="search-result">
<div class="search-result-icon">🔧</div>
<div class="search-result-info">
<div class="search-result-title"><mark>Pastillas de freno</mark> Brembo P50 042</div>
<div class="search-result-meta">SKU: BRM-P50042 · OEM: 04465-33450</div>
</div>
<div style="text-align: right;">
<div class="search-result-price">$1,250.00</div>
<div class="search-result-stock">12 en stock</div>
</div>
</div>
<div class="search-result">
<div class="search-result-icon">🔧</div>
<div class="search-result-info">
<div class="search-result-title"><mark>Pastillas de freno</mark> Wagner QC1210</div>
<div class="search-result-meta">SKU: WGN-QC1210 · OEM: 04465-02220</div>
</div>
<div style="text-align: right;">
<div class="search-result-price">$890.00</div>
<div class="search-result-stock">8 en stock</div>
</div>
</div>
<div class="search-result">
<div class="search-result-icon">🔧</div>
<div class="search-result-info">
<div class="search-result-title"><mark>Pastillas de freno</mark> Akebono ACT1210</div>
<div class="search-result-meta">SKU: AKB-ACT1210 · Aftermarket</div>
</div>
<div style="text-align: right;">
<div class="search-result-price">$650.00</div>
<div class="search-result-stock" style="color: var(--color-warning);">3 en stock</div>
</div>
</div>
<div class="search-dropdown-footer">Ver los 4 resultados para "pastillas de freno" →</div>
</div>
</div>
</section>
<!-- Vehicle Search -->
<section>
<h2>Búsqueda por Vehículo</h2>
<div class="label">Filtrar catálogo por marca, modelo y año</div>
<div class="vehicle-search">
<select class="vehicle-select">
<option>Marca</option>
<option>Toyota</option>
<option>Honda</option>
<option>Nissan</option>
<option>Chevrolet</option>
<option>Ford</option>
<option>Volkswagen</option>
</select>
<select class="vehicle-select">
<option>Modelo</option>
<option>Corolla</option>
<option>Camry</option>
<option>RAV4</option>
<option>Hilux</option>
</select>
<select class="vehicle-select">
<option>Año</option>
<option>2024</option>
<option>2023</option>
<option>2022</option>
<option>2021</option>
<option>2020</option>
</select>
<select class="vehicle-select">
<option>Motor</option>
<option>1.8L</option>
<option>2.0L</option>
<option>2.5L</option>
</select>
<button class="vehicle-search-btn">🔍 Buscar partes</button>
</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>

View File

@@ -0,0 +1,453 @@
<!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 — Tables</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-text {
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-3);
}
/* ====== Table Container ====== */
.table-container {
background: var(--color-bg-elevated);
border: 1px solid var(--color-border);
border-radius: var(--radius-lg);
overflow: hidden;
}
[data-theme="industrial"] .table-container {
border-radius: 0;
clip-path: polygon(0 0, calc(100% - 16px) 0, 100% 16px, 100% 100%, 0 100%);
}
/* Table Toolbar */
.table-toolbar {
display: flex; align-items: center; gap: var(--space-3);
padding: var(--space-4) var(--space-5);
border-bottom: 1px solid var(--color-border);
flex-wrap: wrap;
}
.table-toolbar .search-input {
flex: 1; min-width: 200px;
padding: var(--space-2) var(--space-4);
font-family: var(--font-body); font-size: var(--text-body-sm);
color: var(--color-text-primary); background: var(--color-bg-base);
border: 1px solid var(--color-border); border-radius: var(--radius-md);
outline: none; transition: var(--transition-fast);
}
.table-toolbar .search-input::placeholder { color: var(--color-text-muted); }
.table-toolbar .search-input:focus {
border-color: var(--color-border-focus); box-shadow: var(--shadow-focus);
}
.table-toolbar .toolbar-btn {
padding: var(--space-2) var(--space-3);
font-family: var(--font-body); font-size: var(--text-body-sm);
font-weight: var(--font-weight-semibold);
background: var(--color-bg-base); color: var(--color-text-secondary);
border: 1px solid var(--color-border); border-radius: var(--radius-md);
cursor: pointer; transition: var(--transition-fast);
display: flex; align-items: center; gap: var(--space-1);
}
.table-toolbar .toolbar-btn:hover {
background: var(--color-primary-muted); color: var(--color-primary);
border-color: var(--color-primary);
}
/* Table Itself */
.table {
width: 100%; border-collapse: collapse;
}
.table thead th {
padding: var(--space-3) var(--space-4);
text-align: left;
font-size: var(--text-caption);
font-weight: var(--font-weight-semibold);
color: var(--color-text-muted);
text-transform: uppercase;
letter-spacing: var(--tracking-wider);
background: var(--color-surface-1);
border-bottom: 2px solid var(--color-border);
cursor: pointer; user-select: none;
white-space: nowrap;
}
.table thead th:hover {
color: var(--color-text-primary);
}
.table thead th .sort-icon {
display: inline-block; margin-left: var(--space-1);
opacity: 0.3; font-size: 10px;
}
.table thead th.sorted .sort-icon { opacity: 1; color: var(--color-primary); }
.table tbody tr {
border-bottom: 1px solid var(--color-border);
transition: var(--transition-fast);
}
.table tbody tr:hover {
background: var(--color-primary-muted);
}
.table tbody tr:last-child { border-bottom: none; }
.table tbody td {
padding: var(--space-3) var(--space-4);
font-size: var(--text-body-sm);
vertical-align: middle;
}
.table tbody td.mono {
font-family: var(--font-mono);
letter-spacing: var(--tracking-wide);
}
/* Cell Variants */
.badge {
display: inline-block; padding: 2px var(--space-2);
font-size: 11px; font-weight: var(--font-weight-semibold);
border-radius: var(--radius-sm); text-transform: uppercase;
letter-spacing: var(--tracking-wider);
}
.badge-success { background: var(--color-success-light); color: var(--color-success-dark); }
.badge-warning { background: var(--color-warning-light); color: var(--color-warning-dark); }
.badge-error { background: var(--color-error-light); color: var(--color-error-dark); }
.badge-neutral {
background: var(--color-surface-3); color: var(--color-text-secondary);
}
[data-theme="industrial"] .badge-success { background: rgba(34,197,94,0.15); color: var(--color-success); }
[data-theme="industrial"] .badge-warning { background: rgba(234,179,8,0.15); color: var(--color-warning); }
[data-theme="industrial"] .badge-error { background: rgba(239,68,68,0.15); color: var(--color-error); }
[data-theme="industrial"] .badge-neutral { background: var(--color-surface-3); color: var(--color-text-muted); }
.action-btn {
padding: var(--space-1) var(--space-2);
background: none; border: 1px solid var(--color-border);
color: var(--color-text-muted); border-radius: var(--radius-sm);
cursor: pointer; font-size: 13px; transition: var(--transition-fast);
}
.action-btn:hover {
color: var(--color-primary); border-color: var(--color-primary);
}
/* Checkbox in table */
.table-checkbox {
appearance: none; width: 18px; height: 18px;
border: 2px solid var(--color-border-strong);
border-radius: 3px; background: var(--color-bg-base);
cursor: pointer; transition: var(--transition-fast);
vertical-align: middle;
}
.table-checkbox:checked {
background: var(--color-primary); border-color: var(--color-primary);
}
.table-checkbox:checked::after {
content: '\2713'; color: var(--color-text-inverse);
font-size: 12px; font-weight: bold;
display: flex; align-items: center; justify-content: center;
}
/* ====== Pagination ====== */
.table-pagination {
display: flex; align-items: center; justify-content: space-between;
padding: var(--space-3) var(--space-5);
border-top: 1px solid var(--color-border);
flex-wrap: wrap; gap: var(--space-3);
}
.pagination-info {
font-size: var(--text-body-sm); color: var(--color-text-muted);
}
.pagination-controls {
display: flex; align-items: center; gap: var(--space-1);
}
.page-btn {
display: flex; align-items: center; justify-content: center;
width: 36px; height: 36px;
border: 1px solid var(--color-border);
background: var(--color-bg-base); color: var(--color-text-secondary);
border-radius: var(--radius-md); cursor: pointer;
font-family: var(--font-body); font-size: var(--text-body-sm);
transition: var(--transition-fast);
}
.page-btn:hover:not(:disabled) {
background: var(--color-primary-muted); color: var(--color-primary);
border-color: var(--color-primary);
}
.page-btn.active {
background: var(--color-primary); color: var(--color-text-inverse);
border-color: var(--color-primary);
}
.page-btn:disabled { opacity: 0.3; cursor: not-allowed; }
.per-page-select {
padding: var(--space-1) var(--space-2);
font-family: var(--font-body); font-size: var(--text-body-sm);
background: var(--color-bg-base); color: var(--color-text-primary);
border: 1px solid var(--color-border); border-radius: var(--radius-md);
outline: none;
}
</style>
</head>
<body>
<div class="theme-switcher">
<button class="active" onclick="setTheme('industrial')">Industrial Robusto</button>
<button onclick="setTheme('modern')">Tecnico Moderno</button>
</div>
<h1>Tables</h1>
<p class="subtitle">Tablas con sorting, paginacion y acciones para inventario, ventas y clientes.</p>
<!-- Inventory Table -->
<section>
<h2>Tabla de Inventario</h2>
<p class="label-text">Tabla principal con busqueda, filtros, sorting y paginacion</p>
<div class="table-container">
<div class="table-toolbar">
<input class="search-input" type="text" placeholder="Buscar producto, SKU, marca...">
<button class="toolbar-btn">&#9660; Categoria</button>
<button class="toolbar-btn">&#9660; Stock</button>
<button class="toolbar-btn">&#128229; Exportar</button>
</div>
<table class="table">
<thead>
<tr>
<th style="width: 40px;"><input class="table-checkbox" type="checkbox"></th>
<th>SKU <span class="sort-icon">&#9650;</span></th>
<th class="sorted">Producto <span class="sort-icon">&#9650;</span></th>
<th>Categoria</th>
<th>Precio <span class="sort-icon">&#9660;</span></th>
<th>Stock <span class="sort-icon">&#9650;</span></th>
<th>Estado</th>
<th style="width: 100px;">Acciones</th>
</tr>
</thead>
<tbody>
<tr>
<td><input class="table-checkbox" type="checkbox"></td>
<td class="mono">BRM-BLT-P68064N</td>
<td>Balatas Ceramicas Brembo</td>
<td>Frenos</td>
<td class="mono">$892.00</td>
<td class="mono">24</td>
<td><span class="badge badge-success">En stock</span></td>
<td>
<button class="action-btn" title="Editar">&#9998;</button>
<button class="action-btn" title="Eliminar">&#10005;</button>
</td>
</tr>
<tr>
<td><input class="table-checkbox" type="checkbox" checked></td>
<td class="mono">MOB-OIL-5W30-1L</td>
<td>Aceite Sintetico Mobil 1 5W-30</td>
<td>Motor</td>
<td class="mono">$345.00</td>
<td class="mono" style="color: var(--color-warning);">3</td>
<td><span class="badge badge-warning">Stock bajo</span></td>
<td>
<button class="action-btn" title="Editar">&#9998;</button>
<button class="action-btn" title="Eliminar">&#10005;</button>
</td>
</tr>
<tr>
<td><input class="table-checkbox" type="checkbox"></td>
<td class="mono">MNR-AMT-72321</td>
<td>Amortiguador Monroe Sensatrac</td>
<td>Suspension</td>
<td class="mono">$1,650.00</td>
<td class="mono" style="color: var(--color-error);">0</td>
<td><span class="badge badge-error">Sin stock</span></td>
<td>
<button class="action-btn" title="Editar">&#9998;</button>
<button class="action-btn" title="Eliminar">&#10005;</button>
</td>
</tr>
<tr>
<td><input class="table-checkbox" type="checkbox"></td>
<td class="mono">NGK-BUJ-BKR6E</td>
<td>Bujia NGK BKR6E Iridium</td>
<td>Encendido</td>
<td class="mono">$189.00</td>
<td class="mono">156</td>
<td><span class="badge badge-success">En stock</span></td>
<td>
<button class="action-btn" title="Editar">&#9998;</button>
<button class="action-btn" title="Eliminar">&#10005;</button>
</td>
</tr>
<tr>
<td><input class="table-checkbox" type="checkbox"></td>
<td class="mono">GTS-FLT-AF123</td>
<td>Filtro de Aire Gates AF123</td>
<td>Filtracion</td>
<td class="mono">$245.00</td>
<td class="mono">42</td>
<td><span class="badge badge-success">En stock</span></td>
<td>
<button class="action-btn" title="Editar">&#9998;</button>
<button class="action-btn" title="Eliminar">&#10005;</button>
</td>
</tr>
<tr>
<td><input class="table-checkbox" type="checkbox"></td>
<td class="mono">BOH-DSC-BD5678</td>
<td>Disco de Freno Bosch BD5678</td>
<td>Frenos</td>
<td class="mono">$1,120.00</td>
<td class="mono" style="color: var(--color-warning);">5</td>
<td><span class="badge badge-warning">Stock bajo</span></td>
<td>
<button class="action-btn" title="Editar">&#9998;</button>
<button class="action-btn" title="Eliminar">&#10005;</button>
</td>
</tr>
</tbody>
</table>
<div class="table-pagination">
<div class="pagination-info">
Mostrando <strong>1-6</strong> de <strong>1,423</strong> productos
&nbsp;|&nbsp;
<select class="per-page-select">
<option>10 por pagina</option>
<option>25 por pagina</option>
<option>50 por pagina</option>
<option>100 por pagina</option>
</select>
</div>
<div class="pagination-controls">
<button class="page-btn" disabled title="Primera">&laquo;</button>
<button class="page-btn" disabled title="Anterior">&lsaquo;</button>
<button class="page-btn active">1</button>
<button class="page-btn">2</button>
<button class="page-btn">3</button>
<button class="page-btn">...</button>
<button class="page-btn">143</button>
<button class="page-btn" title="Siguiente">&rsaquo;</button>
<button class="page-btn" title="Ultima">&raquo;</button>
</div>
</div>
</div>
</section>
<!-- Sales Table (compact) -->
<section>
<h2>Tabla de Ventas</h2>
<p class="label-text">Tabla compacta para historial de ventas del dia</p>
<div class="table-container">
<table class="table">
<thead>
<tr>
<th>Folio</th>
<th>Hora</th>
<th>Cliente</th>
<th>Productos</th>
<th>Total</th>
<th>Pago</th>
<th>Estado</th>
</tr>
</thead>
<tbody>
<tr>
<td class="mono">V-2026-0847</td>
<td>14:32</td>
<td>Taller El Rapido</td>
<td>4 items</td>
<td class="mono" style="font-weight: var(--font-weight-bold);">$3,680.00</td>
<td>Credito</td>
<td><span class="badge badge-success">Completada</span></td>
</tr>
<tr>
<td class="mono">V-2026-0846</td>
<td>13:15</td>
<td>Publico General</td>
<td>1 item</td>
<td class="mono" style="font-weight: var(--font-weight-bold);">$892.00</td>
<td>Efectivo</td>
<td><span class="badge badge-success">Completada</span></td>
</tr>
<tr>
<td class="mono">V-2026-0845</td>
<td>12:48</td>
<td>Refacciones Alvarez</td>
<td>12 items</td>
<td class="mono" style="font-weight: var(--font-weight-bold);">$15,420.00</td>
<td>Transferencia</td>
<td><span class="badge badge-warning">Pendiente</span></td>
</tr>
<tr>
<td class="mono">V-2026-0844</td>
<td>11:20</td>
<td>Auto Servicio Lopez</td>
<td>3 items</td>
<td class="mono" style="font-weight: var(--font-weight-bold);">$2,145.00</td>
<td>Tarjeta</td>
<td><span class="badge badge-error">Cancelada</span></td>
</tr>
</tbody>
</table>
</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.toLowerCase().includes(theme === 'industrial' ? 'industrial' : 'tecnico'));
});
}
// Sort demo
document.querySelectorAll('.table thead th').forEach(th => {
th.addEventListener('click', () => {
th.closest('thead').querySelectorAll('th').forEach(h => h.classList.remove('sorted'));
th.classList.add('sorted');
const icon = th.querySelector('.sort-icon');
if (icon) {
icon.innerHTML = icon.innerHTML === '\u25B2' ? '\u25BC' : '\u25B2';
}
});
});
</script>
</body>
</html>

View File

@@ -0,0 +1,312 @@
<!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 — Tabs (Contextuales)</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); }
/* ====== Tab Navigation ====== */
.tab-nav {
display: flex;
border-bottom: 2px solid var(--color-border);
gap: 0;
overflow-x: auto;
}
.tab-nav-item {
padding: var(--space-3) var(--space-5);
font-family: var(--font-body);
font-size: var(--text-body-sm);
font-weight: var(--font-weight-semibold);
color: var(--color-text-muted);
background: transparent;
border: none;
cursor: pointer;
position: relative;
transition: var(--transition-fast);
white-space: nowrap;
}
.tab-nav-item:hover { color: var(--color-text-primary); }
.tab-nav-item.active {
color: var(--color-primary);
}
.tab-nav-item.active::after {
content: '';
position: absolute;
bottom: -2px;
left: 0;
right: 0;
height: 2px;
background: var(--color-primary);
}
.tab-nav-item .tab-count {
margin-left: var(--space-2);
font-size: var(--text-caption);
background: var(--color-primary-muted);
color: var(--color-primary);
padding: 1px 8px;
border-radius: var(--radius-full);
}
.tab-nav-item.active .tab-count {
background: var(--color-primary);
color: var(--color-text-inverse);
}
/* Tab Panel */
.tab-panel {
padding: var(--space-5);
background: var(--color-bg-elevated);
border: 1px solid var(--color-border);
border-top: none;
border-radius: 0 0 var(--radius-md) var(--radius-md);
min-height: 120px;
}
[data-theme="industrial"] .tab-panel { border-radius: 0; }
.tab-panel-content {
font-size: var(--text-body-sm);
color: var(--color-text-secondary);
}
/* ====== Vertical Tabs ====== */
.vertical-tabs {
display: flex;
gap: 0;
border: 1px solid var(--color-border);
border-radius: var(--radius-md);
overflow: hidden;
max-width: 600px;
}
[data-theme="industrial"] .vertical-tabs { border-radius: 0; }
.vertical-tab-nav {
display: flex;
flex-direction: column;
min-width: 180px;
background: var(--color-bg-elevated);
border-right: 1px solid var(--color-border);
}
.vertical-tab-item {
padding: var(--space-3) var(--space-4);
font-family: var(--font-body);
font-size: var(--text-body-sm);
color: var(--color-text-muted);
background: transparent;
border: none;
border-left: 3px solid transparent;
cursor: pointer;
transition: var(--transition-fast);
text-align: left;
}
.vertical-tab-item:hover {
color: var(--color-text-primary);
background: var(--color-primary-muted);
}
.vertical-tab-item.active {
color: var(--color-primary);
border-left-color: var(--color-primary);
background: var(--color-primary-muted);
font-weight: var(--font-weight-semibold);
}
.vertical-tab-content {
flex: 1;
padding: var(--space-4);
font-size: var(--text-body-sm);
color: var(--color-text-secondary);
}
/* ====== Card Tabs ====== */
.card-tabs {
display: flex;
gap: var(--space-1);
background: var(--color-bg-elevated);
padding: var(--space-1);
border-radius: var(--radius-lg);
border: 1px solid var(--color-border);
}
[data-theme="industrial"] .card-tabs { border-radius: 0; }
.card-tab {
flex: 1;
padding: var(--space-3) var(--space-4);
font-family: var(--font-body);
font-size: var(--text-body-sm);
font-weight: var(--font-weight-semibold);
color: var(--color-text-muted);
background: transparent;
border: none;
border-radius: var(--radius-md);
cursor: pointer;
transition: var(--transition-fast);
text-align: center;
}
[data-theme="industrial"] .card-tab { border-radius: 0; }
.card-tab:hover { color: var(--color-text-primary); }
.card-tab.active {
background: var(--color-primary);
color: var(--color-text-inverse);
box-shadow: var(--shadow-sm);
}
/* Stat in tabs */
.tab-stat {
display: block;
font-size: var(--text-h4);
font-family: var(--font-heading);
font-weight: var(--heading-weight-primary);
margin-top: var(--space-1);
}
.card-tab.active .tab-stat { color: var(--color-text-inverse); }
.card-tab:not(.active) .tab-stat { color: var(--color-text-primary); }
</style>
</head>
<body>
<div class="theme-switcher">
<button class="active" onclick="setTheme('industrial')">🔧 Industrial</button>
<button onclick="setTheme('modern')">⚡ Moderno</button>
</div>
<h1>Tabs (Contextuales)</h1>
<p class="subtitle">Tab navigation para inventario, contabilidad y configuración del POS</p>
<!-- Inventory Tabs -->
<section>
<h2>Tabs — Inventario</h2>
<div class="label">Navegación de inventario con contadores</div>
<div class="tab-nav">
<button class="tab-nav-item active">Todos <span class="tab-count">1,247</span></button>
<button class="tab-nav-item">En stock <span class="tab-count">980</span></button>
<button class="tab-nav-item">Bajo stock <span class="tab-count">45</span></button>
<button class="tab-nav-item">Agotados <span class="tab-count">15</span></button>
<button class="tab-nav-item">Por llegar <span class="tab-count">8</span></button>
<button class="tab-nav-item">Descontinuados <span class="tab-count">199</span></button>
</div>
<div class="tab-panel">
<div class="tab-panel-content">
Tabla de inventario con todos los productos. Incluye columnas: SKU, nombre, marca, stock, precio, ubicación.
</div>
</div>
</section>
<!-- Accounting Tabs -->
<section>
<h2>Tabs — Contabilidad</h2>
<div class="label">Módulos financieros del POS</div>
<div class="tab-nav">
<button class="tab-nav-item active">Ventas del día</button>
<button class="tab-nav-item">Compras</button>
<button class="tab-nav-item">Cuentas por Cobrar</button>
<button class="tab-nav-item">Cuentas por Pagar</button>
<button class="tab-nav-item">Corte de Caja</button>
<button class="tab-nav-item">Reportes</button>
</div>
<div class="tab-panel">
<div class="tab-panel-content">
Resumen de ventas del día actual. Total: $45,890.00 MXN · 23 transacciones · Ticket promedio: $1,995.22
</div>
</div>
</section>
<!-- Product Detail Tabs -->
<section>
<h2>Tabs — Detalle de Producto</h2>
<div class="label">Información del producto organizada en tabs</div>
<div class="tab-nav">
<button class="tab-nav-item active">General</button>
<button class="tab-nav-item">Precios y costos</button>
<button class="tab-nav-item">Compatibilidad <span class="tab-count">24</span></button>
<button class="tab-nav-item">Proveedores</button>
<button class="tab-nav-item">Historial</button>
</div>
<div class="tab-panel">
<div class="tab-panel-content">
Información general del producto: nombre, SKU, OEM, categoría, marca, descripción, imagen.
</div>
</div>
</section>
<!-- Vertical Tabs -->
<section>
<h2>Tabs Verticales — Configuración</h2>
<div class="label">Navegación lateral para secciones de configuración</div>
<div class="vertical-tabs">
<div class="vertical-tab-nav">
<button class="vertical-tab-item active">General</button>
<button class="vertical-tab-item">Sucursales</button>
<button class="vertical-tab-item">Usuarios y roles</button>
<button class="vertical-tab-item">Impuestos</button>
<button class="vertical-tab-item">Impresoras</button>
<button class="vertical-tab-item">Notificaciones</button>
<button class="vertical-tab-item">Integraciones</button>
</div>
<div class="vertical-tab-content">
Configuración general del sistema: nombre del negocio, dirección, RFC, logo, moneda y zona horaria.
</div>
</div>
</section>
<!-- Dashboard Card Tabs -->
<section>
<h2>Card Tabs — Dashboard</h2>
<div class="label">Tabs con estadísticas para el dashboard</div>
<div class="card-tabs" style="max-width: 600px;">
<button class="card-tab active">
Ventas hoy
<span class="tab-stat">$45,890</span>
</button>
<button class="card-tab">
Productos vendidos
<span class="tab-stat">127</span>
</button>
<button class="card-tab">
Ticket promedio
<span class="tab-stat">$1,995</span>
</button>
</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>

View File

@@ -0,0 +1,398 @@
<!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 — Toggles & Switches</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); }
/* ====== Toggle Switch ====== */
.toggle-group {
display: flex;
flex-direction: column;
gap: var(--space-4);
max-width: 400px;
margin-bottom: var(--space-6);
}
.toggle-row {
display: flex;
align-items: center;
justify-content: space-between;
gap: var(--space-4);
}
.toggle-label-text {
font-size: var(--text-body-sm);
color: var(--color-text-primary);
}
.toggle-label-desc {
font-size: var(--text-caption);
color: var(--color-text-muted);
}
.toggle {
position: relative;
width: 44px;
height: 24px;
flex-shrink: 0;
}
.toggle input {
opacity: 0;
width: 0;
height: 0;
}
.toggle-slider {
position: absolute;
top: 0; left: 0; right: 0; bottom: 0;
background: var(--color-border-strong);
border-radius: var(--radius-full);
cursor: pointer;
transition: var(--transition-fast);
}
[data-theme="industrial"] .toggle-slider {
border-radius: var(--radius-sm);
}
.toggle-slider::before {
content: '';
position: absolute;
width: 18px;
height: 18px;
left: 3px;
bottom: 3px;
background: white;
border-radius: var(--radius-full);
transition: var(--transition-fast);
}
[data-theme="industrial"] .toggle-slider::before {
border-radius: 2px;
}
.toggle input:checked + .toggle-slider {
background: var(--color-primary);
}
.toggle input:checked + .toggle-slider::before {
transform: translateX(20px);
}
.toggle input:focus-visible + .toggle-slider {
box-shadow: var(--shadow-focus);
}
.toggle input:disabled + .toggle-slider {
opacity: 0.4;
cursor: not-allowed;
}
/* Toggle sizes */
.toggle-sm { width: 36px; height: 20px; }
.toggle-sm .toggle-slider::before { width: 14px; height: 14px; }
.toggle-sm input:checked + .toggle-slider::before { transform: translateX(16px); }
.toggle-lg { width: 52px; height: 28px; }
.toggle-lg .toggle-slider::before { width: 22px; height: 22px; }
.toggle-lg input:checked + .toggle-slider::before { transform: translateX(24px); }
/* ====== Checkboxes ====== */
.checkbox-group {
display: flex;
flex-direction: column;
gap: var(--space-3);
margin-bottom: var(--space-6);
}
.checkbox-item {
display: flex;
align-items: center;
gap: var(--space-3);
cursor: pointer;
}
.checkbox-custom {
width: 20px;
height: 20px;
border: 2px solid var(--color-border-strong);
border-radius: var(--radius-sm);
display: flex;
align-items: center;
justify-content: center;
transition: var(--transition-fast);
flex-shrink: 0;
background: var(--color-bg-base);
}
[data-theme="industrial"] .checkbox-custom {
border-radius: 0;
}
.checkbox-item input { display: none; }
.checkbox-item input:checked + .checkbox-custom {
background: var(--color-primary);
border-color: var(--color-primary);
}
.checkbox-item input:checked + .checkbox-custom::after {
content: '✓';
color: var(--color-text-inverse);
font-size: 12px;
font-weight: bold;
}
.checkbox-item:hover .checkbox-custom {
border-color: var(--color-primary);
}
.checkbox-text {
font-size: var(--text-body-sm);
color: var(--color-text-primary);
}
/* ====== Radio Buttons ====== */
.radio-group {
display: flex;
flex-direction: column;
gap: var(--space-3);
margin-bottom: var(--space-6);
}
.radio-item {
display: flex;
align-items: center;
gap: var(--space-3);
cursor: pointer;
}
.radio-custom {
width: 20px;
height: 20px;
border: 2px solid var(--color-border-strong);
border-radius: var(--radius-full);
display: flex;
align-items: center;
justify-content: center;
transition: var(--transition-fast);
flex-shrink: 0;
background: var(--color-bg-base);
}
[data-theme="industrial"] .radio-custom {
border-radius: var(--radius-full); /* radios stay circular even in industrial */
}
.radio-item input { display: none; }
.radio-item input:checked + .radio-custom {
border-color: var(--color-primary);
}
.radio-item input:checked + .radio-custom::after {
content: '';
width: 10px;
height: 10px;
border-radius: var(--radius-full);
background: var(--color-primary);
}
.radio-item:hover .radio-custom {
border-color: var(--color-primary);
}
.radio-text {
font-size: var(--text-body-sm);
color: var(--color-text-primary);
}
.radio-text-desc {
font-size: var(--text-caption);
color: var(--color-text-muted);
}
</style>
</head>
<body>
<div class="theme-switcher">
<button class="active" onclick="setTheme('industrial')">🔧 Industrial</button>
<button onclick="setTheme('modern')">⚡ Moderno</button>
</div>
<h1>Toggles & Switches</h1>
<p class="subtitle">Switches, checkboxes y radio buttons del sistema POS</p>
<!-- Toggle Switches -->
<section>
<h2>Toggle Switches</h2>
<div class="label">Configuración del sistema POS</div>
<div class="toggle-group">
<div class="toggle-row">
<div>
<div class="toggle-label-text">Notificaciones de stock bajo</div>
<div class="toggle-label-desc">Alertar cuando un producto baje de 5 unidades</div>
</div>
<label class="toggle">
<input type="checkbox" checked>
<span class="toggle-slider"></span>
</label>
</div>
<div class="toggle-row">
<div>
<div class="toggle-label-text">Modo oscuro</div>
<div class="toggle-label-desc">Tema industrial para el POS</div>
</div>
<label class="toggle">
<input type="checkbox" checked>
<span class="toggle-slider"></span>
</label>
</div>
<div class="toggle-row">
<div>
<div class="toggle-label-text">Impresión automática</div>
<div class="toggle-label-desc">Imprimir ticket al completar venta</div>
</div>
<label class="toggle">
<input type="checkbox">
<span class="toggle-slider"></span>
</label>
</div>
<div class="toggle-row">
<div>
<div class="toggle-label-text">Descuentos manuales</div>
<div class="toggle-label-desc">Permitir al vendedor aplicar descuentos (deshabilitado)</div>
</div>
<label class="toggle">
<input type="checkbox" disabled>
<span class="toggle-slider"></span>
</label>
</div>
</div>
<div class="label">Tamaños de toggle</div>
<div style="display: flex; gap: var(--space-6); align-items: center; margin-bottom: var(--space-6);">
<label class="toggle toggle-sm">
<input type="checkbox" checked>
<span class="toggle-slider"></span>
</label>
<span style="font-size: var(--text-caption); color: var(--color-text-muted);">SM</span>
<label class="toggle">
<input type="checkbox" checked>
<span class="toggle-slider"></span>
</label>
<span style="font-size: var(--text-caption); color: var(--color-text-muted);">MD</span>
<label class="toggle toggle-lg">
<input type="checkbox" checked>
<span class="toggle-slider"></span>
</label>
<span style="font-size: var(--text-caption); color: var(--color-text-muted);">LG</span>
</div>
</section>
<!-- Checkboxes -->
<section>
<h2>Checkboxes</h2>
<div class="label">Selección múltiple (filtros de categoría)</div>
<div class="checkbox-group">
<label class="checkbox-item">
<input type="checkbox" checked>
<span class="checkbox-custom"></span>
<span class="checkbox-text">Frenos y pastillas</span>
</label>
<label class="checkbox-item">
<input type="checkbox" checked>
<span class="checkbox-custom"></span>
<span class="checkbox-text">Filtros de aceite</span>
</label>
<label class="checkbox-item">
<input type="checkbox">
<span class="checkbox-custom"></span>
<span class="checkbox-text">Bujías y encendido</span>
</label>
<label class="checkbox-item">
<input type="checkbox">
<span class="checkbox-custom"></span>
<span class="checkbox-text">Suspensión y dirección</span>
</label>
<label class="checkbox-item">
<input type="checkbox">
<span class="checkbox-custom"></span>
<span class="checkbox-text">Sistema eléctrico</span>
</label>
</div>
</section>
<!-- Radio Buttons -->
<section>
<h2>Radio Buttons</h2>
<div class="label">Selección única (método de pago)</div>
<div class="radio-group">
<label class="radio-item">
<input type="radio" name="payment" checked>
<span class="radio-custom"></span>
<div>
<div class="radio-text">Efectivo</div>
<div class="radio-text-desc">Pago en efectivo en caja</div>
</div>
</label>
<label class="radio-item">
<input type="radio" name="payment">
<span class="radio-custom"></span>
<div>
<div class="radio-text">Tarjeta de crédito/débito</div>
<div class="radio-text-desc">Terminal punto de venta</div>
</div>
</label>
<label class="radio-item">
<input type="radio" name="payment">
<span class="radio-custom"></span>
<div>
<div class="radio-text">Transferencia bancaria</div>
<div class="radio-text-desc">SPEI o depósito</div>
</div>
</label>
<label class="radio-item">
<input type="radio" name="payment">
<span class="radio-custom"></span>
<div>
<div class="radio-text">Crédito del cliente</div>
<div class="radio-text-desc">Cargo a cuenta por cobrar</div>
</div>
</label>
</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>

View File

@@ -0,0 +1,315 @@
<!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 — Tooltips & Popovers</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-row { display: flex; flex-wrap: wrap; gap: var(--space-8); align-items: flex-start; margin-bottom: var(--space-6); }
/* ====== Tooltip ====== */
.tooltip-demo {
position: relative;
display: inline-flex;
flex-direction: column;
align-items: center;
}
.tooltip-trigger {
display: inline-flex;
align-items: center;
justify-content: center;
padding: var(--space-3) var(--space-5);
background: var(--color-bg-elevated);
border: 1px solid var(--color-border);
border-radius: var(--radius-md);
color: var(--color-text-secondary);
font-family: var(--font-body);
font-size: var(--text-body-sm);
cursor: help;
}
[data-theme="industrial"] .tooltip-trigger { border-radius: 0; }
.tooltip {
padding: var(--space-2) var(--space-3);
background: var(--color-bg-overlay);
border: 1px solid var(--color-border);
border-radius: var(--radius-sm);
box-shadow: var(--shadow-md);
font-size: var(--text-caption);
color: var(--color-text-primary);
white-space: nowrap;
margin-top: var(--space-2);
}
[data-theme="industrial"] .tooltip {
border-radius: 0;
border-left: 2px solid var(--color-primary);
}
.tooltip-arrow {
text-align: center;
color: var(--color-border);
font-size: 10px;
line-height: 1;
}
/* ====== Popover ====== */
.popover {
background: var(--color-bg-elevated);
border: 1px solid var(--color-border);
border-radius: var(--radius-md);
box-shadow: var(--shadow-lg);
padding: var(--space-4);
max-width: 300px;
margin-top: var(--space-2);
}
[data-theme="industrial"] .popover {
border-radius: 0;
clip-path: polygon(0 0, calc(100% - 10px) 0, 100% 10px, 100% 100%, 0 100%);
}
.popover-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: var(--space-3);
padding-bottom: var(--space-2);
border-bottom: 1px solid var(--color-border);
}
.popover-title {
font-weight: var(--font-weight-semibold);
font-size: var(--text-body-sm);
color: var(--color-text-primary);
}
.popover-close {
background: none;
border: none;
color: var(--color-text-muted);
cursor: pointer;
font-size: var(--text-body-sm);
}
.popover-body {
font-size: var(--text-body-sm);
color: var(--color-text-secondary);
line-height: var(--leading-body-sm);
}
.popover-footer {
margin-top: var(--space-3);
padding-top: var(--space-2);
border-top: 1px solid var(--color-border);
display: flex;
gap: var(--space-2);
justify-content: flex-end;
}
.popover-btn {
padding: var(--space-1) var(--space-3);
font-family: var(--font-body);
font-size: var(--text-caption);
font-weight: var(--font-weight-semibold);
border-radius: var(--radius-sm);
cursor: pointer;
transition: var(--transition-fast);
border: 1px solid;
}
[data-theme="industrial"] .popover-btn { border-radius: 0; }
.popover-btn-primary {
background: var(--color-primary);
color: var(--color-text-inverse);
border-color: var(--color-primary);
}
.popover-btn-ghost {
background: transparent;
color: var(--color-text-muted);
border-color: var(--color-border);
}
/* ====== Info tooltip (icon) ====== */
.info-icon {
display: inline-flex;
align-items: center;
justify-content: center;
width: 18px;
height: 18px;
border-radius: var(--radius-full);
background: var(--color-primary-muted);
color: var(--color-primary);
font-size: 11px;
font-weight: var(--font-weight-bold);
cursor: help;
}
/* Product info popover */
.product-info-row {
display: flex;
justify-content: space-between;
padding: var(--space-1) 0;
font-size: var(--text-caption);
}
.product-info-label {
color: var(--color-text-muted);
}
.product-info-value {
color: var(--color-text-primary);
font-weight: var(--font-weight-semibold);
}
</style>
</head>
<body>
<div class="theme-switcher">
<button class="active" onclick="setTheme('industrial')">🔧 Industrial</button>
<button onclick="setTheme('modern')">⚡ Moderno</button>
</div>
<h1>Tooltips & Popovers</h1>
<p class="subtitle">Tooltips informativos y popovers interactivos del sistema POS</p>
<!-- Basic Tooltips -->
<section>
<h2>Tooltips</h2>
<div class="label">Información rápida al pasar el cursor</div>
<div class="component-row">
<div class="tooltip-demo">
<div class="tooltip-trigger">🛒 Agregar al carrito</div>
<div class="tooltip-arrow"></div>
<div class="tooltip">Agrega este producto a la venta actual</div>
</div>
<div class="tooltip-demo">
<div class="tooltip-trigger">📦 Stock: 12</div>
<div class="tooltip-arrow"></div>
<div class="tooltip">Unidades disponibles en bodega principal</div>
</div>
<div class="tooltip-demo">
<div class="tooltip-trigger">🏷️ OEM: 04465-33450</div>
<div class="tooltip-arrow"></div>
<div class="tooltip">Número de parte original del fabricante</div>
</div>
<div class="tooltip-demo">
<div class="tooltip-trigger">⚠ Bajo stock</div>
<div class="tooltip-arrow"></div>
<div class="tooltip">Quedan menos de 5 unidades. Reorden sugerido.</div>
</div>
</div>
</section>
<!-- Info Icon Tooltips -->
<section>
<h2>Info Icons</h2>
<div class="label">Iconos de ayuda con tooltip</div>
<div style="display: flex; flex-direction: column; gap: var(--space-4); max-width: 400px;">
<div style="display: flex; align-items: center; gap: var(--space-2); font-size: var(--text-body-sm);">
<span>Precio mayoreo</span>
<span class="info-icon">?</span>
<span style="font-size: var(--text-caption); color: var(--color-text-muted);">← Precio para compras de 10+ unidades</span>
</div>
<div style="display: flex; align-items: center; gap: var(--space-2); font-size: var(--text-body-sm);">
<span>Margen de ganancia</span>
<span class="info-icon">?</span>
<span style="font-size: var(--text-caption); color: var(--color-text-muted);">← Diferencia entre costo y precio de venta</span>
</div>
</div>
</section>
<!-- Popovers -->
<section>
<h2>Popovers</h2>
<div class="label">Información detallada con acciones</div>
<div class="component-row">
<!-- Product Info Popover -->
<div>
<div class="tooltip-trigger" style="margin-bottom: var(--space-2);">Ver info del producto</div>
<div class="popover">
<div class="popover-header">
<span class="popover-title">Pastillas Brembo P50 042</span>
<button class="popover-close"></button>
</div>
<div class="popover-body">
<div class="product-info-row">
<span class="product-info-label">SKU</span>
<span class="product-info-value">BRM-P50042</span>
</div>
<div class="product-info-row">
<span class="product-info-label">OEM</span>
<span class="product-info-value">04465-33450</span>
</div>
<div class="product-info-row">
<span class="product-info-label">Precio</span>
<span class="product-info-value" style="color: var(--color-primary);">$1,250.00</span>
</div>
<div class="product-info-row">
<span class="product-info-label">Stock</span>
<span class="product-info-value" style="color: var(--color-success);">12 uds</span>
</div>
<div class="product-info-row">
<span class="product-info-label">Ubicación</span>
<span class="product-info-value">Estante A-14</span>
</div>
</div>
<div class="popover-footer">
<button class="popover-btn popover-btn-ghost">Cerrar</button>
<button class="popover-btn popover-btn-primary">Agregar a venta</button>
</div>
</div>
</div>
<!-- Confirm Popover -->
<div>
<div class="tooltip-trigger" style="margin-bottom: var(--space-2); color: var(--color-error);">🗑️ Eliminar producto</div>
<div class="popover">
<div class="popover-header">
<span class="popover-title">Confirmar eliminación</span>
<button class="popover-close"></button>
</div>
<div class="popover-body">
¿Estás seguro de eliminar este producto? Esta acción no se puede deshacer.
</div>
<div class="popover-footer">
<button class="popover-btn popover-btn-ghost">Cancelar</button>
<button class="popover-btn" style="background: var(--color-error); color: white; border-color: var(--color-error);">Eliminar</button>
</div>
</div>
</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>