:root {
  --plata: #c9ccd1;
  --plata-clara: #f3f4f6;
  --plata-media: #dde0e4;
  --dorado: #b8923f;
  --dorado-claro: #e9d9b3;
  --dorado-oscuro: #8f6e2c;
  --negro: #16161a;
  --texto: #1c1c1f;
  --texto-suave: #6b6d72;
  --blanco: #ffffff;
  --gris-borde: #e2e3e7;
  --exito: #2f6b46;
  --error: #9c2f3d;
  --radio: 10px;
  --sombra: 0 4px 18px rgba(20, 20, 25, 0.08);
}

* { box-sizing: border-box; }

body {
  margin: 0;
  font-family: 'Segoe UI', system-ui, -apple-system, sans-serif;
  background: linear-gradient(180deg, var(--plata-clara) 0%, #ffffff 60%);
  color: var(--texto);
  overflow-x: hidden; /* red de seguridad: ningún elemento debe forzar scroll horizontal de página */
}

a { color: inherit; text-decoration: none; }

/* ---------- Iconografía (SVG lineal propio, hereda currentColor: nunca cambia la paleta) ---------- */
.icono {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
  vertical-align: -3px;
}
.icono-menu { width: 19px; height: 19px; margin-right: 10px; opacity: .85; }
.sidebar nav a:hover .icono-menu,
.sidebar nav a.active .icono-menu { opacity: 1; }
.btn .icono, a.btn .icono, button.btn .icono { margin-right: 6px; vertical-align: -3px; }
.btn-sm .icono { width: 15px; height: 15px; margin-right: 4px; }
.icono-solo { margin-right: 0; }
/* Ícono de la propia pregunta al capturar/llenar un formulario (Promotor, Encuestador,
   Soporte, formulario público) -- mismo ícono elegido en el constructor, dorado, nunca
   ningún otro color (a diferencia de un emoji, un SVG con currentColor sí puede pintarse). */
.icono-pregunta { margin-right: 6px; vertical-align: -3px; color: var(--dorado); }

/* ---------- Login ---------- */
.login-wrap {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  background: radial-gradient(circle at top right, var(--plata-media), transparent 55%),
              radial-gradient(circle at bottom left, var(--dorado-claro), transparent 55%),
              var(--plata-clara);
}

.login-card {
  width: 100%;
  max-width: 380px;
  background: var(--blanco);
  border-radius: var(--radio);
  box-shadow: var(--sombra);
  padding: 40px 32px;
  border-top: 4px solid var(--dorado);
}

.login-card h1 {
  font-size: 1.3rem;
  margin: 0 0 4px;
  letter-spacing: 0.3px;
  color: var(--negro);
}

.login-card p.subtitle {
  color: var(--texto-suave);
  margin: 0 0 28px;
  font-size: 0.9rem;
}

.form-group { margin-bottom: 18px; }

.campo-territorial { position: relative; }
.territorio-resultados {
  position: absolute;
  z-index: 20;
  top: 100%;
  left: 0;
  right: 0;
  background: var(--blanco);
  border: 1px solid var(--gris-borde);
  border-radius: 8px;
  margin-top: 4px;
  max-height: 240px;
  overflow-y: auto;
  box-shadow: 0 4px 14px rgba(0,0,0,0.12);
}
.territorio-item {
  padding: 10px 12px;
  font-size: 0.88rem;
  cursor: pointer;
  border-bottom: 1px solid var(--plata-clara);
}
.territorio-item:last-child { border-bottom: none; }
.territorio-item:hover { background: var(--plata-clara); }
.territorio-item.territorio-vacio { color: var(--texto-suave); cursor: default; }
.territorio-item.territorio-vacio:hover { background: transparent; }

label {
  display: block;
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--texto-suave);
  margin-bottom: 6px;
  text-transform: uppercase;
  letter-spacing: 0.4px;
}

input[type="text"],
input[type="password"],
input[type="email"],
input[type="number"],
input[type="date"],
input[type="tel"],
select,
textarea {
  width: 100%;
  padding: 11px 13px;
  border: 1px solid var(--gris-borde);
  border-radius: 8px;
  font-size: 0.95rem;
  background: var(--plata-clara);
  transition: border-color .15s, box-shadow .15s;
  font-family: inherit;
  color: var(--texto);
}

input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--dorado);
  box-shadow: 0 0 0 3px rgba(184, 146, 63, 0.18);
  background: var(--blanco);
}

fieldset { border: 1px solid var(--gris-borde); border-radius: 8px; padding: 14px 16px; margin-bottom: 16px; }
legend { padding: 0 6px; font-weight: 600; font-size: .85rem; color: var(--texto-suave); text-transform: uppercase; }
.checkbox-row { display: flex; align-items: center; gap: 10px; margin-bottom: 4px; padding: 6px 4px; min-height: 40px; }
.checkbox-row input { width: 20px; height: 20px; flex-shrink: 0; cursor: pointer; }
.checkbox-row label { cursor: pointer; }

/* ---------- Mostrar/ocultar contraseña ---------- */
.password-wrap { position: relative; }
.password-wrap input[type="password"],
.password-wrap input[type="text"] { padding-right: 44px; }
.password-toggle {
  position: absolute;
  right: 6px;
  top: 50%;
  transform: translateY(-50%);
  background: none;
  border: none;
  cursor: pointer;
  padding: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--texto-suave);
  border-radius: 6px;
}
.password-toggle:hover { color: var(--negro); background: var(--plata-clara); }
.password-toggle svg { width: 20px; height: 20px; }
.password-toggle .icono-ocultar { display: none; }
.password-toggle.is-visible .icono-mostrar { display: none; }
.password-toggle.is-visible .icono-ocultar { display: block; }

.btn {
  display: inline-block;
  border: none;
  cursor: pointer;
  padding: 11px 18px;
  border-radius: 8px;
  font-weight: 600;
  font-size: 0.9rem;
  letter-spacing: 0.3px;
  transition: transform .1s, box-shadow .15s, opacity .15s;
}

