/* ============================================================
   Capa 3 de 4: COMPONENTES (tokens.css -> base.css -> componentes.css -> utilidades.css)
   Todo lo que se repetia en las vistas vive UNA sola vez aca:
   layout del shell viejo, cards, campos, botones, pills, kpis y los bloques
   propios de cada vista. Las vistas usan estas clases; casi no ponen estilos inline.
   Era base.css (i144 lo partio en capas sin cambiar ningun selector: el reset
   paso a base.css y las utilidades sueltas a utilidades.css).
   ============================================================ */

/* ---------- layout del shell ---------- */
.ob-app  { display: flex; height: 100vh; }
.ob-main { flex: 1; display: flex; flex-direction: column; min-width: 0; }

.ob-topbar {
  height: 60px; flex: 0 0 60px;
  background: var(--ob-surface);
  border-bottom: 1px solid var(--ob-border);
  display: flex; align-items: center; gap: 14px; padding: 0 22px;
}
.ob-topbar__title {
  font-family: var(--ob-font-head); font-weight: 800; font-size: 15px; color: var(--ob-ink);
}
.ob-topbar__sub { font-size: 12.5px; color: var(--ob-muted); }

/* Titulo contextual: con el menu completo (>=861 px, item activo visible), el menu
   ya dice en que pantalla se esta; el titulo de la topbar se muestra solo cuando el
   menu no puede orientar: riel de iconos, menu oculto, o pantalla angosta. */
@media (min-width: 861px) {
  .ob-app:not(.ob-app--riel):not(.ob-app--oculto) .ob-topbar__title,
  .ob-app:not(.ob-app--riel):not(.ob-app--oculto) .ob-topbar__sub { display: none; }
}

/* Boton "≡" del menu lateral (js/menuLateral.js): arriba de 860 px alterna menu completo / riel de iconos / oculto; bajo 860 px, donde el
   menu ya es un riel que igual ocupa lugar, lo abre y lo cierra. Siempre a la vista: un menu oculto se puede volver a mostrar. */
.ob-navtoggle {
  display: inline-flex; flex: none; align-items: center; justify-content: center; min-width: 36px; min-height: 36px;
  border: 0; border-radius: var(--ob-r-field); background: transparent;
  font-size: 22px; line-height: 1; color: var(--ob-ink); cursor: pointer;
}
.ob-navtoggle:hover { background: var(--ob-bg); }

.ob-view { flex: 1; overflow: auto; padding: 22px 24px 30px; }

/* Layout de dos columnas compartido por las vistas (una sola fuente de verdad).
   Cap + centrado en pantallas anchas; las columnas apilan en angostas. */
.ob-split { display:flex; gap:20px; flex-wrap:wrap; align-items:flex-start; max-width:1120px; margin:0 auto; }
.ob-split__main { flex:1 1 520px; min-width:min(440px, 100%); }
.ob-split__aside { flex:1 1 340px; max-width:400px; min-width:min(300px, 100%); }
.ob-kpis { display:grid; grid-template-columns:repeat(auto-fit, minmax(140px, 1fr)); gap:10px; }

/* Variante SIN cap de 1120px: para el Panel del dueño, la unica vista de
   lectura pura (sin formularios angostos que necesiten mantenerse legibles).
   No se toca `.ob-split` para no afectar las otras 10 vistas que la usan. */
.ob-split--ancho { max-width: none; }
/* Variante de `.ob-kpis` para el Panel: grilla de columnas FIJAS (no
   auto-fit) para que los 4 KPI de plata nunca dejen una fila a medias.
   auto-fit con minmax cortaba la grilla apenas dejaba de entrar una
   columna mas -a 1920px armaba 2 columnas de ~280px y dejaba la mitad
   derecha vacia-. 1 columna en telefono, 2x2 en tablet/1366 chico, las
   4 en una fila desde ~1100px (ahi entran comodas sin achicarse). */
