:root {
  /* Cobalto de peltre esmaltado: el color firma del producto que se vende.
     Neutros entibiados hacia el matiz de marca; nada de #000/#fff puros. */
  --primary: oklch(0.47 0.15 262);
  --primary-dark: oklch(0.37 0.13 262);
  --primary-light: oklch(0.94 0.03 262);
  --bg: oklch(0.97 0.006 85);
  --border: oklch(0.9 0.01 85);
  --white: oklch(0.995 0.003 85);
  --text: oklch(0.28 0.015 75);
  --text-light: oklch(0.54 0.02 75);
  --danger: oklch(0.55 0.19 25);
  --success: oklch(0.58 0.13 150);
  --warning: oklch(0.68 0.13 80);
  --accent: oklch(0.52 0.09 195);
  --radius: 12px;
  --radius-input: 20px;

  /* Lienzo del tablero: azul pizarra sereno (iteracion 2 con Adrian:
     menos saturacion que el cobalto pleno), tarjetas blancas encima */
  --canvas: oklch(0.42 0.04 255);
  --canvas-hondo: oklch(0.34 0.035 257);
  --sobre-canvas: oklch(0.94 0.01 255);

  /* Pills de etapa: fondo claro de color + texto oscuro del mismo matiz
     (legible a pleno sol, como los pills de Bitrix) */
  --etapa-nuevo: oklch(0.87 0.11 85);
  --etapa-nuevo-texto: oklch(0.35 0.07 70);
  --etapa-contactado: oklch(0.85 0.07 245);
  --etapa-contactado-texto: oklch(0.32 0.08 250);
  --etapa-calificado: oklch(0.86 0.08 195);
  --etapa-calificado-texto: oklch(0.3 0.06 200);
  --etapa-cotizado: oklch(0.86 0.1 150);
  --etapa-cotizado-texto: oklch(0.3 0.07 152);
  --etapa-no_util: oklch(0.88 0.012 80);
  --etapa-no_util-texto: oklch(0.4 0.015 75);
  /* Las 7 etapas del Pipeline (#518, paleta A3c "Dos familias"): lo que mueve
     el vendedor en ambares, lo que mueve Operam de cobalto a verde. Declaradas
     UNA vez; las consumen la lista y la pastilla de columna del tablero. */
  --etapa-no_asignado: oklch(0.95 0.02 80);
  --etapa-no_asignado-texto: oklch(0.48 0.04 75);
  --etapa-por_cotizar: oklch(0.95 0.07 85);
  --etapa-por_cotizar-texto: oklch(0.50 0.11 75);
  --etapa-seguimiento: oklch(0.94 0.09 70);
  --etapa-seguimiento-texto: oklch(0.47 0.15 50);
  --etapa-anticipo_pagado: oklch(0.94 0.035 262);
  --etapa-anticipo_pagado-texto: oklch(0.42 0.15 262);
  --etapa-pedido_liberado: oklch(0.94 0.04 230);
  --etapa-pedido_liberado-texto: oklch(0.42 0.11 230);
  --etapa-saldo_pagado: oklch(0.94 0.05 180);
  --etapa-saldo_pagado-texto: oklch(0.44 0.10 180);
  --etapa-producto_entregado: oklch(0.94 0.06 145);
  --etapa-producto_entregado-texto: oklch(0.40 0.12 145);
  --col-vencida: oklch(0.86 0.07 28);
  --col-vencida-texto: oklch(0.36 0.11 28);

  /* Pie de la pantalla (#442): la bottom-nav fija y, en #app-view, la barra
     del total del carrito encima de ella. --pie-fijo es donde se apoya un
     boton de accion sticky para no quedar debajo de ninguna de las dos. */
  --alto-barra-inferior: 64px;
  --alto-total-carrito: 62px;
  --alto-siguiente-envio: 38px;
  --pie-fijo: var(--alto-barra-inferior);
}

* { margin: 0; padding: 0; box-sizing: border-box; }

body {
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  background: var(--bg);
  color: var(--text);
  font-size: 14px;
  line-height: 1.5;
  min-height: 100dvh;
}

#app-view, #historial-view {
  width: 66vw;
  min-width: 800px;
  margin: 0 auto;
}

/* === LOGIN === */
.login-container {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 100dvh;
  padding: 20px;
}

.login-card {
  background: var(--white);
  border-radius: var(--radius);
  padding: 32px 24px;
  width: 100%;
  max-width: 360px;
  box-shadow: 0 2px 12px rgba(0,0,0,0.08);
  border: 1px solid var(--border);
}

.login-card h1 {
  font-size: 18px;
  color: var(--primary-dark);
  margin-bottom: 4px;
  font-weight: 700;
}

.login-card .subtitle {
  color: var(--text-light);
  font-size: 12px;
  margin-bottom: 24px;
}

/* === FORMS === */
.form-group {
  margin-bottom: 14px;
}

.form-group label {
  display: block;
  font-size: 11px;
  font-weight: 700;
  color: var(--text-light);
  margin-bottom: 4px;
  text-transform: uppercase;
  letter-spacing: 0.03em;
}

.form-group select,
.form-group input,
.form-group textarea {
  width: 100%;
  padding: 8px 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius-input);
  font-size: 13px;
  font-family: inherit;
  background: var(--white);
  color: var(--text);
  transition: border-color 0.15s, box-shadow 0.15s;
}

.form-group select:focus,
.form-group input:focus,
.form-group textarea:focus {
  outline: none;
  border-color: var(--primary);
  box-shadow: 0 0 0 2px rgba(65, 143, 255, 0.15);
}

.form-group textarea {
  resize: vertical;
  min-height: 72px;
  border-radius: 10px;
}

.form-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
}

/* === BUTTONS === */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 9px 20px;
  border: none;
  border-radius: var(--radius-input);
  font-size: 13px;
  font-weight: 700;
  font-family: inherit;
  cursor: pointer;
  transition: background 0.15s, opacity 0.15s;
}

.btn:disabled { opacity: 0.5; cursor: not-allowed; }
.btn-primary { background: var(--primary); color: var(--white); }
.btn-primary:hover:not(:disabled) { background: var(--primary-dark); }
.btn-secondary { background: var(--white); color: var(--primary-dark); border: 1px solid var(--border); }
.btn-secondary:hover:not(:disabled) { background: var(--bg); }
.btn-success { background: var(--success); color: var(--white); }
.btn-danger { background: var(--danger); color: var(--white); }
.btn-block { width: 100%; }
.btn-sm { padding: 5px 12px; font-size: 12px; }

/* === APP LAYOUT === */
.app-header {
  background: var(--primary);
  color: var(--white);
  padding: 10px 16px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  position: sticky;
  top: 0;
  z-index: 100;
}

.app-header h1 {
  font-size: 15px;
  font-weight: 700;
}

.app-header .user-info {
  font-size: 12px;
  opacity: 0.85;
}

.prices-date {
  font-size: 10px;
  opacity: 0.65;
  margin-top: 1px;
}

.app-header .btn-secondary {
  background: rgba(255,255,255,0.15);
  color: var(--white);
  border-color: rgba(255,255,255,0.4);
}

.app-header .btn-secondary:hover {
  background: rgba(255,255,255,0.28);
}

/* === TABS === */
.tabs {
  display: flex;
  background: var(--white);
  border-bottom: 1px solid var(--border);
  position: sticky;
  top: 48px;
  z-index: 99;
  overflow-x: auto;
}

.tab {
  flex: 1;
  min-width: 0;
  padding: 9px 8px;
  text-align: center;
  font-size: 12px;
  font-weight: 700;
  color: var(--text-light);
  border: none;
  background: none;
  cursor: pointer;
  border-bottom: 2px solid transparent;
  white-space: nowrap;
  font-family: inherit;
}

.tab.active {
  color: var(--primary);
  border-bottom-color: var(--primary);
}

.tab-content {
  display: none;
  padding: 14px;
}

.tab-content.active { display: block; }

/* === STEPPER (flujo de cotizar, issue #60) === */
.stepper .step-num {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  margin-right: 5px;
  font-size: 10px;
  line-height: 1;
  background: var(--border);
  color: var(--text-light);
  vertical-align: middle;
}
.tab.active .step-num {
  background: var(--primary);
  color: var(--white);
}
.tab.completo .step-num {
  background: var(--success);
  color: var(--white);
}
.tab.completo .step-num::before {
  content: 'OK';
  font-size: 7px;
  font-weight: 700;
}
.tab.completo .step-num { font-size: 0; }

.stepper-progress {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 14px;
  background: var(--white);
  border-bottom: 1px solid var(--border);
  position: sticky;
  top: 84px;
  z-index: 98;
}
.stepper-progress-text {
  font-size: 11px;
  font-weight: 700;
  color: var(--text-light);
  white-space: nowrap;
}
.stepper-progress-rail {
  flex: 1;
  height: 4px;
  border-radius: 2px;
  background: var(--border);
  overflow: hidden;
}
.stepper-progress-fill {
  height: 100%;
  border-radius: 2px;
  background: var(--primary);
  transition: width 0.2s ease;
  width: 25%;
}

/* A quien se cotiza (#480): fija debajo de la barra de progreso (84px de
   header y stepper + ~32px de la barra). */
.franja-cliente {
  display: flex;
  flex-wrap: wrap;
  gap: 2px 14px;
  padding: 6px 14px;
  background: var(--white);
  border-bottom: 1px solid var(--border);
  font-size: 13px;
  position: sticky;
  top: 116px;
  z-index: 97;
}
.franja-cliente.vacia {
  color: var(--text-light);
  font-style: italic;
}
.franja-etiqueta {
  font-size: 11px;
  color: var(--text-light);
}
.franja-valor {
  font-weight: 600;
}

/* === SEARCH (tipo Operam) === */
.search-container {
  position: relative;
  margin-bottom: 8px;
}

.search-input-wrap {
  position: relative;
}

.search-input-wrap input,
.historial-fechas input[type="date"] {
  width: 100%;
  padding: 9px 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius-input);
  font-size: 13px;
  font-family: inherit;
  background: var(--white);
  color: var(--text);
  transition: border-color 0.15s, box-shadow 0.15s;
}

.search-input-wrap input:focus,
.historial-fechas input[type="date"]:focus {
  outline: none;
  border-color: var(--primary);
  box-shadow: 0 0 0 2px rgba(65, 143, 255, 0.15);
}

.historial-fechas {
  display: flex;
  gap: 8px;
  margin-bottom: 12px;
}

.historial-fechas label {
  flex: 1;
  min-width: 0;
  font-size: 12px;
  color: var(--text-light);
}

.historial-fechas input[type="date"] {
  display: block;
  min-width: 0;
  margin-top: 2px;
}

/* Rejilla de filtros por selector (#456, spec #398): la pinta
   buildFiltrosSelectorHtml (filtros-logica.js) y la comparten las vistas con
   buscador. Mismo aspecto que la Tabla de prospectos; en telefono los bloques
   bajan de renglon solos (flex-wrap, base de 150px). */
.filtros-selector {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: flex-end;
  margin-bottom: 10px;
}

