/* ==========================================================================
   UVERO · sistema visual sobre Bootstrap 5.3
   Firma gráfica «Ruta viva»: la jornada arranca de noche y termina de noche,
   así que el tema oscuro es el canónico y el claro es su versión de mediodía.
   El verde del logo es el único acento; el resto es azul de ruta y gris frío.

   Los colores se definen como tokens y se redefinen en el tema oscuro.
   Ningún color se declara solo dentro de [data-bs-theme=dark].
   ========================================================================== */

:root {
  /* --- día: la misma firma con la luz encima ------------------------------ */
  --uv-ground:      #EDF1F3;
  --uv-surface:     #FFFFFF;
  --uv-surface-2:   #E3EAED;
  --uv-ink:         #0B1F2A;
  --uv-muted:       #54707E;
  --uv-line:        #C2D2D8;
  --uv-line-fuerte: #77939E;
  --uv-accent:      #0C7A4F;
  --uv-accent-alto: #095F3D;
  --uv-accent-soft: #E1F4EB;
  --uv-cool:        #1D5A7D;
  --uv-cool-soft:   #D8E6EF;
  --uv-signal:      #955513;
  --uv-signal-soft: #F5E7D2;
  --uv-danger:      #A02C26;
  --uv-danger-soft: #F6DEDC;
  --uv-sombra:      0 1px 2px rgba(11,31,42,.06), 0 8px 24px -18px rgba(11,31,42,.4);
  --uv-barra:       56px;
  --uv-lateral:     236px;

  /* --- tipografía de la firma -------------------------------------------- */
  --uv-titulo: "Barlow Condensed", "Arial Narrow", "Segoe UI", sans-serif;
  --uv-mono:   "IBM Plex Mono", ui-monospace, Menlo, Consolas, monospace;

  --bs-body-bg:      var(--uv-ground);
  --bs-body-color:   var(--uv-ink);
  --bs-border-color: var(--uv-line);
  --bs-primary:      var(--uv-accent);
  --bs-primary-rgb:  12, 122, 79;
  --bs-link-color:   var(--uv-accent);
  --bs-link-hover-color: var(--uv-accent-alto);
  --bs-body-font-family: "Barlow", -apple-system, BlinkMacSystemFont, "Segoe UI",
                         Roboto, "Helvetica Neue", Arial, sans-serif;
  --bs-body-font-size: .96rem;
  --bs-border-radius: .375rem;
}

[data-bs-theme="dark"] {
  /* --- noche: la firma canónica ------------------------------------------ */
  --uv-ground:      #0B1F2A;
  --uv-surface:     #12303F;
  --uv-surface-2:   #17394A;
  --uv-ink:         #EAF2F6;
  --uv-muted:       #8FA9B7;
  --uv-line:        #244C61;
  --uv-line-fuerte: #517C90;
  --uv-accent:      #34D07F;
  --uv-accent-alto: #58E29A;
  --uv-accent-soft: #0F3A2C;
  --uv-cool:        #6BB6E8;
  --uv-cool-soft:   #10344A;
  --uv-signal:      #F0B457;
  --uv-signal-soft: #3A2B12;
  --uv-danger:      #F1837A;
  --uv-danger-soft: #3B1B18;
  --uv-sombra:      0 1px 2px rgba(0,0,0,.45), 0 8px 24px -18px rgba(0,0,0,.85);
  --bs-primary-rgb: 52, 208, 127;
}

body {
  background: var(--uv-ground);
  color: var(--uv-ink);
  -webkit-font-smoothing: antialiased;
}

/* ---------- isotipo ----------
   El archivo de marca en PNG con transparencia. En superficies claras u oscuras
   va a color; sobre el verde de la barra del repartidor se usa como máscara,
   que lo pinta de un solo color sin perder la silueta. */
.uv-iso {
  display: inline-block; flex: 0 0 auto; width: 22px; height: 27px;
  background: url("../img/isotipo.png?v=uvero") center/contain no-repeat;
}
.uv-iso.mono {
  background: currentColor;
  -webkit-mask: url("../img/isotipo.png?v=uvero") center/contain no-repeat;
          mask: url("../img/isotipo.png?v=uvero") center/contain no-repeat;
}

/* ---------- iconos ---------- */
.ic { display: inline-block; vertical-align: -.16em; flex: 0 0 auto; }
.ic-lg { vertical-align: -.22em; }

/* ---------- barra superior ---------- */
.uv-barra {
  position: fixed; inset: 0 0 auto 0; height: var(--uv-barra); z-index: 1035;
  background: var(--uv-surface); border-bottom: 1px solid var(--uv-line);
  display: flex; align-items: center; gap: .75rem; padding: 0 .875rem;
}
.uv-marca {
  display: flex; align-items: center; gap: .5rem; font-weight: 700;
  font-family: var(--uv-titulo); text-transform: uppercase; letter-spacing: .045em;
  color: var(--uv-ink); text-decoration: none; font-size: 1.24rem;
}
.uv-marca .ic { color: var(--uv-accent); }
.uv-marca:hover { color: var(--uv-ink); }

.uv-buscador { position: relative; flex: 1 1 auto; max-width: 460px; }
.uv-buscador .ic { position: absolute; left: .65rem; top: 50%; transform: translateY(-50%);
                   color: var(--uv-muted); pointer-events: none; }
.uv-buscador input {
  width: 100%; height: 36px; padding: 0 2.6rem 0 2.1rem;
  background: var(--uv-surface-2); border: 1px solid transparent;
  border-radius: .45rem; color: var(--uv-ink); font-size: .9rem;
}
.uv-buscador input:focus {
  outline: none; background: var(--uv-surface);
  border-color: var(--uv-accent); box-shadow: 0 0 0 3px var(--uv-accent-soft);
}
.uv-atajo {
  position: absolute; right: .5rem; top: 50%; transform: translateY(-50%);
  font: 600 10.5px/1 var(--uv-mono); color: var(--uv-muted);
  border: 1px solid var(--uv-line); border-radius: .25rem; padding: .2rem .35rem;
  background: var(--uv-surface);
}

