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>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,564 @@
/* ==========================================================================
NEXUS AUTOPARTS — Design Tokens
POS System for Auto Parts Stores
Version: 1.0.0
==========================================================================
Themes:
- [data-theme="industrial"] — Industrial Robusto (Dark)
- [data-theme="modern"] — Técnico Moderno (Light)
========================================================================== */
/* --------------------------------------------------------------------------
GOOGLE FONTS IMPORTS
-------------------------------------------------------------------------- */
@import url('https://fonts.googleapis.com/css2?family=Barlow:wght@400;700&family=Barlow+Condensed:wght@600;800&family=Poppins:wght@300;400;600;700&display=swap');
/* ==========================================================================
GLOBAL TOKENS — Theme-independent, shared across both themes
========================================================================== */
:root {
/* ------------------------------------------------------------------------
SEMANTIC COLORS — Status / Feedback (shared)
------------------------------------------------------------------------ */
--color-success: #22c55e;
--color-success-light: #bbf7d0;
--color-success-dark: #15803d;
--color-warning: #eab308;
--color-warning-light: #fef08a;
--color-warning-dark: #a16207;
--color-error: #ef4444;
--color-error-light: #fecaca;
--color-error-dark: #b91c1c;
/* ------------------------------------------------------------------------
NEUTRAL SCALE — Grey ramp (50900)
------------------------------------------------------------------------ */
--color-neutral-50: #fafafa;
--color-neutral-100: #f5f5f5;
--color-neutral-200: #e5e5e5;
--color-neutral-300: #d4d4d4;
--color-neutral-400: #a3a3a3;
--color-neutral-500: #737373;
--color-neutral-600: #525252;
--color-neutral-700: #404040;
--color-neutral-800: #262626;
--color-neutral-900: #171717;
/* ------------------------------------------------------------------------
SPACING — 4px base grid
------------------------------------------------------------------------ */
/* --space-N = N × 4px */
--space-1: 4px; /* 4px */
--space-2: 8px; /* 8px */
--space-3: 12px; /* 12px */
--space-4: 16px; /* 16px */
--space-5: 20px; /* 20px */
--space-6: 24px; /* 24px */
--space-7: 28px; /* 28px */
--space-8: 32px; /* 32px */
--space-9: 36px; /* 36px */
--space-10: 40px; /* 40px */
--space-11: 44px; /* 44px */
--space-12: 48px; /* 48px */
--space-14: 56px; /* 56px */
--space-16: 64px; /* 64px */
/* ------------------------------------------------------------------------
BORDER RADIUS
------------------------------------------------------------------------ */
--radius-sm: 4px;
--radius-md: 8px;
--radius-lg: 12px;
--radius-xl: 20px;
--radius-full: 9999px;
/* ------------------------------------------------------------------------
TRANSITIONS
------------------------------------------------------------------------ */
--transition-fast: all 0.10s ease;
--transition-normal: all 0.20s ease;
--transition-slow: all 0.40s ease;
/* Easing functions for fine-grained control */
--ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);
--ease-out: cubic-bezier(0, 0, 0.2, 1);
--ease-in: cubic-bezier(0.4, 0, 1, 1);
--duration-fast: 100ms;
--duration-normal: 200ms;
--duration-slow: 400ms;
/* ------------------------------------------------------------------------
Z-INDEX SCALE
------------------------------------------------------------------------ */
--z-dropdown: 1000;
--z-sticky: 1020;
--z-modal: 1050;
--z-toast: 1080;
/* ------------------------------------------------------------------------
BREAKPOINTS — Reference only (use in media queries, not calc())
sm: 640px
md: 768px
lg: 1024px
xl: 1280px
------------------------------------------------------------------------ */
}
/* ==========================================================================
THEME A — Industrial Robusto (Dark)
Usage: <html data-theme="industrial"> or <body data-theme="industrial">
Style: Industrial, robust, high-contrast amber accents, clip-path diagonals
========================================================================== */
[data-theme="industrial"] {
/* ------------------------------------------------------------------------
PRIMITIVE COLORS
------------------------------------------------------------------------ */
--color-primary: #F5A623; /* Amber gold — main brand accent */
--color-primary-hover: #e8951a; /* Darker amber on hover */
--color-primary-active: #d4850f; /* Pressed state */
--color-primary-muted: rgba(245, 166, 35, 0.15); /* Subtle tint */
--color-secondary: #333333; /* Mid-dark border / secondary bg */
--color-secondary-hover: #444444;
--color-accent: #F5A623; /* Same as primary in this theme */
/* ------------------------------------------------------------------------
BACKGROUNDS
------------------------------------------------------------------------ */
--color-bg-base: #0d0d0d; /* Page / app shell background */
--color-bg-elevated: #1a1a1a; /* Cards, panels, sidebars */
--color-bg-overlay: #252525; /* Modals, dropdowns, tooltips */
/* Surface levels (for layered UI) */
--color-surface-1: #1a1a1a; /* Lowest raised surface */
--color-surface-2: #252525; /* Mid-level surface */
--color-surface-3: #303030; /* Highest raised surface */
/* ------------------------------------------------------------------------
TEXT
------------------------------------------------------------------------ */
--color-text-primary: #FFFFFF;
--color-text-secondary: #CCCCCC;
--color-text-muted: #888888;
--color-text-disabled: #555555;
--color-text-inverse: #000000; /* Text on amber background */
--color-text-accent: #F5A623;
/* ------------------------------------------------------------------------
BORDERS
------------------------------------------------------------------------ */
--color-border: #333333;
--color-border-strong: #555555;
--color-border-accent: #F5A623;
--color-border-focus: #F5A623;
/* ------------------------------------------------------------------------
BUTTONS
------------------------------------------------------------------------ */
/* Primary button */
--btn-primary-bg: #F5A623;
--btn-primary-bg-hover: #e8951a;
--btn-primary-bg-active: #d4850f;
--btn-primary-text: #000000;
--btn-primary-border: transparent;
/* Secondary button */
--btn-secondary-bg: transparent;
--btn-secondary-bg-hover: rgba(245, 166, 35, 0.10);
--btn-secondary-text: #F5A623;
--btn-secondary-border: #F5A623;
/* Ghost / Danger */
--btn-ghost-bg: transparent;
--btn-ghost-text: #CCCCCC;
--btn-ghost-border: #333333;
--btn-danger-bg: #ef4444;
--btn-danger-text: #FFFFFF;
/* ------------------------------------------------------------------------
TYPOGRAPHY
------------------------------------------------------------------------ */
/* Font families */
--font-heading: 'Barlow Condensed', 'Arial Narrow', sans-serif;
--font-body: 'Barlow', 'Arial', sans-serif;
--font-mono: 'Courier New', 'Consolas', monospace; /* prices / SKUs */
/* Font weights */
--font-weight-light: 300; /* n/a in Barlow — falls to 400 */
--font-weight-regular: 400;
--font-weight-semibold: 600;
--font-weight-bold: 700;
--font-weight-extrabold: 800;
/* Heading weights (Barlow Condensed) */
--heading-weight-primary: 800;
--heading-weight-secondary: 600;
/* ------------------------------------------------------------------------
SHADOWS / ELEVATION
Tinted with amber to feel cohesive with the theme
------------------------------------------------------------------------ */
--shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.60),
0 1px 2px rgba(0, 0, 0, 0.40);
--shadow-md: 0 4px 6px rgba(0, 0, 0, 0.60),
0 2px 4px rgba(0, 0, 0, 0.40);
--shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.70),
0 4px 6px rgba(0, 0, 0, 0.50);
--shadow-xl: 0 20px 25px rgba(0, 0, 0, 0.80),
0 10px 10px rgba(0, 0, 0, 0.50);
/* Accent glow — use on focused/highlighted elements */
--shadow-accent: 0 0 0 3px rgba(245, 166, 35, 0.40);
--shadow-focus: 0 0 0 3px rgba(245, 166, 35, 0.50);
/* ------------------------------------------------------------------------
MISC UI
------------------------------------------------------------------------ */
--scrollbar-track: #1a1a1a;
--scrollbar-thumb: #444444;
--scrollbar-thumb-hover: #F5A623;
--overlay-backdrop: rgba(0, 0, 0, 0.75);
/* Industrial clip-path angle (use in clip-path: polygon(...) utilities) */
--clip-diagonal-angle: 6deg;
}
/* ==========================================================================
THEME B — Técnico Moderno (Light)
Usage: <html data-theme="modern"> or <body data-theme="modern">
Style: Clean, modern, Poppins typography, subtle dot-grid background
========================================================================== */
[data-theme="modern"] {
/* ------------------------------------------------------------------------
PRIMITIVE COLORS
------------------------------------------------------------------------ */
--color-primary: #FF6B35; /* Orange — main brand accent */
--color-primary-hover: #f05a22; /* Darker on hover */
--color-primary-active: #dc4a12; /* Pressed state */
--color-primary-muted: rgba(255, 107, 53, 0.10); /* Subtle tint */
--color-secondary: #1a1a2e; /* Deep navy — used for strong text */
--color-secondary-hover: #252545;
--color-accent: #FF6B35; /* Same as primary in this theme */
/* ------------------------------------------------------------------------
BACKGROUNDS
------------------------------------------------------------------------ */
--color-bg-base: #FFFFFF; /* Page / app shell background */
--color-bg-elevated: #F8F9FF; /* Cards, panels — very subtle blue */
--color-bg-overlay: #FFFFFF; /* Modals, dropdowns */
/* Surface levels */
--color-surface-1: #F8F9FF;
--color-surface-2: #F0F2FF;
--color-surface-3: #E8EBFF;
/* Dot-grid background pattern (apply via background-image on body/shell) */
/* background-image: radial-gradient(circle, var(--dot-grid-color) 1px, transparent 1px); */
/* background-size: var(--dot-grid-size) var(--dot-grid-size); */
--dot-grid-color: rgba(26, 26, 46, 0.07);
--dot-grid-size: 24px;
/* ------------------------------------------------------------------------
TEXT
------------------------------------------------------------------------ */
--color-text-primary: #1a1a2e;
--color-text-secondary: #4a4a6a;
--color-text-muted: #8080a0;
--color-text-disabled: #b0b0c8;
--color-text-inverse: #FFFFFF; /* Text on orange background */
--color-text-accent: #FF6B35;
/* ------------------------------------------------------------------------
BORDERS
------------------------------------------------------------------------ */
--color-border: #e2e4f0;
--color-border-strong: #c8cadc;
--color-border-accent: #FF6B35;
--color-border-focus: #FF6B35;
/* ------------------------------------------------------------------------
BUTTONS
------------------------------------------------------------------------ */
/* Primary button */
--btn-primary-bg: #FF6B35;
--btn-primary-bg-hover: #f05a22;
--btn-primary-bg-active: #dc4a12;
--btn-primary-text: #FFFFFF;
--btn-primary-border: transparent;
/* Secondary button */
--btn-secondary-bg: transparent;
--btn-secondary-bg-hover: rgba(255, 107, 53, 0.08);
--btn-secondary-text: #FF6B35;
--btn-secondary-border: #FF6B35;
/* Ghost / Danger */
--btn-ghost-bg: transparent;
--btn-ghost-text: #4a4a6a;
--btn-ghost-border: #e2e4f0;
--btn-danger-bg: #ef4444;
--btn-danger-text: #FFFFFF;
/* ------------------------------------------------------------------------
TYPOGRAPHY
------------------------------------------------------------------------ */
/* Font families */
--font-heading: 'Poppins', 'Segoe UI', sans-serif;
--font-body: 'Poppins', 'Segoe UI', sans-serif;
--font-mono: 'Courier New', 'Consolas', monospace; /* prices / SKUs */
/* Font weights */
--font-weight-light: 300;
--font-weight-regular: 400;
--font-weight-semibold: 600;
--font-weight-bold: 700;
--font-weight-extrabold: 800; /* falls to 700 in Poppins */
/* Heading weights (Poppins) */
--heading-weight-primary: 700;
--heading-weight-secondary: 600;
/* ------------------------------------------------------------------------
SHADOWS / ELEVATION
Softer, cooler tints for the light theme
------------------------------------------------------------------------ */
--shadow-sm: 0 1px 3px rgba(26, 26, 46, 0.08),
0 1px 2px rgba(26, 26, 46, 0.05);
--shadow-md: 0 4px 6px rgba(26, 26, 46, 0.08),
0 2px 4px rgba(26, 26, 46, 0.05);
--shadow-lg: 0 10px 15px rgba(26, 26, 46, 0.10),
0 4px 6px rgba(26, 26, 46, 0.06);
--shadow-xl: 0 20px 25px rgba(26, 26, 46, 0.12),
0 10px 10px rgba(26, 26, 46, 0.06);
/* Accent glow — use on focused/highlighted elements */
--shadow-accent: 0 0 0 3px rgba(255, 107, 53, 0.25);
--shadow-focus: 0 0 0 3px rgba(255, 107, 53, 0.30);
/* ------------------------------------------------------------------------
MISC UI
------------------------------------------------------------------------ */
--scrollbar-track: #F8F9FF;
--scrollbar-thumb: #c8cadc;
--scrollbar-thumb-hover: #FF6B35;
--overlay-backdrop: rgba(26, 26, 46, 0.50);
/* No diagonal clip in modern theme — set to 0 for override-safe utilities */
--clip-diagonal-angle: 0deg;
}
/* ==========================================================================
TYPOGRAPHY SCALE — Token definitions
Resolved at theme level because font families differ between themes.
These tokens map to semantic roles and should be consumed directly.
========================================================================== */
/* Shared scale values (dimensionless, theme-independent) */
:root {
/* --- Type scale (font-size) --- */
--text-h1: clamp(2.25rem, 5vw, 3.5rem); /* 36px → 56px */
--text-h2: clamp(1.875rem, 4vw, 2.75rem); /* 30px → 44px */
--text-h3: clamp(1.5rem, 3vw, 2.125rem); /* 24px → 34px */
--text-h4: clamp(1.25rem, 2vw, 1.625rem); /* 20px → 26px */
--text-h5: 1.125rem; /* 18px */
--text-h6: 1rem; /* 16px */
--text-body-lg: 1.125rem; /* 18px */
--text-body: 1rem; /* 16px */
--text-body-sm: 0.875rem; /* 14px */
--text-caption: 0.75rem; /* 12px */
--text-label: 0.8125rem; /* 13px */
--text-mono: 1rem; /* 16px — prices, SKUs */
/* --- Line heights --- */
--leading-h1: 1.10;
--leading-h2: 1.12;
--leading-h3: 1.15;
--leading-h4: 1.20;
--leading-h5: 1.25;
--leading-h6: 1.30;
--leading-body-lg: 1.65;
--leading-body: 1.60;
--leading-body-sm: 1.55;
--leading-caption: 1.45;
--leading-label: 1.40;
--leading-mono: 1.50;
/* --- Letter spacing --- */
--tracking-tight: -0.03em;
--tracking-snug: -0.01em;
--tracking-normal: 0em;
--tracking-wide: 0.03em;
--tracking-wider: 0.06em;
--tracking-widest: 0.12em; /* Use for ALL-CAPS labels / badges */
}
/* Heading letter-spacing per theme */
[data-theme="industrial"] {
--heading-tracking-h1: -0.02em;
--heading-tracking-h2: -0.02em;
--heading-tracking-h3: -0.01em;
--heading-tracking-h4: 0em;
--heading-tracking-h5: 0.02em;
--heading-tracking-h6: 0.04em;
}
[data-theme="modern"] {
--heading-tracking-h1: -0.03em;
--heading-tracking-h2: -0.02em;
--heading-tracking-h3: -0.01em;
--heading-tracking-h4: 0em;
--heading-tracking-h5: 0em;
--heading-tracking-h6: 0.01em;
}
/* ==========================================================================
COMPONENT SHORTHAND TOKENS
Convenience aliases that combine multiple primitives. Components should
reference these rather than the primitives above.
========================================================================== */
:root {
/* --- Input / form fields --- */
/* These are intentionally left as CSS variable references so they resolve
correctly within whichever theme is active at runtime. */
/* (No :root overrides needed — components consume --color-* directly.) */
/* --- Focus ring --- */
--focus-ring: 0 0 0 3px var(--shadow-focus, rgba(245,166,35,0.40));
/* --- Content max widths --- */
--content-xs: 480px;
--content-sm: 640px;
--content-md: 768px;
--content-lg: 1024px;
--content-xl: 1280px;
--content-full: 100%;
}
/* ==========================================================================
UTILITY — Scrollbar styles (opt-in via class)
========================================================================== */
.themed-scrollbar {
scrollbar-width: thin;
scrollbar-color: var(--scrollbar-thumb) var(--scrollbar-track);
}
.themed-scrollbar::-webkit-scrollbar {
width: 8px;
height: 8px;
}
.themed-scrollbar::-webkit-scrollbar-track {
background: var(--scrollbar-track);
}
.themed-scrollbar::-webkit-scrollbar-thumb {
background-color: var(--scrollbar-thumb);
border-radius: var(--radius-full);
border: 2px solid var(--scrollbar-track);
}
.themed-scrollbar::-webkit-scrollbar-thumb:hover {
background-color: var(--scrollbar-thumb-hover);
}
/* ==========================================================================
UTILITY — Dot-grid background (Theme B helper)
Apply class .bg-dot-grid to body or layout shell when using modern theme.
========================================================================== */
[data-theme="modern"] .bg-dot-grid {
background-color: var(--color-bg-base);
background-image: radial-gradient(
circle,
var(--dot-grid-color) 1px,
transparent 1px
);
background-size: var(--dot-grid-size) var(--dot-grid-size);
}
/* ==========================================================================
UTILITY — Industrial diagonal clip helpers (Theme A)
========================================================================== */
[data-theme="industrial"] .clip-top-right {
clip-path: polygon(0 0, calc(100% - 24px) 0, 100% 24px, 100% 100%, 0 100%);
}
[data-theme="industrial"] .clip-bottom-left {
clip-path: polygon(0 0, 100% 0, 100% 100%, 24px 100%, 0 calc(100% - 24px));
}
[data-theme="industrial"] .clip-corner {
clip-path: polygon(0 0, calc(100% - 16px) 0, 100% 16px, 100% 100%, 0 100%);
}
/* ==========================================================================
END OF TOKENS FILE
nexus-autoparts-design/tokens/tokens.css
========================================================================== */