.ob-kpis--panel { grid-template-columns: repeat(1, 1fr); }
@media (min-width: 560px) { .ob-kpis--panel { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1100px) { .ob-kpis--panel { grid-template-columns: repeat(4, 1fr); } }

/* ---------- sidebar ---------- */
.ob-side {
  width: 220px; flex: 0 0 220px;
  background: var(--ob-navy-deep); color: #fff;
  display: flex; flex-direction: column; padding: 16px 12px;
}
/* La marca ES el acceso al catalogo: fija arriba, resaltada en celeste (la base
   de todas las operaciones). La barra naranja se enciende cuando estas adentro. */
.ob-brand {
  display: flex; align-items: center; gap: 10px;
  padding: 8px; margin-bottom: 12px; border-radius: 10px;
  background: var(--ob-celeste-marca); color: var(--ob-navy);
  text-decoration: none; cursor: pointer;
}
.ob-brand:hover { background: var(--ob-celeste-hover); }
.ob-brand.on { box-shadow: inset 3px 0 0 var(--ob-orange); }
.ob-brand__logo {
  width: 34px; height: 34px; border-radius: 9px; background: #EAF3FF; color: var(--ob-navy);
  display: flex; align-items: center; justify-content: center;
}
.ob-brand__logo svg { width: 18px; height: 18px; }
.ob-brand__name  { font-family: var(--ob-font-head); font-weight: 700; font-size: 14px; line-height: 1.15; color: var(--ob-navy); }
.ob-brand__name b { color: #3A5390; font-weight: 700; }

.ob-navitem {
  display: flex; align-items: center; gap: 11px;
  padding: 10px 11px; border-radius: 9px;
  color: var(--ob-side-ink);
  font-family: var(--ob-font-head); font-weight: 700; font-size: 13px;
  cursor: pointer; text-decoration: none; user-select: none;
}
.ob-navitem:hover { background: rgba(255,255,255,.06); }
.ob-navitem.on {
  background: var(--ob-navy-active); color: #fff;
  box-shadow: inset 3px 0 0 var(--ob-orange);
}
/* Los iconos del nav son SVG (icons.js), no emoji: el span es solo contenedor
   y el tamano lo lleva el dibujo (.ob-navitem__ico svg, mas abajo en la base).
   Por eso ya no hay font-size aca: en el riel de iconos el SVG seguia visible
   cuando el label colapsaba a font-size:0, pero el emoji dependia de esta
   regla para no desaparecer junto con el texto. */
.ob-navitem__ico { display: inline-flex; align-items: center; flex: none; }
.ob-navitem__ico svg { width: 17px; height: 17px; display: block; }

/* Rotulo de grupo del nav (fase del negocio): titulo chico no clickeable. */
.ob-side__grupo {
  margin: 14px 11px 4px;
  font-family: var(--ob-font-head); font-weight: 700; font-size: 11.5px;
  letter-spacing: .04em; text-transform: uppercase;
  color: rgba(207, 224, 240, .55);
  user-select: none;
}
.ob-side__grupo:first-child { margin-top: 2px; }

/* Configuracion: el unico bloque plegable (se toca una vez por mes). El
   rotulo es un boton con el mismo aspecto de un item de nav; el chevron
   gira segun el estado y las vistas de adentro van corridas a la derecha,
   anidadas bajo su rotulo. */
.ob-navitem--cfg {
  width: 100%; margin-top: 14px;
  background: none; border: 0; text-align: left;
  font: inherit; color: inherit; cursor: pointer;
}
.ob-navitem--cfg .ob-navitem__chev { margin-left: auto; opacity: .7; display: inline-flex; }
.ob-navitem--cfg .ob-navitem__chev svg { width: 14px; height: 14px; display: block; transition: transform .15s; }
.ob-navitem--cfg[aria-expanded="true"] .ob-navitem__chev svg { transform: rotate(180deg); }
.ob-side__cfg { margin-bottom: 2px; }
.ob-side__cfg .ob-navitem { padding-left: 40px; font-weight: 600; font-size: 12.5px; }

/* ---------- card ---------- */
.ob-card {
  background: var(--ob-surface);
  border: 1px solid var(--ob-border);
  border-radius: var(--ob-r-card);
  overflow: hidden;
}
.ob-card__head {
  display: flex; align-items: center; gap: 10px;
  padding: 12px 16px; border-bottom: 1px solid var(--ob-border);
}
.ob-card__pad { padding: 16px; }

.ob-h2 { font-family: var(--ob-font-head); font-weight: 800; font-size: 14px; color: var(--ob-ink); margin: 0; }

/* ---------- linea de tiempo de despacho (tarjeta de Logistica) ----------
   5 puntos (Entro/Armado/Salio/En transito/Entregado) conectados por una
   linea; el punto define su propio color con un modificador de estado.
   Los datos salen de colaLogistica.js/lineaDeTiempo() (puro, testeado);
   esta clase solo pinta lo que esa funcion ya decidio. Regla del Naranja
   Escaso: el naranja SOLO tinta el punto "actual", nunca dos veces en la
   misma tarjeta. "vencido" (PR3, design/logistica-en-transito) es la
   EXCEPCION deliberada: el punto "En tránsito" pasado de plazo (solo
   envio/encomienda, nunca un retiro) se pinta en rojo con el MISMO halo que
   "actual" usa en naranja -mismo tecnica, otro color de alerta, porque acá
   la alerta manda sobre "es el paso actual"-. */
.ob-tl { display: grid; grid-template-columns: repeat(5, 1fr); gap: 0; margin: 10px 0 2px; position: relative; }
.ob-tl::before { content: ''; position: absolute; left: 10%; right: 10%; top: 7px; height: 2px; background: var(--ob-border-2); }
.ob-tl__punto { position: relative; text-align: center; padding-top: 20px; }
.ob-tl__punto::before {
  content: ''; position: absolute; left: 50%; top: 0; width: 14px; height: 14px;
  margin-left: -7px; border-radius: 50%; background: #fff; border: 2px solid var(--ob-border-2);
}
.ob-tl__punto--hecho::before { background: var(--ob-navy); border-color: var(--ob-navy); }
.ob-tl__punto--actual::before { background: var(--ob-orange); border-color: var(--ob-orange); box-shadow: 0 0 0 4px var(--ob-warn-bg); }
.ob-tl__punto--vencido::before { background: var(--ob-danger-dot); border-color: var(--ob-danger-dot); box-shadow: 0 0 0 4px var(--ob-danger-bg); }
.ob-tl__etiqueta { font-family: var(--ob-font-head); font-weight: 700; font-size: 10.5px; letter-spacing: .04em; text-transform: uppercase; color: var(--ob-muted); }
.ob-tl__punto--hecho .ob-tl__etiqueta, .ob-tl__punto--actual .ob-tl__etiqueta, .ob-tl__punto--vencido .ob-tl__etiqueta { color: var(--ob-ink); }
.ob-tl__hora { font-size: 11.5px; color: var(--ob-muted); margin-top: 1px; }
.ob-tl__punto--hecho .ob-tl__hora { color: var(--ob-ink); }
.ob-tl__punto--actual .ob-tl__hora { color: var(--ob-warn); font-weight: 700; }
.ob-tl__punto--vencido .ob-tl__hora { color: var(--ob-danger); font-weight: 700; }
/* --ob-muted (no --ob-muted-2): el detalle es DATO -quien armo/saco el
   pedido y cuanto tardo-, no una pista decorativa. --ob-muted-2 es "para
   pistas y decoracion" por la Regla del Gris que se Lee (DESIGN.md). */
.ob-tl__detalle { font-size: 11px; color: var(--ob-muted); }
@media (max-width: 640px) {
  /* Dos lineas fijas (line-height×2) para las 5 columnas, aunque solo "EN
     TRÁNSITO" las use: sin el piso, esa etiqueta sola envolvia a la
     segunda linea y le corria el punto/hora hacia abajo respecto de sus
     vecinas de una sola linea -las 5 dejaban de alinear a la misma
     altura-. No se acorta la etiqueta: se le da lugar. */
  /* 11 px es el piso. En mayusculas "ENTREGADO" no entra en una columna de ~55 px
     y se partia a mitad de palabra: con la capitalizacion normal entra entera. */
  .ob-tl__etiqueta { font-size: 11px; line-height: 1.25; min-height: 2.5em; letter-spacing: 0; text-transform: none; }
  .ob-tl__hora { font-size: 11px; }
  /* Fecha y hora en renglones propios: juntas en una sola linea
     ("sáb 26/9 · 11:55") no entraban en los ~42px de columna y el texto
     envolvia a mitad de la fecha o de la hora -dos puntos vecinos se
     leian entreverados-. El separador "·" solo tiene sentido en una
     linea, asi que desaparece; cada parte queda de un solo renglon
     (white-space: nowrap) para que "sáb 26/9" no se corte a la mitad. */
  .ob-tl__sep { display: none; }
  .ob-tl__fecha, .ob-tl__hh { display: block; white-space: nowrap; }
  .ob-tl__detalle { display: none; }
}

/* ---------- campo de formulario ---------- */
.ob-field {
  width: 100%; font-size: 13px; color: var(--ob-ink);
  border: 1px solid var(--ob-border-2); border-radius: var(--ob-r-field);
  padding: 9px 11px; background: #fff; outline: none;
}
.ob-field:focus { border-color: var(--ob-navy); }

.ob-label {
  display: block; font-size: 11.5px; font-weight: 700; color: var(--ob-muted);
  font-family: var(--ob-font-head); text-transform: uppercase; letter-spacing: .04em;
  margin: 12px 0 4px;
}
.ob-label--req { color: var(--ob-warn); }
/* "Obligatorio" con palabras, no solo con color: un lector de pantalla no ve
   el naranja, y el que no distingue colores tampoco. */
.ob-label--req::after { content: " (obligatorio)"; font-weight: 400; text-transform: none; letter-spacing: 0; opacity: .8; }

/* Chip de DESTINO de un campo de la ficha de producto (Tienda / Ficha / Interno).
   Sale del contrato de campos (core/fichaCampos.js via /api/products/contrato):
   dice a donde termina el dato que se carga, para que nadie llene un campo que
   no llega a ningun lado. Va dentro del <label>, a la derecha del nombre. */
.ob-chipdest {
  display: inline-block; margin-left: 5px; padding: 1px 6px; border-radius: var(--ob-r-pill);
  font-size: 9.5px; font-weight: 700; letter-spacing: .03em; text-transform: uppercase; line-height: 1.5;
  border: 1px solid var(--ob-border-2); color: var(--ob-muted); background: var(--ob-surface);
  vertical-align: middle;
}
.ob-chipdest--tienda { color: var(--ob-navy); border-color: var(--ob-navy); }
.ob-chipdest--ficha  { color: var(--ob-verde-accion); border-color: var(--ob-verde-accion); }
/* --alta: entra en la descripcion que se genera al publicar por primera vez en la tienda (no viaja en el sync). */
.ob-chipdest--alta { color: var(--ob-navy); border-color: var(--ob-navy); border-style: dashed; }
.ob-chipdest--interno { color: var(--ob-muted-2); }
/* --imprime: el mismo chip de destino, para un campo que SI sale en un
   impreso (rotulo, remito, presupuesto) — el texto del chip dice cual. */
.ob-chipdest--imprime { color: var(--ob-info); border-color: var(--ob-info); }

/* Reparto de la ficha pegada (modal del Catalogo): marca un campo que se completo
   con un dato dudoso. Se va solo cuando la persona toca el campo. */
.ob-chiprevisar {
  display: inline-block; margin-left: 5px; padding: 1px 6px; border-radius: var(--ob-r-pill);
  font-size: 9.5px; font-weight: 700; letter-spacing: .03em; text-transform: uppercase; line-height: 1.5;
  color: var(--ob-warn); background: var(--ob-warn-bg); border: 1px solid var(--ob-warn-dot); vertical-align: middle;
}
.ob-field--revisar { outline: 2px solid var(--ob-warn-dot); outline-offset: 1px; border-radius: var(--ob-r-field); }

/* Texto de ayuda debajo de un campo: dice DONDE termina el dato (interna,
   remito, rotulo). No repite el nombre del campo, que ya dice el label. */
.ob-field-help {
  display: block; font-size: 11px; color: var(--ob-muted-2); line-height: 1.4;
  margin-top: 4px;
}

/* Grupo de campo que SI sale impreso afuera del local (rotulo/etiqueta del
   bulto): borde y tinte para que sea imposible confundirlo con un campo
   interno. Existe por un incidente real -un dato de facturacion salio
   impreso en la etiqueta pegada al bulto-, ver el comentario en
   views/remito.js donde se arma este campo. */
.ob-fieldgroup--imprime {
  border: 1px solid var(--ob-info-border); background: var(--ob-info-bg);
  border-radius: var(--ob-r-field); padding: 9px 11px 11px;
}
.ob-fieldgroup--imprime .ob-label { margin-top: 0; }
.ob-fieldgroup--imprime .ob-field { border-color: var(--ob-info-border); }

/* ---------- boton ----------
   Se usa indistintamente sobre <button> y sobre <div>. El <button> es el correcto:
   entra en el orden de tabulacion y se activa con Enter/Espacio sin codigo propio.
   Los <div class="ob-btn"> que quedan son legado a migrar vista por vista.

   JERARQUIA (fase 4 de la reestructura, 2026-10-21; i145, 2026-10-22): un solo
   sentido por variante. La regla de oro (d12): UN relleno por pantalla; en una
   lista, el relleno va en la fila activa. El resto baja de nivel.
     (sin variante) secundario: outline navy sobre blanco. Es el estado base:
                después de #318/#324 quedo sin borde y 31 botones ("Cancelar",
                "Simular", "Volver") se leian como texto suelto (i145, T1).
     --sec      alias del base (se conserva: lo usan las vistas)
     --primary  la accion principal de la pantalla (navy relleno, UNO por vista)
     --ok       confirmacion positiva: guardar/cobrar/verificar (verde)
     --peligro  destructivo (borrar, anular, rechazar): outline rojo, SIEMPRE con confirmar()
     --ghost    terciario: texto navy sin borde, solo "Ver mas" / "Ver historial"
     --tap      sube a 44 px donde se toca (mostrador); bajo 640 px ya es 44 para todos
   Alto: 37 px en escritorio (padding 10 + borde 1 + texto). El naranja NO es color
   de boton (d13, La Regla del Naranja en DESIGN.md). */
.ob-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  font-family: var(--ob-font-head); font-weight: 800; font-size: 12.5px;
  min-height: 37px; padding: 10px 14px; border-radius: var(--ob-r-field); cursor: pointer;
  text-align: center; user-select: none;
  /* default explicito: un <button> nativo trae el gris del SO */
  background: var(--ob-surface); color: var(--ob-navy); border: 1px solid var(--ob-field-border);
}
.ob-btn--primary { background: var(--ob-navy); color: #fff; border-color: var(--ob-navy); }
.ob-btn--ok      { background: var(--ob-verde-accion); color: #fff; border-color: var(--ob-verde-accion); }
.ob-btn--sec     { background: var(--ob-surface); border-color: var(--ob-field-border); color: var(--ob-navy); }
.ob-btn--peligro { background: var(--ob-surface); border-color: var(--ob-danger-border); color: var(--ob-danger); }
.ob-btn--ghost   { background: transparent; border-color: transparent; color: var(--ob-navy); padding-left: 6px; padding-right: 6px; }
.ob-btn--tap     { min-height: 44px; }
/* El secundario (base y --sec) y el peligroso reaccionan al hover: sin esto
   parecian disabled. :where() deja el hover sin peso para que no le gane al
   relleno de --primary/--ok. */
.ob-btn:where(:not(.ob-btn--primary, .ob-btn--ok, .ob-btn--peligro, .ob-btn--ghost)):hover { background: var(--ob-navy-tint); }
.ob-btn--peligro:hover { background: var(--ob-danger-bg); }
.ob-btn--ghost:hover   { text-decoration: underline; }
/* Familias legado (i145, T3), una por vista, a migrar en la PR de cada vista:
     .lgt-btn (Logistica, mas abajo), .ll-btn (Leads, mas abajo) y
     .pd-btn (Panel, CSS propio en views/panel.js): .pd-btn = .ob-btn, .pd-btn--pri = .ob-btn--primary. */

/* Atenuado, por las dos vias. `[disabled]` es el boton que el navegador ya
   bloquea; `aria-disabled` es el que sigue siendo clickeable pero no debe
   usarse todavia. Hasta ahora solo habia `opacity`, que un lector de pantalla
   no percibe: anunciaba "Presupuestar" igual con el carrito vacio que lleno. */
.ob-btn[disabled] { opacity: .5; cursor: default; }
.ob-btn[aria-disabled="true"],
button[aria-disabled="true"] { opacity: .45; cursor: not-allowed; }

/* Boton de icono: accion de fila (reabrir, imprimir, anular). Es un <button> con
   aria-label, no un <span> con onclick — si no, el teclado no lo alcanza. */
.ob-iconbtn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 28px; flex: none;
  border: 0; border-radius: 8px; background: transparent; cursor: pointer;
  font-size: 13px; line-height: 1; padding: 0;
}
.ob-iconbtn:hover { background: var(--ob-bg); }
/* 44px: variante para pantallas de mostrador (Venta). El base (28px) queda para
   listas densas (Vendedor); no se agranda desde aca para no romperlas. */
.ob-iconbtn--44 { width: 44px; height: 44px; font-size: 16px; }
.ob-iconbtn--peligro:hover { background: var(--ob-danger-bg); }

/* ---------- foco visible ----------
   El teclado tiene que poder recorrer la app: sin esto, quien no usa mouse
   (o quien tiene una mano ocupada con una caja) no ve nunca donde esta parado.
   :focus-visible y no :focus para que el anillo aparezca al tabular pero no
   al hacer click, que es lo que lo volvia ruido y llevaba a apagarlo.
   Va sobre cualquier interactivo, no solo .ob-btn: alcanza a los <button>
   sin clase, a los links y a lo que venga despues. */
:where(a, button, [role="button"], [tabindex]):focus-visible {
  outline: 2px solid var(--ob-navy);
  outline-offset: 2px;
  border-radius: var(--ob-r-field);
}
/* Los campos van aparte: el selector de arriba no alcanza a input/select/
   textarea, y sin esto tabular por un formulario deja de mostrar donde se esta. */
.ob-field:focus-visible, .ob-navitem:focus-visible {
  outline: 2px solid var(--ob-navy); outline-offset: 2px;
}
/* Sobre fondo navy el anillo navy no se ve: se invierte a blanco. */
.ob-side :where(a, button, [tabindex]):focus-visible { outline-color: #fff; }
/* En los botones de color el anillo blanco va ADENTRO del boton: afuera quedaba
   blanco sobre la pagina blanca y no se veia donde estaba el foco. */
.ob-btn--primary:focus-visible,
.ob-btn--ok:focus-visible { outline-color: #fff; outline-offset: -4px; }

/* ---------- Quote: el numero que se PRONUNCIA ----------
   DESIGN.md lo define como "el numero que se dice EN VOZ ALTA a un cliente que
   esta esperando". Vive aca y no inline para que la proxima vista que tenga que
   cantar una cifra no invente su propio tamano. */
.ob-quote {
  font-family: var(--ob-font-head); font-weight: 800; font-size: 32px;
  line-height: 1.05; letter-spacing: -.01em; color: var(--ob-navy);
  font-variant-numeric: tabular-nums; font-feature-settings: "tnum" 1;
}

/* ---------- chip de SKU (codigo destacado) ---------- */
.ob-sku {
  display: inline-block;
  font-family: var(--ob-font-head); font-weight: 800;
  font-size: 11.5px; letter-spacing: .02em;
  font-variant-numeric: tabular-nums; font-feature-settings: "tnum" 1;
  color: var(--ob-navy); background: var(--ob-sku-bg);
  border: 1px solid var(--ob-sku-border); border-radius: 6px;
  padding: 1px 6px; white-space: nowrap;
}

/* Variante grande: el SKU que se lee con la caja en la mano (ITEMS de Logistica). */
.ob-sku--lg { font-size: 13px; padding: 2px 8px; }

/* ---------- pill / badge de estado ---------- */
.ob-pill {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 11.5px; font-family: var(--ob-font-head); font-weight: 700;
  padding: 3px 9px; border-radius: var(--ob-r-pill);
}
.ob-pill__dot { width: 6px; height: 6px; border-radius: 50%; }

/* ---------- kpi ---------- */
.ob-kpi {
  background: var(--ob-surface); border: 1px solid var(--ob-border);
  border-radius: 12px; padding: 13px 15px;
}
.ob-kpi__label {
  font-size: 11.5px; font-weight: 700; color: var(--ob-muted);
  font-family: var(--ob-font-head); text-transform: uppercase; letter-spacing: .05em;
}
.ob-kpi__value { font-family: var(--ob-font-head); font-weight: 800; font-size: 22px; margin-top: 5px; }

/* ---------- total: EL NUMERO QUE CIERRA UNA OPERACION ----------
   Componente unico para el total de una venta o un remito, en vez de que
   cada pantalla lo reescale con un override inline (pasaba en Venta: 20px
   en la fila de resumen contra 32px en "A cobrar"; en Remito: 22px propio
   sin usar ningun token). Peso de referencia: el que ya usaba Venta en
   "A cobrar" (antes `.ob-quote`, 32/800) — es el mismo momento que Remito
   resuelve con su Total, asi que comparten el mismo peso visual. `.ob-quote`
   sigue existiendo aparte para la cifra que se PRONUNCIA en voz alta
   (hoy, el envio cotizado): mismo tamano, distinto significado — un total
   se lee, un quote se dice. */
.ob-total {
  font-family: var(--ob-font-head); font-weight: 800; font-size: 32px;
  line-height: 1.05; letter-spacing: -.01em; color: var(--ob-navy);
  font-variant-numeric: tabular-nums; font-feature-settings: "tnum" 1;
}
/* Panel: los 4 KPI de plata cierran una LECTURA de tablero, no una venta —
   se quedan en el tamano de Display (22px, el que .ob-kpi__value ya define)
   en vez de heredar el 32px de arriba. */
.ob-total--kpi {
  font-size: 22px; line-height: inherit; letter-spacing: normal; color: inherit;
}

/* ---------- tile (Panel: fila fusionada "Hoy" + "Despacho") ----------
   Card chica de una sola cifra con acento de color en el borde izquierdo
   (semaforo como ACENTO, no como relleno completo — la caja se queda
   blanca). Reemplaza las dos implementaciones locales que tenia panel.js
   (tileHoy con fondo blanco y el fill completo de los tiles de despacho). */
/* Grilla de columnas FIJAS (no flex-wrap): con flex, 8 tiles de ancho
   variable armaban filas dispares segun donde cortaba el viewport (5+3 a
   1366px, con "Pasados de 48 h" solo en la fila 1). 4 columnas -> SIEMPRE
   2 filas parejas (fila 1: Hoy, fila 2: Despacho); 2 columnas debajo de
   ~900px -> 4 filas de a 2, nunca un tile solo. */
.ob-tilerow { display:grid; grid-template-columns: repeat(2, 1fr); gap:12px; padding:14px 16px; }
@media (min-width: 900px) { .ob-tilerow { grid-template-columns: repeat(4, 1fr); } }
.ob-tile {
  min-width:0; text-align:left;
  background:#fff; border:1px solid var(--ob-border-2);
  border-left:3px solid var(--ob-border-2); border-radius:12px; padding:10px 14px;
}
/* Era var(--ob-tile-color, var(--ob-navy)) y nadie declaraba --ob-tile-color:
   siempre caia al navy (lint-ui, i182). */
.ob-tile.is-active { border-left-color: var(--ob-navy); }
button.ob-tile { cursor:pointer; font:inherit; }
.ob-tile__label {
  font-family: var(--ob-font-head); font-weight:700; font-size:10px;
  letter-spacing:.09em; text-transform:uppercase; color:var(--ob-muted);
}
.ob-tile__value { font-family: var(--ob-font-head); font-weight:800; font-size:23px; margin-top:2px; }
.ob-tile__detail { font-size:11px; color:var(--ob-muted-2); margin-top:2px; }

/* ---------- badge de conexion API (topbar) ---------- */
.ob-apibadge {
  margin-left: auto; min-width: 0; font-size: 11.5px; line-height: 1.25;
  font-family: var(--ob-font-head); font-weight: 700;
  padding: 5px 11px; border-radius: 10px;
  background: var(--ob-bg); color: var(--ob-muted);
}
.ob-apibadge[hidden] { display: none; }
/* Conectada: silenciosa. Solo una luz verde de 10px, sin texto ni pastilla. */
.ob-apibadge.is-ok {
  display: block; flex: 0 0 10px; width: 10px; height: 10px; padding: 0;
  border-radius: 50%; background: var(--ob-ok-dot);
}
.ob-apibadge.is-demo { background: var(--ob-warn-bg); color: var(--ob-warn); }
/* En celular el aviso de falla no cabe al lado del titulo: la barra se parte en
   dos renglones y el aviso ocupa el segundo, completo. */
@media (max-width: 640px) {
  .ob-topbar { flex-wrap: wrap; }
  .ob-topbar:has(.ob-apibadge.is-demo) { height: auto; flex: 0 0 auto; padding-top: 8px; padding-bottom: 8px; row-gap: 6px; }
  .ob-apibadge.is-demo { flex: 1 1 100%; margin-left: 0; }
}

/* ---------- boton Buscar de la topbar (i147) ---------- */
.ob-topbar__buscar {
  margin-left: auto;
  display: inline-flex; align-items: center; gap: 8px;
  min-height: 40px; padding: 0 12px;
  border: 1px solid var(--ob-field-border); border-radius: 10px;
  background: var(--ob-surface); color: var(--ob-navy);
  font-family: var(--ob-font-head); font-weight: 700; font-size: 12.5px;
  cursor: pointer; white-space: nowrap;
}
.ob-topbar__buscar:hover { background: var(--ob-navy-tint); }
.ob-topbar__buscar > svg { width: 15px; height: 15px; }
.ob-topbar__buscar-kbd {
  font-family: var(--ob-font-head); font-size: 11px; font-weight: 700;
  color: var(--ob-muted); background: var(--ob-bg);
  border: 1px solid var(--ob-border-2); border-radius: 6px; padding: 2px 6px;
}
/* El boton toma el margen auto que tenia el badge: el badge le cede el lugar. */
.ob-topbar__buscar ~ .ob-apibadge { margin-left: 0; }

/* ---------- paleta de busqueda global (i147) ---------- */
.ob-buscador {
  position: fixed; inset: 0; z-index: 80;
  background: var(--ob-scrim);
  display: flex; align-items: flex-start; justify-content: center;
  padding: 11vh 16px 16px;
}
.ob-buscador[hidden] { display: none; }
.ob-buscador__panel {
  width: min(620px, 100%);
  background: var(--ob-surface); border-radius: var(--ob-r-card);
  box-shadow: var(--ob-shadow); overflow: hidden;
  display: flex; flex-direction: column; max-height: min(72vh, 640px);
}
.ob-buscador__caja {
  display: flex; align-items: center; gap: 10px;
  padding: 12px 14px; border-bottom: 1px solid var(--ob-border);
}
.ob-buscador__ico { display: inline-flex; color: var(--ob-muted); }
.ob-buscador__ico svg { width: 17px; height: 17px; }
.ob-buscador__input {
  flex: 1; min-width: 0; border: 0; outline: none; background: transparent;
  font-family: var(--ob-font); font-weight: 600; font-size: 15px; color: var(--ob-ink);
}
.ob-buscador__input::placeholder { color: var(--ob-muted-2); }
.ob-buscador__kbd {
  font-family: var(--ob-font-head); font-size: 11px; font-weight: 700;
  color: var(--ob-muted-2); background: var(--ob-bg);
  border: 1px solid var(--ob-border-2); border-radius: 6px; padding: 2px 6px;
}
.ob-buscador__res { overflow: auto; padding: 8px; }
.ob-buscador__grupo-titulo {
  display: flex; align-items: baseline; gap: 8px;
  font-family: var(--ob-font-head); font-weight: 800; font-size: 11px;
  letter-spacing: .5px; text-transform: uppercase; color: var(--ob-muted);
  padding: 10px 8px 4px;
}
.ob-buscador__mas { font-size: 11px; font-weight: 600; letter-spacing: 0; text-transform: none; color: var(--ob-muted-2); }
.ob-buscador__item {
  display: flex; flex-direction: column; align-items: flex-start; gap: 1px;
  width: 100%; text-align: left; cursor: pointer; font: inherit;
  padding: 9px 10px; border: 0; border-radius: 9px; background: transparent;
}
.ob-buscador__item-titulo { font-family: var(--ob-font-head); font-weight: 700; font-size: 13.5px; color: var(--ob-ink); }
.ob-buscador__item-detalle { font-size: 12px; color: var(--ob-muted); }
.ob-buscador__item:hover { background: var(--ob-bg); }
.ob-buscador__item--activa, .ob-buscador__item--activa:hover { background: var(--ob-navy-tint); box-shadow: inset 3px 0 0 var(--ob-orange); }
.ob-buscador__estado { padding: 22px 16px; text-align: center; }
.ob-buscador__estado-titulo { font-family: var(--ob-font-head); font-weight: 800; font-size: 14px; color: var(--ob-ink); }
.ob-buscador__estado-sub { font-size: 12.5px; color: var(--ob-muted); margin-top: 5px; }
.ob-buscador__crear { margin-top: 12px; }
.ob-buscador__pie-error { padding: 8px 10px 4px; font-size: 11.5px; color: var(--ob-muted-2); }
/* Celular: la paleta va a pantalla completa (criterio de aceptacion i147) y
   el boton de la topbar queda de solo icono: no hay lugar para texto + kbd. */
@media (max-width: 560px) {
  .ob-buscador { padding: 0; }
  .ob-buscador__panel { width: 100%; min-height: 100dvh; max-height: none; border-radius: 0; }
  .ob-topbar__buscar-txt, .ob-topbar__buscar-kbd { display: none; }
  .ob-topbar__buscar { min-width: 40px; justify-content: center; padding: 0 10px; }
}


/* ---------- spinner ---------- */
.ob-spin {
  width: 24px; height: 24px; border: 3px solid var(--ob-border-2);
  border-top-color: var(--ob-navy); border-radius: 50%; animation: ob-sp .7s linear infinite;
}
@keyframes ob-sp { to { transform: rotate(360deg); } }
/* El giro es puramente decorativo (el texto de al lado ya dice que carga):
   quien pide menos movimiento se queda con el anillo quieto, no con una
   animacion mas lenta. */
@media (prefers-reduced-motion: reduce) { .ob-spin { animation: none; } }

/* ---------- login ---------- */
.ob-login {
  position: fixed; inset: 0; z-index: 100;
  background: linear-gradient(120deg, var(--ob-navy-active), var(--ob-navy-deep));
  display: flex; align-items: center; justify-content: center; padding: 20px;
}
.ob-login__card {
  background: #fff; border-radius: 16px; padding: 34px 30px; width: 340px; max-width: 100%;
  box-shadow: 0 20px 60px rgba(0,0,0,.3); text-align: center;
}
.ob-login__logo {
  width: 58px; height: 58px; border-radius: 14px; background: var(--ob-navy); color: #fff;
  display: flex; align-items: center; justify-content: center;
  font-family: var(--ob-font-head); font-weight: 800; font-size: 24px; margin: 0 auto 14px;
}
.ob-login__title { font-family: var(--ob-font-head); font-weight: 800; font-size: 18px; color: var(--ob-navy); margin: 0 0 2px; }
.ob-login__sub { font-size: 12px; color: var(--ob-muted); margin: 0 0 18px; }
.ob-login__err { color: var(--ob-danger); font-size: 12px; font-weight: 700; min-height: 16px; margin-top: 8px; }

/* ---------- pie del sidebar (rol + salir) ---------- */
.ob-side__foot { margin-top: auto; padding-top: 12px; border-top: 1px solid rgba(255,255,255,.1); }
.ob-side__role {
  font-size: 11.5px; font-family: var(--ob-font-head); font-weight: 700; text-transform: uppercase;
  letter-spacing: .04em; color: #8FB4DA; padding: 4px 11px;
}
.ob-side__logout {
  display: block; padding: 8px 11px; border-radius: 9px; cursor: pointer;
  font-family: var(--ob-font-head); font-weight: 700; font-size: 12px; color: var(--ob-side-ink);
}
.ob-side__logout:hover { background: rgba(255,255,255,.08); }

/* ---------- picker de clientes (libreta) ---------- */
.ob-cli-row:hover { background: var(--ob-navy-tint); }

/* ---------- "Mas info" plegable (Verificacion: Referencia, bancos, notas...) ----------
   <details> nativo: gratis con teclado (Enter/Espacio en el <summary> lo abre)
   y sin JS propio. El summary es el toque, asi que no puede bajar de 44px. */
.ob-mas { border-top: 1px solid var(--ob-border); margin-top: 10px; }
.ob-mas > summary {
  list-style: none; cursor: pointer; user-select: none;
  display: flex; align-items: center; justify-content: space-between;
  min-height: 44px; padding: 4px 2px;
  font-family: var(--ob-font-head); font-weight: 700; font-size: 12.5px; color: var(--ob-link);
}
.ob-mas > summary::-webkit-details-marker { display: none; }
.ob-mas > summary::after { content: '▾'; color: var(--ob-muted); transition: transform .15s ease; }
.ob-mas[open] > summary::after { transform: rotate(180deg); }
.ob-mas__body { padding-bottom: 6px; }

/* ---------- "Datos para facturar" (datosFacturar.js: Verificacion + Cobros) ----------
   Un solo bloque para las dos pantallas. Jerarquia: el DNI/CUIT es EL dato que
   se tipea en la factura, por eso encabeza y es el unico en Display chico; el
   resto son filas etiqueta/valor. Los productos van en filas (no en tabla):
   el nombre largo necesita el ancho entero, en el celular y en el panel de
   400px de Cobros por igual. */
.df { display: flex; flex-direction: column; gap: 14px; padding: 2px 0 4px; }
.df-sec__t {
  font-family: var(--ob-font-head); font-weight: 700; font-size: 11.5px;
  color: var(--ob-muted); text-transform: uppercase; letter-spacing: .04em; margin: 0 0 4px;
}
.df-fila {
  display: flex; justify-content: space-between; align-items: baseline; gap: 12px;
  font-size: 13px; padding: 4px 0;
}
.df-fila + .df-fila { border-top: 1px solid var(--ob-border); }
.df-fila__k { color: var(--ob-muted); flex: 0 0 auto; }
.df-fila__v {
  color: var(--ob-ink); font-weight: 600; text-align: right;
  min-width: 0; overflow-wrap: anywhere;
}
.df-fila__v--copia { display: flex; align-items: center; justify-content: flex-end; gap: 8px; }
.df-fila__v--copia .df-copy { flex: none; margin-left: 0; }
.df-fila--apilada { flex-wrap: wrap; }
.df-fila--apilada .df-fila__v { flex: 1 1 100%; justify-content: space-between; }
.df-fila--apilada .df-fila__v .ob-num { white-space: nowrap; }
.df-fila__v a { color: var(--ob-link); font-weight: 700; text-decoration: none; }
.df-fila__v a:hover { text-decoration: underline; }

/* El dato para facturar: DNI/CUIT grande + condicion fiscal + copiar. */
.df-id {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  background: var(--ob-navy-tint); border: 1px solid var(--ob-border-2);
  border-radius: var(--ob-r-field); padding: 10px 12px;
}
.df-id__lbl { width: 100%; font-family: var(--ob-font-head); font-weight: 700; font-size: 11.5px; color: var(--ob-muted); text-transform: uppercase; letter-spacing: .04em; }
.df-id__num { font-family: var(--ob-font-head); font-weight: 800; font-size: 18px; color: var(--ob-navy); letter-spacing: .01em; }
.df-id__num { flex: 1 1 auto; min-width: 0; overflow-wrap: anywhere; }
.df-id__fiscal { width: 100%; font-size: 12px; font-weight: 600; color: var(--ob-navy-ink-2); }
.df-id__falta { width: 100%; font-size: 12.5px; color: var(--ob-warn); font-weight: 600; }
.df-id .df-copy { flex: none; margin-left: 0; }

/* Copiar: boton de verdad (con foco y nombre), no un emoji suelto. */
.df-copy {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 32px; min-width: 64px; padding: 0 10px; margin-left: 8px;
  font-family: var(--ob-font-head); font-weight: 700; font-size: 11.5px;
  color: var(--ob-navy); background: var(--ob-surface);
  border: 1px solid var(--ob-field-border); border-radius: var(--ob-r-field); cursor: pointer;
}
.df-copy:hover { background: var(--ob-navy-tint); }
.df-copy[data-hecho] { color: var(--ob-ok); border-color: var(--ob-ok-border); background: var(--ob-ok-tint); }

/* Productos: SKU + nombre arriba, "cant x precio" y subtotal abajo. */
.df-items { border: 1px solid var(--ob-border); border-radius: var(--ob-r-field); overflow: hidden; }
.df-item { padding: 8px 10px; }
.df-item + .df-item { border-top: 1px solid var(--ob-border); }
.df-item__top { display: flex; gap: 8px; align-items: baseline; }
.df-item__desc { font-size: 13px; color: var(--ob-ink); line-height: 1.35; }
.df-item__bot { display: flex; justify-content: space-between; margin-top: 3px; font-size: 12px; color: var(--ob-muted); }
.df-item__sub { color: var(--ob-ink); font-weight: 700; }
.df-items__total {
  display: flex; justify-content: space-between; align-items: baseline;
  padding: 8px 10px; background: var(--ob-surface-2); border-top: 1px solid var(--ob-border);
  font-family: var(--ob-font-head); font-weight: 800; font-size: 13px; color: var(--ob-ink);
}

/* Estados: cargando / sin documento vinculado / error. */
.df-nota { font-size: 12px; line-height: 1.45; padding: 8px 10px; border-radius: var(--ob-r-field); }
.df-nota--info { color: var(--ob-muted); background: var(--ob-surface-2); border: 1px solid var(--ob-border); }
.df-nota--warn { color: var(--ob-warn); background: var(--ob-warn-tint); border: 1px solid var(--ob-warn-border); }
.df-nota--error { color: var(--ob-danger); background: var(--ob-danger-bg); border: 1px solid var(--ob-danger-border); display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.df-cargando { display: flex; flex-direction: column; gap: 8px; padding: 6px 0; }
.df-cargando span { height: 12px; border-radius: 4px; background: var(--ob-border); animation: df-pulso 1.1s ease-in-out infinite alternate; }
.df-cargando span:nth-child(1) { width: 55%; height: 38px; }
.df-cargando span:nth-child(2) { width: 90%; }
.df-cargando span:nth-child(3) { width: 70%; }
@keyframes df-pulso { from { opacity: 1; } to { opacity: .45; } }
@media (prefers-reduced-motion: reduce) { .df-cargando span { animation: none; } }

/* ---------- sidebar angosta (icon-only) ---------- */
/* Bajo 860px el sidebar fijo de 220px empuja el contenido a scroll horizontal.
   Se colapsa a solo-icono (~64px): se ocultan textos, quedan los iconos centrados. */
@media screen and (max-width: 860px) {
  .ob-side { width: 64px; flex: 0 0 64px; padding: 16px 8px; }
  .ob-brand { justify-content: center; padding: 8px 4px; }
  .ob-brand__name { display: none; }
  .ob-navitem {
    justify-content: center; gap: 0; padding: 10px 4px;
    font-size: 0; /* colapsa el texto del label (nodo de texto suelto, sin span propio) */
  }
  .ob-side__grupo { display: none; } /* colapsado a iconos: sin rotulos */
  .ob-side__role { display: none; }
  .ob-view { padding: 14px 12px 24px; }
  /* Los sub-items de Configuracion pierden la sangria: en el riel todos los
     iconos se alinean igual (la regla base tiene mas especificidad y si no
     se corrige aca quedarian corridos). El chevron tampoco aporta sin label. */
  .ob-side__cfg .ob-navitem { padding-left: 4px; }
  .ob-navitem--cfg .ob-navitem__chev { display: none; }

  /* El toggle solo existe bajo 860px: arriba, el riel de iconos ya es chico
     y no vale la pena esconderlo. 44px: minimo comodo para un pulgar. */
  .ob-navtoggle { display: inline-flex; min-width: 44px; min-height: 44px; }
  /* .ob-app es flex (layout del shell): sacar el sidebar del flujo con
     display:none le devuelve el ancho a .ob-main solo (flex:1), sin dejar
     hueco ni necesitar un margin/padding de compensacion. */
  .ob-app.nav-cerrada .ob-side { display: none; }
}

/* ---------- impresion ---------- */
.ob-printable { display: none; }
@page { size: A4; margin: 15mm; }   /* papel deterministico: A4 en cualquier PC/navegador */
@media print {
  .ob-side, .ob-topbar, .ob-no-print { display: none !important; }
  .ob-app, .ob-main, .ob-view { display: block !important; height: auto !important; overflow: visible !important; }
  .ob-view { padding: 0 !important; }
  .ob-printable { display: block !important; }
  body { background: #fff !important; }
}

/* ---------- estados vacios / carga / error ----------
   Son TRES cosas distintas y tienen que verse distinto. `.ob-empty` centrado y
   gris significa "aca no hay nada, todo bien": usarlo para un fallo disfraza el
   error de estado normal (le pasaba a la vista Tienda, que mostraba
   "No se pudo comparar" con la tipografia de "sin datos"). */
.ob-empty { padding: 24px; text-align: center; color: var(--ob-muted-2); font-size: 13px; }
.ob-loading { display: flex; align-items: center; justify-content: center; gap: 12px; padding: 40px 0; color: var(--ob-muted); font-size: 13px; }
.ob-error-box {
  padding: 12px 14px; text-align: left; font-size: 13px;
  color: var(--ob-danger); background: var(--ob-danger-bg);
  border: 1px solid var(--ob-danger-dot); border-radius: var(--ob-r-field);
}
/* Spinner en linea, para el renglon de estado de una operacion (el de 24px es
   para el bloque de carga de una card entera). */
.ob-spin--sm { width: 13px; height: 13px; border-width: 2px; flex: none; }

/* ---------- lightbox de comprobante (imagen o PDF) ----------
   Overlay UNICO (public/app/js/lupa.js), antes duplicado entre Verificacion
   (solo imagen) y Cobros (imagen + PDF, sin Esc). Se crea una sola vez y
   se reusa; empieza oculto y JS alterna `style.display` como ya hacia
   cada vista por separado. */
.ob-lightbox {
  position: fixed; inset: 0; z-index: var(--ob-z-dialogo); display: none;
  flex-direction: column; align-items: center; justify-content: center;
  gap: 14px; padding: 20px; background: rgba(14, 52, 96, .85); cursor: zoom-out;
}
.ob-lightbox__body { display: flex; align-items: center; justify-content: center; width: 100%; cursor: default; }
.ob-lightbox__img {
  max-width: 90%; max-height: 80vh; border-radius: 12px; cursor: default;
  box-shadow: 0 20px 60px rgba(0, 0, 0, .5);
}
.ob-lightbox__iframe {
  width: min(900px, 92vw); height: 80vh; border: 0; border-radius: 12px;
  background: #fff; cursor: default; box-shadow: 0 20px 60px rgba(0, 0, 0, .5);
}
/* 44px: el minimo comodo para un pulgar (mismo criterio que .ob-btn en tarjetas). */
.ob-lightbox__cerrar {
  position: absolute; top: 10px; right: 10px; width: 44px; height: 44px;
  display: flex; align-items: center; justify-content: center;
  border: 0; border-radius: 50%; background: rgba(255, 255, 255, .12);
  color: #fff; font-size: 22px; font-weight: 700; line-height: 1; cursor: pointer;
}
.ob-lightbox__cerrar:hover { background: rgba(255, 255, 255, .22); }
.ob-lightbox__header { color: #fff; text-align: center; max-width: 92vw; }
.ob-lightbox__titulo { font-family: var(--ob-font-head); font-weight: 800; font-size: 14px; }
.ob-lightbox__subtitulo { font-size: 12.5px; color: rgba(255, 255, 255, .78); margin-top: 2px; }
.ob-lightbox__acciones { display: flex; gap: 10px; flex-wrap: wrap; justify-content: center; }
.ob-lightbox__descargar, .ob-lightbox__imprimir {
  font-family: var(--ob-font-head); font-weight: 700; font-size: 13px; color: #fff;
  background: rgba(255, 255, 255, .12); padding: 9px 16px; border-radius: var(--ob-r-pill);
  border: 0; text-decoration: none; cursor: pointer;
}
.ob-lightbox__descargar:hover, .ob-lightbox__imprimir:hover { background: rgba(255, 255, 255, .22); }

/* ---------- miniaturas de comprobante (public/app/js/comprobantePedido.js) ----------
   Fila de tarjetitas dentro del detalle expandido de un pedido (Logistica,
   Vendedor): SOLO se pintan si la tarjeta esta abierta, asi que una cola de
   decenas de pedidos colapsados no dispara ni una sola request de imagen. */
.ob-comp-minis { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 6px; }
.ob-comp-mini {
  position: relative; width: 104px; height: 104px; padding: 0; border: 1px solid var(--ob-border);
  border-radius: 10px; overflow: hidden; cursor: zoom-in; background: #F7FAFC;
}
.ob-comp-mini__img { width: 100%; height: 100%; object-fit: cover; display: block; }
.ob-comp-mini__pdf {
  width: 100%; height: 100%; display: flex; flex-direction: column; align-items: center;
  justify-content: center; gap: 3px; font-size: 26px; color: var(--ob-muted);
  font-family: var(--ob-font-head); font-weight: 700;
}
.ob-comp-mini__pdf span { font-size: 10px; letter-spacing: .05em; }
.ob-comp-mini__chip {
  position: absolute; left: 4px; bottom: 4px; font-family: var(--ob-font-head); font-weight: 700;
  font-size: 9px; padding: 2px 6px; border-radius: 999px; text-transform: uppercase;
}
@media (max-width: 640px) { .ob-comp-mini__chip { font-size: 11px; } }

/* ---------- guias de envio: tira de miniaturas y revision (i175, public/app/js/guiaManual.js) ----------
   Cada adjunto es una miniatura de 80 px que abre la lupa, con una X chica (circulo de 22 px) cuya AREA TOCABLE es de
   44 x 44 px. La X sale del borde 10 px (= el hueco de la tira) para no taparle la miniatura al vecino.
   Revision: los botones pesan lo mismo (ninguno relleno); abajo de 640 px ocupan todo el ancho. */
.gm-tira { display: flex; flex-wrap: wrap; gap: 12px 10px; padding: 10px 10px 0 0; }
.gm-mini { position: relative; flex: none; }
.gm-tira .gm-mini .ob-comp-mini { display: block; width: 80px; height: 80px; border-radius: 10px; }
.gm-tira .gm-mini .ob-comp-mini__chip { font-size: 11px; padding: 1px 6px; }
.gm-x {
  position: absolute; top: -10px; right: -10px; width: 44px; height: 44px; padding: 0; margin: 0;
  display: flex; align-items: center; justify-content: center; border: 0; background: transparent; cursor: pointer;
}
.gm-x__c {
  width: 22px; height: 22px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center;
  background: var(--ob-surface); border: 1px solid var(--ob-field-border); color: var(--ob-navy); font-size: 12px;
  box-shadow: 0 1px 3px rgba(23, 34, 48, .18);
}
.gm-x:hover .gm-x__c { background: var(--ob-navy-tint); }
.gm-x[disabled] { opacity: .5; cursor: default; }
.gm-rev { margin-top: 8px; padding: 8px 10px; border-radius: 8px; background: var(--ob-warn-bg); color: var(--ob-ink); }
.gm-rev__t { margin: 0; font-size: 12.5px; overflow-wrap: anywhere; }
.gm-rev__b { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 8px; }
.gm-corrige { padding: 8px 10px; border-radius: 8px; background: var(--ob-info-bg); color: var(--ob-ink); }
@media (max-width: 640px) {
  .gm-rev__b .ob-btn { flex: 1 1 100%; }
}

/* ---------- chip de filtro (public/app/js/chipFiltro.js) ----------
   UN componente para "chip que al tocarlo filtra la lista de abajo", en vez
   de Logistica/Cobros/Stock reconstruyendo cada una el suyo (critica de
   diseno 2026-09-28, item 1). Dos formas segun si trae `count`:
   --pill   (Cobros: rango de fecha / agrupar por, solo etiqueta) y
   --kpi    (Logistica/Stock: etiqueta + numero grande, marca el activo con
             un anillo -el patron que Stock ya resolvia bien- en vez de
             rellenar el fondo entero, que tapaba el color del tono). */
.ob-chipfiltro {
  cursor: pointer; user-select: none; border-radius: var(--ob-r-pill);
  font-family: var(--ob-font-head); font-weight: 700;
  background: var(--ob-surface); color: var(--ob-muted);
  border: 1px solid var(--ob-field-border);
}
/* Caja de 44px (objetivo tactil del mostrador) con la pastilla de siempre dibujada
   adentro (::before, 9px de aire arriba y abajo): el chip pesa igual a la vista pero
   se acierta con el dedo. Las dos pastillas vecinas no se pisan: la caja es 44 y
   la pastilla visible 26. */
.ob-chipfiltro--pill {
  position: relative; isolation: isolate;
  min-height: 44px; padding: 5px 10px; font-size: 11px; border-radius: var(--ob-r-pill);
  background: transparent; border: 0;
}
.ob-chipfiltro--pill::before {
  content: ""; position: absolute; inset: 9px 0; z-index: -1; border-radius: var(--ob-r-pill);
  background: var(--ob-surface); border: 1px solid var(--ob-field-border);
}
.ob-chipfiltro--pill.is-active { color: var(--ob-surface); }
/* El anillo de foco va en la pastilla visible, no en la caja de 44px. */
.ob-chipfiltro--pill:focus-visible { outline: none; }
.ob-chipfiltro--pill:focus-visible::before { outline: 2px solid var(--ob-navy); outline-offset: 2px; }
.ob-chipfiltro--pill.is-active::before {
  border-color: var(--ob-chipfiltro-tono, var(--ob-navy));
  background: var(--ob-chipfiltro-tono, var(--ob-navy));
}
/* Filtro ya puesto, con su ✕ (chipQuitarHTML): se lee como activo pero es una
   accion de quitar. 44px de alto: el Catalogo se usa de pie, en tablet. */
.ob-chipfiltro--quitar {
  display: inline-flex; align-items: center; gap: 9px; min-height: 44px;
  padding: 6px 14px; font-size: 12px; white-space: nowrap;
  color: var(--ob-navy); background: var(--ob-navy-tint); border-color: var(--ob-field-border);
}
.ob-chipfiltro--quitar:hover { background: var(--ob-celeste-hover, #BCD9F7); }
.ob-chipfiltro--kpi {
  display: block; text-align: left; flex: 1 1 150px; min-width: 140px;
  background: var(--ob-surface); border: 1px solid var(--ob-border);
  border-radius: 12px; padding: 10px 14px;
}
.ob-chipfiltro--kpi.is-active {
  box-shadow: inset 0 0 0 2px var(--ob-chipfiltro-tono, var(--ob-navy));
  border-color: var(--ob-chipfiltro-tono, var(--ob-navy));
}
.ob-chipfiltro__label {
  display: block; font-size: 11px; letter-spacing: .05em; text-transform: uppercase;
  color: var(--ob-muted);
}
.ob-chipfiltro__detalle { display: block; font-size: 11px; color: var(--ob-muted); margin-top: 1px; }
.ob-chipfiltro__count {
  display: block; font-family: var(--ob-font-head); font-weight: 800; font-size: 22px;
  line-height: 1.25; margin-top: 3px;
  color: var(--ob-chipfiltro-tono, var(--ob-ink));
  font-variant-numeric: tabular-nums; font-feature-settings: "tnum" 1;
}

/* ---------- detalle del item en el carrito (js/carritoUI.js) ----------
   Chips de medida/color (reusan .ob-chipfiltro--pill) + campo de texto libre.
   El chip del carrito sube a 32px de alto: es lo que el vendedor toca con el
   cliente enfrente. El aviso "Falta elegir ..." informa, no bloquea. */
/* 59px = 16 (gutter) + 34 (icono) + 9 (gap): alinea el detalle con el nombre. */
.cu-detalle { padding: 0 16px 10px 59px; margin-top: -4px; }
@media (max-width: 600px) { .cu-detalle { padding-left: 16px; } }
.cu-chips { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-top: 6px; }
.cu-chips__et { font-size: 11px; color: var(--ob-muted); min-width: 46px; }
/* 44px tambien en el carrito (regla dura del mostrador, decision 5 del 02/10): la caja es 44 y
   la pastilla visible sigue en 32 (::before con 6px de aire), asi las filas no se agrandan a la vista. */
.cu-chips .ob-chipfiltro--pill { min-height: 44px; padding: 6px 12px; font-size: 12px; }
.cu-chips .ob-chipfiltro--pill::before { inset: 6px 0; }
.cu-hint { margin-top: 4px; font-size: 11.5px; font-weight: 600; color: var(--ob-warn); }
.cu-hint[hidden] { display: none; }

/* Linea del carrito (Venta y Remito). Pantalla de mostrador: 44px de area
   tocable en TODO control (PRODUCT/DESIGN). Cantidad, precio y borrar son
   <button>/<input> reales; el gap de 10px evita que un toque fallado caiga en
   el precio. En angosto la fila pasa a dos renglones en vez de achicar el blanco. */
.cu-linea { display: flex; align-items: center; flex-wrap: wrap; gap: 10px; padding: 10px 16px; }
.cu-linea__nombre { flex: 1 1 150px; min-width: 0; }
.cu-cant { display: flex; align-items: center; gap: 4px; }
.cu-step, .cu-del {
  display: inline-flex; align-items: center; justify-content: center; flex: none;
  width: 44px; height: 44px; padding: 0; border: 0; border-radius: 8px; cursor: pointer;
  font-family: var(--ob-font-head); font-weight: 800; line-height: 1;
}
.cu-step { background: var(--ob-surface-2); color: var(--ob-ink); font-size: 18px; }
.cu-step:hover { background: var(--ob-bg); }
/* a cantidad 1 el − borra el renglon: se ve como "quitar" (papelera, en rojo) */
.cu-step--quitar { color: var(--ob-danger); font-size: 15px; }
.cu-step--quitar:hover { background: var(--ob-danger-bg); }
.cu-del { background: transparent; color: var(--ob-danger); font-size: 16px; font-weight: 900; }
.cu-del:hover { background: var(--ob-danger-bg); }
.cu-qty, .cu-precio, .cu-campo {
  min-height: 44px; box-sizing: border-box; border: 1px solid var(--ob-border-2);
  border-radius: 8px; background: #fff; color: var(--ob-ink);
}
.cu-qty { width: 56px; text-align: center; font-size: 14px; padding: 4px; }
.cu-precio { width: 104px; text-align: right; font-size: 13px; padding: 4px 8px; }
.cu-campo { padding: 8px 10px; }
.cu-qty:focus-visible, .cu-precio:focus-visible { outline: 2px solid var(--ob-navy); outline-offset: 2px; }

/* ---------- Mis pedidos (views/vendedor.js + misPedidos.js) ----------
   Cuatro bloques apilados: Necesita atencion / Cotizaciones / Pedidos en curso
   / Historial. Todo son tarjetas planas con borde (.ob-card) y filas en grilla;
   el color aparece SOLO donde hay un estado (la etiqueta de la alerta, los
   chips de pago y despacho): el resto es tinta y gris. Mismo tope de 1120px que
   .ob-split, asi la lista no se estira a 1600px en una pantalla de escritorio. */
.mp { max-width: 1120px; margin: 0 auto; display: flex; flex-direction: column; gap: 20px; }
.mp-meta { font-size: 11.5px; color: var(--ob-muted-2); }
/* Buscador de la Cabina, en la fila de herramientas de la plantilla de pagina (molde i144). */
.v-buscar { position: relative; flex: 1 1 320px; min-width: 0; }
.v-buscar .ob-field { width: 100%; padding-left: 36px; min-height: var(--ob-tap-tactil); }
.v-buscar__ico { position: absolute; left: 12px; top: 50%; transform: translateY(-50%); display: inline-flex; color: var(--ob-muted); pointer-events: none; z-index: 1; }
.v-buscar__ico svg { width: 16px; height: 16px; }
.v-sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.mp-lado { margin-left: auto; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; justify-content: flex-end; }

/* contador de la cabecera de un bloque */
.mp-count {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 22px; height: 20px; padding: 0 7px; border-radius: var(--ob-r-pill);
  font-family: var(--ob-font-head); font-weight: 800; font-size: 11.5px;
  background: var(--ob-bg); color: var(--ob-muted);
  font-variant-numeric: tabular-nums; font-feature-settings: "tnum" 1;
}
.mp-count--warn { background: var(--ob-warn-bg); color: var(--ob-warn); }
.mp-count--crit { background: var(--ob-danger-bg); color: var(--ob-danger); }

/* boton secundario (Ver historial, Ver mas, Reintentar): mismo gesto que "Quitar" del seguimiento */
.mp-btn {
  min-height: 44px; padding: 0 14px; font-size: 12px; background: var(--ob-surface); color: var(--ob-navy);
  border: 1px solid var(--ob-field-border);
}
.mp-btn:hover { background: var(--ob-navy-tint); }
.mp-btn[disabled] { cursor: progress; }

/* avisos y vacios */
.mp-aviso {
  margin: 12px 16px 0; padding: 10px 12px; font-size: 12px; line-height: 1.45; color: var(--ob-ink);
  background: var(--ob-warn-tint); border: 1px solid var(--ob-warn-border); border-radius: var(--ob-r-field);
}
.mp-aviso b { display: block; font-family: var(--ob-font-head); font-size: 11.5px; color: var(--ob-warn); margin-bottom: 2px; }
.mp-aviso p { margin: 0; }
.mp-aviso p + p { margin-top: 3px; }
.mp-vacio { padding: 18px 16px; font-size: 13px; color: var(--ob-muted); }
.mp-vacio--ok::before { content: "✓ "; color: var(--ob-ok); font-weight: 800; }
.mp-vacio--col { padding: 14px; font-size: 12px; color: var(--ob-muted-2); }

/* un pedido = fila + (si esta abierto) su detalle */
.mp-item { border-bottom: 1px solid var(--ob-border); }
.mp-item:last-child { border-bottom: 0; }
.mp-alerta, .mp-cot { cursor: pointer; }
.mp-alerta:hover, .mp-cot:hover { background: var(--ob-surface-2); }

/* lineas de texto compartidas por las tres filas */
.mp-linea1 {
  font-family: var(--ob-font-head); font-weight: 700; font-size: 12.5px; color: var(--ob-ink);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  display: flex; align-items: center; gap: 5px;
}
.mp-linea1 > .mp-txt { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.mp-linea2 { font-size: 11.5px; color: var(--ob-muted); display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.mp-linea3 { font-size: 11.5px; color: var(--ob-muted); margin-top: 1px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mp-monto { font-family: var(--ob-font-head); font-weight: 800; font-size: 13px; text-align: right; color: var(--ob-ink); white-space: nowrap; }

/* filas de la cabina (Resumen): con acciones de 44px no entran en una linea en el celular, bajan */
.v-fila { flex-wrap: wrap; row-gap: 4px; }

/* acciones de fila: TODAS de 44px de alto (mostrador, DESIGN.md): iconos de 44x44,
   botones de texto ("Despachar", "Enviar guia") y "Ver mas"; 8px entre ellas para no
   tocar la vecina. Si no entran en una linea, bajan a la siguiente. */
.mp-acciones { display: flex; align-items: center; justify-content: flex-end; gap: 8px; flex-wrap: wrap; }
.mp-ico { color: var(--ob-ink); width: 44px; height: 44px; }
/* boton de 44px de un formulario del mostrador (Nuevo presupuesto, Confirmar venta...) y su version cuadrada de icono */
.mp-btn44 { min-height: 44px; }
.mp-ico-btn { min-width: 44px; min-height: 44px; padding: 0; }
.mp-tag {
  display: inline-block; padding: 1px 7px; border-radius: var(--ob-r-pill); white-space: nowrap;
  font-family: var(--ob-font-head); font-weight: 700; font-size: 11px; background: var(--ob-bg); color: var(--ob-muted);
}
.mp-guiaok { font-size: 11px; font-family: var(--ob-font-head); font-weight: 700; color: var(--ob-ok); white-space: nowrap; }

/* ---- 1. Necesita atencion: etiqueta | pedido + detalle | monto | acciones ---- */
.mp-alerta {
  display: grid; grid-template-columns: 212px minmax(0, 1fr) 104px 300px;
  align-items: center; column-gap: 14px; padding: 11px 16px;
}
.mp-alerta__tag { justify-self: start; white-space: nowrap; }
.mp-alerta__main, .mp-cot__main { min-width: 0; }
.mp-alerta__main .mp-linea2 { font-size: 12px; display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* ---- 2. Cotizaciones: tablero de tres columnas ---- */
.mp-tablero { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); }
.mp-col { min-width: 0; border-left: 1px solid var(--ob-border); }
.mp-col:first-child { border-left: 0; }
.mp-col__head {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  padding: 8px 14px; background: var(--ob-surface-2); border-bottom: 1px solid var(--ob-border);
}
.mp-col__nombre {
  font-family: var(--ob-font-head); font-weight: 700; font-size: 11.5px; letter-spacing: .04em;
  text-transform: uppercase; color: var(--ob-muted);
}
.mp-cot { display: flex; align-items: center; flex-wrap: wrap; gap: 4px 8px; padding: 9px 8px 9px 14px; }
.mp-cot__main { flex: 1 1 150px; }
.mp-cot .mp-acciones { justify-content: flex-start; }
.mp-cot .mp-linea2 b { color: var(--ob-ink); font-family: var(--ob-font-head); }
.mp-col__mas { padding: 8px 14px 10px; }
/* A quien llamo hoy (i58): cotizaciones con seguimiento para hoy o vencido, arriba de Mis pedidos */
.ll-aviso { display: flex; align-items: center; gap: 10px; padding: 10px 18px; font-size: 13px; font-weight: 600; background: var(--ob-ok-bg); color: var(--ob-ok); }
.ll-aviso--error { background: var(--ob-danger-bg); color: var(--ob-danger); }
.ll-aviso span { flex: 1; }
.ll-aviso button { min-height: 44px; padding: 0 12px; border: 0; background: transparent; color: inherit; font: inherit; font-weight: 700; text-decoration: underline; cursor: pointer; }
.ll-fila { display: flex; flex-wrap: wrap; gap: 12px 18px; align-items: center; padding: 14px 18px; }
.ll-main { flex: 1 1 320px; min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.ll-l1 { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.ll-l1 b { font-size: 15px; }
.ll-doc, .ll-cuando { font-size: 12px; color: var(--ob-muted); }
.ll-nota { font-size: 13px; color: var(--ob-ink); overflow-wrap: anywhere; }
.ll-badge { font-family: var(--ob-font-head); font-weight: 700; font-size: 11px; border-radius: 999px; padding: 3px 9px; background: var(--ob-warn-bg); color: var(--ob-warn); }
.ll-badge--venc { background: var(--ob-danger-bg); color: var(--ob-danger); }
.ll-acc, .ll-pos { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.ll-pos { gap: 6px; }
.ll-pos > span { font-size: 12px; color: var(--ob-muted); margin-right: 2px; }
/* Fila activa (i145 c, filaActiva.js): una sola fila por lista lleva el relleno en su accion principal. Las demas la muestran en
   outline y, en escritorio con mouse, la rellenan al pasar el puntero (sin cambiar cual es la activa). */
@media (hover: hover) {
  [data-activable]:not(.ob-fila--activa):hover [data-principal]:not([disabled]) { background: var(--ob-navy); border-color: var(--ob-navy); color: #fff; }
}
.ll-vacio { padding: 28px 18px; text-align: center; color: var(--ob-muted); font-size: 14px; }

/* ---- 3/4. Pedidos en curso e Historial: pedido | monto | chips | acciones ---- */
.mp-barra {
  display: flex; align-items: center; gap: 7px; flex-wrap: wrap;
  padding: 10px 16px; border-bottom: 1px solid var(--ob-border);
}
.mp-barra .mp-lado .ob-field { width: auto; min-height: 44px; padding: 5px 9px; font-size: 11.5px; font-family: var(--ob-font-head); font-weight: 700; color: var(--ob-muted); }
.mp-pie { padding: 10px 16px 12px; display: flex; align-items: center; gap: 10px; flex-wrap: wrap; border-top: 1px solid var(--ob-border); }

/* historial colapsado: una sola linea */
.mp-historial__linea { display: flex; align-items: center; gap: 10px; padding: 12px 16px; flex-wrap: wrap; }

/* detalle expandido de un pedido */
.mp-detalle { padding: 11px 16px 13px; background: var(--ob-bg); border-top: 1px solid var(--ob-border); }

/* esqueleto mientras llega la primera lectura */
.mp-esq { display: flex; flex-direction: column; gap: 9px; padding: 16px; }
.mp-esq i { display: block; height: 11px; border-radius: 6px; background: var(--ob-bg); animation: mp-pulso 1.4s ease-in-out infinite; }
.mp-esq i:nth-child(odd) { width: 62%; }
.mp-esq i:nth-child(even) { width: 88%; }
@keyframes mp-pulso { 50% { opacity: .45; } }
@media (prefers-reduced-motion: reduce) { .mp-esq i { animation: none; } }

/* Angosto (celular, o la ventana achicada): las filas pasan a renglones en
   vez de apretar cuatro columnas, y el tablero apila las columnas. */
/* Las filas pasan a renglones antes que el tablero: con la columna de acciones de
   44px (300px) la fila de cuatro columnas ya no entra en una tablet apaisada
   (1024px: quedaban ~68px para el cliente). */
@media (max-width: 1180px) {
  .mp-alerta { grid-template-columns: minmax(0, 1fr) auto; row-gap: 5px; }
  .mp-alerta__main { grid-column: 1 / -1; grid-row: 2; }
  .mp-alerta__main .mp-linea2 { white-space: normal; }
  .mp-alerta .mp-monto { grid-column: 2; grid-row: 1; }
  .mp-alerta .mp-acciones { grid-column: 1 / -1; grid-row: 3; justify-content: flex-start; }
}
@media (max-width: 1000px) {
  .mp-tablero { grid-template-columns: 1fr; }
  .mp-col { border-left: 0; border-top: 1px solid var(--ob-border); }
  .mp-col:first-child { border-top: 0; }
}

/* Buscador de producto (carritoUI): fila resaltada con flechas. Fondo + barra navy, no solo color. */
.cu-hit.is-sel, .cu-hit:hover { background: var(--ob-navy-tint); }
.cu-hit.is-sel { box-shadow: inset 3px 0 0 var(--ob-navy); }

/* 44px: acciones de fila de las pantallas de mostrador/deposito (Remito, Stock).
   Variante propia de .ob-iconbtn (28px, listas densas) para no tocar a Vendedor. */
.ob-iconbtn--tap { width: 44px; height: 44px; font-size: 16px; }

/* ---------- Venta: aside "Venta" y pie de cobro (i57) ----------
   Orden: entrega -> Más opciones (plegado) -> TOTAL + COBRAR. El pie se pega al
   fondo del aside en escritorio para que el total y los tres canales de pago se
   vean sin scrollear a 1366x768; bajo 860px vuelve al flujo normal (en un celular
   un bloque pegado tapa el carrito). El aside se estira a lo alto de la fila
   porque `sticky` solo se mueve dentro de su contenedor. */
.vt-aside { align-self: stretch; display: flex; flex-direction: column; gap: 16px; }
.vt-aside__form { flex: 1; display: flex; flex-direction: column; gap: 16px; }
.vt-f44 { min-height: 44px; box-sizing: border-box; }

.vt-seg { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 6px; }
.vt-seg__btn {
  min-height: 44px; border-radius: var(--ob-r-field); cursor: pointer;
  font-family: var(--ob-font-head); font-weight: 700; font-size: 13px;
  background: #fff; color: var(--ob-ink); border: 1px solid var(--ob-field-border);
}
.vt-seg__btn:focus-visible { outline: 2px solid var(--ob-navy); outline-offset: 2px; }
.vt-seg__btn[aria-pressed="true"]:focus-visible { outline-color: var(--ob-navy); box-shadow: 0 0 0 2px #fff inset; }
.vt-seg__btn[aria-pressed="true"] { background: var(--ob-navy); color: #fff; border-color: var(--ob-navy); }

/* Canal de la venta (i128): dos fichas grandes (Mostrador / WhatsApp) y una chica "Otro" que
   despliega tienda / Mercado Libre / otro. Misma ficha que .vt-seg__btn (44px, navy al marcar). */
.vt-canal { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) auto; gap: 6px; }
.vt-canal__otros { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
.vt-canal__otros[hidden] { display: none; }
.vt-chip {
  min-height: 44px; border-radius: var(--ob-r-field); cursor: pointer; padding: 0 14px;
  font-family: var(--ob-font-head); font-weight: 700; font-size: 13px;
  background: #fff; color: var(--ob-ink); border: 1px solid var(--ob-field-border);
}
.vt-canal__otro { font-size: 12px; font-weight: 600; color: var(--ob-muted); }
.vt-chip:focus-visible { outline: 2px solid var(--ob-navy); outline-offset: 2px; }
.vt-chip[aria-pressed="true"] { background: var(--ob-navy); color: #fff; border-color: var(--ob-navy); }
.vt-chip[aria-pressed="true"]:focus-visible { box-shadow: 0 0 0 2px #fff inset; }
/* Bajo 400px "Otro · Mercado Libre" aplastaria Mostrador y WhatsApp: "Otro" pasa a una segunda fila. */
@media (max-width: 400px) {
  .vt-canal { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .vt-canal__otro { grid-column: 1 / -1; }
}

/* Venta ya registrada (i95): el carrito y el cliente de la izquierda quedan de solo lectura. Campos deshabilitados
   con tokens (no hay componente nuevo): fondo de superficie, texto atenuado y cursor de "no". */
.vt-cerrada input:disabled, .vt-cerrada select:disabled {
  background: var(--ob-surface-2); color: var(--ob-muted); cursor: not-allowed;
}
.vt-cerrada .ob-btn:disabled { opacity: .5; cursor: not-allowed; }

.vt-mas__btn {
  width: 100%; min-height: 44px; display: flex; align-items: center; gap: 8px; text-align: left;
  border: 1px dashed var(--ob-field-border); border-radius: var(--ob-r-field); background: var(--ob-surface-2);
  padding: 4px 12px; cursor: pointer; color: var(--ob-navy);
  font-family: var(--ob-font-head); font-weight: 700; font-size: 13px;
}
.vt-mas__btn--hay { border-style: solid; border-color: var(--ob-warn-border); background: var(--ob-warn-tint); }
.vt-mas__t { flex: none; }
.vt-mas__s { flex: 1; min-width: 0; font-family: var(--ob-font); font-weight: 400; font-size: 12px; color: var(--ob-muted); text-align: right; }
.vt-mas__s--hay { font-weight: 700; color: var(--ob-warn); }
.vt-mas__chev { flex: none; transition: transform .15s; color: var(--ob-muted); }
.vt-mas__btn[aria-expanded="true"] .vt-mas__chev { transform: rotate(180deg); }
.vt-mas__grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; margin-top: 12px; }
#vt-mas-panel { padding-top: 2px; }

.vt-foot { padding: 10px 16px 12px; margin-top: auto; }
/* Solo TOTAL + Cobrar viven en el pie pegado (~220px); las acciones del presupuesto (.vt-secard) quedan
   en flujo normal debajo. Pegado solo si hay alto de sobra: en pantallas bajas el pie taparia el cotizador. */
@media (min-width: 860px) and (min-height: 720px) {
  .vt-foot { position: sticky; bottom: 0; z-index: 2; box-shadow: 0 -6px 14px -8px rgba(23, 34, 48, .25); }
}
/* Celular: el pie (TOTAL + Cobrar) se pega al borde de abajo mientras el panel de la venta esta
   a la vista. Antes quedaba al final de la columna y habia que scrollear todo para terminar
   (captura 390px, critica 2026-10-21). Compacto: los tres botones en una fila de 48px. */
@media (max-width: 859px) {
  .vt-foot { position: sticky; bottom: 0; z-index: 2; box-shadow: 0 -6px 14px -8px rgba(23, 34, 48, .25); padding: 8px 12px 10px; }
  .vt-pay { min-height: 48px; font-size: 12px; }
}
/* "Ir a cotizar" hace scrollIntoView: el margen evita que el campo quede detras del pie pegado */
#vt-envio-block, #vt-loc { scroll-margin-top: 12px; scroll-margin-bottom: 260px; }
.vt-secard { padding: 12px 16px 14px; }

.vt-pay-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
.vt-pay {
  min-height: 56px; padding: 4px 4px; border: 0; border-radius: 12px; cursor: pointer; color: #fff;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 0;
  font-family: var(--ob-font-head); font-weight: 800; font-size: 13px; line-height: 1.15; text-align: center;
}
/* Una sola familia (navy) para los tres: son el MISMO desenlace -cobrar- por tres
   canales, no tres acciones distintas. Antes verde/navy/azul competian entre si y con
   "Convertir en venta" (critica 2026-10-21). El verbo va arriba, chico; el canal, abajo. */
.vt-pay { background: var(--ob-navy); }
.vt-pay__v { font-size: 10.5px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; opacity: .8; margin-bottom: 2px; }

/* ---------- fotos del producto (vista Catalogo: modal de edicion y ficha) ----------
   Modal: la portada a la izquierda y la tira de la galeria a la derecha; cada foto es un
   cuadrado con sus botones (←, ↻, →, ★ Hacer portada, ✕). Todo lo que se toca es un <button>
   (el arrastre es un extra para mouse). Debajo de 640 px se apila y la tira pasa a 3 columnas.
   Ficha: la foto grande con flechas y contador, y debajo las miniaturas. */
.fg-layout { grid-column: 1 / -1; display: grid; grid-template-columns: minmax(0, 210px) 1fr; gap: 16px; align-items: start; }
.fg-portada {
  position: relative; aspect-ratio: 1 / 1; display: flex; align-items: center; justify-content: center;
  border: 1px solid var(--ob-border); border-radius: var(--ob-r-card); overflow: hidden; padding: 10px;
}
.fg-portada--nueva { border: 2px solid var(--ob-navy); }
.fg-portada--baja, .fg-portada--vacia { border: 2px dashed var(--ob-field-border); }
.fg-portada--baja { border-color: var(--ob-danger); }
.fg-portada[draggable="true"], .fg-tile[draggable="true"] { cursor: grab; }
.fg-strip { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 8px 6px; }
.fg-tile { position: relative; display: flex; flex-direction: column; gap: 3px; min-width: 0; align-self: start; }
.fg-cuadro {
  position: relative; aspect-ratio: 1 / 1; overflow: hidden; background: #fff;
  border: 1px solid var(--ob-border); border-radius: var(--ob-r-field);
}
.fg-tile--nueva .fg-cuadro { border: 2px solid var(--ob-navy); }
.fg-tile--baja .fg-cuadro { border: 2px dashed var(--ob-danger); }
.fg-tile--vieja { opacity: .65; }
.fg-tile--vieja .fg-cuadro { border-style: dashed; border-color: var(--ob-border-2); }
.fg-tile--vieja img { width: 100%; height: 100%; object-fit: cover; }
.fg-img { display: flex; align-items: center; justify-content: center; width: 100%; height: 100%; padding: 0; margin: 0; border: 0; background: none; cursor: pointer; }
.fg-img:disabled { cursor: default; }
.fg-img img { width: 100%; height: 100%; transition: transform .15s; }
.fg-badge {
  position: absolute; top: 5px; left: 5px; z-index: 1; pointer-events: none;
  font-family: var(--ob-font-head); font-weight: 800; font-size: 10.5px; letter-spacing: .04em;
  padding: 1px 6px; border-radius: var(--ob-r-chip);
  background: rgba(255, 255, 255, .9); color: var(--ob-navy); border: 1px solid var(--ob-border-2);
}
.fg-badge--nueva { background: var(--ob-navy); color: #fff; border-color: var(--ob-navy); }
.fg-badge--baja { background: var(--ob-danger-bg); color: var(--ob-danger); border-color: var(--ob-danger); }
.fg-btn {
  display: inline-flex; align-items: center; justify-content: center; min-width: 32px; min-height: 32px; padding: 0 4px;
  background: #fff; color: var(--ob-navy); border: 1px solid var(--ob-field-border); border-radius: var(--ob-r-field);
  font-size: 14px; line-height: 1; cursor: pointer;
}
.fg-btn:hover:not(:disabled) { background: var(--ob-navy-tint); }
.fg-btn:disabled { opacity: .4; cursor: default; }
.fg-bar { display: flex; gap: 3px; }
.fg-bar .fg-btn { flex: 1 1 0; }
.fg-bar--portada { position: absolute; left: 6px; right: 6px; bottom: 6px; z-index: 2; }
.fg-portada-btn { font-size: 11px; font-weight: 700; min-height: 28px; }
.fg-x {
  position: absolute; top: 3px; right: 3px; z-index: 2; min-width: 28px; min-height: 28px; border-radius: 999px;
  font-size: 12px; font-weight: 700; color: var(--ob-danger); background: rgba(255, 255, 255, .92);
}
.fg-x--undo { background: var(--ob-navy); color: #fff; border-color: var(--ob-navy); }
.fg-mas {
  aspect-ratio: 1 / 1; width: 100%; display: flex; align-items: center; justify-content: center; padding: 0;
  background: none; border: 2px dashed var(--ob-field-border); border-radius: var(--ob-r-field);
  font-size: 22px; color: var(--ob-muted); cursor: pointer;
}
.fg-mas:disabled { opacity: .4; cursor: default; }
.fg-arrastrando { opacity: .4; }
.fg-sobre { outline: 2px solid var(--ob-navy); outline-offset: -2px; }
@media (max-width: 640px) {
  .fg-layout { grid-template-columns: 1fr; }
  .fg-portada { max-width: 260px; }
  /* dedos, no mouse: 2 columnas para que los tres botones de cada foto midan 40 px o mas */
  .fg-strip { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .fg-btn, .fg-x { min-width: 40px; min-height: 40px; }
  .fg-portada-btn { min-height: 40px; }
  .fg-bar--portada { bottom: 4px; left: 4px; right: 4px; }
}

/* Ficha de producto (solo lectura) */
.fg-ficha { display: grid; grid-template-columns: minmax(0, 300px) 1fr; gap: 20px; align-items: start; }
.fg-visor { position: relative; border: 1px solid var(--ob-border); border-radius: var(--ob-r-card); min-height: 240px; display: flex; align-items: center; justify-content: center; padding: 14px; overflow: hidden; }
.fg-visor img { max-width: 100%; max-height: 280px; object-fit: contain; }
.fg-nav {
  position: absolute; top: 50%; transform: translateY(-50%); z-index: 1;
  width: 36px; height: 44px; display: flex; align-items: center; justify-content: center; padding: 0;
  background: rgba(255, 255, 255, .92); color: var(--ob-navy); border: 1px solid var(--ob-border-2); border-radius: var(--ob-r-field);
  font-size: 18px; cursor: pointer;
}
.fg-nav:hover { background: #fff; }
.fg-nav--prev { left: 6px; }
.fg-nav--next { right: 6px; }
.fg-contador {
  position: absolute; right: 8px; bottom: 8px; z-index: 1; font-size: 11.5px; font-weight: 700;
  padding: 2px 8px; border-radius: var(--ob-r-chip); background: rgba(255, 255, 255, .92); color: var(--ob-navy); border: 1px solid var(--ob-border-2);
}
.fg-minis { display: flex; gap: 6px; margin-top: 8px; overflow-x: auto; padding: 2px 2px 6px; }
.fg-mini {
  flex: 0 0 auto; width: 56px; height: 56px; padding: 0; background: #fff; border: 1px solid var(--ob-border);
  border-radius: var(--ob-r-field); overflow: hidden; cursor: pointer; opacity: .75;
}
.fg-mini img { width: 100%; height: 100%; object-fit: cover; display: block; }
.fg-mini:hover { opacity: 1; }
.fg-mini[aria-current="true"] { opacity: 1; border: 2px solid var(--ob-navy); }
@media (max-width: 640px) {
  .fg-ficha { grid-template-columns: 1fr; }
  .fg-mini { width: 48px; height: 48px; }
}
.fg-ficha [hidden], .fg-layout [hidden] { display: none !important; }

/* ================================================================
   Depósito en el celular (<= 640 px) — ver DESIGN.md "Celular".
   Las reglas de arriba del bloque (sin @media) son los estilos de ESCRITORIO
   que antes eran inline: pasan a clase para que una media query pueda
   cambiarlos, con los MISMOS valores (escritorio no cambia).
   Todo lo demás vive en @media (max-width: 860px) o (max-width: 640px).
   `--ob-tap` solo existe bajo 640 px: el inline `min-height:var(--ob-tap,36px)`
   vale 36 px en escritorio y 44 px en el celular sin necesitar !important.
   ================================================================ */
.lg-kpis { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 10px; margin-bottom: 16px; }
.lg-links { display: flex; flex-wrap: wrap; column-gap: 14px; } /* ver "Escritorio HD y Full HD" */
.lg-links > :empty { display: none; }
.lg-filtros-btn { display: none; }
.lg-subtabs { display: flex; gap: 8px; margin-bottom: 14px; }
.lg-desp-mes { margin-bottom: 14px; }
.lg-barra { display: flex; gap: 10px; flex-wrap: wrap; margin-bottom: 16px; align-items: center; }
.lg-f--modo, .lg-f--canal { flex: 0 1 190px; min-width: 170px; }
.lg-f--rango { flex: 0 1 160px; min-width: 145px; }
.lg-f--fecha { flex: 0 1 155px; }
.lg-subtab { cursor: pointer; user-select: none; font-family: var(--ob-font-head); font-weight: 700; font-size: 12.5px; padding: 9px 16px; border-radius: 9px; }
.ob-cerrar { margin-left: auto; cursor: pointer; font-size: 15px; color: var(--ob-muted); background: none; border: 0; padding: 0; font-family: inherit; line-height: inherit; }
.st-chips { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; margin-bottom: 16px; }

/* iOS hace zoom al enfocar un campo de menos de 16 px. */
@media (max-width: 860px) {
  :root { --ob-field-fs: 16px; } /* para los campos con tamano inline: font-size:var(--ob-field-fs,13px) */
  .ob-field { font-size: 16px; }
  /* Stock: 4 fichas en fila (piso 120 px) no entran junto al riel en un celular: bajan de a dos. */
  .st-chips { grid-template-columns: repeat(auto-fit, minmax(min(120px, 100%), 1fr)); }
}

@media (max-width: 640px) {
  :root { --ob-tap: 44px; --lg-q-basis: 0px; --lg-q-min: 0px; }
  .ob-btn, .ob-field { min-height: 44px; }
  /* .ob-tap (enlaces y mitades de un renglon de botones) vive en utilidades.css. */
  /* ✕ del modal: area de 44 px sin agrandar el encabezado (margen negativo). */
  .ob-cerrar { display: inline-flex; align-items: center; justify-content: center; min-width: 44px; min-height: 44px; margin: -8px -8px -8px auto; }

  /* ---- Logística: la primera pantalla tiene que mostrar pedidos ---- */
  /* Fichas de etapa en una sola tira que se desliza (la tercera asoma para avisar que hay más). */
  .lg-kpis { display: flex; gap: 8px; margin-bottom: 6px; overflow-x: auto; scroll-snap-type: x proximity; padding-bottom: 4px; }
  .lg-kpis > * { flex: 0 0 150px; scroll-snap-align: start; }
  /* Los enlaces ("guías para revisar", "nuevos", "retenidos") comparten renglón: regla base (escritorio y celular). */
  .lg-subtab { flex: 1 1 0; min-width: 0; padding: 9px 6px; min-height: 44px; }
  /* Búsqueda + "Filtros" en un renglón; el resto de la barra se abre con el botón. */
  .lg-filtros-btn { display: inline-flex; flex: 0 0 auto; color: var(--ob-navy); background: #fff; border: 1px solid var(--ob-field-border); }
  /* !important: #lg-vista-wrap y #lg-rango/#lg-fecha traen su display inline (JS). */
  .lg-barra:not(.is-abierta) > :is(.lg-f, #lg-vista-wrap, #lg-refresh) { display: none !important; }
  .lg-barra.is-abierta .lg-filtros-btn { background: var(--ob-celeste-marca); }
  .lg-f { flex: 1 1 100%; min-width: 0; }
  .lg-ver { min-height: 44px; }
  .lg-tel { display: inline-flex; align-items: center; min-height: 44px; }

  /* Tarjeta abierta: el orden de sus partes (encabezado, detalle compacto, aviso de impreso viejo, acciones). El detalle ordena sus propias
     columnas (papeles primero: ver .dc__col--pap). */
  .lg-tarj { display: flex; flex-direction: column; }
  .lg-tarj > .lg-tl { order: 2; }
  .lg-tarj__env { order: 5; }
  .lg-tarj__acc { order: 6; }
  /* Stock: la tabla es ancha a propósito; el contenedor desliza y el renglón no se corta. */
  .st-tabla--saldos { min-width: 740px; }
  .st-tabla--movs { min-width: 860px; }
}

/* ================================================================
   Escritorio HD y Full HD — ver DESIGN.md "Escritorio".
   Los monitores del depósito y de ventas van de 1280x720 / 1366x768 (19-20") a
   1920x1080 (23-24"). Dos ejes, cada uno con su regla:
   - ALTO: `(min-width: 861px) and (max-height: 800px)` es el escritorio BAJO
     (1366x768 y 1280x720 dejan 635-683 px de ventana). Ahí la cabecera de cada
     pantalla se compacta para que la lista empiece antes. 1600x900 (815) y
     1920x1080 (995) no entran: tienen alto de sobra.
   - ANCHO: lo decide el contenedor (`@container`) o los cortes ya declarados
     (1100, 1600). Sin cambiar ningún corte del celular (640 / 860).
   ================================================================ */

/* Logística: los enlaces ("guías para revisar", "nuevos", "retenidos") comparten
   renglón también en escritorio (`.lg-links`, arriba). Antes eran tres bloques de
   44 px apilados (`display: contents`): 148 px de cabecera para tres líneas. */

@media (min-width: 861px) and (max-height: 800px) {
  .ob-view { padding-top: 14px; }
  /* Fichas de etapa (Logística) y de Stock: número a la izquierda, rótulo y detalle
     a la derecha. Misma información, la mitad de alto (82 -> 48 px). */
  .lg-kpis, .st-chips { margin-bottom: 10px; }
  .lg-kpis .ob-chipfiltro--kpi, .st-chips .ob-chipfiltro--kpi {
    display: grid; grid-template-columns: auto minmax(0, 1fr); grid-template-areas: "n l" "n d";
    column-gap: 12px; align-items: center; padding: 7px 14px;
  }
  .lg-kpis .ob-chipfiltro__count, .st-chips .ob-chipfiltro__count { grid-area: n; margin-top: 0; line-height: 1.1; }
  .lg-kpis .ob-chipfiltro__label, .st-chips .ob-chipfiltro__label { grid-area: l; }
  .lg-kpis .ob-chipfiltro__detalle, .st-chips .ob-chipfiltro__detalle { grid-area: d; margin-top: 0; }
}

/* Logística, cabecera de escritorio: pestañas y acciones de la cola (↻ Actualizar)
   en el MISMO renglón; buscador y filtros en el de abajo. Antes
   eran tres renglones a 1366 px (pestañas / filtros / acciones sueltas). La barra se
   disuelve (`display: contents`) para que sus hijos se ordenen junto a las pestañas;
   en el celular `.lg-cab` es un bloque y `.lg-barra` sigue siendo la caja plegable. */
@media (min-width: 641px) {
  .lg-cab { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-bottom: 16px; }
  .lg-cab > .lg-barra { display: contents; }
  .lg-cab .lg-subtabs, .lg-cab .lg-desp-mes { margin-bottom: 0; }
  /* Las pestañas reservan todo el renglón menos el lugar de las dos acciones
     (~290 px): así el buscador no sube a este renglón y cae al de abajo. */
  .lg-cab .lg-subtabs { order: 1; flex: 1 0 calc(100% - 300px); }
  /* Vista (Tarjetas | Lista) y Actualizar quedan junto a las pestañas. */
  .lg-cab #lg-refresh, .lg-cab #lg-vista-wrap { order: 2; }
  /* Una pestaña no parte su rótulo: si no entran con las acciones (tablet), las
     acciones bajan de renglón. */
  .lg-cab .lg-subtab { white-space: nowrap; }
  .lg-cab .lg-desp-mes { order: 4; }
  .lg-cab .lg-barra > * { order: 5; }
}

/* Logística, menos cromo antes del primer pedido (i126 v2): la tira de etapas en UNA línea por ficha (número + rótulo,
   ~40 px en vez de ~80) y los enlaces ("guías", "nuevos", "retenidos") dentro de la fila de filtros, junto con
   ↻ Actualizar. El detalle de cada ficha (p. ej. "7 sin coordinar") queda en su tooltip bajo 1600 px. */
@media (min-width: 641px) {
  .lg-kpis { gap: 8px; margin-bottom: 8px; }
  .lg-kpis .ob-chipfiltro--kpi { display: flex; align-items: baseline; gap: 8px; flex-wrap: nowrap; min-width: 0; min-height: 40px; padding: 5px 12px; overflow: hidden; }
  .lg-kpis .ob-chipfiltro__count { order: -1; margin: 0; font-size: 24px; line-height: 1.2; }
  .lg-kpis .ob-chipfiltro__label { font-size: 12px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .lg-kpis .ob-chipfiltro__detalle { margin: 0; font-size: 12px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .lg-links { flex: 0 1 auto; align-items: center; column-gap: 10px; }
  .lg-cab { --lg-q-min: 150px; --lg-q-basis: 150px; gap: 8px; margin-bottom: 8px; }
  #lg-total { margin-bottom: 4px !important; }
  .lg-kpis { margin-bottom: 6px; }
  .lg-f--canal { flex: 0 1 160px; min-width: 140px; }
  .lg-f--rango { flex: 0 1 140px; min-width: 125px; }
  .lg-barra { margin-bottom: 0; }
}
@media (min-width: 641px) and (max-width: 1599px) { .lg-kpis .ob-chipfiltro__detalle { display: none; } }

/* Celular: las 4 fichas de etapa en 2x2, sin deslizar (antes se veían 2 de 4). */
@media (max-width: 640px) {
  .lg-kpis { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; overflow: visible; padding-bottom: 0; }
  .lg-kpis > * { flex: none; min-width: 0; }
  .lg-kpis .ob-chipfiltro--kpi { display: flex; align-items: center; gap: 8px; flex-wrap: nowrap; min-height: 44px; padding: 6px 10px; }
  /* Los enlaces bajan a su propio renglon: si no, aplastan el buscador. */
  .lg-links { flex: 1 1 100%; order: 3; }
  .lg-kpis .ob-chipfiltro__count { order: -1; margin: 0; font-size: 24px; line-height: 1.2; }
  .lg-kpis .ob-chipfiltro__label { font-size: 12px; }
  .lg-kpis .ob-chipfiltro__detalle { display: none; }
}


/* Depósito (escáner): una columna de 640 px centrada, como siempre. Desde 1100 px
   (el corte de dos paneles que ya usa Verificar pagos) los últimos movimientos y la
   carga inicial pasan a la derecha del escáner: lo que se acaba de escanear se ve
   sin scrollear, también a 1366x768. */
.dp-grid { max-width: 640px; margin: 0 auto; }
.dp-hist { margin-top: 18px; }
@media (min-width: 1100px) {
  .dp-grid {
    max-width: 1280px; display: grid; gap: 24px; align-items: start;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  }
  .dp-hist { margin-top: 0; }
}

/* Cobros. Hasta 1600 px, el mismo tope de 1120 px de `.ob-split`, ahora también para
   las tarjetas de arriba (antes iban a todo el ancho y no alineaban con la lista).
   Desde 1600 px (1600x900 y Full HD) el tope sube a 1480 px y el panel de detalle
   gana ancho para el comprobante. Desde 1100 px el panel queda a la vista mientras
   se recorre la lista (pegado arriba, con su propio scroll si es más alto que la
   ventana): antes, elegir un pago de la mitad de la lista dejaba el detalle arriba,
   fuera de pantalla. Los "Comprobantes esperados" van en dos columnas. */
.cb { max-width: 1120px; margin: 0 auto; }
@media (min-width: 1100px) {
  .cb-esp-lista { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .cb-esp-lista > .c-esp:nth-child(odd) { border-right: 1px solid var(--ob-border); }
}
/* El panel de detalle solo queda fijo cuando ya esta al lado de la lista. Con la barra
   lateral de 220 px, `.ob-split` recien deja de envolver cerca de los 1150 px de ventana;
   entre 1100 y 1149 el aside cae debajo de la lista y un sticky ahi solo agrega un scroll
   anidado al final de la pagina. */
@media (min-width: 1150px) {
  .cb .ob-split__aside { position: sticky; top: 0; max-height: calc(100vh - 92px); overflow-y: auto; }
}
@media (min-width: 1600px) {
  .cb { max-width: 1480px; }
  .cb .ob-split { max-width: none; }
  .cb .ob-split__aside { flex-basis: 460px; max-width: 520px; }
}

/* ============================================================
   FILA DE PEDIDO COMPARTIDA (.fp-*) — Mis pedidos (Cabina) y la Lista de Logistica.
   Modulo: js/filaPedido.js. Una palabra de estado, una accion primaria, el resto en ⋯.
   Piso de texto 11px; objetivos tactiles de 44px en celular. La fila NO recorta (overflow
   visible) para que el menu ⋯ salga de ella; `.fp-card` hace lo mismo con la tarjeta que la contiene.
   ============================================================ */
.fp-card { overflow: visible; }
.fp-card > .ob-card__head { border-radius: var(--ob-r-card) var(--ob-r-card) 0 0; }
.fp-card > .mp-item:last-child > .fp-fila { border-radius: 0 0 var(--ob-r-card) var(--ob-r-card); }
.fp-fila.ob-card, .ob-card.lg-tarj { overflow: visible; }

.fp-fila {
  display: grid; grid-template-columns: minmax(0, 1fr) 190px 96px 252px;
  align-items: center; column-gap: 12px; padding: 7px 14px 7px 16px; min-height: 52px; cursor: pointer; position: relative;
}
.fp-fila--lg { grid-template-columns: minmax(0, 1fr) 220px 150px 280px; }
.fp-fila:hover { background: var(--ob-surface-2); }
.fp-main { min-width: 0; }
.fp-l1 { font-family: var(--ob-font-head); font-weight: 700; font-size: 12.5px; color: var(--ob-ink); display: flex; align-items: baseline; gap: 6px; white-space: nowrap; overflow: hidden; }
.fp-l1 .fp-cli { flex: 0 1 auto; max-width: 62%; overflow: hidden; text-overflow: ellipsis; }
.fp-l1 .fp-num { color: var(--ob-navy); font-weight: 800; flex: none; }
.fp-l1 .fp-prod { font-family: var(--ob-font-body); font-weight: 400; font-size: 12px; color: var(--ob-muted); min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.fp-l1 .fp-prod::before { content: '·'; margin-right: 6px; color: var(--ob-border-2); }
.fp-l2 { font-size: 11.5px; color: var(--ob-muted); display: flex; align-items: center; gap: 6px; flex-wrap: wrap; margin-top: 2px; }
.fp-l2 .mp-chat { font-size: 11px; }

/* estado dominante: UNA palabra + su detalle */
.fp-estado { display: flex; flex-direction: column; align-items: flex-end; gap: 2px; min-width: 0; }
.fp-fila--lg .fp-estado { align-items: flex-start; }
.fp-palabra { font-family: var(--ob-font-head); font-weight: 800; font-size: 11.5px; padding: 3px 9px; border-radius: 6px; white-space: nowrap; }
/* El detalle lleva la plata y el plazo: envuelve hasta dos renglones antes de cortarse, nunca a mitad del monto. */
.fp-det { font-size: 11.5px; color: var(--ob-muted); display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; max-width: 100%; }
.fp-palabra--ok     { background: var(--ob-ok-bg);     color: var(--ob-ok); }
.fp-palabra--warn   { background: var(--ob-warn-bg);   color: var(--ob-warn); }
.fp-palabra--danger { background: var(--ob-danger-bg); color: var(--ob-danger); }
.fp-palabra--info   { background: var(--ob-info-bg);   color: var(--ob-info); }
.fp-palabra--navy   { background: var(--ob-navy-tint); color: var(--ob-navy); }
.fp-palabra--muted  { background: var(--ob-bg);        color: var(--ob-muted); }

.fp-monto { font-family: var(--ob-font-head); font-weight: 800; font-size: 13px; text-align: right; white-space: nowrap; color: var(--ob-ink); }
.fp-meta { font-size: 11.5px; color: var(--ob-muted); display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.fp-meta b { color: var(--ob-ink); font-weight: 700; font-family: var(--ob-font-head); }

/* acciones: [primaria] [⋯] [▼] */
.fp-acc { display: flex; align-items: center; justify-content: flex-end; gap: 6px; min-width: 0; }
/* 44px a cualquier ancho: Mis pedidos es pantalla de mostrador (PRODUCT.md, regla dura 8). */
.fp-acc .ob-btn { min-height: 44px; padding: 0 13px; font-size: 12px; white-space: nowrap; }
.fp-ver { width: 44px; height: 44px; border: 0; background: transparent; border-radius: 8px; color: var(--ob-navy); font-size: 12px; cursor: pointer; }
.fp-ver:hover { background: var(--ob-bg); }
.fp-menu { position: relative; }
.fp-menu > summary { list-style: none; width: 44px; height: 44px; display: inline-flex; align-items: center; justify-content: center; border-radius: 8px; border: 1px solid var(--ob-field-border); background: #fff; color: var(--ob-navy); font-weight: 800; font-size: 16px; cursor: pointer; user-select: none; }
.fp-menu > summary::-webkit-details-marker { display: none; }
.fp-menu[open] > summary { background: var(--ob-navy); color: #fff; border-color: var(--ob-navy); }
.fp-menu__lista { position: absolute; right: 0; top: calc(100% + 4px); z-index: 20; min-width: 220px; background: #fff; border: 1px solid var(--ob-border-2); border-radius: 10px; box-shadow: 0 6px 18px rgba(23, 34, 48, .12); padding: 4px; display: flex; flex-direction: column; }
.fp-menu__lista .fp-mi, .fp-menu__lista a { display: flex; align-items: center; gap: 9px; min-height: 44px; padding: 0 12px; border: 0; background: transparent; border-radius: 7px; font-family: var(--ob-font-head); font-weight: 700; font-size: 12.5px; color: var(--ob-ink); text-align: left; cursor: pointer; text-decoration: none; white-space: nowrap; }
.fp-menu__lista .fp-mi:hover, .fp-menu__lista a:hover { background: var(--ob-bg); }
.fp-menu__lista .fp-mi[disabled] { opacity: .5; cursor: default; }
.fp-menu__lista .peligro { color: var(--ob-danger); }
/* Mis pedidos: cotizaciones y alertas llevan las acciones pegadas a la izquierda / derecha de su propia grilla */
.mp-cot .fp-acc { justify-content: flex-start; }
/* tarjeta de Logistica: se opera de pie, 44px de alto */
.lg-tarj__acc .fp-acc .ob-btn { min-height: 44px; }
.lg-tarj__acc .fp-menu > summary, .lg-tarj__acc .fp-ver { width: 44px; height: 44px; }
.fp-menu__lista .ico { width: 18px; text-align: center; flex: none; }

/* stepper comun: <ol> con una columna por paso (--pasos) */
.fp-tl { list-style: none; margin: 10px 0 2px; padding: 0; grid-template-columns: repeat(var(--pasos, 5), 1fr); }
.fp-tl::before { left: calc(50% / var(--pasos, 5)); right: calc(50% / var(--pasos, 5)); }
.fp-tl .ob-tl__etiqueta { font-size: 11px; }
.fp-tl .ob-tl__punto--sosp::before { background: var(--ob-warn-dot); border-color: var(--ob-warn-dot); }
.fp-tl .ob-tl__punto--sosp .ob-tl__etiqueta { color: var(--ob-warn); }
.fp-tl .ob-tl__punto--term::before { background: var(--ob-muted); border-color: var(--ob-muted); }
.fp-tl .ob-tl__punto--term .ob-tl__etiqueta, .fp-tl .ob-tl__punto--term .ob-tl__hora { color: var(--ob-ink); }
.fp-sosp { display: inline-flex; align-items: center; gap: 5px; margin-top: 8px; font-size: 11.5px; color: var(--ob-warn); font-family: var(--ob-font-head); font-weight: 700; background: var(--ob-warn-bg); padding: 4px 9px; border-radius: 6px; }

/* puntitos de la fila compacta (lo que era miniTimelineHTML) */
.fp-tl-mini { list-style: none; margin: 0; padding: 0; display: inline-flex; gap: 3px; align-items: center; flex: 0 0 auto; }
.fp-tl-mini__p { --c: var(--ob-border-2); width: 7px; height: 7px; border-radius: 50%; display: inline-block; border: 1.5px solid var(--c); background: transparent; }
.fp-tl-mini__p--hecho { --c: var(--ob-ok); background: var(--c); }
.fp-tl-mini__p--actual { --c: var(--ob-warn); background: var(--c); }
.fp-tl-mini__p--vencido { --c: var(--ob-danger); background: var(--c); }
.fp-tl-mini__p--sosp { --c: var(--ob-warn-dot); background: var(--c); }
.fp-tl-mini__p--term { --c: var(--ob-muted); background: var(--c); }

@media (max-width: 1180px) {
  .fp-fila, .fp-fila--lg { grid-template-columns: minmax(0, 1fr) auto; row-gap: 6px; padding: 9px 12px; }
  .fp-main { grid-column: 1 / -1; }
  .fp-estado { grid-column: 1; grid-row: 2; align-items: flex-start; }
  .fp-monto, .fp-meta { grid-column: 2; grid-row: 2; text-align: right; align-items: flex-end; }
  .fp-acc { grid-column: 1 / -1; justify-content: flex-start; flex-wrap: wrap; }
}
@media (max-width: 640px) {
  .fp-acc .ob-btn, .fp-menu > summary, .fp-ver { min-height: 44px; height: 44px; }
  /* acciones en UNA linea: los botones con texto se achican para que el ▼ no caiga solo a otra */
  .fp-acc { flex-wrap: nowrap; }
  .fp-acc .ob-btn { flex: 0 1 auto; min-width: 0; padding: 0 9px; white-space: normal; line-height: 1.15; }
  .fp-menu, .fp-ver { flex: none; }
  /* Logistica: estado y meta cada uno a todo el ancho (no compartir renglon) */
  .fp-fila--lg .fp-estado { grid-column: 1 / -1; grid-row: 2; }
  .fp-fila--lg .fp-meta { grid-column: 1 / -1; grid-row: 3; text-align: left; align-items: flex-start; }
  /* stepper: las fechas pueden partirse en dos renglones; en nowrap se pisaban con la columna vecina */
  .fp-tl .ob-tl__punto { min-width: 0; }
  .fp-tl .ob-tl__fecha, .fp-tl .ob-tl__hh { white-space: normal; word-break: normal; overflow-wrap: break-word; }
  .fp-menu > summary { width: 44px; }
  .fp-ver { width: 44px; }
  .fp-l1 { white-space: normal; flex-wrap: wrap; }
  .fp-l1 .fp-cli { max-width: 100%; }
  .fp-det { white-space: normal; }
  .fp-l1 .fp-prod { flex-basis: 100%; }
  .fp-l1 .fp-prod::before { content: none; }
  .fp-menu { position: static; }
  .fp-menu__lista { left: 8px; right: 8px; top: calc(100% + 2px); min-width: 0; }
  .mp-alerta, .mp-cot, .lg-tarj__acc { position: relative; }
  .fp-tl .ob-tl__detalle { display: none; }
}

/* ============================================================
   Logística · modo trabajo (tanda 2) y modo pared
   "Una pantalla para hacer, una vista para ver." Modo trabajo: UN carril por vez, a todo el ancho, filas de una línea
   (js/views/logistica.js + js/filaPedido.js + js/logisticaTrabajo.js). Modo pared: el MISMO modo trabajo en tres columnas,
   tipografía grande (clase .lgt--pared en la vista; su bloque está más abajo). Solo tokens --ob-*; sin sombra en reposo.
   ============================================================ */
.lgt { --lgt-top: -22px; --lgt-carril-h: 56px; --lgt-tabs-h: 42px; display: flex; flex-direction: column; gap: 8px; min-width: 0; }
/* -22 px = el padding-top de .ob-view: un sticky mide desde el borde del CONTENIDO, no del area de scroll (ver i126). */
@media (max-width: 860px) { .lgt { --lgt-top: -14px; } }
@media (min-width: 861px) and (max-height: 800px) { .lgt { --lgt-top: -14px; gap: 6px; } }
.lgt[hidden], .lgt [hidden] { display: none !important; }
.lgt-sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.lgt-parcial { padding: 9px 12px; border-radius: 9px; border: 1px solid var(--ob-warn); background: var(--ob-warn-bg); color: var(--ob-ink); font-size: 12.5px; font-weight: 600; }
/* El resultado de una operacion (ok / parcial / error) flota abajo: arriba se perdia en cuanto la lista scrolleaba. */
.lgt-msg { position: fixed; left: 50%; bottom: 18px; transform: translateX(-50%); z-index: 65; width: max-content; max-width: min(720px, calc(100vw - 24px)); padding: 10px 16px; border-radius: 12px; background: var(--ob-surface); border: 1px solid var(--ob-border-2); font-family: var(--ob-font-head); font-weight: 700; font-size: 12.5px; }

/* ---------- franja "Mirar primero" ---------- */
.lgt-exc { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; min-height: 36px; }
.lgt-exc__lbl { font: 700 11px var(--ob-font-head); letter-spacing: .04em; text-transform: uppercase; color: var(--ob-muted); margin-right: 4px; }
.lgt-exc__ok { color: var(--ob-ok); font-weight: 700; font-size: 12.5px; }
/* El boton que pliega/despliega la franja: ahora en TODOS los anchos (critique 2026-10-21 — antes solo en celular,
   y en escritorio la fila de chips le comia alto a la cola en cada carga). Misma cara que un chip de filtro. */
.lgt-exc__toggle { display: inline-flex; min-height: 32px; align-items: center; gap: 7px; padding: 0 12px; border: 1px solid var(--ob-danger-border); background: var(--ob-danger-bg); color: var(--ob-danger); border-radius: var(--ob-r-pill); font: 700 12.5px var(--ob-font); cursor: pointer; }
.lgt-exc__toggle b { font: 800 14px var(--ob-font-head); }
.lgt-exc__flecha { margin-left: 2px; font-size: 10px; }
.lgt-exc__toggle[aria-expanded="true"] .lgt-exc__flecha { transform: rotate(180deg); }
/* Plegada, la franja es SOLO el boton: chips, visto bueno y rotulo se esconden (vale para todos los anchos). */
.lgt-exc[data-plegada="true"] > .ob-chipfiltro, .lgt-exc[data-plegada="true"] > .lgt-exc__ok, .lgt-exc[data-plegada="true"] > .lgt-exc__lbl { display: none; }
.lgt-exc .ob-chipfiltro--pill { min-height: 32px; padding: 0 12px; font-size: 12.5px; white-space: nowrap; }
.lgt-exc .ob-chipfiltro--pill::before { inset: 2px 0; }
.lgt-exc [data-tono]:not(.is-active) { color: var(--ob-chipfiltro-tono, var(--ob-muted)); }
.lgt-exc [data-tono="danger"]:not(.is-active)::before { background: var(--ob-danger-bg); border-color: var(--ob-danger-border); }
.lgt-exc [data-tono="warn"]:not(.is-active)::before { background: var(--ob-warn-bg); border-color: var(--ob-warn-border); }
/* controles de la vista, en la barra superior del shell (a la izquierda del indicador de conexion) */
.lgt-top-ctl { margin-left: auto; display: flex; align-items: center; gap: 8px; flex: 0 0 auto; }
.lgt-top-ctl ~ .ob-apibadge { margin-left: 0; }
.lgt-icono, .lgt-pantalla { position: relative; height: 36px; min-width: 36px; padding: 0 10px; border: 1px solid var(--ob-border-2); background: var(--ob-surface); border-radius: 10px; color: var(--ob-navy); font: 700 12.5px var(--ob-font-head); display: inline-flex; align-items: center; justify-content: center; gap: 6px; cursor: pointer; white-space: nowrap; }
.lgt-icono[aria-expanded="true"] { background: var(--ob-celeste-marca); border-color: var(--ob-navy); }
.lgt-icono__n { background: var(--ob-navy); color: var(--ob-surface); border-radius: var(--ob-r-pill); min-width: 18px; height: 18px; padding: 0 5px; display: inline-grid; place-items: center; font-size: 11px; }
/* ---- Iconos SVG de la cabina (icons.js) ----
   El SVG nace a 1em (acompaña el font-size de su chip/boton); aca solo los
   contenedores que piden tamano fijo o caja flex. Color: siempre currentColor. */
.lgt-btn__ico svg { width: 15px; height: 15px; display: block; }
.fp-mi .ico, .fp-sosp__ico, .dc__ico, .ob-modal__ico { display: inline-flex; align-items: center; flex: none; }
.fp-mi .ico svg, .ob-modal__ico svg { width: 15px; height: 15px; }
.fp-sosp__ico svg, .dc__ico svg { width: 13px; height: 13px; }
.lgt-icono > svg, .lgt-pantalla > svg { width: 15px; height: 15px; }
.lgt-exc__toggle-ico { display: inline-flex; align-items: center; }
.lgt-exc__toggle-ico svg { width: 14px; height: 14px; }
.lgt-tag__ico, .ob-chip__ico, .ob-chipfiltro__ico { display: inline-flex; align-items: center; margin-right: 1px; }
.lgt-f__est-ico { display: inline-flex; align-items: center; }
.lgt-pared__tit svg, .lgt-pared__ico svg { width: 1em; height: 1em; }
.lgt-sig__btn svg { width: 13px; height: 13px; }
.lgt-buscar .ob-field { width: 100%; }
.lgt-filtros { background: var(--ob-surface); border: 1px solid var(--ob-border); border-radius: 12px; padding: 10px 12px; display: flex; flex-direction: column; gap: 8px; }
.lgt-filtros__fila { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 10px; }
.lgt-campo { display: flex; flex-direction: column; gap: 3px; font-size: 11px; color: var(--ob-muted); font-weight: 700; min-width: 0; }
.lgt-campo .ob-field { min-width: 160px; }
.lgt-alq { min-height: 36px; background: var(--ob-surface); color: var(--ob-navy); border: 1px solid var(--ob-field-border); }
.lgt-alq[aria-pressed="true"] { background: var(--ob-navy); color: var(--ob-surface); border-color: var(--ob-navy); }
/* i217: selector de papel del rotulo, junto a los lotes */
.lgt-papel { display: inline-flex; align-items: center; gap: 6px; margin-left: auto; }
.lgt-papel__tit { font: 700 12px var(--ob-font-head); color: var(--ob-muted); }
.lgt-vista { display: flex; gap: 3px; border: 1px solid var(--ob-field-border); border-radius: 9px; padding: 3px; background: var(--ob-surface); }
.lgt-vista button { min-height: 30px; padding: 4px 11px; font: 700 11.5px var(--ob-font-head); border: 0; border-radius: 6px; background: transparent; color: var(--ob-ink); cursor: pointer; }
.lgt-vista button[aria-pressed="true"] { background: var(--ob-navy); color: var(--ob-surface); }
.lgt-linkbtn { background: none; border: 0; padding: 0 4px; min-height: 36px; font: inherit; font-size: 12.5px; color: var(--ob-muted); text-decoration: underline; cursor: pointer; }
.lgt-linkbtn[aria-pressed="true"] { text-decoration: none; font-weight: 700; }
.lgt-entregados-cab { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; }
.lgt-entregados-cab__tit { margin: 0; font: 800 18px var(--ob-font-head); color: var(--ob-ink); }
.lgt-volver { background: var(--ob-surface); color: var(--ob-navy); border: 1px solid var(--ob-field-border); min-height: 36px; }
.lgt-campo--mes { margin-left: auto; }

/* ---------- pestañas de la cabina: Para despachar | Entregados ----------
   Fijas arriba de los carriles, pegadas al scroll como el resto de la pila (su alto es fijo: no se mide en JS como --lgt-exc-h).
   Misma lectura que los carriles: navy = la seccion que estas viendo; el numero de Entregados es el de HOY (el historial completo
   se navega por mes adentro de la pestaña). */
.lgt-tabs { display: flex; gap: 6px; position: sticky; top: var(--lgt-top); z-index: 4; background: var(--ob-bg); padding: 2px 0 6px; }
.lgt-tabs button { min-height: 34px; padding: 4px 14px; border: 1px solid var(--ob-border-2); border-radius: 10px; background: var(--ob-surface); color: var(--ob-navy); font: 800 13px var(--ob-font-head); cursor: pointer; display: inline-flex; align-items: center; gap: 7px; }
.lgt-tabs button small { font: 600 11.5px var(--ob-font); color: var(--ob-muted); }
.lgt-tabs button[aria-pressed="true"] { background: var(--ob-navy); border-color: var(--ob-navy); color: var(--ob-surface); }
.lgt-tabs button[aria-pressed="true"] small { color: var(--ob-side-ink); }

/* ---------- los tres botones de carril: siempre a la vista, pegados al scroll ---------- */
.lgt-carriles { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; position: sticky; top: calc(var(--lgt-top) + var(--lgt-tabs-h)); z-index: 4; background: var(--ob-bg); padding: 2px 0 6px; }
.lgt-carril { position: relative; height: 48px; border: 1px solid var(--ob-border-2); background: var(--ob-surface); border-radius: 10px; display: flex; align-items: center; justify-content: center; gap: 10px; font: 800 15px var(--ob-font-head); color: var(--ob-navy); cursor: pointer; min-width: 0; padding: 0 10px; }
.lgt-carril__n { font: 800 22px var(--ob-font-head); }
.lgt-carril small { font: 600 12px var(--ob-font); color: var(--ob-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.lgt-carril[aria-pressed="true"] { background: var(--ob-navy); border-color: var(--ob-navy); color: var(--ob-surface); }
.lgt-carril[aria-pressed="true"] small { color: var(--ob-side-ink); }
.lgt-rojo { background: var(--ob-danger); color: var(--ob-surface); border-radius: var(--ob-r-pill); min-width: 22px; height: 22px; padding: 0 7px; display: inline-grid; place-items: center; font: 800 12px var(--ob-font-head); }
@media (min-width: 861px) and (max-width: 1099px) { .lgt-carril small { display: none; } }

/* ---------- barra del carril: los botones de lote (Imprimir y Despachar a la vez si los dos aplican) ---------- */
.lgt-barra { position: sticky; top: calc(var(--lgt-top) + var(--lgt-tabs-h) + var(--lgt-carril-h)); z-index: 3; background: var(--ob-bg); padding-bottom: 4px; }
.lgt-sig { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; background: var(--ob-surface); border: 1px solid var(--ob-border); border-radius: 12px; padding: 6px 12px; min-height: 48px; }
.lgt-sig__acc { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; }
.lgt-sig__btn { min-height: 36px; border: 0; border-radius: 10px; padding: 0 16px; background: var(--ob-navy); color: var(--ob-surface); font: 800 13px var(--ob-font-head); display: inline-flex; align-items: center; justify-content: center; gap: 8px; white-space: nowrap; cursor: pointer; }
.lgt-sig__btn--ok { background: var(--ob-verde-accion); }
.lgt-sig__sec { min-height: 36px; border: 1px solid var(--ob-border-2); border-radius: 10px; padding: 0 12px; background: var(--ob-surface); color: var(--ob-navy); font: 700 12.5px var(--ob-font-head); white-space: nowrap; cursor: pointer; }
.lgt-sig__ask { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; }
.lgt-sig__pregunta { font-size: 12.5px; color: var(--ob-ink); font-weight: 600; }
.lgt-sig__nada { font-size: 12.5px; color: var(--ob-muted); }
/* Subtitulo dentro de un grupo (Por armar: Atrasados / De hoy): parte la lista, no pliega. */
.lgt-sub { margin: 0; padding: 6px 12px 4px; border-top: 1px solid var(--ob-border); font: 700 11px var(--ob-font-head); letter-spacing: .04em; text-transform: uppercase; color: var(--ob-muted); }
.lgt-sub b { font: 800 12px var(--ob-font-head); color: var(--ob-ink); }
.lgt-sub--danger, .lgt-sub--danger b { color: var(--ob-danger); }
.lgt-grp__cuerpo > .lgt-sub:first-child { border-top: 0; }

/* ---------- grupos por etapa y filas de UNA linea ---------- */
.lgt-grp { background: var(--ob-surface); border: 1px solid var(--ob-border); border-radius: 12px; margin-bottom: 10px; }
.lgt-grp__tit { margin: 0; }
.lgt-grp__cab { width: 100%; display: flex; align-items: center; gap: 8px; padding: 0 12px; min-height: 32px; background: var(--ob-surface-2); border: 0; border-radius: 11px 11px 0 0; text-align: left; font: 700 11px var(--ob-font-head); letter-spacing: .04em; text-transform: uppercase; color: var(--ob-muted); cursor: pointer; }
.lgt-grp__cab b { font: 800 12px var(--ob-font-head); color: var(--ob-ink); }
.lgt-grp__flecha { margin-left: auto; font-size: 11px; transition: transform .15s; }
.lgt-grp[data-abierto="false"] .lgt-grp__cab { border-radius: 11px; }
.lgt-grp[data-abierto="false"] .lgt-grp__flecha { transform: rotate(-90deg); }
.lgt-grp--ok .lgt-grp__cab { color: var(--ob-ok); }
.lgt-grp--info .lgt-grp__cab { color: var(--ob-info); }
.lgt-grp--muted .lgt-f { background: var(--ob-surface-2); }
.lgt-grp__cuerpo > :first-child { border-top: 0; }
.lgt-vacio { padding: 22px 10px; font-size: 13px; }

.lgt-f { display: grid; grid-template-columns: 18px 64px minmax(150px, 1.1fr) minmax(0, 1.3fr) auto minmax(190px, 1.2fr) 84px auto; gap: 0 10px; align-items: center; min-height: 36px; padding: 0 8px 0 10px; border-top: 1px solid var(--ob-border); font-size: 12.5px; position: relative; cursor: pointer; }
.lgt-f:hover { background: var(--ob-surface-2); }
.lgt-f--danger::before, .lgt-f--warn::before { content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 3px; }
.lgt-f--danger::before { background: var(--ob-danger-dot); }
.lgt-f--warn::before { background: var(--ob-warn-dot); }
.lgt-f__dot { color: var(--ob-info); font-size: 11px; text-align: center; }
.lgt-f__n { font: 800 12px var(--ob-font-head); color: var(--ob-navy); white-space: nowrap; }
.lgt-f__cli { display: flex; align-items: baseline; gap: 6px; min-width: 0; }
.lgt-f__hora { font: 800 14px var(--ob-font-head); color: var(--ob-info); flex: none; }
.lgt-f__abrir { background: none; border: 0; padding: 0; font: 700 13px var(--ob-font); color: var(--ob-ink); text-align: left; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; cursor: pointer; }
.lgt-f__prod { color: var(--ob-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
/* SKU del primer producto delante del nombre (mismo chip que Mis pedidos) */
.lgt-sku { margin-right: 4px; vertical-align: 1px; }
.lgt-f__tags { display: flex; gap: 4px; align-items: center; }
.lgt-f__est { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-weight: 700; min-width: 0; }
.lgt-f__est small { font-weight: 400; color: var(--ob-muted); font-size: inherit; }
.lgt-f__est--danger { color: var(--ob-danger); }
.lgt-f__est--warn { color: var(--ob-warn); }
.lgt-f__est--ok { color: var(--ob-ok); }
.lgt-f__est--info { color: var(--ob-info); }
.lgt-f__est--navy { color: var(--ob-navy); }
.lgt-f__est--muted { color: var(--ob-muted); }
.lgt-f__cuando { color: var(--ob-muted); font-size: 11.5px; white-space: nowrap; text-align: right; }
.lgt-f__acc { display: flex; justify-content: flex-end; }
.lgt-f .fp-acc { gap: 4px; }
.lgt-f .fp-menu > summary { width: 32px; height: 32px; border-radius: 9px; }
.lgt-tag { display: inline-flex; align-items: center; height: 18px; padding: 0 6px; border-radius: 6px; font: 800 11px var(--ob-font-head); letter-spacing: .02em; white-space: nowrap; }
.lgt-tag--zona { background: var(--ob-sku-bg); color: var(--ob-navy); border: 1px solid var(--ob-sku-border); }
.lgt-tag--alq { background: var(--ob-info-bg); color: var(--ob-info); border: 1px solid var(--ob-info-border); }
.lgt-tag--web { background: var(--ob-surface-2); color: var(--ob-muted); border: 1px solid var(--ob-border-2); font-weight: 700; }
.lgt-tag--mostrador { background: var(--ob-info-bg); color: var(--ob-info); }
.lgt-tag--otra { background: var(--ob-surface-2); color: var(--ob-muted); border: 1px solid var(--ob-border-2); }
/* legado: migrar a .ob-btn (i145, T3). Equivale a .ob-btn; --primary = .ob-btn--primary,
   --ok = .ob-btn--ok, --ghost (texto warn) = .ob-btn (outline navy: el naranja no es boton).
   Alto 32 en escritorio (bajo el piso de 37): se corrige en la PR de Logistica. */
.lgt-btn { height: 32px; min-width: 32px; padding: 0 10px; border-radius: 9px; border: 1px solid var(--ob-border-2); background: var(--ob-surface); color: var(--ob-navy); font: 800 11.5px var(--ob-font-head); display: inline-flex; align-items: center; justify-content: center; gap: 5px; white-space: nowrap; cursor: pointer; text-decoration: none; }
.lgt-btn--primary { background: var(--ob-navy); border-color: var(--ob-navy); color: var(--ob-surface); }
.lgt-btn--ok { background: var(--ob-verde-accion); border-color: var(--ob-verde-accion); color: var(--ob-surface); }
.lgt-btn--ghost { color: var(--ob-warn); border-color: var(--ob-ghost-border); }
.lgt-btn[disabled] { opacity: .5; cursor: default; }
.lgt-det { padding: 5px 10px 6px; background: var(--ob-surface-2); border-top: 1px solid var(--ob-border); }
.lgt-det .ob-card { margin-bottom: 0; }
.lgt-espera { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 10px; padding: 8px 12px 10px 28px; background: var(--ob-warn-tint); border-top: 1px solid var(--ob-warn-border); }
.lgt-espera .lgt-campo--nota { flex: 1 1 260px; }
.lgt-espera .lgt-campo--nota .ob-field { width: 100%; }
.lgt-sec { background: var(--ob-surface); color: var(--ob-navy); border: 1px solid var(--ob-field-border); }
.lgt-pie { display: flex; flex-wrap: wrap; gap: 4px 18px; padding: 2px 2px 8px; }
.lgt-link { background: none; border: 0; min-height: 36px; padding: 0; font: 600 13px var(--ob-font); color: var(--ob-link); cursor: pointer; text-align: left; }
.lgt-link[disabled] { color: var(--ob-muted-2); cursor: default; }
/* Lo que salio hace mas que su ventana de seguimiento y nadie cerro: una linea gris al pie del carril */
.lgt-viejos { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 16px; margin-top: 10px; padding: 8px 12px; border-top: 1px solid var(--ob-border); color: var(--ob-muted); font-size: 13px; }
.lgt-viejos__ask { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; color: var(--ob-ink); }

/* escritorio chico: sin la columna del producto (la fila nunca esconde el estado) */
@media (min-width: 861px) and (max-width: 1100px) {
  .lgt-f { grid-template-columns: 18px 64px minmax(140px, 1fr) auto minmax(0, 1.4fr) 84px auto; }
  .lgt-f__prod { display: none; }
}

/* ---------- tablet y celular: filas de 2 a 4 renglones, 14 px de lectura, 16 px el nombre, 44 px tactil ---------- */
@media (max-width: 860px) {
  .lgt-f { grid-template-columns: auto minmax(0, 1fr) auto 44px; grid-template-rows: auto auto auto auto; min-height: 64px; padding: 8px 6px 8px 14px; gap: 2px 8px; font-size: 14px; align-items: start; }
  .lgt-f__dot { display: none; }
  .lgt-f__n { grid-column: 1; grid-row: 1; font-size: 14px; align-self: center; }
  .lgt-f__cli { grid-column: 2; grid-row: 1; align-self: center; }
  .lgt-f__abrir { font-size: 16px; min-height: 44px; }
  .lgt-f__hora { font-size: 17px; }
  .lgt-f__cuando { grid-column: 3; grid-row: 1; font-size: 14px; align-self: center; }
  .lgt-f__est { grid-column: 1 / 4; grid-row: 2; font-size: 14px; white-space: normal; }
  .lgt-f__prod { display: block; grid-column: 1 / 4; grid-row: 3; font-size: 14px; white-space: normal; }
  .lgt-f__tags { grid-column: 1 / 4; grid-row: 4; flex-wrap: wrap; }
  .lgt-f__acc { grid-column: 4; grid-row: 1 / 5; align-self: center; }
  .lgt-f .fp-acc { flex-direction: column; align-items: flex-end; gap: 4px; }
  .lgt-f .fp-menu > summary { width: 44px; height: 44px; }
  .lgt-btn { height: 44px; min-width: 44px; font-size: 14px; }
  .lgt-btn__txt { display: none; }
  .lgt-tag { height: 22px; font-size: 12px; }
  .lgt-grp__cab { min-height: 44px; font-size: 12px; }
  .lgt-grp__cab b { font-size: 14px; }
  .lgt-det { padding: 6px 4px 8px; }
  .lgt-espera { padding-left: 14px; }
  .lgt-link { min-height: 44px; font-size: 14px; }
  .lgt-linkbtn { min-height: 44px; font-size: 14px; }
  .lgt-icono { height: 44px; min-width: 44px; }
  .lgt-pantalla { display: none; }
  .lgt-top-ctl { gap: 6px; }
}
@media (min-width: 861px) { .lgt-btn__txt { display: inline; } }

/* ---------- celular (<= 640): la franja se pliega, los tres botones en una fila, la barra a todo el ancho ---------- */
@media (max-width: 640px) {
  .lgt-exc { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 6px; }
  .lgt-exc__lbl { display: none; }
  .lgt-exc__toggle { grid-column: 1 / -1; min-height: 44px; gap: 8px; padding: 0 14px; font-size: 15px; }
  .lgt-exc__toggle b { font-size: 17px; }
  .lgt-exc__flecha { margin-left: auto; font-size: 12px; }
  .lgt-exc > .ob-chipfiltro, .lgt-exc > .lgt-exc__ok { grid-column: auto; }
  .lgt-exc .ob-chipfiltro--pill { min-height: 44px; font-size: 14px; min-width: 0; overflow: hidden; }
  .lgt-exc .ob-chipfiltro--pill::before { inset: 4px 0; }
  .lgt { --lgt-tabs-h: 52px; }
  /* A 383 px "Entregados 4 hoy · historial" no entra: la pestaña se recortaba y el conteo quedaba afuera.
     El aclarado va al title; en celular queda etiqueta + numero. */
  .lgt-tabs button { min-height: 44px; flex: 1; min-width: 0; padding: 4px 8px; justify-content: center; white-space: nowrap; }
  .lgt-tabs button small { display: none; }
  .lgt-carriles { gap: 6px; }
  .lgt-carril { height: 56px; flex-direction: column; gap: 0; font-size: 14px; padding: 4px 6px; justify-content: center; }
  .lgt-carril__n { font-size: 20px; line-height: 1; }
  .lgt-carril small { display: none; }
  .lgt-carril .lgt-rojo { position: absolute; top: 4px; right: 6px; }
  .lgt-barra { position: static; }
  .lgt-sig { padding: 10px 12px; }
  .lgt-sig__acc { width: 100%; flex-direction: column; align-items: stretch; }
  .lgt-sig__btn { min-height: 44px; font-size: 14px; width: 100%; }
  .lgt-sub { font-size: 12px; padding: 8px 12px 6px; }
  .lgt-sig__sec { min-height: 44px; font-size: 14px; }
  .lgt-sig__ask { width: 100%; }
  .lgt-sig__pregunta { font-size: 14px; flex: 1 1 100%; }
  .lgt-sig__nada { font-size: 14px; }
  .lgt-sig__ask .lgt-sig__btn { width: auto; flex: 1 1 auto; }
  .lgt-filtros .ob-field, .lgt-campo { width: 100%; }
  .lgt-campo { font-size: 13px; }
  .lgt-alq, .lgt-vista button { min-height: 44px; }
  .lgt-volver { min-height: 44px; }
  .lgt-msg { bottom: 10px; }
}

/* ============================================================
   Logística · modo pared interactivo
   La pared NO es otra pantalla: es una DISPOSICION del modo trabajo (clase .lgt--pared en la vista). Las mismas filas, acciones,
   detalle, lote y manejadores, en tres columnas (Envío / Retiro / Despacho) con scroll propio, sin menu lateral ni barra superior.
   Escala en `em` sobre --lgt-fs (13 px; 16.25 px = x1.25 desde 1600 px). Sin `zoom`: corta el alto en Chrome. Objetivo tactil: 40 a 44 px
   (max(40px, 2.6em) = 40 px a 13 px y 42 px a 16.25 px).
   ============================================================ */
.ob-view.lgt--pared { position: fixed; inset: 0; z-index: 60; padding: 0; overflow: hidden; background: var(--ob-bg); }
.lgt--pared .lgt { --lgt-fs: 13px; --lgt-tap: max(40px, 2.6em); height: 100%; gap: .65em; padding: .9em 1.3em .8em; font-size: var(--lgt-fs); color: var(--ob-ink); }
@media (min-width: 1600px) { .lgt--pared .lgt { --lgt-fs: 16.25px; } }
/* tres columnas no entran bajo 1100 px: la pantalla completa no se ofrece (y la pared se cierra sola si la ventana se achica) */
@media (max-width: 1099px) { .lgt-pantalla { display: none; } }

/* cabecera: titulo, volver, buscar, actualizar y el reloj (rojo a los 2 minutos sin datos nuevos) */
.lgt-pared__cab { display: flex; align-items: center; flex-wrap: wrap; gap: .5em 1em; }
.lgt-pared__tit { margin: 0; font: 800 1.7em/1.1 var(--ob-font-head); color: var(--ob-navy); }
.lgt-pared__salir, .lgt-pared__ico { min-height: var(--lgt-tap); border: 1px solid var(--ob-border-2); background: var(--ob-surface); border-radius: .75em; padding: 0 1em; font: 700 1em var(--ob-font-head); color: var(--ob-navy); cursor: pointer; }
.lgt-pared__ico { min-width: max(40px, 2.1em); min-height: max(40px, 2.1em); padding: 0 .5em; font-size: 1.25em; line-height: 1; }
.lgt-pared__ico[aria-expanded="true"] { background: var(--ob-celeste-marca); border-color: var(--ob-navy); }
.lgt-pared__reloj { margin-left: auto; font: 800 2.1em/1 var(--ob-font-head); color: var(--ob-ink); }
.lgt-pared__reloj small { font: 600 .42em var(--ob-font); color: var(--ob-muted); margin-left: .9em; }
.lgt-pared__viejo { color: var(--ob-danger) !important; font-weight: 800 !important; }
.lgt-pared__pie { display: flex; flex-wrap: wrap; justify-content: space-between; gap: .3em 1.4em; color: var(--ob-muted); font-size: .95em; }
.lgt--pared .lgt-buscar .ob-field { min-height: var(--lgt-tap); font-size: 1.1em; }
.lgt--pared .lgt-parcial { font-size: 1em; }
/* el resultado de una accion (ok / parcial / error) tiene que verse desde la pared */
/* El resultado de una accion en la pared: una franja ARRIBA, bajo la cabecera, a ~1.4em, con borde y fondo del semaforo; no tapa filas y
   queda hasta el proximo clic. Un error se ve igual de grande. */
.lgt--pared .lgt-msg { position: static; transform: none; width: auto; max-width: none; padding: .45em .9em; border-radius: .7em; border-left-width: .35em; font-size: 1em; }
.lgt--pared .lgt-msg [style] { font-size: 1.4em !important; } /* aviso.js fija 12.5px en linea */
.lgt--pared .lgt-msg[data-tono="ok"] { background: var(--ob-ok-bg); border-color: var(--ob-ok); }
.lgt--pared .lgt-msg[data-tono="parcial"] { background: var(--ob-warn-bg); border-color: var(--ob-warn); }
.lgt--pared .lgt-msg[data-tono="error"] { background: var(--ob-danger-bg); border-color: var(--ob-danger); }
/* busqueda o filtro que deja las tres columnas vacias */
.lgt-sinres { display: flex; flex-wrap: wrap; align-items: center; gap: .5em 1em; padding: .4em .9em; background: var(--ob-surface); border: 1px solid var(--ob-border-2); border-radius: .7em; font-size: 1.1em; font-weight: 700; color: var(--ob-ink); }
.lgt-sinres .lgt-sig__sec { min-height: var(--lgt-tap); font-size: .9em; }
/* separador del menu de la fila: lo rojo va al final y aparte */
.fp-sep { height: 1px; background: var(--ob-border-2); margin: 4px 6px; }

/* franja "Mirar primero": filtra las TRES columnas a la vez. En la pared los avisos se ven siempre (el tablero
   es para mirar, no para tocar): la vista la fuerza desplegada y el boton de plegado no se ofrece. */
.lgt--pared .lgt-exc { min-height: 0; gap: .45em; }
.lgt--pared .lgt-exc__toggle { display: none; }
.lgt--pared .lgt-exc__lbl { font-size: .85em; }
.lgt--pared .lgt-exc .ob-chipfiltro--pill { min-height: var(--lgt-tap); font-size: 1em; padding: 0 1em; }
.lgt--pared .lgt-exc__ok { font-size: 1em; }
.lgt--pared .lgt-linkbtn, .lgt--pared .lgt-link { font-size: 1em; }

/* las tres columnas: alto de la ventana, cada una con su propio scroll. Una columna vacia no deja espacio muerto: mide lo que su cabecera. */
.lgt-cols { flex: 1 1 auto; min-height: 0; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); grid-template-rows: minmax(0, 1fr); gap: 1em; align-items: start; }
.lgt-col { min-width: 0; max-height: 100%; display: flex; flex-direction: column; overflow: hidden; background: var(--ob-surface); border: 1px solid var(--ob-border); border-top: .4em solid var(--ob-navy); border-radius: 1em; }
.lgt-col--alerta { border-top-color: var(--ob-danger); }
.lgt-col--atenuada { border-top-color: var(--ob-border-2); }
.lgt-col--atenuada .lgt-col__n { color: var(--ob-muted); }
.lgt-col__cab { flex: none; display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: .2em .7em; align-items: center; padding: .65em 1em .6em; border-bottom: 1px solid var(--ob-border); background: var(--ob-surface); }
.lgt-col__tit { margin: 0; font: 800 1.5em/1.1 var(--ob-font-head); color: var(--ob-ink); display: flex; align-items: baseline; flex-wrap: wrap; gap: .1em .4em; }
.lgt-col__tit small { font: 400 .55em var(--ob-font); color: var(--ob-muted); }
.lgt-col__n { font: 800 2.3em/1 var(--ob-font-head); color: var(--ob-navy); }
.lgt-col__des { grid-column: 1 / -1; display: flex; flex-wrap: wrap; gap: .1em 1em; font-size: .95em; color: var(--ob-muted); }
.lgt-col__des:empty { display: none; }
.lgt-col__lote { grid-column: 1 / -1; margin-top: .25em; }
.lgt-col__lote .lgt-sig__acc { width: 100%; flex-direction: column; align-items: stretch; }
.lgt-col__lote .lgt-sig__btn { width: 100%; min-height: var(--lgt-tap); font-size: 1em; }
.lgt-col .lgt-sub { padding: .5em 1em .3em; font-size: .8em; }
.lgt-col__lote .lgt-sig__sec { min-height: var(--lgt-tap); font-size: 1em; }
.lgt-col__lote .lgt-sig__ask { width: 100%; }
.lgt-col__lote .lgt-sig__pregunta { font-size: .95em; flex: 1 1 100%; }
.lgt-col__lote .lgt-sig__ask .lgt-sig__btn { width: auto; flex: 1 1 auto; }
.lgt-col__lote .lgt-sig__nada { font-size: 1em; }
.lgt-col__cuerpo { flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain; }
.lgt-col__vacio { padding: 1em; font-size: 1.05em; color: var(--ob-muted); }
.lgt-col__pie { flex: none; border-top: 1px solid var(--ob-border); background: var(--ob-surface-2); padding: .3em 1em; font-size: .95em; }
.lgt-col__pie .lgt-viejos { margin: 0; padding: .3em 0; border: 0; font-size: 1em; }
.lgt-col__pie .lgt-link { min-height: var(--lgt-tap); font-size: 1em; }
.lgt-col__pie .lgt-sig__btn, .lgt-col__pie .lgt-sig__sec { min-height: var(--lgt-tap); font-size: 1em; }
.lgt-col .lgt-grp { margin: 0; border: 0; border-radius: 0; border-top: 1px solid var(--ob-border); }
.lgt-col .lgt-grp:first-child { border-top: 0; }
.lgt-col .lgt-grp__cab { min-height: var(--lgt-tap); font-size: .85em; border-radius: 0; padding: 0 1em; }
.lgt-col .lgt-grp__cab b { font-size: 1.25em; }
.lgt-col .lgt-grp[data-abierto="false"] .lgt-grp__cab { border-radius: 0; }

/* la fila en una columna: DOS renglones a la izquierda y la accion a la derecha */
.lgt-f--col { display: flex; align-items: center; gap: .5em; min-height: 0; padding: .5em .5em .5em .9em; font-size: 1em; }
.lgt-f__txt { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: .25em; }
.lgt-f__l1 { display: flex; align-items: baseline; gap: .45em; min-width: 0; }
.lgt-f__l2 { display: flex; align-items: center; gap: .45em; min-width: 0; }
.lgt-f--col .lgt-f__dot { flex: none; font-size: .75em; width: auto; }
.lgt-f--col .lgt-f__dot:empty { display: none; }
.lgt-f--col .lgt-f__n { flex: none; font-size: .95em; }
.lgt-f--col .lgt-f__cli { flex: 1 1 auto; min-width: 0; }
.lgt-f--col .lgt-f__hora { font-size: 1.15em; }
.lgt-f--col .lgt-f__abrir { font-size: 1.1em; min-height: 1.6em; }
.lgt-f--col .lgt-f__cuando { flex: none; font-size: .9em; }
.lgt-f__l2 { flex-wrap: wrap; row-gap: .15em; }
.lgt-f--col .lgt-f__est { flex: none; max-width: 100%; font-size: .95em; white-space: normal; overflow: visible; }
.lgt-f--col .lgt-f__sku { flex: none; }
.lgt-f--col .lgt-f__sku .lgt-sku { margin: 0; }
/* segundo renglon: el estado, el SKU y las etiquetas (zona, alquiler, Web #) NUNCA se recortan; si no entran, el renglon pasa a otra linea.
   Lo unico que se trunca, con elipsis, es el nombre del producto. */
.lgt-f--col .lgt-f__prod { display: block; flex: 1 1 6em; min-width: 0; max-width: 100%; font-size: .95em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.lgt-f--col .lgt-f__tags { flex: none; display: flex; gap: .3em; }
.lgt-f--col .lgt-f__tags > * { flex: none; }
.lgt-f--col .lgt-f__acc { flex: none; align-self: center; }
.lgt-f--col .fp-acc { gap: .35em; }
.lgt--pared .lgt-sku { font-size: .85em; }
.lgt--pared .lgt-tag { height: 1.7em; font-size: .85em; padding: 0 .55em; }
.lgt--pared .lgt-btn { height: max(40px, 2.7em); min-width: max(40px, 2.7em); padding: 0 .85em; font-size: .95em; border-radius: .7em; }
.lgt--pared .lgt-f .fp-menu > summary { width: max(40px, 2.25em); height: max(40px, 2.25em); font-size: 1.15em; border-radius: .7em; }
.lgt--pared .fp-menu__lista { min-width: 17em; }
.lgt--pared .fp-menu__lista .fp-mi, .lgt--pared .fp-menu__lista a { min-height: var(--lgt-tap); font-size: .95em; }
.fp-menu--arriba .fp-menu__lista { top: auto; bottom: calc(100% + 4px); }
.lgt--pared .lgt-det { padding: .6em .7em .8em; }
/* El detalle es la tarjeta de siempre y trae sus tamanos en px en linea: no hay em que escalar. Es lo unico de la pared que usa zoom, y
   es seguro porque vive dentro de la columna que scrollea (el problema de zoom era el alto de la pantalla entera). */
@media (min-width: 1600px) { .lgt--pared .lgt-det__z { zoom: 1.25; } } /* el zoom va en el hijo: .lgt-det (sin zoom) es lo que se mide al scrollear */
.lgt--pared .lgt-espera { padding-left: .9em; font-size: 1em; }
.lgt--pared .lgt-espera .ob-field, .lgt--pared .lgt-espera .ob-btn { min-height: var(--lgt-tap); }

/* ============================================================
   Logística · detalle compacto (.dc) — js/detalleCompacto.js + js/views/logistica.js (detalleCompactoHTML)
   El detalle de un pedido abierto dice solo lo que la fila no dice, en tres columnas: Qué y a dónde | Recorrido | Papeles.
   Tres columnas cuando el detalle mide 900 px o más (por su contenedor, no por la ventana: la pared las apila porque sus columnas son
   angostas); si no, apiladas. En celular (<= 640) los papeles suben primero, como en el resto de Logística. Solo tokens --ob-*.
   ============================================================ */
.dc { container: dc / inline-size; position: relative; display: flex; flex-direction: column; gap: 4px; min-width: 0; font-size: 12.5px; line-height: 1.35; color: var(--ob-ink); }
.dc__top { display: flex; align-items: center; flex-wrap: wrap; gap: 4px 10px; min-height: 28px; }
.dc__pagoweb { font: 600 11.5px var(--ob-font); color: var(--ob-muted); }
.dc__ocultar { margin-left: auto; min-height: 30px; padding: 0 8px; background: transparent; border: 0; border-radius: 8px; font: 700 11.5px var(--ob-font-head); color: var(--ob-navy); cursor: pointer; white-space: nowrap; }
.dc__ocultar:hover { background: var(--ob-bg); }
.dc__sinpapel { min-height: 30px; min-width: 44px; padding: 0 10px; font-size: 11.5px; background: var(--ob-surface); color: var(--ob-muted); border: 1px solid var(--ob-field-border); }
.dc__cols { display: grid; grid-template-columns: minmax(0, 1fr); gap: 8px; align-items: start; }
@container dc (min-width: 900px) {
  .dc__cols { grid-template-columns: minmax(0, 1.2fr) minmax(0, .75fr) minmax(0, 1.35fr); gap: 10px; }
}
.dc__col { min-width: 0; background: var(--ob-surface); border: 1px solid var(--ob-border); border-radius: 9px; padding: 6px 10px; }
.dc__h { margin: 0 0 3px; font: 700 10.5px var(--ob-font-head); letter-spacing: .06em; text-transform: uppercase; color: var(--ob-muted); }

/* columna 1: ítems y entrega */
.dc__items { list-style: none; margin: 0 0 4px; padding: 0; }
.dc__item { display: flex; align-items: baseline; gap: 7px; padding: 3px 0; min-width: 0; }
.dc__item + .dc__item { border-top: 1px solid var(--ob-border); }
.dc__cant { flex: none; font: 800 12px var(--ob-font-head); color: var(--ob-navy); }
.dc__nom { flex: 1 1 auto; min-width: 0; font: 700 13px/1.3 var(--ob-font-head); color: var(--ob-ink); overflow-wrap: anywhere; }
.dc__vacio { margin: 0; color: var(--ob-muted); }
.dc__linea { margin: 0; display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 6px; padding: 1px 0; }
.dc__linea--datos { gap: 2px 12px; }
.dc__dato { display: inline-flex; align-items: baseline; gap: 4px; }
.dc__ico { flex: none; font-size: 12px; }
.dc__tel { color: var(--ob-link); }
.dc__retiro { margin-top: 6px; }
.lg-tarj > .dc { margin-top: 8px; }

/* columna 2: recorrido (vertical, angosto: un paso por renglon y lo que falta en UNO) */
.dc__tl { list-style: none; margin: 0; padding: 0; display: grid; gap: 3px; }
.dc__paso { display: flex; align-items: baseline; flex-wrap: wrap; gap: 0 7px; min-width: 0; }
.dc__punto { flex: none; align-self: center; width: 9px; height: 9px; box-sizing: border-box; border-radius: 50%; border: 2px solid var(--ob-border-2); background: var(--ob-surface); }
.dc__paso--hecho .dc__punto { background: var(--ob-navy); border-color: var(--ob-navy); }
.dc__paso--actual .dc__punto { background: var(--ob-orange); border-color: var(--ob-orange); }
.dc__paso--vencido .dc__punto { background: var(--ob-danger-dot); border-color: var(--ob-danger-dot); }
.dc__paso--sosp .dc__punto { background: var(--ob-warn-dot); border-color: var(--ob-warn-dot); }
.dc__paso--term .dc__punto { background: var(--ob-muted); border-color: var(--ob-muted); }
.dc__pet { font: 700 12px var(--ob-font-head); color: var(--ob-ink); }
.dc__pcu { color: var(--ob-ink); }
.dc__pde { font-size: 11.5px; color: var(--ob-muted); }
.dc__paso--actual .dc__pcu { color: var(--ob-warn); font-weight: 700; }
.dc__paso--vencido .dc__pcu { color: var(--ob-danger); font-weight: 700; }
.dc__paso--sosp .dc__pet { color: var(--ob-warn); }
.dc__despues { margin-top: 1px; padding-left: 16px; font-size: 11.5px; color: var(--ob-muted); }
.dc .fp-sosp { display: block; margin-top: 4px; }

/* columna 3: papeles (guía, comprobante, nota interna) */
.dc__papel { padding: 0 0 4px; }
.dc__papel + .dc__papel, .dc__papel + .dc__nota { padding-top: 4px; border-top: 1px solid var(--ob-border); }
.dc__comprow { display: flex; align-items: center; flex-wrap: wrap; gap: 4px 8px; }
.dc__papelt { color: var(--ob-muted); }
.dc__ninguno { color: var(--ob-ink); }
.dc__btn { min-height: var(--ob-tap, 30px); padding: 4px 10px; font-size: 11.5px; background: var(--ob-surface); color: var(--ob-navy); border: 1px solid var(--ob-field-border); }
.dc .ob-comp-minis { margin-top: 4px; gap: 6px; }
.dc__nota { padding-top: 0; }
.dc__guia--revisar + .dc__nota { margin-top: 6px; padding-top: 6px; border-top: 1px solid var(--ob-border); }
.dc__pie { padding: 6px 10px; }
.dc__notacab { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
.dc__notalbl { margin: 0; }
.dc__notaest { font: 700 11.5px var(--ob-font-head); }
.dc__notaest--ok { color: var(--ob-ok); }
.dc__notaest--info { color: var(--ob-info); }
.dc__notaest--danger { color: var(--ob-danger); }
.dc__notaest--muted { color: var(--ob-muted); }
.dc__notaest--warn { color: var(--ob-warn); }
.dc__reint { margin-left: 6px; min-height: 24px; padding: 0 8px; border: 1px solid var(--ob-field-border); border-radius: 7px; background: var(--ob-surface); color: var(--ob-navy); font: 700 11.5px var(--ob-font-head); cursor: pointer; }
.dc__notaaviso:empty { display: none; }
.dc__notaerr { margin: 3px 0 0; font-size: 11.5px; font-weight: 700; color: var(--ob-danger); }
.dc__notaconf { margin: 3px 0 4px; padding: 4px 8px; border-radius: 7px; background: var(--ob-warn-bg); color: var(--ob-ink); font-size: 12px; white-space: pre-wrap; overflow-wrap: anywhere; }
.dc__notaconfacc { display: flex; flex-wrap: wrap; gap: 6px; }
.dc__notaayuda { margin: 0 0 3px; font-size: 11px; line-height: 1.3; color: var(--ob-muted); }
.dc__campo { display: block; width: 100%; min-height: 0; padding: 5px 8px; font-size: var(--ob-field-fs, 12.5px); line-height: 1.35; resize: none; overflow-y: auto; }
@media (min-width: 641px) {
  /* El formulario de guía y la foto traen alto de 36 px y miniaturas de 104 px: acá van más chicos. */
  .dc__guia { --ob-tap: 30px; }
  .dc .ob-comp-mini { width: 64px; height: 64px; border-radius: 8px; }
  .dc .ob-comp-mini__chip { font-size: 9px; padding: 1px 5px; }
}
/* La nota y, si la hay, la foto de guia por revisar van en una fila de ancho completo: las tres columnas quedan parejas (la de Papeles
   era mucho mas alta y dejaba un hueco). Con espacio, la etiqueta y la ayuda a la izquierda y el campo a la derecha: la fila mide ~60 px. */
@container dc (min-width: 900px) {
  .dc__pie .dc__nota { display: grid; grid-template-columns: minmax(200px, 1fr) minmax(0, 2.4fr); grid-template-areas: "cab campo" "ayu campo" "avi campo"; column-gap: 14px; align-items: start; }
  .dc__pie .dc__notacab { grid-area: cab; }
  .dc__pie .dc__notaayuda { grid-area: ayu; }
  .dc__pie .dc__campo { grid-area: campo; }
  .dc__pie .dc__notaaviso { grid-area: avi; }
  .dc__pie .dc__guia--revisar { padding-bottom: 6px; }
}
@media (max-width: 640px) {
  /* Apilado: que y a donde primero (lo que se LEE). El deposito (rol admin, .dc--deposito) abre un pedido para HACER: sus papeles y su nota primero. */
  .dc { gap: 8px; }
  .dc__cols { display: contents; }
  .dc__col--que { order: 1; }
  .dc__col--rec { order: 2; }
  .dc__col--pap { order: 3; }
  .dc__pie { order: 4; }
  .dc--deposito .dc__col--pap { order: 1; }
  .dc--deposito .dc__pie { order: 2; }
  .dc--deposito .dc__col--que { order: 3; }
  .dc--deposito .dc__col--rec { order: 4; }
  .dc__ocultar, .dc__sinpapel, .dc__btn, .dc__reint { min-height: 44px; }
  .dc__campo { min-height: 44px; }
  .dc__item { padding: 5px 0; }
}

/* La franja "Mirar primero" queda pegada arriba, junto a los carriles y la barra: antes scrolleaba sola y quedaba cortada por el borde
   de la vista. Su alto se mide en JS (--lgt-exc-h): solo se pega mientras entra en UN renglon (en una ventana angosta los chips pasan a otro
   y dos renglones fijos le comerian demasiado a la lista). Bajo 641 px se pliega a un boton y no se pega. El top es el de siempre:
   un sticky mide desde el borde del CONTENIDO (ver --lgt-top). */
@media (min-width: 641px) {
  .lgt[data-exc-pegada="si"] #lgt-exc { position: sticky; top: var(--lgt-top); z-index: 5; background: var(--ob-bg); }
  .lgt-tabs { top: calc(var(--lgt-top) + var(--lgt-exc-h, 0px)); }
  .lgt-carriles { top: calc(var(--lgt-top) + var(--lgt-exc-h, 0px) + var(--lgt-tabs-h)); }
  .lgt-barra { top: calc(var(--lgt-top) + var(--lgt-exc-h, 0px) + var(--lgt-tabs-h) + var(--lgt-carril-h)); }
}

@media (prefers-reduced-motion: reduce) { .lgt-grp__flecha { transition: none; } }

/* Menu lateral plegable (shell.js + js/menuLateral.js): desde 861 px el modo "riel" deja solo los iconos (64 px, el mismo plegado que la
   app ya usa bajo 860 px) y el modo "oculto" saca el menu del todo. Bajo 861 px mandan las reglas de siempre (riel + .nav-cerrada). */
@media (min-width: 861px) {
  .ob-app--riel .ob-side { width: 64px; flex: 0 0 64px; padding: 16px 8px; }
  .ob-app--riel .ob-brand { justify-content: center; padding: 8px 4px; }
  .ob-app--riel .ob-brand__name { display: none; }
  .ob-app--riel .ob-navitem { justify-content: center; gap: 0; padding: 10px 4px; font-size: 0; }
  /* el SVG del icono no depende del font-size:0 del label (ver .ob-navitem__ico svg) */
  .ob-app--riel .ob-side__grupo, .ob-app--riel .ob-side__role { display: none; }
  /* Mismo criterio que el riel CSS angosto: sin sangria en sub-items de
     Configuracion y sin chevron cuando el label no se ve. */
  .ob-app--riel .ob-side__cfg .ob-navitem { padding-left: 4px; }
  .ob-app--riel .ob-navitem--cfg .ob-navitem__chev { display: none; }
  .ob-app--oculto .ob-side { display: none; }
}
/* Bajo 1500 px la franja no tiene lugar para su rotulo: los chips ya se explican solos. */
@media (max-width: 1499px) { .lgt-exc__lbl { display: none; } }
/* La barra superior de Logistica lleva los controles de la vista: nunca parte en dos renglones (el titulo cede). */
.ob-topbar:has(.lgt-top-ctl) { flex-wrap: nowrap; }
.ob-topbar:has(.lgt-top-ctl) .ob-topbar__title, .ob-topbar:has(.lgt-top-ctl) .ob-topbar__sub { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; flex: 0 1 auto; }
@media (max-width: 860px) {
  .ob-topbar:has(.lgt-top-ctl) .ob-topbar__sub { display: none; }
  /* el nombre del cliente puede pasar a un segundo renglon: en un celular es lo que mas se busca */
  .lgt-f__abrir { white-space: normal; overflow: visible; text-overflow: clip; overflow-wrap: anywhere; line-height: 1.2; padding: 4px 0; }
}
@media (max-width: 860px) {
  .ob-topbar:has(.lgt-top-ctl) { padding: 0 10px; gap: 6px; }
  /* i175: el nombre se parte en los renglones que necesite; antes se cortaba en el segundo con puntos suspensivos (un cliente con razon social larga quedaba ilegible). */
  .lgt-f__abrir { display: block; overflow: visible; }
}

/* ---------- Venta propone la espera de mercaderia (esperaVentaUI.js) ----------
   Renglon inline en la tarjeta de pago: no es un modal. Tokens --ob-*; botones de 44 px y campos de 16 px en celular. */
.ob-espera { display: none; margin: 0 0 10px; padding: 10px 12px; border-radius: 10px; background: var(--ob-warn-bg); border: 1px solid var(--ob-warn-border); }
.ob-espera__txt { font-size: 12.5px; line-height: 1.45; color: var(--ob-ink); }
.ob-espera__fila { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 8px; }
.ob-espera__fecha { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; color: var(--ob-muted); }
.ob-espera__fecha .ob-field { min-height: 44px; width: auto; }
.ob-espera__btn { min-height: 44px; padding: 0 14px; background: #fff; color: var(--ob-navy); border: 1px solid var(--ob-field-border); }
.ob-espera__btn[aria-pressed="true"] { background: var(--ob-navy); color: #fff; border-color: var(--ob-navy); }
.ob-espera__err { margin-top: 6px; font-size: 12px; font-weight: 700; color: var(--ob-danger); }
.ob-espera__err:empty { display: none; }
@media (max-width: 640px) {
  .ob-espera__fecha .ob-field { font-size: 16px; }
  .ob-espera__btn { flex: 1 1 auto; }
}

/* ---------- ¿Sale del depósito? de una encomienda, con la guía (despachoEncomiendaModal.js) ----------
   Mismo overlay que confirmar.js. El cuerpo scrollea adentro (el detalle de cobro puede ser largo) y los dos botones
   quedan fijos abajo; los campos y el botón de foto van arriba, antes del pliegue de un celular de 844 px. */
.dem-overlay { position: fixed; inset: 0; z-index: var(--ob-z-dialogo); display: flex; align-items: center; justify-content: center; padding: 24px; background: rgba(14, 52, 96, .55); }
.dem { width: min(440px, 94vw); max-height: 90vh; display: flex; flex-direction: column; }
.dem__cuerpo { flex: 1 1 auto; min-height: 0; overflow-y: auto; padding: 16px 16px 4px; }
.dem__titulo { font-family: var(--ob-font-head); font-weight: 800; font-size: 15px; color: var(--ob-navy); }
.dem__linea { margin-top: 8px; font-size: 13px; line-height: 1.5; color: var(--ob-ink); overflow-wrap: anywhere; }
.dem__detalle { margin-top: 6px; font-size: 12px; line-height: 1.5; color: var(--ob-muted); overflow-wrap: anywhere; }
.dem .ob-label { margin-top: 12px; }
.dem__foto { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 12px; }
.dem__btnfoto, .dem__quitar { min-height: var(--ob-tap, 40px); background: var(--ob-surface); color: var(--ob-navy); border: 1px solid var(--ob-field-border); }
.dem__quitar { background: transparent; color: var(--ob-muted); text-decoration: underline; border-color: transparent; }
.dem__fotoestado { display: inline-flex; align-items: center; gap: 6px; min-width: 0; font-size: 12px; color: var(--ob-ink); overflow-wrap: anywhere; }
.dem__fotoOk { min-width: 0; font-weight: 700; color: var(--ob-ok); overflow-wrap: anywhere; }
/* Lectura de la foto (i174 b): resumen de lo leído y aviso si la guía no es de este pedido. */
.dem__lectura { display: grid; gap: 3px; margin-top: 8px; font-size: 12px; line-height: 1.5; color: var(--ob-muted); overflow-wrap: anywhere; }
.dem__lectura:empty { display: none; }
.dem__lecturaFuerte { color: var(--ob-ink); }
.dem__lecturaOk { color: var(--ob-ok); }
.dem__lecturaWarn { color: var(--ob-warn); }
.dem__aviso { display: grid; gap: 3px; margin-top: 8px; padding: 8px 10px; border-radius: 8px; background: var(--ob-warn-bg); color: var(--ob-ink); font-size: 12px; line-height: 1.5; overflow-wrap: anywhere; }
.dem__aviso strong { color: var(--ob-warn); }
.dem__aviso .dem__quitar { justify-self: start; color: var(--ob-navy); }
.dem__pie { display: flex; gap: 8px; padding: 12px 16px 16px; border-top: 1px solid var(--ob-border); background: var(--ob-surface); }
.dem__pie .ob-btn { flex: 1; min-height: var(--ob-tap, 40px); }
.dem__pie .ob-btn--primary { flex: 2; }
@media (max-width: 640px) {
  .dem-overlay { padding: 10px; }
  .dem { width: 100%; }
}
/* Foto de la guia sin numero: ambar con palabras (no solo color). */
.lgt-falta-num { color: var(--ob-warn); font-weight: 700; }

/* d12 (i175): con un formulario de guia abierto, el UNICO boton relleno de la pantalla es "Guardar guia". Lo demas que va relleno
   en la vista (la accion de la fila activa, las de la barra de lote, "Nuevo presupuesto"...) pasa a outline mientras dure. Es solo CSS
   sobre el contenedor de la vista: al cerrar el formulario (Cancelar, guardar, Escape, un repintado) el :has() deja de cumplirse y el
   relleno vuelve solo, sin que la vista tenga que acordarse. Los dialogos (confirmar, modales) cuelgan del body y no entran. */
#ob-view:has([data-guia-form]) :is(.ob-btn--primary, .ob-btn--ok, .lgt-sig__btn--primary, .lgt-sig__btn--ok):not([data-guia-guardar]) {
  background: var(--ob-surface); color: var(--ob-navy); border: 1px solid var(--ob-field-border);
}
#ob-view:has([data-guia-form]) :is(.ob-btn--primary, .ob-btn--ok, .lgt-sig__btn--primary, .lgt-sig__btn--ok):not([data-guia-guardar]):hover { background: var(--ob-navy-tint); }
