/* ============================================================================
   dhtordo-v5.css  ·  Capa 6 — estilos propios del sistema

   Va SIEMPRE última, después de tokens, puente y componentes.

   Tiene dos trabajos:

   1. La base que en dhTordo v4 ponía el reboot de Bootstrap. V5 no carga
      Bootstrap: el puente ya define .btn, .form-control, .card y .alert con
      declaraciones completas, así que lo único que faltaba era el piso —
      box-sizing, tipografía del cuerpo, fondo, títulos, enlaces.

   2. Lo poco que el kit no trae porque es de este sistema: el aviso dentro de
      la pantalla de acceso, el contador de pantallas sin migrar del menú, y
      la grilla del perfil.

   Si algún día V5 suma Bootstrap 5, se borra el bloque 1 y nada más.
   ============================================================================ */

/* ============================ 1 · BASE =================================== */

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--f-ui);
  font-size: 14px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4 { font-family: var(--f-display); font-weight: 600; letter-spacing: -.02em; margin: 0; }

a { color: var(--accent-ink); text-decoration: none; }
a:hover { color: var(--accent-press); }

button, input, select, textarea { font: inherit; color: inherit; }
button { cursor: pointer; }

img, svg { vertical-align: middle; }

hr { border: 0; border-top: 1px solid var(--line); margin: 20px 0; }

.form-control { display: block; width: 100%; }
label, .form-label { display: block; }

.alert { display: block; padding: 10px 13px; border: 1px solid transparent; border-radius: var(--r-sm); font-size: 13px; }

/* Utilitarios mínimos, los que hacen falta en estas dos pantallas. */
.dh-stack   { display: grid; gap: 16px; }
.dh-row-end { display: flex; justify-content: flex-end; gap: 8px; }
.dh-mut     { color: var(--text-2); }
.dh-mono    { font-family: var(--f-data); }
.dh-sr {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap;
}

/* ==================== 2 · PROPIO DE dhTordo V5 =========================== */

/* ---- Pantalla de acceso -------------------------------------------------- */
.dh-gate-alert { margin-bottom: 18px; }

.dh-gate-form form { display: grid; gap: 15px; }

/* La pantalla de acceso no tiene menú donde poner la firma de la casa, y el
   pie del panel oscuro desaparece en pantallas angostas. Este es el reemplazo. */
.dh-gate-note b { color: var(--au-dp); font-weight: 500; }

/* La entrada de la demo pública (core/demo.php): «Entrar como…» por rol, en
   tarjetas grandes; el formulario de siempre queda plegado abajo. */
.dh-gate-demo .dh-gate-box { max-width: 560px; }
.dh-demo-roles { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; margin-bottom: 22px; }
.dh-demo-roles form { display: block; }
.dh-demo-rol {
  display: flex; flex-direction: column; align-items: flex-start; gap: 4px; width: 100%; height: 100%;
  min-height: 118px; padding: 16px 16px 14px; text-align: left; cursor: pointer;
  background: var(--surface); color: var(--text); border: 1px solid var(--line); border-radius: var(--r);
  box-shadow: var(--sh-1); transition: border-color .15s, box-shadow .15s, transform .15s;
  font: inherit;
}
.dh-demo-rol:hover, .dh-demo-rol:focus-visible { border-color: var(--accent); box-shadow: var(--sh-2); transform: translateY(-1px); outline: none; }
.dh-demo-rol span { font-size: 11px; letter-spacing: .08em; text-transform: uppercase; color: var(--text-3); font-weight: 500; }
.dh-demo-rol b { font-family: var(--f-display); font-size: 18px; font-weight: 600; letter-spacing: -.02em; line-height: 1.15; }
.dh-demo-rol em { font-style: normal; font-size: 12.5px; color: var(--text-2); line-height: 1.35; }
.dh-demo-otro { border-top: 1px solid var(--line); padding-top: 14px; }
.dh-demo-otro summary { cursor: pointer; font-size: 13px; color: var(--text-2); margin-bottom: 4px; }
.dh-demo-otro[open] summary { margin-bottom: 16px; }
.dh-demo-otro h2 { display: none; }
@media (max-width: 480px) { .dh-demo-roles { grid-template-columns: 1fr; } .dh-demo-rol { min-height: 0; } }

/* ---- Menú lateral -------------------------------------------------------- */
/* `desa` arranca vacío: el menú sólo lista lo migrado y esto informa el resto.
   Se ve claramente como un dato de estado y no como una opción del menú. */
.dh-nav-pend {
  margin-top: 6px;
  padding-top: 12px;
  border-top: 1px dashed var(--nav-line);
  color: var(--nav-sec-c);
  font-style: italic;
  text-transform: none;
  letter-spacing: 0;
}

/* ---- Perfil -------------------------------------------------------------- */
.dh-perfil {
  display: grid;
  grid-template-columns: minmax(0, 300px) minmax(0, 1fr);
  gap: 16px;
  align-items: start;
}
@media (max-width: 900px) { .dh-perfil { grid-template-columns: 1fr; } }

.dh-perfil-id { text-align: center; padding: 26px 20px 22px; }
.dh-perfil-id .dh-av { margin: 0 auto 14px; width: 76px; height: 76px; font-size: 25px; }
.dh-perfil-id h2 { font-size: 19px; }
.dh-perfil-id p  { margin: 4px 0 0; color: var(--text-2); font-size: 13px; }

.dh-datos { list-style: none; margin: 20px 0 0; padding: 0; text-align: left; }
.dh-datos li {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 0; border-top: 1px solid var(--line-soft);
  font-size: 13px;
}
.dh-datos li:first-child { border-top: 0; }
.dh-datos .dh-icon { color: var(--text-3); }
.dh-datos span { color: var(--text-3); margin-left: auto; text-align: right; }

/* Lista simple para las cuentas de una asignación: son dos o tres nombres, no
   una grilla. Sin iconos, a diferencia de .dh-datos. */
.dh-lista { list-style: none; margin: 0; padding: 0; }
.dh-lista li {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 0; border-top: 1px solid var(--line-soft); font-size: 13px;
}
.dh-lista li:first-child { border-top: 0; }

/* El puente estiliza .card; acá sólo se le da aire por dentro. */
.card-body   { padding: 20px 22px 22px; }
.card-header {
  padding: 14px 22px;
  border-bottom: 1px solid var(--line);
  font-family: var(--f-display); font-weight: 600; font-size: 15px;
}

/* El enso no trae medida propia: el kit se la da sólo dentro de .dh-credit. */
.dh-gate-brand .dh-enso { width: 132px; height: 132px; }

/* El kit pinta el enso con `.dh-enso path { fill:none; stroke:url(#dhAuGrad) }`,
   pero los selectores CSS no entran al árbol sombra que genera <use>: el enso
   salía como un disco negro. `fill` y `stroke` sí se heredan, así que van sobre
   el <svg> y bajan solos a los path clonados.
   (Vale para todo el kit, no sólo acá: el armazón de referencia usa <use>.) */
.dh-enso {
  fill: none;
  stroke: url(#dhAuGrad);
  stroke-linecap: round;
}

/* El puente no define el estado deshabilitado del botón: sin esto, el botón
   de guardar del perfil se ve idéntico habilitado y deshabilitado. */
.btn:disabled,
.btn[disabled] { opacity: .45; cursor: not-allowed; pointer-events: none; }

/* ---- Censo de personas y ficha ------------------------------------------ */
.dh-kpis { display: grid; gap: 14px; margin-bottom: 18px;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); }
.dh-kpi {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-lg); padding: 15px 18px 16px; box-shadow: var(--sh-1);
}
.dh-kpi-t { font-size: 12px; color: var(--text-2); }
.dh-kpi-v { font-family: var(--f-data); font-size: 30px; font-weight: 700;
  line-height: 1.1; margin-top: 4px; font-variant-numeric: tabular-nums; }
.dh-kpi-f { font-size: 11.5px; color: var(--text-3); margin-top: 6px; line-height: 1.45; }
.dh-kpi.is-alerta { border-color: var(--accent-line); }
.dh-kpi.is-alerta .dh-kpi-v { color: var(--accent-ink); }

/* ============================================================================
   TABLA COMPACTA

   La primera versión usaba 44px de alto de fila, 14px de padding y 13.5px de
   letra, y el panel de vendedores no entraba: había que correrse en horizontal
   para ver el centro de costo, y no quedaba lugar para la columna de la
   derecha. La v4, con 12px de letra, entra entera Y deja esa columna.

   Una grilla operativa se mira todo el día y lo que importa es cuántas filas se
   ven de una vez, no que respire. Los números de acá salen de medir contra la
   pantalla de v4, no de redondear para abajo:

       alto de fila   44px -> 30px
       padding        14px -> 8px
       letra        13.5px -> 12px
       botón          28px -> 22px

   Y otro apretón el 03/09/2026, por el listado de productos: son DIEZ columnas
   con importe y porcentaje en cinco de ellas, y con 12px se corría en
   horizontal. Fila a 26px, letra a 11px y cabecera a 9.5px.

   El desplazamiento propio se conserva igual: si una tabla no entra —y alguna
   no va a entrar— se corre ella, nunca el cuerpo de la página.
   ========================================================================== */
.dh-tabla { overflow-x: auto; max-width: 100%; }
.card { min-width: 0; }
.dh-tabla table { border-collapse: collapse; width: 100%; font-size: 11px; }
.dh-tabla th, .dh-tabla td {
  padding: 0 5px; height: 26px; text-align: left;
  border-bottom: 1px solid var(--line-soft); white-space: nowrap;
}
.dh-tabla thead th {
  font-size: 9.5px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase;
  color: var(--text-3); background: var(--surface-2);
  border-bottom: 1px solid var(--line); position: sticky; top: 0;
}

/* La razón social es lo único que puede ser largo de verdad. Se le deja partir
   antes que empujar a las demás fuera de la pantalla. */
.dh-tabla td.dh-ancho { white-space: normal; min-width: 220px; }
.dh-tabla tbody tr:last-child td { border-bottom: 0; }
.dh-tabla tbody tr:hover { background: var(--surface-2); }
.dh-num { text-align: right; font-family: var(--f-data); font-variant-numeric: tabular-nums; }
/* Título y cifra a la derecha, los dos. `.dh-tabla td` (más específico) dejaba
   la cifra a la izquierda y el título a la derecha: se leían columnas cruzadas. */
.dh-tabla th.dh-num, .dh-tabla td.dh-num { text-align: right; }

.dh-tag {
  display: inline-block; font-size: 10.5px; font-weight: 500; letter-spacing: .04em;
  padding: 1px 7px; border-radius: 100px;
  background: var(--surface-3); color: var(--text-3); vertical-align: middle;
}
.dh-alerta { color: var(--accent-ink); }
.es-multiple td:first-child { box-shadow: inset 3px 0 0 var(--accent); }
.es-oculto { opacity: .55; }

.dh-ficha { display: grid; gap: 16px; align-items: start;
  grid-template-columns: minmax(0, 300px) minmax(0, 1fr); }
@media (max-width: 980px) { .dh-ficha { grid-template-columns: 1fr; } }
.dh-ficha-id { text-align: center; padding: 26px 20px 22px; }
.dh-ficha-id .dh-av { margin: 0 auto 14px; width: 76px; height: 76px; font-size: 25px; }
.dh-ficha-id h2 { font-size: 19px; }
.dh-ficha-id p { margin: 4px 0 0; color: var(--text-2); font-size: 13px; }
.dh-ficha-cuerpo {
  display: grid; gap: 16px; min-width: 0;
  /* Sin esto las tarjetas se dimensionan por el ancho natural de su tabla y
     desbordan la columna: las pistas implícitas de grid son max-content. */
  grid-template-columns: minmax(0, 1fr);
}

/* ---- Menú de tres niveles ------------------------------------------------ */
/* `menu > submenu > item`. El esquema siempre tuvo los tres; el armazón sólo
   dibujaba dos, y Vendedores, Repartidores y Empleados terminaban colgando
   todos juntos de la misma sección. Se abre con <details>, sin JavaScript. */