.btn-primary {
  background: linear-gradient(135deg, var(--dorado), var(--dorado-oscuro));
  color: var(--blanco);
}
.btn-primary:hover { box-shadow: 0 6px 16px rgba(184, 146, 63, 0.35); }

.btn-secondary {
  background: var(--blanco);
  border: 1px solid var(--gris-borde);
  color: var(--texto);
}
.btn-secondary:hover { border-color: var(--negro); }

.btn-oscuro {
  background: var(--negro);
  color: var(--blanco);
}

.btn-peligro {
  background: var(--blanco);
  border: 1px solid var(--error);
  color: var(--error);
}

.btn-sm { padding: 9px 14px; font-size: 0.8rem; min-height: 38px; display: inline-flex; align-items: center; }
.btn-block { width: 100%; }

.alert {
  padding: 12px 14px;
  border-radius: 8px;
  font-size: 0.88rem;
  margin-bottom: 18px;
}
.alert-error { background: #f7e7e9; color: var(--error); border: 1px solid #e6c1c6; }
.alert-success { background: #e9f2ec; color: var(--exito); border: 1px solid #c3ddc9; }

/* ---------- Layout con panel ---------- */
.app-shell {
  display: grid;
  grid-template-columns: 240px 1fr;
  min-height: 100vh;
}

.sidebar {
  background: linear-gradient(180deg, var(--negro), #232327);
  color: #e8e8ea;
  padding: 24px 18px;
}

.sidebar-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.sidebar .brand {
  display: block;
  font-weight: 700;
  letter-spacing: 0.4px;
  color: var(--dorado-claro);
  margin-bottom: 28px;
  font-size: 1.05rem;
  cursor: pointer;
}
.sidebar .brand:hover { color: var(--dorado); }

.menu-toggle {
  display: none;
  background: none;
  border: 1px solid rgba(255,255,255,0.2);
  border-radius: 8px;
  color: #e8e8ea;
  width: 44px;
  height: 44px;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  flex-shrink: 0;
}
.menu-toggle svg { width: 22px; height: 22px; }

.nav-grupo-titulo {
  font-size: 0.74rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.6px;
  color: var(--dorado-claro);
  margin: 18px 0 8px;
  padding: 0 12px;
  border-top: 1px solid rgba(255,255,255,0.1);
  padding-top: 14px;
}
.nav-grupo-titulo:first-child { margin-top: 0; border-top: none; padding-top: 0; }

.sidebar nav a {
  display: block;
  padding: 11px 12px 11px 22px;
  border-radius: 8px;
  margin-bottom: 4px;
  margin-left: 6px;
  border-left: 2px solid rgba(255,255,255,0.08);
  color: #cfcfd2;
  font-size: 0.87rem;
  min-height: 44px;
  display: flex;
  align-items: center;
}
.sidebar nav a:hover,
.sidebar nav a.active {
  background: rgba(184, 146, 63, 0.18);
  color: var(--dorado-claro);
  border-left-color: var(--dorado);
}
.sidebar nav a.nav-logout {
  margin-top: 14px;
  margin-left: 0;
  padding-left: 12px;
  border-left: none;
  opacity: .8;
  border-top: 1px solid rgba(255,255,255,0.12);
  padding-top: 16px;
  border-radius: 0;
}

.sidebar .role-tag {
  display: inline-block;
  background: var(--dorado);
  color: var(--negro);
  font-size: 0.7rem;
  font-weight: 700;
  padding: 3px 9px;
  border-radius: 20px;
  margin-bottom: 22px;
  text-transform: uppercase;
}

.main-content {
  padding: 28px 32px;
  /* Un elemento hijo de CSS grid no se encoge por debajo del ancho intrínseco de su
     contenido (min-width:auto por defecto). Sin esto, una tabla ancha empuja todo el
     grid (.app-shell) más allá del viewport en vez de activar el scroll interno de
     .table-scroll, y como body tiene overflow-x:hidden como red de seguridad, el
     contenido queda recortado (botones "cortados") en vez de accesible por scroll. */
  min-width: 0;
  /* Evita que el panel se estire de borde a borde en monitores grandes; se centra
     dentro del espacio disponible junto al sidebar. */
  max-width: 1400px;
}

/* CAUSA RAÍZ REAL (confirmada con Chrome real vía CDP, midiendo clientWidth/scrollWidth
   antes y después, no por inspección visual): un margin:auto en un item de CSS Grid le hace
   perder su comportamiento "stretch" al track y en vez de eso el navegador lo dimensiona
   según el ancho de su CONTENIDO -- aquí, la tabla ancha de .table-scroll. Eso hacía que
   .main-content, .panel y .table-scroll se inflaran todos hasta el ancho de la tabla (medido:
   820px en un viewport de 390px) en vez de quedarse en el ancho real del track del grid. Como
   resultado, .table-scroll.clientWidth == .table-scroll.scrollWidth (ambos ~760px): NUNCA
   hubo overflow real que desplazar, así que ningún gesto -ni táctil ni asignar scrollLeft por
   JS- podía mover nada. min-width:0 (arriba) no alcanza a evitar esto porque no es un problema
   de "no encogerse", es un problema de "crecer más allá del track por el margin:auto".
   El centrado en monitores grandes (el motivo original del margin:auto) solo hace falta
   cuando existe el sidebar de escritorio -- en el grid de una sola columna de móvil/tablet
   (@media max-width:820px) el track YA ocupa el 100% del ancho disponible, así que centrar
   ahí no solo es innecesario: es lo que rompía el scroll de TODAS las tablas de la
   plataforma. Se limita a viewports de escritorio, donde se verificó (Chrome real, 1920px)
   que el resultado es idéntico, sin ningún cambio visual. */
@media (min-width: 821px) {
  .main-content {
    margin: 0 auto;
  }
}

/* Red de seguridad GLOBAL y centralizada: ningún hijo DIRECTO de los 4 contenedores
   estructurales que usa toda la plataforma puede ser más ancho que su propio padre. Es la
   regla raíz que implementa "en móvil, ningún elemento debe desbordar la página" sin tener
   que perseguir cada pantalla una por una — cualquier bloque, botón, badge o formulario nuevo
   que se agregue directamente dentro de .main-content/.panel/.topbar/.toolbar queda protegido
   automáticamente, sin escribir una regla específica para él.
   NO se aplica a nietos/descendientes más profundos: .table-scroll (que SÍ es un hijo directo
   de .panel) sigue limitado a 100% de ancho por esta regla, pero la <table> de adentro
   conserva su min-width:640px y su propio scroll interno — el desbordamiento controlado que
   ya usan las tablas de muchas columnas no se ve afectado. */
.main-content > *,
.panel > *,
.topbar > *,
.toolbar > * {
  max-width: 100%;
}

/* El título y el grupo de botones quedan SIEMPRE en filas separadas (columna), en vez
   de intentar compartir una fila y confiar en que flexbox decida encoger/envolver
   según el ancho disponible. Esto no depende de ningún cálculo de ancho ni de ningún
   punto de quiebre — es así en cualquier tamaño de pantalla, así que no hay forma de
   que un botón quede cortado por falta de espacio horizontal. */
.topbar {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 12px;
  margin-bottom: 26px;
}

.topbar h1 { font-size: 1.4rem; margin: 0; color: var(--negro); }

/* Grupo de botones de acción: su propia fila, envolviendo internamente los botones
   que no quepan en vez de recortarlos. Alineados a la IZQUIERDA (no a la derecha):
   con justify-content:flex-end el último botón queda pegado exacto al borde derecho
   del contenedor, sin ningún margen de tolerancia — cualquier diferencia mínima de
   medición (fuente, subpíxeles) lo recorta. Con flex-start hereda el mismo margen
   izquierdo de 32px de .main-content que ya usan el título y el resto del contenido,
   así que siempre hay aire de sobra, sin depender de que el cálculo sea exacto.
   min-width:0 evita que, al ser un item flex de .topbar, se niegue a encogerse por
   debajo del ancho de su contenido (causa real de los cortes anteriores). */
.topbar > div {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-start;
  gap: 8px;
  min-width: 0;
  max-width: 100%;
}

.cards-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 18px;
  margin-bottom: 30px;
}

.stat-card {
  background: var(--blanco);
  border-radius: var(--radio);
  padding: 20px;
  box-shadow: var(--sombra);
  border-left: 4px solid var(--dorado);
}
.stat-card .num { font-size: 1.9rem; font-weight: 700; color: var(--negro); }
.stat-card .label { color: var(--texto-suave); font-size: 0.85rem; margin-top: 4px; }

.panel {
  background: var(--blanco);
  border-radius: var(--radio);
  box-shadow: var(--sombra);
  padding: 22px;
  margin-bottom: 22px;
  overflow-wrap: break-word;
}

.panel h2, .panel h3 { color: var(--negro); margin-top: 0; }

table { width: 100%; border-collapse: collapse; font-size: 0.9rem; }
/* Espaciado consistente entre botones/formularios de acciones dentro de una celda,
   para que sean fáciles de tocar por separado en pantallas táctiles. */
td form { display: inline-block; margin: 2px 4px 2px 0; }
td > a.btn { margin: 2px 4px 2px 0; display: inline-flex; }
.table-scroll { width: 100%; overflow-x: auto; -webkit-overflow-scrolling: touch; }
.table-scroll table { min-width: 640px; }
th, td { padding: 10px 12px; text-align: left; border-bottom: 1px solid var(--gris-borde); overflow-wrap: break-word; vertical-align: top; }
th { color: var(--texto-suave); text-transform: uppercase; font-size: 0.75rem; letter-spacing: 0.3px; }
tr:hover td { background: var(--plata-clara); }

.badge {
  display: inline-block;
  padding: 3px 10px;
  border-radius: 20px;
  font-size: 0.72rem;
  font-weight: 700;
  text-transform: uppercase;
}
.badge-activo { background: #e9f2ec; color: var(--exito); }
.badge-inactivo { background: #f2f2f3; color: var(--texto-suave); }
.badge-publico { background: var(--dorado-claro); color: var(--dorado-oscuro); }
.badge-privado { background: var(--plata-media); color: var(--texto); }

.toolbar { display: flex; gap: 10px; flex-wrap: wrap; margin-bottom: 18px; align-items: end; }
.toolbar .form-group { margin-bottom: 0; min-width: 160px; flex: 1 1 160px; }

.field-row {
  display: grid;
  grid-template-columns: 1fr 1fr 140px auto;
  gap: 10px;
  align-items: center;
  padding: 10px;
  border: 1px solid var(--gris-borde);
  border-radius: 8px;
  margin-bottom: 8px;
  background: var(--plata-clara);
}

/* Tarjeta de pregunta del constructor de formularios (Soporte). .campo-card sobreescribe el
   .field-row de arriba (que se conserva por si algo más lo usa) con un layout de 2 franjas:
   cabecera compacta (arrastre + icono + vista previa + acciones) y cuerpo con los campos reales. */
.field-row.campo-card {
  display: block;
  padding: 0;
  overflow: hidden;
}
.campo-card-cabecera {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  border-bottom: 1px solid var(--gris-borde);
}
.campo-drag-handle {
  cursor: grab;
  color: var(--texto-suave);
  font-size: 1.1rem;
  line-height: 1;
  user-select: none;
  flex-shrink: 0;
  padding: 4px;
}
.campo-drag-handle:active { cursor: grabbing; }
.campo-icono-preview {
  flex-shrink: 0;
  width: 24px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--dorado);
  font-size: 1.2rem;
}
.campo-icono-preview .icono { width: 18px; height: 18px; }
.campo-titulo-preview {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--negro);
  font-weight: 600;
}
.campo-card-acciones { display: flex; gap: 6px; flex-shrink: 0; }
.campo-card-cuerpo {
  display: grid;
  grid-template-columns: 1.4fr 110px 1.1fr 1.1fr;
  gap: 12px;
  padding: 12px;
}
.campo-icono-presets { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 6px; }
.campo-icono-boton {
  border: 1px solid var(--gris-borde);
  background: var(--blanco);
  border-radius: 6px;
  width: 32px;
  height: 32px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--texto);
  cursor: pointer;
  padding: 0;
}
.campo-icono-boton .icono { width: 16px; height: 16px; }
.campo-icono-boton:hover { border-color: var(--dorado); }
.campo-icono-boton.activo {
  border-color: var(--dorado);
  background: var(--dorado-claro);
  color: var(--dorado-oscuro);
}
.field-row.campo-card.arrastrando { opacity: .4; }

/* Lista de formularios de Promotor/Encuestador ("Registrar promovido" / "Realizar encuesta"),
   compartida vía partials/lista_formularios.php. Se usan filas tipo tarjeta en vez de una
   <table> de 3 columnas: así "Formulario" y sus botones de Acciones siempre pueden quedar
   juntos y visibles en la misma línea (o envolver entre sí sin salirse de la pantalla) incluso
   en celulares angostos, sin depender nunca de scroll horizontal — la Descripción va debajo,
   nunca compite por el ancho con los botones. */
.lista-formularios { display: flex; flex-direction: column; gap: 10px; }
.fila-formulario {
  border: 1px solid var(--gris-borde);
  border-radius: 8px;
  padding: 12px 14px;
}
.fila-formulario-principal {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px 14px;
  flex-wrap: wrap;
}
.fila-formulario-titulo { font-weight: 600; color: var(--negro); }
.fila-formulario-acciones { display: flex; gap: 6px; flex-wrap: wrap; flex-shrink: 0; }
.fila-formulario-descripcion { color: var(--texto-suave); font-size: 0.85rem; margin: 8px 0 0; }

/* "Mis promovidos" / "Mis encuestas" (Promotor y Encuestador), vía
   partials/lista_mis_registros.php. Desde/Hasta comparten una fila (mitad y mitad) en vez de
   ocupar 2 filas completas — ya ahorra espacio vertical en cualquier ancho, no solo celular. */
.filtro-fechas { display: flex; gap: 10px; flex: 1 1 160px; }
.filtro-fechas .form-group { flex: 1 1 0; min-width: 0; }

/* Escritorio/tablet: tabla real de siempre. Celular: se oculta y se muestra la lista de
   tarjetas de abajo — nunca las dos al mismo tiempo, nunca con scale()/zoom. La tabla en sí NO
   cambia (misma <table>, mismas columnas) en ningún ancho por encima del punto de quiebre. */
.lista-registros-movil { display: none; }

@media (max-width: 640px) {
  .tabla-registros-desktop { display: none; }
  .lista-registros-movil { display: flex; flex-direction: column; gap: 10px; }

  /* Controles de filtro más compactos SOLO en esta pantalla (no afecta otros .toolbar de la
     plataforma), para que 4 filtros + botón no ocupen media pantalla en un celular. */
  .toolbar-registros input,
  .toolbar-registros select { padding: 8px 11px; font-size: 0.88rem; }
  .toolbar-registros .form-group { margin-bottom: 0; }
  .toolbar-registros label { font-size: 0.82rem; margin-bottom: 2px; }

  /* Tarjeta de estadística ("Total registrados por ti") más compacta en celular — el número y
     la etiqueta ocupaban demasiado alto para ser solo un dato de referencia. */
  .cards-grid-compacta { margin-bottom: 14px; }
  .cards-grid-compacta .stat-card { padding: 12px 16px; display: flex; align-items: baseline; gap: 10px; }
  .cards-grid-compacta .stat-card .num { font-size: 1.3rem; }
  .cards-grid-compacta .stat-card .label { margin-top: 0; font-size: 0.8rem; }
}

.tarjeta-registro {
  border: 1px solid var(--gris-borde);
  border-radius: 8px;
  padding: 12px 14px;
}
.tarjeta-registro-id { font-weight: 700; color: var(--negro); margin-bottom: 8px; }
.tarjeta-registro-datos { margin: 0 0 12px; }
.tarjeta-registro-datos > div {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  padding: 5px 0;
  border-bottom: 1px solid var(--gris-borde);
  font-size: 0.88rem;
}
.tarjeta-registro-datos > div:last-child { border-bottom: none; }
.tarjeta-registro-datos dt { color: var(--texto-suave); flex-shrink: 0; }
.tarjeta-registro-datos dd { margin: 0; text-align: right; overflow-wrap: anywhere; }
.tarjeta-registro-acciones { display: flex; gap: 6px; flex-wrap: wrap; }
.tarjeta-registro-acciones .btn,
.tarjeta-registro-acciones form { flex: 1 1 0; min-width: 84px; }
.tarjeta-registro-acciones .btn { width: 100%; justify-content: center; text-align: center; }
.tarjeta-registro-acciones form .btn { width: 100%; }

.share-box {
  background: var(--plata-clara);
  border: 1px dashed var(--dorado);
  border-radius: 8px;
  padding: 12px 14px;
  font-size: 0.85rem;
  overflow-wrap: break-word;
}

.detalle-lista { list-style: none; padding: 0; margin: 0; }
.detalle-lista li { padding: 10px 0; border-bottom: 1px solid var(--gris-borde); }
.detalle-lista .k { color: var(--texto-suave); font-size: 0.78rem; text-transform: uppercase; letter-spacing: .3px; display:block; margin-bottom:2px;}

.pagination { display: flex; gap: 6px; margin-top: 16px; }
.pagination a, .pagination span {
  padding: 6px 12px; border-radius: 6px; border: 1px solid var(--gris-borde); font-size: 0.85rem;
}
.pagination .current { background: var(--negro); color: var(--blanco); border-color: var(--negro); }

/* ---------- Gráficas (CSS/SVG puro, sin dependencias externas) ---------- */
.stats-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 18px;
  margin-bottom: 22px;
}