/* ---------- lateral ---------- */
.uv-lateral {
  position: fixed; top: var(--uv-barra); bottom: 0; left: 0; width: var(--uv-lateral);
  background: var(--uv-surface); border-right: 1px solid var(--uv-line);
  padding: .75rem .625rem; overflow-y: auto; z-index: 1030;
}
.uv-lateral .grupo {
  font: 600 11.5px/1 var(--uv-titulo); letter-spacing: .16em;
  text-transform: uppercase; color: var(--uv-muted);
  padding: .9rem .6rem .45rem;
}
.uv-nav-item {
  display: flex; align-items: center; gap: .6rem;
  padding: .5rem .6rem; border-radius: .4rem; color: var(--uv-ink);
  text-decoration: none; font-size: .9rem; font-weight: 500; margin-bottom: 1px;
}
.uv-nav-item .ic { color: var(--uv-muted); }
.uv-nav-item:hover { background: var(--uv-surface-2); color: var(--uv-ink); }
.uv-nav-item:hover .ic { color: var(--uv-accent); }
.uv-nav-item.activo {
  background: var(--uv-accent-soft); color: var(--uv-accent); font-weight: 600;
  box-shadow: inset 2.5px 0 0 var(--uv-accent);
}
.uv-nav-item.activo .ic { color: var(--uv-accent); }
.uv-nav-item .cuenta {
  margin-left: auto; font: 600 11px/1 var(--uv-mono);
  background: var(--uv-accent); color: var(--uv-surface);
  border-radius: 999px; padding: .22rem .42rem; min-width: 20px; text-align: center;
}

/* ---------- contenido ---------- */
.uv-contenido { margin: var(--uv-barra) 0 0 var(--uv-lateral); padding: 1.25rem 1.5rem 3rem; }
.uv-encabezado { display: flex; align-items: flex-start; gap: 1rem; flex-wrap: wrap; margin-bottom: 1.1rem; }
.uv-encabezado h1 {
  font-family: var(--uv-titulo); font-size: 1.72rem; font-weight: 600;
  letter-spacing: .01em; margin: 0; line-height: 1.15;
}
.uv-encabezado p { margin: .2rem 0 0; color: var(--uv-muted); font-size: .9rem; }
.uv-acciones { margin-left: auto; display: flex; gap: .5rem; align-items: center; }

/* ---------- tarjetas y métricas ---------- */
.uv-panel {
  background: var(--uv-surface); border: 1px solid var(--uv-line);
  border-radius: .55rem; box-shadow: var(--uv-sombra);
}
/* ---------- avisos ----------
   Fondo lleno y no panel blanco: el aviso aparece sobre una interfaz que ya es
   blanca, y un panel claro con un filete de color al costado se pierde. Con el
   color de lado a lado se ve sin buscarlo, que es lo que tiene que pasar cuando
   entra un pedido y nadie está mirando la pantalla. */
.uv-aviso {
  display: flex; align-items: center; gap: .55rem;
  max-width: 26rem; padding: .7rem .95rem;
  border-radius: .6rem; border: 1px solid rgba(0, 0, 0, .12);
  font-size: .88rem; font-weight: 500; line-height: 1.35;
  color: #fff; background: var(--uv-accent);
  box-shadow: 0 .55rem 1.4rem rgba(11, 31, 42, .28);
  cursor: pointer;                    /* un clic lo cierra: 30 s es mucho rato */
  animation: uv-aviso-entra .18s ease-out;
}
.uv-aviso.error { background: var(--uv-danger); }
.uv-aviso.info  { background: var(--uv-cool); }
.uv-aviso .cuerpo { flex: 1; }
.uv-aviso .cerrar { opacity: .75; font-size: 1.1rem; line-height: 1; }
.uv-aviso:hover .cerrar { opacity: 1; }

@keyframes uv-aviso-entra {
  from { opacity: 0; transform: translateY(.4rem); }
  to   { opacity: 1; transform: none; }
}

.uv-panel-cab {
  display: flex; align-items: center; gap: .5rem;
  padding: .7rem .95rem; border-bottom: 1px solid var(--uv-line); font-weight: 600; font-size: .9rem;
}
.uv-metricas { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: .75rem; }
.uv-metrica {
  background: var(--uv-surface); border: 1px solid var(--uv-line); border-radius: .55rem;
  padding: .85rem 1rem; display: flex; flex-direction: column; gap: .3rem;
  box-shadow: var(--uv-sombra);
}
.uv-metrica .fila { display: flex; align-items: center; gap: .45rem; color: var(--uv-muted); }
.uv-metrica .rotulo { font: 600 11.5px/1.3 var(--uv-titulo);
                      letter-spacing: .13em; text-transform: uppercase; }
.uv-metrica .valor { font-size: 1.65rem; font-weight: 700; letter-spacing: -.03em;
                     line-height: 1; font-variant-numeric: tabular-nums; }
.uv-metrica.acento { border-left: 3px solid var(--uv-accent); }
.uv-metrica.aviso  { border-left: 3px solid var(--uv-signal); }
.uv-metrica.frio   { border-left: 3px solid var(--uv-cool); }

/* ---------- bandeja de pedidos ---------- */
.uv-bandeja { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 400px); gap: 1rem; align-items: start; }
.uv-lista { display: flex; flex-direction: column; gap: .5rem; }

.uv-tarjeta-pedido {
  background: var(--uv-surface); border: 1px solid var(--uv-line); border-left: 3px solid transparent;
  border-radius: .5rem; padding: .75rem .9rem; cursor: pointer;
  display: grid; grid-template-columns: auto minmax(0,1fr) auto; gap: .75rem; align-items: center;
  transition: border-color .12s ease, background .12s ease;
}
.uv-tarjeta-pedido:hover { background: var(--uv-surface-2); }
.uv-tarjeta-pedido.seleccionado {
  border-left-color: var(--uv-accent); background: var(--uv-accent-soft);
  outline: 2px solid var(--uv-accent); outline-offset: -1px;
}
.uv-tarjeta-pedido.revision { border-left-color: var(--uv-signal); }
.uv-tarjeta-pedido .cliente { font-weight: 600; }
.uv-tarjeta-pedido .meta { color: var(--uv-muted); font-size: .8rem; display: flex; gap: .6rem; flex-wrap: wrap; align-items: center; }
.uv-tarjeta-pedido .total { font-variant-numeric: tabular-nums; font-weight: 700; white-space: nowrap; }

.uv-origen {
  width: 32px; height: 32px; border-radius: .4rem; display: grid; place-items: center;
  background: var(--uv-surface-2); color: var(--uv-muted); flex: 0 0 auto;
}
.uv-origen.audio { background: var(--uv-cool-soft); color: var(--uv-cool); }
.uv-origen.texto { background: var(--uv-accent-soft); color: var(--uv-accent); }

/* barra de confianza: el operador la lee sin leer números */
.uv-confianza { display: flex; gap: 2px; align-items: center; }
.uv-confianza i { width: 12px; height: 4px; border-radius: 1px; background: var(--uv-line); display: block; }
.uv-confianza i.on { background: var(--uv-accent); }
.uv-confianza.baja i.on { background: var(--uv-signal); }