.dh-nav-rama > summary {
  list-style: none;
  cursor: pointer;
  user-select: none;
}
.dh-nav-rama > summary::-webkit-details-marker { display: none; }

.dh-nav-rama > summary .dh-chev {
  width: 15px; height: 15px; margin-left: auto; flex: 0 0 auto;
  transition: transform .18s cubic-bezier(.4, 0, .2, 1);
}
.dh-nav-rama[open] > summary .dh-chev { transform: rotate(180deg); }
.dh-nav-rama[open] > summary { color: var(--nav-on); }

.dh-nav-hijos { display: grid; padding: 2px 0 6px; }
.dh-nav-hijo {
  display: block;
  padding: 6px 12px 6px 47px;      /* alineado con el texto del padre */
  font-size: 13px;
  color: var(--nav-text);
  text-decoration: none;
  border-left: 2px solid transparent;
}
.dh-nav-hijo:hover { color: var(--nav-on); background: rgba(255, 255, 255, .04); }
.dh-nav-hijo.is-on {
  color: var(--nav-on);
  border-left-color: var(--accent);
  background: rgba(255, 255, 255, .05);
}

/* Con el menú angosto no hay lugar para el tercer nivel. */
.dh-app.is-mini .dh-nav-rama > summary .dh-chev,
.dh-app.is-mini .dh-nav-hijos { display: none; }

/* ==========================================================================
   BARRA DE TABLA  ·  buscar, ordenar, paginar
   La dibuja dharma.js sobre cualquier <table data-dh-tabla>. Si el js no
   carga, nada de esto existe y la tabla se ve igual: por eso los estilos
   viven acá y no dependen de ninguna clase que ponga el servidor.
   ========================================================================== */
/* Cabecera: lo que se decide ANTES de mirar. El select de filas a la
   izquierda y el buscador a la derecha, como en la grilla de v4. */
.dh-tbar {
  display: flex; align-items: center; justify-content: space-between;
  gap: 10px; flex-wrap: wrap;
  padding: 10px 14px; border-bottom: 1px solid var(--line-soft);
}

/* Pie: lo que se lee DESPUÉS. Cuántas hay a la izquierda, el paginador a la
   derecha. Separarlo de la cabecera es lo que hace que el «Siguiente» quede
   al lado de la última fila y no a tres pantallas de scroll. */
.dh-tpie {
  display: flex; align-items: center; justify-content: space-between;
  gap: 10px; flex-wrap: wrap;
  padding: 10px 14px; border-top: 1px solid var(--line-soft);
}
.dh-tbar-b {
  display: flex; align-items: center; gap: 7px; flex: 0 1 340px; min-width: 200px;
  padding: 0 10px; height: 32px; border-radius: var(--r-xs);
  background: var(--surface-2); border: 1px solid var(--line-soft);
}
.dh-tbar-b:focus-within { border-color: var(--accent-line); }
.dh-tbar-b .dh-icon { width: 15px; height: 15px; color: var(--text-3); flex: none; }
.dh-tbar-b input {
  flex: 1; min-width: 0; border: 0; background: none; outline: none;
  font: inherit; font-size: 13px; color: var(--text);
}
.dh-tbar-n { font-size: 12px; color: var(--text-3); font-variant-numeric: tabular-nums; }
.dh-tbar-pg { display: flex; align-items: center; gap: 6px; }
.dh-tbar-pg > span { font-size: 12px; color: var(--text-3); font-variant-numeric: tabular-nums; }

/* Los números de página, en el centro del paginador. */
.dh-tbar-p { display: flex; align-items: center; gap: 2px; }
.dh-tpg {
  min-width: 30px; height: 30px; padding: 0 7px; cursor: pointer;
  font: inherit; font-size: 12.5px; font-variant-numeric: tabular-nums;
  color: var(--text-2); background: none;
  border: 1px solid transparent; border-radius: var(--r-xs);
}
.dh-tpg:hover { background: var(--surface-2); color: var(--text); }
.dh-tpg.es-actual {
  color: var(--accent-ink); background: var(--surface-2);
  border-color: var(--accent-line); font-weight: 600;
}
.dh-tpg-hueco { padding: 0 2px; color: var(--text-3); font-size: 12.5px; }
.dh-tbtn {
  height: 30px; padding: 0 11px; font: inherit; font-size: 12.5px; cursor: pointer;
  color: var(--text); background: var(--surface-2);
  border: 1px solid var(--line-soft); border-radius: var(--r-xs);
}
.dh-tbtn:hover:not(:disabled) { background: var(--surface-3); }
.dh-tbtn:disabled { opacity: .4; cursor: default; }

/* Cabecera ordenable. La flecha se dibuja con ::after para no tocar el HTML. */
.dh-tabla th.is-ord { cursor: pointer; user-select: none; }
.dh-tabla th.is-ord:hover { color: var(--text-2); }
.dh-tabla th.is-ord::after {
  content: '↕'; margin-left: 6px; opacity: .35; font-size: 10px;
}
.dh-tabla th.es-asc::after  { content: '↑'; opacity: 1; color: var(--accent-ink); }
.dh-tabla th.es-desc::after { content: '↓'; opacity: 1; color: var(--accent-ink); }
/* En una columna de cifras la flecha va a la izquierda del título, para que
   el título termine donde terminan los números. */
.dh-tabla th.dh-num.is-ord::after { content: none; }
.dh-tabla th.dh-num.is-ord::before { content: '↕'; margin-right: 6px; opacity: .35; font-size: 10px; }
.dh-tabla th.dh-num.es-asc::before  { content: '↑'; opacity: 1; color: var(--accent-ink); }
.dh-tabla th.dh-num.es-desc::before { content: '↓'; opacity: 1; color: var(--accent-ink); }
.dh-tvacio td { text-align: center; color: var(--text-3); font-size: 13px; }

/* ==========================================================================
   COLUMNA DE ACCIONES
   Un botón por lo que se puede hacer con esa fila. Los que apuntan a una
   pantalla todavía no migrada se dibujan igual, apagados y con el motivo en
   el title: esconderlos haría creer que la acción no existe, y existe — en
   v4. Así el hueco se ve, que es lo que hay que ver.
   ========================================================================== */
.dh-tabla th.dh-acc, .dh-tabla td.dh-acc { text-align: right; white-space: nowrap; }
.dh-acc-g { display: inline-flex; gap: 2px; justify-content: flex-end; }
.dh-abtn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 20px; height: 20px; border-radius: var(--r-xs);
  color: var(--text-2); background: var(--surface-2);
  border: 1px solid var(--line-soft); cursor: pointer; text-decoration: none;
}
.dh-abtn .dh-icon { width: 13px; height: 13px; }
.dh-abtn:hover { background: var(--surface-3); color: var(--text); border-color: var(--line); }
.dh-abtn.es-peligro:hover { color: var(--bad); border-color: var(--bad); }

/* El color va en el dibujo, no en el botón (Pedro, 30/09/2026): consultar
   celeste, estadísticas violeta, editar naranja, eliminar rojo, volver a
   activar verde. Lo pone
   `acciones()` en core/view.php según el ícono. */
/* Tonos apagados, para que acompañen a la paleta y no griten en una tabla
   llena de filas (Pedro, 30/09/2026). En oscuro, un punto más claros. */
:root {
  --acc-ver: #6a9fbd; --acc-editar: #c49a5c; --acc-eliminar: #c27272; --acc-activar: #6e9e80;
  --acc-estadisticas: #9585bf;
}
[data-theme="dark"] {
  --acc-ver: #8bb8d2; --acc-editar: #d4b07a; --acc-eliminar: #d99191; --acc-activar: #8dbb9d;
  --acc-estadisticas: #b3a6d9;
}
.dh-abtn.es-ver      .dh-icon { color: var(--acc-ver); }
.dh-abtn.es-estadisticas .dh-icon { color: var(--acc-estadisticas); }
.dh-abtn.es-editar   .dh-icon { color: var(--acc-editar); }
.dh-abtn.es-eliminar .dh-icon { color: var(--acc-eliminar); }
.dh-abtn.es-activar  .dh-icon { color: var(--acc-activar); }

/* Sin migrar: se ve, no se usa. */
.dh-abtn.es-pendiente {
  opacity: .32; cursor: not-allowed; border-style: dashed;
}
.dh-abtn.es-pendiente:hover { background: var(--surface-2); color: var(--text-2); }

/* ============================================================================
   PANEL A DOS COLUMNAS

   v4 pone la grilla a la izquierda y las acciones a la derecha —Agregar,
   Estadísticas, y los formularios de frecuencia—, y esa disposición no es
   decorativa: son las cosas que se hacen MIENTRAS se mira la lista. Ponerlas
   arriba obliga a subir y bajar.

   La columna derecha es fija en 280px porque su contenido son formularios
   angostos; lo que se estira es la tabla, que es lo que necesita el ancho.
   ========================================================================== */
.dh-panel-2col {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 280px;
  gap: 16px;
  align-items: start;
}
@media (max-width: 1100px) { .dh-panel-2col { grid-template-columns: 1fr; } }

/* Los dos botones grandes de la derecha. */
/* Los botones de la columna derecha de un panel.
 *
 * MÁS CHICOS que antes —18px de padding y 15px de letra— porque la grilla de
 * productos tiene diez columnas y necesitaba el ancho. Con 10px y 13px la
 * columna entra sin apretar el resto.
 */
.dh-cta {
  display: flex; align-items: center; justify-content: center; gap: 7px;
  padding: 10px 12px; border-radius: var(--r-md, 8px); text-decoration: none;
  font-size: 13px; font-weight: 600; box-shadow: var(--sh-1);
  background: var(--surface); color: var(--text);
  border: 1px solid var(--line);
}