.filtro-selector {
  display: flex;
  flex-direction: column;
  gap: 4px;
  flex: 1 1 150px;
  min-width: 0;
}

.filtro-selector label {
  font-size: 11px;
  color: var(--text-light);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.filtro-selector select {
  padding: 7px 10px;
  border: 1px solid var(--border);
  border-radius: var(--radius-input);
  font-size: 13px;
  font-family: inherit;
  background: var(--white);
  color: var(--text);
  min-width: 0;
}

.filtros-contador {
  font-size: 13px;
  color: var(--text-light);
  margin-bottom: 10px;
}

.filtros-contador strong { color: var(--primary-dark); }

.search-dropdown {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  right: 0;
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: 0 4px 16px rgba(0,0,0,0.10);
  z-index: 200;
  max-height: 320px;
  overflow-y: auto;
}

.dropdown-group-label {
  padding: 6px 12px 2px;
  font-size: 10px;
  font-weight: 700;
  color: var(--text-light);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  background: var(--bg);
  border-bottom: 1px solid var(--border);
}

.dropdown-item {
  display: flex;
  align-items: baseline;
  gap: 8px;
  padding: 8px 12px;
  cursor: pointer;
  border-bottom: 1px solid var(--border);
  transition: background 0.1s;
}

.dropdown-item:last-child { border-bottom: none; }

.dropdown-item:hover, .dropdown-item.focused {
  background: var(--primary-light);
}

.dropdown-item.in-cart {
  background: rgba(56, 161, 105, 0.06);
}

.dropdown-item-sku {
  font-size: 11px;
  font-weight: 700;
  color: var(--primary-dark);
  white-space: nowrap;
  min-width: 90px;
}

.dropdown-item-name {
  font-size: 12px;
  color: var(--text);
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.dropdown-item-price {
  font-size: 12px;
  font-weight: 700;
  color: var(--text-light);
  white-space: nowrap;
}

.dropdown-empty {
  padding: 16px;
  text-align: center;
  color: var(--text-light);
  font-size: 12px;
}

/* === SEARCH SELECTED ITEM === */
.search-selected-item {
  margin-top: 8px;
  background: var(--white);
  border: 1px solid var(--primary);
  border-radius: var(--radius);
  padding: 10px 12px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  flex-wrap: wrap;
}

.search-selected-info {
  display: flex;
  flex-direction: column;
  gap: 1px;
  flex: 1;
  min-width: 0;
}

.search-selected-sku {
  font-size: 11px;
  font-weight: 700;
  color: var(--primary-dark);
}

.search-selected-name {
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.search-selected-price {
  font-size: 12px;
  color: var(--text-light);
}

.search-selected-actions {
  display: flex;
  align-items: center;
  gap: 6px;
}

/* === PRODUCT LIST (lista del carrito en tab productos) === */
.product-list {
  display: flex;
  flex-direction: column;
  gap: 5px;
}

.product-item {
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 9px 12px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}

.product-item.in-cart {
  border-color: var(--primary);
  background: var(--primary-light);
}

.product-info {
  flex: 1;
  min-width: 0;
}

.product-name {
  font-size: 12px;
  font-weight: 700;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.product-key {
  font-size: 11px;
  color: var(--text-light);
}

/* === QUANTITY CONTROLS === */
.qty-controls {
  display: flex;
  align-items: center;
  gap: 4px;
}

.qty-btn {
  width: 30px;
  height: 30px;
  border: 1px solid var(--border);
  border-radius: 50%;
  background: var(--white);
  font-size: 16px;
  font-weight: 700;
  color: var(--primary);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: inherit;
  transition: background 0.1s;
}

.qty-btn:active { background: var(--primary-light); }

.qty-input {
  width: 48px;
  height: 30px;
  text-align: center;
  border: 1px solid var(--border);
  border-radius: 6px;
  font-size: 13px;
  font-weight: 600;
  font-family: inherit;
}

/* === TIER INDICATOR === */
.tier-bar {
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 9px 12px;
  margin-bottom: 10px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 6px;
}

.tier-label {
  font-size: 13px;
  font-weight: 700;
  color: var(--primary-dark);
}

.tier-next {
  font-size: 12px;
  color: var(--accent);
  font-weight: 600;
}

.tier-stats {
  font-size: 12px;
  color: var(--text-light);
}

.tier-select {
  font-size: 12px;
  padding: 4px 6px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--white);
}

.tier-aviso {
  font-size: 12px;
  color: oklch(0.36 0.08 70);
  background: oklch(0.95 0.05 80);
  border-radius: var(--radius);
  padding: 6px 10px;
  margin-bottom: 10px;
}

/* === CART SUMMARY (barra inferior fija) === */
/* Se apoya ARRIBA de la bottom-nav (#442): con bottom 0 quedaba debajo de
   ella (z-index 50 contra 900), igual que .expo-guardar-fijo. Su alto es fijo
   para que los botones .accion-fija se apoyen justo encima de ella. */
.cart-summary {
  position: sticky;
  bottom: var(--alto-barra-inferior);
  height: var(--alto-total-carrito);
  background: var(--white);
  border-top: 1px solid var(--border);
  padding: 10px 16px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  z-index: 50;
  box-shadow: 0 -2px 8px rgba(0,0,0,0.06);
}

/* Con el total a la vista (updateCartSummary le escribe display flex/none),
   los botones de accion de #app-view se apoyan arriba de el. Fuera de
   #app-view (el alta re-parentada a Clientes) no hay total: sigue la raiz. */
#app-view:has(> #cart-summary:not([style*="none"])) {
  --pie-fijo: calc(var(--alto-barra-inferior) + var(--alto-total-carrito));
}

.cart-total {
  font-size: 16px;
  font-weight: 700;
  color: var(--primary-dark);
}

.cart-count {
  font-size: 11px;
  color: var(--text-light);
  white-space: nowrap;
}

/* === CART ITEMS (en tab resumen) === */
.cart-item {
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 10px 12px;
  margin-bottom: 6px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}

.cart-item-info { flex: 1; min-width: 0; }
.cart-item-name { font-size: 13px; font-weight: 700; color: var(--text); }
.cart-item-detail { font-size: 11px; color: var(--text-light); }
.cart-item-total { font-size: 13px; font-weight: 700; color: var(--primary-dark); white-space: nowrap; }

.remove-btn {
  width: 24px;
  height: 24px;
  border: none;
  background: none;
  color: var(--danger);
  font-size: 16px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* === TOTALS TABLE === */
.totals-table {
  width: 100%;
  max-width: 300px;
  margin-left: auto;
  border-collapse: collapse;
}

.totals-table td {
  padding: 5px 0;
  font-size: 13px;
}

.totals-table td:last-child {
  text-align: right;
  font-weight: 700;
}

.totals-table .total-row td {
  font-size: 15px;
  font-weight: 700;
  color: var(--primary-dark);
  border-top: 2px solid var(--primary);
  padding-top: 8px;
}

/* === NOTES SECTION === */
.notes-box {
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 12px;
  margin: 12px 0;
}

.notes-box h3 {
  font-size: 11px;
  font-weight: 700;
  color: var(--text-light);
  text-transform: uppercase;
  letter-spacing: 0.03em;
  margin-bottom: 6px;
}

/* === SECTION HEADERS === */
.section-header {
  font-size: 13px;
  font-weight: 700;
  color: var(--primary-dark);
  margin: 14px 0 8px;
  padding-bottom: 4px;
  border-bottom: 1px solid var(--border);
}

/* === ALERTS === */
.alert {
  padding: 9px 12px;
  border-radius: var(--radius);
  font-size: 12px;
  margin-bottom: 10px;
}

.alert-info { background: #EBF3FF; color: var(--primary-dark); border: 1px solid #C3DAFE; }
.alert-success { background: #F0FFF4; color: #276749; border: 1px solid #C6F6D5; }
.alert-warning { background: #FFFFF0; color: #975A16; border: 1px solid #FEFCBF; }
.alert-error { background: #FFF5F5; color: #C53030; border: 1px solid #FED7D7; }

/* === EMPTY STATE === */
.empty-state {
  text-align: center;
  padding: 40px 20px;
  color: var(--text-light);
}

.empty-state p { font-size: 13px; }

/* === FLUJO GUIADO === */
.flujo-container {
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 12px;
  margin-bottom: 10px;
  display: flex;
  gap: 12px;
  align-items: flex-start;
  flex-wrap: wrap;
}

.flujo-grid {
  display: grid;
  grid-template-columns: repeat(7, minmax(90px, 1fr));
  gap: 8px;
  width: 65%;
  min-width: 630px;
  flex-shrink: 0;
}

.flujo-paso label {
  display: block;
  font-size: 10px;
  font-weight: 700;
  color: var(--text-light);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin-bottom: 3px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.flujo-paso select {
  width: 100%;
  padding: 6px 8px;
  border: 1px solid var(--border);
  border-radius: var(--radius-input);
  font-size: 12px;
  font-family: inherit;
  background: var(--white);
  color: var(--text);
}

.flujo-paso select:disabled {
  background: var(--bg);
  color: var(--text-light);
  cursor: not-allowed;
}

.flujo-resultado {
  flex: 1;
  min-width: 240px;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 12px;
  background: var(--primary-light);
  border: 1px solid var(--primary);
  border-radius: var(--radius);
  flex-wrap: wrap;
}

.flujo-res-info {
  flex: 1;
  min-width: 140px;
}

.flujo-sku-nombre {
  font-size: 13px;
  font-weight: 700;
  color: var(--primary-dark);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.flujo-sku-precio {
  font-size: 11px;
  color: var(--text-light);
}

.flujo-res-actions {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-shrink: 0;
}

/* === TAB INDICATOR === */
.tab-dot {
  display: inline-block;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--success);
  margin-left: 4px;
  vertical-align: middle;
  opacity: 0;
}
.tab-dot.visible { opacity: 1; }

/* === HISTORIAL === */
.historial-header {
  background: var(--primary);
  color: var(--white);
  padding: 10px 16px;
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.historial-header h1 { font-size: 15px; font-weight: 700; }

/* Boton Volver unico (#200): pastilla con flecha + texto, a la izquierda y ANTES
   del titulo. Barra: 9 + 30 + 9 = 48 px; el titulo largo se corta en un renglon. */
.historial-header.con-volver { justify-content: flex-start; gap: 10px; padding: 9px 16px 9px 10px; }
.historial-header.con-volver h1 { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.volver {
  position: relative;
  display: inline-flex; align-items: center; gap: 1px;
  flex: 0 0 auto;
  height: 30px;
  padding: 0 10px 0 5px;
  border-radius: var(--radius-input);
  font: inherit; font-size: 13px; font-weight: 600; line-height: 1; white-space: nowrap;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: background-color 150ms cubic-bezier(0.25, 1, 0.5, 1), transform 150ms cubic-bezier(0.25, 1, 0.5, 1);
}
/* Area tactil de 44 px aunque la pastilla visible mida 30 */
.volver::before { content: ""; position: absolute; inset: -7px -4px; }
.volver svg { width: 18px; height: 18px; flex: 0 0 auto; }
.volver:active { transform: scale(0.97); }
.volver:focus-visible { outline: 2px solid currentColor; outline-offset: 2px; }

/* Superficie oscura: barra azul de la vista */
.volver-barra { color: var(--white); background: rgba(255,255,255,0.15); border: 1px solid rgba(255,255,255,0.4); }
.volver-barra:hover { background: rgba(255,255,255,0.28); }
.volver-barra:active { background: rgba(255,255,255,0.34); }

/* Superficie clara: arriba de un paso */
.volver-paso { color: var(--primary-dark); background: var(--white); border: 1px solid var(--border); margin-bottom: 14px; }
.volver-paso:hover,
.volver-paso:active { background: var(--primary-light); }

.cot-card {
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 12px;
  margin-bottom: 8px;
}
.cot-card-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  margin-bottom: 6px;
}
.cot-card-cliente { font-size: 15px; font-weight: 700; color: var(--text); line-height: 1.3; }
/* #536: en la tarjeta del tablero el importe nunca se corta; cede el nombre ("PARKS CONCENTRADORA" empujaba el total fuera de la tarjeta). */
.tablero-card .cot-card-header > :first-child { min-width: 0; }
.tablero-card .cot-card-cliente { overflow-wrap: anywhere; }
.cot-card-meta { font-size: 11px; color: var(--text-light); }
.cot-cadena-operam { font-size: 11px; color: var(--primary-dark); margin-top: 4px; font-variant-numeric: tabular-nums; }
.cot-card-total { font-size: 17px; font-weight: 700; color: var(--primary-dark); text-align: right; font-variant-numeric: tabular-nums; }
.cot-card-tier { font-size: 11px; color: var(--primary); }
.cot-card-actions { display: flex; gap: 6px; margin-top: 8px; flex-wrap: wrap; }
.cot-card-actions input, .cot-card-actions select { max-width: 100%; }

/* === RESUMEN ITEMS EDITABLE === */
.cart-item-qty {
  display: flex;
  align-items: center;
  gap: 4px;
  margin-top: 4px;
}
.cart-item-qty .qty-btn { width: 26px; height: 26px; font-size: 14px; }
.cart-item-qty .qty-input { width: 44px; height: 26px; font-size: 12px; }

/* === CART LINES TABLE (tab productos) === */
.cart-lines-table {
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
}

.cart-lines-head,
.cart-line {
  display: grid;
  grid-template-columns: 100px 1fr 90px 70px 62px 72px 28px;
  align-items: center;
  gap: 0;
}

.cart-lines-head {
  background: var(--primary);
  color: var(--white);
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.cart-lines-head span,
.cart-line > span,
.cart-line > div {
  padding: 7px 8px;
  border-right: 1px solid rgba(0,0,0,0.06);
}

.cart-lines-head span:last-child,
.cart-line > span:last-child,
.cart-line > div:last-child {
  border-right: none;
}

.cart-line {
  border-bottom: 1px solid var(--border);
  font-size: 12px;
}

.cart-line:last-child { border-bottom: none; }
.cart-line:nth-child(even) { background: var(--bg); }

.cart-line-sku {
  font-size: 11px;
  font-weight: 700;
  color: var(--primary-dark);
  word-break: break-all;
}

.cart-line-name {
  font-size: 12px;
  color: var(--text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.col-num { text-align: right; }
.col-del { text-align: center; }

.cart-line-qty-wrap {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 2px;
}

.cart-line-qty-wrap .qty-display {
  font-size: 12px;
  font-weight: 600;
  min-width: 22px;
  text-align: center;
}

.qty-icon-btn {
  background: none;
  border: none;
  cursor: pointer;
  font-size: 14px;
  color: var(--primary);
  padding: 1px 3px;
  line-height: 1;
  flex-shrink: 0;
}

.qty-icon-btn:hover { color: var(--primary-dark); }

.qty-ok-btn { color: var(--success); font-size: 16px; }
.qty-ok-btn:hover { color: #1a7a3a; }

.cart-line-qty-wrap .qty-input {
  width: 36px;
  height: 22px;
  font-size: 11px;
}

.cart-line-price {
  text-align: right;
  color: var(--text-light);
}

/* Precio manual de calca (#279): mismo control que el % de descuento por linea,
   un poco mas ancho porque lleva pesos y centavos. Sin permiso la celda es solo
   texto, igual que el descuento. */
.cart-line-price .precio-input {
  width: 64px;
  height: 22px;
  font-size: 11px;
  text-align: right;
  padding: 0 4px;
  border: 1px solid var(--border);
  border-radius: var(--radius-input);
  font-family: inherit;
}

/* % de descuento por linea (#137): sin permiso la celda es solo texto */
.cart-line-desc { text-align: right; }

/* Mismo control para la linea (#137) y para el atajo "% a todo" (#138) */
.cart-line-desc .desc-input,
.cart-desc-global .desc-input {
  width: 46px;
  height: 22px;
  font-size: 11px;
  text-align: right;
  padding: 0 4px;
  border: 1px solid var(--border);
  border-radius: var(--radius-input);
  font-family: inherit;
}

/* Atajo de descuento global (#138): escribe el mismo % en todas las partidas */
.cart-desc-global {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 8px;
  font-size: 12px;
  color: var(--text);
}

/* Editor de la descripcion que ve el cliente (#139): fila propia bajo la partida
   -- el texto llega a 1000 caracteres y no cabe en la celda del nombre. */
.cart-line-descripcion {
  grid-column: 1 / -1;
  border-top: 1px dashed var(--border);
  background: var(--bg);
}

.cart-line-descripcion textarea {
  width: 100%;
  font-family: inherit;
  font-size: 12px;
  padding: 5px 6px;
  border: 1px solid var(--border);
  border-radius: var(--radius-input);
  resize: vertical;
}

.cart-line-descripcion-hint {
  font-size: 10px;
  color: var(--text-light);
  margin-top: 3px;
}

/* Cancelar/Aceptar (#240): antes solo habia guardado invisible en blur. */
.cart-line-descripcion-acciones {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  margin-top: 6px;
  padding-bottom: 5px;
}

/* La partida con descripcion propia marca su lapiz para que se distinga de un
   nombre de catalogo de un vistazo. */
.cart-line-desc-editada { color: var(--primary); }

.cart-line-total {
  text-align: right;
  font-weight: 700;
  color: var(--text);
}

.cart-line-del {
  display: flex;
  justify-content: center;
}

.cart-line-del button {
  background: none;
  border: none;
  color: var(--danger);
  font-size: 15px;
  cursor: pointer;
  line-height: 1;
  padding: 2px;
}

.cart-lines-subtotal {
  margin-top: 6px;
  text-align: right;
  font-size: 13px;
  color: var(--text-light);
  padding: 0 4px;
}

.cart-lines-subtotal strong {
  color: var(--primary-dark);
  font-size: 14px;
}

/* Etiqueta de tarjeta movil (#233): oculta en escritorio, la pinta el media
   query de abajo. Markup aditivo, no cambia llaves ni onclick. */
.cart-line-etiqueta { display: none; }

/* === ENVIA.COM RATES === */
.envia-rate-card {
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 10px 14px;
  margin-bottom: 6px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  cursor: pointer;
  transition: border-color 0.15s, background 0.15s;
}

.envia-rate-card:hover {
  border-color: var(--primary);
  background: var(--primary-light);
}

.envia-rate-card.selected {
  border-color: var(--success);
  background: #F0FFF4;
}

.envia-rate-carrier {
  font-size: 13px;
  font-weight: 700;
  color: var(--primary-dark);
}

.envia-rate-servicio {
  font-size: 11px;
  color: var(--text-light);
  margin-top: 1px;
}

.envia-rate-precio {
  font-size: 15px;
  font-weight: 700;
  color: var(--text);
  white-space: nowrap;
}

.badge-rec {
  display: inline-block;
  font-size: 10px;
  font-weight: 600;
  background: var(--success);
  color: #fff;
  border-radius: 10px;
  padding: 1px 7px;
  margin-left: 6px;
  vertical-align: middle;
}

/* Chips de estado: tinte claro + texto oscuro del mismo matiz (estilo
   "NO LEIDO" de Bitrix; legible a pleno sol, WCAG AA en texto chico) */
.espera-badge, .cliente-badge, .reunion-badge, .evento-badge, .siguiente-contacto-badge, .origen-badge {
  display: inline-block;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.02em;
  border-radius: 9px;
  padding: 2px 8px;
  vertical-align: middle;
}
.espera-verde { background: oklch(0.9 0.08 150); color: oklch(0.3 0.08 152); }
.espera-ambar { background: oklch(0.89 0.1 80); color: oklch(0.36 0.08 70); }
.espera-rojo { background: oklch(0.87 0.08 28); color: oklch(0.36 0.12 28); }
.cliente-badge { background: var(--etapa-contactado); color: var(--etapa-contactado-texto); }
.reunion-badge { background: oklch(0.89 0.06 310); color: oklch(0.34 0.1 310); }
/* Chips de catalogo cerrado de la captura de expo (issue #261): un toque con el
   prospecto enfrente, area comoda para el pulgar en el telefono. */
.chip {
  display: inline-block;
  font-size: 14px;
  font-weight: 600;
  border: 1px solid var(--border);
  background: var(--white);
  color: inherit;
  border-radius: 18px;
  padding: 9px 14px;
  margin: 0 6px 6px 0;
  cursor: pointer;
}
.chip-activo { background: var(--primary); color: var(--white); border-color: var(--primary); }
.expo-acciones .btn { display: block; width: 100%; margin-bottom: 10px; padding: 14px; font-size: 16px; text-align: center; }

/* Pantalla unica de captura de expo (issue #267): tres bloques en una columna,
   sin acordeones, y Guardar fijo sobre el bottom-nav para que el vendedor no lo
   busque al final de una pantalla larga. */
.expo-cuerpo { padding: 16px 16px 88px; }
.seccion-titulo {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-light);
  margin: 18px 0 8px;
  padding-top: 12px;
  border-top: 1px solid var(--border);
}
.seccion-titulo:first-child { border-top: 0; padding-top: 0; margin-top: 0; }
.etiqueta-opcional { font-weight: 400; text-transform: none; letter-spacing: 0; color: var(--text-light); }
/* Ciudad por codigo postal en la captura de expo (issue #268): el chip confirma
   lo que dijo el indice -- la ciudad se ve, no se pide dos veces -- y el enlace
   "No sabe su CP" es la salida del stand, discreta y siempre a la mano. */
.chip-cp {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  margin-top: 6px;
  font-size: 13px;
  font-weight: 500;
  color: var(--primary);
  background: var(--primary-light);
  border-radius: 999px;
  padding: 6px 12px;
}
.enlace-sin-cp {
  display: block;
  margin-top: 6px;
  padding: 0;
  border: 0;
  background: none;
  font-size: 13px;
  color: var(--primary);
  text-decoration: underline;
  cursor: pointer;
}

.expo-guardar-fijo {
  position: fixed;
  left: 0;
  right: 0;
  bottom: var(--alto-barra-inferior);
  padding: 10px 16px;
  background: var(--white);
  border-top: 1px solid var(--border);
  z-index: 890;
}
.expo-guardar-fijo .btn { width: 100%; padding: 14px; font-size: 16px; }

/* Aviso de dominio mal escrito del correo (issue #269): mismo mecanismo que el
   formulario publico (public/css/mayoreo.css), que es otra hoja y no se carga
   aqui. Oculto hasta que sugerirDominioCorreo propone algo. */
.sug-correo { display: none; font-size: 12px; color: var(--text-light); margin-top: 6px; }
.sug-correo.ver { display: flex; align-items: center; gap: 8px; }

/* Evento de expo (issue #261): el prospecto que dejo la expo se reconoce de
   un vistazo en la tarjeta y en el pipeline. */
.evento-badge { background: oklch(0.9 0.07 200); color: oklch(0.34 0.09 220); }
.siguiente-contacto-badge { background: oklch(0.89 0.07 230); color: oklch(0.34 0.1 250); }

/* Origen (issue #287, GLOSSARY.md "Origen"): de donde vino el prospecto, con
   etiqueta propia en toda tarjeta de prospecto, cotizacion y cliente. El
   "sin identificar" (cliente historico de Operam, cotizacion sin prospecto
   ligado) va atenuado para que no se lea como un origen real. */
.origen-badge { background: oklch(0.91 0.05 285); color: oklch(0.35 0.09 290); }
.origen-badge-vacio { background: oklch(0.95 0.005 262); color: var(--text-light); font-weight: 600; }

/* Calificacion del paso 2 (issue #263): se lee de un vistazo en la tarjeta, y
   "Calificacion pendiente" usa el mismo chip mientras este vacia. */
.calificacion-badge {
  display: inline-block;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.02em;
  border-radius: 9px;
  padding: 2px 8px;
  margin: 0 4px 4px 0;
  vertical-align: middle;
  background: oklch(0.91 0.05 100);
  color: oklch(0.35 0.08 90);
}

/* Campo de texto libre con dictado: el microfono va pegado al campo. Sin
   soporte del navegador (marca sin-dictado en <body>) desaparece, para no
   ofrecer un boton que no hace nada. */
.campo-dictado { display: flex; gap: 6px; align-items: flex-start; }
.campo-dictado > input, .campo-dictado > textarea { flex: 1; }
.btn-mic {
  border: 1px solid var(--border);
  background: var(--white);
  border-radius: 8px;
  padding: 8px 10px;
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
}
.btn-mic-activo { background: var(--primary); border-color: var(--primary); }
.sin-dictado .btn-mic { display: none; }

/* PRE / Cotizacion N (issue #63, #309): una pre-cotizacion (sin folio de Operam)
   lleva el chip ambar "PRE"; una cotizacion registrada lleva el chip azul
   "Cotizacion N". */
.cot-badge {
  display: inline-block;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.02em;
  border-radius: 9px;
  padding: 2px 8px;
  margin-left: 6px;
  vertical-align: middle;
}
.badge-pre { background: oklch(0.89 0.1 80); color: oklch(0.36 0.08 70); }
.badge-operam { background: var(--primary-light); color: var(--primary-dark); }
/* Pago sin registrar (issue #77): tarjeta entregada con cobranza pendiente (rojo). */
.badge-impago { background: oklch(0.9 0.06 25); color: oklch(0.42 0.13 25); }
/* Falta comprobante (#485): la prueba del pago, no el pago -- ambar como sin Contacto. */
.badge-falta-comprobante { background: oklch(0.89 0.1 80); color: oklch(0.36 0.08 70); }
/* Calca incompleta (#535): aviso del checklist, no candado -- ambar como Falta comprobante. */
.badge-calca-incompleta { background: oklch(0.89 0.1 80); color: oklch(0.36 0.08 70); }
.comprobante-pago-archivos { font-size: 12px; color: var(--text-light); margin-bottom: 4px; }
/* Oportunidad sin Contacto (#342): falta la persona, no el dinero -- ambar. */
.badge-sin-contacto { background: oklch(0.89 0.1 80); color: oklch(0.36 0.08 70); margin-left: 0; }
/* Estados del Cliente Operam de la Oportunidad (#344, ADR-0016): rojo cuando
   falta la constancia, gris cuando ya la tiene, verde cuando ya nos compro. */
.badge-fiscal-pendiente { background: oklch(0.9 0.06 25); color: oklch(0.42 0.13 25); }
.badge-fiscal-listo { background: oklch(0.94 0.005 262); color: oklch(0.45 0.02 262); }
.badge-con-pedido { background: oklch(0.9 0.07 150); color: oklch(0.4 0.11 150); }

/* Estado de auto-subida a Operam (#83): bloque bajo los botones de generar y en
   las tarjetas del historial. Vacio cuando no hay subida en curso. */
.operam-status-slot:empty { display: none; }
.operam-status {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
  font-size: 13px;
  padding: 6px 10px;
  border-radius: 8px;
  background: var(--surface-2, #f4f4f5);
}
.operam-status-ok { background: oklch(0.93 0.06 150); color: oklch(0.38 0.09 150); font-weight: 600; }
.operam-status-pre { background: oklch(0.95 0.05 80); color: oklch(0.36 0.08 70); }
.operam-status-candidatos { display: block; }
.operam-candidatos-msg { font-weight: 600; margin-bottom: 6px; }
.operam-candidatos-lista { list-style: none; margin: 0 0 8px; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.operam-candidato { display: flex; align-items: flex-start; justify-content: space-between; gap: 8px; flex-wrap: wrap; padding-bottom: 6px; border-bottom: 1px solid var(--surface-2, #e5e5e8); }
.operam-candidato:last-child { border-bottom: none; padding-bottom: 0; }
.operam-candidato-info { display: flex; flex-direction: column; gap: 3px; min-width: 0; flex: 1 1 200px; }
/* Acciones por candidato (#211): Elegir y "Es sucursal de este cliente" -- envuelven
   en movil en vez de desbordar la fila. */
.operam-candidato-acciones { display: flex; flex-wrap: wrap; gap: 6px; align-items: flex-start; }
/* Reporte de pasos del alta en dos capas (#364, ADR-0017): el mensaje del glosario
   siempre a la vista y el detalle tecnico plegado dentro de un <details>. Discreto:
   lo normal es que la subida salga bien y esta lista ni aparezca. */
.operam-pasos { list-style: none; margin: 6px 0 0; padding: 0; display: flex; flex-direction: column; gap: 4px; }
.operam-paso { font-size: 12px; line-height: 1.4; padding-left: 10px; border-left: 3px solid oklch(0.75 0.13 85); }
.operam-paso-error { border-left-color: oklch(0.6 0.18 25); }
.operam-paso-ok { border-left-color: var(--success); }
.operam-paso-omitido { border-left-color: oklch(0.75 0 0); }
.operam-paso-detalle > summary { cursor: pointer; font-size: 11px; color: oklch(0.5 0 0); }
.operam-paso-detalle > div { font-size: 11px; color: oklch(0.45 0 0); word-break: break-word; }
/* Reporte del upgrade fiscal (#367): los datos que Operam no guardo, con el mismo
   patron de dos capas que el reporte de pasos del alta. Vive junto al panel de alta
   y solo aparece cuando queda algo que corregir. */
.upgrade-reporte { margin: 12px 0; padding: 10px 12px; border: 1px solid oklch(0.8 0.09 85); border-radius: 8px; background: oklch(0.98 0.02 85); }
.upgrade-reporte-titulo { margin: 0 0 6px; font-size: 13px; font-weight: 600; }
.upgrade-reporte .btn { margin-top: 10px; }
/* Hechos del picker de candidatos (#210): diferencia de nombre cruda y letreros
   de celular/correo -- evidencia, nunca candado (no deshabilitan Elegir/Crear
   nuevo). Sobrios y legibles en movil: texto chico, chips que envuelven. */
.operam-candidato-diff { font-size: 12px; color: oklch(0.5 0 0); }
/* Nombre corto repetido (#242): el hecho mas duro del picker -- Operam no dejaria
   crear un cliente con ese cust_ref. Se destaca sobre la diferencia de nombre. */
.operam-candidato-custref { font-size: 12px; font-weight: 600; color: oklch(0.42 0.13 25); }
.operam-candidato-letreros { display: flex; flex-wrap: wrap; gap: 6px; }
.operam-letrero { font-size: 11px; padding: 1px 7px; border-radius: 999px; white-space: nowrap; }
.operam-letrero-ok { background: oklch(0.93 0.06 150); color: oklch(0.38 0.09 150); }
.operam-letrero-alerta { background: oklch(0.9 0.08 25); color: oklch(0.42 0.13 25); }
.operam-letrero-neutro { background: var(--surface-2, #f4f4f5); color: oklch(0.5 0 0); }

/* Tableros kanban: prospectos (issue #49) y cotizaciones (issue #50) */
#prospectos-contenido { max-width: 520px; }
#prospectos-contenido.modo-tablero { max-width: none; }
.tablero {
  display: flex;
  gap: 14px;
  align-items: flex-start;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  margin-top: 16px;
  padding: 16px 14px 20px;
  border-radius: var(--radius);
  background: linear-gradient(160deg, var(--canvas) 0%, var(--canvas-hondo) 100%);
}
.tablero-col {
  flex: 0 0 280px;
  min-width: 280px;
  scroll-snap-align: start;
  background: oklch(1 0 0 / 0.07);
  border: 1px solid oklch(1 0 0 / 0.1);
  border-radius: var(--radius);
  padding: 8px;
  transition: background 180ms cubic-bezier(0.22, 1, 0.36, 1);
}
.tablero-col.drop-ok {
  background: oklch(1 0 0 / 0.16);
  border-color: oklch(1 0 0 / 0.45);
}
/* Mientras se arrastra: las columnas validas se encienden y las invalidas
   se apagan -- el tablero ensena a donde puede ir la tarjeta. */
.tablero.arrastrando .tablero-col.drop-valido {
  border-color: oklch(1 0 0 / 0.55);
  border-style: dashed;
  background: oklch(1 0 0 / 0.12);
}
.tablero.arrastrando .tablero-col:not(.drop-valido) {
  opacity: 0.45;
}
.tablero-col-vacia {
  border: 1px dashed oklch(1 0 0 / 0.25);
  border-radius: 8px;
  padding: 18px 8px;
  text-align: center;
  font-size: 12px;
  color: oklch(1 0 0 / 0.55);
}
.tablero-col-header { margin-bottom: 6px; }
.col-pill {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  font-weight: 700;
  border-radius: 8px;
  padding: 6px 10px;
}
.col-pill-nuevo, .col-pill-dia7 { background: var(--etapa-nuevo); color: var(--etapa-nuevo-texto); }
.col-pill-contactado, .col-pill-reciente { background: var(--etapa-contactado); color: var(--etapa-contactado-texto); }
.col-pill-calificado, .col-pill-dia2 { background: var(--etapa-calificado); color: var(--etapa-calificado-texto); }
.col-pill-cotizado, .col-pill-ganada { background: var(--etapa-cotizado); color: var(--etapa-cotizado-texto); }
.col-pill-no_util, .col-pill-perdida, .col-pill-cancelada { background: var(--etapa-no_util); color: var(--etapa-no_util-texto); }
.col-pill-por_vencer, .col-pill-vencida { background: var(--col-vencida); color: var(--col-vencida-texto); }
.col-pill-no_asignado { background: var(--etapa-no_asignado); color: var(--etapa-no_asignado-texto); }
.col-pill-por_cotizar { background: var(--etapa-por_cotizar); color: var(--etapa-por_cotizar-texto); }
.col-pill-seguimiento { background: var(--etapa-seguimiento); color: var(--etapa-seguimiento-texto); }
.col-pill-anticipo_pagado { background: var(--etapa-anticipo_pagado); color: var(--etapa-anticipo_pagado-texto); }
.col-pill-pedido_liberado { background: var(--etapa-pedido_liberado); color: var(--etapa-pedido_liberado-texto); }
.col-pill-saldo_pagado { background: var(--etapa-saldo_pagado); color: var(--etapa-saldo_pagado-texto); }
.col-pill-producto_entregado { background: var(--etapa-producto_entregado); color: var(--etapa-producto_entregado-texto); }
.tablero-col-count {
  background: oklch(0 0 0 / 0.12);
  border-radius: 9px;
  font-size: 11px;
  font-weight: 700;
  padding: 1px 8px;
}
.tablero-col-suma {
  text-align: center;
  font-size: 12px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--sobre-canvas);
  background: oklch(1 0 0 / 0.1);
  border-radius: 8px;
  padding: 3px 8px;
  margin-bottom: 6px;
}
.tablero-quick-add {
  width: 100%;
  border: 1px dashed oklch(1 0 0 / 0.4);
  background: none;
  color: var(--sobre-canvas);
  font-size: 12px;
  font-weight: 600;
  border-radius: 8px;
  padding: 7px 8px;
  margin-bottom: 6px;
  cursor: pointer;
  transition: background 150ms ease-out;
}
.tablero-quick-add:hover, .tablero-quick-add:focus-visible {
  background: oklch(1 0 0 / 0.12);
}
.tablero-col-cards { min-height: 40px; }
.tablero-col-cards .cot-card {
  background: var(--white);
  box-shadow: 0 1px 3px oklch(0.2 0.06 264 / 0.35);
  border: none;
  margin-bottom: 8px;
}
.tablero-card[draggable="true"] { cursor: grab; }
.tablero-card .cot-card-actions { flex-wrap: wrap; }
/* Control de asignar vendedor en la tarjeta No Asignado (issue #57) */
.tablero-asignar { margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--border); }
/* Checklist de producto decorado / calca (issue #61); plegada y con casillas (#532) */
.decorado-control { display: block; margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--border); }
.calca-pleg { padding-top: 0; }
.calca-pleg > summary { list-style: none; display: flex; align-items: center; gap: 8px; min-height: 44px; font-size: 13px; font-weight: 700; cursor: pointer; }
.calca-pleg > summary::-webkit-details-marker { display: none; }
.calca-pleg > summary .pl-chev { margin-left: auto; }
.calca-pleg > summary:focus-visible { outline: 3px solid var(--primary); outline-offset: -3px; }
.calca-pleg .pl-estado { font-variant-numeric: tabular-nums; }
.calca-checklist { list-style: none; margin: 0; padding: 0; }
.calca-paso { border-top: 1px solid var(--border); }
.calca-paso:first-child { border-top: none; }
.calca-check { display: grid; grid-template-columns: 15px 1fr; gap: 8px; align-items: center; min-height: 30px; padding: 3px 0; font-size: 12px; line-height: 1.2; cursor: pointer; }
.calca-check input { width: 15px; height: 15px; margin: 0; accent-color: var(--success); cursor: pointer; }
.calca-paso-hecho .calca-check span { color: var(--text-light); }
.calca-dropbox { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; padding: 0 0 6px 23px; }
.calca-dropbox input[type=file] { flex: 1 1 160px; min-width: 0; font-size: 12px; font-family: inherit; color: var(--text-light); }
.calca-dropbox input[type=file]::file-selector-button { min-height: 30px; margin-right: 8px; padding: 0 10px; font-size: 12px; border-radius: 6px; border: 1px solid var(--border); background: var(--white); color: var(--primary-dark); font-weight: 700; font-family: inherit; }
.calca-dropbox .btn { margin: 0; min-height: 30px; font-size: 12px; padding: 0 10px; }
.calca-quitar { display: block; margin: 2px 0 0 auto; min-height: 32px; padding: 0 4px; border: none; background: none; font: inherit; font-size: 12px; font-weight: 700; color: var(--danger); cursor: pointer; }
.tablero-aviso {
  position: fixed;
  bottom: 24px;
  left: 50%;
  transform: translateX(-50%);
  background: var(--text);
  color: var(--white);
  font-size: 13px;
  padding: 8px 16px;
  border-radius: 6px;
  z-index: 1100;
}

/* === Lista del Pipeline (#518): acordeon por etapa + fila que se expande ===
   Movil primero (sol directo, un pulgar): nombres 16px, secundario 14px, todo
   lo tocable >= 44px. Cada seccion toma su color de --etapa-<etapa>. */
.etapa-no_asignado { --e: var(--etapa-no_asignado); --et: var(--etapa-no_asignado-texto); }
.etapa-por_cotizar { --e: var(--etapa-por_cotizar); --et: var(--etapa-por_cotizar-texto); }
.etapa-seguimiento { --e: var(--etapa-seguimiento); --et: var(--etapa-seguimiento-texto); }
.etapa-anticipo_pagado { --e: var(--etapa-anticipo_pagado); --et: var(--etapa-anticipo_pagado-texto); }
.etapa-pedido_liberado { --e: var(--etapa-pedido_liberado); --et: var(--etapa-pedido_liberado-texto); }
.etapa-saldo_pagado { --e: var(--etapa-saldo_pagado); --et: var(--etapa-saldo_pagado-texto); }
.etapa-producto_entregado { --e: var(--etapa-producto_entregado); --et: var(--etapa-producto_entregado-texto); }
.pl { --pl-ease: cubic-bezier(0.22, 1, 0.36, 1); padding-bottom: 24px; }
.pl-chev { width: 18px; height: 18px; flex: 0 0 18px; color: var(--text-light); transition: transform 200ms var(--pl-ease); }
[aria-expanded="true"] > .pl-chev, details[open] > summary > .pl-chev { transform: rotate(180deg); }
.pl-barra { display: flex; justify-content: flex-end; margin-bottom: 4px; }
.pl-todo { border: none; background: none; color: var(--primary); font: inherit; font-size: 14px; font-weight: 700; min-height: 44px; padding: 0 4px; cursor: pointer; }
.pl-sec { margin-bottom: 10px; }
.pl-sec-cab {
  position: sticky; top: 0; z-index: 3; width: 100%;
  display: grid; grid-template-columns: 1fr auto auto 18px; align-items: center; gap: 10px;
  min-height: 52px; padding: 0 12px; border: none; border-left: 6px solid var(--et);
  border-radius: 8px; background: var(--e); color: var(--et); font: inherit; text-align: left; cursor: pointer;
}
.pl-sec-abierta > .pl-sec-cab { border-bottom-left-radius: 0; border-bottom-right-radius: 0; }
.pl-sec-nom { font-size: 16px; font-weight: 700; }
.pl-sec-n { min-width: 28px; text-align: center; font-size: 14px; font-weight: 800; padding: 2px 9px; border-radius: 5px; background: var(--et); color: var(--white); font-variant-numeric: tabular-nums; }
.pl-sec-suma { font-size: 14px; font-weight: 600; font-variant-numeric: tabular-nums; }
.pl-sec-cab > .pl-chev { color: var(--et); }
.pl-sec-vacia .pl-sec-cab { cursor: default; min-height: 44px; opacity: 0.6; grid-template-columns: 1fr auto auto; }
.pl-filas { padding: 6px 0 4px; display: flex; flex-direction: column; gap: 8px; }
.pl-fila { background: var(--white); border: 1px solid var(--border); border-radius: 8px; scroll-margin-top: 60px; }
.pl-abierta { border: 2px solid var(--et); }
.pl-fila-cab {
  width: 100%; display: grid; grid-template-columns: 1fr auto 18px;
  grid-template-areas: "nom tot chev" "chips chips chips" "meta meta meta";
  column-gap: 10px; row-gap: 5px; align-items: start; min-height: 64px; padding: 12px 12px 12px 14px;
  border: none; background: none; color: var(--text); font: inherit; text-align: left; cursor: pointer; border-radius: 8px;
}
.pl-fila-cab:focus-visible, .pl-sec-cab:focus-visible, .pl-todo:focus-visible, .pl-pleg summary:focus-visible { outline: 3px solid var(--primary); outline-offset: -3px; }
.pl-nombre { grid-area: nom; font-size: 16px; font-weight: 700; line-height: 1.25; overflow-wrap: anywhere; }
.pl-total { grid-area: tot; font-size: 16px; font-weight: 700; font-variant-numeric: tabular-nums; white-space: nowrap; }
.pl-sin-total { font-size: 14px; font-weight: 500; color: var(--text-light); }
.pl-fila-cab > .pl-chev { grid-area: chev; margin-top: 2px; }
.pl-chips { grid-area: chips; display: flex; flex-wrap: wrap; gap: 5px; }
.pl-meta { grid-area: meta; font-size: 14px; color: var(--text-light); }
.pl .cot-badge, .pl .origen-badge { margin: 0; font-size: 12px; padding: 3px 9px; }
.pl .cot-cadena-operam { font-size: 14px; margin: 0; }
.pl-detalle { padding: 2px 14px 14px; display: flex; flex-direction: column; gap: 12px; }
.pl-info { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; padding-top: 12px; border-top: 1px solid var(--border); }
.pl-detalle .btn { min-height: 46px; font-size: 15px; margin: 0; }
.pl-detalle select { min-height: 46px; font-size: 15px; font-family: inherit; border: 1px solid var(--border); border-radius: 6px; background: var(--white); color: var(--text); padding: 0 12px; }
.pl-acciones { display: flex; flex-wrap: wrap; gap: 8px; }
.pl-acciones .cot-card-actions { display: contents; }
.pl-acciones .btn { flex: 1 1 140px; }
.pl-acciones select { flex: 1 1 100%; }
.pl-acciones .badge-sin-contacto { display: none; }
/* WhatsApp y Correo de la Oportunidad (#519): el mismo par en la tarjeta y en la fila abierta; el icono es chico pero el blanco de toque mide 44 px. */
.cot-card-lado { display: flex; flex-direction: column; align-items: flex-end; }
.tablero-card .cot-card-lado { flex-shrink: 0; }
.contacto-directo { display: flex; margin: -10px -10px -10px 0; }
.cot-card-total + .contacto-directo { margin-top: -6px; }
.pl-info .contacto-directo { margin-left: auto; }
.btn-contacto { display: inline-flex; align-items: center; justify-content: center; width: 44px; height: 44px; padding: 0; border: 0; border-radius: 50%; background: none; color: var(--text-light); cursor: pointer; text-decoration: none; }
.btn-contacto svg { width: 22px; height: 22px; }
.btn-contacto-wa { color: #128C7E; }
.btn-contacto:hover { background: var(--bg); }
.btn-contacto:disabled { color: var(--text); opacity: .3; cursor: not-allowed; background: none; }
/* Menu de tres puntos (#533, variante A de #531): en el renglon de WhatsApp y correo; la lista flota (position fixed, la coloca app.js) para que no la tape la tarjeta vecina ni el borde de la columna. */
.contacto-fila { display: flex; align-items: center; }
.cot-card-total + .contacto-fila { margin-top: -6px; }
.pl-info .contacto-fila { margin-left: auto; }
.contacto-fila .contacto-directo { margin-right: 0; }
.menu-mas { display: flex; margin: -10px -10px -10px 0; }
.menu-mas-boton { display: inline-flex; align-items: center; justify-content: center; width: 44px; height: 44px; padding: 0; border: 0; border-radius: 50%; background: none; color: var(--text-light); cursor: pointer; }
.menu-mas-boton:hover, .menu-mas-boton[aria-expanded="true"] { background: var(--bg); color: var(--text); }
.menu-mas-boton:focus-visible { outline: 3px solid var(--primary); outline-offset: -3px; }
.menu-mas-lista { position: fixed; z-index: 120; min-width: 210px; padding: 6px; border-radius: 10px; background: var(--white); box-shadow: 0 8px 24px oklch(0.25 0.03 255 / 0.22), 0 0 0 1px var(--border); }
.menu-mas-lista[hidden] { display: none; }
.menu-mas-opcion { display: flex; flex-direction: column; justify-content: center; align-items: flex-start; width: 100%; min-height: 48px; padding: 6px 12px; border: 0; border-radius: 6px; background: none; font: inherit; font-size: 15px; font-weight: 600; color: var(--text); text-align: left; cursor: pointer; }
.menu-mas-opcion small { font-size: 12px; font-weight: 500; color: var(--text-light); }
.menu-mas-opcion:hover { background: var(--bg); }
.menu-mas-opcion:focus-visible { background: var(--bg); outline: 2px solid var(--primary); outline-offset: -2px; }
.menu-mas-peligro { color: var(--danger); }
.pl-pleg { border: 1px solid var(--border); border-radius: 8px; background: var(--bg); }
.pl-pleg summary { list-style: none; display: grid; grid-template-columns: 1fr auto 18px; gap: 10px; align-items: center; min-height: 50px; padding: 0 12px; font-size: 15px; font-weight: 700; cursor: pointer; }
.pl-pleg summary::-webkit-details-marker { display: none; }
.pl-estado { font-size: 12px; font-weight: 700; padding: 3px 9px; border-radius: 5px; }
.pl-estado-alerta { background: oklch(0.89 0.1 80); color: oklch(0.36 0.08 70); }
.pl-estado-pend { background: var(--primary-light); color: var(--primary-dark); }
.pl-estado-ok { background: oklch(0.92 0.06 150); color: oklch(0.32 0.09 150); }
.pl-pleg-cuerpo { padding: 0 12px 12px; }
.pl-pleg .cot-card-actions { display: flex; flex-direction: column; align-items: flex-start; gap: 8px; margin: 0; padding: 0; border: none; }
.pl-pleg .calca-check { font-size: 13px; }
.pl-pleg .btn { min-height: 34px; font-size: 13px; padding: 0 12px; }
.pl-pleg input[type=file] { width: 100%; font-size: 13px; padding: 0; color: var(--text-light); font-family: inherit; }
.pl-pleg input[type=file]::file-selector-button { min-height: 32px; margin-right: 10px; padding: 0 10px; font-size: 13px; border-radius: 6px; border: 1px solid var(--border); background: var(--white); color: var(--primary-dark); font-weight: 700; font-family: inherit; }
.pl-pleg .comprobante-pago-archivos { font-size: 14px; color: var(--text-light); }
.pl-salida { display: flex; flex-direction: column; gap: 8px; padding-top: 12px; border-top: 1px solid var(--border); }
.pl-salida-tit { font-size: 12px; font-weight: 800; letter-spacing: 0.06em; text-transform: uppercase; color: var(--text-light); }
.pl-salida .cot-card-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin: 0; }
.pl-salida select { grid-column: 1 / -1; }
.pl-salida .btn { background: var(--white); color: var(--danger); border: 1px solid var(--danger); }
@media (min-width: 900px) {
  .pl { max-width: 1000px; }
  .pl-fila-cab { grid-template-columns: minmax(0, 1.6fr) minmax(0, 1.4fr) minmax(0, 1.2fr) 140px 18px; grid-template-areas: "nom chips meta tot chev"; align-items: center; min-height: 56px; }
  .pl-total { text-align: right; }
  .pl-detalle { display: grid; grid-template-columns: 1fr 1fr; align-items: start; }
  .pl-info, .pl-salida { grid-column: 1 / -1; }
}
@media (prefers-reduced-motion: reduce) { .pl-chev { transition: none; } }
/* Fecha de entrega del pedido (#531, variante A): renglon con camion bajo el
   encabezado de la tarjeta y en la fila cerrada de la lista. Sin color por
   atraso; la cuenta de dias va en negritas cuando es hoy o ya vencio. */
.entrega-pedido { display: flex; align-items: center; gap: 6px; margin: 2px 0 6px; font-size: 14px; color: var(--text); font-variant-numeric: tabular-nums; }
.entrega-pedido svg { width: 18px; height: 18px; flex: 0 0 18px; color: var(--text-light); }
.entrega-pedido b { font-weight: 700; }
.entrega-pedido-dias { color: var(--text-light); white-space: nowrap; } /* #536: baja completa, nunca "en 15 / d" */
.entrega-pedido-dias.entrega-pedido-ya { color: var(--text); font-weight: 700; }
/* #534: Entregado parcialmente es un aviso dentro de Producto entregado; naranja
   oscuro (el tono de --warning, legible como texto sobre blanco). */
.entrega-pedido.entrega-pedido-parcial, .entrega-pedido.entrega-pedido-parcial svg { color: oklch(0.52 0.14 55); }
.pl .entrega-pedido { grid-area: ent; margin: 0; font-size: 15px; }
.pl-fila-cab:has(.entrega-pedido) { grid-template-areas: "nom tot chev" "ent ent ent" "chips chips chips" "meta meta meta"; }
@media (min-width: 900px) {
  .pl-sec:is(.etapa-anticipo_pagado, .etapa-pedido_liberado, .etapa-saldo_pagado, .etapa-producto_entregado) .pl-fila-cab { grid-template-columns: minmax(0, 1.4fr) 300px minmax(0, 1.1fr) minmax(0, 1.1fr) 120px 18px; grid-template-areas: "nom ent chips meta tot chev"; }
}

/* === RESPONSIVE === */
@media (max-width: 480px) {
  /* El shell de 66vw/800px es de escritorio; en telefono el paso Cliente (#82)
     exige ancho fluido sin scroll horizontal (PRODUCT.md movil primero). */
  #app-view, #historial-view { width: 100vw; min-width: 0; padding: 0 4px; }
  .form-row { grid-template-columns: 1fr; }
  .tab { font-size: 11px; padding: 8px 4px; }
  .flujo-grid {
    grid-template-columns: repeat(3, 1fr);
    width: 100%;
    min-width: 0;
  }
  .search-selected-item { flex-direction: column; align-items: flex-start; }

  /* Tarjeta apilada para "Articulos cotizados" (#233): en telefono la rejilla
     de 7 columnas no cabe (422px fijos + 1fr) y el overflow:hidden cortaba la
     derecha sin scroll. Debajo de 480px cada linea se convierte en tarjeta:
     el encabezado se oculta (las etiquetas viven en la celda via markup
     aditivo .cart-line-etiqueta) y las 4 celdas numericas pasan a una fila de
     4 columnas iguales, cada una con su etiqueta apilada arriba. */
  .cart-lines-table { overflow: visible; border: none; background: none; }

  .cart-lines-head { display: none; }

  .cart-line {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    grid-template-areas:
      "sku sku sku del"
      "name name name name"
      "qty price desc total";
    gap: 4px 6px;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    margin-bottom: 8px;
    padding: 8px;
  }

  /* La regla de escritorio le quita el borde inferior al ultimo renglon
     (linea 926); en tarjeta cada linea necesita su borde completo, la
     ultima incluida -- sin este override la ultima tarjeta se queda sin
     borde de abajo. */
  .cart-line:last-child { border: 1px solid var(--border); margin-bottom: 8px; }
  .cart-line:nth-child(even) { background: var(--white); }

  .cart-lines-head span,
  .cart-line > span,
  .cart-line > div {
    padding: 0;
    border-right: none;
  }

  .cart-line-sku { grid-area: sku; }

  .cart-line-name {
    grid-area: name;
    white-space: normal;
    overflow: visible;
    text-overflow: clip;
  }

  .cart-line-qty-wrap {
    grid-area: qty;
    flex-wrap: wrap;
    justify-content: flex-start;
    /* La celda lleva .col-num (text-align:right) y su etiqueta ocupa el ancho
       completo: sin este left, "Cant." se pegaba a la derecha mientras su valor
       quedaba a la izquierda. Las otras tres celdas ya lo reciben abajo. */
    text-align: left;
  }

  .cart-line-price,
  .cart-line-desc,
  .cart-line-total {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    text-align: left;
  }

  .cart-line-price { grid-area: price; }
  .cart-line-desc { grid-area: desc; }
  .cart-line-total { grid-area: total; }

  .cart-line-del {
    grid-area: del;
    justify-content: flex-end;
  }

  .cart-line-etiqueta {
    display: block;
    flex-basis: 100%;
    font-size: 9px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: var(--text-light);
  }
}

/* === ACORDEON ALTA CLIENTE (issue #27) === */

.alta-seccion {
  margin-bottom: 8px;
  border: 2px solid var(--border);
  border-radius: var(--radius);
  /* clip y no hidden (#442): hidden hace de la seccion un contenedor de scroll
     y el boton .accion-fija dejaria de pegarse a la pantalla. */
  overflow: clip;
  transition: border-color 0.15s;
}

/* Boton de accion (#442): el que confirma cada seccion del alta, "Siguiente"
   de los pasos y la fila de Generar PDF. Mientras lo que cierra sigue abajo,
   se queda a la vista ARRIBA de la bottom-nav y del total del carrito. */
.accion-fija {
  position: sticky;
  bottom: var(--pie-fijo);
  z-index: 1;
}

/* Cotizar de Envio (#488): se apila arriba del "Siguiente" de Envio, que
   tambien es sticky; si compartieran --pie-fijo, el Siguiente lo taparia.
   #shipping-envia sin caja: el sticky no sale de su bloque contenedor y asi
   ese bloque es el paso Envio entero (app.js lo muestra con display ''). */
#shipping-envia { display: contents; }
#btn-sig-envio { height: var(--alto-siguiente-envio); }
#shipping-envia > .accion-fija {
  bottom: calc(var(--pie-fijo) + var(--alto-siguiente-envio));
  /* #513: hueco opaco (fondo en linea) entre Cotizar y el Siguiente. */
  padding-bottom: 10px;
}

.alta-seccion.alta-sec-activa {
  border-color: var(--primary);
}

.alta-seccion-bloqueada {
  opacity: 0.5;
}

.alta-sec-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 13px 16px;
  cursor: pointer;
  background: #fff;
  user-select: none;
  transition: background 0.1s;
}

.alta-sec-header:hover {
  background: var(--primary-light);
}

.alta-seccion-bloqueada .alta-sec-header:hover {
  background: #fff;
}

.alta-sec-num {
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: var(--border);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 11px;
  font-weight: 700;
  color: var(--text-light);
  flex-shrink: 0;
  transition: background 0.15s, color 0.15s;
}

.alta-sec-activa .alta-sec-num {
  background: var(--primary);
  color: #fff;
}

.alta-sec-titulo {
  font-weight: 700;
  font-size: 13px;
  color: var(--text);
}

.alta-sec-activa .alta-sec-titulo {
  color: var(--primary-dark);
}

.alta-sec-icono {
  font-size: 18px;
  color: var(--text-light);
}

.alta-sec-body {
  padding: 16px;
  background: #fff;
  border-top: 1px solid var(--border);
}

.alta-checkpoint {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
}

.alta-chk-dot {
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--border);
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 9px;
  font-weight: 700;
  color: #fff;
  transition: background 0.2s;
}

.alta-chk-dot.done {
  background: var(--success);
}

.alta-chk-label {
  color: var(--text-light);
  transition: color 0.2s;
}

.alta-chk-dot.done + .alta-chk-label {
  color: var(--text);
}

/* Acordeon y lateral "Progreso del alta" lado a lado; en telefono el lateral
   pasa a una tira compacta ARRIBA del formulario (#442): con su ancho fijo de
   210px desbordaba la pantalla a 412px y la pagina se desplazaba de lado. */
#alta-layout {
  display: flex;
  gap: 16px;
  align-items: flex-start;
}

#alta-sidebar {
  width: 210px;
  flex-shrink: 0;
  position: sticky;
  top: 16px;
}

.alta-checkpoints {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

@media (max-width: 480px) {
  #alta-layout {
    flex-direction: column;
    align-items: stretch;
    gap: 8px;
  }
  #alta-sidebar {
    order: -1;
    width: 100%;
    position: static;
  }
  .alta-checkpoints {
    flex-direction: row;
    flex-wrap: wrap;
    gap: 6px 14px;
  }
}

/* === CSF DROPZONE (issue #28) === */

.csf-dropzone {
  border: 2px dashed var(--border);
  border-radius: var(--radius);
  padding: 32px 16px;
  text-align: center;
  background: var(--bg);
  cursor: pointer;
  transition: border-color 0.2s, background 0.2s;
  margin-bottom: 12px;
}

.csf-dropzone.dragover {
  border-color: var(--primary);
  background: var(--primary-light);
}

.csf-drop-icon {
  font-size: 36px;
  margin-bottom: 10px;
}

.csf-dropzone strong {
  display: block;
  font-size: 15px;
  color: var(--text);
  margin-bottom: 4px;
}

.csf-dropzone p {
  font-size: 13px;
  color: var(--text-light);
}

.csf-spinner-wrap {
  text-align: center;
  padding: 20px 0;
  color: var(--primary-dark);
  font-size: 13px;
}

.csf-spinner {
  display: inline-block;
  width: 28px;
  height: 28px;
  border: 3px solid var(--primary-light);
  border-top-color: var(--primary);
  border-radius: 50%;
  animation: csf-spin 0.8s linear infinite;
  margin-bottom: 10px;
}

@keyframes csf-spin {
  to { transform: rotate(360deg); }
}

.csf-banner-ok {
  background: #e8f5e9;
  color: #2e7d32;
  border-radius: 8px;
  padding: 10px 14px;
  font-size: 13px;
  font-weight: 600;
  margin-bottom: 4px;
}

.csf-banner-err {
  background: #ffeaea;
  color: var(--danger);
  border-radius: 8px;
  padding: 10px 14px;
  font-size: 13px;
  font-weight: 500;
  margin-bottom: 4px;
}

/* === TAB SWITCHER (issue #30) === */

.alta-tab-switcher {
  display: flex;
  gap: 0;
  margin-bottom: 16px;
  border: 1px solid var(--border);
  border-radius: 8px;
  overflow: hidden;
}

.alta-tab-btn {
  flex: 1;
  padding: 8px 12px;
  font-size: 13px;
  font-weight: 600;
  background: var(--white);
  color: var(--text-light);
  border: none;
  cursor: pointer;
  transition: background 0.15s, color 0.15s;
}

.alta-tab-btn + .alta-tab-btn {
  border-left: 1px solid var(--border);
}

.alta-tab-btn.active {
  background: var(--primary);
  color: var(--white);
}

/* === DEDUPLICACION (issue #31) === */

.dedup-alerta-roja {
  background: #ffeaea;
  color: var(--danger);
  border-left: 4px solid var(--danger);
  border-radius: 6px;
  padding: 10px 14px;
  font-size: 13px;
  font-weight: 600;
  margin-bottom: 8px;
}

.dedup-alerta-naranja {
  background: #fff3e0;
  color: #e65100;
  border-left: 4px solid #e65100;
  border-radius: 6px;
  padding: 10px 14px;
  font-size: 13px;
  font-weight: 600;
  margin-bottom: 8px;
}

.dedup-exacto, .dedup-candidatos, .dedup-domicilios, .dedup-candidatos-generico {
  font-size: 13px;
  padding: 8px 0;
}

.candidato-generico-fila {
  padding: 6px 0;
}

.dedup-domicilios label, .dedup-candidatos label {
  display: block;
  padding: 6px 0;
  cursor: pointer;
}

/* === DIFF FISCAL al subir CSF de cliente existente (issue #38) === */

.diff-fiscal-panel {
  margin-top: 12px;
  padding: 10px 14px;
  background: #fff8f0;
  border: 1px solid #fff3e0;
  border-radius: 6px;
  font-size: 13px;
}

.diff-fiscal-fila {
  padding: 4px 0;
}

.diff-fiscal-anterior {
  color: var(--text-light);
  text-decoration: line-through;
}

.diff-fiscal-nuevo {
  color: var(--text);
  font-weight: 600;
}

/* Frase de un campo que Operam no devuelve en ninguna lectura (#395): no es una
   diferencia medida, asi que no lleva el fondo de alerta del encabezado -- solo el
   ritmo del panel y el ancho de linea del texto corrido. */
.diff-fiscal-no-verificable {
  margin: 8px 0 0;
  line-height: 1.45;
}

.diff-fiscal-acciones {
  margin-top: 10px;
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

/* Navegacion inferior fija (bottom-nav, issue #53): 4 destinos con el pulgar.
   Cobalto de marca para el activo; el resto neutro. */
.bottom-nav {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  align-items: stretch;
  background: var(--white);
  border-top: 1px solid var(--border);
  box-shadow: 0 -2px 8px oklch(0.28 0.015 75 / 0.06);
  z-index: 900;
}
.bottom-nav-btn {
  flex: 1;
  border: none;
  background: none;
  padding: 12px 4px;
  font-size: 13px;
  font-weight: 600;
  color: var(--text-light);
  cursor: pointer;
}
.bottom-nav-btn.activo {
  color: var(--primary);
  box-shadow: inset 0 2px 0 var(--primary);
}
.nav-mas-menu {
  position: absolute;
  right: 8px;
  bottom: 56px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 8px;
  box-shadow: 0 4px 16px oklch(0.28 0.015 75 / 0.12);
}
/* Boton + global (issue #54): crear desde cualquier destino. Centrado en la
   barra, cobalto de marca, sobresale para leerse como accion primaria. */
.bottom-nav-add {
  flex: 0 0 48px;
  align-self: center;
  width: 48px;
  height: 48px;
  margin: 0 4px;
  border: none;
  border-radius: 50%;
  background: var(--primary);
  color: var(--white);
  font-size: 26px;
  line-height: 1;
  font-weight: 400;
  cursor: pointer;
  box-shadow: 0 2px 8px oklch(0.28 0.015 75 / 0.18);
}
/* Menu del boton + (issue #54): centrado sobre el boton, mismo estilo que Mas. */
.nav-nuevo-menu {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  bottom: 64px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 8px;
  box-shadow: 0 4px 16px oklch(0.28 0.015 75 / 0.12);
}
/* Deja espacio para que la barra fija no tape el contenido. */
body {
  padding-bottom: var(--alto-barra-inferior);
}

/* ============================================================
   Paso Cliente -- variante B (issue #82)
   Dos caminos, buscador unificado, tarjeta con chips. Reusa los
   tokens de marca; tap targets >= 44px, flujo de un pulgar.
   ============================================================ */
.pc-pregunta { font-size: 22px; font-weight: 700; line-height: 1.25; margin-bottom: 16px; letter-spacing: -0.01em; color: var(--text); }
.pc-pregunta small { display: block; font-size: 13px; font-weight: 400; color: var(--text-light); margin-top: 4px; letter-spacing: 0; }

/* Caminos */
.pc-camino {
  display: flex; align-items: center; gap: 14px; width: 100%; text-align: left;
  background: var(--white); border: 1.5px solid var(--border); border-radius: var(--radius);
  padding: 18px 16px; margin-bottom: 10px; cursor: pointer; font: inherit; color: inherit;
  transition: border-color .18s, box-shadow .18s;
}
.pc-camino:hover { border-color: var(--primary); }
.pc-camino:active { border-color: var(--primary-dark); }
.pc-camino-ico { width: 44px; height: 44px; border-radius: var(--radius); flex-shrink: 0; display: flex; align-items: center; justify-content: center; font-size: 20px; background: var(--primary-light); color: var(--primary-dark); }
.pc-camino-txt { flex: 1; min-width: 0; }
.pc-camino-tit { display: block; font-size: 16px; font-weight: 700; }
.pc-camino-desc { display: block; font-size: 13px; color: var(--text-light); margin-top: 1px; }
.pc-camino-fl { margin-left: auto; color: var(--text-light); font-size: 22px; line-height: 1; }

/* Nota de diferimiento */
.pc-nota { display: flex; gap: 10px; margin-top: 18px; padding: 12px 14px; background: var(--white); border: 1px solid var(--border); border-radius: var(--radius); font-size: 12.5px; color: var(--text-light); line-height: 1.5; }

/* Buscador */
.pc-search { margin-bottom: 8px; }
.pc-input-lg { width: 100%; min-height: 54px; padding: 14px 16px; border: 1.5px solid var(--border); border-radius: var(--radius-input); font-size: 17px; outline: none; background: var(--white); color: var(--text); }
.pc-input-lg:focus { border-color: var(--primary); }

/* Resultados */
.pc-res-titulo { font-size: 12px; font-weight: 700; color: var(--text-light); text-transform: uppercase; letter-spacing: .04em; margin: 14px 0 6px; }
.pc-res-row {
  display: flex; align-items: center; gap: 12px; width: 100%; text-align: left;
  background: var(--white); border: 1.5px solid var(--border); border-radius: var(--radius);
  padding: 12px 14px; margin-bottom: 8px; cursor: pointer; min-height: 60px;
  font: inherit; color: inherit; transition: border-color .18s;
}
.pc-res-row:hover { border-color: var(--primary); }
.pc-res-ini { width: 38px; height: 38px; border-radius: 50%; flex-shrink: 0; display: flex; align-items: center; justify-content: center; font-size: 14px; font-weight: 700; background: var(--primary-light); color: var(--primary-dark); }
/* .contacto es la fila de la PERSONA en la vista Clientes (#346) */
.pc-res-ini.prospecto, .pc-res-ini.contacto { background: oklch(0.93 0.05 85); color: oklch(0.42 0.08 70); }
.pc-res-main { flex: 1; min-width: 0; }
.pc-res-nombre { display: block; font-size: 15px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pc-res-sub { display: block; font-size: 12.5px; color: var(--text-light); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pc-tag { font-size: 11px; font-weight: 700; padding: 3px 9px; border-radius: 999px; flex-shrink: 0; }
.pc-tag.operam { background: var(--primary-light); color: var(--primary-dark); }
.pc-tag.prospecto { background: oklch(0.93 0.05 85); color: oklch(0.42 0.08 70); }
/* Cliente Operam Sin datos fiscales: salta a la vista Clientes (#94/#344) */
.pc-tag.generico { background: oklch(0.9 0.06 25); color: oklch(0.42 0.13 25); }
/* Estado comercial con pedido (#344): verde -- ya nos compro */
.pc-tag.con-pedido { background: oklch(0.9 0.07 150); color: oklch(0.4 0.11 150); }
/* Etiquetas del Contacto (#346): las dos que no reusan un tag existente */
.pc-tag.cotizado { background: oklch(0.93 0.04 262); color: oklch(0.4 0.09 262); }
.pc-tag.cliente-en-linea { background: oklch(0.93 0.05 310); color: oklch(0.42 0.1 310); }
/* Banner de contexto del upgrade fiscal (#94): contra quien se actualiza */
.banner-upgrade { display: flex; gap: 10px; align-items: flex-start; background: var(--primary-light); border: 1px solid var(--primary); border-radius: var(--radius); padding: 12px 14px; font-size: 13px; margin-bottom: 14px; }
.banner-upgrade b { display: block; }
.banner-upgrade small { color: var(--primary-dark); }
.pc-crear { border-style: dashed; border-color: oklch(0.82 0.03 262); background: oklch(0.985 0.008 262); }
.pc-crear .pc-res-ini { background: var(--primary); color: var(--white); font-size: 22px; font-weight: 400; }

/* Sugerencias (contacto nuevo) */
.pc-sugerencias { margin: -4px 0 10px; }
.pc-sug-titulo { font-size: 12px; color: var(--text-light); margin-bottom: 6px; }

/* intl-tel-input en los cinco campos de telefono del alta interna (issue #176).
   El widget envuelve el input en su propio .iti, que por default es
   inline-block y dejaria el campo a media caja. El padding izquierdo del input
   (el hueco de la bandera) lo pone el propio widget en linea segun el ancho de
   su boton, asi que aqui NO se toca: escribirlo desde el CSS lo pisaria. */
.iti { width: 100%; }
.tel-aviso {
  margin-top: 6px; font-size: 12.5px; padding: 8px 10px; border-radius: 8px; line-height: 1.4;
  background: oklch(0.95 0.06 85); color: oklch(0.42 0.09 70);
}

/* Avisos de clasificacion de celular */
.pc-cel-aviso { margin-top: 6px; font-size: 12.5px; padding: 8px 10px; border-radius: 8px; line-height: 1.4; }
.pc-aviso-ambar { background: oklch(0.95 0.06 85); color: oklch(0.42 0.09 70); }
.pc-aviso-rojo { background: oklch(0.95 0.04 25); color: var(--danger); }
.pc-error { margin-top: 8px; font-size: 13px; color: var(--danger); }
/* Aviso del almacen del que entrega el domicilio elegido (#409): mismo ambar que
   el resto de los avisos que piden atencion sin bloquear. Nace oculto; el JS lo
   prende solo cuando el domicilio no entrega del almacen de producto terminado. */
.pc-dom-aviso { display: none; margin-top: 6px; font-size: 12.5px; padding: 8px 10px; border-radius: 8px; line-height: 1.4; background: oklch(0.95 0.06 85); color: oklch(0.42 0.09 70); }
/* Domicilio unico del Cliente Operam, en solo lectura donde iria el selector (#424) */
.pc-dom-unico { font-size: 13px; color: var(--text); padding: 8px 0; }
.pc-link { background: none; border: none; color: var(--primary-dark); font-weight: 600; cursor: pointer; text-decoration: underline; font-size: 12.5px; padding: 0; }

/* Tarjeta del cliente seleccionado */
.pc-cli-card { background: var(--white); border: 1.5px solid var(--border); border-radius: var(--radius); padding: 18px 16px; }
.pc-cli-nombre { font-size: 18px; font-weight: 700; line-height: 1.3; color: var(--text); }
.pc-cli-sub { font-size: 13px; color: var(--text-light); margin-top: 2px; }
.pc-cli-hint { font-size: 12.5px; color: var(--text-light); margin-top: 12px; line-height: 1.45; }
/* Cliente en moneda extranjera (#297): ocupa el lugar del CTA a Productos */
.pc-cli-bloqueo { margin-top: 16px; font-size: 12.5px; padding: 10px 12px; border-radius: 8px; line-height: 1.45; background: oklch(0.95 0.04 25); color: var(--danger); }
.pc-chips { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 14px; align-items: center; }
.pc-chip { display: inline-flex; align-items: center; gap: 5px; font-size: 12px; font-weight: 600; padding: 6px 11px; border-radius: 999px; min-height: 30px; }
.pc-chip.ok { background: oklch(0.94 0.04 150); color: oklch(0.32 0.08 150); }
.pc-chip.pend { background: oklch(0.94 0.01 85); color: var(--text-light); }
.pc-chip.parcial { background: oklch(0.94 0.06 80); color: oklch(0.4 0.1 70); }
.pc-chip-btn { background: none; border: none; padding: 0; cursor: pointer; font: inherit; display: inline-flex; }

/* Ficha del Contacto (#346): sus Oportunidades y sus Clientes Operam */
.pc-ficha-seccion { margin-top: 16px; padding-top: 12px; border-top: 1px solid var(--border); }
.pc-ficha-item { display: flex; gap: 10px; align-items: flex-start; padding: 8px 0; }
.pc-ficha-item + .pc-ficha-item { border-top: 1px solid oklch(0.94 0.005 262); }
.pc-chip-btn .pc-chip.pend { border: 1px dashed oklch(0.82 0.03 262); }
.pc-dom { margin-top: 14px; }

/* Bloque de domicilio de entrega en el paso Envio (#84; antes revelado inline
   bajo la tarjeta del paso Cliente, #82) */
.pc-entrega-inline { margin-top: 16px; margin-bottom: 16px; padding: 16px; border: 1.5px solid var(--border); border-radius: var(--radius); background: var(--white); }

/* === BANDEJA DE REVISION "Rescatados de Operam" (issue #122) ===
   Vista fuera de las 7 columnas del pipeline. Reusa cot-card / cot-badge /
   alert / empty-state; lo propio es la barra de filtros, la rejilla de datos del
   quote y los badges de tipo y de marcas. */
.bandeja-toolbar { display: flex; justify-content: space-between; align-items: center; gap: 8px; margin-bottom: 12px; flex-wrap: wrap; }
.bandeja-filtros { display: inline-flex; gap: 4px; flex-wrap: wrap; }
.bandeja-card-descartada { opacity: 0.55; }
.bandeja-card-aceptada { border-color: oklch(0.9 0.07 150); }
.bandeja-marcas { margin-top: 2px; }
.badge-compro-otra { background: oklch(0.89 0.06 310); color: oklch(0.34 0.1 310); }
.badge-dup { background: oklch(0.89 0.1 80); color: oklch(0.36 0.08 70); }
.badge-sin-cel { background: oklch(0.88 0.012 80); color: oklch(0.4 0.015 75); }
.badge-tipo-prospecto { background: oklch(0.86 0.08 195); color: oklch(0.3 0.06 200); }
.badge-tipo-cotizacion { background: var(--primary-light); color: var(--primary-dark); }
.bandeja-datos { display: grid; grid-template-columns: 1fr 1fr; gap: 2px 16px; margin-top: 6px; font-size: 12px; }
.bandeja-dato { overflow-wrap: anywhere; }
.bandeja-dato b { font-weight: 600; color: var(--text-light); font-size: 11px; text-transform: uppercase; letter-spacing: 0.03em; margin-right: 6px; }
.bandeja-dato-vacio { color: var(--text-light); }
.bandeja-vendedor-wrap { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; }
.bandeja-vendedor-wrap label { font-size: 11px; font-weight: 700; color: var(--text-light); text-transform: uppercase; }
#bandeja-view .cot-card-actions { align-items: center; }

/* En telefono los datos del quote van en una sola columna (la app no scrollea
   horizontal en ningun ancho). */
@media (max-width: 480px) {
  .bandeja-datos { grid-template-columns: 1fr; }
}

/* Calcas en el paso Productos (issue #91). El codigo resuelto por tamano x
   tintas se muestra con su precio del tier vigente; sin precio (tier Menudeo)
   la ficha se pinta en rojo, porque la calca no se vende por debajo de 100
   piezas de producto y un precio en blanco seria un $0 disfrazado. */
.calca-resuelto {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  background: var(--primary-light);
  border-radius: 8px;
  padding: 8px 12px;
  font-size: 12.5px;
  margin-bottom: 10px;
}
.calca-resuelto-sku {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-weight: 700;
  color: var(--primary-dark);
}
.calca-resuelto-precio { font-weight: 700; font-variant-numeric: tabular-nums; }
.calca-resuelto.sin-precio { background: oklch(0.95 0.04 25); }
.calca-resuelto.sin-precio .calca-resuelto-sku,
.calca-resuelto.sin-precio .calca-resuelto-precio { color: var(--danger); }

/* Relacion calca/producto en la linea del carrito ("200 de 600 piezas"): se
   muestra siempre y no se juzga -- el pedido mixto y la doble calca sobre la
   misma pieza son ambos legitimos. */
.calca-relacion {
  color: var(--accent);
  font-size: 11px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* Linea del carrito sin precio en el tier vigente (calca bajo el umbral de 100
   piezas, #91): se marca en rojo porque el carrito esta en estado invalido y no
   puede generar documento hasta resolverse. */
.cart-line-sin-precio .cart-line-price,
.cart-line-sin-precio .cart-line-total { color: var(--danger); font-weight: 600; }

/* Captura del telefono del cliente (#418): hermano de #pc-root, bajo la tarjeta */
.pc-tel-captura { margin-top: 12px; padding: 14px 16px; background: var(--white); border: 1.5px dashed oklch(0.82 0.03 262); border-radius: var(--radius); }
.pc-tel-captura .form-group { margin-bottom: 0; }
.pc-tel-captura-hint { display: block; margin-top: 6px; font-size: 12.5px; color: var(--text-light); }