.uv-etiqueta {
  font: 600 11px/1 var(--uv-titulo); letter-spacing: .12em; text-transform: uppercase;
  padding: .28rem .5rem; border-radius: .25rem; white-space: nowrap;
}
.uv-etiqueta.ok    { background: var(--uv-accent-soft); color: var(--uv-accent); }
.uv-etiqueta.rev   { background: var(--uv-signal-soft); color: var(--uv-signal); }
.uv-etiqueta.frio  { background: var(--uv-cool-soft);  color: var(--uv-cool); }
.uv-etiqueta.mal   { background: var(--uv-danger-soft); color: var(--uv-danger); }

/* ---------- panel de detalle ---------- */
.uv-detalle { position: sticky; top: calc(var(--uv-barra) + 1.25rem); }
.uv-mensaje {
  background: var(--uv-cool-soft); border-radius: .5rem; padding: .7rem .85rem;
  font-size: .88rem; line-height: 1.5; color: var(--uv-ink);
}
.uv-mensaje .rotulo { font: 600 11px/1 var(--uv-titulo); letter-spacing: .14em;
                      text-transform: uppercase; color: var(--uv-cool); display: block; margin-bottom: .35rem; }
.uv-linea {
  display: grid; grid-template-columns: 60px minmax(0,1fr) auto; gap: .6rem;
  align-items: center; padding: .5rem 0; border-bottom: 1px solid var(--uv-line);
}
.uv-linea:last-child { border-bottom: 0; }
.uv-linea .desc { font-size: .875rem; }
.uv-linea .evidencia { color: var(--uv-muted); font-size: .76rem; font-style: italic; }
.uv-linea .importe { font-variant-numeric: tabular-nums; font-weight: 600; white-space: nowrap; font-size: .875rem; }
.uv-cant {
  width: 100%; text-align: center; font-variant-numeric: tabular-nums; font-weight: 600;
  border: 1px solid var(--uv-line-fuerte); background: var(--uv-surface); color: var(--uv-ink);
  border-radius: .3rem; padding: .22rem .1rem; font-size: .875rem;
}
.uv-cant:focus { outline: none; border-color: var(--uv-accent); box-shadow: 0 0 0 3px var(--uv-accent-soft); }

/* ---------- captura de pedidos ----------
   La pantalla del pedido que no llego por WhatsApp. Lo que se busca --la tienda,
   el producto-- se elige de una lista que cae debajo del campo, y el canal se
   marca como se marcaria en papel: tres casillas grandes y a la vista. */
/* Sin tienda elegida no hay precio que resolver: el buscador de productos
   arranca apagado y se ve apagado. */
.uv-buscador input:disabled { opacity: .5; cursor: not-allowed; }

.uv-sugerencias {
  display: flex; flex-direction: column;
  border: 1px solid var(--uv-line); border-radius: .45rem; overflow: hidden;
}
.uv-sugerencias:empty { display: none; }
.uv-sugerencia {
  display: flex; align-items: center; gap: .6rem; width: 100%; text-align: left;
  padding: .45rem .7rem; font-size: .88rem; cursor: pointer;
  background: var(--uv-surface); color: var(--uv-ink);
  border: 0; border-bottom: 1px solid var(--uv-line);
}
.uv-sugerencia:last-child { border-bottom: 0; }
.uv-sugerencia:hover, .uv-sugerencia:focus-visible { background: var(--uv-surface-2); }
.uv-sugerencia .detalle { color: var(--uv-muted); font-size: .77rem; }
.uv-sugerencia .importe {
  margin-left: auto; color: var(--uv-muted); font-size: .8rem;
  font-variant-numeric: tabular-nums;
}

/* La tienda ya elegida: ocupa el lugar del buscador para que no queden dos
   formas de decir lo mismo en la misma pantalla. */
.uv-elegido {
  display: flex; align-items: center; gap: .6rem;
  padding: .55rem .7rem; border-radius: .45rem;
  background: var(--uv-accent-soft); color: var(--uv-accent);
}
.uv-elegido .detalle { color: var(--uv-ink); opacity: .72; font-size: .78rem; }

.uv-canal { display: flex; gap: .5rem; }
.uv-canal-op { flex: 1 1 0; position: relative; margin: 0; }
.uv-canal-op input { position: absolute; width: 0; height: 0; opacity: 0; }
.uv-canal-op .cara {
  display: flex; flex-direction: column; align-items: center; gap: .2rem; height: 100%;
  padding: .6rem .35rem; border: 1px solid var(--uv-line); border-radius: .5rem;
  color: var(--uv-muted); text-align: center; cursor: pointer;
}
.uv-canal-op .cara b { font: 600 .85rem/1.3 inherit; color: var(--uv-ink); }
.uv-canal-op .cara .ayuda { font-size: .72rem; }
.uv-canal-op input:checked + .cara {
  border-color: var(--uv-accent); background: var(--uv-accent-soft); color: var(--uv-accent);
}
.uv-canal-op input:checked + .cara b { color: var(--uv-accent); }
.uv-canal-op input:focus-visible + .cara { outline: 2px solid var(--uv-accent); outline-offset: 2px; }

/* Truncar dentro de un flex necesita esto; la clase ya se usaba en la bandeja
   dando por sentado que existia. */
.min-w-0 { min-width: 0; }

/* ---------- tablas ---------- */
.uv-tabla { width: 100%; border-collapse: collapse; font-size: .885rem; }
.uv-tabla th {
  font: 600 11.5px/1.4 var(--uv-titulo); letter-spacing: .14em; text-transform: uppercase;
  color: var(--uv-muted); text-align: left; padding: .6rem .8rem;
  background: var(--uv-surface-2); border-bottom: 1px solid var(--uv-line); white-space: nowrap;
}
.uv-tabla td { padding: .38rem .7rem; border-bottom: 1px solid var(--uv-line); vertical-align: middle; }
.uv-tabla th { padding: .45rem .7rem; }
.uv-tabla .btn-icono { width: 28px; height: 28px; }
.uv-tabla .btn-icono + .btn-icono { margin-left: .15rem; }

/* Miniatura del producto. Tamano fijo para que una foto vertical no estire la
   fila: se recorta al cuadro en vez de deformar la grilla. */
.uv-mini {
  width: 34px; height: 34px; border-radius: .4rem; object-fit: cover;
  border: 1px solid var(--uv-line); background: var(--uv-surface-2); display: block;
}
.uv-tabla tbody tr:last-child td { border-bottom: 0; }
.uv-tabla tbody tr:hover { background: var(--uv-surface-2); }
.uv-num { font-variant-numeric: tabular-nums; text-align: right; white-space: nowrap; }
/* El encabezado de una columna de números va a la derecha, sobre sus cifras.
   «.uv-tabla th» fija la izquierda con más especificidad que .uv-num, así que
   sin esta regla el título quedaba lejos de la columna que nombra. */
