Files
Autoparts-DB/docs/design/design-system/components/columnas-costo-margen.html
Lucy ccd3962458 feat(design): add 16 new components + update 5 pages (ronda 2)
Bloqueantes POS: modal-pago, ticket-termico, banner-cliente, fkeys-footer, columnas-costo-margen
Componentes nuevos: calculadora-cambio, panel-deslizante, badge-cfdi, arbol-colapsable, tarjeta-metrica, grafica-barras, selector-periodo, etiqueta-codigo-barras
Estados: estado-vacio, banner-offline, modal-confirmacion
Páginas actualizadas: facturación, contabilidad, dashboard, configuración, reportes
2026-04-01 07:06:34 +00:00

508 lines
20 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="es" data-theme="industrial">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Nexus Autoparts — Columnas Costo y Margen</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);
}
/* ====== Toggle Permission ====== */
.perm-toggle {
display: flex; align-items: center; gap: var(--space-3);
padding: var(--space-3) var(--space-4);
background: var(--color-surface-1);
border: 1px solid var(--color-border);
border-radius: var(--radius-md);
margin-bottom: var(--space-4);
}
.perm-toggle label {
font-size: var(--text-body-sm); font-weight: var(--font-weight-semibold);
color: var(--color-text-secondary); cursor: pointer;
}
.toggle-switch {
position: relative; width: 44px; height: 24px;
}
.toggle-switch input {
opacity: 0; width: 0; height: 0;
}
.toggle-slider {
position: absolute; inset: 0;
background: var(--color-border-strong);
border-radius: var(--radius-full);
cursor: pointer; transition: var(--transition-fast);
}
.toggle-slider::after {
content: ''; position: absolute;
left: 3px; top: 3px;
width: 18px; height: 18px;
background: var(--color-text-primary);
border-radius: var(--radius-full);
transition: var(--transition-fast);
}
.toggle-switch input:checked + .toggle-slider {
background: var(--color-primary);
}
.toggle-switch input:checked + .toggle-slider::after {
transform: translateX(20px);
background: var(--color-text-inverse);
}
.perm-badge {
font-size: var(--text-caption); font-weight: var(--font-weight-semibold);
padding: 2px var(--space-2); border-radius: var(--radius-sm);
text-transform: uppercase; letter-spacing: var(--tracking-wide);
}
.perm-badge.admin { background: var(--color-primary-muted); color: var(--color-text-accent); }
.perm-badge.owner { background: var(--color-success-light); color: var(--color-success-dark); }
/* ====== Table ====== */
.sale-table-container {
background: var(--color-bg-elevated);
border: 1px solid var(--color-border);
border-radius: var(--radius-lg);
overflow-x: auto;
}
.sale-table {
width: 100%; border-collapse: collapse;
font-size: var(--text-body-sm);
}
.sale-table thead {
background: var(--color-surface-2);
}
.sale-table th {
padding: var(--space-3) var(--space-4);
text-align: left; font-weight: var(--font-weight-semibold);
color: var(--color-text-muted); font-size: var(--text-caption);
text-transform: uppercase; letter-spacing: var(--tracking-widest);
border-bottom: 2px solid var(--color-border);
white-space: nowrap;
}
.sale-table td {
padding: var(--space-3) var(--space-4);
border-bottom: 1px solid var(--color-border);
vertical-align: middle;
}
.sale-table tbody tr:hover {
background: var(--color-primary-muted);
}
.sale-table th.right, .sale-table td.right { text-align: right; }
.sale-table th.center, .sale-table td.center { text-align: center; }
/* Product cell */
.product-cell {
display: flex; flex-direction: column; gap: 2px;
}
.product-name {
font-weight: var(--font-weight-semibold);
color: var(--color-text-primary);
}
.product-sku {
font-family: var(--font-mono); font-size: 11px;
color: var(--color-text-muted);
}
/* Price cells */
.price {
font-family: var(--font-mono); font-weight: var(--font-weight-semibold);
}
/* ====== Margin Column Styles ====== */
.col-cost, .col-margin {
transition: var(--transition-normal);
}
.col-cost.hidden, .col-margin.hidden {
display: none;
}
.cost-value {
font-family: var(--font-mono); font-size: var(--text-body-sm);
color: var(--color-text-muted);
}
.margin-badge {
display: inline-flex; align-items: center; gap: 4px;
padding: 2px var(--space-2);
border-radius: var(--radius-sm);
font-family: var(--font-mono); font-size: var(--text-caption);
font-weight: var(--font-weight-bold);
white-space: nowrap;
}
.margin-high {
background: var(--color-success-light); color: var(--color-success-dark);
}
.margin-mid {
background: var(--color-warning-light); color: var(--color-warning-dark);
}
.margin-low {
background: var(--color-error-light); color: var(--color-error-dark);
}
/* Margin bar (visual) */
.margin-bar-container {
display: flex; align-items: center; gap: var(--space-2);
}
.margin-bar {
width: 60px; height: 6px;
background: var(--color-surface-3);
border-radius: var(--radius-full);
overflow: hidden;
}
.margin-bar-fill {
height: 100%;
border-radius: var(--radius-full);
transition: var(--transition-normal);
}
.margin-bar-fill.high { background: var(--color-success); }
.margin-bar-fill.mid { background: var(--color-warning); }
.margin-bar-fill.low { background: var(--color-error); }
/* ====== Totals Row ====== */
.sale-table tfoot td {
padding: var(--space-3) var(--space-4);
font-weight: var(--font-weight-bold);
border-top: 2px solid var(--color-border);
background: var(--color-surface-1);
}
.total-margin {
font-family: var(--font-mono); font-size: var(--text-body);
font-weight: var(--font-weight-bold);
}
/* ====== Legend ====== */
.legend {
display: flex; gap: var(--space-6); margin-top: var(--space-4);
padding: var(--space-3) var(--space-4);
background: var(--color-surface-1);
border: 1px solid var(--color-border);
border-radius: var(--radius-md);
flex-wrap: wrap;
}
.legend-item {
display: flex; align-items: center; gap: var(--space-2);
font-size: var(--text-caption); color: var(--color-text-secondary);
}
.legend-dot {
width: 10px; height: 10px; border-radius: var(--radius-full);
}
.legend-dot.high { background: var(--color-success); }
.legend-dot.mid { background: var(--color-warning); }
.legend-dot.low { background: var(--color-error); }
/* ====== Qty controls ====== */
.qty-cell {
display: flex; align-items: center; gap: var(--space-1);
}
.qty-btn {
width: 24px; height: 24px;
display: flex; align-items: center; justify-content: center;
background: var(--color-surface-2); border: 1px solid var(--color-border);
border-radius: var(--radius-sm); cursor: pointer;
font-size: 14px; font-weight: bold;
color: var(--color-text-secondary);
transition: var(--transition-fast);
}
.qty-btn:hover { background: var(--color-primary-muted); border-color: var(--color-primary); }
.qty-value {
min-width: 28px; text-align: center;
font-family: var(--font-mono); font-weight: var(--font-weight-bold);
}
/* ====== Delete btn ====== */
.del-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); cursor: pointer;
color: var(--color-text-muted); font-size: 14px;
transition: var(--transition-fast);
}
.del-btn:hover { background: var(--color-error-light); color: var(--color-error); border-color: var(--color-error); }
</style>
</head>
<body>
<!-- Theme Switcher -->
<div class="theme-switcher">
<button class="active" onclick="setTheme('industrial')">A — Industrial Robusto</button>
<button onclick="setTheme('modern')">B — Técnico Moderno</button>
</div>
<h1>Columnas Costo y Margen</h1>
<p class="subtitle">2 columnas extra en la tabla de venta, visibles solo con permiso Admin/Owner. Costo unitario + Margen % con color semántico.</p>
<!-- ============================================== -->
<!-- SECTION: With Columns Visible -->
<!-- ============================================== -->
<section>
<h2>Tabla de Venta — Columnas Visibles (Admin/Owner)</h2>
<div class="perm-toggle">
<label class="toggle-switch">
<input type="checkbox" id="toggle-cols" checked onchange="toggleColumns()">
<span class="toggle-slider"></span>
</label>
<label for="toggle-cols">Mostrar Costo y Margen</label>
<span class="perm-badge admin">Admin</span>
<span class="perm-badge owner">Owner</span>
</div>
<div class="sale-table-container">
<table class="sale-table">
<thead>
<tr>
<th style="width: 32px;">#</th>
<th>Producto</th>
<th class="center" style="width: 90px;">Cantidad</th>
<th class="right">P. Unitario</th>
<th class="right col-cost">Costo Unit.</th>
<th class="center col-margin" style="width: 140px;">Margen</th>
<th class="right">Importe</th>
<th style="width: 40px;"></th>
</tr>
</thead>
<tbody>
<!-- Row 1: High margin -->
<tr>
<td style="color: var(--color-text-muted);">1</td>
<td>
<div class="product-cell">
<span class="product-name">Balatas cerám. del. Brembo P68034</span>
<span class="product-sku">BRM-P68034</span>
</div>
</td>
<td class="center">
<div class="qty-cell" style="justify-content: center;">
<button class="qty-btn">-</button>
<span class="qty-value">2</span>
<button class="qty-btn">+</button>
</div>
</td>
<td class="right"><span class="price">$1,250.00</span></td>
<td class="right col-cost"><span class="cost-value">$720.00</span></td>
<td class="center col-margin">
<div class="margin-bar-container" style="justify-content: center;">
<span class="margin-badge margin-high">42.4%</span>
<div class="margin-bar"><div class="margin-bar-fill high" style="width: 42.4%;"></div></div>
</div>
</td>
<td class="right"><span class="price">$2,500.00</span></td>
<td class="center"><button class="del-btn">&#x2715;</button></td>
</tr>
<!-- Row 2: Mid margin -->
<tr>
<td style="color: var(--color-text-muted);">2</td>
<td>
<div class="product-cell">
<span class="product-name">Filtro aceite Wix WL7200</span>
<span class="product-sku">WIX-7200</span>
</div>
</td>
<td class="center">
<div class="qty-cell" style="justify-content: center;">
<button class="qty-btn">-</button>
<span class="qty-value">1</span>
<button class="qty-btn">+</button>
</div>
</td>
<td class="right"><span class="price">$185.00</span></td>
<td class="right col-cost"><span class="cost-value">$138.00</span></td>
<td class="center col-margin">
<div class="margin-bar-container" style="justify-content: center;">
<span class="margin-badge margin-mid">25.4%</span>
<div class="margin-bar"><div class="margin-bar-fill mid" style="width: 25.4%;"></div></div>
</div>
</td>
<td class="right"><span class="price">$185.00</span></td>
<td class="center"><button class="del-btn">&#x2715;</button></td>
</tr>
<!-- Row 3: Low margin -->
<tr>
<td style="color: var(--color-text-muted);">3</td>
<td>
<div class="product-cell">
<span class="product-name">Amortiguador tras. Monroe OESpec 72364</span>
<span class="product-sku">MON-72364</span>
</div>
</td>
<td class="center">
<div class="qty-cell" style="justify-content: center;">
<button class="qty-btn">-</button>
<span class="qty-value">2</span>
<button class="qty-btn">+</button>
</div>
</td>
<td class="right"><span class="price">$1,071.25</span></td>
<td class="right col-cost"><span class="cost-value">$950.00</span></td>
<td class="center col-margin">
<div class="margin-bar-container" style="justify-content: center;">
<span class="margin-badge margin-low">11.3%</span>
<div class="margin-bar"><div class="margin-bar-fill low" style="width: 11.3%;"></div></div>
</div>
</td>
<td class="right"><span class="price">$2,142.50</span></td>
<td class="center"><button class="del-btn">&#x2715;</button></td>
</tr>
<!-- Row 4: High margin -->
<tr>
<td style="color: var(--color-text-muted);">4</td>
<td>
<div class="product-cell">
<span class="product-name">Aceite Motor Mobil 1 5W-30 Sintético 5L</span>
<span class="product-sku">MOB-5W30-5L</span>
</div>
</td>
<td class="center">
<div class="qty-cell" style="justify-content: center;">
<button class="qty-btn">-</button>
<span class="qty-value">1</span>
<button class="qty-btn">+</button>
</div>
</td>
<td class="right"><span class="price">$890.00</span></td>
<td class="right col-cost"><span class="cost-value">$520.00</span></td>
<td class="center col-margin">
<div class="margin-bar-container" style="justify-content: center;">
<span class="margin-badge margin-high">41.6%</span>
<div class="margin-bar"><div class="margin-bar-fill high" style="width: 41.6%;"></div></div>
</div>
</td>
<td class="right"><span class="price">$890.00</span></td>
<td class="center"><button class="del-btn">&#x2715;</button></td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="3" style="text-align: right; color: var(--color-text-muted);">5 artículos, 6 piezas</td>
<td class="right">Subtotal:</td>
<td class="right col-cost">
<span class="cost-value">$4,098.00</span>
</td>
<td class="center col-margin">
<span class="total-margin margin-badge margin-high" style="font-size: var(--text-body-sm);">
Promedio: 32.8%
</span>
</td>
<td class="right"><span class="price" style="font-size: var(--text-body);">$5,717.50</span></td>
<td></td>
</tr>
</tfoot>
</table>
</div>
<!-- Legend -->
<div class="legend">
<div class="legend-item">
<span class="legend-dot high"></span>
<span>Verde: margen &gt; 30%</span>
</div>
<div class="legend-item">
<span class="legend-dot mid"></span>
<span>Amarillo: margen 15% 30%</span>
</div>
<div class="legend-item">
<span class="legend-dot low"></span>
<span>Rojo: margen &lt; 15%</span>
</div>
</div>
</section>
<!-- ============================================== -->
<!-- SECTION: Margin Badge Variants -->
<!-- ============================================== -->
<section>
<h2>Variantes del Badge de Margen</h2>
<p class="label-text">Los 3 niveles de color semántico</p>
<div style="display: flex; gap: var(--space-6); flex-wrap: wrap; align-items: center;">
<div style="text-align: center;">
<p class="label-text">Alto (&gt;30%)</p>
<div class="margin-bar-container">
<span class="margin-badge margin-high">42.4%</span>
<div class="margin-bar" style="width: 80px;"><div class="margin-bar-fill high" style="width: 42.4%;"></div></div>
</div>
</div>
<div style="text-align: center;">
<p class="label-text">Medio (15-30%)</p>
<div class="margin-bar-container">
<span class="margin-badge margin-mid">25.4%</span>
<div class="margin-bar" style="width: 80px;"><div class="margin-bar-fill mid" style="width: 25.4%;"></div></div>
</div>
</div>
<div style="text-align: center;">
<p class="label-text">Bajo (&lt;15%)</p>
<div class="margin-bar-container">
<span class="margin-badge margin-low">11.3%</span>
<div class="margin-bar" style="width: 80px;"><div class="margin-bar-fill low" style="width: 11.3%;"></div></div>
</div>
</div>
<div style="text-align: center;">
<p class="label-text">Negativo</p>
<div class="margin-bar-container">
<span class="margin-badge margin-low">-5.2%</span>
<div class="margin-bar" style="width: 80px;"><div class="margin-bar-fill low" style="width: 0%;"></div></div>
</div>
</div>
</div>
</section>
<script>
function setTheme(theme) {
document.documentElement.setAttribute('data-theme', theme);
document.querySelectorAll('.theme-switcher button').forEach(b => b.classList.remove('active'));
event.target.classList.add('active');
}
function toggleColumns() {
const checked = document.getElementById('toggle-cols').checked;
document.querySelectorAll('.col-cost, .col-margin').forEach(el => {
el.classList.toggle('hidden', !checked);
});
}
</script>
</body>
</html>