/* ============================================================
   Estilos por pagina (tablero, promotoria, promotor). Cargado por
   base.html despues de app.css. Lo generico vive en app.css.
   ============================================================ */

/* ---------- Tablero ---------- */
.tablero .tb-sub { margin: 4px 0 0; font-size: 12.5px; max-width: 70ch; }
.tb-filtros { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.tb-kpis { margin-top: 6px; }
.tb-marca { font-weight: 600; }
.tb-tabla thead th { position: sticky; top: 0; background: var(--surface); z-index: 2; }
.tb-tabla thead tr:nth-child(2) th { top: var(--th1, 0px); }
.tb-tabla td.tb-sep, .tb-tabla th.tb-sep { border-left: 1px solid var(--line); }
.tb-tabla th.tb-grupo, .xtab th.tb-grupo { text-align: center; border-bottom: 1px solid var(--line); }
.xtab th.th-abajo { vertical-align: bottom; }
.tb-tabla tr.tb-total td { border-top: 2px solid var(--line); background: var(--surface-2); }
.tb-tabla tr.tb-sin td { opacity: .45; }
.tb-tabla tr.tb-sem-act td, .tb-tabla tr.tb-mes-act-row td { background: var(--brand-tint); }
.tb-tabla th.tb-mes-act { color: var(--brand-hi); text-decoration: underline; text-underline-offset: 3px; }
/* columnas fijas a la izquierda (1, 2 o 3) */
.tb-fix1 td:nth-child(1), .tb-fix1 th:nth-child(1),
.tb-fix2 td:nth-child(-n+2), .tb-fix2 th:nth-child(-n+2),
.tb-fix3 td:nth-child(-n+3), .tb-fix3 th:nth-child(-n+3) { position: sticky; left: 0; background: var(--surface); z-index: 1; }
.tb-fix2 td:nth-child(2), .tb-fix2 th:nth-child(2) { left: var(--c1, 0); box-shadow: 1px 0 0 var(--line); }
.tb-fix3 td:nth-child(2), .tb-fix3 th:nth-child(2) { left: var(--c1, 0); }
.tb-fix3 td:nth-child(3), .tb-fix3 th:nth-child(3) { left: var(--c2, 0); box-shadow: 1px 0 0 var(--line); }
.tb-fix1 td:nth-child(1), .tb-fix1 th:nth-child(1) { box-shadow: 1px 0 0 var(--line); }
.tb-tabla thead th:nth-child(-n+3) { z-index: 3; }
.tb-tabla tr.tb-total td:nth-child(-n+3), .tb-tabla tr:hover td:nth-child(-n+3) { background: var(--surface-2); }
.tb-tabla tr.tb-sem-act td:nth-child(-n+3), .tb-tabla tr.tb-mes-act-row td:nth-child(-n+3) { background: var(--brand-tint); }
.tb-cmp-bar { min-width: 180px; }
@media (max-width: 639.98px) {
  .tb-cmp-bar { min-width: 110px; }
  .tb-tabla thead th:nth-child(-n+3), .tb-tabla thead th:nth-child(-n+2) { position: sticky; }
  /* en telefono solo la primera columna fija: dos o tres se comen el ancho */
  .tb-fix2 td:nth-child(2), .tb-fix2 th:nth-child(2),
  .tb-fix3 td:nth-child(2), .tb-fix3 th:nth-child(2), .tb-fix3 td:nth-child(3), .tb-fix3 th:nth-child(3) { position: static; box-shadow: none; }
  .tb-fix2 td:nth-child(1), .tb-fix2 th:nth-child(1), .tb-fix3 td:nth-child(1), .tb-fix3 th:nth-child(1) { box-shadow: 1px 0 0 var(--line); }
}
@media print {
  .tabs, .tb-filtros, .btn, .nav-toggle { display: none !important; }
  .tabla-scroll, .tb-scroll { border: 0; overflow: visible; background-image: none; }
  .tb-tabla td, .tb-tabla th, .fi-tabla td, .fi-tabla th { position: static !important; }
}

/* ---------- Ficha por modelo (inicio) ---------- */
.ficha .fi-sub { margin: 4px 0 0; font-size: 12.5px; }
.fi-cab { display: grid; gap: 12px; margin-top: 16px;
  grid-template-columns: 112px repeat(auto-fit, minmax(140px, 1fr)); }
.fi-kpi-nombre { grid-column: span 2; }
.fi-nombre { font-size: 18px; line-height: 1.2; white-space: normal; }
.fi-buscar { min-width: 20ch; max-width: 100%; }
.fi-foto { display: grid; place-items: center; min-height: 96px; border: 1px dashed var(--line-hard);
  border-radius: 12px; color: var(--text-3); font-family: var(--font-mono); font-size: 10px;
  text-transform: uppercase; letter-spacing: .08em; }
.fi-h2 { margin: 28px 0 0; font-size: 14px; display: flex; align-items: baseline; gap: 10px; }
.fi-tag { font-family: var(--font-mono); font-size: 10px; font-weight: 500; color: var(--text-3);
  text-transform: uppercase; letter-spacing: .08em; }
.fi-tabla thead th { position: sticky; top: 0; background: var(--surface); z-index: 2; }
.fi-tabla thead tr:nth-child(2) th { top: var(--th1, 0px); }
.fi-tabla thead th:first-child { z-index: 3; }
.fi-tabla td.fi-sep, .fi-tabla th.fi-sep { border-left: 1px solid var(--line); }
.fi-tabla th.fi-mes-act { color: var(--brand-hi); text-decoration: underline; text-underline-offset: 3px; }
.fi-tabla tr.tb-total td { border-top: 2px solid var(--line); background: var(--surface-2); }
.fi-tabla tr.fi-despl td { color: var(--text-2); font-style: italic; }
.fi-vacio { color: var(--text-3); }
.fi-nota { font-size: 12px; color: var(--text-3); margin: 6px 0 0; max-width: 90ch; }
.fi-ok { color: var(--ok); }
.fi-amarillo { background: var(--warn-bg); color: var(--warn); }
.fi-rojo { background: var(--danger-bg); color: var(--danger-ink); font-weight: 600; }
.fi-leyenda { padding: 1px 6px; border-radius: 4px; }
.fi-parcial { outline: 1px dashed var(--warn-fill); outline-offset: -2px; color: var(--text-2); }
@media (max-width: 639.98px) { .fi-cab { grid-template-columns: repeat(2, 1fr); } .fi-foto { display: none; } }

/* ---------- Promotoria (lista + hoja del promotor) ---------- */
.pr-filtros { display:flex; gap:8px; align-items:center; flex-wrap:wrap; }
/* Un select con opciones largas (el "Qué" de /actividad/cambios) medía más
   que el teléfono y empujaba la página de lado: no pasa del ancho de la fila. */
.pr-filtros .field-periodo, .pr-filtros .select-ctrl { max-width: 100%; min-width: 0; }
.pr-kpis { margin-top: 6px; }
.pr-h3 { margin: 10px 0 4px; font-size: 13px; }
.pr-sub { margin: 4px 0 0; font-size: 12px; }
.pr-tabla { margin-top: 0; }
.pr-tabla td.pr-sep, .pr-tabla th.pr-sep { border-left: 1px solid var(--line); }
.pr-tabla tr.pr-total td { border-top: 1px solid var(--line); background: var(--surface-2); }
.pr-tabla tr.pr-inactivo td { opacity: .55; }
.pr-tabla tr.pr-inactivo td:first-child a::after { content: " · baja"; font-size: 10px; color: var(--text-3); text-transform: uppercase; letter-spacing: .08em; }
.pr-detalle { white-space: normal; max-width: 40ch; }
.pr-alta { margin-top: 12px; }
.pr-in { width: 100%; }
.pr-in-meta { width: 12ch; text-align: right; font-family: var(--font-mono); }
.pr-in-eval { width: 9ch; text-align: right; font-family: var(--font-mono); }
.pr-meta-form { display: inline-flex; gap: 6px; align-items: center; margin: 0; }
.kpi-card .pr-meta-form { display: flex; margin: 6px 0; }
.pr-inline { display: inline-flex; margin: 0; }
.pr-btn-mini { padding: 3px 9px; font-size: 10px; }
.pr-wide { flex: 1 1 260px; }
.pr-acc-cols { display: grid; gap: 18px; grid-template-columns: repeat(auto-fit, minmax(min(320px, 100%), 1fr)); }
.pr-acc-form { margin-top: 8px; }
/* dias (acordeon, uno por dia) */
.pr-dias { display: flex; flex-direction: column; gap: 6px; margin-top: 8px; }
.pr-dia { border: 1px solid var(--line); border-radius: var(--r-lg); background: var(--surface); overflow: hidden; }
.pr-dia.pr-dom { opacity: .7; }
.pr-dia.pr-fut { opacity: .5; }
.pr-dia.pr-hoy { border-color: var(--brand-hi); box-shadow: 0 0 0 2px color-mix(in srgb, var(--brand) 25%, transparent); }
.pr-dia-head {
  display: grid; grid-template-columns: 28px 36px 1fr auto auto; align-items: center; gap: 8px;
  width: 100%; padding: 8px 12px 8px 14px; min-height: var(--tap); cursor: pointer; user-select: none;
  background: none; border: 0; text-align: left; font: inherit; color: inherit;
}
.pr-dia-head:hover { background: var(--surface-2); }
.pr-dia-head .ico { color: var(--text-3); transition: transform .15s; }
.pr-dia.abierto .pr-dia-head .ico { transform: rotate(180deg); }
.pr-letra { font-family: var(--font-mono); font-size: 11px; color: var(--text-3); text-transform: uppercase; }
.pr-fecha { font-weight: 700; font-size: 16px; }
.pr-res { font-size: 13px; color: var(--text-2); font-variant-numeric: tabular-nums; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pr-avance { font-family: var(--font-mono); font-size: 12px; color: var(--text-2); }
.pr-dia.pr-cap .pr-fecha::after { content: ' ●'; color: var(--ok); font-size: 9px; vertical-align: middle; }
.pr-dia-body { display: none; padding: 4px 14px 14px; border-top: 1px solid var(--line); }
.pr-dia.abierto .pr-dia-body { display: block; }
.pr-grp { display: flex; flex-wrap: wrap; gap: 8px 12px; align-items: flex-end; padding: 10px 0; border-bottom: 1px dashed var(--line); }
.pr-grp:last-child { border-bottom: 0; }
.pr-grp label { display: flex; flex-direction: column; gap: 4px; font-size: 11px; color: var(--text-2); flex: 1 1 120px; min-width: 0; }
.pr-lbl { flex: 0 0 100%; font-family: var(--font-mono); font-size: 10px; letter-spacing: .08em; text-transform: uppercase; color: var(--text-3); }
.pr-calc { flex: 1 1 100%; font-size: 12px; color: var(--text-2); font-variant-numeric: tabular-nums; }
.pr-foto input { min-height: var(--tap); }
.pr-thumb img { height: 52px; width: 52px; object-fit: cover; border-radius: 6px; border: 1px solid var(--line); display: block; }
.pr-nota-grp .btn { flex: 0 0 auto; min-height: var(--tap); }
.pr-leyenda { display: flex; flex-wrap: wrap; gap: 4px 16px; margin: 8px 0 0; font-size: 12px; color: var(--text-2); }
.pr-leyenda b { color: var(--text); font-weight: 600; }
@media (max-width: 639.98px) {
  .pr-grp label { flex-basis: 45%; }
  .pr-nota-grp .btn { flex-basis: 100%; justify-content: center; }
  .pr-res { font-size: 12px; }
}

/* ---------- Promotoria · captura del dia (celular) ----------
   Movil primero: aqui el ancho por defecto ES el telefono, y el @media de
   arriba solo acomoda la pantalla grande. Es al reves que el resto del
   portal porque esta pagina se usa de pie en el piso de venta. */
.ph { max-width: 560px; }
.ph-head h1 { font-size: 22px; margin: 2px 0 0; }
.ph-fecha { display: flex; align-items: center; gap: 8px; margin-top: 10px; }
.ph-fecha-txt { font-size: 15px; color: var(--text-2); }
.ph-fecha-txt strong { font-size: 17px; color: var(--text); }
.ph-btn-off { opacity: .3; pointer-events: none; }
.ph-chip { font-size: 10px; text-transform: uppercase; letter-spacing: .08em; padding: 2px 7px; border-radius: 999px; }
.ph-chip-hoy { background: var(--brand); color: var(--on-brand); }
.ph-aviso { display: flex; gap: 6px; align-items: flex-start; font-size: 13px; margin: 10px 0 0; padding: 8px 10px; border-radius: var(--r-md); }
.ph-aviso .ico { flex: 0 0 auto; margin-top: 2px; }
.ph-aviso-info { background: var(--surface-2); color: var(--text-2); }
/* Faltaban las dos variantes que ya usaban Ventas y Teams: sin ellas el
   aviso salia con el fondo de la pagina y no se distinguia de un parrafo. */
.ph-aviso-warn { background: var(--warn-bg); color: var(--text); border: 1px solid color-mix(in srgb, var(--warn) 45%, transparent); }
.ph-aviso-warn .ico { color: var(--warn); }
.ph-aviso-ok { background: color-mix(in srgb, var(--ok) 12%, transparent); color: var(--text); border: 1px solid color-mix(in srgb, var(--ok) 45%, transparent); }
.ph-aviso-ok .ico { color: var(--ok); }

.ph-titulo { font-size: 13px; text-transform: uppercase; letter-spacing: .07em; color: var(--text-3); margin: 22px 0 8px; font-weight: 600; }
.ph-titulo .muted { text-transform: none; letter-spacing: 0; font-weight: 400; }

.ph-card { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg); padding: 14px; margin: 0 0 10px; }
.ph-checadas { display: flex; flex-direction: column; }
.ph-card-top { display: flex; justify-content: space-between; align-items: center; gap: 10px; }
.ph-card-nombre { font-weight: 600; font-size: 15px; }
.ph-hora { display: inline-flex; align-items: center; gap: 4px; font-family: var(--font-mono); font-size: 15px; font-weight: 600; }
.ph-hora .ico { width: 15px; height: 15px; color: var(--text-3); }
.ph-hora-vacia { font-family: var(--font-body); font-size: 12px; font-weight: 400; color: var(--text-3); }
.ph-hora-tarde { color: var(--danger); }
.ph-checada.ph-lista { border-color: color-mix(in srgb, var(--ok) 45%, var(--line)); }

.ph-guardado { display: flex; gap: 10px; margin-top: 10px; }
.ph-thumb img { width: 64px; height: 64px; object-fit: cover; border-radius: var(--r-md); border: 1px solid var(--line); display: block; }
.ph-meta { min-width: 0; font-size: 12.5px; }
.ph-meta p { margin: 0 0 2px; display: flex; align-items: center; gap: 4px; }
.ph-meta .ico { width: 14px; height: 14px; flex: 0 0 auto; }
.ph-ok { color: var(--ok); }
.ph-falta { color: var(--warn); }
.ph-mini { font-size: 11px; }
.ph-mapa { font-size: 12px; display: inline-flex; align-items: center; gap: 3px; }
.ph-mapa .ico { width: 12px; height: 12px; }

/* Boton de camara: el <input file> va escondido dentro del <label>, que es lo
   que se ve y lo que se toca. */
.ph-btn-foto {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  min-height: 52px; margin-top: 10px; cursor: pointer;
  border: 1px dashed var(--platinum-lo); border-radius: var(--r-md);
  background: var(--surface-2); color: var(--text); font-size: 15px; font-weight: 500;
}
.ph-btn-foto:active { background: var(--brand-tint); }
.ph-btn-foto input { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
.ph-btn-foto .ico { width: 20px; height: 20px; }
.ph-estado { font-size: 12.5px; margin: 8px 0 0; }
.ph-estado--espera { color: var(--text-2); }
.ph-estado--ok { color: var(--ok); }
.ph-estado--falta { color: var(--warn); }
/* Camara dentro de la pagina: en Android con poca RAM, abrir la app de camara
   manda Chrome a segundo plano, el sistema lo cierra y la foto se pierde
   ("Memoria insuficiente para completar la operacion anterior"). */
.ph-cam { position: fixed; inset: 0; z-index: 1000; background: #000; display: flex; flex-direction: column; }
.ph-cam video { flex: 1 1 auto; min-height: 0; width: 100%; object-fit: contain; background: #000; }
.ph-cam-espejo video { transform: scaleX(-1); }
.ph-cam-msg { color: #fff; text-align: center; font-size: 14px; margin: 0; padding: 10px 16px 0; }
.ph-cam-barra { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 16px 20px calc(16px + env(safe-area-inset-bottom)); }
.ph-cam-barra button { min-height: var(--tap); background: none; border: 0; color: #fff; font-size: 15px; cursor: pointer; flex: 1 1 0; }
.ph-cam-barra .ph-cam-disparo { flex: 0 0 72px; width: 72px; height: 72px; border-radius: 50%; border: 4px solid #fff; background: rgba(255, 255, 255, .25); }
.ph-cam-barra .ph-cam-disparo:disabled { opacity: .4; }
.ph-btn-guardar { width: 100%; min-height: var(--tap); justify-content: center; margin-top: 10px; }
.ph-link-retomar { background: none; border: 0; padding: 8px 0 0; color: var(--text-3); font-size: 12.5px; text-decoration: underline; cursor: pointer; }

.ph-campos { display: flex; gap: 10px; }
.ph-campos label, .ph-nota { display: flex; flex-direction: column; gap: 4px; font-size: 12px; color: var(--text-2); flex: 1 1 0; min-width: 0; }
.ph-campos input, .ph-campos select, .ph-nota input { min-height: var(--tap); font-size: 16px; }  /* 16px: menos de eso, iOS hace zoom al enfocar */
.ph-nota { margin-top: 10px; }
.ph-mas { margin-top: 12px; }
.ph-mas summary { font-size: 13px; color: var(--text-2); cursor: pointer; padding: 4px 0; }
.ph-mas .ph-campos { margin-top: 8px; }
.ph-mes { font-size: 12.5px; margin: 10px 0 0; text-align: center; }

.ph-acc-lista { list-style: none; padding: 0; margin: 0 0 10px; }
.ph-acc-lista li { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; padding: 10px 12px; border: 1px solid var(--line); border-radius: var(--r-md); margin-bottom: 6px; background: var(--surface); font-size: 13px; }
.ph-acc-tipo { font-weight: 600; }
.ph-acc-det { flex: 1 1 100%; color: var(--text-2); }
.ph-acc-sec { font-size: 11px; }
.ph-pie { margin: 24px 0 0; text-align: center; font-size: 13px; }
.ph-pie .ico { width: 14px; height: 14px; vertical-align: -2px; }

@media (max-width: 400px) {
  .ph-campos { flex-direction: column; gap: 8px; }
}

/* Evidencia de la checada dentro de la hoja del mes (vista de supervision). */
.pr-evid { flex: 1 1 100%; font-size: 11.5px; display: flex; gap: 6px; align-items: center; flex-wrap: wrap; }
.pr-evid .ico { width: 13px; height: 13px; }
.pr-evid-ok { color: var(--ok); display: inline-flex; align-items: center; gap: 3px; }
.pr-evid-falta { color: var(--warn); display: inline-flex; align-items: center; gap: 3px; }


/* --- Tablero: panel de filtros y resumen del cursor -----
   Los filtros viven en el panel lateral (.filtros-side, en app.css). De los
   chips solo queda el aviso de la lista de productos recortada. */
.tb-nota-filtro { margin: 2px 0 0; }
/* Calendario del panel, debajo de los atajos del mismo slicer. Una fecha por
   renglón: en 15.5rem, dos campos de fecha lado a lado se cortan a la mitad. */
.tb-fechas {
  display: grid; gap: 5px; padding: 7px 9px 9px;
  border-top: 1px solid var(--line); background: var(--surface-2);
}
.tb-fechas label {
  display: grid; grid-template-columns: 2.1rem 1fr; align-items: center; gap: 6px;
  font-family: var(--font-mono); font-size: 10px; letter-spacing: .1em;
  text-transform: uppercase; color: var(--text-3);
}
.tb-fechas input[type="date"] {
  font-family: var(--font-mono); font-size: 12.5px; padding: 6px 7px;
  min-width: 0; width: 100%; min-height: 32px;
  color: var(--text); background: var(--canvas);
  border: 1px solid var(--line); border-radius: 6px;
}
.tb-fechas input[type="date"]:focus {
  outline: none; border-color: var(--platinum);
}
/* El icono del calendario viene negro: sobre el tema oscuro hay que
   invertirlo, sobre papel no (quedaria blanco sobre blanco). */
.tb-fechas input[type="date"]::-webkit-calendar-picker-indicator {
  opacity: .55; cursor: pointer;
}
:root[data-tema="oscuro"] .tb-fechas input[type="date"]::-webkit-calendar-picker-indicator {
  filter: invert(1);
}
.tb-fechas input[type="date"]:hover::-webkit-calendar-picker-indicator { opacity: 1; }
.tb-chips { margin: 0 0 10px; }
.tb-tabla tr.tb-resto td { font-style: italic; color: var(--text-3); }

.tb-tip { position: fixed; z-index: 60; pointer-events: none; max-width: 300px;
  padding: 10px 12px; border: 1px solid var(--line-hard); border-radius: 8px;
  background: var(--surface); box-shadow: 0 10px 28px rgba(17, 19, 24, .18);
  font-size: 12.5px; line-height: 1.35; }
.tb-tip[hidden] { display: none; }
.tb-tip.fijo { border-color: var(--brand-hi); }
.tb-tip-cab { font-weight: 600; }
.tb-tip-sub { color: var(--text-3); font-size: 11.5px; margin-top: 1px; }
.tb-tip-val { font-size: 19px; font-weight: 650; margin: 6px 0 5px;
  font-variant-numeric: tabular-nums; }
.tb-tip-fila { display: flex; justify-content: space-between; gap: 16px; padding: 1px 0; }
.tb-tip-fila > span { color: var(--text-3); }
.tb-tip-fila > b { font-variant-numeric: tabular-nums; font-weight: 600; }
.tb-tip-fila.up > b { color: var(--ok); }
.tb-tip-fila.down > b { color: var(--danger-ink); }
.tb-tabla td[data-c]:hover { outline: 1.5px solid var(--brand-hi); outline-offset: -1px; cursor: help; }
@media print { .tb-tip, .tb-chips { display: none !important; } }

/* --- Tablero: filtrar desde el encabezado y las etiquetas de las tablas ---- */
.tb-lbl { color: inherit; text-decoration: none; border-bottom: 1px dotted var(--line-hard); }
.tb-lbl:hover { color: var(--brand-hi); border-bottom-color: var(--brand-hi); }

.tb-menu { display: inline-block; }
.tb-menu > summary { list-style: none; cursor: pointer; display: inline-flex;
  align-items: center; gap: 4px; white-space: nowrap; }
.tb-menu > summary::-webkit-details-marker { display: none; }
.tb-menu > summary .ico { width: 11px; height: 11px; opacity: .35; flex: none; }
.tb-menu > summary:hover { color: var(--brand-hi); }
.tb-menu > summary:hover .ico, .tb-menu[open] > summary .ico { opacity: 1; }
.tb-menu.on > summary { color: var(--brand-hi); }
.tb-menu.on > summary .ico { opacity: 1; }

/* Posicion fija: el popup vive dentro de una tabla con overflow-x y en flujo
   normal quedaria recortado. El <script> del final le pone left/top. */
.tb-menu-pop { position: fixed; z-index: 70; min-width: 170px; max-width: 320px;
  max-height: 320px; overflow-y: auto; padding: 4px;
  border: 1px solid var(--line-hard); border-radius: 8px; background: var(--surface);
  box-shadow: 0 10px 28px rgba(17, 19, 24, .18); }
.tb-menu-pop a { display: block; padding: 4px 9px; border-radius: 5px;
  font-size: 12.5px; font-weight: 400; text-transform: none; letter-spacing: 0;
  color: var(--text); text-decoration: none; white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis; }
.tb-menu-pop a:hover { background: var(--surface-2); color: var(--brand-hi); }
.tb-menu-pop a.act { color: var(--brand-hi); font-weight: 600; }

.tb-menu-pop hr { margin: 4px 2px; border: 0; border-top: 1px solid var(--line); }
.tb-menu-pop .tb-ord { display: block; width: 100%; padding: 4px 9px; border: 0;
  border-radius: 5px; background: none; cursor: pointer; text-align: left;
  font: inherit; font-size: 12.5px; font-weight: 400; text-transform: none;
  letter-spacing: 0; color: var(--text-2); white-space: nowrap; }
.tb-menu-pop .tb-ord:hover { background: var(--surface-2); color: var(--brand-hi); }

/* --- Tablero: ordenar por columna ----------------------------------------- */
.tb-ord-th { cursor: pointer; user-select: none; }
.tb-ord-th:hover { color: var(--brand-hi); }
.tb-tabla th[data-orden] { color: var(--brand-hi); }
.tb-tabla th[data-orden]::after { font-size: 9px; margin-left: 3px; }
.tb-tabla th[data-orden="desc"]::after { content: "▼"; }
.tb-tabla th[data-orden="asc"]::after { content: "▲"; }

@media print {
  .tb-menu > summary .ico { display: none; }
  .tb-menu-pop { display: none !important; }
  .tb-lbl { border-bottom: 0; }
}

/* ---------- Promotoria v2 (pv-) ----------
   Pantallas del mockup del cliente: supervisor (mis promotores -> contacto /
   metas / asistencias) y promotor (% de meta, checar, exhibicion). Movil
   primero, como .ph: se usan de pie en la tienda. En escritorio (jefe y
   supervisores en la oficina) el tope es el ancho "lg": a 720px la lista de
   promotores se cortaba con barra horizontal. */
.pv { max-width: 1200px; }
.pv-admin { max-width: none; }
.pv-lista { max-width: none; }
.pv-dest { max-width: none; }
.pv-head { display: flex; justify-content: space-between; align-items: flex-end; gap: 12px; flex-wrap: wrap; margin-bottom: 14px; }
.pv h1 { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.pv-miga { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; font-family: var(--font-mono); font-size: 10.5px; letter-spacing: .1em; text-transform: uppercase; color: var(--text-3); margin: 0 0 10px; }
.pv-miga a { color: var(--text-2); text-decoration: none; }
.pv-miga a:hover { color: var(--brand-hi); }
.pv-miga [aria-current] { color: var(--text); font-weight: 600; }
.pv-miga-sep .ico { width: 12px; height: 12px; }
.pv-vacio { display: flex; gap: 6px; align-items: flex-start; padding: 12px 14px; margin: 12px 0; border: 1px dashed var(--line-hard); border-radius: var(--r-lg); font-size: 13.5px; color: var(--text-2); }
.pv-vacio .ico { flex: 0 0 auto; margin-top: 2px; }

/* menu del promotor: tres tarjetas grandes */
.pv-tarjetas { display: grid; gap: 10px; margin-top: 16px; }
.pv-tarjeta { display: grid; grid-template-columns: 1fr auto; grid-template-rows: auto auto; align-items: center; gap: 2px 10px; padding: 16px; min-height: var(--tap); background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg); text-decoration: none; color: var(--text); }
.pv-tarjeta:hover { border-color: var(--brand); box-shadow: var(--shadow-sm); }
.pv-tarjeta-titulo { font-weight: 700; font-size: 16px; }
.pv-tarjeta .muted { font-size: 12.5px; }
.pv-tarjeta .ico { grid-column: 2; grid-row: 1 / span 2; color: var(--text-3); }

/* formularios */
.pv-form { display: grid; gap: 10px; }
.pv-guardado { margin: 0; display: flex; align-items: center; gap: 6px; font-size: 13px; font-weight: 600; color: var(--ok); }
.pv-sin-llegada { margin: 0 0 10px; display: flex; align-items: flex-start; gap: 6px; font-size: 13px; color: var(--warn); }
.pv-form label { display: flex; flex-direction: column; gap: 4px; font-size: 12px; color: var(--text-2); }
.pv-form .btn { justify-self: start; }
.pv-form-inline { display: flex; flex-wrap: wrap; gap: 10px; align-items: flex-end; }
.pv-form-inline label { display: flex; flex-direction: column; gap: 4px; font-size: 12px; color: var(--text-2); flex: 1 1 140px; }
.pv-in-hora { width: 8ch; font-family: var(--font-mono); }
.pv-in-usuario { min-width: 11ch; }
.pv-datos { margin: 0; display: grid; grid-template-columns: max-content 1fr; gap: 8px 14px; font-size: 13.5px; }
.pv-datos dt { color: var(--text-3); font-size: 11px; text-transform: uppercase; letter-spacing: .08em; font-family: var(--font-mono); align-self: center; }
.pv-datos dd { margin: 0; overflow-wrap: anywhere; }

/* mes */
.pv-mes { display: flex; align-items: center; gap: 10px; margin: 10px 0 14px; font-size: 15px; }

/* anillo de meta */
.pv-anillo { position: relative; width: 96px; height: 96px; }
.pv-anillo-xl { width: 150px; height: 150px; }
.pv-anillo svg { width: 100%; height: 100%; transform: rotate(-90deg); }
.pv-anillo circle { fill: none; stroke-width: 9; }
.pv-anillo-fondo { stroke: var(--surface-2); }
.pv-anillo-valor { stroke: var(--brand); stroke-linecap: round; transition: stroke-dasharray .5s ease; }
.pv-anillo-valor.pv-anillo-ok { stroke: var(--ok); }
.pv-anillo-txt { position: absolute; inset: 0; display: grid; place-items: center; font-family: var(--font-mono); font-weight: 600; font-size: 20px; }
.pv-anillo-xl .pv-anillo-txt { font-size: 30px; }
.pv-meta { display: flex; gap: 20px; align-items: center; flex-wrap: wrap; }
.pv-meta-anillo { display: flex; flex-direction: column; align-items: center; gap: 8px; }
.pv-meta-rot { margin: 0; text-align: center; font-size: 12px; color: var(--text-2); line-height: 1.3; }
.pv-meta-cifras { display: grid; gap: 12px; flex: 1 1 200px; }
.pv-meta-cifras-fila { grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); }
.pv-cifra { display: block; font-family: var(--font-mono); font-size: 24px; font-weight: 600; line-height: 1.1; }
.pv-cifra-rot { display: block; font-size: 12px; color: var(--text-2); }

/* chips del semaforo */
.pv-chip { display: inline-block; font-size: 10px; font-weight: 600; letter-spacing: .08em; text-transform: uppercase; padding: 2px 8px; border-radius: 999px; background: var(--surface-2); color: var(--text-2); vertical-align: middle; }
.pv-chip-a_tiempo { background: color-mix(in srgb, var(--ok) 14%, transparent); color: var(--ok); }
.pv-chip-retardo { background: color-mix(in srgb, var(--warn) 16%, transparent); color: var(--warn); }
.pv-chip-falto { background: color-mix(in srgb, var(--danger) 12%, transparent); color: var(--danger); }
.pv-chip-pendiente { background: color-mix(in srgb, var(--brand) 12%, transparent); color: var(--brand-hi); }
.pv-chip-aprobado { background: color-mix(in srgb, var(--ok) 14%, transparent); color: var(--ok); }
.pv-chip-rechazado { background: color-mix(in srgb, var(--danger) 12%, transparent); color: var(--danger); }
.pv-chip-contratado { background: color-mix(in srgb, var(--gold) 16%, transparent); color: var(--gold); }

/* insignia de iniciales, celda de nombre en tablas de personas */
.pv-avatar {
  display: inline-flex; align-items: center; justify-content: center;
  width: 24px; height: 24px; border-radius: 50%; vertical-align: middle;
  margin-right: 6px; font-family: var(--font-mono); font-size: 10px;
  font-weight: 700; letter-spacing: .02em; color: var(--brand-hi);
  background: var(--text-3);
}
.pv-tabla tbody tr:nth-child(6n+1) .pv-avatar { background: var(--ok); }
.pv-tabla tbody tr:nth-child(6n+2) .pv-avatar { background: var(--brand); color: var(--surface); }
.pv-tabla tbody tr:nth-child(6n+3) .pv-avatar { background: var(--warn); }
.pv-tabla tbody tr:nth-child(6n+4) .pv-avatar { background: var(--danger); }
.pv-tabla tbody tr:nth-child(6n+5) .pv-avatar { background: var(--gold); }
.pv-tabla tbody tr:nth-child(6n+6) .pv-avatar { background: var(--text-3); }
.pv-skills { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.pv-skills li { padding: 6px 10px; background: var(--surface-2); border-radius: var(--r-lg); font-size: 13.5px; }
.pv-leyenda { display: flex; flex-wrap: wrap; gap: 6px 14px; margin: 0 0 10px; font-size: 13px; }
.pv-leyenda span { display: inline-flex; align-items: center; gap: 4px; }

/* semanas y dias */
.pv-semanas { display: grid; gap: 10px; }
.pv-semana-titulo { margin: 0 0 8px; font-weight: 700; }
.pv-dias { display: flex; flex-wrap: wrap; gap: 8px; }
.pv-dia { display: flex; flex-direction: column; align-items: center; gap: 1px; min-width: 66px; padding: 8px 6px; border: 1px solid var(--line); border-left: 4px solid var(--line); border-radius: var(--r-md); text-decoration: none; color: var(--text); background: var(--surface); }
.pv-dia:hover { border-color: var(--brand); }
.pv-dia-num { font-family: var(--font-mono); font-size: 18px; font-weight: 600; }
.pv-dia-rot { font-size: 10px; text-transform: uppercase; letter-spacing: .08em; color: var(--text-3); }
.pv-dia-est { font-size: 10.5px; color: var(--text-2); }
.pv-dia-a_tiempo { border-left-color: var(--ok); }
.pv-dia-retardo { border-left-color: var(--warn); }
.pv-dia-falto { border-left-color: var(--danger); }
.pv-dia-pendiente { border-left-color: var(--brand); }
.pv-dia-hoy { box-shadow: 0 0 0 2px color-mix(in srgb, var(--brand) 25%, transparent); }
.pv-jornada { margin-top: 16px; }
.pv-jornada summary { cursor: pointer; }
.pv-jornada form { margin-top: 10px; }

/* dia */
.pv-eventos, .pv-exhib { display: grid; gap: 10px; }
.pv-corrige { margin-top: 8px; }
.pv-checar { width: 100%; min-height: var(--tap); font-size: 14px; margin-top: 10px; }

/* inicio del promotor */
.pv-yo { text-align: center; max-width: 480px; }
.pv-yo-titulo { justify-content: center; font-size: 15px; text-transform: uppercase; letter-spacing: .08em; color: var(--text-2); margin-bottom: 8px; }
.pv-yo-anillo { display: inline-block; text-decoration: none; }
.pv-yo-sub { margin: 6px 0 20px; }
.pv-yo-btn { display: flex; flex-direction: column; align-items: center; gap: 2px; width: 100%; min-height: 64px; font-size: 16px; }
.pv-yo-btn-sub { font-size: 11.5px; font-weight: 400; opacity: .85; text-transform: none; letter-spacing: 0; }
.pv-yo-datos { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; margin: 24px 0 0; text-align: left; }
.pv-yo-datos div { padding: 10px; background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-md); }
.pv-yo-datos dt { font-family: var(--font-mono); font-size: 10px; letter-spacing: .1em; text-transform: uppercase; color: var(--text-3); }
.pv-yo-datos dd { margin: 2px 0 0; font-size: 13px; font-weight: 600; overflow-wrap: anywhere; }
.pv-yo-links { display: flex; justify-content: center; gap: 18px; margin-top: 18px; font-size: 13px; }
.pv-yo-links a { display: inline-flex; align-items: center; gap: 2px; }

/* tablas */
.pv-tabla td { padding: 14px 16px; }
.pv-tabla-chica { width: auto; }
.pv-tabla-form td { vertical-align: middle; }
.pv-tabla-form .pr-in, .pv-tabla-form .select-ctrl { min-width: 9ch; }
.pv-sel-tienda { max-width: 260px; }
.pv-fila-alta td { background: var(--surface-2); }
.pv-importar { display: grid; gap: 10px; grid-template-columns: repeat(auto-fit, minmax(min(320px, 100%), 1fr)); }

/* Un <select> mide, en Chromium, lo que mida su opcion mas larga, y como
   item de grid su min-width es auto: el de "Tienda" (todas las sucursales de
   todas las cadenas) ensanchaba el formulario y con el la pagina entera.
   minmax(0,1fr) deja que la columna se encoja y el select recorte. */
.pv-form { grid-template-columns: minmax(0, 1fr); }
.pv-form > *, .pv-form label { min-width: 0; }
/* max-width y no width: hay controles que se quieren angostos a proposito
   (.pv-in-hora son 8ch, .pv-tabla-form pone min-width 9ch en las celdas) y
   un width:100% aqui se los comeria. */
.pv-form select, .pv-form input, .pv-form textarea { max-width: 100%; box-sizing: border-box; }
.pv-form select { width: 100%; }
.pv-tabla-form select, .pv-form-inline select { width: auto; }   /* en celda y en linea manda el ancho del contenido */

/* Colchon: una tabla ancha SIN el wrapper .tabla-scroll (las de supervision)
   ensancharia la PAGINA entera, y a ancho de telefono el encabezado, las
   tarjetas y los formularios quedan cortados a la derecha. Con esto la tabla
   se desplaza sola y la pagina no. Dentro de .tabla-scroll manda su propia
   regla (`min-width: max-content`). */
@media (max-width: 639.98px) {
  :not(.tabla-scroll):not(.tb-scroll) > table.pv-tabla {
    display: block; width: 100%; max-width: 100%;
    overflow-x: auto; -webkit-overflow-scrolling: touch; overscroll-behavior-x: contain;
  }
}

/* Dos tablas de supervision caben enteras si se les quita una columna que es
   ayuda y no dato, y eso es mejor que dejarlas desplazarse: en el celular lo
   que queda fuera de cuadro es justo lo que el supervisor va a leer o a
   capturar.
     evaluacion  Rubro · Criterio · Peso · Cumplimiento · Puntos -> fuera el
                 criterio ("Minimo 80%"), que ademas ya esta en el manual.
     visitas     ...Duracion · Promotores · ACC -> fuera los dos conteos, que
                 se ven completos al abrir la visita. */
@media (max-width: 639.98px) {
  :not(.tabla-scroll):not(.tb-scroll) > table.pv-tabla-eval,
  :not(.tabla-scroll):not(.tb-scroll) > table.pv-tabla-visitas { display: table; overflow-x: visible; }
  /* thead/tbody y no `th:nth-child(2)` a secas: en el pie la segunda celda
     es el TOTAL (la primera es el <th colspan> con la palabra "Total"), y
     la regla suelta lo escondia justo a el. */
  .pv-tabla-eval thead th:nth-child(2), .pv-tabla-eval tbody td:nth-child(2) { display: none; }
  .pv-tabla-visitas th:nth-last-child(-n+2), .pv-tabla-visitas td:nth-last-child(-n+2) { display: none; }
  .pv-tabla-eval th, .pv-tabla-eval td,
  .pv-tabla-visitas th, .pv-tabla-visitas td { padding-left: 8px; padding-right: 8px; }
  .pv-tabla-eval tfoot th[colspan] { text-align: right; }
}

@media (max-width: 480px) {
  .pv-yo-datos { grid-template-columns: 1fr; }
  .pv-meta { flex-direction: column; align-items: stretch; }
  .pv-meta-anillo { align-self: center; }
  /* En columna el flex-basis de 200px se vuelve alto y estira las cifras. */
  .pv-meta-cifras { flex-basis: auto; }
}

/* ---------- Promotoria v2 · hoja tipo Excel del admin ---------- */
.pv-hojas { display: flex; align-items: center; gap: 4px; flex-wrap: wrap; margin: 14px 0 0; border-bottom: 1px solid var(--line-hard); }
.pv-hoja { border: 1px solid transparent; border-bottom: 0; background: none; padding: 8px 14px; font: inherit; font-size: 13px; font-weight: 600; color: var(--text-2); cursor: pointer; border-radius: var(--r-md) var(--r-md) 0 0; margin-bottom: -1px; }
.pv-hoja:hover { color: var(--text); background: var(--surface-2); }
.pv-hoja.activo { color: var(--brand-hi); background: var(--surface); border-color: var(--line-hard); border-bottom: 1px solid var(--surface); }
.pv-n { font-family: var(--font-mono); font-size: 10.5px; font-weight: 400; color: var(--text-3); margin-left: 4px; }
.pv-buscar { display: flex; align-items: center; gap: 6px; flex: 1 1 260px; margin-left: auto; padding: 4px 0; }
.pv-buscar .ico { color: var(--text-3); flex: 0 0 auto; }
.pv-buscar input { width: 100%; max-width: 420px; padding: 7px 10px; font: inherit; font-size: 13px; border: 1px solid var(--line-hard); border-radius: var(--r-md); background: var(--surface); }
.pv-importar-det summary { list-style: none; display: inline-flex; gap: 6px; }
.pv-importar-det summary::-webkit-details-marker { display: none; }
.pv-importar-det[open] .pv-importar { margin-top: 10px; }

.pv-grid { overflow: auto; max-height: calc(100vh - 230px); border: 1px solid var(--line-hard); border-top: 0; background: var(--surface); }
.pv-excel { border-collapse: separate; border-spacing: 0; width: max-content; min-width: 100%; font-size: 12.5px; }
.pv-excel th, .pv-excel td { border-right: 1px solid var(--line); border-bottom: 1px solid var(--line); padding: 0; white-space: nowrap; vertical-align: middle; background: var(--surface); }
.pv-excel thead th { position: sticky; top: 0; z-index: 3; background: var(--surface-2); font-family: var(--font-mono); font-size: 10px; letter-spacing: .08em; text-transform: uppercase; color: var(--text-3); text-align: left; padding: 8px 8px; }
.pv-excel .pv-fijo { position: sticky; left: 0; z-index: 2; box-shadow: 2px 0 0 var(--line); }
.pv-excel thead .pv-fijo { z-index: 4; }
.pv-excel td.pv-fijo { display: flex; align-items: center; gap: 4px; min-width: 220px; }
.pv-excel td.pv-fijo input { font-weight: 600; }
.pv-excel input:not([type=checkbox]), .pv-excel select { width: 100%; min-width: 8ch; border: 0; background: transparent; padding: 7px 8px; font: inherit; font-size: 12.5px; color: var(--text); outline: 0; }
.pv-excel input.mono, .pv-excel td.mono { font-family: var(--font-mono); font-size: 12px; }
.pv-excel input:focus, .pv-excel select:focus { background: color-mix(in srgb, var(--brand) 8%, var(--surface)); box-shadow: inset 0 0 0 2px var(--brand); }
.pv-excel select { max-width: 260px; text-overflow: ellipsis; }
.pv-excel td.pv-solo { padding: 7px 8px; color: var(--text-2); }
.pv-excel td.pv-c { text-align: center; padding: 0 10px; }
.pv-excel td.num { text-align: right; font-family: var(--font-mono); }
.pv-excel .pv-acc { padding: 3px 6px; position: sticky; right: 0; z-index: 2; box-shadow: -2px 0 0 var(--line); }
.pv-excel thead .pv-acc { z-index: 4; }
.pv-guardar { opacity: .45; }
.pv-fila:hover td { background: var(--surface-2); }
.pv-fila.pv-sucio td { background: color-mix(in srgb, var(--warn) 9%, var(--surface)); }
.pv-fila.pv-sucio .pv-guardar { opacity: 1; background: var(--brand); color: var(--on-brand); border-color: var(--brand); }
.pv-fila.pv-resalta td { background: color-mix(in srgb, var(--ok) 12%, var(--surface)); }
.pv-fila.pv-baja td { opacity: .55; }
.pv-fila.pv-alta td { background: var(--surface-2); }
.pv-fila.pv-alta input::placeholder { color: var(--text-3); font-style: italic; }
.pv-pend { color: var(--warn) !important; font-style: italic; }
.pv-ir { color: var(--text-3); padding: 0 6px; display: inline-flex; }
.pv-ir:hover { color: var(--brand-hi); }
.pv-ir .ico { width: 14px; height: 14px; }

/* ---------- Promotoria v2 · seguimiento del equipo ---------- */
/* Rotulo de bloque: el dia, la semana, el mes (2026-09-21). La pantalla
   hablaba de un dia en el titulo y luego mezclaba mes y semana sin avisar --
   la tarjeta de meta del mes junto a las del dia, el ranking del mes entre
   dos secciones del dia. Cada bloque lleva ahora su periodo escrito, con
   una linea que lo separa de verdad: un <h2> mas no alcanzaba, porque ya
   habia seis h2 en la pagina y todos se veian igual. */
.pv-bloque {
  display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap;
  margin: 34px 0 14px; padding-top: 13px; border-top: 2px solid var(--line-hard);
  font-family: var(--font-mono); font-size: 10.5px; text-transform: uppercase;
  letter-spacing: .16em; color: var(--text-3);
}
.pv-bloque b { font-family: var(--font-body); font-size: 15px; font-weight: 600;
  letter-spacing: 0; text-transform: none; color: var(--text-1); }
.pv-bloque .muted { letter-spacing: 0; text-transform: none; font-size: 12px; }
.pv-bloque:first-of-type { margin-top: 18px; }

.pv-seg { max-width: none; }
.pv-kpis { margin-top: 10px; }
/* Padding en vez de margen: no se colapsa con el margen del section-title
   de abajo, asi que la fila de graficas del dia siempre queda con aire
   real antes del siguiente titulo, sin importar el layout (una o dos
   columnas). */
.pv-seg-charts { padding-bottom: 20px; }
/* Tarjetas "spotlight" de /promotoria/destacados: mas aire y texto mas
   grande que un kpi-card normal, porque cada una cuenta una persona, no
   solo un numero. */
.pv-destacados { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 14px; margin: 14px 0 4px; }
.pv-destacado .kpi-label { display: flex; align-items: center; gap: 6px; margin-bottom: 10px; }
.pv-destacado-persona { display: flex; align-items: center; gap: 8px; font-size: 15px; margin-bottom: 2px; }
.pv-destacado-dato { font-family: var(--font-mono); font-size: 20px; font-weight: 600; color: var(--brand-hi); margin: 8px 0 0; }
/* Caja de canvas separada del <h3> del chart-wrap: si el alto fijo se le
   pone al chart-wrap completo (titulo + canvas), el canvas se desborda
   por abajo (el titulo ya se comio parte de esos pixeles) y el borde
   redondeado se ve "cortado". Aislando el canvas en su propia caja con
   su propio alto, el chart-wrap crece lo que haga falta y nunca se
   desborda. */
.pv-chart-box { position: relative; height: 220px; }
.pv-seg-tabla td { vertical-align: middle; padding: 8px 12px; }
.pv-seg-tabla tr.pv-seg-falto td:first-child { box-shadow: inset 3px 0 0 var(--danger); }
.pv-seg-tabla tr.pv-seg-retardo td:first-child { box-shadow: inset 3px 0 0 var(--warn); }
.pv-seg-tabla tr.pv-seg-a_tiempo td:first-child { box-shadow: inset 3px 0 0 var(--ok); }
.pv-seg-fotos { display: flex; gap: 4px; }
.pv-mini-foto { position: relative; display: block; }
.pv-mini-foto img { width: 44px; height: 44px; object-fit: cover; border-radius: 6px; border: 1px solid var(--line); display: block; }
.pv-geo-ok { position: absolute; right: -3px; bottom: -3px; background: var(--ok); color: var(--on-brand); border-radius: 50%; width: 16px; height: 16px; display: grid; place-items: center; }
.pv-geo-ok .ico { width: 10px; height: 10px; }
.pv-galeria { display: grid; gap: 12px; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); margin-top: 8px; }
.pv-foto { margin: 0; background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg); overflow: hidden; }
.pv-foto img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; display: block; }
.pv-foto figcaption { display: flex; flex-direction: column; gap: 2px; padding: 8px 10px; font-size: 12px; }
.pv-foto figcaption a { display: inline-flex; align-items: center; gap: 3px; }
.pv-foto figcaption .ico { width: 13px; height: 13px; }
/* Visita del supervisor: atajos arriba de la ficha y el aviso de "estás en
   tienda" que sustituye al formulario de llegada mientras haya una abierta. */
.pv-atajos, .pv-abierta { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.pv-abierta p { flex: 1 1 100%; margin: 0 0 4px; }
.pv-foto figcaption form { margin-top: 4px; }
/* Inicio del mercha: Asistencia y Visitas a tienda, uno bajo el otro. */
.pv-yo-btn + .pv-yo-btn { margin-top: 10px; }

/* ============================================================
   Control Tower de importaciones (/importaciones/control)

   La reja es Tabulator, ya tematizada en app.css; aqui solo van el
   semaforo de dias y el avance del checklist documental. El color NO se
   decide en el CSS: la clase se la pone el formateador de la columna
   leyendo `sem_*`, que calcula app/importaciones_control.py. Un solo
   lugar define que es verde.
   ============================================================ */
.sem-verde    { color: var(--ok); font-variant-numeric: tabular-nums; }
.sem-amarillo { color: var(--warn); font-variant-numeric: tabular-nums; }
.sem-rojo     { color: var(--danger-ink); font-variant-numeric: tabular-nums; font-weight: 600; }
/* Etapa todavia corriendo: el numero sigue subiendo, se marca con punto. */
.sem-curso::after { content: " ·"; content: " ·" / ""; opacity: .6; }
/* Semaforo con FORMA ademas de color (semaforo() de importaciones.js y sem()
   de _importaciones.html): punto, triangulo y rombo se distinguen en escala
   de grises y con daltonismo. La forma es decorativa ("/ ''" la calla para
   el lector, que ya oye "(rojo, fuera de objetivo)"); el primer `content`
   es el respaldo de los navegadores sin texto alternativo en content. */
.ct-sem::before { display: inline-block; width: 1.1em; font-size: .8em; }
.ct-sem.sem-verde::before    { content: "●"; content: "●" / ""; }
.ct-sem.sem-amarillo::before { content: "▲"; content: "▲" / ""; }
.ct-sem.sem-rojo::before     { content: "◆"; content: "◆" / ""; }

/* Avance documental: 7 casillas resumidas a "5/7" con barrita. El ancho
   llega como dato (style="--pct:NN%"), no como estilo en linea. */
.ct-docs { display: flex; align-items: center; gap: 7px; font-variant-numeric: tabular-nums; }
.ct-docs-barra { flex: 1; height: 4px; border-radius: 2px; background: var(--surface-3); overflow: hidden; min-width: 34px; }
.ct-docs-barra span { display: block; height: 100%; width: var(--pct, 0%); background: var(--platinum); }
.ct-docs.completo .ct-docs-barra span { background: var(--ok); }
/* Docs como enlace a la pestaña Documentos de la ficha (plan 3.3). */
.ct-docs-enlace { color: inherit; text-decoration: none; display: block; }
.ct-docs-enlace:hover .ct-docs, .ct-docs-enlace:focus-visible .ct-docs { text-decoration: underline; }

/* Casilla documental como interruptor (ctDoc() de importaciones.js): check
   en --ok si esta, circulo vacio en --text-3 si falta. Nada de rojo: que
   falte un papel no es un error, es lo que sigue. */
.ct-doc {
  display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 28px; padding: 0; border: 0; border-radius: 50%;
  background: none; color: var(--text-3); cursor: pointer;
}
.ct-doc[aria-disabled="true"] { cursor: default; }
/* En tactil el interruptor llega a --tap (44px) como el resto de objetivos
   (app.css); el icono sigue de 16px. Son 7 casillas pegadas por fila. */
@media (pointer: coarse), (max-width: 639.98px) {
  .ct-doc { width: var(--tap); height: var(--tap); }
}
.ct-doc:focus-visible { outline: 2px solid var(--brand); outline-offset: 1px; }
.ct-doc--ok { color: var(--ok); }
.ct-doc .ico { width: 16px; height: 16px; }
.ct-doc-vacio { width: 12px; height: 12px; border: 1.5px solid currentColor; border-radius: 50%; }
/* La celda de una casilla (cssClass de colDoc): sin el relleno lateral de
   la reja, para que el interruptor de 44px quepa en la columna de 64px sin
   que Tabulator le pegue los puntos suspensivos. */
.tabulator .tabulator-row .tabulator-cell.ct-doc-celda { padding-left: 0; padding-right: 0; text-overflow: clip; }

/* Historial de fechas (ventana de la comprometida). Antes en un <style>
   propio de la plantilla con hex de respaldo; aqui, con tokens. */
.ct-hist { list-style: none; margin: 0; padding: 0; max-height: 50dvh; overflow-y: auto; }
.ct-hist li { padding: 8px 0; border-bottom: 1px solid var(--line); font-size: var(--fs-sm); }
/* 12px y no --fs-xs (11px): metadatos atenuados dentro de un dialogo que
   tambien se lee en telefono; los rotulos no bajan de 12px. */
.ct-hist .muted { font-size: 12px; }
/* Aviso de arribo (ventana de vista previa del correo). */
.ct-aviso { display: flex; flex-direction: column; gap: 10px; font-size: var(--fs-sm); max-height: 62dvh; overflow-y: auto; }
.ct-aviso p { margin: 0; }
.ct-aviso-bloqueos { color: var(--danger-ink); border: 1px solid var(--danger-ink); border-radius: 8px; padding: 8px 12px; }
.ct-aviso-bloqueos ul { margin: 4px 0 0; padding-left: 18px; }
.ct-aviso-repetido { color: var(--ok); }
.ct-aviso-datos { display: grid; grid-template-columns: max-content 1fr; gap: 4px 12px; margin: 0; }
.ct-aviso-datos dt { color: var(--text-3); }
.ct-aviso-datos dd { margin: 0; overflow-wrap: anywhere; }
.ct-aviso-tabla { overflow-x: auto; }
.ct-aviso-tabla td.num { text-align: right; font-variant-numeric: tabular-nums; }
.ct-aviso-sub { margin: 4px 0 0; font-size: var(--fs-sm); }
.ct-aviso .ct-hist { max-height: none; }
.ct-aviso-pie { display: flex; align-items: center; justify-content: flex-end; gap: 12px; flex-wrap: wrap; }
#ct-aviso-msg.ct-estado--error, #ct-odoo-msg.ct-estado--error { color: var(--danger-ink); }
/* Envio a Odoo: misma ventana de vista previa que el aviso de arribo. */
.ct-odoo-error { color: var(--danger-ink); }
.ct-odoo-omitidas { margin: 0; padding-left: 18px; color: var(--text-2); }
.ct-in-correos { min-width: min(320px, 100%); }
/* Lo proyectado (llegada o desviacion que todavia no pasa): en cursiva. */
.ct-proy { font-style: italic; opacity: .85; }
/* La fecha comprometida abre su historial: boton que se ve como texto. */
.ct-comp-btn {
  background: none; border: 0; padding: 0; color: inherit; font: inherit;
  text-decoration: underline dotted; cursor: pointer;
}
/* Atajo a la Ficha del embarque (plan 2.10): el icono chevron-right de
   icon() en lugar de la flecha de texto. */
.ct-abrir {
  display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 28px; border-radius: 6px; color: var(--text-2);
}
.ct-abrir:hover { background: var(--surface-2); color: var(--text); }
.ct-abrir:focus-visible { outline: 2px solid var(--brand); outline-offset: 1px; }
.ct-abrir .ico { width: 16px; height: 16px; }
/* Areas tactiles >= 44x44 en pantalla tactil (plan 2.10, movil-a11y-07):
   cerrar de los dialogos, la fecha comprometida (abre el historial) y el
   atajo a la ficha. Acotado a esta pantalla: .tm-cerrar solo dentro de los
   dialogos del Control Tower, para no mover Teams ni Devoluciones. */
@media (pointer: coarse) {
  #ct-hist-modal .tm-cerrar, #ct-modal .tm-cerrar, #ct-op-modal .tm-cerrar,
  #ct-aviso-modal .tm-cerrar, #ct-odoo-modal .tm-cerrar,
  .ct-comp-btn, .ct-abrir {
    display: inline-flex; align-items: center; justify-content: center;
    min-width: var(--tap); min-height: var(--tap);
  }
  /* El enlace Docs de la reja (a la pestaña Documentos): 21 px de alto en
     una tableta tactil. */
  .ct-docs-enlace { display: flex; align-items: center; min-height: var(--tap); }
  /* La regla --tap de app.css pone .tabs button a 44 px, pero el min-height
     de 40 px de .tabs, que va despues, le gana: aqui se asegura. */
  .ct-vistas button { min-height: var(--tap); }
}

/* Vistas en pestañas, Resumen / Operacion (plan 2.1). Usa .tabs tal cual;
   aqui solo se acerca a la tabla. Bajo 640 px la reja cede el lugar a las
   tarjetas (2.9) y las pestañas, que solo cambian columnas de la reja, se
   van con ella. */
.ct-vistas { margin-top: 10px; margin-bottom: 10px; }
@media (max-width: 639.98px) { .ct-vistas { display: none; } }
/* Encabezados agrupados de Operacion: el rotulo del grupo, en el mismo
   tono que los titulos de columna y separado de ellos por una linea. */
/* La linea va arriba de las columnas hijas y no bajo el rotulo: el rotulo
   mide lo que su texto (ver abajo) y la linea debe cruzar todo el grupo. */
.tabulator .tabulator-col:is(.ct-grupo, .ct-grupo-op) > .tabulator-col-group-cols { border-top: 1px solid var(--line); }
.tabulator .tabulator-col.ct-grupo > .tabulator-col-content .tabulator-col-title { color: var(--text-2); }
/* Rotulo de grupo pegajoso: al desplazar la reja a la derecha, el rotulo
   ("Retraso") se quedaba en el borde izquierdo de su grupo, debajo de las
   columnas fijas, y se leia "SO". Ahora se pega al borde derecho de lo fijo
   (--ct-fijo, lo mide fijaAnclaGrupos() de la pagina) mientras su grupo
   este a la vista; sticky no lo deja salir de su grupo. Mide lo que su
   texto para poder deslizarse dentro de el. El grupo deja de recortar
   (overflow visible): con el `hidden` de Tabulator el grupo mismo era el
   contenedor de desplazamiento del sticky y el rotulo se corria 246 px
   dentro de su propio grupo; asi se mide contra el encabezado, que es lo
   que se desplaza. El rotulo no se sale: max-width 100%. */
.tabulator .tabulator-header .tabulator-col:is(.ct-grupo, .ct-grupo-op):not(.tabulator-frozen) { overflow: visible; }
.tabulator .tabulator-header .tabulator-col:is(.ct-grupo, .ct-grupo-op):not(.tabulator-frozen) > .tabulator-col-content {
  position: sticky; left: var(--ct-fijo, 0px);
  width: max-content; max-width: 100%;
}
/* Encabezados de la vista Operacion con los colores del Excel "Machote
   Pagina" (columnasDe(): ct-h + ct-h-<color>). Texto blanco en negritas,
   con el titulo tal cual (sin mayusculas forzadas) y en dos renglones si no
   cabe, como en el Excel. El mismo fondo en los dos temas: los cuatro dan
   mas de 4.5:1 con blanco. Tabulator pone el cssClass tambien en las
   celdas; aqui solo se pinta el encabezado. Las reglas de app.css que
   cambian fondo y color al ordenar o pasar el mouse (y la de fijas) se
   igualan en especificidad y esta hoja carga despues. */
.ct-h-azul  { --ct-h-bg: #0070c0; }
.ct-h-azul2 { --ct-h-bg: #156082; }
.ct-h-gris  { --ct-h-bg: #595959; }
.ct-h-verde { --ct-h-bg: #13501b; }
.tabulator .tabulator-header .tabulator-col.ct-h,
.tabulator .tabulator-header .tabulator-col.ct-h.tabulator-frozen { background: var(--ct-h-bg); }
.tabulator .tabulator-header .tabulator-col.ct-h.tabulator-sortable:hover {
  background: color-mix(in srgb, var(--ct-h-bg) 82%, #000);
}
.tabulator .tabulator-header .tabulator-col.ct-h .tabulator-col-content .tabulator-col-title,
.tabulator .tabulator-header .tabulator-col.ct-h.tabulator-sortable[aria-sort] .tabulator-col-content .tabulator-col-title {
  color: #fff; font-weight: 700; text-transform: none; letter-spacing: 0;
  font-size: 11px; line-height: 1.25; white-space: normal; overflow-wrap: normal;
}
.tabulator .tabulator-header .tabulator-col.ct-h .tabulator-col-sorter .tabulator-arrow {
  border-bottom-color: rgba(255, 255, 255, .55) !important;
}
.tabulator .tabulator-header .tabulator-col.ct-h[aria-sort="ascending"] .tabulator-arrow,
.tabulator .tabulator-header .tabulator-col.ct-h[aria-sort="descending"] .tabulator-arrow {
  border-bottom-color: #fff !important; border-top-color: #fff !important;
}
.tabulator .tabulator-header .tabulator-col.ct-h:focus-visible { outline: 2px solid #fff; outline-offset: -3px; }
/* "Dias aduana" con el formato condicional del Excel (mas de 14 rojo, 11 a
   14 amarillo, menos de 10 verde). La celda lleva .ct-xl-<nivel> y el
   numero el semaforo con forma (.ct-sem). En oscuro, los tintes y tintas de
   siempre; en claro, el relleno y el texto exactos del Excel. */
.tabulator .tabulator-row .tabulator-cell.ct-xl-rojo     { background: var(--danger-bg); }
.tabulator .tabulator-row .tabulator-cell.ct-xl-amarillo { background: var(--warn-bg); }
.tabulator .tabulator-row .tabulator-cell.ct-xl-verde    { background: color-mix(in srgb, var(--ok) 14%, transparent); }
:root[data-tema="claro"] .tabulator .tabulator-row .tabulator-cell.ct-xl-rojo     { background: #ffc7ce; }
:root[data-tema="claro"] .tabulator .tabulator-row .tabulator-cell.ct-xl-amarillo { background: #ffeb9c; }
:root[data-tema="claro"] .tabulator .tabulator-row .tabulator-cell.ct-xl-verde    { background: #c6efce; }
:root[data-tema="claro"] .ct-xl-rojo .ct-sem     { color: #9c0006; }
:root[data-tema="claro"] .ct-xl-amarillo .ct-sem { color: #9c5700; }
:root[data-tema="claro"] .ct-xl-verde .ct-sem    { color: #006100; }

/* Paso para Comercial (PASOS_COMERCIAL): 4 tramos + el nombre del paso.
   El color nunca va solo: el texto dice el paso y el lector "paso n de 4". */
.ct-paso { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.ct-paso-barra { display: flex; gap: 3px; }
.ct-paso-barra > span { flex: 1; height: 6px; border-radius: 3px; background: var(--line-hard); }
.ct-paso-barra > .ct-paso-hecho { background: var(--brand); opacity: .55; }
.ct-paso-barra > .ct-paso-actual { background: var(--brand); }
.ct-paso-txt { font-size: 12px; line-height: 1.3; color: var(--text-2); white-space: normal; overflow-wrap: anywhere; }
/* Encabezado de una linea (plan 0.7 opcion b / 1.1; la decision esta
   anotada junto a .tm-barra): titulo, conteo "N embarques · M marcas",
   "Solo consulta" y las acciones a la derecha. El h1 no hereda el tamaño
   de `.content > h1` (no es hijo directo): aqui es un rotulo de pantalla,
   no una portada.
   Plan 1.4: la barra de filtros (.ct-barra) entra a este mismo bloque, una
   reja de DOS renglones a cualquier ancho:
     >= 640 px  titulo + conteo | aviso de guardado | acciones (Nuevo, Excel, PDF)
                filtros, a todo lo ancho
     <  640 px  titulo + conteo
                Filtros (n)     | Nuevo, Exportar      (+ aviso si lo hay)
   Bajo 640 px "Filtros" y "Exportar" son <details> cuyo panel se abre
   ENCIMA de la tabla (posicion absoluta contra .ct-head), asi el encabezado
   no crece al abrirlos. Arriba de 640 px el script de la pagina los deja
   abiertos y aqui se esconde su <summary>: se ven como barra normal.
   Sustituye a los overrides de .tm-barra que achicaban los select (12.5 px,
   4 px de relleno) y a los rotulos sueltos .ctrl-label: ahora son los
   controles estandar .field-periodo/.field-tag/.select-ctrl. */
.ct-head {
  position: relative; display: grid; align-items: center; gap: 10px 16px;
  grid-template-columns: auto minmax(0, 1fr) auto;
  grid-template-areas: "tit est acc" "filt filt filt";
  margin: 0 0 14px; padding-bottom: 12px; border-bottom: 1px solid var(--line);
}
.ct-tit-grupo { grid-area: tit; display: flex; align-items: center; flex-wrap: wrap; gap: 8px 12px; min-width: 0; }
.ct-tit {
  font-family: var(--font-display); font-weight: 600; margin: 0; color: var(--text);
  font-size: clamp(22px, 2.4vw, 28px); line-height: 1.1; letter-spacing: -.03em;
}
.ct-head .ct-acciones { grid-area: acc; justify-self: end; align-items: center; }
.ct-head .ct-filtros { grid-area: filt; min-width: 0; }
.ct-head #ct-estado { grid-area: est; justify-self: end; margin: 0; text-align: right; }
#ct-estado:empty { display: none; }
.ct-solo { display: inline-flex; align-items: center; gap: 4px; }
.ct-solo .ico { width: 12px; height: 12px; }
/* Ayuda segun el puntero (plan 2.6): la reja edita con UN clic o UN toque,
   y la pista lo dice con el verbo del dispositivo. display:none, no
   solo-lector: el lector oye solo la que aplica. */
.ct-si-tacto { display: none; }
@media (pointer: coarse) {
  .ct-si-tacto { display: inline; }
  .ct-si-raton { display: none; }
}

/* Plegables (Filtros, Exportar): el <summary> es un .btn sin triangulito. */
.ct-plegable > summary { list-style: none; cursor: pointer; }
.ct-plegable > summary::-webkit-details-marker { display: none; }
.ct-filtros-n { font-variant-numeric: tabular-nums; }
.ct-exportar-panel { display: flex; gap: 8px; }

/* La barra: controles estandar, a la altura de .btn-sm (como
   `.ctrl-group > select` de app.css). El padding de arriba deja aire a la
   etiqueta flotante (.field-tag) cuando la fila envuelve. */
.ct-barra { display: flex; flex-wrap: wrap; align-items: center; gap: 14px 10px; padding-top: 7px; }
/* Tope de ancho: un select nativo mide lo que su opcion mas larga
   ("Entregado sin fecha de llegada") y empujaba Cerrados a otro renglon. */
.ct-barra .select-ctrl { padding: 8px 32px 8px 11px; background-position: right 11px center; max-width: 210px; }
.ct-barra .field-periodo { margin-top: 0; max-width: 100%; }
.ct-q-campo { flex: 1 1 220px; max-width: 340px; }
.ct-barra .ct-q {
  width: 100%; margin: 0; padding: 8px 11px;
  background: var(--surface); border-radius: 7px;
}
.ct-cerrados {
  display: inline-flex; align-items: center; gap: 6px; cursor: pointer;
  font-size: var(--fs-sm); color: var(--text-2);
}
@media (pointer: coarse) {
  .ct-cerrados { min-height: var(--tap); padding: 0 4px; }
  .ct-cerrados input { width: 20px; height: 20px; }
}
@media (min-width: 640px) {
  .ct-plegable > summary { display: none; }
}
@media (max-width: 639.98px) {
  .ct-head {
    gap: 8px; grid-template-columns: auto minmax(0, 1fr) auto;
    grid-template-areas: "tit tit tit" "filt . acc" "est est est";
  }
  .ct-head .ct-acciones { flex-wrap: nowrap; }
  /* "Nuevo" a la vista; "embarque" sigue para el lector. */
  .ct-head .ct-largo {
    position: absolute; width: 1px; height: 1px; overflow: hidden;
    clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
  }
  .ct-head #ct-estado { justify-self: start; text-align: left; }
  /* La pista de edicion se calla en telefono: seria un renglon mas del
     encabezado (criterio de 1.1). La de tacto sigue en tableta. */
  #ct-estado:has(> .ct-pista) { display: none; }
  .ct-plegable[open] > summary { background: var(--surface-2); border-color: var(--platinum-lo); }
  .ct-plegable-panel {
    position: absolute; z-index: 30; top: calc(100% + 4px); left: 0; right: 0;
    padding: 18px 14px 14px; background: var(--surface);
    border: 1px solid var(--line); border-radius: var(--r-md); box-shadow: var(--shadow);
  }
  .ct-plegable-panel .field-tag { background: var(--surface); }
  .ct-barra { flex-direction: column; align-items: stretch; gap: 18px; }
  .ct-barra .field-periodo, .ct-barra .select-ctrl, .ct-q-campo { width: 100%; max-width: none; }
  /* En columna, el flex-basis de 220px del buscador seria su ALTO. */
  .ct-q-campo { flex: none; }
  .ct-barra #ct-limpiar { align-self: flex-start; }
  .ct-exportar-panel { left: auto; flex-direction: column; padding: 8px; }
}

/* Tabla vacia con contexto (plan 1.6): el placeholder de Tabulator es un
   elemento propio (.ct-vacio) con el porque y, si hay filtros, "Limpiar".
   --text-2 y no el --text-3 del placeholder de app.css: es un mensaje que
   hay que leer, no un adorno. */
.ct-vacio { padding: 22px 16px; text-align: center; color: var(--text-2); font-size: var(--fs-sm); }
.ct-vacio p { margin: 0 0 10px; }
.ct-vacio p:last-child { margin-bottom: 0; }

/* Leyenda de los objetivos del semaforo, al pie de la reja. */
.ct-leyenda { margin-top: 14px; }
/* Reserva al pie tras cerrar un embarque (conservaScroll() de la pagina):
   el alto del renglon que salio, para que el scroll no brinque. */
.ct-leyenda { padding-bottom: var(--ct-reserva, 0px); }

/* Franja "Requiere atencion" (plan 1.2) sobre los KPI: chips-enlace con
   color + icono + texto. Bajo 640 px es UNA tira que se desliza de lado
   (no 4 renglones de chips antes de ver la tabla). */
.ct-alertas { display: flex; align-items: center; gap: 8px 12px; flex-wrap: wrap; margin: 0 0 12px; }
.ct-alertas-tit {
  display: inline-flex; align-items: center; gap: 6px; margin: 0;
  font-size: var(--fs-sm, 13px); font-weight: 600; color: var(--text-2);
}
.ct-alertas-tit .ico { width: 14px; height: 14px; color: var(--warn); }
.ct-alertas-tit:focus { outline: none; }
.ct-alertas-tit:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
.ct-alertas-lista { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; min-height: 28px; }
.ct-alertas-lista > p { margin: 0; }
.ct-alertas-lista .muted { display: inline-flex; align-items: center; gap: 6px; font-size: var(--fs-sm, 13px); }
.ct-alertas-lista .muted .ico { width: 14px; height: 14px; }
.ct-alerta {
  display: inline-flex; align-items: center; gap: 5px; min-height: 28px;
  text-decoration: none; white-space: nowrap; cursor: pointer;
}
.ct-alerta:hover { text-decoration: underline; text-underline-offset: 2px; }
.ct-alerta .ico { width: 12px; height: 12px; flex: none; }
.ct-alerta-n { font-variant-numeric: tabular-nums; }
.ct-alerta-ej { font-weight: 400; opacity: .8; }
.ct-alerta[aria-current="true"] { box-shadow: 0 0 0 2px var(--brand); }
.ct-skel-chip {
  display: inline-block; width: 110px; height: 24px; border-radius: 999px;
  background: linear-gradient(90deg, var(--surface), var(--surface-3), var(--surface));
  background-size: 200% 100%; animation: shimmer 1.3s linear infinite;
}
@media (prefers-reduced-motion: reduce) { .ct-skel-chip { animation: none; } }
@media (max-width: 639.98px) {
  .ct-alertas { flex-wrap: nowrap; }
  .ct-alertas-tit { flex: none; }
  .ct-alertas-lista {
    flex-wrap: nowrap; overflow-x: auto; min-width: 0; flex: 1;
    scrollbar-width: thin; padding-bottom: 2px;
  }
  .ct-alertas-lista > p { white-space: nowrap; }
}
@media (pointer: coarse) { .ct-alerta, .ct-filtro-chip { min-height: 44px; } }

/* "Filtro: Vencidos ×" (plan 1.5) */
.ct-filtro-activo { margin: 0 0 10px; }
.ct-filtro-activo[hidden] { display: none; }
.ct-filtro-chip {
  display: inline-flex; align-items: center; gap: 6px; cursor: pointer;
  font: inherit; font-size: var(--fs-sm, 13px); border-color: var(--brand);
}
.ct-filtro-chip .ico { width: 12px; height: 12px; }

/* KPI clicables (plan 1.5): una tarjeta-boton se ve igual que la tarjeta y
   se nota pulsada con el filo de marca. Vencidos en --danger-ink y En riesgo
   en --warn, siempre con su icono (nunca solo color). */
#ct-kpis { margin-bottom: 6px; }
#ct-kpis .kpi-label .ico { width: 13px; height: 13px; flex: none; }
#ct-kpis .kpi-value, #ct-kpis .kpi-sub { display: block; }
button.ct-kpi {
  font: inherit; color: inherit; text-align: left; width: 100%; cursor: pointer;
  display: block;
}
button.ct-kpi:hover { border-color: var(--line-hard); }
button.ct-kpi[aria-pressed="true"] {
  border-color: var(--brand); box-shadow: inset 0 0 0 1px var(--brand);
}
.ct-kpi--rojo .kpi-value, .ct-kpi--rojo .kpi-label { color: var(--danger-ink); }
.ct-kpi--warn .kpi-value, .ct-kpi--warn .kpi-label { color: var(--warn); }
.ct-kpi-skel {
  grid-column: 1 / -1; margin: 0;
  grid-template-columns: repeat(auto-fill, minmax(212px, 1fr));
}
.ct-kpi-skel .skel-row { height: 104px; }
/* En el telefono, dos tarjetas por renglon: una por renglon eran seis
   pantallas de KPI antes de llegar a la tabla. */
@media (max-width: 639.98px) {
  #ct-kpis, .ct-kpi-skel { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
  #ct-kpis .kpi-card { padding: 12px; }
  #ct-kpis .kpi-sub { font-size: 10px; margin-top: 6px; padding-top: 6px; }
  .ct-kpi-skel .skel-row { height: 96px; }
}
@media (prefers-reduced-motion: reduce) { .ct-kpi-skel .skel-row { animation: none; } }
/* El aviso de la barra ("Guardando…", "Guardado.") cuando el servidor
   rechaza el valor. */
#ct-estado.ct-estado--error,
#ct-comp-msg.ct-estado--error { color: var(--danger-ink); }

/* Badge de retraso dentro de la reja: sutil, no un grito rojo. */
.ct-retraso {
  font-family: var(--font-mono); font-size: 10.5px; letter-spacing: .04em;
  padding: 2px 7px; border-radius: 100px; white-space: nowrap;
  color: var(--warn);
  background: var(--warn-bg);
}

/* Odoo vs CEDIS (plan 5.1): los dias de diferencia junto a la fecha de
   Odoo. Neutro si esta dentro del umbral; con icono y fondo de alerta si no
   (nunca solo color: el icono y el texto del lector van en el HTML). */
.ct-odoo {
  font-family: var(--font-mono); font-size: 10.5px; white-space: nowrap;
  font-variant-numeric: tabular-nums; color: var(--brand-lo);
}
.ct-odoo--alerta {
  display: inline-flex; align-items: center; gap: 3px;
  padding: 2px 7px; border-radius: 100px;
  color: var(--danger-ink); background: var(--danger-bg); font-weight: 600;
}
.ct-odoo--alerta svg { width: 12px; height: 12px; flex: none; }

/* Grupo plegable "Operación" (plan 2.7): el titulo del grupo es un boton
   con aria-expanded; "+4" dice cuantas columnas mas despliega. */
.ct-grupo-btn {
  display: inline-flex; align-items: center; gap: 6px;
  background: none; border: 0; padding: 2px 4px; margin: -2px -4px;
  color: inherit; font: inherit; cursor: pointer; border-radius: 6px;
  /* Un <button> no hereda text-transform ni letter-spacing (el navegador
     le pone `none`): se leia "Operación" junto a "DOCUMENTOS". Hereda los
     del rotulo de columna (app.css) como los demas grupos. */
  text-transform: inherit; letter-spacing: inherit;
}
.ct-grupo-btn:hover { color: var(--brand); }
.ct-grupo-btn:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
/* En el telefono es el UNICO control que enseña Nota de retraso, BL,
   Forwarder y Notas: blanco de toque completo. */
@media (pointer: coarse) {
  .ct-grupo-btn { min-height: var(--tap); padding-inline: 8px; margin: 0; }
}
.ct-grupo-n {
  font-family: var(--font-mono); font-size: var(--fs-xs, 11px);
  padding: 0 6px; border-radius: 100px; background: var(--surface-3); color: var(--text-2);
}
/* Texto largo en una celda (BL, forwarder, notas): una linea con "…", el
   completo en el title. */
.ct-txt { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Columnas de la ficha en solo lectura (D3): atenuadas, sin pista de edicion. */
.tabulator .tabulator-cell.ct-col-ficha { color: var(--text-2); }
/* Folio en mono, como en la tarjeta de movil: los folios ("IMP-2026-046")
   se comparan caracter por caracter y asi la columna de 132 px da ~14. Solo
   la celda: el encabezado sigue como los demas. */
.tabulator .tabulator-cell.ct-col-folio {
  font-family: var(--font-mono); font-size: 12.5px; font-variant-numeric: tabular-nums;
}

/* Menu por fila ⋯ (plan 2.7). El boton de la celda y UN menu flotante para
   toda la tabla (position: fixed, lo coloca el script junto al boton). */
.ct-fila-menu {
  display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 28px; padding: 0; border: 0; border-radius: 6px;
  background: none; color: var(--text-2); font: inherit; font-size: 18px; line-height: 1;
  cursor: pointer;
}
.ct-fila-menu:hover, .ct-fila-menu[aria-expanded="true"] { background: var(--surface-2); color: var(--text); }
.ct-fila-menu:focus-visible { outline: 2px solid var(--brand); outline-offset: 1px; }
@media (pointer: coarse) {
  .ct-fila-menu { width: var(--tap); height: var(--tap); }
}
.ct-menu {
  position: fixed; z-index: 60; min-width: 220px; padding: 6px;
  top: var(--ct-menu-y, 0); left: var(--ct-menu-x, 0);
  display: flex; flex-direction: column;
  background: var(--paper); border: 1px solid var(--line-hard); border-radius: 10px;
  box-shadow: var(--shadow);
}
.ct-menu[hidden] { display: none; }
.ct-menu-item {
  display: block; width: 100%; text-align: left;
  padding: 9px 12px; border: 0; border-radius: 6px; background: none;
  color: var(--text); font: inherit; font-size: var(--fs-sm, 13px);
  text-decoration: none; cursor: pointer;
}
.ct-menu-item:hover, .ct-menu-item:focus { background: var(--surface-2); outline: none; }
.ct-menu-item:focus-visible { box-shadow: inset 0 0 0 2px var(--brand); }
.ct-menu-item--peligro { color: var(--danger-ink); }
@media (pointer: coarse) {
  .ct-menu-item { min-height: var(--tap); }
}

/* Movil del Control Tower (plan 2.9).
   < 640 px: la reja (.ct-tabla) no se ve y la lista es de tarjetas
   (.ct-tarjetas, pintaTarjetas()). 640-900 px: la reja con responsiveLayout
   "collapse" y el desglose .ct-colapso. Selectores con la clase propia de
   esta reja, nada global sobre .tabulator. */
.ct-tarjetas { display: none; }
@media (max-width: 639.98px) {
  div.ct-tabla.tabulator { display: none; }
  .ct-tarjetas { display: block; }
  /* La leyenda habla de las columnas de dias, que en la tarjeta no estan. */
  .ct-leyenda { display: none; }
}
.ct-tarjetas-lista { list-style: none; margin: 0; padding: 0; }
.ct-tarjeta { display: flex; flex-direction: column; gap: 10px; min-width: 0; }
.ct-tarjeta-top { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 6px 10px; }
/* El folio siempre completo: parte la linea antes que recortarse. */
.ct-tarjeta-folio { margin: 0; font-size: var(--fs-md); font-weight: 600; overflow-wrap: anywhere; min-width: 0; }
.ct-tarjeta-marca { margin: -6px 0 0; color: var(--text-2); font-size: var(--fs-sm); }
.ct-tarjeta-datos {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px 14px; margin: 0;
}
.ct-tarjeta-datos > div { min-width: 0; }
.ct-tarjeta-datos .ct-tarjeta-estatus { grid-column: 1 / -1; }
/* Rotulos de 12px (no --fs-xs): se leen en telefono. */
.ct-tarjeta-datos dt { margin: 0 0 3px; font-size: 12px; color: var(--text-2); }
.ct-tarjeta-datos dd { margin: 0; font-size: var(--fs-sm); }
.ct-tarjeta-datos .chip { max-width: 100%; white-space: normal; }
.ct-tarjeta-pie { display: flex; align-items: center; justify-content: flex-end; gap: 8px; }
.ct-tarjeta-pie .btn { min-height: var(--tap); }
.ct-tarjeta-pie .btn .ico { width: 16px; height: 16px; }
.ct-tarjeta .ct-fila-menu { width: var(--tap); height: var(--tap); }
.ct-tarjetas-mas { width: 100%; min-height: var(--tap); justify-content: center; }
.ct-tarjetas .ct-vacio { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg); }

/* 640-900 px: boton del desglose (primera columna) y el desglose mismo. */
.ct-colapso-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 32px; padding: 0; border: 1px solid var(--line-hard); border-radius: 50%;
  background: none; color: var(--text-2); cursor: pointer;
}
@media (pointer: coarse) { .ct-colapso-btn { width: var(--tap); height: var(--tap); } }
.ct-colapso-btn span::before { content: "+"; content: "+" / ""; font-size: 16px; line-height: 1; }
.ct-colapso-btn[aria-expanded="true"] span::before { content: "−"; content: "−" / ""; }
.ct-colapso-btn:hover { background: var(--surface-2); color: var(--text); }
.ct-colapso-btn:focus-visible { outline: 2px solid var(--brand); outline-offset: 1px; }
/* Sin nada colapsado (la reja cupo entera) el boton no tiene que abrir. */
.ct-tabla .tabulator-row:has(> .tabulator-responsive-collapse:empty) .ct-colapso-btn { visibility: hidden; }
.ct-tabla .tabulator-cell.ct-col-colapso { padding-left: 0; padding-right: 0; text-overflow: clip; }
/* Ficha y Acciones con su objetivo de 44 px en tactil: sin el relleno de la
   celda, para que Tabulator no les pegue "…" al lado. */
@media (pointer: coarse) {
  .ct-tabla .tabulator-row .tabulator-cell[tabulator-field="id"],
  .ct-tabla .tabulator-row .tabulator-cell[tabulator-field="_menu"] { padding-left: 0; padding-right: 0; text-overflow: clip; }
}
/* El desglose trae bordes #999 de Tabulator: aqui, con tokens. */
.ct-tabla .tabulator-row .tabulator-responsive-collapse {
  padding: 6px 12px 10px 52px; border-top: 1px solid var(--line); border-bottom: 0;
}
/* Cerrado hasta que su boton (.ct-colapso-btn) le pone la clase. */
.ct-tabla .tabulator-row .tabulator-responsive-collapse:not(.ct-colapso-abierto) { display: none; }
.ct-colapso {
  display: grid; grid-template-columns: max-content minmax(0, 1fr); gap: 6px 14px; margin: 0;
  font-size: var(--fs-sm);
}
.ct-colapso dt { color: var(--text-2); }
.ct-colapso dd { margin: 0; min-width: 0; overflow-wrap: anywhere; }
.ct-colapso .ico { width: 14px; height: 14px; vertical-align: -2px; color: var(--ok); }
/* En el desglose la barrita de Docs mide lo de su celda, no todo el dd. */
.ct-colapso .ct-docs { display: inline-flex; width: 140px; max-width: 100%; }
.ct-colapso .ct-paso { width: 160px; max-width: 100%; }

/* ============================================================
   Usuarios del portal (/usuarios)

   Dos bloques: el formulario de alta (una rejilla que se apila sola en
   celular) y el aviso de entrega, que es la UNICA vez que una contrasena
   en claro aparece en pantalla — por eso se ve distinto a todo lo demas:
   quien la ve tiene que darse cuenta de que hay que copiarla ahora.
   ============================================================ */
.usr-alta {
  display: grid; gap: 12px 16px; align-items: end; margin-bottom: 8px;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
}
.usr-alta label { display: flex; flex-direction: column; gap: 5px; font-size: 13px; }
/* El campo de ejecutivo solo aparece con perfil=cobranza, y lo esconde el
   atributo `hidden`. Sin esta linea no se esconderia: `.usr-alta label` le
   gana en especificidad a la regla [hidden] del navegador. */
.usr-alta label[hidden] { display: none; }
.usr-alta .btn { justify-self: start; }
/* La ayuda del perfil ocupa su propio renglon completo, debajo de todo. */
.usr-ayuda { grid-column: 1 / -1; margin: 0; min-height: 1.2em; }

.usr-acciones { display: flex; gap: 6px; flex-wrap: wrap; }
.usr-acciones form { margin: 0; }
.usr-nota { max-width: 74ch; margin-top: 18px; }
/* Una cuenta dada de baja sigue en la lista (para reactivarla) pero no
   compite visualmente con las que si pueden entrar. */
.fila-baja { opacity: .55; }

.ent-caja { border-color: var(--ok); margin: 14px 0 4px; }
.ent-tit { display: flex; align-items: center; gap: 6px; margin: 0 0 10px; font-weight: 600; }
.ent-tit .ico { width: 15px; height: 15px; color: var(--ok); }
.ent-datos { display: flex; flex-wrap: wrap; gap: 10px 28px; margin-bottom: 8px; }
.ent-datos div { display: flex; flex-direction: column; gap: 2px; }
.ent-datos span { font-size: 11.5px; letter-spacing: .04em; text-transform: uppercase; }
.ent-datos b { font-size: 17px; }

/* ============================================================
   Landing pública de reclutamiento (/promotoria/reclutamiento/unete)
   Sin nav: la pagina es su propio marco. Mobile-first: el link llega por
   WhatsApp y se abre en un celular de 390 px. Solo tokens, para que el
   tema claro se vea igual de bien.
   ============================================================ */
.un { flex: 1; min-width: 0; max-width: 760px; width: 100%; margin: 0 auto; padding: 28px var(--gutter) 40px; }
.un-hero { padding: 24px 0 32px; border-bottom: 1px solid var(--line); animation: fade-up .6s both; }
.un-marca { display: block; width: 36px; height: 36px; color: var(--platinum); margin: 0 0 18px; }
.un-eyebrow {
  font-family: var(--font-mono); font-size: 10px; letter-spacing: .28em;
  text-transform: uppercase; color: var(--platinum-lo); margin: 0 0 10px;
}
.un-hero h1 {
  font-family: var(--font-display); font-weight: 600; letter-spacing: -.03em;
  font-size: clamp(28px, 6vw, 44px); line-height: 1.08; margin: 0 0 14px; color: var(--text);
}
.un-lead { font-size: 15.5px; line-height: 1.55; color: var(--text-2); margin: 0 0 22px; max-width: 54ch; }
.un-cta { min-height: 44px; }
.un-seccion { padding: 30px 0 6px; }
.un-h2 {
  font-family: var(--font-display); font-weight: 600; letter-spacing: -.02em;
  font-size: clamp(20px, 3.4vw, 26px); margin: 0 0 16px; color: var(--text);
}
.un-nota { margin: -8px 0 14px; font-size: 13.5px; }

/* tarjetas "que hacemos": una columna en celular, tres en escritorio */
.un-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 10px; }
.un-card { margin: 0; padding: 16px; }
.un-card-ico { display: inline-flex; color: var(--platinum); margin-bottom: 10px; }
.un-card-ico .ico { width: 22px; height: 22px; }
.un-card h3 { font-size: 15px; font-weight: 600; margin: 0 0 6px; color: var(--text); }
.un-card p { margin: 0; font-size: 13.5px; line-height: 1.5; }

/* chips de cadenas */
.un-chips { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 8px; }
.un-chip {
  display: inline-flex; align-items: center; gap: 5px; padding: 7px 12px;
  border: 1px solid var(--line); border-radius: 999px; background: var(--surface);
  font-size: 13px; color: var(--text); white-space: nowrap;
}
.un-chip .ico { width: 14px; height: 14px; color: var(--text-3); }

/* pasos numerados */
.un-pasos { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }
.un-paso { display: flex; gap: 14px; align-items: flex-start; margin: 0; padding: 16px; }
.un-paso strong { display: block; font-size: 15px; margin-bottom: 4px; color: var(--text); }
.un-paso p { margin: 0; font-size: 13.5px; line-height: 1.5; }
.un-paso-num {
  flex: 0 0 auto; width: 30px; height: 30px; display: grid; place-items: center;
  font-family: var(--font-mono); font-size: 13px; font-weight: 600;
  color: var(--void); background: var(--platinum); border-radius: 50%;
}

/* formulario: hereda .ph-card/.pv-form; aqui solo lo que cambia en publico */
.un-form { padding: 18px 16px; scroll-margin-top: 16px; }
.un-form .pr-in { min-height: 44px; font-size: 16px; }  /* 16px: iOS no hace zoom al enfocar */
.un-privacidad { display: flex; gap: 6px; align-items: flex-start; font-size: 12.5px; margin: 6px 0 0; }
.un-privacidad .ico { flex: 0 0 auto; margin-top: 2px; }
.un-enviar { min-height: 44px; }
@media (max-width: 639.98px) {
  .un-form .btn { justify-self: stretch; justify-content: center; }
  .un-cta { width: 100%; justify-content: center; }
}

/* confirmacion */
.un-listo { display: flex; gap: 14px; align-items: flex-start; padding: 20px 18px; border-color: var(--ok); }
.un-listo-ico { flex: 0 0 auto; display: grid; place-items: center; width: 36px; height: 36px; border-radius: 50%; color: var(--ok); background: color-mix(in srgb, var(--ok) 14%, transparent); }
.un-listo-titulo { font-size: 17px; font-weight: 600; margin: 0 0 4px; color: var(--text); }
.un-listo p { margin: 0; }

/* pie */
.un-pie {
  display: flex; justify-content: space-between; align-items: center; gap: 12px; flex-wrap: wrap;
  margin-top: 40px; padding-top: 18px; border-top: 1px solid var(--line);
  font-family: var(--font-mono); font-size: 10.5px; letter-spacing: .08em; text-transform: uppercase;
  color: var(--text-3);
}
.un-pie a { color: var(--text-3); text-decoration: none; }
.un-pie a:hover { color: var(--text); }

/* Aviso de datos de ejemplo del Control Tower. Deliberadamente distinto al
   resto de la pagina: tiene que interrumpir la lectura, porque confundir un
   embarque inventado con uno real es comprometerle una fecha a un cliente. */
.ct-demo {
  border: 1px solid var(--warn); border-left-width: 4px; border-radius: var(--r-lg);
  background: var(--warn-bg); padding: 12px 16px; margin: 0 0 14px;
  display: flex; flex-direction: column; gap: 6px; max-width: 92ch;
}
.ct-demo p { margin: 0; font-size: 13.5px; line-height: 1.5; }
/* El texto va dentro de un <span>: si no, cada trozo (la negrita, la coma)
   se vuelve una pieza del flex y le salen huecos de 7px alrededor. */
.ct-demo-tit { display: flex; align-items: baseline; gap: 7px; font-weight: 600; font-size: 14.5px; }
.ct-demo-tit span { font-weight: 600; }
.ct-demo-tit .ico { width: 16px; height: 16px; color: var(--warn); flex: none; }
.ct-demo form { margin: 4px 0 0; }
/* La invitacion a cargarlos no es una advertencia: no grita. */
.ct-demo-vacio { border-color: var(--line); border-left-color: var(--platinum); background: var(--surface); }
.ct-demo-vacio .ct-demo-tit .ico { color: var(--text-3); }

/* Alta de embarque desde la propia sabana. */
.ct-nuevo {
  display: flex; flex-wrap: wrap; align-items: end; gap: 10px 16px;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-lg); padding: 12px 16px; margin: 0 0 14px;
}
.ct-nuevo label { display: flex; flex-direction: column; gap: 5px; font-size: 13px; }
.ct-nuevo .ct-nuevo-ayuda { flex-basis: 100%; margin: 0; }
/* El renglon recien creado: se le va el color solo, sin dejar nada pegado. */
.ct-fila-nueva { animation: ct-destello 2.4s ease-out 1; }
@keyframes ct-destello {
  0%, 55% { background: var(--warn-bg); }
  100%    { background: transparent; }
}
/* Sin animaciones (app.css las apaga todas): una marca fija a la izquierda
   para que el renglon recien dado de alta se siga encontrando. */
@media (prefers-reduced-motion: reduce) {
  .ct-fila-nueva { box-shadow: inset 3px 0 0 var(--warn); }
}
/* Alta sin recargar (plan 2.8): el rechazo del servidor dentro del modal,
   con texto (no solo color), y el enlace a la ficha en la barra. */
.ct-nuevo-error { margin: 0; background: var(--danger-bg); color: var(--text);
  border: 1px solid color-mix(in srgb, var(--danger) 45%, transparent); }
.ct-nuevo-error[hidden] { display: none; }
.ct-nuevo input[aria-invalid="true"] { border-color: var(--danger-ink); }
/* "Marca (opcional)": rotulo y aclaracion en un renglon; el "(opcional)"
   no se parte a la mitad. */
.ct-rotulo .muted { white-space: nowrap; }
.ct-alta-ficha { font-weight: 600; }
@media (pointer: coarse) {
  .ct-alta-ficha { display: inline-flex; align-items: center; min-height: var(--tap); }
}

/* ============================================================
   Ventas: seguimiento de clientes (/ventas)

   La barra no es adorno: el cliente pidio explicitamente poder decir "este
   va en 30, este en 80" de un vistazo, sin leer numeros. Por eso la barra
   manda y el porcentaje va al lado, no al reves.
   ============================================================ */
.ven-barra { display: inline-flex; align-items: center; gap: 9px; min-width: 150px; }
.ven-barra-fondo {
  flex: 1; height: 7px; border-radius: 100px; background: var(--surface-3);
  overflow: hidden; min-width: 72px;
}
.ven-barra-fondo > span { display: block; height: 100%; background: var(--platinum); transition: width .3s; }
.ven-barra b { font-family: var(--font-mono); font-size: 12px; font-variant-numeric: tabular-nums; }
/* El color dice en que banda va, no si esta bien o mal: nadie decide nada
   con esto, es para leer la tabla rapido. */
.ven-bajo     .ven-barra-fondo > span { background: var(--text-3); }
.ven-medio    .ven-barra-fondo > span { background: var(--warn); }
.ven-alto     .ven-barra-fondo > span { background: var(--brand); }
.ven-completo .ven-barra-fondo > span { background: var(--ok); }
.ven-col-barra { min-width: 132px; }
/* Dentro de la tabla la barra se encoge: ahi el dato es el porcentaje que
   va escrito al lado, la barra solo lo hace comparable de un vistazo. */
.lista .ven-barra { min-width: 92px; gap: 6px; }

/* La tabla de clientes cabe en una pantalla (2026-09-21). Antes habia que
   irse de lado para ver el avance, que es lo que se viene a ver: la columna
   congelada tapaba las de en medio al desplazar y el renglon se leia partido.
   Se aprieta lo que no es dato -- separaciones y anchos de mas -- en vez de
   esconder columnas detras de un boton. */
.ven-pasos-chico {
  font-family: var(--font-mono); font-size: 11px; color: var(--text-3);
  margin-left: 7px; font-variant-numeric: tabular-nums;
}
.ven-fecha { font-family: var(--font-mono); font-size: 12.5px; white-space: nowrap; }
.lista.tabla-orden td, .lista.tabla-orden th { padding-left: 10px; padding-right: 10px; }
.ven-td-vend { min-width: 140px; }
.ven-td-vend .ven-asignar { max-width: 150px; }

.ven-tarjetas { display: grid; gap: 12px; grid-template-columns: repeat(auto-fill, minmax(215px, 1fr)); margin-bottom: 6px; }
.ven-tarjeta { display: flex; flex-direction: column; gap: 4px; margin: 0; }
.ven-tarjeta-nom { margin: 0; font-weight: 600; }
.ven-tarjeta .ven-barra { margin-top: 4px; }
.ven-sin { margin: 6px 0 0; font-size: 12.5px; color: var(--text-3); }

.ven-alta {
  display: grid; gap: 12px 16px; align-items: end;
  grid-template-columns: repeat(auto-fit, minmax(175px, 1fr));
}
.ven-alta label { display: flex; flex-direction: column; gap: 5px; font-size: 13px; }
.ven-alta .btn { justify-self: start; }

.ven-resumen { display: flex; align-items: center; gap: 22px; flex-wrap: wrap; margin: 4px 0 8px; }
.ven-resumen-num {
  font-family: var(--font-display); font-size: clamp(38px, 7vw, 56px);
  font-weight: 600; letter-spacing: -.03em; line-height: 1;
}
.ven-resumen-barra { flex: 1; min-width: 220px; }
.ven-resumen-barra .ven-barra { width: 100%; }
.ven-resumen-barra .ven-barra-fondo { height: 10px; }
.ven-bajo.ven-resumen-num     { color: var(--text-3); }
.ven-medio.ven-resumen-num    { color: var(--warn); }
.ven-alto.ven-resumen-num     { color: var(--brand); }
.ven-completo.ven-resumen-num { color: var(--ok); }

/* El checklist. Casilla grande: se pica desde el celular, en la calle. */
.ven-pasos { list-style: none; margin: 10px 0 0; padding: 0; display: flex; flex-direction: column; gap: 2px; }
.ven-paso {
  display: flex; align-items: center; gap: 13px; padding: 11px 13px;
  border: 1px solid var(--line); border-radius: var(--r-lg); background: var(--surface);
}
.ven-paso + .ven-paso { margin-top: 4px; }
.ven-paso form { margin: 0; }
.ven-check {
  width: 30px; height: 30px; border-radius: 8px; border: 1.5px solid var(--line);
  background: var(--surface-2); cursor: pointer; display: grid; place-items: center;
  color: var(--on-brand); padding: 0; flex: none;
}
.ven-check:hover { border-color: var(--platinum); }
.ven-check .ico { width: 17px; height: 17px; }
.ven-paso.hecho .ven-check { background: var(--ok); border-color: var(--ok); }
.ven-paso.hecho .ven-paso-nom { color: var(--text-2); }
.ven-paso-txt { flex: 1; min-width: 0; }
.ven-paso-nom { margin: 0; font-size: 14px; display: flex; align-items: baseline; gap: 8px; }
.ven-paso-num {
  font-family: var(--font-mono); font-size: 11px; color: var(--text-3);
  border: 1px solid var(--line); border-radius: 5px; padding: 1px 6px; flex: none;
}
.ven-paso-pct { font-family: var(--font-mono); font-size: 12.5px; color: var(--text-3); flex: none; }
.ven-paso.hecho .ven-paso-pct { color: var(--ok); }

/* Observaciones por paso (2026-09-21). El renglon del checklist se estira
   cuando se abre una: la casilla y el porcentaje se van ARRIBA en vez de
   quedarse al centro de un bloque alto, que los dejaba flotando a media
   altura sin relacion visible con el nombre del paso. */
.ven-paso:has(.ven-nota[open]) { align-items: flex-start; }
.ven-paso:has(.ven-nota[open]) .ven-paso-pct { margin-top: 7px; }
.ven-nota { margin-top: 6px; }
.ven-nota summary {
  display: inline-flex; align-items: center; gap: 5px; cursor: pointer;
  font-size: 12.5px; color: var(--text-3); list-style: none; width: fit-content;
}
.ven-nota summary::-webkit-details-marker { display: none; }
.ven-nota summary:hover { color: var(--text-2); }
.ven-nota summary .ico { width: 13px; height: 13px; flex: none; }
.ven-nota[open] summary { margin-bottom: 6px; }
.ven-nota textarea { width: 100%; resize: vertical; font-size: 13.5px; line-height: 1.5; }
.ven-nota-pie { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-top: 6px; }

/* Datos del cliente, plegados arriba de los pasos. */
.ven-datos { margin: 4px 0 14px; }
.ven-datos summary { display: inline-flex; cursor: pointer; list-style: none; }
.ven-datos summary::-webkit-details-marker { display: none; }
.ven-datos .ven-alta { margin-top: 10px; }

/* ---------------------------------------------------------------- seguimiento
   El tablero marca x cadena. Es una cuadricula ancha a proposito: es la
   forma en que esta gente ya lee su trabajo en Excel, y cambiarsela por una
   lista vertical seria pedirles que aprendan a leer su propio tablero. La
   primera columna va congelada (tabla-scroll--fija1) para que el nombre de
   la actividad no se pierda al recorrer las cadenas. */
.seg-barra { align-items: center; }
.seg-mes { font-size: 15px; min-width: 130px; text-align: center; }
.seg-tablero { font-size: 13px; }
.seg-tablero th, .seg-tablero td { padding: 7px 10px; vertical-align: middle; }
.seg-col { min-width: 116px; }
.seg-col a { font-weight: 600; }
.seg-sub { display: block; font-weight: 400; font-size: 10.5px; color: var(--text-3);
  text-transform: none; letter-spacing: 0; }
.seg-act { white-space: normal; }
.seg-num {
  font-family: var(--font-mono); font-size: 10.5px; color: var(--text-3);
  border: 1px solid var(--line); border-radius: 5px; padding: 1px 5px; margin-right: 6px;
}
.seg-peso { font-family: var(--font-mono); font-size: 11px; color: var(--text-3); margin-left: 6px; }
.seg-celda { text-align: center; }
.seg-celda form { margin: 0; display: inline-flex; }
/* Renglones que NO son del checklist: se distinguen para que la cuadricula
   no se lea como veinte palomitas seguidas. */
.seg-cabeza td { background: var(--surface-2); font-size: 12px; color: var(--text-2); }
.seg-total td { border-top: 1px solid var(--line-hard); font-weight: 600; }
.seg-semana td { font-size: 12px; color: var(--text-2); vertical-align: top; }
.seg-nota { white-space: normal; max-width: 220px; }
.seg-check {
  width: 26px; height: 26px; border-radius: 7px; border: 1.5px solid var(--line);
  background: var(--surface-2); cursor: pointer; display: inline-grid; place-items: center;
  color: var(--on-brand); padding: 0;
}
.seg-check:hover { border-color: var(--platinum); }
.seg-check.hecho { background: var(--ok); border-color: var(--ok); }
.seg-check .ico { width: 15px; height: 15px; }
.seg-solo-lectura { cursor: default; }
.seg-peso-in { width: 72px; text-align: right; }
.seg-mes-form { grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); }
.seg-semanas { display: grid; gap: 10px; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); margin-top: 10px; }
.seg-semana-card textarea { width: 100%; resize: vertical; font-size: 13px; margin-top: 6px; }

/* Telefono con WhatsApp y temperatura del prospecto (2026-09-22). */
.ven-td-tel { white-space: nowrap; }
.ven-wa { display: inline-flex; align-items: center; gap: 5px; font-family: var(--font-mono);
  font-size: 12.5px; text-decoration: none; color: var(--ok); }
.ven-wa:hover { text-decoration: underline; }
.ven-wa .ico { width: 14px; height: 14px; flex: none; }
.ven-temp {
  display: inline-block; font-size: 10.5px; font-weight: 600; letter-spacing: .04em;
  padding: 2px 7px; border-radius: 999px; text-transform: uppercase;
}
.ven-temp-caliente { background: color-mix(in srgb, var(--danger-ink) 14%, transparent); color: var(--danger-ink); }
.ven-temp-tibio    { background: var(--warn-bg); color: var(--warn); }
.ven-temp-frio     { background: var(--surface-3); color: var(--text-3); }
.ven-temp-dias { display: block; font-size: 10.5px; color: var(--text-3); margin-top: 2px;
  font-family: var(--font-mono); }

/* Tarjeta de KPI que se puede picar (cobranza, 2026-09-23). Es un <button>
   y no un <div> con onclick: asi se alcanza con el teclado y el lector de
   pantalla la anuncia como lo que es. */
.kpi-picable {
  cursor: pointer; text-align: left; width: 100%; font: inherit;
  border: 1px solid var(--line); transition: border-color .14s, transform .14s;
}
.kpi-picable:hover { border-color: var(--platinum); transform: translateY(-1px); }
.kpi-picable:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
.kpi-modal-tabla { max-height: 46vh; margin: 8px 0; }
/* La ventana de facturas: el ultimo nivel, cuando ya se dejo de comparar. */
#fac-modal { padding: 18px 20px 20px; width: min(720px, calc(100vw - 32px)); }
#fac-modal .lista { margin-top: 0; font-size: 13px; }
#fac-modal .lista td, #fac-modal .lista th { padding: 5px 10px; }
#fac-modal .tm-modal-pie { margin-top: 10px; }

/* Las tarjetas y, al picar una, su desglose AL LADO: las tarjetas se
   recorren a la izquierda y la que se pico se sigue viendo junto a lo que
   la explica. Un popup tapaba justamente eso. */
.kpi-zona { display: grid; gap: 14px; grid-template-columns: 1fr; }
.kpi-zona.con-panel { grid-template-columns: minmax(0, 1fr) minmax(300px, 380px); }
@media (max-width: 1023.98px) { .kpi-zona.con-panel { grid-template-columns: 1fr; } }
.kpi-card.kpi-abierta { border-color: var(--platinum); box-shadow: var(--shadow-sm); }
.kpi-panel { background: var(--surface); background-image: var(--facet);
  border: 1px solid var(--line); border-radius: 12px; padding: 14px 16px;
  display: flex; flex-direction: column; min-width: 0; animation: fade-up .3s both; }
.kpi-panel-top { display: flex; justify-content: space-between; align-items: center; gap: 8px; }
.kpi-panel-tit { margin: 0; font-family: var(--font-mono); font-size: 10px;
  letter-spacing: .16em; text-transform: uppercase; color: var(--text-3); }
.kpi-panel-sub { margin: 2px 0 8px; font-size: 12.5px; color: var(--text-2); }
.kpi-panel-lista { display: flex; flex-direction: column; overflow-y: auto; max-height: 340px; }
.kpi-panel-pie { margin: 8px 0 0; font-size: 11.5px; color: var(--text-3); }
/* Cada cliente del desglose se pica y abre sus facturas. */
.kpi-cli { display: grid; grid-template-columns: 1fr auto; gap: 0 10px; width: 100%;
  background: none; border: 0; border-bottom: 1px solid var(--line-soft); cursor: pointer;
  padding: 6px 4px; text-align: left; font: inherit; color: inherit; border-radius: 6px; }
.kpi-cli:hover { background: var(--surface-2); }
.kpi-cli:focus-visible { outline: 2px solid var(--brand); outline-offset: -2px; }
.kpi-cli-n { font-size: 12.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.kpi-cli-m { font-family: var(--font-mono); font-size: 12.5px; font-variant-numeric: tabular-nums; }
.kpi-cli-p { grid-column: 1 / -1; font-family: var(--font-mono); font-size: 10.5px; color: var(--text-3); }
.kpi-cli-a { color: var(--text-3); opacity: .8; }
.tb-mal { color: var(--danger-ink); }

/* ----------------------------------------------------------------- transporte
   Una tarjeta por destino en vez de una tabla gigante: la pregunta siempre
   es de UN destino ("¿quien me lleva a Monterrey?"), y una cuadricula de 151
   renglones por doce columnas es justo lo que hoy obliga a leer a ojo. */
.tr-destino { margin: 10px 0; padding: 12px 14px; }
.tr-destino-top { display: flex; align-items: baseline; gap: 10px; }
.tr-destino-top h2 { margin: 0; font-size: 16px; }
.tr-tabla { margin-top: 6px; font-size: 13px; }
.tr-tabla td, .tr-tabla th { padding: 5px 10px; }
.tr-disp {
  font-family: var(--font-mono); font-size: 10px; text-transform: uppercase;
  padding: 1px 6px; border-radius: 999px; background: var(--surface-3); color: var(--text-3);
}
.tr-alta { background: color-mix(in srgb, var(--ok) 16%, transparent); color: var(--ok); }
.tr-nuevo { background: var(--warn-bg); color: var(--warn); }
.tr-baja { background: var(--surface-3); color: var(--text-3); }

/* Informe de la importacion de clientes. */
.ven-informe { border-color: var(--ok); margin: 12px 0; }
.ven-informe-tit { display: flex; align-items: baseline; gap: 7px; margin: 0 0 8px; font-weight: 600; }
.ven-informe-tit .ico { width: 15px; height: 15px; color: var(--ok); flex: none; }
.ven-informe-lista { margin: 0 0 6px; padding-left: 18px; font-size: 13.5px; line-height: 1.7; }
.ven-importar { margin: 0 0 14px; }
.ven-importar summary { display: inline-flex; cursor: pointer; list-style: none; }
.ven-importar summary::-webkit-details-marker { display: none; }
.ven-importar .ven-alta { margin-top: 10px; }
.ven-calif { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }

/* Reparto de cartera desde la tabla. El selector se ve como texto hasta que
   se le acerca el cursor: una columna de 99 cajas grises tapaba los nombres,
   que es lo que se viene a leer. */
.ven-td-vend { min-width: 172px; }
.ven-asignar {
  width: 100%; max-width: 190px; padding: 4px 6px; font: inherit; font-size: 13px;
  color: var(--text); background: transparent; border: 1px solid transparent;
  border-radius: 6px; cursor: pointer; appearance: none;
}
.ven-asignar:hover, .ven-asignar:focus { border-color: var(--line); background: var(--surface-2); }
.ven-asignar:disabled { opacity: .5; cursor: progress; }
/* Sin dueño se sigue viendo como la etiqueta ambar de antes: es lo que el
   gerente busca con la vista cuando entra a repartir. */
.ven-asignar.sin-dueno {
  font-family: var(--font-mono); font-size: 11.5px; color: var(--warn);
  border-color: color-mix(in srgb, var(--warn) 45%, transparent);
}
.ven-guardado { animation: ven-destello 1.6s ease-out 1; }
@keyframes ven-destello {
  0%, 40% { background: color-mix(in srgb, var(--ok) 16%, transparent); }
  100%    { background: transparent; }
}
.ven-aviso {
  position: sticky; top: 8px; z-index: 5; margin: 0 0 10px; padding: 8px 14px;
  border-radius: 100px; background: var(--surface-2); border: 1px solid var(--line);
  font-size: 13px; width: fit-content;
}
.ven-aviso.malo { color: var(--danger-ink); border-color: var(--danger-ink); }

/* ============================================================
   Teams: pendientes del equipo (/teams)

   Lista y no tabla: un pendiente es una frase con gente y una fecha, no
   ocho columnas. La frase se lee de corrido; una tabla obligaria a cruzar
   la vista entre celdas para entender una sola tarea.
   ============================================================ */
.tm-lista { list-style: none; margin: 14px 0 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.tm-item {
  display: flex; align-items: center; gap: 12px; padding: 12px 14px;
  border: 1px solid var(--line); border-radius: var(--r-lg); background: var(--surface);
}
.tm-item-txt { flex: 1; min-width: 0; }
.tm-item-tit { margin: 0 0 3px; font-size: 14.5px; font-weight: 600; }
.tm-item-tit a { color: inherit; text-decoration: none; }
.tm-item-tit a:hover { text-decoration: underline; }
.tm-item p.muted { margin: 0; display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.tm-item form { margin: 0; }
/* Lo cerrado sigue en la lista pero no compite con lo que falta por hacer. */
.tm-cerrado { opacity: .5; }
.tm-cerrado .tm-item-tit { text-decoration: line-through; }
.tm-vencido { border-color: color-mix(in srgb, var(--danger-ink) 45%, transparent); }

/* La prioridad es una barrita al borde, no otra etiqueta mas que leer. */
.tm-prio { width: 4px; align-self: stretch; border-radius: 3px; flex: none; background: var(--line); }
.tm-prio-alta  { background: var(--danger-ink); }
.tm-prio-media { background: var(--warn); }
.tm-prio-baja  { background: var(--line); }

.tm-estado {
  font-family: var(--font-mono); font-size: 10.5px; letter-spacing: .06em;
  text-transform: uppercase; padding: 2px 8px; border-radius: 100px;
  border: 1px solid var(--line); color: var(--text-3); white-space: nowrap;
}
.tm-abierto   { color: var(--brand); border-color: color-mix(in srgb, var(--brand) 45%, transparent); }
.tm-en_curso  { color: var(--warn); border-color: color-mix(in srgb, var(--warn) 45%, transparent); }
.tm-hecho     { color: var(--ok); border-color: color-mix(in srgb, var(--ok) 45%, transparent); }
.tm-cancelado { color: var(--text-3); }
.tm-tarde { color: var(--danger-ink); }
.tm-hoy { color: var(--warn); }

/* Barra de arriba: el boton, el resumen y los filtros en un solo renglon.
   El titulo y la bajada se fueron -- el menu ya dice donde estas, y ocupaban
   el primer tercio de la pantalla para repetirlo.
   DECISION NUEVA para el Control Tower (2026-10-05, plan 0.7, decision D4,
   opcion b): ahi el titulo SI vuelve, pero en un encabezado de una linea
   (.ct-head, bloque "Control Tower" de arriba): h1 visible + conteo + acciones
   en el mismo renglon, y esta barra se queda solo con los filtros. Por que:
   en movil el menu se esconde y con lector de pantalla un h1 oculto no da
   contexto, y la ficha del embarque si tiene dash-head. Se descarto (a)
   revertir al bloque alto de titulo y bajada, que es justo lo que se quito.
   Teams sigue como estaba: alla el menu basta. */
.tm-barra {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  margin: 0 0 14px; padding-bottom: 12px; border-bottom: 1px solid var(--line);
}
.tm-barra-sep { flex: 1; }
.tm-resumen { margin: 0; font-size: 13px; color: var(--text-2); }
.tm-filtros { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin: 0; }
.tm-filtros select { font-size: 12.5px; padding: 4px 8px; }

/* Ventana emergente del alta. Nativa: fondo, foco y Escape sin libreria. */
.tm-modal {
  border: 1px solid var(--line); border-radius: var(--r-lg); background: var(--surface);
  color: var(--text); padding: 0; width: min(760px, calc(100vw - 32px));
  max-height: calc(100dvh - 48px); overflow: auto;
}
.tm-modal::backdrop { background: rgba(0, 0, 0, .55); }
/* mpConfirm() de base.html: la misma ventana, angosta, para una pregunta. */
.mp-confirm { width: min(440px, calc(100vw - 32px)); }
.mp-confirm .tm-form { grid-template-columns: 1fr; }
.mp-confirm p { margin: 0; font-size: var(--fs-sm); line-height: 1.5; }
.tm-modal .tm-form { padding: 18px 20px 20px; margin: 0; }
.tm-modal-top { display: flex; justify-content: space-between; align-items: center; gap: 12px; }
.tm-modal-top h2 { margin: 0; font-size: 17px; }
.tm-modal-pie { display: flex; justify-content: flex-end; gap: 10px; margin-top: 4px; }
.tm-cerrar { background: none; border: 0; padding: 4px; cursor: pointer; color: var(--text-3); display: inline-flex; }
.tm-cerrar:hover { color: var(--text); }
.tm-cerrar .ico { width: 18px; height: 18px; }
.tm-form {
  display: grid; gap: 12px 16px; align-items: end; margin-top: 10px;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
}
.tm-form label { display: flex; flex-direction: column; gap: 5px; font-size: 13px; }
.tm-form .tm-ancho { grid-column: 1 / -1; }
.tm-form textarea { resize: vertical; font: inherit; }
.tm-form .btn { justify-self: start; }
.tm-check { flex-direction: row !important; align-items: center; gap: 8px !important; }

.tm-avisos { border-color: var(--brand); margin: 12px 0; }
.tm-avisos-top { display: flex; justify-content: space-between; align-items: center; gap: 12px; flex-wrap: wrap; }
.tm-avisos-tit { display: flex; align-items: baseline; gap: 7px; margin: 0; font-weight: 600; }
.tm-avisos-tit .ico { width: 15px; height: 15px; color: var(--brand); flex: none; }
.tm-avisos-lista { margin: 8px 0 0; padding-left: 18px; font-size: 13.5px; line-height: 1.8; }
.tm-avisos-top form { margin: 0; }

.tm-detalle { white-space: pre-wrap; margin: 4px 0 14px; max-width: 78ch; line-height: 1.6; }
.tm-acciones { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 8px; }
.tm-acciones form { margin: 0; }

.tm-gente { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
.tm-persona {
  display: inline-flex; align-items: center; gap: 6px; padding: 5px 10px;
  border: 1px solid var(--line); border-radius: 100px; font-size: 13px;
}
.tm-persona .ico { width: 14px; height: 14px; color: var(--text-3); }
.tm-persona em { font-family: var(--font-mono); font-size: 10px; letter-spacing: .06em;
  text-transform: uppercase; color: var(--text-3); font-style: normal; }
.tm-resp { border-color: var(--platinum); }
.tm-persona form { margin: 0; display: inline-flex; }
.tm-quitar { background: none; border: 0; padding: 0; cursor: pointer; color: var(--text-3); display: inline-flex; }
.tm-quitar .ico { width: 12px; height: 12px; }
.tm-quitar:hover { color: var(--danger-ink); }
.tm-invitar { display: inline-flex; gap: 6px; align-items: center; margin: 0; }

.tm-coments { list-style: none; margin: 10px 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.tm-coments li { border-left: 2px solid var(--line); padding: 2px 0 2px 12px; }
.tm-coment-quien { margin: 0; font-size: 13px; font-weight: 600; display: flex; gap: 8px; align-items: baseline; }
.tm-coment-txt { margin: 2px 0 0; white-space: pre-wrap; line-height: 1.55; max-width: 78ch; }
.tm-comentar { display: flex; gap: 10px; align-items: flex-end; margin-top: 10px; flex-wrap: wrap; }
.tm-comentar textarea { flex: 1; min-width: 240px; resize: vertical; font: inherit; }

.tm-editar { margin-top: 18px; }
.tm-editar summary { display: inline-flex; cursor: pointer; list-style: none; }
.tm-editar summary::-webkit-details-marker { display: none; }
.tm-historial { list-style: none; margin: 10px 0 0; padding: 0; font-size: 13px; line-height: 1.9; }
.tm-historial .muted { font-family: var(--font-mono); font-size: 11.5px; margin-right: 8px; }
.tm-ayuda { margin: 12px 0; }
.tm-ayuda ol { margin: 8px 0 0; padding-left: 20px; line-height: 1.7; font-size: 13.5px; max-width: 80ch; }
.tm-nota { max-width: 80ch; margin-top: 16px; }
/* El correo se captura en el propio renglon de la lista de usuarios. */
.usr-campo[type="email"] { min-width: 170px; max-width: 220px; }
.usr-perfil { margin: 0; }
.usr-perfil select { font-size: 12.5px; padding: 3px 6px; min-width: 120px; }

/* ============================================================
   Organigrama (/usuarios/organigrama)

   Arbol vertical con sangria, no cajas conectadas con lineas: con 21
   cuentas y cuatro niveles, el diagrama clasico se sale de la pantalla y
   obliga a hacer zoom para leer un nombre. La sangria se lee de corrido y
   funciona igual en celular.
   ============================================================ */
.usr-vistas { margin: 0 0 4px; }
.og-scroll { overflow-x: auto; padding: 4px 2px 8px; }
.og-arbol, .og-hijos { list-style: none; margin: 0; padding: 0; }
.og-hijos { margin-left: 26px; padding-left: 18px; border-left: 1px solid var(--line); }
.og-nodo { position: relative; margin: 6px 0; }
/* La rayita que une cada caja con la linea vertical de su nivel. */
.og-hijos > .og-nodo::before {
  content: ""; position: absolute; left: -18px; top: 20px;
  width: 14px; height: 1px; background: var(--line);
}
.og-caja {
  display: inline-block; min-width: 190px; padding: 9px 14px;
  border: 1px solid var(--line); border-radius: var(--r-lg); background: var(--surface);
}
.og-nombre { margin: 0; font-weight: 600; font-size: 14px; }
.og-puesto { margin: 1px 0 0; font-size: 12.5px; color: var(--text-2); }
.og-meta { margin: 5px 0 0; display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.og-perfil {
  font-family: var(--font-mono); font-size: 10px; letter-spacing: .06em;
  text-transform: uppercase; color: var(--text-3);
  border: 1px solid var(--line); border-radius: 100px; padding: 1px 7px;
}
.og-equipo { font-size: 11.5px; color: var(--text-3); }
.og-ciclo > .og-caja { border-color: var(--danger-ink); }
.og-alerta { margin: 6px 0 0; font-size: 12px; color: var(--danger-ink); display: flex; gap: 5px; align-items: center; }
.og-alerta .ico { width: 13px; height: 13px; flex: none; }
/* Puesto y jefe, cada uno en su celda. Anchos acotados: sin esto, un
   desplegable con veintiun nombres estira la columna hasta empujar las de
   al lado fuera de la pantalla. */
.usr-org { max-width: 190px; }
.usr-org input, .usr-org select {
  width: 100%; max-width: 180px; font-size: 12.5px; padding: 4px 8px;
}
.usr-org select { text-overflow: ellipsis; }

/* Cuadrante DACA: etiqueta corta al borde del renglon. El color agrupa de un
   vistazo sin obligar a leer "estratégico y urgente" en cada fila. */
.tm-prio {
  width: auto; align-self: flex-start; flex: none; padding: 2px 7px; border-radius: 6px;
  font-family: var(--font-mono); font-size: 10.5px; font-weight: 600;
  border: 1px solid var(--line); color: var(--text-3); background: transparent;
}
.tm-q-Q1 > .tm-prio, .tm-prio.tm-q-Q1 { color: var(--danger-ink); border-color: color-mix(in srgb, var(--danger-ink) 50%, transparent); }
.tm-q-Q2 > .tm-prio, .tm-prio.tm-q-Q2 { color: var(--brand); border-color: color-mix(in srgb, var(--brand) 50%, transparent); }
.tm-q-Q3 > .tm-prio, .tm-prio.tm-q-Q3 { color: var(--warn); border-color: color-mix(in srgb, var(--warn) 50%, transparent); }
.tm-q-Q4 > .tm-prio, .tm-prio.tm-q-Q4 { color: var(--text-3); }

/* Avatares con iniciales: tres colaboradores escritos largo se comen el
   titulo, que es lo unico que hay que leer de un vistazo. */
.tm-avatares { display: inline-flex; gap: 3px; }
.tm-avatar {
  display: inline-flex; align-items: center; justify-content: center;
  width: 22px; height: 22px; border-radius: 50%; flex: none;
  background: var(--surface-3); color: var(--text-2);
  font-family: var(--font-mono); font-size: 9.5px; font-weight: 600; letter-spacing: 0;
}
.tm-fecha-chip {
  font-family: var(--font-mono); font-size: 11px; padding: 1px 7px;
  border-radius: 100px; background: var(--surface-2);
}
.tm-fecha-chip.tm-tarde { color: var(--danger-ink); background: var(--danger-bg, transparent);
  border: 1px solid color-mix(in srgb, var(--danger-ink) 40%, transparent); }
.tm-fecha-chip.tm-hoy { color: var(--warn); border: 1px solid color-mix(in srgb, var(--warn) 45%, transparent); }

.tm-item-acciones { display: flex; align-items: center; gap: 8px; flex: none; }
.tm-item-acciones form { margin: 0; }
.tm-estado-sel { font-size: 11.5px; padding: 3px 6px; border-radius: 6px; max-width: 120px; }
.tm-mover { display: inline-flex; gap: 3px; }
.tm-mover-b {
  font-family: var(--font-mono); font-size: 10.5px; padding: 3px 6px; cursor: pointer;
  border: 1px solid var(--line); border-radius: 5px; background: transparent; color: var(--text-3);
}
.tm-mover-b:hover { border-color: var(--platinum); color: var(--text); }
.tm-mover-b:disabled { opacity: .4; cursor: progress; }
.tm-borrar { background: none; border: 0; padding: 3px; cursor: pointer; color: var(--text-3); display: inline-flex; }
.tm-borrar:hover { color: var(--danger-ink); }
.tm-borrar .ico { width: 14px; height: 14px; }
.tm-chevron { background: none; border: 0; padding: 0 2px 0 0; cursor: pointer; color: var(--text-3); display: inline-flex; }
.tm-chevron .ico { width: 14px; height: 14px; transition: transform .15s; }
.tm-chevron.abierto .ico { transform: rotate(180deg); }
.tm-detalle-inline { margin-top: 8px; padding: 9px 12px; border-left: 2px solid var(--line); }
.tm-detalle-inline p { margin: 0; white-space: pre-wrap; font-size: 13px; line-height: 1.55; }

/* Colaboradores como casillas: se ve a todo el equipo de un golpe, sin
   scroll y sin ctrl+clic, que nadie sabe que hay que hacer. */
.tm-colabs { border: 1px solid var(--line); border-radius: var(--r-lg); padding: 10px 14px; margin: 0; }
.tm-colabs summary {
  display: flex; justify-content: space-between; align-items: center; gap: 12px;
  cursor: pointer; font-size: 13px; list-style: none;
}
.tm-colabs summary::-webkit-details-marker { display: none; }
.tm-colabs summary::after { content: "▾"; color: var(--text-3); font-size: 11px; }
.tm-colabs[open] summary::after { content: "▴"; }
.tm-colabs-cuenta {
  font-family: var(--font-mono); font-size: 11px; color: var(--text-3);
  border: 1px solid var(--line); border-radius: 100px; padding: 2px 9px; margin-left: auto;
}
.tm-colabs-buscar { display: block; margin: 10px 0 8px; }
.tm-colabs-buscar input { width: 100%; font-size: 13px; }
.tm-colabs-rejilla {
  display: grid; gap: 6px 14px; grid-template-columns: repeat(auto-fill, minmax(185px, 1fr));
  max-height: 210px; overflow-y: auto;
}
.tm-colab { display: flex; flex-direction: row !important; align-items: center; gap: 8px !important; font-size: 13px; cursor: pointer; }

.tm-fechas { display: flex; gap: 5px; flex-wrap: wrap; margin-top: 5px; }
.tm-fechas button {
  font-size: 11px; padding: 3px 9px; border-radius: 100px; cursor: pointer;
  border: 1px solid var(--line); background: transparent; color: var(--text-2);
}
.tm-fechas button:hover, .tm-fechas button.puesto { border-color: var(--platinum); color: var(--text); }

.tm-checklist { list-style: none; margin: 8px 0 0; padding: 0; display: flex; flex-direction: column; gap: 4px; }
.tm-checklist li { display: flex; align-items: center; gap: 10px; padding: 6px 10px; border: 1px solid var(--line); border-radius: var(--r-md); }
.tm-checklist li form { margin: 0; }
.tm-checklist li > span { flex: 1; font-size: 13.5px; }
.tm-checklist li.hecho > span { color: var(--text-3); text-decoration: line-through; }
/* Pista junto al campo de producto: sin ella nadie sabe que ese cuadro busca. */
.fi-pista { font-size: 10.5px; letter-spacing: 0; text-transform: none; }
.ven-ancho { grid-column: 1 / -1; }
.tm-modal .ven-alta { padding: 18px 20px 20px; margin: 0; }
.ct-ancho { grid-column: 1 / -1; }
.tm-modal .ct-nuevo { display: grid; gap: 12px 16px; align-items: end; padding: 18px 20px 20px;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); margin: 0; background: none; border: 0; }
.tm-barra .ctrl-label { font-size: 11px; }
.tm-barra select { font-size: 12.5px; padding: 4px 8px; }

/* Resumen del equipo (/teams/equipo): el organigrama con lo que trae cada
   quien, y al lado lo ultimo que se movio en la empresa. */
.te-columnas { display: grid; gap: 26px; grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr); }
@media (max-width: 899.98px) { .te-columnas { grid-template-columns: 1fr; } }
.te-caja { min-width: 260px; }
.te-cifras { margin: 4px 0 0; display: flex; gap: 10px; flex-wrap: wrap; align-items: center; font-size: 12.5px; }
.te-cifras a { color: inherit; text-decoration: none; }
.te-cifras a:hover { text-decoration: underline; }
.te-q1 { color: var(--danger-ink); }
.te-ok { color: var(--ok); }
.te-rojo { border-color: color-mix(in srgb, var(--danger-ink) 45%, transparent); }
.te-reciente { list-style: none; margin: 10px 0 0; padding: 0; display: flex; flex-direction: column; gap: 7px; font-size: 13px; }
.te-reciente li { display: flex; gap: 7px; flex-wrap: wrap; align-items: baseline; padding-bottom: 7px; border-bottom: 1px solid var(--line); }
.te-cuando { font-family: var(--font-mono); font-size: 11px; color: var(--text-3); flex: none; }
.te-quien { font-weight: 600; }
/* Ligar "quién escaneó" con la cuenta del vendedor. */
.ven-ligar { border-color: var(--warn); margin: 12px 0; }
.ven-ligar-auto { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; margin: 8px 0 4px; }
.ven-ligar-lista { list-style: none; margin: 8px 0 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.ven-ligar-lista li { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; padding: 6px 0; border-top: 1px solid var(--line); }
.ven-ligar-lista form { display: flex; gap: 6px; align-items: center; margin: 0 0 0 auto; }
.ven-ligar-lista select { font-size: 12.5px; padding: 4px 8px; min-width: 150px; }
.ven-ligar-nom { font-weight: 600; font-size: 13.5px; }
/* La tarjeta de cada persona es un boton: abre sus pendientes a la derecha. */
.te-caja { display: block; width: 100%; text-align: left; cursor: pointer; font: inherit; color: inherit; }
.te-caja:hover { border-color: var(--platinum); }
.te-caja.activa { border-color: var(--brand); box-shadow: 0 0 0 1px var(--brand); }
.te-derecha { position: sticky; top: 12px; align-self: start; }
.te-pend { list-style: none; margin: 10px 0 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.te-pend-item { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; padding: 8px 10px; border: 1px solid var(--line); border-radius: var(--r-md); font-size: 13px; }
.te-pend-item a { color: inherit; text-decoration: none; flex: 1; min-width: 140px; }
.te-pend-item a:hover { text-decoration: underline; }
.te-derecha .section-title { display: flex; justify-content: space-between; align-items: center; gap: 10px; }

/* ============================================================
   Portada (/inicio)

   Una tarjeta por modulo, cada una con UNA cifra grande y el detalle
   debajo. La cifra grande es la que contesta "como vamos" desde la puerta;
   si todas las tarjetas pesaran igual, la portada seria una lista de datos
   en vez de un tablero.
   ============================================================ */
.in-rejilla { display: grid; gap: 14px; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); }
.in-card { margin: 0; display: flex; flex-direction: column; gap: 4px; }
.in-ancha { grid-column: span 2; }
@media (max-width: 719.98px) { .in-ancha { grid-column: span 1; } }
.in-tit { display: flex; align-items: center; gap: 7px; margin: 0 0 6px; font-size: 13px;
  font-weight: 600; letter-spacing: .02em; }
.in-tit .ico { width: 15px; height: 15px; color: var(--text-3); }
.in-tit a { color: var(--text-2); text-decoration: none; }
.in-tit a:hover { color: var(--text); text-decoration: underline; }
.in-cifra {
  margin: 0; font-family: var(--font-display); font-size: clamp(26px, 3.4vw, 34px);
  font-weight: 600; letter-spacing: -.02em; line-height: 1.1;
  font-variant-numeric: tabular-nums;
}
.in-cifra span { font-family: var(--font-body); font-size: 13px; font-weight: 400; color: var(--text-3); letter-spacing: 0; }
.in-sube { color: var(--ok); font-size: 14px !important; }
.in-baja { color: var(--danger-ink); font-size: 14px !important; }
.in-sub { margin: 2px 0 0; font-size: 12.5px; color: var(--text-2); line-height: 1.5; }
.in-etiqueta { font-family: var(--font-mono); font-size: 10.5px; letter-spacing: .08em;
  text-transform: uppercase; color: var(--text-3); margin-top: 10px; }
.in-lista { list-style: none; margin: 8px 0 0; padding: 0; display: flex; flex-direction: column; gap: 3px; }
.in-lista li { display: flex; justify-content: space-between; gap: 12px; font-size: 12.5px;
  padding: 3px 0; border-bottom: 1px solid var(--line); }
.in-lista li:last-child { border-bottom: 0; }
.in-lista li span { color: var(--text-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.in-lista li b { font-variant-numeric: tabular-nums; flex: none; }
.in-reciente { list-style: none; margin: 6px 0 0; padding: 0; display: flex; flex-direction: column; gap: 5px; font-size: 12.5px; }
.in-reciente li { display: flex; gap: 6px; flex-wrap: wrap; align-items: baseline; }
.in-reciente a { color: var(--text-2); }
.in-dos { display: grid; gap: 20px; grid-template-columns: 1fr 1fr; }
@media (max-width: 719.98px) { .in-dos { grid-template-columns: 1fr; } }
/* Una tarjeta con algo que atender se nota sin leerla. */
.in-alerta { border-color: color-mix(in srgb, var(--warn) 50%, transparent); }
.in-vacio { margin: 6px 0 0; font-size: 12.5px; color: var(--text-3); }

/* Una cifra que se explica sola: se pica y sale de quien es. Es un
   <details>, no un tooltip: el clic abre Y cierra, el teclado lo alcanza y
   en tableta funciona igual (donde no hay "pasar el cursor"). Sin JS: el
   desglose es texto que ya viaja en la pagina. */
.in-pop { position: relative; display: inline-block; }
.in-cifra .in-pop, .in-cifra .in-pop-ancla { font: inherit; color: inherit; letter-spacing: inherit; }
.in-pop-ancla { display: inline; cursor: pointer; list-style: none;
  text-decoration: underline dotted; text-underline-offset: 5px;
  text-decoration-color: var(--line); font-variant-numeric: tabular-nums; }
.in-pop-ancla::-webkit-details-marker { display: none; }
.in-pop-ancla:hover, .in-pop[open] .in-pop-ancla { text-decoration-color: var(--text-3); }
.in-pop-caja { position: absolute; z-index: 30; top: calc(100% + 8px); left: 0;
  width: max-content; max-width: min(340px, 78vw); display: flex; flex-direction: column;
  padding: 10px 12px; background: var(--surface); border: 1px solid var(--line);
  border-radius: 10px; box-shadow: var(--shadow); text-align: left; cursor: default; }
.in-cifra .in-pop-caja, .in-cifra .in-pop-caja span, .in-cifra .in-pop-caja b,
.in-sub .in-pop-caja, .in-sub .in-pop-caja span, .in-sub .in-pop-caja b {
  font-family: var(--font-body); font-size: 12.5px; font-weight: 400;
  letter-spacing: 0; color: var(--text); line-height: 1.5; }
.in-pop-caja .in-pop-tit { font-family: var(--font-mono); font-size: 10.5px;
  letter-spacing: .08em; text-transform: uppercase; color: var(--text-3); margin-bottom: 5px; }
.in-pop-fila { display: flex; justify-content: space-between; gap: 18px; padding: 2px 0; }
.in-pop-fila > span { color: var(--text-2); overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; }
.in-pop-fila b { font-weight: 600; font-variant-numeric: tabular-nums; flex: none; }
.in-pop-otros > span { color: var(--text-3); }
.in-pop-suma { margin-top: 5px; padding-top: 6px; border-top: 1px solid var(--line); }
/* El desglose dice de QUIEN es el saldo; la tabla dice CUALES facturas son. */
.in-pop-mas { display: inline-flex; align-items: center; gap: 5px; margin-top: 9px;
  font-size: 12px; color: var(--text-2); text-decoration: none; }
.in-pop-mas:hover { color: var(--text); text-decoration: underline; }
.in-pop-mas .ico { width: 13px; height: 13px; }
/* Los dolares no se suman con los pesos: se ven, separados. */
.in-aparte { color: var(--text-3); }
.in-pie { margin: 26px 0 0; padding-top: 14px; border-top: 1px solid var(--line); font-size: 12.5px; }
.in-pie a { color: var(--text-3); display: inline-flex; align-items: center; gap: 6px; }
.in-pie a:hover { color: var(--text); }
.in-pie .ico { width: 14px; height: 14px; }
/* La tarjeta de cada vendedor abre su cartera. */
button.ven-tarjeta { text-align: left; cursor: pointer; font: inherit; color: inherit; width: 100%; }
button.ven-tarjeta:hover:not(:disabled) { border-color: var(--platinum); }
button.ven-tarjeta:disabled { cursor: default; }
.ven-vend { padding: 18px 20px 20px; }
.ven-vend-lista { list-style: none; margin: 12px 0 0; padding: 0; display: flex; flex-direction: column; gap: 6px; max-height: 60dvh; overflow-y: auto; }
.ven-vend-lista li { display: grid; gap: 4px 12px; align-items: center; padding: 8px 10px;
  border: 1px solid var(--line); border-radius: var(--r-md); font-size: 13px;
  grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr) 170px 44px; }
@media (max-width: 719.98px) { .ven-vend-lista li { grid-template-columns: 1fr; } }
.ven-vend-lista a { color: inherit; text-decoration: none; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ven-vend-lista a:hover { text-decoration: underline; }
.ven-vend-pasos { font-family: var(--font-mono); font-size: 11.5px; text-align: right; }

/* ---------------------------------------------------------------------------
   "Mi día" del promotor: un paso a la vez (pr_hoy.html). La tarjeta grande es
   lo que toca AHORA y es lo unico que se puede tocar; abajo va el dia
   completo en una lista de solo lectura.
   --------------------------------------------------------------------------- */
.ph-avance { margin: 18px 0 22px; }
.ph-avance-barra { height: 8px; border-radius: 99px; background: var(--surface-2); overflow: hidden; }
.ph-avance-barra span { display: block; height: 100%; border-radius: 99px; background: var(--ok, #2F6B46);
                        transition: width .4s ease; }
.ph-avance-txt { margin: 8px 0 0; font: 500 14px/1.3 inherit; color: var(--text-2); }

.ph-paso { border: 2px solid var(--ok, #2F6B46); border-radius: 22px; padding: 22px 20px 24px;
           background: var(--surface-1); box-shadow: 0 10px 28px rgba(16, 16, 18, .07); }
.ph-paso-etq { margin: 0 0 6px; font: 700 13px/1 "JetBrains Mono", monospace; letter-spacing: .1em;
               text-transform: uppercase; color: var(--ok, #2F6B46); display: flex; align-items: center; gap: 6px; }
.ph-paso-tit { margin: 0 0 8px; font-size: 26px; line-height: 1.15; }
.ph-paso-sub { margin: 0 0 14px; color: var(--text-2); }
.ph-paso-hora { margin: 0 0 14px; font: 500 15px/1.3 inherit; display: flex; align-items: center; gap: 8px; }
.ph-paso-form { display: grid; gap: 12px; }
.ph-paso-form .ph-btn-guardar { width: 100%; justify-content: center; font-size: 17px; padding: 16px; }
.ph-paso-listo { border-color: var(--line); }
.ph-venta-campo { display: grid; gap: 6px; font-weight: 600; }

.ph-pasos { list-style: none; margin: 0; padding: 0; display: grid; gap: 2px; }
.ph-fila { display: flex; align-items: center; gap: 12px; padding: 12px 14px; border-radius: 14px; }
.ph-fila-num { flex: 0 0 28px; height: 28px; border-radius: 99px; display: grid; place-items: center;
               font: 700 14px "JetBrains Mono", monospace; background: var(--surface-2); color: var(--text-2); }
.ph-fila-txt { flex: 1; display: grid; gap: 2px; font-weight: 600; }
.ph-fila-dato { font: 500 13px "JetBrains Mono", monospace; color: var(--text-2); }
.ph-fila-thumb { flex: 0 0 44px; }
.ph-fila-thumb img { width: 44px; height: 44px; object-fit: cover; border-radius: 10px; display: block; }
.ph-fila--hecho .ph-fila-num { background: var(--ok, #2F6B46); color: #fff; }
.ph-fila--hecho .ph-fila-num svg { width: 16px; height: 16px; }
.ph-fila--ahora { background: var(--surface-2); }
.ph-fila--ahora .ph-fila-num { background: var(--ok, #2F6B46); color: #fff; }
.ph-fila--ahora .ph-fila-dato { color: var(--ok, #2F6B46); font-weight: 700; }
.ph-fila--despues { opacity: .55; }

/* Guardado en tanda de la lista de usuarios. */
.usr-guardar-barra {
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  position: sticky; top: 0; z-index: 4; padding: 8px 0;
  background: var(--canvas); border-bottom: 1px solid var(--line); margin-bottom: 8px;
}
.usr-guardar-barra .section-title { margin: 0; }
.usr-guardar-barra .btn:disabled { opacity: .45; cursor: default; }
/* Un campo tocado se marca: con veintiun renglones, saber cual movimos es la
   diferencia entre guardar con confianza y guardar a ciegas. */
.usr-tocado { border-color: var(--warn) !important; background: var(--warn-bg); }
.usr-campo { font-size: 12.5px; padding: 4px 8px; }
td .usr-campo + .usr-campo { margin-left: 6px; }

/* Resumen de que alcanza cada perfil. */
.usr-matriz { margin: 10px 0 14px; }
.usr-matriz summary { display: inline-flex; cursor: pointer; list-style: none; }
.usr-matriz summary::-webkit-details-marker { display: none; }
.usr-matriz-tabla { margin-top: 10px; font-size: 12.5px; }
/* Diez columnas tienen que caber sin irse de lado: el encabezado va mas
   chico y con menos espaciado entre letras, y las celdas aprietan los
   costados. Lo que se recorta es el aire, no el dato. */
.usr-matriz-tabla th {
  white-space: nowrap; font-size: 9.5px; letter-spacing: .08em;
  padding-left: 7px; padding-right: 7px;
}
.usr-matriz-tabla td { padding-left: 7px; padding-right: 7px; }
.usr-matriz-tabla tbody td:first-child { padding-left: 12px; }
.usr-donde { display: block; color: var(--text-3); font-size: 11px; margin-top: 2px; }
/* Sin palomita: la palabra ya dice si ve o si edita, y el icono costaba
   14px en cada una de las cien celdas de la tabla. */
.usr-si { color: var(--ok); font-size: 11.5px; }
.usr-ve { color: var(--text-2); font-size: 11.5px; }
.usr-no { color: var(--line); }

/* Directorio de tiendas. */
.dir-sin td:first-child { border-left: 2px solid var(--warn); }
.dir-contactos { list-style: none; margin: 10px 0 18px; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.dir-contactos li { display: flex; align-items: center; gap: 8px; }
.dir-fila { display: grid; gap: 6px; flex: 1; margin: 0;
  grid-template-columns: 150px minmax(0, 1.2fr) 130px minmax(0, 1.3fr) auto; }
@media (max-width: 899.98px) { .dir-fila { grid-template-columns: 1fr 1fr; } }
.dir-fila input { font-size: 12.5px; padding: 4px 8px; }
.dir-solo-lectura { align-items: center; padding: 8px 10px; border: 1px solid var(--line); border-radius: var(--r-md); }
.dir-puesto { font-family: var(--font-mono); font-size: 10.5px; letter-spacing: .06em;
  text-transform: uppercase; color: var(--text-3); }
.dir-promotores { list-style: none; margin: 8px 0 0; padding: 0; font-size: 13.5px; line-height: 1.9; }

/* Pantalla de error de formulario. */
.err-caja { max-width: 60ch; margin: 40px auto; padding: 22px 26px;
  border: 1px solid color-mix(in srgb, var(--warn) 50%, transparent);
  border-radius: var(--r-lg); background: var(--surface); }
.err-tit { display: flex; align-items: baseline; gap: 8px; margin: 0 0 10px;
  font-weight: 600; font-size: 17px; }
.err-tit .ico { width: 17px; height: 17px; color: var(--warn); flex: none; }
.err-msg { margin: 0 0 16px; font-size: 14.5px; line-height: 1.55; }
.err-acciones { display: flex; gap: 10px; margin: 0 0 12px; flex-wrap: wrap; }
.usr-ejecutivo { display: block; margin-top: 3px; font-size: 11px; color: var(--text-3);
  font-family: var(--font-mono); letter-spacing: .02em; }

/* Guardado en tanda de la hoja de promotoría. */
.pv-sep-flex { flex: 1; }
.pv-guardar-todo:disabled { opacity: .45; cursor: default; }
.pv-tocada > td { background: var(--warn-bg); }
.pv-error > td { background: color-mix(in srgb, var(--danger-ink) 10%, transparent); }
.pv-aviso-malo { color: var(--danger-ink); }

/* ============================================================
   Capacitaciones (/capacitaciones)

   El tablero es el Excel que ya conocen -- tiendas por dias -- pero
   generado. Las celdas llevan la HORA, no una palomita: es el dato que la
   gente buscaba dentro de la celda en la hoja original.
   ============================================================ */
.cap-mes { font-size: 15px; min-width: 160px; text-align: center; }
.cap-cifra { margin: 4px 0 0; font-family: var(--font-display); font-size: 26px;
  font-weight: 600; line-height: 1; }
.cap-cifra span { font-family: var(--font-body); font-size: 12.5px; font-weight: 400; color: var(--text-3); }
.cap-rejilla th.cap-dia { min-width: 34px; text-align: center; font-size: 10.5px; padding: 4px 2px; }
.cap-rejilla .cap-hoy { color: var(--brand); border-bottom: 2px solid var(--brand); }
.cap-celda { text-align: center; padding: 2px; }
.cap-marca {
  display: inline-block; font-family: var(--font-mono); font-size: 10px;
  padding: 2px 4px; border-radius: 4px; white-space: nowrap;
}
.cap-realizada { background: color-mix(in srgb, var(--ok) 18%, transparent); color: var(--ok); }
.cap-programada { background: var(--surface-3); color: var(--text-2); }
.cap-cancelada { background: color-mix(in srgb, var(--danger-ink) 14%, transparent);
  color: var(--danger-ink); text-decoration: line-through; }
.cap-reprogramada { background: var(--warn-bg); color: var(--warn); }
.cap-pendiente { background: var(--surface-3); color: var(--text-3); }

/* El calendario de pared (2026-09-21). El tablero tienda x dia contesta
   "que tienda lleva un mes sin nada"; este contesta "que toca esta semana",
   que es la pregunta que se hace todos los lunes. */
.cap-vista-head { display: flex; align-items: baseline; gap: 14px; flex-wrap: wrap; }
.cap-vistas { display: flex; gap: 6px; margin-left: auto; }
.cap-vistas .activo { background: var(--surface-3); color: var(--text-1); }
.cap-cal { margin-top: 10px; }
.cap-cal-sem { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 4px; }
.cap-cal-sem + .cap-cal-sem { margin-top: 4px; }
.cap-cal-nom > div {
  font-family: var(--font-mono); font-size: 10px; text-transform: uppercase;
  letter-spacing: .14em; color: var(--text-3); padding: 0 0 6px 4px;
}
.cap-cal-dia {
  min-height: 86px; border: 1px solid var(--line); border-radius: var(--r-md);
  background: var(--surface); padding: 5px 6px 7px;
}
/* Los dias de los meses vecinos se pintan apagados y NO se dejan en blanco:
   una primera semana vacia se lee como si el mes empezara en martes. */
.cap-fuera { background: transparent; border-style: dashed; opacity: .5; }
.cap-cal-hoy { border-color: var(--brand); box-shadow: inset 0 0 0 1px var(--brand); }
.cap-cal-num {
  display: block; font-family: var(--font-mono); font-size: 11.5px;
  color: var(--text-3); margin-bottom: 4px;
}
.cap-cal-hoy .cap-cal-num { color: var(--brand); font-weight: 600; }
.cap-ev {
  display: block; position: relative; font-size: 11.5px; line-height: 1.35;
  padding: 3px 5px; border-radius: 5px; margin-bottom: 3px; text-decoration: none;
}
/* El recorte va en el texto y NO en el enlace: con overflow:hidden arriba,
   la ficha que sale al pasar el cursor se cortaba en el borde de la casilla. */
.cap-ev-txt { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cap-ev b { font-family: var(--font-mono); font-size: 10.5px; }
.cap-ev-marca { opacity: .75; font-size: 10.5px; }

/* La ficha al pasar el cursor. Reemplaza al `title` del navegador: ahi solo
   cabe una linea, tarda un segundo en aparecer y el teclado no la alcanza.
   Esta tambien sale al tabular (:focus-visible). */
.cap-tip {
  position: absolute; left: 0; top: calc(100% + 5px); z-index: 40;
  display: none; width: max-content; max-width: 260px;
  background: var(--surface); color: var(--text-1);
  border: 1px solid var(--line-hard); border-radius: var(--r-md);
  box-shadow: 0 8px 24px rgb(0 0 0 / .18); padding: 9px 11px;
  font-size: 12px; line-height: 1.5; white-space: normal; text-align: left;
}
.cap-ev:hover .cap-tip, .cap-ev:focus-visible .cap-tip { display: block; }
.cap-ev:hover, .cap-ev:focus-visible { z-index: 41; }
.cap-tip-tit { display: block; font-size: 13px; }
.cap-tip-sub { display: block; color: var(--text-3); font-size: 11.5px; margin-bottom: 5px; }
.cap-tip-dato { display: block; }
.cap-tip-dato i {
  display: inline-block; min-width: 86px; font-style: normal;
  color: var(--text-3); font-family: var(--font-mono); font-size: 10px;
  text-transform: uppercase; letter-spacing: .1em;
}
.cap-tip-nota {
  display: block; margin-top: 6px; padding-top: 6px;
  border-top: 1px solid var(--line-soft); color: var(--text-2); font-size: 11.5px;
}
/* En las dos ultimas columnas la ficha se sale de la pantalla por la
   derecha: se ancla al borde contrario. */
.cap-cal-sem > .cap-cal-dia:nth-child(n+6) .cap-tip { left: auto; right: 0; }
/* Y en los ultimos renglones se abre hacia arriba, para no empujar la pagina. */
.cap-cal-sem:nth-last-child(-n+2) .cap-tip { top: auto; bottom: calc(100% + 5px); }
@media (max-width: 720px) {
  /* En telefono siete columnas dejan celdas de 40px: se apila por dia. */
  .cap-cal-sem { grid-template-columns: 1fr; }
  .cap-cal-nom { display: none; }
  .cap-cal-dia { min-height: 0; }
  .cap-fuera:not(:has(.cap-ev)) { display: none; }
}

/* Detalle del mes: cada control en SU columna, debajo del encabezado que lo
   nombra. Los campos dejan de estirarse al ancho de la celda -- un
   desplegable de 900px para escribir "Realizada" era lo que hacia que cada
   renglon midiera tres pisos. */
.cap-detalle td { vertical-align: middle; }
.cap-detalle .pr-in { width: auto; min-width: 0; font-size: 13px; padding: 5px 8px; }
.cap-detalle select.pr-in { max-width: 168px; }
.cap-detalle .cap-asist { width: 62px; text-align: right; }
.cap-cuando b { font-family: var(--font-mono); font-size: 13px; }
.cap-cuando .muted { display: block; font-family: var(--font-mono); font-size: 10.5px; }

.cap-fila { display: flex; gap: 6px; align-items: center; margin: 0; flex-wrap: wrap; }
.cap-fila select, .cap-fila input { font-size: 12.5px; padding: 4px 8px; }
.cap-fila input[type="number"] { width: 70px; }

/* Base comun (2026-09-27): historial de cambios de un registro
   (_historial_cambios.html) y adjuntos (_adjuntos.html). Los dos se
   incrustan en pantallas de detalle, asi que no traen fondo ni margen
   propio: heredan el del bloque donde caen. */
.hc { margin-top: 28px; }
.hc-sum { cursor: pointer; list-style: none; display: flex; align-items: center; gap: 8px; }
.hc-sum::-webkit-details-marker { display: none; }
.hc-sum::after { content: "▸"; color: var(--text-3); margin-left: auto; }
.hc[open] > .hc-sum::after { content: "▾"; }
.hc-valor { max-width: 320px; overflow-wrap: anywhere; font-size: 12.5px; }

.adj { margin-top: 28px; }
.adj-lista { list-style: none; margin: 0 0 12px; padding: 0; }
.adj-item { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 12px;
            padding: 8px 0; border-bottom: 1px solid var(--line-soft); }
.adj-item > a { display: inline-flex; align-items: center; gap: 6px; overflow-wrap: anywhere; }
.adj-nota { flex-basis: 100%; color: var(--text-2); font-size: 12.5px; }
.adj-borrar { margin: 0 0 0 auto; }
.adj-subir input[type="file"] { max-width: 100%; font-size: 12.5px; }

/* ============================================================
   Ficha del embarque (/importaciones/seguimiento/<id>): guardar con
   confianza (plan 3.5). Error junto al campo, campos del Control Tower en
   solo lectura (borde punteado), campos reaplicados tras un 409 y el aviso
   de conflicto. Pestañas con ancla (plan 3.3). Todo con prefijo ct- o
   imp-ficha-: nada global.
   ============================================================ */
.ct-error { display: flex; gap: 6px; align-items: flex-start; margin-top: 4px;
  font-size: 12px; color: var(--danger-ink); }
.ct-error svg { width: 14px; height: 14px; flex-shrink: 0; margin-top: 1px; }
/* El input base de app.css (`:where(...)` con tres :not()) pesa 0,4,2: una
   regla con solo clases pierde en borde y fondo, y por eso el campo con
   error no se ponia rojo ni el de solo lectura cambiaba. Se ancla al
   #ficha-datos (1,x,x) para ganarle sin !important. */
#ficha-datos [aria-invalid="true"] { border-color: var(--danger);
  box-shadow: 0 0 0 1px var(--danger); }
/* Solo lectura (campos del Control Tower, o todo el perfil de consulta): se
   lee como DATO, no como campo. Sin borde de input, fondo --surface-2 y
   cursor normal; la nota «se capturan en el Control Tower» va ligada con
   aria-describedby. El foco con teclado se sigue viendo (app.css). */
#ficha-datos :is(input, textarea)[readonly] { background: var(--surface-2);
  border-color: transparent; color: var(--text-2); cursor: default; }
#ficha-datos input[readonly]::-webkit-calendar-picker-indicator { display: none; }
/* Textareas igual que los inputs: el navegador les da fuente monoespaciada
   y borde propio, y ningun estilo base del portal las cubre. */
.imp-ficha-seccion textarea, .imp-ficha-dform textarea {
  font-family: var(--font-body); font-size: 15px; letter-spacing: 0; text-transform: none;
  color: var(--text); background: var(--canvas); border: 1px solid var(--line);
  border-radius: var(--r-md); padding: 9px 12px; min-height: 64px; max-width: 100%;
  box-sizing: border-box; resize: vertical; transition: border-color .12s, background .12s; }
/* Un error abajo de un campo alargaba su columna y, con la fila alineada
   abajo (flex-end), subia ese input y lo desalineaba de sus vecinos. En la
   fila con error se alinea arriba: el mensaje ocupa espacio abajo sin mover
   a nadie. */
.imp-ficha-seccion .form-row:has(.ct-error) { align-items: flex-start; }
.imp-ficha-seccion .ct-reaplicado { outline: 2px solid var(--platinum); outline-offset: 1px; }
.imp-ficha-seccion + .imp-ficha-seccion { margin-top: 14px; }
.imp-ficha-seccion > .dash-section-title { margin-top: 0; }
/* Pestañas: la tira es .tabs de app.css; con JS la activa lleva
   aria-selected (patron tabs de ARIA) en lugar de aria-current. */
.imp-ficha-tabs a[aria-selected="true"] { color: var(--brand-hi); border-bottom-color: var(--brand-hi);
  font-weight: 600; }
.imp-ficha-cuenta { display: inline-block; min-width: 18px; padding: 0 6px; border-radius: 9px;
  background: var(--surface-2); color: var(--text-2); font: 600 11px/18px var(--font-mono);
  text-align: center; }
.imp-ficha-panel { scroll-margin-top: 16px; }
.imp-ficha-panel:focus { outline: none; }
/* Sin JS: todo apilado, con un separador entre secciones. */
.imp-ficha-paneles:not(.imp-ficha-js) .imp-ficha-panel + .imp-ficha-panel {
  margin-top: 28px; padding-top: 4px; border-top: 1px solid var(--line); }
.ct-aviso p { margin: 0 0 8px; }
.ct-aviso p:last-child { margin: 0; }
.ct-aviso svg { width: 14px; height: 14px; vertical-align: -2px; }
/* Campo con error posible: el mensaje va FUERA del <label> (si no, el
   lector de pantalla lo lee dos veces: en el nombre y en aria-describedby). */
.form-row .ct-campo { flex: 1 1 140px; min-width: 0; display: flex; flex-direction: column; }
.form-row .ct-campo > label { flex: 0 0 auto; }
/* Plan 3.7: tablas de la ficha ordenables con tabla-orden.js. La flecha
   dice en que sentido quedo (la de .tb-tabla, aqui para .lista). El estado
   aduanal guardado va en chip junto al formulario. */
.imp-ficha-panel th[data-orden] { color: var(--brand-hi); }
.imp-ficha-panel th[data-orden]::after { font-size: 9px; margin-left: 3px; }
.imp-ficha-panel th[data-orden="desc"]::after { content: "▼"; }
.imp-ficha-panel th[data-orden="asc"]::after { content: "▲"; }
.imp-ficha-aduana-guardada { margin: 0 0 10px; font-size: 13px; color: var(--text-2); }
/* Checklist documental de la pestaña Documentos (plan 4.1): casilla, y si
   tiene archivo, fue recibida en físico o sigue pendiente. */
.imp-ficha-docs { margin: 0 0 16px; }
.imp-ficha-docs-t { margin: 0 0 8px; font-size: 14px; font-weight: 600; }
.imp-ficha-docs-t .muted { font-weight: 400; margin-left: 6px; }
.imp-ficha-docs-lista { list-style: none; margin: 0 0 8px; padding: 0;
  display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 6px 16px; }
.imp-ficha-docs-item { display: flex; align-items: center; justify-content: space-between;
  gap: 8px; padding: 6px 0; border-bottom: 1px solid var(--line); min-width: 0; }
.imp-ficha-docs-nombre { overflow-wrap: anywhere; }
/* Miga con regreso y Anterior/Siguiente (plan 3.1) y cabecera de estado
   con stepper (plan 3.2) de la ficha del embarque. Prefijo imp-ficha-. */
.imp-ficha-miga { display: flex; align-items: center; justify-content: space-between;
  flex-wrap: wrap; gap: 6px 14px; margin: 0 0 10px; }
.imp-ficha-miga .pv-miga { margin: 0; }
.imp-ficha-vecinos { display: flex; align-items: center; gap: 4px; font-size: 12.5px; }
.imp-ficha-vecino { display: inline-flex; align-items: center; gap: 4px; min-height: 32px;
  padding: 0 8px; border-radius: 8px; color: var(--text-2); text-decoration: none; }
.imp-ficha-vecino .ico { width: 14px; height: 14px; }
.imp-ficha-vecino[href]:hover, .imp-ficha-vecino[href]:focus-visible { color: var(--brand-hi);
  background: var(--surface-2); }
.imp-ficha-vecino[aria-disabled="true"] { color: var(--text-3); opacity: .55; }
.imp-ficha-pos { font-family: var(--font-mono); font-size: 11px; color: var(--text-3);
  font-variant-numeric: tabular-nums; min-width: 4ch; text-align: center; }
@media (pointer: coarse) {
  .imp-ficha-vecino { min-height: var(--tap, 44px); min-width: var(--tap, 44px);
    justify-content: center; }
  /* Plan 2.10: todo objetivo >= 44x44 al tacto. La miga, las cifras de la
     cabecera (Documentos, Actividades, Incidencias) y «Ver costos» eran
     enlaces en linea de 11 a 28 px. */
  .imp-ficha-miga .pv-miga a, .imp-ficha-estado .ct-docs-enlace,
  .imp-ficha-estado .imp-ficha-kpi-enlace, .imp-ficha-ver-costos {
    display: inline-flex; align-items: center;
    min-height: var(--tap, 44px); min-width: var(--tap, 44px);
  }
}
/* Las 6-7 tarjetas caben en un renglon a 1440 px; en movil, de dos en dos
   con la llegada a todo lo ancho (es "la cifra"). */
.imp-ficha-estado { margin: 0 0 14px; grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); }
/* En tarjetas angostas el valor se parte en renglones en vez de salirse. */
.imp-ficha-estado .kpi-row span:last-child { white-space: normal; text-align: right; min-width: 0; }
@media (max-width: 639.98px) {
  .imp-ficha-estado { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
  .imp-ficha-estado .kpi-total { grid-column: 1 / -1; }
}
.imp-ficha-estado .imp-ficha-chip { min-height: 26px; display: flex; align-items: center; }
.imp-ficha-estado .ct-docs-enlace { font-family: var(--font-mono); font-size: 18px; }
.imp-ficha-estado .imp-ficha-kpi-enlace { color: inherit; text-decoration: none; }
.imp-ficha-estado .imp-ficha-kpi-enlace:hover,
.imp-ficha-estado .imp-ficha-kpi-enlace:focus-visible { text-decoration: underline; }
.imp-ficha-desv--tarde { color: var(--danger-ink); }
.imp-ficha-nota { color: var(--text-3); font-size: 10.5px; }
.imp-ficha-monedas span { display: block; }
.imp-ficha-pasos { list-style: none; margin: 0 0 18px; padding: 0; display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 6px; counter-reset: none; }
.imp-ficha-paso { position: relative; display: flex; flex-direction: column; align-items: center;
  gap: 3px; text-align: center; padding-top: 2px; min-width: 0; }
/* La linea que une los pasos: del centro de uno al del siguiente. */
.imp-ficha-paso + .imp-ficha-paso::before { content: ""; position: absolute; top: 15px;
  right: 50%; width: calc(100% + 6px); height: 2px; background: var(--line); z-index: 0; }
.imp-ficha-paso--hecho + .imp-ficha-paso::before { background: var(--ok); }
.imp-ficha-paso-ico { position: relative; z-index: 1; display: grid; place-items: center;
  width: 28px; height: 28px; border-radius: 50%; border: 2px solid var(--line-hard);
  background: var(--surface); color: var(--text-3); }
.imp-ficha-paso-ico .ico { width: 14px; height: 14px; }
.imp-ficha-paso--hecho .imp-ficha-paso-ico { border-color: var(--ok); background: var(--ok); color: var(--surface); }
.imp-ficha-paso--actual .imp-ficha-paso-ico { border-color: var(--brand-hi); color: var(--brand-hi); }
.imp-ficha-paso-txt { font-family: var(--font-mono); font-size: 10.5px; letter-spacing: .08em;
  text-transform: uppercase; color: var(--text-2); }
.imp-ficha-paso--actual .imp-ficha-paso-txt { color: var(--text); font-weight: 600; }
.imp-ficha-paso-fecha { font-size: 12px; color: var(--text-2); font-variant-numeric: tabular-nums; }
@media (max-width: 639.98px) {
  .imp-ficha-pasos { grid-template-columns: repeat(3, minmax(0, 1fr)); row-gap: 12px; }
  .imp-ficha-paso:nth-child(4)::before { display: none; }
  .imp-ficha-vecino span { position: absolute; width: 1px; height: 1px; overflow: hidden;
    clip: rect(0 0 0 0); white-space: nowrap; }
}

/* Ficha: altas en dialogo y estados reales (plan 3.4 y 3.6). El dialogo es
   el .tm-modal de siempre; aqui solo su rejilla, que en 390 px deja un
   campo por renglon (nunca mas de dos) y el boton que lo abre. */
.imp-ficha-altas { margin: 12px 0 4px; display: flex; gap: 8px; flex-wrap: wrap; }
.tm-modal .imp-ficha-dform { grid-template-columns: repeat(auto-fit, minmax(min(100%, 200px), 1fr)); }
/* Los <select> de los dialogos llevan .select-ctrl (flecha y tema del
   portal); aqui toman la medida y la letra de los inputs de al lado. */
.imp-ficha-dform .select-ctrl { font-family: var(--font-body); font-size: 15px; letter-spacing: 0;
  min-height: 40px; padding: 9px 32px 9px 12px; background-color: var(--canvas);
  border-radius: var(--r-md); background-position: right 12px center; max-width: 100%; }
.imp-ficha-dform .select-ctrl:hover { background-color: var(--surface-2); }
.imp-ficha-dform .hint { margin: 0; }
.imp-ficha-dcontexto { margin: 0; padding: 8px 10px; border-left: 3px solid var(--line-hard);
  background: var(--surface-2); color: var(--text-2); font-size: var(--fs-sm); overflow-wrap: anywhere; }
.imp-ficha-acciones { display: flex; gap: 6px; flex-wrap: wrap; }
.imp-ficha-acciones form { margin: 0; }
/* Actividad vencida: --danger-ink con icono y la palabra (nunca solo color). */
.imp-ficha-vencida { color: var(--danger-ink); font-weight: 600; white-space: nowrap; }
.imp-ficha-vencida .ico { width: 14px; height: 14px; vertical-align: -2px; }
.imp-ficha-vencida-txt { font-family: inherit; font-weight: 600; }
/* Embarque cerrado: aviso de solo lectura con «Reabrir». */
.imp-ficha-cerrado { display: flex; gap: 10px 16px; align-items: center; flex-wrap: wrap;
  margin: 0 0 16px; padding: 10px 14px; border: 1px solid var(--line-hard);
  border-radius: var(--r-md); background: var(--surface-2); }
.imp-ficha-cerrado p { margin: 0; flex: 1 1 260px; font-size: var(--fs-sm); line-height: 1.5; }
.imp-ficha-cerrado .ico { width: 14px; height: 14px; vertical-align: -2px; }
.imp-ficha-cerrado form { margin: 0; }
.imp-ficha-seccion :disabled { opacity: .75; cursor: not-allowed; }