.uv-tabla th.uv-num { text-align: right; }

/* Encabezado que ordena. La flecha solo se ve en la columna que manda; en las
   demas aparece apagada al pasar por encima, que es como se anuncia que se
   puede tocar sin llenar la fila de flechas. */
.uv-tabla th .uv-orden {
  display: inline-flex; align-items: center; gap: .3rem;
  color: inherit; text-decoration: none; cursor: pointer;
}
.uv-tabla th .uv-orden .ic { opacity: 0; transition: opacity .12s ease, transform .12s ease; }
.uv-tabla th:hover .uv-orden .ic { opacity: .4; }
.uv-tabla th .uv-orden.asc, .uv-tabla th .uv-orden.desc { color: var(--uv-accent); }
.uv-tabla th .uv-orden.asc .ic, .uv-tabla th .uv-orden.desc .ic { opacity: 1; }
/* El galon apunta hacia abajo dibujado: de menor a mayor se le da la vuelta. */
.uv-tabla th .uv-orden.asc .ic { transform: rotate(180deg); }

/* Texto largo en una celda: se corta a la vista y se lee completo en el titulo.
   Va en un span y no en la celda porque el recorte necesita un ancho, y darselo
   a la celda le mueve el reparto de toda la tabla. */
.uv-recorte {
  display: inline-block; max-width: 25ch; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; vertical-align: middle;
}

/* ---------- grilla paginada ----------
   La lista es un fragmento que pinta el servidor y que se reemplaza solo. Lo de
   aca es el marco: la barra de herramientas arriba, el paginador abajo y el
   atenuado de mientras. */
.uv-grilla-barra {
  display: flex; flex-wrap: wrap; gap: .5rem; align-items: center;
  padding: .7rem .8rem; border-bottom: 1px solid var(--uv-line);
  background: var(--uv-surface-2);
}
.uv-grilla-barra .uv-buscador { max-width: 320px; }
.uv-grilla-barra select.form-select-sm { width: auto; }

/* Mientras llega el fragmento la lista se apaga un poco y deja de recibir
   clics: sin esto se puede pedir la pagina 4 dos veces, o ordenar por una
   columna que ya va a desaparecer. */
[data-grilla-lista] { transition: opacity .12s ease; }
[data-grilla-lista].cargando { opacity: .45; pointer-events: none; }

/* Lo mismo para la tabla de una consulta mientras el buscador la vuelve a
   pedir: se apaga un poco para que se vea que lo de abajo ya no es la
   respuesta a lo que se está escribiendo. */
#panelConsulta { transition: opacity .12s ease; }
#panelConsulta.cargando { opacity: .45; pointer-events: none; }

.uv-paginador {
  display: flex; flex-wrap: wrap; gap: .6rem; align-items: center;
  justify-content: space-between;
  padding: .6rem .8rem; border-top: 1px solid var(--uv-line);
}
.uv-paginador .cuenta { color: var(--uv-muted); font-size: .8rem; }
.uv-paginador .cuenta b { color: var(--uv-ink); font-weight: 600; }
.uv-paginador .paginas { display: flex; gap: .2rem; align-items: center; }
.uv-paginador .pag {
  min-width: 30px; height: 30px; padding: 0 .4rem;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--uv-line); border-radius: .35rem;
  background: var(--uv-surface); color: var(--uv-ink);
  font-size: .8rem; font-weight: 600; font-variant-numeric: tabular-nums;
  cursor: pointer;
}
.uv-paginador .pag:hover:not([disabled]):not(.activa) { background: var(--uv-surface-2); }
.uv-paginador .pag[disabled] { opacity: .35; cursor: default; }
.uv-paginador .pag.activa {
  background: var(--uv-accent); border-color: var(--uv-accent); color: #fff; cursor: default;
}
.uv-paginador .salto { color: var(--uv-muted); padding: 0 .15rem; }

@media (max-width: 575px) {
  .uv-paginador { justify-content: center; }
  .uv-paginador .cuenta { width: 100%; text-align: center; }
}