/* Los dos con fondo propio: ahí sí la letra va blanca. */
.dh-cta.es-alta   { background: var(--ok); color: #fff; border-color: transparent; }
.dh-cta.es-oscura { background: var(--surface-inv, #2f4050); color: #fff; border-color: transparent; }

/* EL BLANCO SÓLO DONDE HAY FONDO.
 *
 * Antes `.dh-cta:hover` ponía `color: #fff` a TODOS, así que «Marcas» y
 * «Rubros» —que no tienen fondo— quedaban con la letra blanca sobre blanco y
 * desaparecían al pasar el mouse o al tabular hasta ellos. */
.dh-cta.es-alta:hover, .dh-cta.es-oscura:hover,
.dh-cta.es-alta:focus, .dh-cta.es-oscura:focus,
.dh-cta.es-alta:focus-visible, .dh-cta.es-oscura:focus-visible {
  filter: brightness(1.06); color: #fff;
}

/* Y el que no tiene fondo se marca con el fondo, no con la letra. */
.dh-cta:hover, .dh-cta:focus, .dh-cta:focus-visible {
  background: var(--surface-2); color: var(--text); border-color: var(--line);
}
/* Los que tienen fondo lo conservan al pasar el mouse: la regla de arriba
   les ponía el fondo blanco y, con la letra blanca, el botón desaparecía. */
.dh-cta.es-alta:hover,   .dh-cta.es-alta:focus,   .dh-cta.es-alta:focus-visible   { background: var(--ok); color: #fff; border-color: transparent; }
.dh-cta.es-oscura:hover, .dh-cta.es-oscura:focus, .dh-cta.es-oscura:focus-visible { background: var(--surface-inv, #2f4050); color: #fff; border-color: transparent; }

.dh-cta:focus-visible { outline: 2px solid var(--accent-ink); outline-offset: 2px; }
.dh-cta .dh-icon  { width: 16px; height: 16px; }

/* ---- Formularios --------------------------------------------------------- */
.dh-form { display: grid; gap: 12px; }
.dh-form label { font-size: 12px; color: var(--text-2); display: grid; gap: 4px; }
.dh-form .form-control { font-size: 13px; }

/* Dos a cuatro campos por fila según el ancho, sin medidas fijas: los
   formularios de v4 tienen cuatro columnas en pantalla grande y una en el
   teléfono. */
.dh-form-g {
  display: grid; gap: 12px;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
}

.dh-nota { font-size: 11.5px; line-height: 1.5; }

/* ---- Ficha del vendedor ---------------------------------------------- */
.dh-ficha-cuerpo {
  display: grid;
  grid-template-columns: minmax(0, 340px) minmax(0, 1fr);
  gap: 16px; align-items: start;
}
@media (max-width: 1000px) { .dh-ficha-cuerpo { grid-template-columns: 1fr; } }

/* ============================================================================
   FORMULARIO ADMINISTRATIVO

   No es una landing: es una pantalla de carga que alguien usa cuarenta veces
   por día. Etiqueta chica y pegada al campo, campos bajos, columnas fijas y
   nada de aire decorativo. La distribución copia la de v4 —cuatro columnas
   arriba, dos abajo— porque quien la usa ya sabe dónde está cada cosa.
   ========================================================================== */
.dh-form-admin { gap: 10px; }
.dh-form-admin label { font-size: 11px; gap: 2px; color: var(--text-2); }
.dh-form-admin .form-control { height: 30px; padding: 0 8px; font-size: 12.5px; }
.dh-form-admin textarea.form-control { height: auto; padding: 6px 8px; }

/* ---- Campo destacado ----------------------------------------------------
   Para el dato que no se lee igual que los de al lado: la comisión en medio
   del teléfono y el correo. Se realza el campo entero —rótulo e input— con un
   fondo y una barra al costado, no sólo el rótulo: pintar la etiqueta sola lo
   hace parecer una cabecera de tabla en vez de un campo.

   El acento va en el borde y no en el fondo del input, así el campo se sigue
   viendo editable y no deshabilitado. */
.dh-campo-plata {
  padding: 6px 10px 8px; border-radius: var(--r-xs);
  background: var(--surface-2);
  border: 1px solid var(--line-soft);
  border-left: 3px solid var(--accent-line);
}
.dh-campo-plata > span {
  display: block; font-size: 11px; color: var(--text-2); margin-bottom: 2px;
}
.dh-campo-plata .dh-campo-plata-in { position: relative; display: block; }

/* El signo de porcentaje adentro del input, a la derecha: dice qué unidad es
   sin gastar una línea de ayuda debajo. */
.dh-campo-plata .dh-campo-plata-in::after {
  content: '%'; position: absolute; right: 9px; top: 50%;
  transform: translateY(-50%); pointer-events: none;
  font-size: 12px; color: var(--text-3); font-family: var(--f-data);
}
.dh-campo-plata input { padding-right: 24px; font-family: var(--f-data); }

.dh-g4 { display: grid; gap: 10px; grid-template-columns: repeat(4, minmax(0, 1fr)); }
.dh-g2 { display: grid; gap: 10px; grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (max-width: 900px) {
  .dh-g4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .dh-g2 { grid-template-columns: 1fr; }
}

/* La observación ocupa las dos filas de al lado, como en v4. */
.dh-fila-doble { grid-row: span 3; }

/* ---- Ficha del vendedor -------------------------------------------------- */
/* El encabezado verde de v4: el nombre grande y el rol arriba. Se conserva
   porque es lo que hace reconocible la pantalla de un vistazo. */
.dh-ficha-titulo {
  background: var(--ok); color: #fff; text-align: center;
  padding: 16px; border-radius: var(--r-lg) var(--r-lg) 0 0;
  font-size: 12px; letter-spacing: .06em; text-transform: uppercase;
}
.dh-ficha-titulo b {
  display: block; margin-top: 4px;
  font-family: var(--f-display); font-size: 20px;
  letter-spacing: -.01em; text-transform: none;
}

/* Tres KPI en una fila y las dos tablas de productos una al lado de la otra:
   es la mitad derecha de la ficha de v4. */
.dh-kpis-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); margin-bottom: 0; }
.dh-2col   { display: grid; gap: 16px; grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (max-width: 1200px) {
  .dh-kpis-3 { grid-template-columns: 1fr; }
  .dh-2col   { grid-template-columns: 1fr; }
}

.dh-mapa { display: block; width: 100%; height: 220px; border: 0; }

/* ============================================================================
   BARRA DE LA TABLA — el selector de cuántas filas

   El buscador y el paginador ya estaban; faltaba decir cuántas filas se ven por
   página. Va en la esquina de arriba a la izquierda: se decide antes de mirar,
   no después.
   ========================================================================== */
.dh-tbar-c {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 12px; color: var(--text-3); white-space: nowrap;
}
.dh-tbar-c select {
  height: 30px; padding: 0 6px; font-size: 12.5px;
  border: 1px solid var(--line); border-radius: var(--r-xs);
  background: var(--surface); color: var(--text);
}

/* La tabla respira dentro de su tarjeta. Antes iba pegada a los bordes y las
   primeras y últimas columnas parecían cortadas. */
.dh-tabla { padding: 0 12px 12px; }
.dh-tabla table { width: 100%; }

/* ============================================================================
   REJILLA DE 12 COLUMNAS PARA FORMULARIOS

   Las filas de v4 no son todas iguales: provincia y localidad piden ancho, el
   código postal son cuatro dígitos. Con 12 columnas cada campo pide lo que
   necesita —5, 5 y 2— en vez de repartirse el ancho en partes iguales.
   ========================================================================== */
.dh-g12 { display: grid; gap: 10px; grid-template-columns: repeat(12, minmax(0, 1fr)); }
.dh-c1  { grid-column: span 1; }
.dh-c2  { grid-column: span 2; }
.dh-c3  { grid-column: span 3; }
.dh-c4  { grid-column: span 4; }
.dh-c5  { grid-column: span 5; }
.dh-c6  { grid-column: span 6; }
.dh-c7  { grid-column: span 7; }
.dh-c8  { grid-column: span 8; }
.dh-c12 { grid-column: span 12; }
@media (max-width: 900px) {
  .dh-c1, .dh-c2, .dh-c3, .dh-c4, .dh-c5, .dh-c6, .dh-c7, .dh-c8 { grid-column: span 12; }
}
/* La grilla de 12 también ordena fichas: tarjeta a la izquierda (4), tabla a
   la derecha (8) y lo ancho abajo (12). Las tarjetas no se estiran a la
   altura de su vecina. */
.dh-g12.dh-ficha-g { gap: 16px; align-items: start; }
.dh-ficha-g > * { min-width: 0; }
.dh-tiras + .dh-ficha-g { margin-top: 16px; }

/* Un importe en etiqueta: fondo suave para leerlo de un vistazo en una tabla.
   Neutro por defecto; `es-ok` en verde (la comisión, lo cobrado). */
.dh-monto { display: inline-block; padding: 2px 8px; border-radius: var(--r-xs, 5px);
  background: var(--surface-3); color: var(--text); font-variant-numeric: tabular-nums; white-space: nowrap; }
.dh-monto.es-ok { background: var(--ok-soft); color: var(--ok); font-weight: 600; }

/* Gráfico de columnas (ventas mes a mes): sin librerías. Cada `.dh-col` es
   un mes; la barra `i` toma su alto en % del máximo. El mes en curso va en el
   acento; el detalle sale en el `title` al pasar el mouse. */
.dh-col-res { display: flex; flex-wrap: wrap; gap: 6px 22px; font-size: 12.5px; color: var(--text-3); margin-bottom: 12px; }
.dh-col-res b { color: var(--text); font-variant-numeric: tabular-nums; margin-left: 4px; }
.dh-cols { display: flex; align-items: stretch; gap: 6px; height: 190px; }
.dh-col { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; justify-content: flex-end; align-items: center; gap: 4px; cursor: default; }
.dh-col i { display: block; width: 100%; max-width: 34px; border-radius: 4px 4px 0 0; background: var(--acc-ver, #6a9fbd); opacity: .55; transition: opacity .15s; }
.dh-col:hover i { opacity: .9; }
.dh-col.es-actual i { background: var(--accent); opacity: .9; }
.dh-col-v { font-size: 10.5px; color: var(--text-3); white-space: nowrap; font-variant-numeric: tabular-nums;
  max-width: 100%; overflow: hidden; text-overflow: clip; }
@media (max-width: 700px) { .dh-col-v { display: none; } }
.dh-col-m { font-size: 11px; color: var(--text-3); text-transform: capitalize; }
.dh-col.es-actual .dh-col-m { color: var(--text); font-weight: 600; }

/* ---- Estadísticas de ventas (vendedor/estadisticas) ---------------------- */
.dh-est-filtro { display: flex; flex-wrap: wrap; gap: 8px; align-items: flex-end; }
.dh-est-filtro label { margin: 0; font-size: 12px; color: var(--text-3); }
.dh-est-filtro input { width: 150px; }
.dh-est-compara { font-size: 12px; flex: 1 1 180px; align-self: center; }
.dh-est-tiras { grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); margin-top: 16px; }
.dh-est-tiras .dh-tira-v { font-size: 20px; }
.dh-est-chip { display: inline-block; font-size: 11px; padding: 1px 7px; border-radius: 999px; margin-top: 2px;
  background: var(--surface-3); color: var(--text-2); font-weight: 600; white-space: nowrap; text-transform: none; letter-spacing: 0; }
.dh-est-chip.es-bien { background: var(--ok-soft); color: var(--ok); }
.dh-est-chip.es-mal  { background: var(--bad-soft); color: var(--bad); }
.dh-est-avisos { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 10px; margin: 16px 0; }
.dh-est-aviso { border-radius: var(--r); padding: 9px 12px; font-size: 12.5px; border: 1px solid transparent; }
.dh-est-aviso b { font-weight: 600; }
.dh-est-aviso.es-peligro { background: var(--bad-soft); color: var(--bad); }
.dh-est-aviso.es-alerta  { background: hsl(38 90% 50% / .12); color: hsl(32 80% 35%); }
.dh-est-aviso.es-ok      { background: var(--ok-soft); color: var(--ok); }

.dh-est-leyenda { display: flex; flex-wrap: wrap; gap: 6px 18px; font-size: 12px; color: var(--text-3); margin-bottom: 10px; }
.dh-est-leyenda b { color: var(--text); margin-left: 4px; font-variant-numeric: tabular-nums; }
.dh-est-leyenda i { display: inline-block; width: 12px; height: 3px; border-radius: 2px; vertical-align: middle; margin-right: 6px; }
.dh-est-leyenda i.es-act { background: var(--accent); height: 3px; }
.dh-est-leyenda i.es-ant { background: var(--text-3); height: 2px; }
.dh-est-leyenda i.es-cc, .dh-est-mezcla .es-cc, .dh-col-pila .es-cc { background: var(--acc-ver, #6a9fbd); }
.dh-est-leyenda i.es-contado, .dh-est-mezcla .es-contado, .dh-col-pila .es-contado { background: var(--acc-editar, #c49a5c); }
.dh-est-leyenda i.es-cc, .dh-est-leyenda i.es-contado { height: 10px; width: 10px; }
.dh-est-linea { display: block; width: 100%; height: 190px; overflow: visible; }
.dh-est-linea polyline { fill: none; vector-effect: non-scaling-stroke; stroke-linejoin: round; }
.dh-est-linea .es-act { stroke: var(--accent); stroke-width: 2.5; }
.dh-est-linea .es-ant { stroke: var(--text-3); stroke-width: 1.5; stroke-dasharray: 5 4; }
.dh-est-eje { display: flex; justify-content: space-between; font-size: 11px; color: var(--text-3); margin-top: 4px; }

.dh-col-pila { display: flex; flex-direction: column; width: 100%; max-width: 34px; border-radius: 4px 4px 0 0; overflow: hidden; min-height: 0; }
.dh-col-pila i { display: block; min-height: 0; opacity: .75; }
.dh-col.es-actual .dh-col-pila i { opacity: 1; }
.dh-col:hover .dh-col-pila i { opacity: 1; }

.dh-est-celbar { position: relative; display: inline-block; min-width: 120px; text-align: right; }
.dh-est-celbar i { position: absolute; left: 0; bottom: -3px; height: 3px; border-radius: 2px; background: var(--accent); opacity: .7; }
.dh-est-mezcla { display: flex; width: 90px; height: 8px; border-radius: 4px; overflow: hidden; background: var(--surface-3); }
.dh-est-mezcla i { display: block; }

.dh-est-cob { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 12px; align-items: center; }
.dh-est-cob select { width: auto; min-width: 140px; }
.dh-est-cob label { display: flex; align-items: center; gap: 6px; margin: 0; font-size: 12px; color: var(--text-3); }
.dh-barra.dh-barra-cob { grid-template-columns: minmax(0, 1.2fr) minmax(30px, 1fr) auto; }
.dh-barra.dh-barra-cob span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dh-barra.dh-barra-cob b { white-space: nowrap; }
.dh-barra.dh-barra-cob small { display: none; }
.dh-barra.dh-barra-cob i { background: var(--acc-activar, #6e9e80); }

.dh-est-quien { display: flex; align-items: center; gap: 12px; margin-bottom: 14px; }
.dh-est-quien b { display: block; font-size: 15px; }
.dh-est-quien span { font-size: 12.5px; }
.dh-est-accesos { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 16px; }

/* Un bloque reservado: lo que se va a medir y todavía no existe. */
.dh-reservado { border-style: dashed; background: transparent; box-shadow: none; }

/* El cuadro informativo de un punto del mapa («Casa»). */
.dh-mapa-cartel { display: flex; align-items: center; gap: 6px; font-weight: 600; font-size: 13px;
  color: #1f2933; padding: 2px 4px; }
.dh-mapa-cartel .dh-icon { width: 16px; height: 16px; color: #1e8449; }

/* ---- El mapa para elegir la ubicación ------------------------------------ */
.dh-campo-mapa { display: grid; gap: 4px; }
.dh-form-lbl   { font-size: 11px; color: var(--text-2); }
.dh-form-lbl em {
  font-style: normal; font-family: var(--f-data);
  color: var(--text-3); margin-left: 6px;
}

.dh-mapa-lienzo {
  position: relative; height: 260px; overflow: hidden;
  border: 1px solid var(--line); border-radius: var(--r-sm);
  background: var(--surface-2); cursor: crosshair; user-select: none;
}
.dh-mapa-ayuda { margin: 0; font-size: 11px; color: var(--text-3); }

/* ---- Cuando Google no cargó --------------------------------------------
   Lo que se ve en lugar del mapa. Ocupa el mismo alto que ocuparía el mapa a
   propósito: si el cartel fuera más bajo, la pantalla se acomodaría distinto
   según Google cargue o no, y el formulario saltaría al terminar de cargar.

   Hasta el 25/09/2026 acá había un mapa de respaldo con teselas de
   OpenStreetMap, con sus pines, sus mandos de zoom y su línea de crédito.
   Se sacó entero: el sistema muestra Google Maps o no muestra mapa. */
.dh-mapa-sin {
  display: flex; align-items: center; justify-content: center;
  min-height: 260px; padding: 20px;
  border: 1px dashed var(--line);
  border-radius: var(--r-sm);
  background: var(--surface-2);
  text-align: center;
}

.dh-mapa-sin .dh-mapa-ayuda { max-width: 42ch; line-height: 1.6; }

/* ---- Ficha del cliente --------------------------------------------------
   La distribución de v4: quién es arriba a la izquierda, qué compró a la
   derecha, y abajo el mapa con el listado de pedidos al lado. El mapa va
   pegado a su listado a propósito: se señala una fila y se ilumina su punto,
   y eso sólo sirve si se ven los dos a la vez. */
/* Rejilla de DOCE columnas, y cada bloque dice cuántas ocupa.
 *
 * Antes eran dos columnas fijas 5fr/7fr con `grid-template-areas`, y eso
 * obligaba a que las DOS filas tuvieran el mismo reparto. La de arriba lo
 * quiere: la identidad es angosta y el listado de ventas necesita aire. La de
 * abajo no: el mapa y el listado de pedidos se miran juntos —se señala una
 * fila y se ilumina su punto— y con 5/7 el mapa quedaba chico para lo que
 * tiene que mostrar.
 *
 * Con doce columnas el reparto se lee en el CSS y cada fila elige el suyo sin
 * tocar el HTML: la primera 5 y 7, la segunda 6 y 6. El orden lo da el
 * documento, así que no hacen falta las áreas nombradas. */
.dh-cli-ficha {
  display: grid; gap: 16px; align-items: start;
  grid-template-columns: repeat(12, minmax(0, 1fr));
}
.dh-cli-id      { grid-column: span 5; }
.dh-cli-ventas  { grid-column: span 7; }
.dh-cli-mapa    { grid-column: span 6; }
.dh-cli-pedidos { grid-column: span 6; }

@media (max-width: 1100px) {
  .dh-cli-ficha > .card { grid-column: 1 / -1; }
}

/* La cabecera verde de v4, que es como se reconoce la ficha del cliente. */
.dh-cli-cab {
  padding: 16px 20px; text-align: center; color: #fff;
  background: var(--ok, #1e8449);
  border-radius: var(--r-lg) var(--r-lg) 0 0;
}
.dh-cli-cab b    { display: block; font-family: var(--f-display); font-size: 16px; }
.dh-cli-cab span { display: block; font-size: 12.5px; opacity: .85; margin-top: 2px; }

.dh-cli-mapa .dh-mapa-lienzo { height: 360px; }

/* La fila del listado que se está señalando, para que el ida y vuelta con
   el mapa se vea de los dos lados. */
tr.es-activa > td { background: var(--surface-2); }

/* ============================================================================
   FICHA DEL VENDEDOR — diseño propio de v5

   v4 pone un bloque verde con el nombre y debajo una lista de renglones con un
   tilde adelante. Funciona, pero no dice nada: todos los datos pesan igual y el
   tilde no significa nada.

   Acá la identidad va arriba, en una franja con la inicial, el documento y la
   comisión —lo que se busca de un vistazo—, y el resto en una rejilla de dos
   columnas donde la etiqueta es chica y gris y el dato es lo que se lee.
   ========================================================================== */
.dh-tarjeta-cab {
  display: flex; align-items: center; gap: 12px;
  padding: 16px 18px; border-bottom: 1px solid var(--line);
  background: var(--surface);
  border-radius: var(--r-lg) var(--r-lg) 0 0;
}
.dh-tarjeta-cab > div { min-width: 0; }
.dh-tarjeta-cab b {
  display: block; font-family: var(--f-display); font-size: 16px;
  letter-spacing: -.01em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.dh-tarjeta-cab span { font-size: 12px; color: var(--text-3); font-family: var(--f-data); }
.dh-av-g { width: 42px; height: 42px; font-size: 15px; flex: none; }

.dh-chip {
  margin-left: auto; flex: none;
  padding: 3px 9px; border-radius: 100px; font-size: 11px !important;
  background: var(--accent-soft, var(--surface-2)); color: var(--accent-ink);
  border: 1px solid var(--accent-line, var(--line));
}

/* La rejilla de datos. Dos por fila; los que pueden ser largos toman las dos.
   NINGÚN HUECO EN GRIS (Pedro, 06/10/2026): el fondo es el de la tarjeta y
   las líneas las pone cada celda, así que un lugar vacío queda blanco. Las
   fichas que arma `rejilla()` (productos) estiran el dato que queda solo. */
.dh-campos {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0; margin: 0; padding: 0; background: var(--surface); overflow: hidden;
}
.dh-campos > div {
  background: var(--surface); padding: 9px 14px; min-width: 0;
  box-shadow: 1px 0 0 var(--line-soft), 0 1px 0 var(--line-soft);
}
.dh-campo-ancho { grid-column: span 2; }
.dh-campos > .dh-campos-titulo {
  padding: 14px 14px 6px; font-size: 11px; font-weight: 600;
  letter-spacing: .06em; text-transform: uppercase; color: var(--accent-ink, var(--text-2));
}
.dh-campos dt {
  font-size: 10px; letter-spacing: .05em; text-transform: uppercase;
  color: var(--text-3); margin-bottom: 2px;
}
.dh-campos dd {
  margin: 0; font-size: 13px; color: var(--text);
  overflow: hidden; text-overflow: ellipsis;
}

/* ---- Tiras de KPI --------------------------------------------------------
   No son tarjetas sueltas con borde: es una sola pieza dividida, con una barra
   de color arriba que distingue de qué habla cada número. Ocupa menos y se lee
   como un conjunto, que es lo que es. */
.dh-tiras {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1px; background: var(--line);
  border: 1px solid var(--line); border-radius: var(--r-lg); overflow: hidden;
}
.dh-tiras-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (max-width: 800px) { .dh-tiras, .dh-tiras-2 { grid-template-columns: 1fr; } }

.dh-tira {
  background: var(--surface); padding: 14px 16px 15px;
  border-top: 3px solid var(--line); min-width: 0;
}
.dh-tira.es-fuerte { border-top-color: var(--ok); }
.dh-tira.es-acento { border-top-color: var(--accent-ink); }
.dh-tira.es-alerta { border-top-color: var(--bad); }

.dh-tira-t { display: block; font-size: 11px; color: var(--text-3);
  letter-spacing: .04em; text-transform: uppercase; }
.dh-tira-v {
  display: block; margin: 5px 0 3px;
  font-family: var(--f-data); font-size: 24px; font-weight: 700;
  line-height: 1.1; font-variant-numeric: tabular-nums;
}
/* El nombre de un cliente no es un número: ni tabular ni tan grande. */
.dh-tira-txt {
  font-family: var(--f-display); font-size: 16px; font-variant-numeric: normal;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.dh-tira-f { display: block; font-size: 11px; color: var(--text-3); line-height: 1.4; }

/* Los radios SÍ/NO del formulario de clientes: en línea, con el rótulo
   arriba como cualquier otro campo. */
.dh-radios { display: flex; gap: 14px; align-items: center; height: 30px; }
.dh-radios label { display: inline-flex; align-items: center; gap: 5px; font-size: 12.5px; color: var(--text); }
.dh-radios input { margin: 0; }

/* ============================================================================
   DESPLEGABLE CON BUSCADOR

   Lo dibuja `dh-select.js` al lado de cada `<select>` de más de ocho opciones.
   El `<select>` de verdad sigue en el formulario —es el que se envía— y queda
   fuera de la vista sin `display:none`, para que un campo `required` siga
   siendo enfocable y el navegador pueda decir cuál falta.
   ========================================================================== */
.dh-sel { position: relative; }

.dh-sel-nativo {
  position: absolute; opacity: 0; pointer-events: none;
  width: 100%; height: 100%; left: 0; top: 0; z-index: -1;
}

.dh-sel-btn {
  text-align: left; cursor: pointer; background: var(--surface);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.dh-sel-btn::after {
  content: ''; position: absolute; right: 10px; top: 50%; margin-top: -2px;
  border: 4px solid transparent; border-top-color: var(--text-3);
}
.dh-sel-btn.es-vacio { color: var(--text-3); }

.dh-sel-panel {
  position: absolute; z-index: 40; left: 0; right: 0; top: calc(100% + 3px);
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-sm); box-shadow: var(--sh-2, 0 6px 20px rgba(0,0,0,.14));
  padding: 6px;
}

.dh-sel-busca { width: 100%; margin-bottom: 5px; padding: 6px 8px; font-size: 12.5px;
  border: 1px solid var(--line); border-radius: var(--r-xs); background: var(--bg); }

.dh-sel-lista { max-height: 240px; overflow-y: auto; }

.dh-sel-op { padding: 6px 8px; font-size: 12.5px; border-radius: var(--r-xs); cursor: pointer; }
.dh-sel-op:hover, .dh-sel-op.es-activa { background: var(--surface-2); }
.dh-sel-op.es-sel { font-weight: 600; color: var(--accent-ink); }

.dh-sel-nada { padding: 8px; font-size: 12.5px; color: var(--text-3); }

/* ---- Ficha del producto -------------------------------------------------
   La distribución de dhFMC: la identidad con el precio desarmado a la
   izquierda y los movimientos de stock a la derecha, 5 y 7 de doce. */
.dh-prod-ficha {
  display: grid; gap: 16px; align-items: start;
  grid-template-columns: repeat(12, minmax(0, 1fr));
}
.dh-prod-id  { grid-column: span 5; }
.dh-prod-der { grid-column: span 7; }
@media (max-width: 1100px) { .dh-prod-ficha > .card { grid-column: 1 / -1; } }

/* La cabecera con la marca chica arriba y la denominación grande, como el
   bloque «pricing» de v4 pero con la tipografía de la casa. */
.dh-prod-cab {
  padding: 16px 20px; text-align: center; color: #fff;
  background: var(--surface-inv, #2f4050);
  border-radius: var(--r-lg) var(--r-lg) 0 0;
}
.dh-prod-cab span { display: block; font-size: 12px; opacity: .8; letter-spacing: .06em; text-transform: uppercase; }
.dh-prod-cab b    { display: block; font-family: var(--f-display); font-size: 17px; margin-top: 3px; }
.dh-prod-cab em   { display: block; font-style: normal; font-size: 11.5px; opacity: .7; margin-top: 4px;
                    font-family: var(--f-data); }

/* El valor de venta es el número que se mira: va más grande que el resto. */
.dh-prod-venta dd {
  font-family: var(--f-data); font-size: 20px; font-weight: 700;
  color: var(--ok); font-variant-numeric: tabular-nums;
}

/* La fila del PVP en la proyección: es el número al que llega la cuenta. */
.dh-proy-pvp td { border-top: 2px solid var(--line); background: var(--surface-2); }
.dh-proy-pvp td:last-child { color: var(--ok); font-size: 13px; }

/* La muestra de color de una marca, en el listado del catálogo. */
.dh-color {
  display: inline-block; width: 12px; height: 12px; border-radius: 3px;
  border: 1px solid var(--line); vertical-align: -1px;
}

/* El campo de color de la marca: el selector del navegador y el código al lado. */
.dh-color-campo { display: flex; gap: 8px; align-items: center; }
.dh-color-campo input[type="color"] {
  width: 38px; height: 30px; padding: 2px; flex: 0 0 auto;
  border: 1px solid var(--line); border-radius: var(--r-xs); background: var(--surface);
}

/* El panel de dos columnas AL REVÉS: el formulario a la izquierda y la tabla a
   la derecha, que es como están los cuatro catálogos en v4 (col-md-4 y
   col-md-8). El orden del documento no cambia —la tabla va primero, que es lo
   que importa para el lector de pantalla— y las columnas se cruzan en el CSS. */
.dh-panel-2col.es-invertido { grid-template-columns: 320px minmax(0, 1fr); }
.dh-panel-2col.es-invertido > :first-child { grid-column: 2; }
.dh-panel-2col.es-invertido > :last-child  { grid-column: 1; grid-row: 1; }
@media (max-width: 1100px) {
  .dh-panel-2col.es-invertido { grid-template-columns: 1fr; }
  .dh-panel-2col.es-invertido > :first-child,
  .dh-panel-2col.es-invertido > :last-child { grid-column: 1; grid-row: auto; }
}

/* ==================== 7 · CONFIRMAR UNA BAJA ==============================
   El cartel que `dh-confirmar.js` levanta antes de ocultar un registro.

   Se dibuja en el documento y no dentro de la fila: una fila de tabla no es
   lugar para un diálogo —hereda el `overflow` de la grilla y queda recortado—.

   Sin animación de entrada a propósito. Un cartel que pregunta si dar de baja
   tiene que estar entero y legible en el primer cuadro; los 150 ms de fundido
   son justo los que alguien que ya venía apretando usa para apretar de nuevo.
   ========================================================================= */

.dh-confirmar-fondo {
  position: fixed; inset: 0; z-index: 100;
  display: flex; align-items: center; justify-content: center;
  padding: 20px;
  background: color-mix(in srgb, var(--ink) 55%, transparent);
}

.dh-confirmar {
  width: 100%; max-width: 420px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: 22px;
  box-shadow: var(--sh-3);
}

.dh-confirmar-t {
  font-size: 16.5px;
  margin-bottom: 20px;
  /* El título lleva el nombre de la fila, que puede ser largo y venir de la
     base sin control de largo. Se parte en vez de desbordar la caja. */
  overflow-wrap: anywhere;
}

.dh-confirmar-pie { display: flex; gap: 9px; justify-content: flex-end; }

/* El de confirmar va en rojo y el de cancelar neutro: el color dice cuál es
   cuál sin leer, y el neutro es el que viene enfocado. */
.dh-confirmar .dh-btn {
  height: 34px; padding: 0 15px;
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  background: var(--surface);
  color: var(--text);
  font: inherit; font-weight: 500;
  cursor: pointer;
}

.dh-confirmar .dh-btn:hover { background: var(--surface-2); }

.dh-confirmar .dh-btn.es-peligro {
  background: var(--bad); border-color: var(--bad); color: #fff;
}

.dh-confirmar .dh-btn.es-peligro:hover {
  background: color-mix(in srgb, var(--bad) 85%, var(--ink));
}

/* ==================== 8 · LISTAS DE PRECIO ================================
   El ajuste de una lista se lee de un vistazo por el color: verde lo que baja
   el precio, ámbar lo que lo sube. No se usa el rojo de `--bad` a propósito —
   un recargo no es un error— ni el verde de `--ok` para el recargo, que sería
   al revés de lo que el que compra espera leer.
   ========================================================================= */

.dh-alza { color: var(--warn); }
.dh-baja { color: var(--ok); }

/* La nota abajo de un campo: dice qué pasa con el valor por omisión, que es lo
   que nadie sabe hasta que lo prueba. */
.dh-form-ayuda {
  margin: -4px 0 0;
  font-size: 11px;
  line-height: 1.45;
  color: var(--text-3);
}

/* El buscador de una pantalla: campo y botón en la misma línea. */
.dh-form-inline { display: flex; gap: 8px; }
.dh-form-inline .form-control { flex: 1; min-width: 0; }

/* ==================== 9 · MODIFICACIÓN POR LOTE ===========================
   Una sola fila: a la izquierda a quiénes, a la derecha qué (Pedro,
   06/10/2026). Los separa una línea vertical porque son dos decisiones
   distintas y el que filtra todavía no está aplicando nada.
   ========================================================================= */

/* EN UNA FILA: los campos se achican para entrar (los botones no). Sólo en
   una ventana angosta, donde no entran, bajan. */
.dh-lote-fila { display: flex; gap: 18px; align-items: flex-end; flex-wrap: nowrap; }

.dh-lote-filtros,
.dh-lote-accion { display: flex; gap: 10px; align-items: flex-end; flex-wrap: nowrap; min-width: 0; }
.dh-lote-filtros,
.dh-lote-accion  { flex: 1 1 0; }
.dh-lote-fila label { flex: 1 1 0; min-width: 90px; grid-template-columns: minmax(0, 1fr); }
.dh-lote-fila .dh-sel, .dh-lote-fila select { min-width: 0; }
.dh-lote-fila .btn { flex: none; }
@media (max-width: 1200px) {
  .dh-lote-fila { flex-wrap: wrap; }
  .dh-lote-filtros, .dh-lote-accion { flex: 1 1 100%; }
  .dh-lote-accion { padding-left: 0; border-left: 0; }
}

/* Marca y Rubro son el desplegable de la casa (`.dh-sel`): el botón que se
   ve toma el ancho de la etiqueta, no el del select escondido. */
.dh-lote-fila .form-control { width: 100%; }
.dh-lote-filtros .dh-sel,
.dh-lote-filtros .dh-sel-btn { width: 100%; }
.dh-lote-accion label:first-child { min-width: 175px; }

.dh-lote-filtros label,
.dh-lote-accion label { display: grid; gap: 4px; font-size: 11px; color: var(--text-2); margin: 0; }

/* Campos y botones de la misma altura, así la fila queda pareja abajo. */
.dh-lote-fila .form-control,
.dh-lote-fila .btn {
  height: 36px; margin: 0; font-size: 13px; box-sizing: border-box;
}
.dh-lote-fila .btn { display: inline-flex; align-items: center; padding-top: 0; padding-bottom: 0; }

.dh-lote-accion { padding-left: 18px; border-left: 1px solid var(--line); }

/* La columna de tildes: angosta y centrada, y el encabezado no ordena. */
.dh-chk { width: 34px; text-align: center; }

/* ==================== 10 · PROVEEDORES DE UN PRODUCTO =====================
   Una tarjeta por proveedor. Van en grilla y no en tabla porque son pocos y
   se comparan de a dos o tres: una tabla de seis columnas para dos filas se
   lee peor que dos fichas al lado.
   ========================================================================= */

.dh-prov-grid { display: grid; gap: 12px; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); }

.dh-prov-card {
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  background: var(--surface-2);
  padding: 12px 14px;
}

.dh-prov-nom {
  font-weight: 600;
  margin-bottom: 8px;
  padding-bottom: 8px;
  border-bottom: 1px solid var(--line);
  overflow-wrap: anywhere;
}

/* ==================== 11 · COMPRAS ========================================
   El filtro del listado, la tabla de renglones y la columna de importes de
   la carga. Cada importe se escribe en porcentaje o en pesos: el porcentaje
   va angosto a la izquierda porque es la ayuda, y el importe a la derecha
   porque es lo que se guarda y se suma.
   ========================================================================= */

.dh-filtros { display: flex; flex-wrap: wrap; gap: 10px 14px; align-items: flex-end; }
.dh-filtros label { display: grid; gap: 4px; font-size: 11px; color: var(--text-2); }
.dh-filtros .form-control { height: 32px; font-size: 13px; }
.dh-filtros select, .dh-filtros .dh-sel { min-width: 240px; }

.dh-renglones td { vertical-align: middle; }
.dh-renglones .form-control { height: 30px; padding: 4px 6px; }
.dh-renglones .form-control.dh-num { text-align: right; }
.dh-renglones select.form-control { min-width: 11em; }

.dh-imp {
  display: grid; gap: 10px; align-items: center;
  grid-template-columns: 1fr 7.5em 10em;
  padding: 6px 0; border-top: 1px solid var(--line-soft);
}
.dh-imp:first-child { border-top: 0; }
.dh-imp-lbl { font-size: 13px; }
.dh-imp-lbl small { color: var(--text-3); }
/* `.dh-form label` es una grilla de rótulo arriba y campo abajo; acá el
   símbolo va al lado del número, y la casilla al lado de su texto. */
.dh-form .dh-imp-pct, .dh-form .dh-imp-val { display: flex; align-items: center; gap: 4px; margin: 0; }
.dh-imp .form-control { height: 30px; padding: 4px 6px; text-align: right; }
.dh-imp-pct span, .dh-imp-val span { color: var(--text-3); font-size: 12px; flex: none; }
.dh-imp-pct .form-control, .dh-imp-val .form-control { flex: 1; min-width: 0; }
.dh-imp-sub b, .dh-imp-total b { grid-column: 3; text-align: right; font-variant-numeric: tabular-nums; }
.dh-imp-total { border-top: 2px solid var(--line); margin-top: 4px; padding-top: 10px; }
.dh-imp-total b { font-size: 18px; }

/* ==================== 12 · VENTAS Y COMISIONES DEL VENDEDOR ===============
   La franja de pago abajo de la tabla de pendientes, las barras de las
   series —ventas por día, por mes— y los botones que eligen un día en el
   recorrido.
   ========================================================================= */

.dh-pago {
  display: flex; flex-wrap: wrap; gap: 12px 18px; align-items: center;
  border-top: 1px solid var(--line-soft);
}
.dh-pago > span b { font-size: 16px; font-variant-numeric: tabular-nums; }
.dh-pago label { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; }
.dh-pago .dh-radios { height: auto; }

/* Comisiones: el filtro y los números de la calle en una fila; abajo, dos
   columnas que apilan tarjetas. */
.dh-g12.dh-com-cab { align-items: stretch; margin-bottom: 16px; }
.dh-com-cab > .card { margin: 0; }
.dh-com-cab > .dh-c7 { display: flex; }
.dh-com-cab .dh-tiras { flex: 1; }
.dh-com-cab .dh-tira-v { font-size: 22px; }
.dh-com-cab .dh-tira { display: flex; flex-direction: column; justify-content: center; }
.dh-com-filtro .dh-com-vend { flex: 1 1 220px; }
.dh-com-filtro .dh-com-vend select { width: 100%; }
.dh-com-filtro select.dh-com-tipo { min-width: 0; }
.dh-pila { display: grid; gap: 16px; align-content: start; min-width: 0; }
.dh-pila > .card, .dh-pila > form > .card { margin: 0; }
.dh-com-bajada { display: block; font-weight: 400; font-size: 12px; margin-top: 2px; }
.dh-com-info { margin: 0; }
.dh-com-info > div {
  display: flex; justify-content: space-between; gap: 12px;
  padding: 6px 8px; border-bottom: 1px solid var(--line-soft); border-radius: 4px;
}
.dh-com-info dt { font-weight: 400; color: var(--text-2); font-size: 13px; }
.dh-com-info dd { margin: 0; font-weight: 600; font-variant-numeric: tabular-nums; }
.dh-com-info > div.es-elegida { background: var(--accent-soft, var(--line-soft)); }
.dh-com-sub { margin: 14px 0 6px; font-size: 11px; color: var(--text-3); letter-spacing: .04em; text-transform: uppercase; }
.dh-com-nota { font-size: 12px; margin: 8px 0 0; }
.dh-com-aviso { color: var(--bad); font-size: 12px; margin: 0; }
.dh-est-ventas { margin-top: 16px; }

.dh-barra {
  display: grid; grid-template-columns: 4.5em 1fr 9em 2em; gap: 10px; align-items: center;
  padding: 3px 0; font-size: 12.5px;
}
.dh-barra i {
  display: block; height: 12px; min-width: 2px;
  border-radius: 3px; background: var(--accent);
}
.dh-barra b { text-align: right; font-variant-numeric: tabular-nums; font-weight: 500; }
.dh-barra small { text-align: right; }
/* Los conceptos de pago —«COMISIÓN», «AGUINALDO»— no entran en el ancho de un mes. */
.dh-barra.dh-barra-concepto { grid-template-columns: 8em 1fr 9em 2em; }

/* El mapa de pedidos es la pantalla, no un recuadro de la ficha: más alto, y
   la caja crece con el lienzo en vez de dejarlo desbordar sobre la tarjeta de
   abajo. */
.dh-mapa.dh-mapa-pedidos { height: auto; }
.dh-mapa-pedidos .dh-mapa-lienzo { height: 440px; border: 0; border-radius: 0; cursor: grab; }

.dh-rutas { display: flex; flex-wrap: wrap; gap: 6px; border-bottom: 1px solid var(--line-soft); }
.dh-rutas .btn { font-size: 12px; padding: 3px 10px; }
.dh-rutas .btn.es-activa { background: var(--surface-2); font-weight: 600; }

/* LA IMPRESIÓN. El comprobante de un pago de comisión se imprime desde el
   navegador —es el «PDF del pago» de v4— y en el papel sobra todo lo que no es
   el comprobante: el menú, la barra de arriba y los botones. El sistema no
   tenía ninguna pantalla para imprimir hasta ésta. */
/* ==================== 13 · EL COMPROBANTE DE VENTA ========================
   La cabecera como en el papel: emisor a la izquierda, la letra en un
   recuadro al medio —es lo primero que se busca en una factura— y el número a
   la derecha.
   ========================================================================= */

.dh-comp-cab {
  display: grid; grid-template-columns: 1fr auto 1fr; gap: 16px; align-items: start;
  padding-bottom: 14px; margin-bottom: 14px; border-bottom: 1px solid var(--line);
}
.dh-comp-letra {
  width: 54px; height: 54px; display: grid; place-items: center;
  border: 2px solid var(--text); border-radius: var(--r-sm);
  font-size: 30px; font-weight: 700;
}
.dh-comp-num { text-align: right; }
.dh-comp-importes { max-width: 420px; margin-left: auto; }

@media print {
  /* Los avisos no van al papel, salvo los que son parte del comprobante:
     un recibo ANULADO tiene que salir impreso como anulado. */
  .dh-no-imprime, .alert:not(.dh-imprime) { display: none !important; }
  .dh-nav, .dh-top, .dh-veil, .dh-head-act, .dh-acc { display: none !important; }
  .dh-app, .dh-main, .dh-scroll { display: block !important; height: auto !important; overflow: visible !important; }
  body { background: #fff !important; }
  .card { box-shadow: none !important; break-inside: avoid; }
}

.dh-casillas { display: flex; flex-direction: column; gap: 10px; }
.dh-form .dh-casilla { display: flex; align-items: center; gap: 8px; font-size: 13px; color: var(--text); margin: 0; }
.dh-casilla input { margin: 0; }

/* ==================== 12 · CUENTA CORRIENTE DEL PROVEEDOR =================
   El formulario de una línea que va dentro de una fila —anular una nota con
   su motivo, marcar un cheque debitado con su fecha— y la deuda de migración,
   que se cancela primero y por eso se distingue en la tabla del pago.
   ========================================================================= */

.dh-fila-form { display: inline-flex; gap: 6px; align-items: center; margin: 0; }
.dh-fila-form .form-control { height: 30px; font-size: 12px; width: auto; min-width: 9em; }
.dh-fila-form .btn { padding: 4px 10px; font-size: 12px; }
tr.es-migracion td { background: var(--accent-soft, rgba(200, 160, 40, .08)); }
.dh-renglones select[name="cheque[]"] { min-width: 16em; }

/* ---- Indicadores a la izquierda, tabla a la derecha ------------------- */
/* Un tercio y dos tercios (4 y 8 de 12). Las tiras se apilan en columna. */
.dh-lado {
  display: grid; gap: 16px; align-items: start;
  grid-template-columns: minmax(0, 1fr) minmax(0, 2fr);
}
.dh-lado .dh-tiras { grid-template-columns: 1fr; }
@media (max-width: 1000px) { .dh-lado { grid-template-columns: 1fr; } }

/* Una cabecera de tarjeta con botones a la derecha. */
.dh-cab-act { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.dh-cab-act > .dh-cab-btns { margin-left: auto; display: flex; gap: 8px; }
.dh-cab-act .btn { font-size: 13px; padding: 5px 12px; }

/* Una casilla con su rótulo al lado (Ofertas: precio final, comisiona). */
.dh-form label.dh-check, label.dh-check { display: flex; align-items: center; gap: 8px; margin: 0; font-size: 13px; color: var(--text); }
.dh-check input[type="checkbox"] { width: 16px; height: 16px; flex: none; }

/* Lo que lleva `hidden` no se ve, aunque su clase diga otra cosa (.alert, .table). */
[hidden] { display: none !important; }

/* La composición del precio de una oferta: los importes no se parten. */
#composicion td.dh-num { white-space: nowrap; }

/* ¿Dónde trabajás hoy? · un botón grande por canal de venta. */
.dh-canales { display: grid; gap: 12px; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); max-width: 900px; }
.dh-canal {
  display: grid; gap: 4px; text-align: left; padding: 18px 20px; cursor: pointer;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg);
  font: inherit; color: var(--text); transition: border-color .12s, box-shadow .12s;
}
.dh-canal:hover { border-color: var(--accent-line); box-shadow: var(--sh-2); }
.dh-canal b { font-family: var(--f-display); font-size: 16px; }
.dh-canal span { font-size: 12.5px; color: var(--text-3); }
.dh-canal em { font-style: normal; font-size: 11px; color: var(--accent-ink); }
.dh-canal.es-actual { border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-soft); }

/* El canal de la sesión, arriba: se ve siempre y, con más de uno, se cambia. */
.dh-top-canal {
  display: inline-flex; align-items: center; gap: 6px; padding: 5px 11px; margin-right: 8px;
  border: 1px solid var(--line); border-radius: 100px; font-size: 12.5px; color: var(--text-2);
  text-decoration: none; white-space: nowrap;
}
a.dh-top-canal:hover { border-color: var(--accent-line); color: var(--text); }
.dh-top-canal b { color: var(--text); font-weight: 600; }

/* Ficha del usuario: un canal de venta por fila, con «habitual» a la derecha. */
.dh-canal-fila { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 6px 0; border-bottom: 1px solid var(--line-soft); }
.dh-canal-fila:last-child { border-bottom: 0; }

/* Ofertas · el tipo, como cuatro tarjetas para elegir. */
.dh-tipos-of { display: grid; gap: 8px; grid-template-columns: repeat(4, minmax(0, 1fr)); }
@media (max-width: 1200px) { .dh-tipos-of { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.dh-form label.dh-tipo-of, label.dh-tipo-of {
  display: grid; gap: 3px; padding: 10px 12px; margin: 0; cursor: pointer;
  border: 1px solid var(--line); border-radius: var(--r); background: var(--surface);
}
.dh-tipo-of input { position: absolute; opacity: 0; pointer-events: none; }
.dh-tipo-of b { font-size: 13px; color: var(--text); }
.dh-tipo-of span { font-size: 11.5px; color: var(--text-3); font-weight: 400; }
.dh-tipo-of:has(input:checked) { border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-soft); }
.dh-tipo-of.es-apagado { opacity: .45; cursor: default; }

/* Ofertas · los valores: una fila por valor, unidad o producto del combo. */
.dh-of-valor, .dh-of-item { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.dh-of-valor .form-control { width: auto; min-width: 120px; flex: 1 1 140px; }
.dh-of-item select { flex: 1 1 260px; }
.dh-of-item input { flex: 0 0 90px; }
.dh-of-rot { font-size: 12.5px; color: var(--text-2); min-width: 130px; }
.dh-of-acc { display: flex; gap: 8px; }
.dh-of-canal-ed { padding: 8px 0 12px 24px; display: grid; gap: 8px; border-bottom: 1px solid var(--line-soft); }

/* Venta · los renglones de descuento por oferta, debajo de su producto. */
tr.dh-of-desc td { padding-top: 0; border-top: 0; color: var(--text-2); }
tr.dh-of-regalo td { color: var(--text-2); font-style: italic; }
.dh-of-benef { list-style: none; margin: 4px 0 0; padding: 0; font-size: 12px; color: var(--text-3); white-space: normal; }
.dh-of-benef b { font-weight: 500; color: var(--text-2); white-space: nowrap; }

/* ==================== REGISTRAR VENTA (dhFMC egresar) ====================
   La disposición de v4: dos columnas arriba (campos | tablas y formulario del
   producto), la tabla del comprobante abajo, los totales a la derecha y el
   cartel «Sistema de Alertas». */
.dh-venta { align-items: start; }
.dh-venta .dh-form-inline .btn { flex: none; }
.dh-venta .dh-tabla table td { font-size: 12px; }
.dh-form-producto { padding: 12px; border: 1px solid var(--line); border-radius: var(--r-md, 8px); background: var(--surface-2); }
.dh-form-producto-disp { display: flex; align-items: center; }
.dh-form-producto > .dh-c10 { grid-column: span 10; }
@media (max-width: 900px) { .dh-form-producto > .dh-c10 { grid-column: span 12; } }
.dh-form-producto-disp .badge { font-size: 13px; padding: 6px 10px; }
.dh-form-producto-alerta { text-align: center; color: var(--bad); font-size: 13px; margin: 0; }
.dh-ancho { width: 100%; justify-content: center; }
.dh-venta-totales { margin-left: auto; min-width: 220px; text-align: right; }
.dh-venta-totales p { margin: 0; padding: 4px 0; border-bottom: 1px solid var(--line-soft); font-family: var(--f-data); }
.dh-venta-totales p:last-child { font-weight: 600; font-size: 15px; border-bottom: 0; }
tr.dh-of-regalo td { color: var(--text-2); }
dialog.dh-alertas { max-width: 720px; width: calc(100% - 32px); padding: 0; border: 1px solid var(--line);
  border-radius: var(--r-lg); box-shadow: var(--sh-3); }
dialog.dh-alertas::backdrop { background: rgba(0, 0, 0, .35); }
.dh-alertas-msj { display: flex; gap: 14px; align-items: flex-start; }
.dh-alertas-msj > .dh-icon { width: 34px; height: 34px; flex: none; color: var(--bad); }
.dh-alertas-msj.es-autorizar > .dh-icon { color: var(--info); }
.dh-alertas-msj p { margin: 0 0 8px; }
.dh-alertas-msj .dh-form-inline { align-items: center; flex-wrap: wrap; }
.dh-alertas-t { font-size: 18px; margin: 0 0 10px; }

/* ==================== EL RECIBO DE HABERES ================================
   Los dos recibos de dhFMC: dos copias iguales en una hoja apaisada,
   «Recibo para empleado» y «Recibo para empleador», cada una con sus firmas.
   ========================================================================= */

.dh-recibo { display: grid; grid-template-columns: 1fr 1fr; gap: 0; padding: 0; }
.dh-recibo-copia { padding: 18px 20px; display: flex; flex-direction: column; gap: 12px; min-width: 0; }
.dh-recibo-copia + .dh-recibo-copia { border-left: 1px dashed var(--line); }
.dh-recibo-copia header { display: flex; justify-content: space-between; gap: 12px; flex-wrap: wrap;
  border-bottom: 2px solid var(--text); padding-bottom: 6px; }
.dh-recibo-copia header b { font-size: 13px; letter-spacing: .04em; text-transform: uppercase; }
.dh-recibo-copia header span { font-size: 12.5px; color: var(--text-2); }
.dh-recibo-datos { display: grid; grid-template-columns: 1fr 1fr; gap: 6px 16px; margin: 0; }
.dh-recibo-datos dt { font-size: 11px; color: var(--text-3); font-weight: 400; }
.dh-recibo-datos dd { margin: 0; font-size: 13px; }
.dh-recibo-copia table { width: 100%; border-collapse: collapse; font-size: 12.5px; }
.dh-recibo-copia th { text-align: left; font-size: 11px; color: var(--text-3); font-weight: 500;
  border-bottom: 1px solid var(--line); padding: 4px 6px; }
.dh-recibo-copia td { border-bottom: 1px solid var(--line-soft); padding: 5px 6px; vertical-align: top; }
.dh-recibo-copia td small { color: var(--text-3); }
.dh-recibo-copia .dh-num { text-align: right; white-space: nowrap; }
.dh-recibo-pie { display: flex; justify-content: flex-end; gap: 18px; flex-wrap: wrap; font-size: 12.5px; color: var(--text-2); }
.dh-recibo-pie b { color: var(--text); }
.dh-recibo-pie .es-neto b { font-size: 15px; }
.dh-recibo-firmas { display: flex; justify-content: space-around; gap: 16px; margin-top: auto; padding-top: 44px; font-size: 12px; }
.dh-recibo-firmas span { border-top: 1px dotted var(--text-2); padding-top: 4px; min-width: 40%; text-align: center; }
@media (max-width: 900px) {
  .dh-recibo { grid-template-columns: 1fr; }
  .dh-recibo-copia + .dh-recibo-copia { border-left: 0; border-top: 1px dashed var(--line); }
}
/* La hoja apaisada sólo para el recibo (página con nombre): el resto de los
   comprobantes sigue saliendo vertical. */
@page recibo { size: A4 landscape; margin: 10mm; }
@media print {
  .dh-recibo { page: recibo; grid-template-columns: 1fr 1fr !important; border: 0 !important; }
  .dh-recibo-copia + .dh-recibo-copia { border-left: 1px dashed #999 !important; border-top: 0 !important; }
  .dh-head p, .dh-crumb { display: none !important; }
}

/* ==================== CONFIGURAR EMPLEADO (dhFMC) =========================
   Los listados para asociar y unificar se abren y cierran; el aviso de
   duplicados del panel lleva un botón por empleado.
   ========================================================================= */

.dh-desplegable { border-top: 1px solid var(--line-soft); }
.dh-desplegable > summary { cursor: pointer; padding: 10px 16px; font-size: 13px; font-weight: 500; color: var(--text-2); list-style: none; }
.dh-desplegable > summary::-webkit-details-marker { display: none; }
.dh-desplegable > summary::before { content: '+'; display: inline-block; width: 1em; color: var(--accent); font-weight: 600; }
.dh-desplegable[open] > summary::before { content: '−'; }
.dh-desplegable[open] > summary { color: var(--text); }
tr.es-sugerido > td { background: var(--accent-soft, rgba(200, 160, 40, .08)); }
.dh-duplicados ul { list-style: none; margin: 8px 0 0; padding: 0; display: grid; gap: 6px; }
.dh-duplicados li { display: flex; flex-wrap: wrap; gap: 6px; }
.dh-duplicados .btn { padding: 3px 10px; font-size: 12px; }
.dh-pila { display: flex; flex-direction: column; gap: var(--gap, 16px); min-width: 0; }

/* Pedidos entre almacenes · una cantidad mayor que lo que tiene el origen. */
.dh-pedido.es-error { border-color: var(--danger, #c0392b); box-shadow: 0 0 0 2px rgba(192, 57, 43, .15); }

/* ---- Pedidos del vendedor (pedidovendedor, fase 3 · D) --------------------
   El lote de dhFMC: pedidos a la izquierda (4/12), indicadores y visor a la
   derecha (8/12). La fila de un cliente con la cuenta vencida y la de un
   renglón sin stock, en rojo suave; el estado «a imprimir» en ámbar. */
.dh-pv-lote { display: grid; grid-template-columns: minmax(0, 4fr) minmax(0, 8fr); gap: 16px; align-items: start; }
@media (max-width: 1100px) { .dh-pv-lote { grid-template-columns: 1fr; } }
.dh-pv-kpis { grid-template-columns: repeat(4, minmax(0, 1fr)); margin-bottom: 0; }
@media (max-width: 700px) { .dh-pv-kpis { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.dh-est-chip.es-aviso { background: hsl(38 90% 50% / .14); color: hsl(32 80% 35%); }
tr.es-vencida > td, tr.es-falta > td { background: var(--bad-soft); }
tr.dh-pv-dif-agregado > td:first-child { box-shadow: inset 3px 0 0 var(--ok); }
tr.dh-pv-dif-quitado  > td:first-child { box-shadow: inset 3px 0 0 var(--bad); }
tr.dh-pv-dif-cambiado > td:first-child { box-shadow: inset 3px 0 0 hsl(38 90% 50%); }
.dh-pv-vendedores { display: grid; gap: 6px; max-height: 220px; overflow: auto; padding: 4px 0; }
.dh-pv-historia { margin: 12px 0 0; padding-left: 18px; font-size: 12px; color: var(--text-2); display: grid; gap: 4px; }

/* Autorizar un pedido: las dos columnas (cuenta y pedido) se apilan antes de
   que sus tablas dejen de entrar. */
@media (max-width: 1400px) { .dh-pv-autorizar > .dh-c6 { grid-column: span 12; } }

/* Fase 3 · pantallas que no entraban en un panel angosto. */
/* NC: el «Crédito» va debajo de «La nota será», a la derecha; en angosto, a lo ancho. */
.dh-nc-credito { grid-column: 7 / span 4; }
@media (max-width: 900px) { .dh-nc-credito { grid-column: span 12; } }
/* Armar reparto: la tabla de ventas y la lista de seleccionados se apilan antes
   de que el botón «Agregar» de cada fila quede fuera de la vista. */
@media (max-width: 1400px) { .dh-ht-configurar > .dh-c8, .dh-ht-configurar > .dh-c4 { grid-column: span 12; } }
/* Cerrar la hoja: los cuatro bloques de arriba pasan a dos por fila. */
@media (max-width: 1300px) { .dh-ht-cierre > .dh-c3 { grid-column: span 6; } }
@media (max-width: 700px)  { .dh-ht-cierre > .dh-c3 { grid-column: span 12; } }

/* Procesar por vendedor (dhFMC preparaLoteVendedor) — Pedro, 12/10/2026.
   La disposición de dhFMC con la cara de GM. Lo único nuevo son las listas
   de pedidos: tarjetas de dos líneas con buscador, contador y ALTO MÁXIMO con
   desplazamiento propio —un vendedor tiene más de 50 pedidos por día y la
   columna no puede estirarse con todos—. */
.dh-pv-vendedor { background: var(--accent-soft); border: 1px solid var(--accent-line);
  border-radius: var(--r-lg); padding: 12px 16px; text-align: center; }
.dh-pv-vendedor h2 { margin: 0; font-size: 17px; font-weight: 600; color: var(--accent-ink); overflow-wrap: anywhere; }
.dh-pv-head { display: flex; align-items: center; gap: 8px; min-width: 0; }
.dh-pv-head > .dh-icon { width: 15px; height: 15px; color: var(--text-3); flex: none; }
.dh-pv-head-end { margin-left: auto; display: inline-flex; gap: 4px; align-items: center; }
.dh-pv-btn-head { height: 28px; padding: 0 10px; font-size: 12.5px; display: inline-flex; align-items: center; gap: 6px; }
.dh-pv-btn-head .dh-icon { width: 14px; height: 14px; }
.dh-pv-filtro { display: flex; align-items: center; gap: 10px; padding: 10px 14px; border-bottom: 1px solid var(--line-soft); }
.dh-pv-filtro .dh-tbar-b { flex: 1 1 auto; min-width: 0; }
.dh-pv-cuenta { font-size: 12px; color: var(--text-3); white-space: nowrap; font-variant-numeric: tabular-nums; }
.dh-pv-lista { display: flex; flex-direction: column; }
.dh-pv-scroll { max-height: min(460px, 55vh); overflow-y: auto; overscroll-behavior: contain; }
.dh-pv-item { display: flex; flex-direction: column; gap: 3px; padding: 10px 16px 10px 13px; width: 100%;
  border: 0; border-left: 3px solid transparent; border-top: 1px solid var(--line-soft); background: none;
  color: var(--text); text-decoration: none; text-align: left; font: inherit; cursor: default; }
button.dh-pv-item, a.dh-pv-item { cursor: pointer; }
.dh-pv-item[hidden] { display: none; }
.dh-pv-lista > .dh-pv-item:first-child { border-top: 0; }
a.dh-pv-item:hover, button.dh-pv-item:hover { background: var(--surface-2); }
button.dh-pv-item:focus-visible, a.dh-pv-item:focus-visible { outline: 2px solid var(--accent-line); outline-offset: -2px; }
.dh-pv-item.es-vencida { border-left-color: var(--bad); }
.dh-pv-item.es-aviso   { border-left-color: var(--warn); }
.dh-pv-item.es-activa  { border-left-color: var(--accent); background: var(--accent-soft); }
.dh-pv-l1 { display: flex; align-items: baseline; gap: 12px; min-width: 0; }
.dh-pv-cli { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 600; }
.dh-pv-tot { font-family: var(--f-data); font-weight: 600; white-space: nowrap; }
.dh-pv-l2 { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px; font-size: 12px; color: var(--text-2); min-width: 0; }
.dh-pv-det { flex: 1 1 120px; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--text-3); }
.dh-pv-acc { margin-left: auto; }
.dh-pv-vacio { margin: 0; padding: 18px 16px; color: var(--text-3); text-align: center; font-size: 13px; }
.dh-pv-vacio[hidden] { display: none; }
/* Los cuatro indicadores de dhFMC, cada uno con su color. */
.dh-pv-kpi { border-top: 3px solid var(--line); }
.dh-pv-kpi.es-azul    { border-top-color: var(--info); }
.dh-pv-kpi.es-naranja { border-top-color: var(--warn); }
.dh-pv-kpi.es-verde   { border-top-color: var(--ok); }
.dh-pv-kpi.es-violeta { border-top-color: hsl(268 55% 58%); }
.dh-pv-chev { transition: transform .15s; transform: rotate(180deg); }
.es-plegado .dh-pv-chev { transform: none; }
.dh-pv-volver { transform: rotate(90deg); }
.dh-pv-rotulo { font-size: 12px; font-weight: 600; color: var(--text-2); display: block; margin-bottom: 6px; }
.dh-pv-sel { width: 34px; text-align: center !important; }
.dh-est-chip.es-info { background: var(--info-soft); color: var(--info); }
/* El formulario de un producto: la grilla de dhFMC (4+8 · 3+3+3+3 · 6 vacías + 3+3). */
.dh-pv-desde6 { grid-column: 7 / span 3; }
@media (max-width: 760px) { .dh-pv-desde6 { grid-column: span 12; } }
.dh-pv-form-producto .dh-c2, .dh-pv-form-producto .dh-c10 { display: flex; }
.dh-pv-ancho { width: 100%; justify-content: center; display: inline-flex; align-items: center; gap: 6px; }
.dh-pv-ancho .dh-icon { width: 14px; height: 14px; }
.dh-pv-disp { margin: 0; padding: 6px 12px; text-align: center; }
.dh-pv-alerta-stock { text-align: center; font-size: 14px; color: var(--bad); }
/* El visor: las tres cajas de dhFMC en una fila y el «Monto Total» a la derecha. */
.dh-pv-cajas { margin-bottom: 12px; }
.dh-pv-caja { background: var(--surface-2); border: 1px solid var(--line-soft); border-radius: var(--r-sm); padding: 8px 10px; }
.dh-pv-monto { display: flex; justify-content: flex-end; }
.dh-pv-monto label { background: var(--bad-soft); color: var(--bad); border-radius: var(--r-sm); padding: 6px 14px;
  font-family: var(--f-data); font-size: 15px; font-weight: 700; font-variant-numeric: tabular-nums; }
.dh-pv-renglones td { white-space: normal; }
.dh-pv-renglones .form-control { width: 100%; min-width: 4.5em; }
.dh-pv-renglones input[readonly] { background: var(--surface-2); }
.dh-pv-stock { background: var(--info-soft); color: var(--info); }
#div_array_egresos { padding-top: 12px; }
#btn_cargar { display: inline-flex; align-items: center; gap: 6px; }
#btn_cargar .dh-icon { width: 14px; height: 14px; }
/* El cartel de dhFMC (sistema_alertas). */
.dh-pv-modal[hidden] { display: none; }
.dh-pv-modal-caja { max-width: 560px; }
.dh-pv-modal-msj { display: flex; gap: 14px; align-items: flex-start; margin-bottom: 18px; }
.dh-pv-modal-msj > .dh-icon { width: 30px; height: 30px; color: var(--bad); flex: none; }
.dh-pv-modal-msj h5 { margin: 4px 0 0; font-size: 13.5px; font-weight: 500; line-height: 1.5; }
.dh-pv-modal-form { display: grid; gap: 10px; margin-bottom: 16px; }
.dh-pv-modal-form p { margin: 0; }
.dh-pv-modal-txt { font-size: 14px; }
/* El aviso flotante de error (lo que en dhFMC era PNotify «error»). */
.dh-toast.es-error .dh-av { background: var(--bad); color: #fff; }
.dh-toast.es-error b { color: var(--bad); }

/* ============================================================================
   DENSIDAD (Pedro, 12/10/2026: «quedan muchos padding que desperdician mucho
   espacio haciendo muy largo el sistema»). GM es una herramienta de carga que
   se usa todo el día, no una página para leer: menos aire en la página, las
   tarjetas, los campos, las tablas y los indicadores, para que entre más en
   la pantalla sin tener que bajar. Va al final para mandar sobre el kit.
   ========================================================================== */
:root { --row-h: 34px; }

.dh-page { padding: 14px 18px 32px; }
.dh-head { margin-bottom: 12px; gap: 10px; }
.dh-head h1 { font-size: 22px; }
.dh-crumb { margin-bottom: 2px; }

.card-header, .panel-heading { padding: 9px 14px; font-size: 14px; }
.card-body, .panel-body { padding: 12px 14px; }

.form-control, .form-select, .custom-select, select.form-control, input.form-control { height: 32px; padding: 0 10px; }
textarea.form-control { padding: 7px 10px; min-height: 64px; }
.btn { min-height: 32px; padding-top: 0; padding-bottom: 0; }
.dh-form, .dh-form-g { gap: 8px; }
.dh-form label { gap: 2px; font-size: 11.5px; }
.dh-g12 { row-gap: 8px; }

.dh-stack { gap: 10px; }
.dh-kpis { gap: 10px; margin-bottom: 10px; }
.dh-kpi { padding: 8px 12px 9px; }
.dh-kpi-v { font-size: 22px; margin-top: 2px; }
.dh-kpi-f { margin-top: 3px; }

.alert { padding: 8px 12px; margin-bottom: 8px; }

/* Procesar por vendedor */
.dh-pv-vendedor { padding: 6px 12px; }
.dh-pv-vendedor h2 { font-size: 15px; }
.dh-pv-item { padding: 6px 12px 6px 9px; gap: 1px; }
.dh-pv-lote, .dh-pila { gap: 10px; }

/* Botones del formulario de producto (venta y pedidos): «volver» a su medida
   y «Cargar a comprobante» con el resto, en una sola fila que no se monta. */
.dh-pv-botones { display: flex; gap: 8px; align-items: stretch; }
.dh-pv-botones > .btn:first-of-type { flex: 0 0 auto; }
.dh-pv-botones > .btn:last-of-type  { flex: 1 1 auto; justify-content: center; }
.dh-g12.dh-ficha-g, .dh-g12.dh-com-cab { gap: 10px; }
.dh-g12.dh-com-cab { margin-bottom: 10px; }

/* ---- Procesar por vendedor, más compacto (Pedro, 12/10/2026) ----------- */
/* Migas y «Volver» en una fila; el nombre del vendedor ya está en la franja. */
.dh-pv-barra { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 8px; }
.dh-pv-barra .dh-crumb { margin: 0; }
/* Indicadores en una línea: rótulo a la izquierda, número a la derecha. */
.dh-pv-kpi { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; padding: 6px 12px 7px; }
.dh-pv-kpi .dh-kpi-v { font-size: 20px; margin: 0; }
/* La caja del buscador de las tablas dentro de un .dh-form: la regla de los
   rótulos (display: grid) la partía en dos líneas. */
.dh-form label.dh-tbar-b { display: flex; gap: 7px; }
.dh-form label.dh-tbar-c { display: inline-flex; gap: 6px; }
.dh-tbar, .dh-tpie { padding: 6px 10px; }
.dh-pv-rotulo { margin-bottom: 2px; }
/* Tarjeta de pedido: la marca entre el cliente y el total. */
.dh-pv-l1 > .dh-est-chip { flex: none; font-size: 10.5px; padding: 1px 6px; }
.dh-pv-filtro { padding: 6px 10px; }
/* Visor: las tres condiciones sin caja alrededor; el monto pegado. */
.dh-pv-caja { background: none; border: 0; padding: 0; }
.dh-pv-cajas { margin-bottom: 6px; }
.dh-pv-monto label { padding: 4px 12px; }
/* Renglones: P.Unit y Subtotal son datos, no campos; sin flechitas en ninguno. */
.dh-pv-renglones .form-control { height: 28px; padding: 0 6px; }
.dh-pv-renglones input[readonly] { background: none; border-color: transparent; font-family: var(--f-data); }
.dh-pv-renglones input[type=number] { -moz-appearance: textfield; appearance: textfield; text-align: right; }
.dh-pv-renglones input[type=number]::-webkit-inner-spin-button,
.dh-pv-renglones input[type=number]::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; }
.dh-pv-renglones td { padding-top: 3px; padding-bottom: 3px; }

/* ---- Pedidos y presupuestos a rajatabla con v4 (Pedro, 12/10/2026) -------
   Las pantallas de v4 no tienen cabecera: la miga sola y el título en la
   tarjeta (el x_title). */
.dh-crumb.es-sola { margin-bottom: 8px; }
.dh-pv-panel-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.dh-pv-panel-head .btn { margin-left: auto; }
/* La ficha a lo ancho (pedido ya vendido): cuatro datos por fila. */
.dh-campos.dh-campos-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
@media (max-width: 900px) { .dh-campos.dh-campos-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
/* Consultar pedido · «Resultado»: quitado en rojo y tachado, cambiado en
   amarillo, agregado con su rótulo verde (FASE3 §2.17c). */
tr.dh-pv-res-quitado > td  { background: var(--bad-soft); color: var(--bad); text-decoration: line-through; }
tr.dh-pv-res-cambiado > td { background: var(--warn-soft); }
tr.dh-pv-res-cambiado b    { font-weight: 700; }
/* Procesar por vendedor y Autorizar · el precio del pedido que hoy es otro
   (FASE3 §2.17e): la celda P.Unit con el color de advertencia y el precio
   de hoy en chico. Se vende al del pedido. */
td.dh-pv-precio-cambio { background: var(--warn-soft); box-shadow: inset 2px 0 0 var(--warn); }
.dh-pv-renglones td.dh-pv-precio-cambio input[readonly] { color: var(--warn); font-weight: 600; }
.dh-pv-hoy { display: block; text-align: right; font-size: 10.5px; line-height: 1.2; color: var(--warn); white-space: nowrap; }
.dh-pv-hoy[hidden] { display: none; }
.dh-pv-rot {
  display: inline-block; text-decoration: none; margin-left: 4px; padding: 0 5px; border-radius: 3px;
  font-size: 9.5px; line-height: 15px; font-weight: 600; letter-spacing: .03em; vertical-align: 1px;
}
.dh-pv-rot.es-mal  { color: var(--bad); background: var(--bad-soft); border: 1px solid var(--bad); }
.dh-pv-rot.es-bien { color: var(--ok);  background: var(--ok-soft);  border: 1px solid var(--ok); }
@media (max-width: 1200px) { .dh-pv-comparar > .dh-c6 { grid-column: span 12; } }
/* Descargar pedidos: la lista de vendedores seleccionados (dhFMC). */
.dh-pv-seleccionados { display: block; margin-top: 8px; }
.dh-pv-lista-sel { width: 100%; border-collapse: collapse; font-size: 12px; }
.dh-pv-lista-sel td { padding: 3px 0; border-bottom: 1px solid var(--line-soft); }
.dh-pv-lista-sel td.dh-acc { width: 30px; text-align: right; }
/* Formulario del producto (dhFrio): la cantidad disponible, en la franja roja. */
.dh-pv-disp { background: var(--bad-soft); border-radius: 6px; padding: 5px 10px; }
/* Autorizar: la decisión a la derecha y siempre a la vista. */
.dh-pv-decision { position: sticky; top: 12px; }
.dh-pv-autorizar > .dh-c8 { min-width: 0; }
@media (max-width: 1100px) { .dh-pv-autorizar > .dh-c8, .dh-pv-autorizar > .dh-c4 { grid-column: span 12; } .dh-pv-decision { position: static; order: -1; } }
/* Presupuesto · consultar: el PDF a la derecha, como el iframe de v4. */
.dh-pr-pdf { width: 100%; height: 580px; border: 0; display: block; background: var(--surface); }
.dh-pr-imprimir { margin-bottom: 8px; }
/* Registrar pedido: la columna de 4/12 es angosta; la fecha no la desborda. */
.dh-venta .form-control { min-width: 0; width: 100%; }