.bar-chart { display: flex; flex-direction: column; gap: 10px; }
.bar-row { display: grid; grid-template-columns: 120px 1fr 46px; align-items: center; gap: 10px; font-size: 0.85rem; }
.bar-track { background: var(--plata-clara); border-radius: 6px; height: 14px; overflow: hidden; }
.bar-fill { background: linear-gradient(90deg, var(--dorado-oscuro), var(--dorado)); height: 100%; border-radius: 6px; }
.bar-label { color: var(--texto); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bar-value { text-align: right; color: var(--texto-suave); font-weight: 600; }

.donut-wrap { display: flex; align-items: center; gap: 20px; flex-wrap: wrap; }
.donut {
  width: 140px; height: 140px; border-radius: 50%;
  flex-shrink: 0;
}
.donut-legend { display: flex; flex-direction: column; gap: 6px; font-size: 0.85rem; }
.donut-legend .item { display: flex; align-items: center; gap: 8px; }
.donut-legend .dot { width: 10px; height: 10px; border-radius: 50%; display: inline-block; }

.sparkline { width: 100%; height: 90px; }
.sparkline polyline { fill: none; stroke: var(--dorado); stroke-width: 2.5; }
.sparkline circle { fill: var(--negro); }
.sparkline .eje { stroke: var(--gris-borde); stroke-width: 1; }

@media (max-width: 820px) {
  /* Causa raíz REAL del espacio negro debajo del encabezado en móvil (corregido en la ronda
     anterior con align-content, que ataca el reparto de espacio ENTRE filas — pero el hueco no
     es un espacio entre filas, es la propia caja de .sidebar, con su fondo oscuro, ESTIRÁNDOSE
     para llenar el alto de su fila). Eso lo controla align-items/align-self, no align-content:
     todo elemento de grid tiene align-self:stretch por defecto, así que el .sidebar se estira
     verticalmente para ocupar toda su fila implícita — y como .app-shell tiene min-height:100vh,
     esa fila puede ser mucho más alta que el contenido real del sidebar en cualquier pantalla
     con poco contenido (ej. un dashboard recién cargado). align-items:start evita que CUALQUIER
     elemento del grid (sidebar o main-content) se estire más allá de su propio contenido — se
     conserva align-content:start como refuerzo adicional para el reparto entre filas. */
  .app-shell { grid-template-columns: 1fr; align-content: start; align-items: start; }

  .sidebar {
    padding: 10px 16px;
    position: relative;
    z-index: 100;
  }
  .sidebar-top { margin-bottom: 0; }
  .sidebar .brand { margin-bottom: 0; font-size: 1rem; }
  .sidebar .role-tag { display: none; }
  .menu-toggle { display: flex; }

  .sidebar nav {
    display: none;
    flex-direction: column;
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    background: var(--negro);
    padding: 10px 14px 18px;
    box-shadow: 0 12px 24px rgba(0,0,0,0.28);
    max-height: calc(100vh - 60px);
    overflow-y: auto;
  }
  .sidebar.sidebar-abierto nav { display: flex; }
  .sidebar nav a { white-space: normal; }

  .main-content { padding: 16px; }
  .field-row { grid-template-columns: 1fr; }
  .campo-card-cuerpo { grid-template-columns: 1fr; }
  .bar-row { grid-template-columns: 90px 1fr 36px; font-size: 0.78rem; }
  .donut-wrap { flex-direction: column; align-items: flex-start; }
  .stats-grid { grid-template-columns: 1fr; }
}

@media (max-width: 480px) {
  .main-content { padding: 14px; }
  .topbar h1 { font-size: 1.2rem; }
  .login-card { padding: 28px 20px; }
}

/* ---------- Refuerzo responsive adicional (pantallas de celular: 320–480px) ---------- */
@media (max-width: 640px) {
  /* Filtros de búsqueda: se reorganizan verticalmente en vez de quedar apretados uno junto al otro.
     Se usa ">" (solo hijos DIRECTOS) a propósito: si esta regla alcanzara también a subgrupos
     anidados dentro del toolbar (ej. .filtro-fechas, que agrupa 2 campos en una sola fila),
     los forzaría a min-width:100% cada uno y, al no caber ambos en una fila sin envolver,
     el segundo se desborda hacia la derecha — así se rompió "Hasta" en Mis promovidos. Un
     subgrupo así ya controla su propio responsive; el toolbar no debe pisarlo. */
  .toolbar > .form-group { min-width: 100%; flex-basis: 100%; }
  .toolbar > .form-group > button,
  .toolbar > button { width: 100%; }

  /* Encabezados de sección: título y botones de acción apilados, cada botón a ancho completo
     para que sea fácil de tocar sin apuntar con precisión.
     IMPORTANTE: se usa display:block (no flex) a propósito. display:flex + flex-direction:column
     seguía dejando casos reales sin cubrir (ej. Conversaciones) porque un item de flex conserva
     min-width:auto por defecto: si el contenido (ej. "Volver a Mensajería" + icono) no cabe, el
     item puede negarse a encogerse por debajo de su propio ancho mínimo en vez de respetar el
     100% del padre, y como el padre no tiene overflow propio, ese sobrante queda recortado por
     el overflow-x:hidden de body sin ninguna forma de alcanzarlo. display:block no tiene esa
     ambigüedad: un bloque con width:100% JAMÁS excede el ancho de su contenedor por definición
     de la especificación — el texto que no quepa se envuelve dentro del propio botón, nunca se
     desborda. */
  .topbar { flex-direction: column; align-items: stretch; }
  .topbar > div { display: block; width: 100%; }
  .topbar > div > * { display: block; width: 100%; margin-bottom: 8px; }
  .topbar > div > *:last-child { margin-bottom: 0; }
  .topbar .btn, .topbar a.btn { width: 100%; text-align: center; white-space: normal; }

  /* Tarjetas de estadísticas: una sola columna, más legible que forzar 2 columnas angostas. */
  .cards-grid { grid-template-columns: 1fr; }

  /* Acciones sueltas fuera de una tabla (ej. botones "Aprobar"/"Cancelar" en un panel):
     cada una a todo lo ancho para que sea fácil de tocar. */
  td form, td > a.btn, td > button.btn,
  td > div > a.btn, td > div > button.btn { display: block; width: 100%; margin: 4px 0; }

  /* Excepción: dentro de una tabla con muchas filas (.table-scroll), se conserva el patrón
     compacto y desplazable horizontalmente — apilar 5-6 botones por fila en una lista larga
     sería peor que poder deslizar hacia los lados. Mayor especificidad, así que gana sobre
     la regla general de arriba. */
  .table-scroll td form,
  .table-scroll td > a.btn,
  .table-scroll td > button.btn,
  .table-scroll td > div > a.btn,
  .table-scroll td > div > button.btn { display: inline-block; width: auto; margin: 2px 4px 2px 0; }

  .panel { padding: 16px; }
  .detalle-lista li { display: flex; flex-direction: column; }
}

@media (max-width: 360px) {
  .login-card { padding: 24px 16px; }
  .stat-card { padding: 16px; }
  .btn { padding: 10px 14px; font-size: 0.85rem; }
}

/* ================== Listados extensos compactos (móvil) ==================
   Componente reutilizable para las pantallas: Promotor->Inicio, Formularios,
   Promovidos (admin), Conversaciones. Usa clases NUEVAS y propias
   (.fila-acciones, .txt-corto, .txt-largo) en vez de tocar .table-scroll,
   .toolbar o .topbar directamente, para no alterar el comportamiento ya
   funcional de ninguna otra pantalla de la plataforma que reutiliza esos
   componentes globales. Estas clases solo existen en el HTML de las vistas
   listadas arriba, así que no tienen ningún efecto en el resto del sitio.

   .fila-acciones: agrupa los botones de una celda "Acciones" en una sola
   fila que nunca se apila verticalmente. Si la fila completa no cabe en el
   ancho del celular, el usuario la alcanza deslizando la <table> dentro de
   su .table-scroll (el contenedor sigue siendo el mismo de siempre: la
   página nunca se desplaza, solo la tabla).

   .txt-largo / .txt-corto: par de textos alternativos dentro de un mismo
   botón. En escritorio se ve .txt-largo (el texto actual, sin cambios) y
   .txt-corto permanece oculto; en móvil se invierte. Así el botón ocupa
   menos espacio en pantallas pequeñas sin cambiar el diseño de escritorio. */
.fila-acciones {
  display: flex;
  flex-wrap: nowrap;
  gap: 6px;
}
.fila-acciones .btn,
.fila-acciones > form,
.fila-acciones > a.btn,
.fila-acciones > button.btn {
  flex-shrink: 0;
  white-space: nowrap;
}

.txt-corto { display: none; }

@media (max-width: 640px) {
  .txt-largo { display: none; }
  .txt-corto { display: inline; }

  .fila-acciones .btn,
  .fila-acciones button.btn {
    padding: 7px 10px;
    font-size: 0.78rem;
  }
}

/* ================== Promotor -> Inicio: "Registros recientes" ==================
   Exclusivo de esta tarjeta (promotor/dashboard.php). Todas las clases llevan el
   prefijo/ámbito ".registros-recientes" para que no puedan afectar ninguna otra
   tabla ni pantalla de la plataforma.

   .registros-recientes.table-scroll table: la tabla de esta tarjeta solo tiene
   2-3 columnas cortas (a diferencia de las tablas anchas de Formularios/Promovidos/
   etc.), así que se le quita el min-width:640px que sí necesitan esas otras tablas
   -- si no, esta tarjeta forzaría scroll horizontal innecesario en el celular
   incluso cuando su contenido cabe perfectamente. .table-scroll (overflow-x:auto)
   se conserva sin tocar: si en el futuro se agregan más columnas y el contenido
   ya no cabe, el scroll horizontal EXCLUSIVO de esta tarjeta vuelve a activarse
   solo, sin ningún cambio adicional.

   .col-hora / .hora-inline / .txt-hora-header: en escritorio se ven las 3 columnas
   de siempre (Fecha | Hora | Formulario), sin ningún cambio. En móvil (≤640px) la
   columna "Hora" se oculta y su valor aparece unido a la fecha en la misma celda
   ("25/08/2026 · 18:18"): el dato no se pierde, solo se reubica en la celda vecina
   para que la tarjeta quede compacta sin recortar ni encoger el texto. */
.registros-recientes.table-scroll table {
  min-width: 0;
  width: 100%;
}
.registros-recientes .hora-inline { display: none; }
.registros-recientes .txt-hora-header { display: none; }

@media (max-width: 640px) {
  .registros-recientes .col-hora { display: none; }
  .registros-recientes .hora-inline { display: inline; }
  .registros-recientes .txt-hora-header { display: inline; }
}

/* ================== Administrador -> Formularios: botones compactos (móvil) ==================
   Exclusivo de app/views/soporte/formularios/index.php.

   Diagnóstico: los botones de Acciones ya usan .btn-sm, que fija min-height:38px
   como tamaño mínimo de toque táctil para TODA la plataforma (línea 211). La
   compactación de .fila-acciones de una ronda anterior solo bajaba padding/font-size
   en móvil, pero nunca podía bajar de esos 38px de alto por botón -- por eso la fila
   de 5 botones (Ver/Editar/Duplicar/Desactivar/Eliminar) seguía viéndose alta. No se
   puede bajar min-height de .btn-sm ni de .fila-acciones de forma global sin afectar
   otras pantallas (.fila-acciones también la usa Promovidos), así que aquí se usa una
   clase nueva y exclusiva de esta vista, con mayor especificidad, que sí baja
   min-height solo para estos botones. */
@media (max-width: 640px) {
  .acciones-formularios {
    gap: 4px;
  }
  .acciones-formularios .btn,
  .acciones-formularios button.btn {
    min-height: 30px;
    padding: 5px 9px;
    font-size: 0.72rem;
  }
  .acciones-formularios .btn .icono {
    width: 13px;
    height: 13px;
    margin-right: 3px;
  }

  /* Botones superiores (Archivados / + Nuevo): la regla general de arriba
     (.topbar > div > *{width:100%}, .topbar .btn{width:100%}) apila los botones a ancho
     completo en TODAS las pantallas -- correcto para el resto de la plataforma, pero aquí
     se pide justo lo contrario: en una sola fila, compactos, sin ocupar todo el ancho. El
     contenedor ya es "display:flex" (estilo en línea en la vista, no se toca), así que basta
     con devolverle "width:auto" a los botones -- un item de flex con ancho automático se
     acomoda junto a los demás en la misma fila sin necesitar nada más. Selectores con 3
     clases para ganar sin tocar la regla general de arriba, que sigue intacta para las
     demás pantallas. */
  .topbar .topbar-formularios-acciones > * {
    width: auto;
    margin-bottom: 0;
  }
  .topbar .topbar-formularios-acciones .btn {
    width: auto;
    padding: 9px 12px;
    font-size: 0.8rem;
    white-space: nowrap;
  }
}

/* ================== Administrador -> Formularios: contenedor de scroll dedicado ==================
   Exclusivo de app/views/soporte/formularios/index.php. NO se modifica .table-scroll (línea
   420-421): esa regla sigue intacta, sin cambios, para el resto de la plataforma. Mismo patrón
   exacto que ya usa .table-scroll en todas las demás pantallas (width:100% + overflow-x:auto en
   el contenedor, min-width en la tabla interna) -- solo con un min-width mayor, porque esta
   tabla tiene 7 columnas y su columna Acciones sola ya tiene 5 botones. Selector con las dos
   clases combinadas para que gane sobre ".table-scroll table" sin depender del orden del archivo. */
.table-scroll.tabla-formularios-scroll {
  width: 100%;
  max-width: 100%;
  overflow-x: auto;
}
.table-scroll.tabla-formularios-scroll > table {
  min-width: 760px;
}

/* ================== Mensajería -> Conversaciones: bandeja de chat ==================
   Exclusivo de app/views/mensajeria/conversaciones.php + partials/bandeja_conversaciones_lista.php.
   Todas las clases son nuevas y usan el prefijo bandeja- o chat- -- no se toca ninguna regla
   general (.panel, .main-content, .table-scroll, etc.), así que esto no puede afectar ninguna
   otra pantalla. Altura acotada (no 100vh) a propósito: evita repetir el problema de .main-content
   con CSS Grid ya resuelto antes en la plataforma -- el chat vive DENTRO del flujo normal de la
   página, con su propio scroll interno, nunca intenta ocupar el viewport completo. */
.bandeja-conversaciones {
  display: grid;
  grid-template-columns: 340px 1fr;
  gap: 18px;
  background: var(--blanco);
  border-radius: var(--radio);
  box-shadow: var(--sombra);
  overflow: hidden;
  height: min(78vh, 720px);
  min-height: 480px;
}

/* ---- Panel izquierdo: lista ---- */
.bandeja-lista {
  display: flex;
  flex-direction: column;
  border-right: 1px solid var(--gris-borde);
  min-width: 0;
  overflow: hidden;
}
.bandeja-lista-cabecera {
  padding: 16px 16px 0;
}
.bandeja-lista-cabecera h1 { font-size: 1.1rem; margin: 0; display: flex; align-items: center; gap: 8px; }
/* Fila propia para Reporte/Excel/Volver -- con el título arriba (bandeja-lista-cabecera), en
   vez de compartir la misma fila. La columna izquierda mide 340px fijos en cualquier ancho de
   escritorio (no depende del viewport), así que 3 botones + título nunca caben en una sola fila
   sin quedar irreconociblemente apretados -- se detectó midiendo posiciones reales en el
   navegador, no solo revisando que el HTML existiera. */
.bandeja-lista-acciones {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  padding: 8px 16px 12px;
}
.bandeja-lista-acciones .btn { white-space: nowrap; }
.bandeja-lista-filtros {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  padding: 0 16px 12px;
  border-bottom: 1px solid var(--gris-borde);
}
.bandeja-lista-filtros .form-group { margin-bottom: 0; min-width: 110px; }
.bandeja-lista-filas { flex: 1; overflow-y: auto; }
.bandeja-lista-vacia { color: var(--texto-suave); padding: 16px; font-size: .88rem; }

.bandeja-fila {
  display: block;
  padding: 10px 16px;
  border-bottom: 1px solid var(--plata-clara);
  text-decoration: none;
  color: var(--texto);
}
.bandeja-fila:hover { background: var(--plata-clara); }
.bandeja-fila.activa { background: var(--dorado-claro); }
.bandeja-fila-linea1 { display: flex; justify-content: space-between; gap: 8px; }
.bandeja-fila-nombre { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bandeja-fila.no-atendida .bandeja-fila-nombre { font-weight: 700; }
.bandeja-fila-hora { font-size: .72rem; color: var(--texto-suave); flex-shrink: 0; }
.bandeja-fila-linea2 { display: flex; align-items: center; gap: 6px; margin-top: 2px; }
.bandeja-fila-canal .icono { width: 15px; height: 15px; color: var(--texto-suave); flex-shrink: 0; }
.bandeja-fila-ultimo {
  font-size: .82rem;
  color: var(--texto-suave);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  flex: 1;
}
.bandeja-fila-punto { width: 8px; height: 8px; border-radius: 50%; background: var(--dorado); flex-shrink: 0; }
.bandeja-fila-linea3 { display: flex; align-items: center; gap: 6px; margin-top: 6px; flex-wrap: wrap; }
.bandeja-fila-telefono { font-size: .76rem; color: var(--texto-suave); }

/* ---- Panel derecho: chat ---- */
.bandeja-chat { display: flex; flex-direction: column; min-width: 0; }
.bandeja-chat-vacio {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  color: var(--texto-suave);
  text-align: center;
  padding: 24px;
}
.bandeja-chat-vacio .icono { width: 48px; height: 48px; opacity: .5; }

.bandeja-chat-cabecera {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 16px;
  border-bottom: 1px solid var(--gris-borde);
  flex-wrap: wrap;
}
.bandeja-chat-volver { display: none; font-size: 1.3rem; text-decoration: none; color: var(--texto); }
.bandeja-chat-cabecera-info { display: flex; flex-direction: column; margin-right: auto; }
.bandeja-chat-cabecera-info strong { font-size: 1rem; }
.bandeja-chat-cabecera-info span { font-size: .8rem; color: var(--texto-suave); }

.bandeja-chat-encuesta {
  background: var(--dorado-claro);
  color: var(--dorado-oscuro);
  padding: 8px 16px;
  font-size: .85rem;
  display: flex;
  gap: 10px;
  align-items: center;
}

.bandeja-chat-gestion {
  border-bottom: 1px solid var(--gris-borde);
  padding: 14px 16px;
  display: flex;
  flex-direction: column;
  gap: 14px;
  max-height: 320px;
  overflow-y: auto;
}
.bandeja-chat-gestion form { display: flex; flex-direction: column; gap: 8px; }
.bandeja-chat-gestion .form-group { margin-bottom: 0; }
.bandeja-chat-gestion .k { color: var(--texto-suave); font-size: .78rem; text-transform: uppercase; letter-spacing: .3px; display: block; margin-bottom: 2px; }
.bandeja-chat-gestion p { margin: 0; font-size: .88rem; }

.bandeja-chat-mensajes {
  flex: 1;
  overflow-y: auto;
  padding: 16px;
  display: flex;
  flex-direction: column;
  gap: 4px;
  background: var(--plata-clara);
}
.chat-separador-fecha { display: flex; justify-content: center; margin: 10px 0; }
.chat-separador-fecha span {
  background: var(--blanco);
  color: var(--texto-suave);
  font-size: .74rem;
  padding: 3px 12px;
  border-radius: 20px;
  box-shadow: var(--sombra);
}
.chat-burbuja-fila { display: flex; margin: 3px 0; }
.chat-burbuja-fila.enviado { justify-content: flex-end; }
.chat-burbuja-fila.recibido { justify-content: flex-start; }
.chat-burbuja {
  max-width: 75%;
  border-radius: 12px;
  padding: 8px 12px;
  box-shadow: 0 1px 2px rgba(20, 20, 25, 0.08);
}
.chat-burbuja-fila.enviado .chat-burbuja { background: var(--dorado-claro); border-bottom-right-radius: 3px; }
.chat-burbuja-fila.recibido .chat-burbuja { background: var(--blanco); border-bottom-left-radius: 3px; }
.chat-burbuja p { margin: 0; white-space: pre-wrap; word-break: break-word; }
.chat-burbuja-meta { display: block; font-size: .7rem; color: var(--texto-suave); text-align: right; margin-top: 3px; }
.chat-tick { margin-left: 2px; }
.chat-tick-leido { color: #2f7dd6; }
.chat-tick-fallido { color: var(--error); }

.bandeja-chat-entrada { border-top: 1px solid var(--gris-borde); padding: 12px 16px; }
.chat-opt-out-aviso { color: var(--error); margin: 0; font-size: .88rem; }
.chat-input-bar { display: flex; align-items: flex-end; gap: 8px; }
.chat-input-bar textarea {
  flex: 1;
  resize: none;
  max-height: 110px;
  border-radius: 18px;
  padding: 10px 16px;
}
.chat-enviar-boton { border-radius: 50%; width: 42px; height: 42px; padding: 0; display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.chat-enviar-boton .icono { margin-right: 0; }

.chat-emoji-wrap { position: relative; flex-shrink: 0; }
.chat-emoji-boton {
  border: 1px solid var(--gris-borde);
  background: var(--blanco);
  border-radius: 50%;
  width: 42px;
  height: 42px;
  font-size: 1.2rem;
  cursor: pointer;
  line-height: 1;
}
.chat-emoji-boton:hover { border-color: var(--dorado); }
.chat-emoji-popover {
  position: absolute;
  bottom: 48px;
  left: 0;
  width: 236px;
  max-height: 200px;
  overflow-y: auto;
  background: var(--blanco);
  border: 1px solid var(--gris-borde);
  border-radius: 10px;
  box-shadow: var(--sombra);
  padding: 8px;
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 2px;
  z-index: 20;
}
.chat-emoji-popover button {
  border: none;
  background: none;
  font-size: 1.2rem;
  cursor: pointer;
  border-radius: 6px;
  padding: 4px 0;
  line-height: 1;
}
.chat-emoji-popover button:hover { background: var(--plata-clara); }

@media (max-width: 820px) {
  .bandeja-conversaciones {
    grid-template-columns: 1fr;
    height: auto;
    min-height: 0;
  }
  .bandeja-lista { border-right: none; }
  .bandeja-chat { border-top: 1px solid var(--gris-borde); }

  /* Sin conversación activa: solo la lista. Con conversación activa: solo el chat + botón volver.
     Decisión tomada 100% en servidor (clase .tiene-activa según $conversacionActiva) -- nunca
     depende de JavaScript para mostrarse correctamente. */
  .bandeja-lista { display: flex; }
  .bandeja-chat { display: none; }
  .bandeja-conversaciones.tiene-activa .bandeja-lista { display: none; }
  .bandeja-conversaciones.tiene-activa .bandeja-chat { display: flex; height: 78vh; max-height: 640px; }
  .bandeja-conversaciones.tiene-activa .bandeja-chat-volver { display: inline-block; }

  .bandeja-chat-mensajes { padding: 12px; }
  .chat-emoji-popover { width: 200px; grid-template-columns: repeat(5, 1fr); }
}