/* ---------- botones ---------- */
.btn { font-size: .885rem; font-weight: 500; display: inline-flex; align-items: center; gap: .4rem; }
.btn-primary { background: var(--uv-accent); border-color: var(--uv-accent); color: #fff; }
.btn-primary:hover, .btn-primary:focus { background: var(--uv-accent-alto); border-color: var(--uv-accent-alto); color: #fff; }
[data-bs-theme="dark"] .btn-primary,
[data-bs-theme="dark"] .btn-primary:hover { color: #05231A; }
/* Bootstrap pinta el botón deshabilitado y el presionado con sus variables, que
   ganan por especificidad a lo de arriba: sin esto, «Registrar» deshabilitado o
   recién tocado salía azul de Bootstrap en vez del verde de la marca. */
.btn-primary {
  --bs-btn-active-bg: var(--uv-accent-alto); --bs-btn-active-border-color: var(--uv-accent-alto); --bs-btn-active-color: #fff;
  --bs-btn-disabled-bg: var(--uv-accent); --bs-btn-disabled-border-color: var(--uv-accent); --bs-btn-disabled-color: #fff;
}
[data-bs-theme="dark"] .btn-primary { --bs-btn-active-color: #05231A; --bs-btn-disabled-color: #05231A; }
.btn-suave {
  background: var(--uv-surface); border: 1px solid var(--uv-line); color: var(--uv-ink);
}
.btn-suave:hover { background: var(--uv-surface-2); color: var(--uv-ink); border-color: var(--uv-line); }
.btn-icono {
  width: 34px; height: 34px; padding: 0; display: inline-grid; place-items: center; vertical-align: middle;
  border-radius: .4rem; border: 1px solid transparent; background: transparent; color: var(--uv-muted);
}
.btn-icono:hover { background: var(--uv-surface-2); color: var(--uv-ink); }

/* ---------- ayuda de teclado ---------- */
.uv-teclas { display: flex; gap: .9rem; flex-wrap: wrap; align-items: center;
             color: var(--uv-muted); font-size: .78rem; }
kbd.uv-k {
  font: 600 10.5px/1 var(--uv-mono); background: var(--uv-surface);
  border: 1px solid var(--uv-line); border-bottom-width: 2px; border-radius: .25rem;
  padding: .18rem .34rem; color: var(--uv-ink);
}

/* ---------- vacío ---------- */
.uv-vacio { text-align: center; padding: 3rem 1rem; color: var(--uv-muted); }
.uv-vacio .ic { color: var(--uv-line); margin-bottom: .75rem; }
.uv-vacio h3 { font-size: 1rem; color: var(--uv-ink); margin-bottom: .3rem; }

/* ---------- accesibilidad ---------- */
:focus-visible { outline: 2px solid var(--uv-accent); outline-offset: 2px; }
.solo-lectores {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap;
}

/* ---------- responsivo ---------- */
@media (max-width: 1200px) {
  .uv-bandeja { grid-template-columns: 1fr; }
  .uv-detalle { position: static; }
}
@media (max-width: 992px) {
  :root { --uv-lateral: 0px; }
  .uv-lateral {
    transform: translateX(-100%); width: 260px;
    transition: transform .18s ease; box-shadow: var(--uv-sombra);
  }
  .uv-lateral.abierto { transform: translateX(0); }
  .uv-contenido { padding: 1rem; }
  .uv-buscador { max-width: none; }
}
@media (min-width: 993px) { .uv-alternar-lateral { display: none; } }
@media (max-width: 576px) {
  .uv-tarjeta-pedido { grid-template-columns: auto minmax(0,1fr); }
  .uv-tarjeta-pedido .total { grid-column: 2; text-align: left; }
  .uv-encabezado h1 { font-size: 1.2rem; }
}
@media (prefers-reduced-motion: reduce) { * { transition: none !important; animation: none !important; } }

/* ---------- hilo de conversación ---------- */
.uv-hilo { display: flex; flex-direction: column; gap: .45rem; }
.uv-burbuja {
  max-width: 88%; padding: .5rem .7rem; border-radius: .6rem;
  font-size: .84rem; line-height: 1.45; white-space: pre-wrap; word-break: break-word;
}
.uv-burbuja.entrante {
  align-self: flex-start; background: var(--uv-surface-2);
  border-bottom-left-radius: .15rem;
}
.uv-burbuja.saliente {
  align-self: flex-end; background: var(--uv-accent-soft); color: var(--uv-ink);
  border-bottom-right-radius: .15rem;
}
.uv-burbuja .sello {
  display: block; margin-top: .3rem; font-size: .68rem; color: var(--uv-muted);
  font-family: var(--uv-mono); letter-spacing: .04em;
}

/* ---------- paradas de ruta ---------- */
.uv-paradas { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 2px; }
.uv-parada {
  display: grid; grid-template-columns: 26px minmax(0,1fr) auto auto auto;
  gap: .5rem; align-items: center; padding: .4rem .5rem;
  border-radius: .35rem; font-size: .875rem; background: var(--uv-surface);
}
.uv-parada:hover { background: var(--uv-surface-2); }
.uv-parada[draggable="true"] { cursor: grab; }
.uv-parada.arrastrando { opacity: .4; }
.uv-parada.destino { box-shadow: inset 0 2px 0 var(--uv-accent); }
.uv-parada .orden {
  font: 600 11px/1 var(--uv-mono); color: var(--uv-muted);
  background: var(--uv-surface-2); border-radius: .25rem; padding: .3rem 0; text-align: center;
}
.uv-parada .monto { font-variant-numeric: tabular-nums; font-weight: 600; white-space: nowrap; }
.uv-parada .asa { color: var(--uv-line); }
.uv-parada:hover .asa { color: var(--uv-muted); }

/* ---------- impresión de la hoja de carga ---------- */
@media print {
  .uv-barra, .uv-lateral, .uv-acciones, .no-imprimir { display: none !important; }
  .uv-contenido { margin: 0; padding: 0; }
  .uv-panel { border: none; box-shadow: none; }
  body { background: #fff; color: #000; font-size: 11pt; }
  .uv-tabla th { background: #eee !important; color: #000 !important; }
}

/* ==========================================================================
   Cargador y confirmación
   Dos piezas transversales: el velo que aparece mientras algo tarda, y el
   cuadro que pregunta antes de una acción que no se puede deshacer.
   El confirm() del navegador servía, pero se ve ajeno, no se puede explicar
   nada con formato y en el móvil sale con el dominio del sitio adelante.
   ========================================================================== */
.uv-velo {
  position: fixed; inset: 0; z-index: 1090;
  display: flex; align-items: center; justify-content: center;
  background: rgba(11, 31, 42, .32);
  backdrop-filter: blur(2px);
  opacity: 0; transition: opacity .16s ease;
}
.uv-velo.visible { opacity: 1; }

.uv-cargador {
  background: var(--uv-surface);
  border: 1px solid var(--uv-line);
  border-radius: 14px;
  box-shadow: var(--uv-sombra);
  padding: 22px 26px;
  min-width: 232px; max-width: 340px;
  text-align: center;
  transform: translateY(6px) scale(.98);
  transition: transform .16s ease;
}
.uv-velo.visible .uv-cargador { transform: none; }

/* Anillo: dos arcos girando a distinta velocidad. Se lee como progreso sin
   prometer un porcentaje que no conocemos. */
.uv-anillo {
  width: 40px; height: 40px; margin: 0 auto 14px;
  border-radius: 50%;
  border: 3px solid var(--uv-surface-2);
  border-top-color: var(--uv-accent);
  border-right-color: var(--uv-accent);
  animation: uv-girar .9s linear infinite;
}
@keyframes uv-girar { to { transform: rotate(360deg); } }

.uv-cargador .mensaje { font-size: .92rem; font-weight: 600; color: var(--uv-ink); }
.uv-cargador .demora {
  margin-top: 6px; font-size: .78rem; color: var(--uv-muted);
  opacity: 0; transition: opacity .3s ease;
}
.uv-cargador .demora.visible { opacity: 1; }

/* ---------- confirmación ---------- */
.uv-confirmar {
  background: var(--uv-surface);
  border: 1px solid var(--uv-line);
  border-radius: 14px;
  box-shadow: var(--uv-sombra);
  width: min(440px, calc(100vw - 32px));
  overflow: hidden;
  transform: translateY(8px) scale(.98);
  transition: transform .16s ease;
}
.uv-velo.visible .uv-confirmar { transform: none; }

.uv-confirmar .cabeza {
  display: flex; align-items: center; gap: 10px;
  padding: 16px 18px 0;
  font-size: 1.02rem; font-weight: 700; color: var(--uv-ink);
}
.uv-confirmar .cabeza .marca {
  width: 34px; height: 34px; flex: none;
  display: grid; place-items: center;
  border-radius: 9px;
  background: var(--uv-cool-soft); color: var(--uv-cool);
}
.uv-confirmar.peligro .cabeza .marca { background: var(--uv-danger-soft); color: var(--uv-danger); }

.uv-confirmar .cuerpo {
  padding: 10px 18px 18px 62px;
  font-size: .9rem; color: var(--uv-muted); line-height: 1.45;
  white-space: pre-line;   /* respeta los saltos del mensaje */
}
.uv-confirmar .pie {
  display: flex; justify-content: flex-end; gap: 8px;
  padding: 12px 18px;
  background: var(--uv-ground);
  border-top: 1px solid var(--uv-line);
}

@media (prefers-reduced-motion: reduce) {
  .uv-velo, .uv-cargador, .uv-confirmar { transition: none; }
  .uv-anillo { animation-duration: 1.6s; }
}

/* ==========================================================================
   Modal que se puede mover
   El modal con data-arrastrable se agarra por el encabezado (comun.js hace el
   resto). El cursor es lo único que lo anuncia: nadie va a intentar mover una
   ventana que no dice que se mueve.
   ========================================================================== */
.modal[data-arrastrable] .modal-header { cursor: move; user-select: none; }
.modal[data-arrastrable].uv-moviendo .modal-header { cursor: grabbing; }

/* Mientras se arrastra, el diálogo sigue al ratón sin la transición de
   Bootstrap detrás, que lo dejaba yendo un paso atrás del puntero. */
.modal[data-arrastrable].uv-moviendo .modal-dialog { transition: none; }

/* En pantalla chica el modal ya ocupa casi todo: no se mueve, y el cursor no
   debe prometer que sí. */
@media (max-width: 767.98px) {
  .modal[data-arrastrable] .modal-header { cursor: default; }
}

/* ==========================================================================
   Modal con el cuerpo desplazable
   Bootstrap arma .modal-dialog-scrollable contando con que el encabezado, el
   cuerpo y el pie sean hijos directos de .modal-content, que es la columna
   flexible. Cuando el modal es un formulario y hay un <form> en el medio, esa
   columna se corta: el cuerpo pierde su altura máxima, no saca su barra, crece
   cuanto quiera y lo que sobra --el pie con el botón de registrar incluido--
   queda debajo del borde, escondido por el overflow:hidden del contenido.

   Se le devuelve al form el papel que el contenido le delegó. El min-height:0
   es lo que permite que el cuerpo se encoja: sin él, un flex item nunca baja
   del tamaño de su contenido y no hay nada que desplazar.
   ========================================================================== */
.modal-dialog-scrollable .modal-content > form {
  display: flex;
  flex-direction: column;
  min-height: 0;
  max-height: 100%;
}

/* ==========================================================================
   Diálogos nativos
   La clase se usaba en Impuestos y en Facturación pero no existía en el CSS:
   un <dialog> sin ancho se estira a lo que le permita el contenido, y con dos
   columnas de formulario eso terminaba en un cuadro de 1300 px para pedir
   cuatro datos. El ancho se fija acá, no en cada vista.
   ========================================================================== */
.uv-dialogo {
  width: min(560px, calc(100vw - 32px));
  padding: 20px 22px;
  border: 1px solid var(--uv-line);
  border-radius: 14px;
  background: var(--uv-surface);
  color: var(--uv-ink);
  box-shadow: var(--uv-sombra);
}
.uv-dialogo::backdrop { background: rgba(11, 31, 42, .32); backdrop-filter: blur(2px); }

.uv-dialogo h3 {
  font: 700 1.05rem/1.3 var(--uv-titulo);
  margin: 0 0 14px;
}
.uv-dialogo .form-label { font-size: .78rem; margin-bottom: .15rem; }
.uv-dialogo .form-control, .uv-dialogo .form-select { font-size: .875rem; }

/* Las acciones abajo a la derecha y separadas del formulario. */
.uv-dialogo .uv-dialogo-pie {
  display: flex; justify-content: flex-end; gap: .5rem;
  margin-top: 18px; padding-top: 14px;
  border-top: 1px solid var(--uv-line);
}

/* ---------- cruces de cartera ----------
   A la izquierda los clientes con algo que cruzar; a la derecha sus documentos
   y, pegada abajo, la cuenta de lo que se toma y lo que se cancela: el botón
   solo se habilita cuando los dos lados dan igual. */
.uv-cruce-clientes { display: flex; flex-direction: column; }
.uv-cruce-cliente {
  display: block; padding: .65rem .95rem; color: inherit; text-decoration: none;
  border-bottom: 1px solid var(--uv-line); border-left: 3px solid transparent;
}
.uv-cruce-cliente:last-child { border-bottom: 0; }
.uv-cruce-cliente:hover { background: var(--uv-surface-2); color: inherit; }
.uv-cruce-cliente.activo { background: var(--uv-accent-soft); border-left-color: var(--uv-accent); }
.uv-cruce-cliente .nombre { font-weight: 600; }
.uv-cruce-cliente .cifras {
  display: flex; gap: .75rem; flex-wrap: wrap;
  font-size: .8rem; color: var(--uv-muted); font-variant-numeric: tabular-nums;
}
.uv-cruce-valor { width: 8.5rem; max-width: 100%; text-align: right; font-variant-numeric: tabular-nums; }
.uv-cruce-pie {
  position: sticky; bottom: .75rem; z-index: 5;
  display: flex; flex-wrap: wrap; align-items: center; gap: .6rem 1.1rem;
  padding: .75rem .95rem; background: var(--uv-surface);
  border: 1px solid var(--uv-line); border-radius: .55rem; box-shadow: var(--uv-sombra);
}
.uv-cruce-pie .cifra { display: flex; flex-direction: column; font-size: .74rem; color: var(--uv-muted); }
.uv-cruce-pie .cifra strong { font-size: 1.05rem; color: var(--uv-ink); font-variant-numeric: tabular-nums; }
.uv-cruce-pie .estado { font-size: .82rem; }
.uv-cruce-pie .estado.cuadra { color: var(--uv-accent); }
.uv-cruce-pie .estado.descuadre { color: var(--uv-signal); }


/* Menu de la consola de plataforma.
   Horizontal y no lateral como el del back office: son cinco secciones, y una
   barra fija de 236 px le quitaria al contenido mas de lo que aporta. */
.uv-menu-plataforma {
  position: sticky; top: var(--uv-barra); z-index: 5;
  display: flex; flex-wrap: wrap; gap: .1rem;
  padding: 0 1.5rem; background: var(--uv-surface);
  border-bottom: 1px solid var(--uv-line);
}
.uv-menu-plataforma a {
  display: inline-flex; align-items: center; gap: .4rem;
  padding: .6rem .8rem; margin-bottom: -1px;
  border-bottom: 2px solid transparent;
  color: var(--uv-muted); text-decoration: none;
  font-size: .88rem; font-weight: 500; white-space: nowrap;
}
.uv-menu-plataforma a .ic { color: var(--uv-muted); }
.uv-menu-plataforma a:hover { color: var(--uv-ink); }
.uv-menu-plataforma a:hover .ic { color: var(--uv-accent); }
.uv-menu-plataforma a.activo { color: var(--uv-accent); border-bottom-color: var(--uv-accent); }
.uv-menu-plataforma a.activo .ic { color: var(--uv-accent); }

/* ---------- combo con alta en el lugar ----------
   Un combo de maestros con un + al lado: al tocarlo, el combo cede su lugar a
   un campo de texto con guardar y cancelar. Sin ventana encima de la ventana. */
.uv-combo-mas { display: flex; align-items: center; gap: .25rem; }
.uv-combo-mas > select,
.uv-combo-mas > input { flex: 1 1 auto; min-width: 0; }
.uv-combo-mas > .btn-icono { flex: none; width: 30px; height: 30px; }
/* El código de la unidad es corto --KG, UN, LT--: no merece medio renglón. */
.uv-combo-mas > .uv-combo-codigo { flex: 0 0 5.5rem; }

/* ---------- movimientos de inventario ----------
   El modal de entrada, salida y ajuste, y el detalle de un movimiento. */

/* El tipo como botones pegados: se ve de un vistazo cuál está elegido. */
.uv-segmentos { display: inline-flex; border: 1px solid var(--uv-line); border-radius: .45rem; overflow: hidden; }
.uv-segmentos > .btn {
  display: inline-flex; align-items: center; gap: .35rem; border: 0; border-radius: 0;
  background: var(--uv-surface); color: var(--uv-muted); font-weight: 500;
}
.uv-segmentos > label.btn:not(:first-of-type) { border-left: 1px solid var(--uv-line); }
.uv-segmentos > .btn:hover { background: var(--uv-surface-2); color: var(--uv-ink); }
.uv-segmentos > .btn-check:checked + .btn { background: var(--uv-accent); color: #fff; }
.uv-segmentos > .btn-check:focus-visible + .btn { outline: 2px solid var(--uv-accent); outline-offset: -2px; }

/* La grilla de existencias: una fila por producto que se despliega en sus
   presentaciones, y la columna para marcar lo que se va a mover. */
.uv-col-desplegar { width: 2.6rem; }
.uv-col-marcar { width: 6rem; text-align: center; }
.uv-marcar-todo {
  display: inline-flex; align-items: center; gap: .35rem; margin: 0; cursor: pointer;
  font: inherit; letter-spacing: inherit; text-transform: inherit;
}
.uv-desplegar .ic { transition: transform .15s ease; }
.uv-inv-grupo.abierto .uv-desplegar .ic { transform: rotate(90deg); }
.uv-link-desplegar {
  background: none; border: 0; padding: 0; color: var(--uv-accent); font: inherit; font-weight: 500;
}
.uv-link-desplegar:hover { text-decoration: underline; }
.uv-tabla-inventario tr.uv-inv-presentacion > td { background: var(--uv-surface-2); }
.uv-tabla-inventario tr.uv-inv-presentacion > td:nth-child(3) { padding-left: 1.2rem; }
.uv-tabla-inventario tr.marcada > td { background: var(--uv-accent-soft); }

/* El número de marcadas en el botón Registrar. */
.uv-contador {
  display: inline-grid; place-items: center; min-width: 1.35rem; height: 1.35rem; padding: 0 .35rem;
  border-radius: 999px; background: rgba(255, 255, 255, .25); font-size: .74rem; font-weight: 600;
}

/* El modal de registro: rótulos de sección, aviso en línea y el detalle. */
.uv-seccion {
  margin-bottom: .45rem; color: var(--uv-muted); font-size: .72rem; font-weight: 600;
  letter-spacing: .06em; text-transform: uppercase;
}
.uv-aviso-linea {
  display: flex; align-items: flex-start; gap: .5rem; padding: .55rem .7rem; border-radius: .45rem;
  background: var(--uv-signal-soft); color: var(--uv-ink); font-size: .85rem;
}
.uv-aviso-linea .ic { color: var(--uv-signal); flex: none; margin-top: .1rem; }
.uv-reg-campo { width: 7.5rem; margin-left: auto; }
.uv-tabla-registro tr.se-mueve > td { background: var(--uv-accent-soft); }
.uv-tabla-registro tfoot td { border-top: 2px solid var(--uv-line); }

/* El detalle se lleva la barra, y no el modal entero: la fecha, el documento y
   el proveedor siguen a la vista mientras se recorren treinta presentaciones.
   Los títulos de columna y la fila de totales se quedan pegados a sus bordes
   --con «en bodega», «cantidad» y «quedará» todas en números, una columna sin
   título arriba no se sabe cuál es--.

   Las líneas van por dentro, como sombra: con border-collapse el borde de una
   celda pegajosa se queda en su sitio al desplazar y la raya desaparece. */
.uv-cuerpo-detalle { display: flex; flex-direction: column; }
.uv-cuerpo-detalle > .table-responsive {
  flex: 1 1 auto; min-height: 7rem; overflow: auto;
}
.uv-cuerpo-detalle thead th {
  position: sticky; top: 0; z-index: 2;
  border-bottom: 0; box-shadow: inset 0 -1px 0 var(--uv-line);
}
/* El bottom:-1px es por el redondeo: el alto del contenedor cae en una
   fracción de píxel y a los totales les quedaba asomando por debajo una línea
   de la fila siguiente. */
.uv-cuerpo-detalle tfoot td {
  position: sticky; bottom: -1px; z-index: 2;
  background: var(--uv-surface); border-top: 0; box-shadow: inset 0 2px 0 var(--uv-line);
}

/* El cálculo del inventario en Movimientos: cuatro cajas con sus signos. */
.uv-calculo {
  display: grid; grid-template-columns: 1fr auto 1fr auto 1fr auto 1fr; align-items: stretch;
  gap: .5rem; padding: .9rem 1rem;
}
.uv-calculo-caja {
  padding: .65rem .8rem; border: 1px solid var(--uv-line); border-radius: .5rem; background: var(--uv-surface);
}
.uv-calculo-caja .rotulo {
  color: var(--uv-muted); font-size: .72rem; font-weight: 600; letter-spacing: .06em; text-transform: uppercase;
}
.uv-calculo-caja .valor { font-size: 1.15rem; font-weight: 600; font-variant-numeric: tabular-nums; }
.uv-calculo-caja .cantidad { color: var(--uv-muted); font-size: .82rem; font-variant-numeric: tabular-nums; }
.uv-calculo-caja .nota { margin-top: .25rem; color: var(--uv-muted); font-size: .74rem; }
.uv-calculo-caja.final { border-color: var(--uv-accent); background: var(--uv-accent-soft); }
.uv-calculo-caja.final .valor { color: var(--uv-accent); }
.uv-calculo-signo { display: grid; place-items: center; color: var(--uv-muted); font-size: 1.3rem; font-weight: 600; }
@media (max-width: 900px) {
  .uv-calculo { grid-template-columns: 1fr; }
  .uv-calculo-signo { padding: 0; }
}

/* El inventario inicial: la tabla larga desplaza por dentro y el pie queda a la vista. */
.uv-inicial-tabla { max-height: 62vh; overflow-y: auto; }
.uv-inicial-tabla thead th { position: sticky; top: 0; z-index: 2; }
.uv-inicial-tabla tr.se-mueve > td { background: var(--uv-accent-soft); }
.uv-inicial-pie {
  display: flex; flex-wrap: wrap; align-items: center; gap: .9rem; padding: .7rem 1rem;
  border-top: 1px solid var(--uv-line); font-size: .85rem;
}
.uv-inicial-cifra strong { font-variant-numeric: tabular-nums; }
.uv-errores-lectura {
  margin: .6rem 1rem; padding: .6rem .8rem; border-radius: .45rem;
  background: var(--uv-danger-soft); color: var(--uv-ink); font-size: .84rem;
}
.uv-errores-lectura .ic { color: var(--uv-danger); }
.uv-errores-lectura ul { padding-left: 1.4rem; margin-top: .35rem; }

/* Las casillas con el verde de la marca y no con el azul de Bootstrap. */
/* Con la misma especificidad de Bootstrap, que para la casilla a medias usa
   [type=checkbox] y le ganaba a la regla sin él. */
.form-check-input:checked,
.form-check-input[type=checkbox]:indeterminate { background-color: var(--uv-accent); border-color: var(--uv-accent); }
.form-check-input:focus { border-color: var(--uv-accent); box-shadow: 0 0 0 .2rem var(--uv-accent-soft); }

/* Lo que sube y lo que baja la existencia. */
.uv-sube { color: var(--uv-accent); }
.uv-baja { color: var(--uv-danger); }

/* Los datos del encabezado en el detalle: rótulo y valor en dos columnas. */
.uv-detalle-datos { display: grid; grid-template-columns: max-content 1fr; gap: .25rem 1rem; margin-bottom: 1rem; font-size: .88rem; }
.uv-detalle-datos:empty { display: none; }
.uv-detalle-datos dt { color: var(--uv-muted); font-weight: 500; }
.uv-detalle-datos dd { margin: 0; }

/* ===================== INVENTARIO FÍSICO =====================
   El conteo se hace de pie frente a la estantería: lo que se acaba de anotar
   tiene que verse sin buscarlo, y lo último leído tiene que quedar a la vista
   para saber que el lector sí disparó. */
.uv-destello { animation: uv-destello 1.1s ease-out 1; }

@keyframes uv-destello {
    0%   { background: color-mix(in srgb, var(--uv-brand) 26%, transparent); }
    100% { background: transparent; }
}

@media (prefers-reduced-motion: reduce) {
    .uv-destello { animation: none; }
}

.uv-recientes ul { display: flex; flex-wrap: wrap; gap: .35rem; }

.uv-recientes li {
    background: var(--uv-surface-2);
    border: 1px solid var(--uv-line);
    border-radius: 999px;
    padding: .15rem .6rem;
    font-size: .8rem;
}

/* La primera es la de hace un segundo: se distingue de las anteriores. */
.uv-recientes li:first-child {
    border-color: var(--uv-brand);
    font-weight: 600;
}

/* ===================== DEVOLUCIONES =====================
   La lista de facturas del modal: se elige con un clic, y cada una dice lo
   suficiente para reconocerla sin abrirla. */
.uv-facturas { display: flex; flex-direction: column; gap: .25rem; max-height: 210px; overflow-y: auto; }

.uv-factura {
    display: grid;
    grid-template-columns: 7rem 1fr 6rem 7rem auto;
    gap: .5rem;
    align-items: center;
    text-align: left;
    background: var(--uv-surface-2);
    border: 1px solid var(--uv-line);
    border-radius: .45rem;
    padding: .4rem .6rem;
    font-size: .85rem;
    color: inherit;
}

.uv-factura:hover, .uv-factura:focus-visible { border-color: var(--uv-brand); }
.uv-factura .numero { font-weight: 600; }
.uv-factura .cliente { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.uv-factura .fecha, .uv-factura .total { color: var(--uv-muted); text-align: right; }

@media (max-width: 640px) {
    .uv-factura { grid-template-columns: 1fr 1fr; }
}

/* ===================== CONSULTAS =====================
   El menú de consultas son tarjetas que se tocan enteras; la consulta abierta es
   una tabla ancha, con los títulos fijos al bajar y los totales al pie. */
.uv-consultas-area { margin-bottom: 1.5rem; }

.uv-consultas-tarjetas {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(290px, 1fr));
    gap: .75rem;
}

.uv-consulta-tarjeta {
    display: flex;
    gap: .75rem;
    align-items: flex-start;
    padding: .9rem 1rem;
    background: var(--uv-surface);
    border: 1px solid var(--uv-line);
    border-radius: .6rem;
    color: inherit;
    text-decoration: none;
}

.uv-consulta-tarjeta:hover, .uv-consulta-tarjeta:focus-visible {
    border-color: var(--uv-brand);
    color: inherit;
}

.uv-consulta-tarjeta .icono {
    flex: 0 0 auto;
    display: grid;
    place-items: center;
    width: 2.4rem;
    height: 2.4rem;
    border-radius: .5rem;
    background: color-mix(in srgb, var(--uv-brand) 12%, transparent);
    color: var(--uv-brand);
}

.uv-consulta-tarjeta .texto { display: flex; flex-direction: column; gap: .25rem; min-width: 0; }
.uv-consulta-tarjeta .nombre { font-weight: 600; }
.uv-consulta-tarjeta .descripcion { font-size: .82rem; color: var(--uv-muted); }
.uv-consulta-tarjeta .etiquetas { display: flex; gap: .3rem; flex-wrap: wrap; margin-top: .15rem; }

.uv-migas { font-size: .8rem; color: var(--uv-muted); margin-bottom: .15rem; }
.uv-migas a { color: inherit; }

.uv-consulta-tabla { max-height: 68vh; overflow: auto; }

.uv-consulta-tabla thead th {
    position: sticky;
    top: 0;
    z-index: 1;
    background: var(--uv-surface-2);
}

.uv-consulta-tabla tfoot td {
    position: sticky;
    bottom: 0;
    background: var(--uv-surface-2);
    border-top: 2px solid var(--uv-line);
}

.uv-consulta-tabla td { white-space: nowrap; }
.uv-fila-destacada td { background: var(--uv-surface-2); font-weight: 600; }
