/* Socoltenango — sistema visual compartido. Se carga después del CSS legado.
   Los colores de alerta, mapas y gráficas conservan su significado. */
:root {
  --ui-font: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --ui-canvas: #f5f5f7;
  --ui-surface: #fff;
  --ui-subtle: #f0f1f3;
  --ui-ink: #202124;
  --ui-muted: #5f6368;
  --ui-line: #e3e5e8;
  /* Borde de campos de texto, listas y áreas de texto: ≥ 3:1 contra el campo y la
     superficie (WCAG 1.4.11). --ui-line (1.26:1) queda para separadores. */
  --ui-control-line: #767b84;
  --ui-accent: #0067c7;
  --ui-primary: #0067c7;
  --ui-primary-hover: #0056a8;
  --ui-accent-hover: #0056a8;
  --ui-on-primary: #fff;
  --ui-accent-legible: var(--ui-accent);
  --ui-selected: #eaf2fb;
  --ui-shadow: 0 2px 8px rgb(25 32 45 / 3%);
  --ui-radius: 18px;
  --ui-fast: 160ms;
  --ui-enter: 240ms;
  --ui-ease: cubic-bezier(.2, .7, .2, 1);
  --ease-apple: var(--ui-ease);
  --ease-apple-suave: var(--ui-ease);
  --ease-apple-entrada: var(--ui-ease);
  --ease-resorte: var(--ui-ease);
  --dur-apple: var(--ui-enter);
  --dur-apple-corta: var(--ui-fast);
}
html.dark {
  color-scheme: dark;
  --ui-canvas: #151618;
  --ui-surface: #202226;
  --ui-subtle: #292c31;
  --ui-ink: #f0f1f3;
  --ui-muted: #adb2b9;
  --ui-line: #35383e;
  --ui-control-line: #8d939c;
  --ui-accent: #8bbdff;
  --ui-accent-hover: #add0ff;
  --ui-selected: #26384c;
  --ui-shadow: 0 2px 8px rgb(0 0 0 / 10%);
}
html #appBody {
  font-family: var(--ui-font);
  background: var(--ui-canvas);
  color: var(--ui-ink);
  -webkit-font-smoothing: antialiased;
}
/* Etapa 1 con la convención de la etapa 2 (ver su comentario, más abajo): las listas
   :is() del compuesto derecho se escriben como listas de selectores y, donde mezclaban
   especificidades, el relleno (.a.a, :root o html delante, #appBody#appBody, :where())
   conserva la mayor. */
#appBody button, #appBody input, #appBody select, #appBody textarea { font-family: inherit; }
#appBody .font-black { font-weight: 650; }
#appBody .font-extrabold { font-weight: 650; }
#appBody .tracking-widest { letter-spacing: .065em; }
#appBody .font-black.uppercase { font-weight: 550; text-transform: none; letter-spacing: .015em; }
#appBody h1, #appBody h2, #appBody h3 { letter-spacing: -.035em; }
#appBody h1, #appBody h2 { font-weight: 650; }
#appBody .lucide, #appBody .ui-icon { stroke-width: 1.65; }
.ui-icon { display: inline-block; width: 1.1em; height: 1.1em; vertical-align: -.15em; flex-shrink: 0; }

/* Superficies: adaptadores explícitos para Tailwind, Día D y Estadísticas. */
#appBody .bg-white, #appBody .dark\:bg-slate-800, #appBody .dark\:bg-slate-900 { background-color: var(--ui-surface); }
#appBody .bg-slate-50, #appBody .bg-slate-100 { background-color: var(--ui-canvas); }
#appBody .border-slate-100, #appBody .border-slate-200, #appBody .border-slate-300, #appBody .border-slate-200\/60 { border-color: var(--ui-line); }
#appBody .text-slate-800, #appBody .text-slate-900 { color: var(--ui-ink); }
#appBody .text-slate-500, #appBody .text-slate-600 { color: var(--ui-muted); }
#appBody .text-slate-400 { color: var(--ui-muted); }
#appBody .text-indigo-500, #appBody .text-indigo-600, #appBody .text-indigo-700 { color: var(--ui-accent); }
#appBody .bg-indigo-50, #appBody .bg-indigo-100 { background-color: var(--ui-selected); }
#appBody .bg-indigo-600 { background-color: var(--ui-primary); }
/* (2,0,0) y (2,1,0) con :hover: la especificidad que daba #loginBtn a toda la lista. */
#appBody#appBody :where(button.bg-indigo-600), #appBody#appBody :where(button.bg-indigo-500),
#appBody#appBody :where(.dd-btn-primario), #appBody #loginBtn {
  background: var(--ui-primary); border-color: transparent; color: #fff;
  box-shadow: none;
}
#appBody#appBody :where(button.bg-indigo-600):hover, #appBody#appBody :where(button.bg-indigo-500):hover,
#appBody#appBody :where(.dd-btn-primario):hover, #appBody #loginBtn:hover { background: var(--ui-primary-hover); }
/* (2,0,1): la que daba #page-estadisticas. */
html #appBody#appBody :where(.dd-mod), html #appBody #page-estadisticas {
  --dd-fondo: var(--ui-surface); --dd-fondo2: var(--ui-canvas); --dd-fondo3: var(--ui-subtle);
  --dd-borde: var(--ui-line); --dd-borde2: var(--ui-line);
  --dd-texto: var(--ui-ink); --dd-suave: var(--ui-muted); --dd-tenue: var(--ui-muted);
  --dd-indigo: var(--ui-accent); --dd-indigo-suave: var(--ui-selected); --dd-sombra: var(--ui-shadow);
  --est-fondo: var(--ui-surface); --est-fondo2: var(--ui-canvas); --est-borde: var(--ui-line);
  --est-texto: var(--ui-ink); --est-suave: var(--ui-muted); --est-tenue: var(--ui-muted);
  --est-indigo: var(--ui-accent); --est-fila: var(--ui-canvas);
}
#mainContent { background: var(--ui-canvas); scrollbar-gutter: stable; }
#mainContent > section { max-width: 1800px; margin-inline: auto; }
/* (1,2,0): la de .rounded-3xl.bg-white; las clases solas se repiten. */
#mainContent .rounded-3xl.bg-white, #mainContent .dd-card.dd-card, #mainContent .dd-kpi.dd-kpi,
#mainContent .est-card.est-card, #mainContent .est-kpi.est-kpi, #mainContent .kpi-card.kpi-card {
  border-radius: var(--ui-radius); border-color: var(--ui-line); box-shadow: var(--ui-shadow);
}
/* (1,1,1): la de «.dd-kpi b»; html delante del atributo suma la etiqueta. */
#mainContent .dd-kpi b, #mainContent .est-kpi b, html #mainContent [id^="kpi-"] {
  font-weight: 600; letter-spacing: -.045em; font-variant-numeric: tabular-nums;
}
#appBody .dd-card-head, #appBody .est-card-head { padding: 18px 20px; }
#appBody .dd-card-body, #appBody .est-card-body { padding: 20px; }
#appBody .dd-h4, #appBody .est-h4 { font-weight: 600; }
#mainContent .shadow-lg, #mainContent .shadow-xl { box-shadow: var(--ui-shadow); }
#mainContent [class*="from-indigo-9"], #mainContent [class*="from-slate-9"], #mainContent [class*="from-purple-9"] { background: #252b34; }
#mainContent .kpi-card:hover, #mainContent .dd-kpi:hover { transform: none; box-shadow: var(--ui-shadow); }
#appBody .dd-btn, #appBody .est-btn { font-weight: 550; border-radius: 10px; }
#appBody .dd-tab { font-weight: 550; }
#appBody .dd-tab-on { background: var(--ui-primary); color: #fff; box-shadow: none; }
#appBody .dd-ayuda-btn:hover { background: var(--ui-primary); color: #fff; }

/* Navegación tranquila: selección visible, sin lámparas ni halos. */
html #sidebar { background: var(--ui-surface); border-color: var(--ui-line); }
#sidebar > div:first-child { padding-block: 25px; }
#sidebar nav { padding: 16px 12px; }
#sidebar .sidebar-item { font-size: 13px; font-weight: 500; border-radius: 10px; color: var(--ui-muted); }
#sidebar .sidebar-item:hover { background: var(--ui-canvas); color: var(--ui-ink); }
#sidebar .sidebar-item.active { color: var(--ui-accent); background: var(--ui-selected); font-weight: 600; }
#sidebar .dv-nav-tubelight .sidebar-item.active { background: var(--ui-selected) !important; }
#sidebar .dv-lampara-lateral { display: none; }
#appBody .dv-tubelight { height: 2px; box-shadow: none; border-radius: 2px; transition-duration: var(--ui-enter); }
#appBody .tab-btn.active { color: var(--ui-accent); border-bottom-color: var(--ui-accent); }
#appBody .dv-tabs-tubelight { isolation: isolate; }
#sidebar > div:last-child { background: var(--ui-surface); }
#sidebar #userRole { color: var(--ui-muted); font-weight: 500; }
#appTitle { font-size: 13px; }
#appBody .mv-barra { background: var(--ui-surface); border-color: var(--ui-line); box-shadow: none; }
#appBody .mv-tab.mv-activo { color: var(--ui-accent); }
#appBody .mv-tab.mv-activo svg { transform: none; }
#appBody .mv-pastilla { background: var(--ui-selected); transition-duration: var(--ui-enter); }
#appBody .mv-ripple { display: none; }

/* Formularios y tablas conservan densidad, estados y controles existentes.
   El borde usa --ui-control-line; el foco lo marca el contorno de :focus-visible y el
   error, .ui-campo-invalido (con !important), así que ninguno de los dos cambia.
   textarea y select conservan (1,5,1), la que daba a la lista el input con sus cinco
   :not(): cinco :root delante. */
#appBody input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="color"]):not([type="file"]),
:root:root:root:root:root #appBody textarea, :root:root:root:root:root #appBody select {
  border-color: var(--ui-control-line); border-radius: 10px; font-weight: 450;
  transition: border-color var(--ui-fast) var(--ui-ease), box-shadow var(--ui-fast) var(--ui-ease);
}
/* Las dos de foco ya las clasifica Chromium por :focus-visible y :focus (solo se
   prueban en el elemento enfocado): se quedan con su lista :is(). */
#appBody :is(button, a, input, textarea, select, [tabindex]):focus-visible {
  outline: 2px solid var(--ui-accent) !important; outline-offset: 3px;
}
#appBody :is(input, textarea, select):focus { border-color: var(--ui-accent); }
#appBody input:is([aria-invalid="true"], .border-red-500, .border-rose-500),
#appBody textarea:is([aria-invalid="true"], .border-red-500, .border-rose-500),
#appBody select:is([aria-invalid="true"], .border-red-500, .border-rose-500) { border-color: #d43c45; }
#appBody button:disabled, #appBody input:disabled, #appBody select:disabled, #appBody textarea:disabled { cursor: not-allowed; }
#mainContent th { font-weight: 600; letter-spacing: .045em; }
#mainContent td { font-variant-numeric: tabular-nums; }
#mainContent tbody tr { transition: background-color var(--ui-fast) var(--ui-ease); }
#mainContent tbody tr:hover { background-color: var(--ui-selected); }

/* Acceso y pantalla de carga: ver «Etapa 2 · acceso» al final (29/09). */

/* Un solo lenguaje de movimiento, sin rebotes ni elevación al pasar el cursor.
   Sin fill-mode: los modales fixed anidados no deben cambiar su contenedor. */
@keyframes ui-enter { from { opacity: 0; transform: translateY(5px); } to { opacity: 1; transform: none; } }
@keyframes ui-dialog { from { opacity: 0; transform: translateY(6px) scale(.99); } to { opacity: 1; transform: none; } }
#appBody .animate-fadeIn, #appBody .dv-panel-in, #appBody .animate-login-card-in { animation: ui-enter var(--ui-enter) var(--ui-ease); }
#appBody .dv-modal-pop, #appBody .dv-menu-in, #appBody .dd-modal-caja { animation: ui-dialog var(--ui-enter) var(--ui-ease) !important; }
#appBody button:not(.dv-sin-anim) {
  transition: background-color var(--ui-fast) var(--ui-ease), color var(--ui-fast) var(--ui-ease), border-color var(--ui-fast) var(--ui-ease), opacity var(--ui-fast) var(--ui-ease), scale var(--ui-fast) var(--ui-ease);
}
#appBody button:not(.dv-sin-anim):hover { translate: none; }
#appBody button:not(.dv-sin-anim):not(:disabled):active { scale: .985; }
#appBody .dd-btn:active { transform: none; }
#appBody .group:hover .group-hover\:scale-110 { transform: none; }
#appBody .animate-blob, #appBody .animate-ping { animation: none; }
#page-dashboard .animate-pulse { animation: none; }
@media (min-width: 768px) {
  html #sidebar { width: 256px; }
  #mainContent > section { padding: 32px; }
  #mainContent > section > div:first-child h2 { font-size: 28px; line-height: 1.2; }
}
@media (max-width: 767px) {
  #appBody #sidebar { transition-duration: var(--ui-enter) !important; }
  #appBody .dd-card-head, #appBody .est-card-head, #appBody .dd-card-body, #appBody .est-card-body { padding: 16px; }
}
@media (prefers-reduced-motion: reduce) {
  /* :root delante: (1,1,0), la de la lista :is(*, .dv-modal-pop, …) anterior, que gana
     a la animación de las ventanas; * ya abarcaba todos los elementos. */
  :root #appBody *,
  #appBody *::before, #appBody *::after {
    animation-duration: .01ms !important; animation-iteration-count: 1 !important;
    transition-duration: .01ms !important; scroll-behavior: auto !important;
  }
  #appBody button:active { scale: 1 !important; }
}
html.dv-quieto #appBody *, html.dv-quieto #appBody *::before, html.dv-quieto #appBody *::after {
  animation: none !important; transition: none !important;
}
@media print { #appBody { background: white; color: black; } }

/* Primera etapa de accesibilidad: filtros con contexto persistente y estados. */
#appBody .ui-filter-field { padding-top: 24px; }
#appBody .ui-filter-label {
  position: absolute; top: 0; left: 0; color: var(--ui-ink);
  font-size: 12px; line-height: 18px; font-weight: 550;
}
#appBody .ui-filter-field > .pointer-events-none { top: 24px; }
#appBody .ui-form-help { color: var(--ui-muted); font-size: 14px; line-height: 1.5; }
#appBody .ui-form-error { color: #b42332; font-size: 14px; line-height: 1.5; font-weight: 600; }
html.dark #appBody .ui-form-error { color: #ffb4bc; }
#appBody .ui-form-error:empty:not([data-ui-live]), #appBody .ui-form-help:empty:not([data-ui-live]) { display: none; }
/* Las regiones vivas permanecen presentes antes de recibir el mensaje. */
#appBody [data-ui-live]:empty { margin: 0; }
#appBody .ui-status { font-size: 12px; line-height: 18px; font-weight: 600; }
#appBody .ui-status-ok { color: #066044; background: #ecfdf5; border-color: #9dd5bb; }
#appBody .ui-status-warning { color: #854000; background: #fffbeb; border-color: #e8c37a; }
html.dark #appBody .ui-status-ok { color: #a7f3d0; background: #063b2b; border-color: #427a63; }
html.dark #appBody .ui-status-warning { color: #fde68a; background: #452a09; border-color: #a17b39; }
#appBody :is(#pe_contenedorBotonesPaginas, #ca_contenedorBotonesPaginas) button { min-width: 36px; min-height: 36px; }

/* Etapa 2, todas las secciones: el último compuesto de cada selector empieza con
   clase, etiqueta, id o atributo, nunca con :is()/:where() de varias opciones. Así el
   navegador prueba cada regla solo en los elementos que pueden cumplirla y no en
   todo el documento (con miles de filas, el recálculo de estilos subía ~50 %).
   Una lista :is(a, b) se escribe como a, b. Si la lista mezclaba
   especificidades, se conserva la mayor (:is() toma la de su argumento más
   específico): clase repetida (.a.a) o :root delante suman una clase, html delante
   suma una etiqueta, #appBody#appBody suma un id y :where() deja sin peso lo que
   envuelve. */

/* Etapa 2 · lenguaje: estado de la captura local (H19) y aviso de conexión del Panel Principal. */
#appBody .ui-estado-local {
  background: var(--ui-surface);
  border: 1px solid var(--ui-line);
  border-radius: var(--ui-radius);
  box-shadow: var(--ui-shadow);
  padding: 16px 18px;
}
#appBody .ui-estado-local-titulo {
  margin: 0 0 12px;
  color: var(--ui-ink);
  font-size: 16px;
  font-weight: 650;
  line-height: 1.3;
  letter-spacing: -.01em;
}
/* Columnas según el ancho del propio panel (no de la ventana, que incluye el menú
   lateral): dos; cuatro cuando cada dato tiene al menos ~210 px, y una sola con menos
   de 300 px útiles (más abajo). Cada dato ocupa solo su alto, sin estirarse al del
   vecino más largo. */
#appBody .ui-estado-local { container-type: inline-size; }
#appBody .ui-estado-local-lista {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  align-items: start;
  gap: 8px;
}
@container (min-width: 880px) { #appBody .ui-estado-local-lista { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
#appBody .ui-estado-local-item {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
  margin: 0;
  padding: 10px 12px;
  border-radius: 12px;
  background: var(--ui-subtle);
}
#appBody .ui-estado-local-etiqueta { color: var(--ui-muted); font-size: 13px; line-height: 1.35; }
#appBody .ui-estado-local-valor {
  color: var(--ui-ink);
  font-size: 15px;
  font-weight: 600;
  line-height: 1.35;
  overflow-wrap: anywhere;
}
/* El estado de conexión se escribe; el color solo refuerza. */
#appBody .ui-estado-local-item[data-estado="disponible"] .ui-estado-local-valor { color: #17693a; }
#appBody .ui-estado-local-item[data-estado="sin-conexion"] .ui-estado-local-valor { color: #8a4300; }
html.dark #appBody .ui-estado-local-item[data-estado="disponible"] .ui-estado-local-valor { color: #7fdca4; }
html.dark #appBody .ui-estado-local-item[data-estado="sin-conexion"] .ui-estado-local-valor { color: #ffc680; }
#appBody .ui-estado-local-nota {
  margin: 12px 0 0;
  color: var(--ui-muted);
  font-size: 14px;
  line-height: 1.5;
}
#appBody .ui-estado-local-resultado {
  margin: 10px 0 0;
  color: var(--ui-ink);
  font-size: 14px;
  font-weight: 600;
  line-height: 1.5;
}
#appBody .ui-estado-local-resultado:empty { margin: 0; }
#appBody .ui-estado-local-resultado[data-tipo="error"],
#appBody .ui-estado-local-resultado[data-tipo="sin-conexion"] { color: #b42332; }
html.dark #appBody .ui-estado-local-resultado[data-tipo="error"],
html.dark #appBody .ui-estado-local-resultado[data-tipo="sin-conexion"] { color: #ffb4bc; }
/* Teléfono: panel compacto para que el formulario no quede tan abajo (va después de
   las reglas base para poder reducir sus rellenos). Con menos de 300 px útiles, dos
   columnas partían «sincronizaciones» a media palabra: una sola columna y cada dato
   en un renglón, con el valor junto a su etiqueta o debajo si no cabe. */
@media (max-width: 767.98px) {
  #appBody .ui-estado-local { padding: 12px 14px; }
  #appBody .ui-estado-local-titulo { margin-bottom: 8px; font-size: 15px; }
  #appBody .ui-estado-local-lista { gap: 6px; }
  #appBody .ui-estado-local-item { padding: 8px 10px; }
  #appBody .ui-estado-local-nota { margin-top: 8px; }
}
@container (max-width: 299.98px) {
  #appBody .ui-estado-local-lista { grid-template-columns: minmax(0, 1fr); gap: 4px; }
  #appBody .ui-estado-local-item { flex-flow: row wrap; align-items: baseline; justify-content: space-between; column-gap: 12px; padding: 6px 10px; }
}

/* Punto del Panel Principal sin conexión: ámbar y quieto. */
#appBody .ui-punto-sin-conexion { background-color: #c26a00; animation: none; }
html.dark #appBody .ui-punto-sin-conexion { background-color: #ffb454; }
@media (prefers-reduced-motion: reduce) {
  #appBody #dash_estado_punto { animation: none; }
}
html.dv-quieto #appBody #dash_estado_punto { animation: none; }

/* Zona de eliminación (Configuración): con la etiqueta larga del botón, el campo
   «ELIMINAR TODO» quedaba en 39 px a 768 px. En fila (≥ 640 px) el campo conserva
   al menos 11rem y, si no caben los dos, el botón baja a su propio renglón.
   lenguaje.py retira la zona; si sigue (cadena parcial), legibilidad.py marca su
   renglón con .ui-borrado-total-fila (antes, div:has(> #inputConfirmarBorrado),
   que se probaba en cada div del documento). */
@media (min-width: 640px) {
  #appBody .ui-borrado-total-fila { flex-wrap: wrap; }
  #appBody #inputConfirmarBorrado { flex: 999 1 11rem; width: auto; min-width: 11rem; }
  #appBody #btnBorrarTodo { flex: 1 0 auto; }
}

/* Etapa 2 · formularios: resumen de errores, mensaje por campo y opcionales. */
#appBody .ui-sr-only, #appBody .ui-archivo {
  position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}
#appBody .ui-error-summary {
  grid-column: 1 / -1; border: 2px solid #b42332; border-radius: 14px;
  padding: 14px 16px; background: #fff6f6; color: var(--ui-ink); text-align: left;
}
html.dark #appBody .ui-error-summary { border-color: #ff8a97; background: #34191e; }
#appBody .ui-error-summary:focus { outline: 3px solid var(--ui-accent); outline-offset: 3px; }
#appBody .ui-error-summary-title {
  margin: 0; font-size: 16px; line-height: 1.35; font-weight: 650; color: var(--ui-ink);
  text-transform: none; letter-spacing: 0;
}
#appBody .ui-error-summary-note { margin: 4px 0 0; font-size: 14px; line-height: 1.45; color: var(--ui-muted); }
#appBody .ui-error-summary-list { margin: 8px 0 0; padding: 0; list-style: none; }
#appBody .ui-error-summary-list li + li { margin-top: 6px; }
#appBody .ui-error-summary-list a {
  color: #a51d2d; font-size: 14px; line-height: 1.45; font-weight: 600;
  text-decoration: underline; text-underline-offset: 2px;
}
html.dark #appBody .ui-error-summary-list a { color: #ffb4bc; }
#appBody .ui-field-error {
  margin: 6px 0 0; color: #b42332; font-size: 13px; line-height: 1.45; font-weight: 600;
  text-transform: none; letter-spacing: 0; text-align: left;
}
html.dark #appBody .ui-field-error { color: #ffb4bc; }
#appBody .ui-campo-invalido { border-color: #b42332 !important; box-shadow: 0 0 0 1px #b42332; }
html.dark #appBody .ui-campo-invalido { border-color: #ff8a97 !important; box-shadow: 0 0 0 1px #ff8a97; }
/* «(opcional)» sin mayúsculas forzadas para distinguirlo del nombre del campo. */
#appBody .ui-opcional { text-transform: none; letter-spacing: 0; font-weight: 500; color: var(--ui-muted); }
/* Archivos con la etiqueta como botón: el campo real conserva el foco visible. */
#appBody label:has(+ input.ui-archivo:focus-visible),
#appBody :has(+ input.ui-archivo:focus-visible) > label[for] { outline: 2px solid var(--ui-accent); outline-offset: 3px; }
/* Interruptores de Configuración: el foco se ve en la pista visible. */
#page-configuracion input.sr-only.peer:focus-visible + div { outline: 2px solid var(--ui-accent); outline-offset: 3px; }
/* Sin animaciones propias: el resumen aparece sin movimiento (reduced-motion y dv-quieto). */

/* Etapa 2 · tablas: acciones por registro, procedencia, estados de lista y
   paginación. Solo colores y medidas; sin animaciones nuevas. */

/* Acciones de fila: «Ver expediente» primero; borrar al final y separado. */
#appBody .ui-acciones-fila {
  display: grid; grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
  gap: 8px; align-items: stretch;
}
#appBody .ui-acciones-fila > button { min-height: 40px; white-space: nowrap; font-weight: 600; }
#appBody .ui-acciones-fila > .ui-acciones-separador {
  grid-column: 1 / -1; height: 1px; margin-top: 4px; background: var(--ui-line);
}
#appBody .ui-acciones-fila > .ui-accion-peligro { grid-column: 1 / -1; justify-self: end; min-width: 128px; }
@media (min-width: 768px) {
  #appBody .ui-acciones-fila { display: flex; justify-content: center; align-items: center; }
  #appBody .ui-acciones-fila > button { min-height: 32px; }
  #appBody .ui-acciones-fila > .ui-acciones-separador { width: 1px; height: 24px; margin: 0 4px; }
  #appBody .ui-acciones-fila > .ui-accion-peligro { min-width: 0; }
}
/* Anchos intermedios (768–1279 px, con el menú lateral abierto): en una sola línea
   las tres acciones ocupaban ~390 px y la columna del nombre se quedaba en ~100 px.
   Pasan a dos renglones, «Ver expediente» arriba y «Ubicación» | «Borrar» abajo,
   con sus etiquetas visibles (WCAG 2.5.3). Las celdas de estas tablas usan 12 px de
   relleno lateral y, en el Padrón Electoral, las fichas de simpatía y expediente y
   sus dos filtros se apilan para dejar sitio al nombre; los filtros de sección y
   casilla conservan 4.5rem para que «Todas» y su flecha se vean completas.
   En las tablas cuya primera columna es el nombre, legibilidad.py marca el
   encabezado (thead.ui-encabezado-nombre); el cuerpo se alcanza con «~ tbody». Antes
   se deducía con :has() desde cada celda; con 3000 filas en Mensajería eso subía el
   recálculo de estilos ~18 % a 1024 px. «html body main» delante y la clase
   repetida (o :not()) conservan la especificidad (1,3,7) del selector anterior;
   .ui-fichas-estado repetida, la (2,2,1) de .flex:has(> .ui-status). La fila de
   estado (vacía, descargando) queda como estaba; el encabezado ya lleva 12 px sin
   filas y no salta al llegar los datos. */
@media (min-width: 768px) and (max-width: 1279.98px) {
  #appBody .ui-acciones-fila { flex-wrap: wrap; justify-content: flex-start; gap: 6px; min-width: 12.5rem; }
  #appBody .ui-acciones-fila > .ui-accion-principal { flex: 1 0 100%; }
  #appBody .ui-acciones-fila > .ui-accion-ubicacion,
  #appBody .ui-acciones-fila > .ui-accion-peligro { flex: 1 1 auto; padding-inline: 8px; }
  #appBody .ui-acciones-fila > .ui-acciones-separador { margin: 0 2px; }
  html body main#mainContent table > thead.ui-encabezado-nombre.ui-encabezado-nombre.ui-encabezado-nombre > tr > th,
  html body main#mainContent table > thead.ui-encabezado-nombre.ui-encabezado-nombre.ui-encabezado-nombre > tr > td,
  html body main#mainContent thead.ui-encabezado-nombre.ui-encabezado-nombre ~ tbody > tr:not(.ui-estado-fila) > th,
  html body main#mainContent thead.ui-encabezado-nombre.ui-encabezado-nombre ~ tbody > tr:not(.ui-estado-fila) > td { padding-inline: 12px; }
  #appBody #tablePadronElectoral td > .ui-fichas-estado.ui-fichas-estado { flex-wrap: wrap; }
  #appBody #page-padron-electoral thead #pe_filtro_seccion,
  #appBody #page-padron-electoral thead #pe_filtro_barrio,
  #appBody #page-padron-electoral thead #pe_filtro_casilla { min-width: 4.5rem; padding-inline: 8px; }
  #appBody #page-padron-electoral table > thead > tr > td:has(> :is(#pe_filtro_seccion, #pe_filtro_barrio, #pe_filtro_casilla, .ui-pe-par)) { padding-inline: 4px; }
}

/* Destructiva: contorno, sin relleno; conserva el color de advertencia. */
#appBody .ui-accion-peligro { background: transparent; color: #b42332; border: 1px solid #e3a3aa; box-shadow: none; }
#appBody .ui-accion-peligro:hover { background: #fdf1f2; color: #8f1b28; }
html.dark #appBody .ui-accion-peligro { background: transparent; color: #ffb4bc; border-color: #7a3a42; }
html.dark #appBody .ui-accion-peligro:hover { background: #3b1d22; color: #ffd0d5; }
/* Separación visible respecto a las acciones de consulta de la misma fila. */
#appBody .ui-accion-aparte { position: relative; margin-inline-start: 10px; }
#appBody .ui-accion-aparte::before {
  content: ""; position: absolute; inset-block: 4px; inset-inline-start: -10px;
  width: 1px; background: var(--ui-line); pointer-events: none;
}

#appBody .ui-accion-ubicacion { color: #7a4300; background: #fff8eb; border-color: #efcf98; }
#appBody .ui-accion-ubicacion:hover { background: #fdefd3; }
html.dark #appBody .ui-accion-ubicacion { color: #fcd9a0; background: #33260f; border-color: #6e5324; }
html.dark #appBody .ui-accion-ubicacion:hover { background: #423116; }

/* Procedencia del expediente: texto legible; demo y prueba se distinguen. */
#appBody .ui-origen {
  display: inline-flex; align-items: center; max-width: 100%;
  font-size: 12px; line-height: 18px; font-weight: 550; color: var(--ui-muted);
  text-transform: none; letter-spacing: 0;
}
#appBody .ui-origen-titulo { font-size: 12px; line-height: 18px; font-weight: 600; color: var(--ui-muted); }
#appBody .ui-origen-demo, #appBody .ui-origen-prueba {
  padding: 0 6px; border: 1px solid #e8c37a; border-radius: 6px;
  color: #854000; background: #fffbeb;
}
html.dark #appBody .ui-origen-demo, html.dark #appBody .ui-origen-prueba { color: #fde68a; background: #452a09; border-color: #a17b39; }
#appBody .ui-origen-ninguno { font-style: italic; }

/* Estados de lista: sin registros, sin coincidencias y error de carga. */
#appBody .ui-estado-fila > td { padding: 40px 16px; text-align: center; }
#appBody .ui-estado-fila:hover { background: transparent; }
#appBody .ui-estado-lista {
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  max-width: 420px; margin: 0 auto; text-align: center;
}
#appBody .ui-estado-lista > svg, #appBody .ui-estado-lista > i { width: 32px; height: 32px; margin-bottom: 4px; color: var(--ui-muted); }
#appBody .ui-estado-lista[data-ui-estado="error"] > svg, #appBody .ui-estado-lista[data-ui-estado="error"] > i { color: #b42332; }
html.dark #appBody .ui-estado-lista[data-ui-estado="error"] > svg, html.dark #appBody .ui-estado-lista[data-ui-estado="error"] > i { color: #ffb4bc; }
#appBody .ui-estado-titulo { margin: 0; font-size: 15px; line-height: 1.4; font-weight: 650; color: var(--ui-ink); text-transform: none; letter-spacing: 0; }
#appBody .ui-estado-texto { margin: 0; font-size: 14px; line-height: 1.5; font-weight: 450; color: var(--ui-muted); text-transform: none; letter-spacing: 0; }
#appBody .ui-estado-accion {
  display: inline-flex; align-items: center; gap: 6px; margin-top: 8px;
  min-height: 36px; padding: 6px 14px; border: 1px solid var(--ui-line); border-radius: 10px;
  background: var(--ui-surface); color: var(--ui-accent-legible, var(--ui-accent)); font-size: 13px; font-weight: 600;
}
#appBody .ui-estado-accion:hover { background: var(--ui-selected); }
#appBody .ui-estado-accion > svg, #appBody .ui-estado-accion > i { width: 16px; height: 16px; }
/* En las tablas que se vuelven tarjetas en móvil, la fila del estado también. */
@media (max-width: 767px) {
  #appBody tbody.block > .ui-estado-fila, #appBody tbody.block > .ui-estado-fila > td { display: block; }
}

/* Paginación: objetivos de 36 px y extremos deshabilitados visibles. */
#appBody .ui-paginacion button { min-width: 36px; min-height: 36px; }
#appBody .ui-paginacion button:disabled { opacity: .45; cursor: not-allowed; }
#appBody .ui-paginacion button[aria-current="page"] { font-weight: 700; }

/* Confirmaciones (AppDialog): la tarjeta nunca pasa del alto de la pantalla (a
   320 × 568 la de «Borrar expediente» medía 646 px y perdía cabecera y botones).
   Se desplaza solo el cuerpo; la cabecera de contexto y los botones quedan a la
   vista, y los botones pasan a otro renglón si sus etiquetas no caben juntas. */
#appBody #appDialogCard { max-height: calc(100vh - 32px); max-height: calc(100dvh - 32px); }
#appBody #appDialogCard > .overflow-y-auto { min-height: 0; overscroll-behavior: contain; }
#appBody #appDialogButtons { flex-wrap: wrap; align-items: stretch; }
#appBody #appDialogButtons > button { flex: 1 1 auto; }
@media (max-width: 479.98px), (max-height: 640px) {
  #appBody #appDialogCard > .overflow-y-auto { padding: 20px; }
  #appBody #appDialogIconBox { width: 48px; height: 48px; margin-bottom: 12px; }
  #appBody #appDialogIconBox > svg { width: 24px; height: 24px; }
  #appBody #appDialogTitle { font-size: 20px; margin-bottom: 8px; }
}

/* Etapa 2 · navegación: salto al contenido, ubicación actual y destino de foco. */
#appBody .ui-skip-link {
  position: fixed; top: 8px; left: 8px; z-index: 100000;
  padding: 10px 16px; border-radius: 10px; border: 1px solid var(--ui-line);
  background: var(--ui-surface); color: var(--ui-ink); font-size: 14px; font-weight: 600;
  text-decoration: none; transform: translateY(calc(-100% - 16px));
}
#appBody .ui-skip-link:focus { transform: none; box-shadow: 0 8px 24px rgb(20 30 50 / 18%); }
/* Ubicación sin depender solo del color: barra lateral en el destino actual. */
#appBody #sidebar .sidebar-item[aria-current="page"] { box-shadow: inset 3px 0 0 var(--ui-accent); }
/* Títulos que reciben el foco al cambiar de vista: solo el anillo de
   :focus-visible compartido. La sección sin título no es un control. */
#appBody [data-ui-destino-vista]:focus:not(:focus-visible) { outline: none; }
#appBody #mainContent > section[data-ui-destino-vista]:focus-visible { outline: none !important; }
#appBody [data-ui-activar-teclado] { cursor: pointer; }
/* Pestañas de Configuración: siete apartados no caben en una línea con el menú
   lateral abierto («Exportación y Reportes» quedaba cortada a 1440 px). Desde 768 px
   pasan a otro renglón: todas quedan a la vista y la que se enfoca con las flechas
   (UIPestanas) se ve entera. En el teléfono siguen siendo la tira deslizable de la capa
   móvil (.mv-tira, con el borde desvanecido que indica que hay más). */
@media (min-width: 768px) {
  #appBody #page-configuracion div:has(> #btn-tab-apariencia) { flex-wrap: wrap; row-gap: 8px; overflow-x: visible; }
}
/* Si «Volver arriba» recibe el foco del teclado mientras está oculto (opacity-0),
   se muestra, para que el foco nunca quede en un control invisible. */
#appBody #btnVolverArriba:focus-visible { opacity: 1; --tw-translate-y: 0px; pointer-events: auto; }
/* Espacio final para que lo último de cada vista (paginación) suba por encima del
   botón flotante «Volver arriba» y no quede tapado (WCAG 2.4.11). En el teléfono
   la capa móvil ya reserva el espacio de su barra inferior. */
@media (min-width: 768px) {
  #appBody #mainContent > section:not(#page-campo) { padding-bottom: 5.5rem; }
}

/* Etapa 2 · filtros_movil: resumen de filtros (UIFiltros), alcance de cada
   zona de filtros (H22) y ergonomía móvil (H23, WCAG 2.5.8 y 2.4.11). */
#appBody .ui-filtros-resumen {
  display: flex; flex-direction: column; gap: 8px;
  padding: 10px 16px; border-bottom: 1px solid var(--ui-line); background: var(--ui-surface);
}
#appBody .ui-filtros-cabeza { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 14px; }
#appBody .ui-filtros-conteo { margin: 0; color: var(--ui-ink); font-size: 14px; line-height: 20px; font-weight: 650; }
#appBody .ui-filtros-conteo:empty { display: none; }
#appBody .ui-filtros-alcance { margin: 0; color: var(--ui-muted); font-size: 13px; line-height: 18px; font-weight: 450; }
#appBody .ui-filtros-activos { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 14px; }
#appBody .ui-filtros-activos[hidden] { display: none; }
#appBody .ui-filtros-grupo { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; min-width: 0; }
#appBody .ui-filtros-grupo-titulo { color: var(--ui-muted); font-size: 12px; line-height: 18px; font-weight: 600; }
#appBody .ui-filtros-chips { display: flex; flex-wrap: wrap; gap: 6px; margin: 0; padding: 0; list-style: none; min-width: 0; }
#appBody .ui-filtros-chips > li { display: flex; min-width: 0; max-width: 100%; }
#appBody .ui-filtro-chip {
  display: inline-flex; align-items: center; gap: 6px; max-width: 100%; min-height: 32px;
  padding: 4px 8px 4px 12px; border: 1px solid var(--ui-line); border-radius: 999px;
  background: var(--ui-selected); color: var(--ui-ink); font-size: 13px; line-height: 18px; font-weight: 500;
  cursor: pointer; transition: border-color var(--ui-fast) var(--ui-ease), background-color var(--ui-fast) var(--ui-ease);
}
#appBody .ui-filtro-chip-texto { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#appBody .ui-filtro-chip-texto b { font-weight: 650; }
#appBody .ui-filtro-chip .ui-icon { width: 16px; height: 16px; }
#appBody .ui-filtro-chip:hover { border-color: var(--ui-accent); }
#appBody .ui-filtros-limpiar {
  display: inline-flex; align-items: center; gap: 6px; min-height: 32px; margin-left: auto;
  padding: 4px 12px; border: 1px solid var(--ui-line); border-radius: 10px;
  background: var(--ui-surface); color: var(--ui-ink); font-size: 13px; line-height: 18px; font-weight: 600;
  transition: border-color var(--ui-fast) var(--ui-ease);
}
#appBody .ui-filtros-limpiar:hover { border-color: var(--ui-accent); }
/* Un solo «Limpiar filtros» cuando el resumen está activo. Solo se oculta el botón
   heredado de la zona de filtros, no la acción del estado «Sin coincidencias» de la
   tabla (.ui-estado-accion / data-ui-accion), que también llama a la misma función. */
#page-padron-electoral:has([data-ui-filtros="pe"][data-ui-listo]) thead button[onclick^="limpiarTodosFiltrosPE"],
#page-censo:has([data-ui-filtros="cs"][data-ui-listo]) button[onclick^="limpiarTodosFiltrosCS"]:not(.ui-estado-accion):not([data-ui-accion]):not(tbody *) { display: none !important; }
/* Alcance de los filtros de métricas, bajo sus dos campos. */
#appBody #pe-consulta div:has(> #pe_alcance_metricas) { flex-wrap: wrap; }
#appBody #pe_alcance_metricas { flex-basis: 100%; }
@media (min-width: 768px) { #appBody #pe_alcance_metricas { margin-top: -6px; text-align: right; } }
/* Contadores y tarjetas que filtran: estado presionado visible además del color
   (el anillo de foco lo da la regla global de ui-premium.css). */
#appBody [data-ui-activable] { cursor: pointer; }
#appBody div[data-ui-activable][aria-pressed="true"] { box-shadow: inset 0 0 0 2px var(--ui-accent); }
/* Chips heredados de Reportes: al menos 24 × 24 px. */
#appBody #rep_active_filters_chips button { min-width: 24px; min-height: 24px; }
/* Etiquetas de los filtros de la tabla del Padrón Electoral: en escritorio
   las dan los encabezados de columna; en el teléfono se muestran estas. */
#appBody .ui-filtros-etq-movil { display: none; }
/* Tablas con encabezado sticky: el foco no queda debajo del encabezado. */
#appBody .overflow-y-auto:has(> table > thead.sticky),
#appBody .overflow-auto:has(> table > thead.sticky) { scroll-padding-top: 48px; }

@media (max-width: 767.98px) {
  /* Foco no tapado por la barra inferior fija. */
  html:not(.mv-sin-barra) #appBody #mainContent { scroll-padding-bottom: calc(var(--mv-barra, 62px) + var(--mv-safe-b, 0px) + 16px); }

  /* Padrón Electoral: los filtros de la tabla también existen en el teléfono. */
  #appBody #page-padron-electoral table > thead { display: block; }
  #appBody #page-padron-electoral table > thead > tr:has(#pe_filtro_nombre) {
    display: grid !important; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; padding: 12px;
  }
  #appBody #page-padron-electoral table > thead > tr:has(#pe_filtro_nombre) > td { display: block; min-width: 0; padding: 0 !important; }
  /* Mismo orden que el DOM (y que el tabulador): nombre; sección y barrio; casilla; simpatía y expediente. */
  #appBody #page-padron-electoral table > thead > tr > td:is(:has(#pe_filtro_nombre), :has(#pe_filtro_casilla), :has(#pe_filtro_simpatia)) { grid-column: 1 / -1; }
  #appBody #page-padron-electoral:has([data-ui-listo]) thead td:has(> button[onclick^="limpiarTodosFiltrosPE"]) { display: none !important; }
  #appBody #page-padron-electoral thead .ui-filtros-etq-movil {
    display: block; margin: 0 0 4px; color: var(--ui-ink); font-size: 12px; line-height: 18px; font-weight: 550; text-align: left;
  }

  /* Filtros de Beneficiarios: la etiqueta ocupa su propio renglón y no se
     encima al campo cuando se parte en dos líneas (320 px). */
  #appBody #page-censo .ui-filter-field { padding-top: 0; }
  /* Solo en la cuadrícula de filtros; el buscador (columna flexible) conserva todo el ancho. */
  #appBody #page-censo .grid > .ui-filter-field { align-self: end; }
  #appBody #page-censo .ui-filter-field > .ui-filter-label { position: static; display: block; margin-bottom: 4px; }
  #appBody #page-censo .ui-filter-field > .pointer-events-none { top: auto !important; bottom: 0; height: 44px; }

  /* Contadores que filtran: pasan al siguiente renglón en vez de recortarse. */
  /* Con el id de la sección fuera de :is(), las demás vistas descartan la regla
     sin revisar los hijos de cada div. */
  #appBody #page-censo div:has(> span[data-ui-activable]),
  #appBody #page-padron-electoral div:has(> span[data-ui-activable]) { flex-wrap: wrap; }

  /* Objetivos táctiles cercanos a 44 px en filtros, formularios y ventanas.
     :root delante de select conserva la especificidad de la lista :is() anterior. */
  #appBody #mainContent input:is([type="text"], [type="search"], [type="date"], [type="time"], [type="tel"], [type="email"], [type="number"], :not([type])):not(.sr-only),
  :root #appBody #mainContent select:not(.sr-only),
  #appBody [data-ui-dialog] input:is([type="text"], [type="search"], [type="date"], [type="tel"], [type="email"], [type="number"], :not([type])):not(.sr-only),
  :root #appBody [data-ui-dialog] select:not(.sr-only),
  #appBody .dd-input, #appBody .dd-select { min-height: 44px; }
  #appBody .ui-filtro-chip, #appBody .ui-filtros-limpiar { min-height: 44px; }
  #appBody .ui-filtro-chip { padding-left: 14px; padding-right: 12px; }
  #appBody .mv-tira > * { min-height: 44px; }
  #appBody .dd-btn, #appBody .dd-ayuda-btn { min-height: 44px; }
  #appBody .dd-btn-xs { min-height: 40px; }
  #appBody .dd-cerrar { min-width: 44px; width: 44px; height: 44px; }
  #appBody [data-ui-dialog] button[aria-label="Cerrar ventana"] { min-width: 44px; min-height: 44px; }
  #appBody #appDialogCard button { min-height: 44px; }
  #appBody [data-ui-activable] { min-height: 44px; }
  #appBody #rep_active_filters_chips button { min-width: 32px; min-height: 32px; }
}
/* Filtros de Beneficiarios en el teléfono: a 12 px el texto elegido («Expedientes
   (Todos)», «Sección (Todas)») se cortaba o quedaba bajo la flecha (la capa móvil
   deja 24 px a la derecha y la flecha llega a 28). Sin el icono decorativo de la
   izquierda (la etiqueta visible ya nombra el campo) y con la flecha más cerca del
   borde, el texto cabe y termina antes de ella; a menos de 375 px «Estado del
   expediente» ocupa el renglón completo. */
@media (max-width: 767.98px) {
  #appBody #page-censo .ui-filter-field:has(> select) > .pointer-events-none.left-0 { display: none; }
  #appBody #page-censo .ui-filter-field:has(> select) > .pointer-events-none.right-0 { padding-right: 4px; }
  #appBody #page-censo .ui-filter-field:has(> select) > .pointer-events-none.right-0 > svg { width: 14px; height: 14px; }
  #appBody #page-censo .ui-filter-field > select:is(.pl-9, .pl-10) { padding-left: 12px !important; padding-right: 22px !important; }
}
@media (max-width: 374.98px) {
  #appBody #page-censo .grid > .ui-filter-field:has(> #cs_filtro_completitud) { grid-column: 1 / -1; }
}

/* ── Etapa 2 · legibilidad: tipografía (H09), contraste residual (H08) y marca de agua (H03).
   Solo CSS sobre clases existentes; no cambia datos, cálculos ni textos.
   Umbrales: texto normal 4.5:1, grande 3:1. Tamaños: metadatos ≥ 12 px,
   nombre principal de fila 14 px (decisión de producto, no mínimo WCAG). ── */

/* 1. Tokens --ui-muted, --ui-on-primary y --ui-accent-legible: en :root y html.dark.
   legibilidad.js recalcula los dos últimos cuando se configura un color de marca. */

/* 2. Escala tipográfica. Etiquetas, fichas y metadatos de 7–11 px suben a 12 px
   (sustituye el 11 px anterior). Las únicas variantes responsivas combinadas
   con estas clases son sm:/md:text-xs, también 12 px. */
#appBody .text-\[7px\], #appBody .text-\[7\.5px\], #appBody .text-\[8px\], #appBody .text-\[8\.5px\],
#appBody .text-\[9px\], #appBody .text-\[9\.5px\], #appBody .text-\[10px\], #appBody .text-\[11px\],
#appBody .sm\:text-\[9px\], #appBody .sm\:text-\[10px\], #appBody .md\:text-\[9px\], #appBody .md\:text-\[10px\] { font-size: 12px; }
/* Estilos en línea de plantillas JS (font-size:9px, 11px…). */
#appBody [style*="font-size:7px"], #appBody [style*="font-size: 7px"], #appBody [style*="font-size:7.5px"],
#appBody [style*="font-size:8px"], #appBody [style*="font-size: 8px"], #appBody [style*="font-size:8.5px"],
#appBody [style*="font-size:9px"], #appBody [style*="font-size: 9px"], #appBody [style*="font-size:9.5px"],
#appBody [style*="font-size:10px"], #appBody [style*="font-size: 10px"], #appBody [style*="font-size:10.5px"],
#appBody [style*="font-size: 10.5px"], #appBody [style*="font-size:11px"], #appBody [style*="font-size: 11px"],
#appBody [style*="font-size:11.5px"], #appBody [style*="font-size: 11.5px"] { font-size: 12px !important; }
/* <small> hereda 80 % del padre: nunca menos de 12 px. */
:where(#appBody) small { font-size: max(12px, 80%); }

/* Día D, Estadísticas, Teles y barra móvil: sus propias clases de 8–11 px.
   Todos conservan la especificidad (1,2,0) de la lista :is() anterior (clase
   repetida; la etiqueta, dentro de :where()). «.dd-campo > label» y «.dd-ayuda-tabs
   .dd-chip» ya quedan dentro de «.dd-campo label» y «.dd-chip». */
#appBody .dd-campo.dd-campo :where(label), #appBody .dd-tabla.dd-tabla :where(th), #appBody .dd-tab .dd-cnt,
#appBody .dd-kpi.dd-kpi :where(small), #appBody .dd-item-txt.dd-item-txt :where(small),
#appBody .dd-act-foto-pie.dd-act-foto-pie :where(small), #appBody .dd-act-fila.dd-act-fila :where(small),
#appBody .dd-cap-txt.dd-cap-txt :where(small),
#appBody .dd-chip.dd-chip, #appBody .dd-td-min.dd-td-min, #appBody .dd-btn-xs.dd-btn-xs, #appBody .dd-cas-pct.dd-cas-pct,
#appBody .dd-cas-ln.dd-cas-ln, #appBody .dd-qr-titulo.dd-qr-titulo, #appBody .dd-act-titulo.dd-act-titulo,
#appBody .dd-act-sub.dd-act-sub, #appBody .dd-act-foto-pie.dd-act-foto-pie, #appBody .dd-act-nota.dd-act-nota,
#appBody .dd-qr-nota.dd-qr-nota, #appBody .dd-qr-pie.dd-qr-pie, #appBody .dd-ayuda-btn.dd-ayuda-btn,
#appBody .dd-ayuda-n.dd-ayuda-n, #appBody .dd-check.dd-check, #appBody .dd-p.dd-p, #appBody .dd-sub.dd-sub,
#appBody .dd-nav-nuevo.dd-nav-nuevo { font-size: 12px; }
#appBody .dd-lbl { font-size: 12px !important; letter-spacing: .06em; }
#appBody .dd-chip { letter-spacing: .02em; }
#appBody .dd-nav-nuevo { padding: 1px 6px; letter-spacing: .04em; }
/* Especificidad (2,1,1), la de la lista :is() anterior: html delante de las clases solas. */
#appBody #page-estadisticas .est-kpi small, #appBody #page-estadisticas .est-filtros label,
#appBody #page-estadisticas .est-tabla th, #appBody #page-estadisticas .est-fila-barra b,
#appBody #page-estadisticas .est-fila-barra em, #appBody #page-estadisticas .est-sim-fila label,
#appBody #page-estadisticas .est-a-sec small, #appBody #page-estadisticas .est-paginacion button,
html #appBody #page-estadisticas .est-kpi-lbl, html #appBody #page-estadisticas .est-conteo,
html #appBody #page-estadisticas .est-sub, html #appBody #page-estadisticas .est-partido,
html #appBody #page-estadisticas .est-nota, html #appBody #page-estadisticas .est-etiqueta,
html #appBody #page-estadisticas .est-paginacion { font-size: 12px; }
#appBody .tv-boton, #appBody .tv-vista, #appBody .tv-pie { font-size: 12px; }
#appBody .mv-tab { font-size: 12px; letter-spacing: 0; }
#appBody .mv-tab .mv-badge { font-size: 12px; min-width: 18px; height: 18px; line-height: 1; top: 1px; }
/* La capa móvil fija 10.5–11 px con !important: se sube el piso con la misma fuerza. */
@media (max-width: 767.98px), (min-width: 768px) and (max-width: 1199.98px) and (pointer: coarse) {
  #appBody small { font-size: max(12px, 80%) !important; }
  #appBody #page-censo select.pl-9, #appBody #page-censo select.pl-10 { font-size: 12px !important; }
  /* Especificidad (2,1,1), la de la lista :is() anterior: html o :root delante. */
  #appBody #page-estadisticas .est-tabla th, :root #appBody #page-estadisticas label,
  html #appBody #page-estadisticas .est-kpi-lbl, html #appBody #page-estadisticas .est-indigo,
  html #appBody #page-estadisticas .est-etiqueta, html #appBody #page-estadisticas .est-partido { font-size: 12px !important; }
}

/* Texto de trabajo: nombre de la fila a 14 px, demás celdas a 13 px (tablas de escritorio). */
@media (min-width: 768px) {
  /* El nombre largo pasa a varias líneas en vez de ensanchar la tabla (la celda no
     tiene ancho fijo, así que el recorte con puntos suspensivos no se aplicaba).
     Se parte entre palabras (break-word; con anywhere la tabla podía dejar la
     columna en una letra por línea) y la columna conserva al menos 12rem. */
  #mainContent tbody td:first-child .font-black.text-xs, #mainContent tbody td:first-child .font-black.md\:text-xs,
  #mainContent tbody td:first-child .font-black.text-sm, #mainContent tbody td:first-child .font-bold.text-xs,
  #mainContent tbody td:first-child .font-bold.md\:text-xs, #mainContent tbody td:first-child .font-bold.text-sm { font-size: 14px; line-height: 1.35; white-space: normal; overflow-wrap: break-word; }
  /* Filas marcadas por legibilidad.py (antes, td:first-child:has(…) en cada fila).
     La clase repetida conserva la especificidad (1,3,2). */
  #mainContent tbody .ui-fila-nombre.ui-fila-nombre > td:first-child { min-width: 12rem; }
  /* Fichas con icono dentro del nombre («Bloqueado»): el icono no se separa del texto.
     html delante conserva la especificidad (1,3,4) de span:has(> :is(svg, i)). */
  html #mainContent tbody td:first-child .ui-fila-titulo > span.ui-ficha-con-icono { white-space: nowrap; }
  #mainContent tbody td.text-xs:not(:first-child),
  #mainContent tbody td:not(:first-child) .text-xs,
  #mainContent tbody td:not(:first-child) .md\:text-xs { font-size: 13px; }
}
/* Tablas Día D (10 columnas): celdas se quedan en 12 px; los encabezados suben de
   9 a 12 px con menos espaciado y pueden partirse en dos líneas para no ensanchar la tabla. */
#appBody .dd-mod .dd-tabla th { letter-spacing: .04em; white-space: normal; vertical-align: bottom; }
#appBody .dd-item-txt b:not([style*="font-size"]) { font-size: 14px; }
#appBody .dd-btn:not(.dd-btn-xs):not(.dd-btn-lg):not(.dd-btn-xl) { font-size: 13px; }
/* Pie de Modo Campo: con texto de 12 px, a 320 px el botón pasa a otra línea en lugar de salirse. */
#appBody .dd-campo-pie { flex-wrap: wrap; row-gap: 6px; }
#appBody .dd-campo-pie > .dd-btn { margin-left: auto; }

/* Consecuencias del piso de 12 px en cajas angostas. */
/* Etiquetas de KPI y de datos en mayúsculas («Inconsistencias», «Fuerza Empadronada»,
   «Resolución Física»): menos espaciado entre letras y, si una palabra aun así no
   cabe, se parte dentro de la caja (con guion donde el navegador sabe dividir en
   español) en lugar de salirse. */
#appBody .dd-kpi .dd-lbl { letter-spacing: .02em; overflow-wrap: break-word; hyphens: auto; }
#mainContent p.uppercase:is(.text-\[9px\], .text-\[10px\]) { letter-spacing: .02em; overflow-wrap: break-word; hyphens: auto; }
/* KPI de Día D con el menú lateral abierto (768–899 px): dos columnas en lugar de tres. */
@media (min-width: 768px) and (max-width: 899.98px) {
  #appBody .dd-mod .dd-grid-6:has(> .dd-kpi) { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
/* Alertas de meta del Panel Principal: título y dato en hasta dos líneas en vez de
   cortarse («Sección 9003: f…» perdía cuántos faltan). */
#appBody #dd_pt_alertas .dd-item-txt b, #appBody #dd_pt_alertas .dd-item-txt small {
  white-space: normal; overflow-wrap: break-word;
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2;
}
/* Mensajería: con la ficha de simpatía y el teléfono a 12 px, las columnas fijas
   (45/15/20/20 % de 550 px) no alcanzaban: la ficha invadía el teléfono, este se
   recortaba y el botón «Enviar» (128 px fijos) se salía de su celda. Con 680 px y
   36/20/20/24 % caben la ficha, el teléfono, el botón y un nombre común; por debajo
   de ese ancho la tabla se desplaza en horizontal, como ya lo hacía. */
#appBody #page-mensajeria table.table-fixed { min-width: 680px; }
#appBody #page-mensajeria table.table-fixed > thead th:nth-child(1) { width: 36%; }
#appBody #page-mensajeria table.table-fixed > thead th:nth-child(2) { width: 20%; }
#appBody #page-mensajeria table.table-fixed > thead th:nth-child(3) { width: 20%; }
#appBody #page-mensajeria table.table-fixed > thead th:nth-child(4) { width: 24%; }
/* Reportes · Cronología: «Hora exacta» y «Personal / Capturista» se enciman a 768 px
   con 9 % y 21 % de ancho; se les da un mínimo. */
#appBody #rep_vista_detalle table > thead th:nth-child(1) { width: max(9%, 7rem); }
#appBody #rep_vista_detalle table > thead th:nth-child(2) { width: max(21%, 11rem); }
/* Reportes · Perfil de Capturista: a 1024 px el selector se encogía a unos 30 px junto
   a los botones del período. Con 16rem se lee «Selecciona un Capturista...» completo y
   los botones del período pasan a otro renglón. */
#appBody #page-reportes .flex-1:has(> .relative > #perfil_capturista_trigger) { min-width: 16rem; }
/* Escala visual global por debajo de 100 % (zoom en #appBody): el piso de 12 px se
   ve más chico. No se compensa (casi todo el texto de trabajo mide 12 o 13 px y la
   escala dejaría de servir en pantallas chicas); la nota junto al control lo dice. */
#appBody .ui-escala-nota {
  margin: 8px 0 0; padding-left: 10px; border-left: 3px solid #c26a00;
  color: var(--ui-ink); font-size: 13px; line-height: 1.45; font-weight: 450;
}
html.dark #appBody .ui-escala-nota { border-left-color: #ffb454; }

/* 3. Contraste. Encabezado de Beneficiarios: el adaptador de superficies
   volvía blanco el fondo negro en tema claro (texto blanco sobre blanco). */
html:not(.dark) #appBody thead.bg-black { background-color: #1f2328; }

/* Marcadores de estado, avisos y enlaces de color sobre fondo claro: tono 700 de la
   misma familia (o el acento legible). Especificidad de una sola clase: las
   variantes hover:, group-hover: y dark: siguen mandando. En rojo, ámbar y naranja
   es de dos clases (la clase se repite): la lista :is() anterior tomaba la de su
   selector con atributo y así se conserva. Se excluye el texto dentro de tarjetas
   oscuras del tema claro (no los velos de las ventanas). */
:where(html:not(.dark) #appBody) .text-red-500.text-red-500:where(:not(:is(.bg-black, .bg-black\/40, .bg-slate-800, .bg-slate-800\/30, .bg-slate-800\/80, .bg-slate-900, .bg-slate-950, .bg-gray-900, .bg-indigo-900, .bg-indigo-950, .from-slate-800, .from-slate-900, .from-indigo-900, .from-indigo-950, .from-purple-900, .from-purple-950) *)),
:where(html:not(.dark) #appBody) .text-red-600.text-red-600:where(:not(:is(.bg-black, .bg-black\/40, .bg-slate-800, .bg-slate-800\/30, .bg-slate-800\/80, .bg-slate-900, .bg-slate-950, .bg-gray-900, .bg-indigo-900, .bg-indigo-950, .from-slate-800, .from-slate-900, .from-indigo-900, .from-indigo-950, .from-purple-900, .from-purple-950) *)),
:where(html:not(.dark) #appBody) .text-red-400[class*="hover:text-red"]:where(:not(:is(.bg-black, .bg-black\/40, .bg-slate-800, .bg-slate-800\/30, .bg-slate-800\/80, .bg-slate-900, .bg-slate-950, .bg-gray-900, .bg-indigo-900, .bg-indigo-950, .from-slate-800, .from-slate-900, .from-indigo-900, .from-indigo-950, .from-purple-900, .from-purple-950) *)) { color: #b91c1c; }
:where(html:not(.dark) #appBody) .text-rose-500:where(:not(:is(.bg-black, .bg-black\/40, .bg-slate-800, .bg-slate-800\/30, .bg-slate-800\/80, .bg-slate-900, .bg-slate-950, .bg-gray-900, .bg-indigo-900, .bg-indigo-950, .from-slate-800, .from-slate-900, .from-indigo-900, .from-indigo-950, .from-purple-900, .from-purple-950) *)),
:where(html:not(.dark) #appBody) .text-rose-600:where(:not(:is(.bg-black, .bg-black\/40, .bg-slate-800, .bg-slate-800\/30, .bg-slate-800\/80, .bg-slate-900, .bg-slate-950, .bg-gray-900, .bg-indigo-900, .bg-indigo-950, .from-slate-800, .from-slate-900, .from-indigo-900, .from-indigo-950, .from-purple-900, .from-purple-950) *)),
:where(html:not(.dark) #appBody) .text-rose-600\/80:where(:not(:is(.bg-black, .bg-black\/40, .bg-slate-800, .bg-slate-800\/30, .bg-slate-800\/80, .bg-slate-900, .bg-slate-950, .bg-gray-900, .bg-indigo-900, .bg-indigo-950, .from-slate-800, .from-slate-900, .from-indigo-900, .from-indigo-950, .from-purple-900, .from-purple-950) *)),
:where(html:not(.dark) #appBody) .text-rose-700\/70:where(:not(:is(.bg-black, .bg-black\/40, .bg-slate-800, .bg-slate-800\/30, .bg-slate-800\/80, .bg-slate-900, .bg-slate-950, .bg-gray-900, .bg-indigo-900, .bg-indigo-950, .from-slate-800, .from-slate-900, .from-indigo-900, .from-indigo-950, .from-purple-900, .from-purple-950) *)),
:where(html:not(.dark) #appBody) .text-rose-800\/50:where(:not(:is(.bg-black, .bg-black\/40, .bg-slate-800, .bg-slate-800\/30, .bg-slate-800\/80, .bg-slate-900, .bg-slate-950, .bg-gray-900, .bg-indigo-900, .bg-indigo-950, .from-slate-800, .from-slate-900, .from-indigo-900, .from-indigo-950, .from-purple-900, .from-purple-950) *)),
:where(html:not(.dark) #appBody) .text-rose-400\/50:where(:not(:is(.bg-black, .bg-black\/40, .bg-slate-800, .bg-slate-800\/30, .bg-slate-800\/80, .bg-slate-900, .bg-slate-950, .bg-gray-900, .bg-indigo-900, .bg-indigo-950, .from-slate-800, .from-slate-900, .from-indigo-900, .from-indigo-950, .from-purple-900, .from-purple-950) *)) { color: #be123c; }
:where(html:not(.dark) #appBody) .text-amber-500.text-amber-500:where(:not(:is(.bg-black, .bg-black\/40, .bg-slate-800, .bg-slate-800\/30, .bg-slate-800\/80, .bg-slate-900, .bg-slate-950, .bg-gray-900, .bg-indigo-900, .bg-indigo-950, .from-slate-800, .from-slate-900, .from-indigo-900, .from-indigo-950, .from-purple-900, .from-purple-950) *)),
:where(html:not(.dark) #appBody) .text-amber-600.text-amber-600:where(:not(:is(.bg-black, .bg-black\/40, .bg-slate-800, .bg-slate-800\/30, .bg-slate-800\/80, .bg-slate-900, .bg-slate-950, .bg-gray-900, .bg-indigo-900, .bg-indigo-950, .from-slate-800, .from-slate-900, .from-indigo-900, .from-indigo-950, .from-purple-900, .from-purple-950) *)),
:where(html:not(.dark) #appBody) .text-amber-700[class~="bg-amber-100"]:where(:not(:is(.bg-black, .bg-black\/40, .bg-slate-800, .bg-slate-800\/30, .bg-slate-800\/80, .bg-slate-900, .bg-slate-950, .bg-gray-900, .bg-indigo-900, .bg-indigo-950, .from-slate-800, .from-slate-900, .from-indigo-900, .from-indigo-950, .from-purple-900, .from-purple-950) *)),
:where(html:not(.dark) #appBody) .text-amber-600\/80.text-amber-600\/80:where(:not(:is(.bg-black, .bg-black\/40, .bg-slate-800, .bg-slate-800\/30, .bg-slate-800\/80, .bg-slate-900, .bg-slate-950, .bg-gray-900, .bg-indigo-900, .bg-indigo-950, .from-slate-800, .from-slate-900, .from-indigo-900, .from-indigo-950, .from-purple-900, .from-purple-950) *)),
:where(html:not(.dark) #appBody) .text-amber-600\/50.text-amber-600\/50:where(:not(:is(.bg-black, .bg-black\/40, .bg-slate-800, .bg-slate-800\/30, .bg-slate-800\/80, .bg-slate-900, .bg-slate-950, .bg-gray-900, .bg-indigo-900, .bg-indigo-950, .from-slate-800, .from-slate-900, .from-indigo-900, .from-indigo-950, .from-purple-900, .from-purple-950) *)),
:where(html:not(.dark) #appBody) .text-amber-700\/70.text-amber-700\/70:where(:not(:is(.bg-black, .bg-black\/40, .bg-slate-800, .bg-slate-800\/30, .bg-slate-800\/80, .bg-slate-900, .bg-slate-950, .bg-gray-900, .bg-indigo-900, .bg-indigo-950, .from-slate-800, .from-slate-900, .from-indigo-900, .from-indigo-950, .from-purple-900, .from-purple-950) *)),
:where(html:not(.dark) #appBody) .text-amber-700\/80.text-amber-700\/80:where(:not(:is(.bg-black, .bg-black\/40, .bg-slate-800, .bg-slate-800\/30, .bg-slate-800\/80, .bg-slate-900, .bg-slate-950, .bg-gray-900, .bg-indigo-900, .bg-indigo-950, .from-slate-800, .from-slate-900, .from-indigo-900, .from-indigo-950, .from-purple-900, .from-purple-950) *)),
:where(html:not(.dark) #appBody) .text-amber-400\/50.text-amber-400\/50:where(:not(:is(.bg-black, .bg-black\/40, .bg-slate-800, .bg-slate-800\/30, .bg-slate-800\/80, .bg-slate-900, .bg-slate-950, .bg-gray-900, .bg-indigo-900, .bg-indigo-950, .from-slate-800, .from-slate-900, .from-indigo-900, .from-indigo-950, .from-purple-900, .from-purple-950) *)) { color: #9f4b0b; }
:where(html:not(.dark) #appBody) .text-orange-500.text-orange-500:where(:not(:is(.bg-black, .bg-black\/40, .bg-slate-800, .bg-slate-800\/30, .bg-slate-800\/80, .bg-slate-900, .bg-slate-950, .bg-gray-900, .bg-indigo-900, .bg-indigo-950, .from-slate-800, .from-slate-900, .from-indigo-900, .from-indigo-950, .from-purple-900, .from-purple-950) *)),
:where(html:not(.dark) #appBody) .text-orange-600.text-orange-600:where(:not(:is(.bg-black, .bg-black\/40, .bg-slate-800, .bg-slate-800\/30, .bg-slate-800\/80, .bg-slate-900, .bg-slate-950, .bg-gray-900, .bg-indigo-900, .bg-indigo-950, .from-slate-800, .from-slate-900, .from-indigo-900, .from-indigo-950, .from-purple-900, .from-purple-950) *)),
:where(html:not(.dark) #appBody) .text-orange-500\/80.text-orange-500\/80:where(:not(:is(.bg-black, .bg-black\/40, .bg-slate-800, .bg-slate-800\/30, .bg-slate-800\/80, .bg-slate-900, .bg-slate-950, .bg-gray-900, .bg-indigo-900, .bg-indigo-950, .from-slate-800, .from-slate-900, .from-indigo-900, .from-indigo-950, .from-purple-900, .from-purple-950) *)),
:where(html:not(.dark) #appBody) .text-orange-700\/80.text-orange-700\/80:where(:not(:is(.bg-black, .bg-black\/40, .bg-slate-800, .bg-slate-800\/30, .bg-slate-800\/80, .bg-slate-900, .bg-slate-950, .bg-gray-900, .bg-indigo-900, .bg-indigo-950, .from-slate-800, .from-slate-900, .from-indigo-900, .from-indigo-950, .from-purple-900, .from-purple-950) *)),
:where(html:not(.dark) #appBody) .text-orange-400[class*="hover:bg-orange"]:where(:not(:is(.bg-black, .bg-black\/40, .bg-slate-800, .bg-slate-800\/30, .bg-slate-800\/80, .bg-slate-900, .bg-slate-950, .bg-gray-900, .bg-indigo-900, .bg-indigo-950, .from-slate-800, .from-slate-900, .from-indigo-900, .from-indigo-950, .from-purple-900, .from-purple-950) *)) { color: #b3400c; }
:where(html:not(.dark) #appBody) .text-emerald-500:where(:not(:is(.bg-black, .bg-black\/40, .bg-slate-800, .bg-slate-800\/30, .bg-slate-800\/80, .bg-slate-900, .bg-slate-950, .bg-gray-900, .bg-indigo-900, .bg-indigo-950, .from-slate-800, .from-slate-900, .from-indigo-900, .from-indigo-950, .from-purple-900, .from-purple-950) *)),
:where(html:not(.dark) #appBody) .text-emerald-600:where(:not(:is(.bg-black, .bg-black\/40, .bg-slate-800, .bg-slate-800\/30, .bg-slate-800\/80, .bg-slate-900, .bg-slate-950, .bg-gray-900, .bg-indigo-900, .bg-indigo-950, .from-slate-800, .from-slate-900, .from-indigo-900, .from-indigo-950, .from-purple-900, .from-purple-950) *)),
:where(html:not(.dark) #appBody) .text-emerald-700\/70:where(:not(:is(.bg-black, .bg-black\/40, .bg-slate-800, .bg-slate-800\/30, .bg-slate-800\/80, .bg-slate-900, .bg-slate-950, .bg-gray-900, .bg-indigo-900, .bg-indigo-950, .from-slate-800, .from-slate-900, .from-indigo-900, .from-indigo-950, .from-purple-900, .from-purple-950) *)),
:where(html:not(.dark) #appBody) .text-emerald-700\/80:where(:not(:is(.bg-black, .bg-black\/40, .bg-slate-800, .bg-slate-800\/30, .bg-slate-800\/80, .bg-slate-900, .bg-slate-950, .bg-gray-900, .bg-indigo-900, .bg-indigo-950, .from-slate-800, .from-slate-900, .from-indigo-900, .from-indigo-950, .from-purple-900, .from-purple-950) *)) { color: #047857; }
:where(html:not(.dark) #appBody) .text-sky-500:where(:not(:is(.bg-black, .bg-black\/40, .bg-slate-800, .bg-slate-800\/30, .bg-slate-800\/80, .bg-slate-900, .bg-slate-950, .bg-gray-900, .bg-indigo-900, .bg-indigo-950, .from-slate-800, .from-slate-900, .from-indigo-900, .from-indigo-950, .from-purple-900, .from-purple-950) *)),
:where(html:not(.dark) #appBody) .text-sky-600:where(:not(:is(.bg-black, .bg-black\/40, .bg-slate-800, .bg-slate-800\/30, .bg-slate-800\/80, .bg-slate-900, .bg-slate-950, .bg-gray-900, .bg-indigo-900, .bg-indigo-950, .from-slate-800, .from-slate-900, .from-indigo-900, .from-indigo-950, .from-purple-900, .from-purple-950) *)),
:where(html:not(.dark) #appBody) .text-sky-600\/80:where(:not(:is(.bg-black, .bg-black\/40, .bg-slate-800, .bg-slate-800\/30, .bg-slate-800\/80, .bg-slate-900, .bg-slate-950, .bg-gray-900, .bg-indigo-900, .bg-indigo-950, .from-slate-800, .from-slate-900, .from-indigo-900, .from-indigo-950, .from-purple-900, .from-purple-950) *)),
:where(html:not(.dark) #appBody) .text-sky-700\/80:where(:not(:is(.bg-black, .bg-black\/40, .bg-slate-800, .bg-slate-800\/30, .bg-slate-800\/80, .bg-slate-900, .bg-slate-950, .bg-gray-900, .bg-indigo-900, .bg-indigo-950, .from-slate-800, .from-slate-900, .from-indigo-900, .from-indigo-950, .from-purple-900, .from-purple-950) *)) { color: #0369a1; }
:where(html:not(.dark) #appBody) .text-blue-500:where(:not(:is(.bg-black, .bg-black\/40, .bg-slate-800, .bg-slate-800\/30, .bg-slate-800\/80, .bg-slate-900, .bg-slate-950, .bg-gray-900, .bg-indigo-900, .bg-indigo-950, .from-slate-800, .from-slate-900, .from-indigo-900, .from-indigo-950, .from-purple-900, .from-purple-950) *)),
:where(html:not(.dark) #appBody) .text-blue-600:where(:not(:is(.bg-black, .bg-black\/40, .bg-slate-800, .bg-slate-800\/30, .bg-slate-800\/80, .bg-slate-900, .bg-slate-950, .bg-gray-900, .bg-indigo-900, .bg-indigo-950, .from-slate-800, .from-slate-900, .from-indigo-900, .from-indigo-950, .from-purple-900, .from-purple-950) *)) { color: #1d4ed8; }
:where(html:not(.dark) #appBody) .text-violet-500:where(:not(:is(.bg-black, .bg-black\/40, .bg-slate-800, .bg-slate-800\/30, .bg-slate-800\/80, .bg-slate-900, .bg-slate-950, .bg-gray-900, .bg-indigo-900, .bg-indigo-950, .from-slate-800, .from-slate-900, .from-indigo-900, .from-indigo-950, .from-purple-900, .from-purple-950) *)),
:where(html:not(.dark) #appBody) .text-purple-500:where(:not(:is(.bg-black, .bg-black\/40, .bg-slate-800, .bg-slate-800\/30, .bg-slate-800\/80, .bg-slate-900, .bg-slate-950, .bg-gray-900, .bg-indigo-900, .bg-indigo-950, .from-slate-800, .from-slate-900, .from-indigo-900, .from-indigo-950, .from-purple-900, .from-purple-950) *)),
:where(html:not(.dark) #appBody) .text-violet-600\/50:where(:not(:is(.bg-black, .bg-black\/40, .bg-slate-800, .bg-slate-800\/30, .bg-slate-800\/80, .bg-slate-900, .bg-slate-950, .bg-gray-900, .bg-indigo-900, .bg-indigo-950, .from-slate-800, .from-slate-900, .from-indigo-900, .from-indigo-950, .from-purple-900, .from-purple-950) *)),
:where(html:not(.dark) #appBody) .text-violet-400\/50:where(:not(:is(.bg-black, .bg-black\/40, .bg-slate-800, .bg-slate-800\/30, .bg-slate-800\/80, .bg-slate-900, .bg-slate-950, .bg-gray-900, .bg-indigo-900, .bg-indigo-950, .from-slate-800, .from-slate-900, .from-indigo-900, .from-indigo-950, .from-purple-900, .from-purple-950) *)) { color: #6d28d9; }
:where(html:not(.dark) #appBody) .text-indigo-600\/80:where(:not(:is(.bg-black, .bg-black\/40, .bg-slate-800, .bg-slate-800\/30, .bg-slate-800\/80, .bg-slate-900, .bg-slate-950, .bg-gray-900, .bg-indigo-900, .bg-indigo-950, .from-slate-800, .from-slate-900, .from-indigo-900, .from-indigo-950, .from-purple-900, .from-purple-950) *)),
:where(html:not(.dark) #appBody) .text-indigo-700\/70:where(:not(:is(.bg-black, .bg-black\/40, .bg-slate-800, .bg-slate-800\/30, .bg-slate-800\/80, .bg-slate-900, .bg-slate-950, .bg-gray-900, .bg-indigo-900, .bg-indigo-950, .from-slate-800, .from-slate-900, .from-indigo-900, .from-indigo-950, .from-purple-900, .from-purple-950) *)),
:where(html:not(.dark) #appBody) .text-indigo-700\/80:where(:not(:is(.bg-black, .bg-black\/40, .bg-slate-800, .bg-slate-800\/30, .bg-slate-800\/80, .bg-slate-900, .bg-slate-950, .bg-gray-900, .bg-indigo-900, .bg-indigo-950, .from-slate-800, .from-slate-900, .from-indigo-900, .from-indigo-950, .from-purple-900, .from-purple-950) *)) { color: var(--ui-accent-legible); }

/* Tema oscuro: clases pensadas para fondo claro que no declaran variante dark:.
   Se aclaran si el elemento no tiene fondo propio o su fondo pasa a oscuro
   (dark:bg-*, o blanco/gris claro que el adaptador vuelve superficie);
   si declara dark:text-*, esa gana. */
:where(html.dark #appBody) .text-red-500:where(:not([class*="bg-"]), [class*="dark:bg-"], .bg-white, .bg-slate-50, .bg-slate-100),
:where(html.dark #appBody) .text-red-600:where(:not([class*="bg-"]), [class*="dark:bg-"], .bg-white, .bg-slate-50, .bg-slate-100),
:where(html.dark #appBody) .text-red-700:where(:not([class*="bg-"]), [class*="dark:bg-"], .bg-white, .bg-slate-50, .bg-slate-100) { color: #f87171; }
:where(html.dark #appBody) .text-rose-500:where(:not([class*="bg-"]), [class*="dark:bg-"], .bg-white, .bg-slate-50, .bg-slate-100),
:where(html.dark #appBody) .text-rose-600:where(:not([class*="bg-"]), [class*="dark:bg-"], .bg-white, .bg-slate-50, .bg-slate-100),
:where(html.dark #appBody) .text-rose-700:where(:not([class*="bg-"]), [class*="dark:bg-"], .bg-white, .bg-slate-50, .bg-slate-100),
:where(html.dark #appBody) .text-rose-400\/50:where(:not([class*="bg-"]), [class*="dark:bg-"], .bg-white, .bg-slate-50, .bg-slate-100),
:where(html.dark #appBody) .text-rose-400\/70:where(:not([class*="bg-"]), [class*="dark:bg-"], .bg-white, .bg-slate-50, .bg-slate-100) { color: #fb7185; }
:where(html.dark #appBody) .text-emerald-600:where(:not([class*="bg-"]), [class*="dark:bg-"], .bg-white, .bg-slate-50, .bg-slate-100),
:where(html.dark #appBody) .text-emerald-700:where(:not([class*="bg-"]), [class*="dark:bg-"], .bg-white, .bg-slate-50, .bg-slate-100),
:where(html.dark #appBody) .text-emerald-400\/70:where(:not([class*="bg-"]), [class*="dark:bg-"], .bg-white, .bg-slate-50, .bg-slate-100) { color: #34d399; }
:where(html.dark #appBody) .text-blue-500:where(:not([class*="bg-"]), [class*="dark:bg-"], .bg-white, .bg-slate-50, .bg-slate-100),
:where(html.dark #appBody) .text-blue-600:where(:not([class*="bg-"]), [class*="dark:bg-"], .bg-white, .bg-slate-50, .bg-slate-100),
:where(html.dark #appBody) .text-blue-700:where(:not([class*="bg-"]), [class*="dark:bg-"], .bg-white, .bg-slate-50, .bg-slate-100) { color: #60a5fa; }
:where(html.dark #appBody) .text-amber-600:where(:not([class*="bg-"]), [class*="dark:bg-"], .bg-white, .bg-slate-50, .bg-slate-100),
:where(html.dark #appBody) .text-amber-700:where(:not([class*="bg-"]), [class*="dark:bg-"], .bg-white, .bg-slate-50, .bg-slate-100),
:where(html.dark #appBody) .text-amber-400\/50:where(:not([class*="bg-"]), [class*="dark:bg-"], .bg-white, .bg-slate-50, .bg-slate-100),
:where(html.dark #appBody) .text-amber-400\/70:where(:not([class*="bg-"]), [class*="dark:bg-"], .bg-white, .bg-slate-50, .bg-slate-100),
:where(html.dark #appBody) .text-amber-400\/80:where(:not([class*="bg-"]), [class*="dark:bg-"], .bg-white, .bg-slate-50, .bg-slate-100) { color: #fbbf24; }
:where(html.dark #appBody) .text-violet-500:where(:not([class*="bg-"]), [class*="dark:bg-"], .bg-white, .bg-slate-50, .bg-slate-100),
:where(html.dark #appBody) .text-violet-600:where(:not([class*="bg-"]), [class*="dark:bg-"], .bg-white, .bg-slate-50, .bg-slate-100),
:where(html.dark #appBody) .text-purple-500:where(:not([class*="bg-"]), [class*="dark:bg-"], .bg-white, .bg-slate-50, .bg-slate-100),
:where(html.dark #appBody) .text-purple-600:where(:not([class*="bg-"]), [class*="dark:bg-"], .bg-white, .bg-slate-50, .bg-slate-100),
:where(html.dark #appBody) .text-violet-400\/50:where(:not([class*="bg-"]), [class*="dark:bg-"], .bg-white, .bg-slate-50, .bg-slate-100),
:where(html.dark #appBody) .text-violet-600\/50:where(:not([class*="bg-"]), [class*="dark:bg-"], .bg-white, .bg-slate-50, .bg-slate-100) { color: #c4b5fd; }
:where(html.dark #appBody) .text-sky-600:where(:not([class*="bg-"]), [class*="dark:bg-"], .bg-white, .bg-slate-50, .bg-slate-100),
:where(html.dark #appBody) .text-sky-700:where(:not([class*="bg-"]), [class*="dark:bg-"], .bg-white, .bg-slate-50, .bg-slate-100),
:where(html.dark #appBody) .text-sky-600\/80:where(:not([class*="bg-"]), [class*="dark:bg-"], .bg-white, .bg-slate-50, .bg-slate-100) { color: #38bdf8; }
:where(html.dark #appBody) .text-orange-400\/80:where(:not([class*="bg-"]), [class*="dark:bg-"], .bg-white, .bg-slate-50, .bg-slate-100),
:where(html.dark #appBody) .text-orange-500\/80:where(:not([class*="bg-"]), [class*="dark:bg-"], .bg-white, .bg-slate-50, .bg-slate-100) { color: #fb923c; }
:where(html.dark #appBody) .text-indigo-300\/60:where(:not([class*="bg-"]), [class*="dark:bg-"], .bg-white, .bg-slate-50, .bg-slate-100),
:where(html.dark #appBody) .text-indigo-300\/70:where(:not([class*="bg-"]), [class*="dark:bg-"], .bg-white, .bg-slate-50, .bg-slate-100),
:where(html.dark #appBody) .text-indigo-300\/80:where(:not([class*="bg-"]), [class*="dark:bg-"], .bg-white, .bg-slate-50, .bg-slate-100),
:where(html.dark #appBody) .text-indigo-400\/70:where(:not([class*="bg-"]), [class*="dark:bg-"], .bg-white, .bg-slate-50, .bg-slate-100),
:where(html.dark #appBody) .text-indigo-400\/80:where(:not([class*="bg-"]), [class*="dark:bg-"], .bg-white, .bg-slate-50, .bg-slate-100) { color: #a5b4fc; }
/* Fichas de fondo claro sin variante dark: siguen claras: texto 700. */
:where(html.dark #appBody) .text-red-500:where([class~="bg-red-50"], [class~="bg-red-100"]):where(:not([class*="dark:bg-"])),
:where(html.dark #appBody) .text-red-600:where([class~="bg-red-50"], [class~="bg-red-100"]):where(:not([class*="dark:bg-"])) { color: #b91c1c; }
:where(html.dark #appBody) .text-rose-500:where([class~="bg-rose-50"], [class~="bg-rose-100"]):where(:not([class*="dark:bg-"])),
:where(html.dark #appBody) .text-rose-600:where([class~="bg-rose-50"], [class~="bg-rose-100"]):where(:not([class*="dark:bg-"])) { color: #be123c; }
:where(html.dark #appBody) .text-amber-500:where([class~="bg-amber-50"], [class~="bg-amber-100"]):where(:not([class*="dark:bg-"])),
:where(html.dark #appBody) .text-amber-600:where([class~="bg-amber-50"], [class~="bg-amber-100"]):where(:not([class*="dark:bg-"])) { color: #9f4b0b; }
:where(html.dark #appBody) .text-emerald-500:where([class~="bg-emerald-50"], [class~="bg-emerald-100"]):where(:not([class*="dark:bg-"])),
:where(html.dark #appBody) .text-emerald-600:where([class~="bg-emerald-50"], [class~="bg-emerald-100"]):where(:not([class*="dark:bg-"])) { color: #047857; }
:where(html.dark #appBody) .text-sky-500:where([class~="bg-sky-50"], [class~="bg-sky-100"]):where(:not([class*="dark:bg-"])),
:where(html.dark #appBody) .text-sky-600:where([class~="bg-sky-50"], [class~="bg-sky-100"]):where(:not([class*="dark:bg-"])) { color: #0369a1; }
:where(html.dark #appBody) .text-slate-700:where(.bg-white) { color: var(--ui-ink); }
/* Variantes dark: con opacidad (…/50, /70, /80): mismo tono, opaco. */
html.dark #appBody .dark\:text-emerald-400\/70 { color: #34d399; }
html.dark #appBody .dark\:text-amber-400\/50 { color: #fbbf24; }
html.dark #appBody .dark\:text-amber-400\/70 { color: #fbbf24; }
html.dark #appBody .dark\:text-amber-400\/80 { color: #fbbf24; }
html.dark #appBody .dark\:text-indigo-300\/80 { color: #c7d2fe; }
html.dark #appBody .dark\:text-indigo-400\/70 { color: #a5b4fc; }
html.dark #appBody .dark\:text-indigo-400\/80 { color: #a5b4fc; }
html.dark #appBody .dark\:text-orange-400\/80 { color: #fb923c; }
html.dark #appBody .dark\:text-orange-500\/80 { color: #fb923c; }
html.dark #appBody .dark\:text-rose-300\/50 { color: #fda4af; }
html.dark #appBody .dark\:text-rose-400\/70 { color: #fb7185; }
html.dark #appBody .dark\:text-violet-400\/50 { color: #c4b5fd; }


/* Fondos saturados con texto blanco (botones y fichas): tono más oscuro de la
   misma familia, también al pasar el cursor; se respeta un dark:bg-* declarado. */
:where(#appBody) .bg-amber-400:where(.text-white:not([class*=" dark:bg-"], [class^="dark:bg-"])),
:where(#appBody) .bg-amber-500:where(.text-white:not([class*=" dark:bg-"], [class^="dark:bg-"])),
:where(#appBody) .bg-amber-600:where(.text-white:not([class*=" dark:bg-"], [class^="dark:bg-"])) { background-color: #b45309; }
:where(#appBody) .bg-emerald-400:where(.text-white:not([class*=" dark:bg-"], [class^="dark:bg-"])),
:where(#appBody) .bg-emerald-500:where(.text-white:not([class*=" dark:bg-"], [class^="dark:bg-"])),
:where(#appBody) .bg-emerald-600:where(.text-white:not([class*=" dark:bg-"], [class^="dark:bg-"])) { background-color: #047857; }
:where(#appBody) .bg-sky-400:where(.text-white:not([class*=" dark:bg-"], [class^="dark:bg-"])),
:where(#appBody) .bg-sky-500:where(.text-white:not([class*=" dark:bg-"], [class^="dark:bg-"])),
:where(#appBody) .bg-sky-600:where(.text-white:not([class*=" dark:bg-"], [class^="dark:bg-"])) { background-color: #0369a1; }
:where(#appBody) .bg-blue-500:where(.text-white:not([class*=" dark:bg-"], [class^="dark:bg-"])) { background-color: #2563eb; }
:where(#appBody) .bg-red-500:where(.text-white:not([class*=" dark:bg-"], [class^="dark:bg-"])) { background-color: #dc2626; }
:where(#appBody) .bg-rose-400:where(.text-white:not([class*=" dark:bg-"], [class^="dark:bg-"])),
:where(#appBody) .bg-rose-500:where(.text-white:not([class*=" dark:bg-"], [class^="dark:bg-"])) { background-color: #e11d48; }
:where(#appBody) .bg-orange-500:where(.text-white:not([class*=" dark:bg-"], [class^="dark:bg-"])),
:where(#appBody) .bg-orange-600:where(.text-white:not([class*=" dark:bg-"], [class^="dark:bg-"])) { background-color: #c2410c; }
:where(#appBody) .bg-teal-500:where(.text-white:not([class*=" dark:bg-"], [class^="dark:bg-"])) { background-color: #0f766e; }
:where(#appBody) .bg-purple-500:where(.text-white:not([class*=" dark:bg-"], [class^="dark:bg-"])) { background-color: #9333ea; }
:where(#appBody) .bg-violet-500:where(.text-white:not([class*=" dark:bg-"], [class^="dark:bg-"])) { background-color: #7c3aed; }
:where(#appBody) .bg-\[\#25D366\]:where(.text-white:not([class*=" dark:bg-"], [class^="dark:bg-"])) { background-color: #0e7a6d; }
:where(#appBody) .bg-amber-400:where(.text-white:not([class*=" dark:bg-"], [class^="dark:bg-"])[class*="hover:bg-"]):hover,
:where(#appBody) .bg-amber-500:where(.text-white:not([class*=" dark:bg-"], [class^="dark:bg-"])[class*="hover:bg-"]):hover,
:where(#appBody) .bg-amber-600:where(.text-white:not([class*=" dark:bg-"], [class^="dark:bg-"])[class*="hover:bg-"]):hover { background-color: #92400e; }
:where(#appBody) .bg-emerald-400:where(.text-white:not([class*=" dark:bg-"], [class^="dark:bg-"])[class*="hover:bg-"]):hover,
:where(#appBody) .bg-emerald-500:where(.text-white:not([class*=" dark:bg-"], [class^="dark:bg-"])[class*="hover:bg-"]):hover,
:where(#appBody) .bg-emerald-600:where(.text-white:not([class*=" dark:bg-"], [class^="dark:bg-"])[class*="hover:bg-"]):hover { background-color: #065f46; }
:where(#appBody) .bg-sky-400:where(.text-white:not([class*=" dark:bg-"], [class^="dark:bg-"])[class*="hover:bg-"]):hover,
:where(#appBody) .bg-sky-500:where(.text-white:not([class*=" dark:bg-"], [class^="dark:bg-"])[class*="hover:bg-"]):hover,
:where(#appBody) .bg-sky-600:where(.text-white:not([class*=" dark:bg-"], [class^="dark:bg-"])[class*="hover:bg-"]):hover { background-color: #075985; }
:where(#appBody) .bg-blue-500:where(.text-white:not([class*=" dark:bg-"], [class^="dark:bg-"])[class*="hover:bg-"]):hover { background-color: #1d4ed8; }
:where(#appBody) .bg-red-500:where(.text-white:not([class*=" dark:bg-"], [class^="dark:bg-"])[class*="hover:bg-"]):hover { background-color: #b91c1c; }
:where(#appBody) .bg-rose-400:where(.text-white:not([class*=" dark:bg-"], [class^="dark:bg-"])[class*="hover:bg-"]):hover,
:where(#appBody) .bg-rose-500:where(.text-white:not([class*=" dark:bg-"], [class^="dark:bg-"])[class*="hover:bg-"]):hover { background-color: #be123c; }
:where(#appBody) .bg-orange-500:where(.text-white:not([class*=" dark:bg-"], [class^="dark:bg-"])[class*="hover:bg-"]):hover,
:where(#appBody) .bg-orange-600:where(.text-white:not([class*=" dark:bg-"], [class^="dark:bg-"])[class*="hover:bg-"]):hover { background-color: #9a3412; }
:where(#appBody) .bg-teal-500:where(.text-white:not([class*=" dark:bg-"], [class^="dark:bg-"])[class*="hover:bg-"]):hover { background-color: #115e59; }
:where(#appBody) .bg-purple-500:where(.text-white:not([class*=" dark:bg-"], [class^="dark:bg-"])[class*="hover:bg-"]):hover { background-color: #7e22ce; }
:where(#appBody) .bg-violet-500:where(.text-white:not([class*=" dark:bg-"], [class^="dark:bg-"])[class*="hover:bg-"]):hover { background-color: #6d28d9; }
:where(#appBody) .bg-\[\#25D366\]:where(.text-white:not([class*=" dark:bg-"], [class^="dark:bg-"])[class*="hover:bg-"]):hover { background-color: #075e54; }
:where(#appBody) .bg-red-600\/90:where(.text-white) { background-color: rgb(185 28 28 / 90%); }
:where(#appBody) .from-emerald-600:where(.text-white) { --tw-gradient-from: #047857 var(--tw-gradient-from-position); }
:where(#appBody) .to-teal-600:where(.text-white) { --tw-gradient-to: #0f766e var(--tw-gradient-to-position); }
/* Vista previa de mensajería: verde más oscuro de la misma marca (antes 3.03:1). */
:where(#appBody) .bg-\[\#00a884\] { background-color: #008069; }
:where(#appBody) .bg-\[\#00a884\] .text-emerald-100 { color: #ecfdf5; }
/* Estados vacíos atenuados con opacidad: el gris secundario ya marca la jerarquía. */
#appBody .text-slate-400.opacity-60, #appBody .text-slate-400.opacity-70,
#appBody .text-slate-500.opacity-60, #appBody .text-slate-500.opacity-70 { opacity: 1; }

/* Grises: el adaptador aclaraba slate-600 a --ui-muted; sobre slate-200 quedaba en 4.49:1. */
#appBody .tv-cuenta, #appBody .tv-nota, #appBody .tv-pie { color: var(--ui-muted); }
html.dark #appBody .tv-vista.es-activa { background: #4f46e5; border-color: #4f46e5; }
/* Pantallas, tema claro: vistas no seleccionadas #64748b sobre #f1f5f9 daban 4.34:1;
   con #475569, 6.9:1 (y #334155 al pasar el cursor, como antes). */
html:not(.dark) #appBody .tv-vista:not(.es-activa) { color: #475569; }
html:not(.dark) #appBody .tv-vista:not(.es-activa):hover { color: #334155; }
/* Expediente: el identificador del documento era gris claro sobre blanco (1.48:1). */
#appBody #mp_id_doc { color: var(--ui-muted); }
/* Texto de ejemplo en campos: mismo gris secundario, opaco (antes #9ca3af, 2.54:1). */
#appBody :is(input, textarea)::placeholder { color: var(--ui-muted); opacity: 1; }

/* Día D: estados (En curso, Crítica, Meta cumplida…) y botones de color. */
html:not(.dark) #appBody .dd-mod {
  --dd-verde: #047857; --dd-ambar: #9f4b0b; --dd-rojo: #be123c; --dd-azul: #0369a1; --dd-morado: #6d28d9;
}
html:not(.dark) #appBody #page-estadisticas { --est-verde: #047857; --est-ambar: #9f4b0b; --est-rojo: #be123c; }
html.dark #appBody .dd-mod .dd-chip-azul { color: #7dd3fc; }
html.dark #appBody .dd-mod .dd-btn-verde { background: #047857; border-color: #047857; }
html.dark #appBody .dd-mod .dd-btn-rojo { background: #be123c; border-color: #be123c; }
html.dark #appBody .dd-mod .dd-btn-ambar { background: #b45309; border-color: #b45309; }
#appBody .dd-mod .dd-btn-ambar { color: #fff; }

/* 4. Color de marca configurable (aplicarColorTema): texto sobre la marca con
   --ui-on-primary (blanco o tinta) y acento como texto con --ui-accent-legible.
   Especificidad (2,0,0), la de la lista :is() anterior (por #loginBtn), para seguir
   ganando a la regla de los botones de marca de arriba: id repetido y el resto dentro
   de :where(). */
#appBody #loginBtn, #appBody#appBody :where(button.bg-indigo-600), #appBody#appBody :where(button.bg-indigo-500),
#appBody#appBody :where(.dd-btn-primario), #appBody#appBody :where(.dd-tab-on),
#appBody#appBody :where(.dd-ayuda-btn:hover) { color: var(--ui-on-primary); }
/* (1,2,1) en los hijos, como antes: html delante de la clase sola. */
#appBody .bg-indigo-600.text-white, html #appBody .bg-indigo-600 > .text-white,
#appBody .bg-indigo-600 > svg.lucide { color: var(--ui-on-primary); }
#appBody .bg-indigo-500:where(.text-white), #appBody .bg-indigo-400:where(.text-white) { background-color: var(--ui-primary); color: var(--ui-on-primary); }
#appBody .dd-ayuda-n, #appBody .dd-nav-nuevo { background: var(--ui-primary); color: var(--ui-on-primary); }
#appBody #page-estadisticas .est-tab-on, #appBody #page-estadisticas .est-tab-on:hover { background: var(--ui-primary); color: var(--ui-on-primary); }
#appBody .text-indigo-500, #appBody .text-indigo-600, #appBody .text-indigo-700 { color: var(--ui-accent-legible); }
#sidebar .sidebar-item.active, #appBody .tab-btn.active, #appBody .mv-tab.mv-activo { color: var(--ui-accent-legible); }
/* (2,0,1), como la regla de superficies del principio a la que corrige. */
html #appBody #page-estadisticas, html #appBody#appBody :where(.dd-mod) { --dd-indigo: var(--ui-accent-legible); --est-indigo: var(--ui-accent-legible); }

/* 5. Marca de agua (H03): perceptible como disuasión, sin competir con el texto.
   Antes gris al 15 % y peso 500; ahora 9 % y peso normal. Sigue aria-hidden. */
#appBody .watermark-text { color: rgb(128 128 128 / 9%); font-weight: 400; }
html.dark #appBody .watermark-text { color: rgb(170 170 170 / 8%); }

/* ── Etapa 2 · tablas: catálogo de grupos y Mensajería en el teléfono ── */

/* Catálogo de grupos. A 390 px la barra de herramientas se salía de la tarjeta
   («Crear nuevo grupo» quedaba cortado y el buscador medía unos 70 px) y la tabla
   solo dejaba ver su primera columna. En el teléfono cada grupo pasa a ser un
   bloque, como en las demás listas que se vuelven tarjetas (Beneficiarios,
   asignaciones, Seguridad): nombre y datos, avance y acciones. Los encabezados
   se quedan arriba como barra de orden («Fecha de creación», «Progreso / Meta»). */
/* La barra de herramientas pasa a otro renglón cuando no cabe (también de 768 a
   unos 1000 px con el menú lateral abierto, donde «Crear nuevo grupo» se salía);
   en pantallas anchas cabe en una línea y no cambia. */
#appBody .ui-grupos-herramientas { flex-wrap: wrap; }
@media (max-width: 767.98px) {
  /* Icono y título en el primer renglón; los contadores, debajo. */
  #appBody .ui-grupos-titulo { flex-wrap: wrap; row-gap: 8px; }
  #appBody .ui-grupos-titulo > div:nth-child(2) { flex: 1 1 calc(100% - 52px); min-width: 0; }
  #appBody .ui-grupos-titulo > span { margin-left: 0; }
  #appBody .ui-grupos-herramientas > .flex-1 { flex: 1 1 100%; }
  #appBody .ui-grupos-herramientas > button { flex: 1 1 auto; justify-content: center; min-height: 44px; }
  #appBody #contenedorDropdownFiltroSeccional { flex: 1 1 auto; }
  #appBody #btnDropdownFiltroSeccional { width: 100%; min-height: 44px; }
  #appBody #btnDropdownFiltroSeccional > #chevronFiltroSeccional { margin-left: auto; }

  #appBody .ui-tabla-tarjetas,
  #appBody .ui-tabla-tarjetas > thead,
  #appBody .ui-tabla-tarjetas > tbody,
  #appBody .ui-tabla-tarjetas > tbody > tr,
  #appBody .ui-tabla-tarjetas > tbody > tr > td { display: block; width: 100%; }
  #appBody .ui-tabla-tarjetas > thead > tr { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 16px; padding: 10px 16px; }
  #appBody .ui-tabla-tarjetas > thead > tr > th { display: block; width: auto; padding: 0; text-align: left; }
  #appBody #btnOrdenFechaGrupos { min-height: 40px; }
  /* «Acciones y gestión»: en el bloque, cada botón ya dice lo que hace. */
  #appBody .ui-tabla-tarjetas > thead > tr > th:last-child { display: none; }
  #appBody .ui-tabla-tarjetas > tbody > tr:not(.ui-estado-fila) > td { padding: 6px 16px; text-align: left; }
  #appBody .ui-tabla-tarjetas > tbody > tr:not(.ui-estado-fila) > td:first-child { padding-top: 16px; }
  #appBody .ui-tabla-tarjetas > tbody > tr:not(.ui-estado-fila) > td:last-child { padding-bottom: 16px; }
  /* Avance alineado con el texto del bloque, no centrado. */
  #appBody .ui-tabla-tarjetas > tbody > tr:not(.ui-estado-fila) > td:nth-child(2) > div { margin-inline: 0; max-width: 16rem; }
  /* Acciones: «Integrantes» y «Editar» en un renglón; «Borrar», en el suyo, al
     final y a la derecha (como en Beneficiarios), con 40 px de alto. */
  #appBody .ui-tabla-tarjetas > tbody > tr:not(.ui-estado-fila) > td:last-child > div {
    display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px;
  }
  #appBody .ui-tabla-tarjetas > tbody > tr:not(.ui-estado-fila) > td:last-child > div > button { min-height: 40px; }
  #appBody .ui-tabla-tarjetas > tbody > tr:not(.ui-estado-fila) > td:last-child > div > .ui-accion-peligro {
    grid-column: 1 / -1; justify-self: end; min-width: 128px; margin: 4px 0 0;
  }
  #appBody .ui-tabla-tarjetas .ui-accion-aparte::before { display: none; }

  /* Mensajería: «Ver expediente» también en el teléfono (antes solo desde 640 px),
     con 40 px para el dedo. */
  #appBody #tablaMensajeria [data-ui-accion="expediente"] { width: 40px; height: 40px; }
}

/* ── Etapa 2 · filtros_movil: listas restantes ──
   Resumen de filtros (UIFiltros) en la asignación de apoyos, grupos y gremios,
   Mensajería, el directorio de Seguridad y Reportes. Usa los estilos comunes de
   .ui-filtros-resumen; aquí solo lo propio de cada lugar. */

/* Reportes: la barra heredada de filtros activos es ahora el resumen, dentro de
   la tarjeta de filtros: sin fondo ni borde inferior propios, con la línea
   superior que ya tenía la barra. */
#appBody #rep_active_filters_bar {
  padding: 10px 0 0; border-bottom: 0; border-top: 1px solid var(--ui-line); background: transparent;
}
/* Su botón heredado se oculta cuando el resumen está listo (queda el del resumen);
   si el script no carga, sigue a la vista. */
#appBody #rep_active_filters_bar[data-ui-listo] > button[onclick^="limpiarFiltrosProductividad"] { display: none; }
/* La regla heredada de 24 px para los chips de Reportes no debe achicar los del resumen. */
#appBody #rep_active_filters_chips .ui-filtro-chip,
#appBody #rep_active_filters_chips .ui-filtros-limpiar { min-width: 0; min-height: 32px; }
@media (max-width: 767.98px) {
  #appBody #rep_active_filters_chips .ui-filtro-chip,
  #appBody #rep_active_filters_chips .ui-filtros-limpiar { min-height: 44px; }
}

/* ── Etapa 2 · formularios: aviso junto al campo (posible registro existente) ── */
/* Aviso que no es un error: no bloquea, no marca el campo como inválido y no
   mueve el foco (lo llena la verificación temprana de duplicados de Nuevo
   Registro). Usa el par de aviso de .ui-status-warning (7.5:1 en claro y 10.6:1
   en oscuro). Vacío no ocupa lugar. */
#appBody .ui-campo-aviso:empty { display: none; }
#appBody .ui-campo-aviso {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; margin: 8px 0 0; padding: 10px 12px;
  border: 1px solid #e8c37a; border-radius: 12px; background: #fffbeb; color: #854000;
  font-size: 13px; line-height: 1.45; font-weight: 500; text-transform: none; letter-spacing: 0; text-align: left;
}
html.dark #appBody .ui-campo-aviso { border-color: #a17b39; background: #452a09; color: #fde68a; }
#appBody .ui-campo-aviso-texto { flex: 1 1 14rem; margin: 0; }
#appBody .ui-campo-aviso-texto > strong { font-weight: 700; }
#appBody .ui-campo-aviso-accion {
  min-height: 36px; padding: 6px 14px; border: 1px solid currentColor; border-radius: 10px;
  background: transparent; color: inherit; font-size: 13px; font-weight: 700; cursor: pointer;
}
#appBody .ui-campo-aviso-accion:hover { background: rgb(133 64 0 / 8%); }
html.dark #appBody .ui-campo-aviso-accion:hover { background: rgb(253 230 138 / 12%); }
@media (max-width: 767.98px) {
  #appBody .ui-campo-aviso-accion { min-height: 44px; }
}
/* Escáner INE: «Archivo inválido» centrado bajo la fila de botones de la cámara. */
#appBody #ineInputArchivo-error { text-align: center; }

/* ── Etapa 2 · tablas: Mensajería en bloques en el teléfono ── */
/* Bajo 768 px la lista de Mensajería seguía siendo una tabla de al menos 550 px
   que se deslizaba de lado: el nombre se cortaba en unas 17 letras y la ficha de
   simpatía quedaba en el borde. Ahora cada persona es un bloque, como en el
   catálogo de grupos (.ui-tabla-tarjetas, que pone tablas.py): nombre completo
   con «Ver expediente», simpatía y teléfono con su rótulo, y «Enviar» a todo lo
   ancho, con su texto y 44 px de alto. Desde 768 px no cambia nada.
   Los encabezados de columna se ocultan solo a la vista: la tabla y sus
   encabezados siguen en el árbol accesible (Chromium conserva los roles de tabla
   aunque las celdas sean bloques), por eso el rótulo visible de cada dato lleva
   texto alternativo vacío (content: "…" / "") y no se anuncia dos veces. Donde
   el navegador no entiende esa forma queda la primera declaración. */
@media (max-width: 767.98px) {
  /* (2,2,1): gana a «table.table-fixed { min-width: 680px }» de la sección de legibilidad. */
  #appBody #page-mensajeria table.ui-tabla-tarjetas.ui-tarjetas-mensajeria { min-width: 0; white-space: normal; }
  #appBody .ui-tabla-tarjetas.ui-tarjetas-mensajeria > thead {
    position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; border: 0;
    overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%);
  }
  #appBody .ui-tabla-tarjetas.ui-tarjetas-mensajeria > tbody > tr:not(.ui-estado-fila) {
    display: grid; grid-template-columns: minmax(0, 1fr); row-gap: 10px; padding: 14px 16px;
  }
  /* El bloque pone el relleno; las celdas, ninguno (también la primera y la
     última, que el catálogo de grupos rellena por su cuenta). */
  #appBody .ui-tabla-tarjetas.ui-tarjetas-mensajeria > tbody > tr:not(.ui-estado-fila) > td,
  #appBody .ui-tabla-tarjetas.ui-tarjetas-mensajeria > tbody > tr:not(.ui-estado-fila) > td:first-child,
  #appBody .ui-tabla-tarjetas.ui-tarjetas-mensajeria > tbody > tr:not(.ui-estado-fila) > td:last-child { padding: 0; }
  /* Nombre completo: en varias líneas si hace falta, partido entre palabras. */
  #appBody .ui-tabla-tarjetas.ui-tarjetas-mensajeria .ui-fila-titulo {
    white-space: normal; overflow: visible; text-overflow: clip; overflow-wrap: break-word;
    font-size: 14px; line-height: 1.3;
  }
  /* Simpatía y teléfono: el rótulo a la izquierda y el dato a la derecha. */
  #appBody .ui-tabla-tarjetas.ui-tarjetas-mensajeria > tbody > tr:not(.ui-estado-fila) > td:nth-child(2),
  #appBody .ui-tabla-tarjetas.ui-tarjetas-mensajeria > tbody > tr:not(.ui-estado-fila) > td:nth-child(3) {
    display: flex; align-items: center; justify-content: space-between; gap: 12px; min-width: 0; overflow: visible;
  }
  #appBody .ui-tabla-tarjetas.ui-tarjetas-mensajeria > tbody > tr:not(.ui-estado-fila) > td:nth-child(3) { font-size: 14px; }
  #appBody .ui-tabla-tarjetas.ui-tarjetas-mensajeria > tbody > tr:not(.ui-estado-fila) > td:nth-child(2)::before,
  #appBody .ui-tabla-tarjetas.ui-tarjetas-mensajeria > tbody > tr:not(.ui-estado-fila) > td:nth-child(3)::before {
    flex: none; font-family: var(--ui-font); font-size: 12px; font-weight: 700; line-height: 1.3;
    letter-spacing: .06em; text-transform: uppercase; color: var(--ui-muted);
  }
  #appBody .ui-tabla-tarjetas.ui-tarjetas-mensajeria > tbody > tr:not(.ui-estado-fila) > td:nth-child(2)::before { content: "Simpat\ED a"; content: "Simpat\ED a" / ""; }
  #appBody .ui-tabla-tarjetas.ui-tarjetas-mensajeria > tbody > tr:not(.ui-estado-fila) > td:nth-child(3)::before { content: "Tel\E9 fono"; content: "Tel\E9 fono" / ""; }
  /* «Enviar»: a todo lo ancho del bloque, con su texto (antes solo el icono bajo 640 px). */
  #appBody .ui-tabla-tarjetas.ui-tarjetas-mensajeria > tbody > tr:not(.ui-estado-fila) > td:nth-child(4) { padding-top: 2px; }
  #appBody .ui-tabla-tarjetas.ui-tarjetas-mensajeria > tbody > tr:not(.ui-estado-fila) > td:nth-child(4) > button {
    width: 100%; min-height: 44px; margin: 0; font-size: 13px;
  }
  #appBody .ui-tabla-tarjetas.ui-tarjetas-mensajeria > tbody > tr:not(.ui-estado-fila) > td:nth-child(4) > button > span { display: inline; }
}

/* ── Etapa 2 · legibilidad: cifra del Panel cuya lectura falló ── */
/* «No se pudo cargar» en lugar del número: más pequeño que la cifra para que
   quepa en la tarjeta, con el rojo de los errores (≥ 4.5:1 en los dos temas). */
#appBody .ui-cifra-error { display: block; font-size: 14px; line-height: 1.35; font-weight: 600; letter-spacing: 0; color: #b42332; }
html.dark #appBody .ui-cifra-error { color: #ffb4bc; }

/* ── Padrón Electoral: filtros de la tabla y fichas de simpatía (26/09) ── */
/* Simpatía y Expediente comparten columna. Desde 768 px van uno sobre otro, a todo
   el ancho: lado a lado, desde 1280 px, «Expedientes» se recortaba (83 px de 102).
   Sustituye a las reglas con :has() que lo hacían solo entre 768 y 1279 px. */
/* 27/09: la celda ocupa también la columna «Acciones» (colspan="2"), cuya celda de
   filtros quedaba vacía: su «Limpiar filtros» lo da el resumen de filtros. Con ese
   ancho (unos 300 px) los dos caben lado a lado sin recortarse. */
#appBody #page-padron-electoral thead td:has(> button[onclick^="limpiarTodosFiltrosPE"]) { display: none !important; }
@media (min-width: 768px) {
  #appBody #page-padron-electoral .ui-pe-par { flex-wrap: nowrap; gap: 8px; }
  #appBody #page-padron-electoral .ui-pe-par > select { flex: 1 1 0; width: auto; min-width: 0; }
}
/* Punto de color de las fichas de simpatía: decorativo (aria-hidden), del color del
   texto y separado de él (antes, «•Indeciso» parecía un punto pegado a la palabra). */
#appBody .ui-punto { display: inline-block; width: 6px; height: 6px; border-radius: 999px; background: currentColor; flex-shrink: 0; }

/* ── Menú según los módulos visibles, menú de la cuenta y riel (27/09) ──
   ui-accessibility.js pone <html data-ui-menu>: «uno» (1 módulo, sin menú),
   «pocos» (2 a 5, pestañas arriba) o «lateral» (6 o más). Sin atributo (antes de
   cargar los permisos), el menú lateral de siempre. Además: .ui-menu-secciones
   (9 o más), .ui-menu-holgado (6 a 8) y .ui-menu-compacto (4 o menos, teléfono). */

/* Pie del menú lateral: la tarjeta de la persona abre el menú de la cuenta. */
#sidebar .ui-cuenta { padding: 12px; background: var(--ui-surface); }
#appBody .ui-cuenta-btn {
  display: flex; align-items: center; gap: 12px; width: 100%; min-height: 52px; padding: 6px 10px 6px 6px;
  border: 0; border-radius: 12px; background: var(--ui-subtle); color: var(--ui-ink); text-align: left; cursor: pointer;
  transition: background var(--ui-fast) var(--ui-ease);
}
#appBody .ui-cuenta-btn:hover, #appBody .ui-cuenta-btn[aria-expanded="true"] { background: var(--ui-line); }
#appBody .ui-cuenta-texto { display: flex; flex-direction: column; flex: 1; min-width: 0; }
#sidebar #userDisplay { font-size: 14px; line-height: 20px; font-weight: 650; color: var(--ui-ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#sidebar #userRole { font-size: 12px; line-height: 16px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#appBody .ui-cuenta-flecha { width: 16px; height: 16px; flex-shrink: 0; color: var(--ui-muted); }
#appBody #sidebarAvatarContainer { background: var(--ui-selected); border-color: transparent; box-shadow: none; }
#appBody #sidebarAvatarContainer svg { color: var(--ui-accent); }

/* Menú de la cuenta: fijo, pegado al botón que lo abre (lo coloca ui-accessibility.js). */
#appBody .ui-menu-cuenta {
  position: fixed; z-index: 60; width: 232px; padding: 4px; flex-direction: column; gap: 1px;
  background: var(--ui-surface); border: 1px solid var(--ui-line); border-radius: 12px;
  box-shadow: 0 6px 20px rgb(25 32 45 / 10%);
}
#appBody .ui-menu-cuenta:not([hidden]) { display: flex; }
html.dark #appBody .ui-menu-cuenta { border-color: #484c53; box-shadow: 0 8px 24px rgb(0 0 0 / 40%); }
#appBody .ui-menu-cuenta-quien { display: none; padding: 8px 10px 10px; margin-bottom: 4px; border-bottom: 1px solid var(--ui-line); }
#appBody .ui-menu-cuenta.ui-con-quien .ui-menu-cuenta-quien { display: block; }
#appBody .ui-menu-cuenta-nombre { display: block; font-size: 14px; line-height: 20px; font-weight: 650; color: var(--ui-ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#appBody .ui-menu-cuenta-rol { display: block; font-size: 12px; line-height: 16px; color: var(--ui-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#appBody .ui-menu-cuenta-op {
  display: flex; align-items: center; gap: 10px; width: 100%; min-height: 36px; padding: 6px 10px;
  border: 0; border-radius: 8px; background: transparent; color: var(--ui-ink);
  font-size: 13px; line-height: 18px; font-weight: 500; text-align: left; cursor: pointer;
}
#appBody .ui-menu-cuenta-op:hover { background: var(--ui-subtle); }
#appBody .ui-menu-cuenta-op svg { width: 16px; height: 16px; flex-shrink: 0; color: var(--ui-ink); }
#appBody .ui-menu-cuenta-op.ui-menu-cuenta-salir, #appBody .ui-menu-cuenta-salir svg { color: #b42332; }
#appBody .ui-menu-cuenta-op.ui-menu-cuenta-salir:hover { background: #fdf1f2; }
html.dark #appBody .ui-menu-cuenta-op.ui-menu-cuenta-salir, html.dark #appBody .ui-menu-cuenta-salir svg { color: #ffb4bc; }
html.dark #appBody .ui-menu-cuenta-op.ui-menu-cuenta-salir:hover { background: #3b1d22; }
#appBody .ui-menu-cuenta-sep { height: 1px; margin: 3px 6px; background: var(--ui-line); }
/* Interruptor de Modo oscuro: su estado lo anuncia aria-pressed del botón. */
#appBody .ui-interruptor {
  position: relative; margin-left: auto; width: 28px; height: 16px; flex-shrink: 0;
  border-radius: 999px; background: var(--ui-control-line); transition: background var(--ui-fast) var(--ui-ease);
}
#appBody .ui-interruptor::after {
  content: ""; position: absolute; top: 2px; left: 2px; width: 12px; height: 12px; border-radius: 50%;
  background: #fff; transition: transform var(--ui-fast) var(--ui-ease);
}
html.dark #appBody .ui-interruptor::after { background: var(--ui-surface); }
#appBody [aria-pressed="true"] > .ui-interruptor { background: var(--ui-accent); }
#appBody [aria-pressed="true"] > .ui-interruptor::after { transform: translateX(12px); }
/* «Contraer menú» / «Expandir menú»: el texto y el icono siguen al estado del menú. */
#appBody .ui-menu-cuenta .ui-si-contraido { display: none; }
#appBody #sidebar.sidebar-colapsado ~ .ui-menu-cuenta .ui-si-abierto { display: none; }
#appBody #sidebar.sidebar-colapsado ~ .ui-menu-cuenta .ui-si-contraido { display: inline; }
/* Solo se contrae el menú lateral de escritorio. */
html[data-ui-menu="uno"] #appBody .ui-menu-cuenta-contraer,
html[data-ui-menu="pocos"] #appBody .ui-menu-cuenta-contraer { display: none; }
@media (max-width: 767.98px) {
  #appBody .ui-menu-cuenta-contraer { display: none; }
}

/* Nombre del único módulo: solo cuando no hay menú. */
#appBody .ui-menu-modulo { display: none; font-size: 15px; line-height: 20px; font-weight: 650; color: var(--ui-ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* Teléfono con 4 módulos o menos: todos caben en la barra inferior (sin «Menú»),
   así que no hay cajón ni hamburguesa; la cabecera lleva el nombre de la vista y
   «Tu cuenta» (Modo oscuro, Acerca de, Cerrar sesión). */
#appBody .ui-cuenta-movil { display: none; }
@media (max-width: 767.98px) {
  html.ui-menu-compacto #appBody .ui-cuenta-movil {
    display: flex; align-items: center; justify-content: center; width: 44px; height: 44px; flex-shrink: 0;
    border: 0; border-radius: 50%; background: var(--ui-selected); color: var(--ui-accent);
  }
  html.ui-menu-compacto #appBody .ui-cuenta-movil[aria-expanded="true"] { box-shadow: 0 0 0 2px var(--ui-accent); }
  html.ui-menu-compacto #appBody button[aria-label="Abrir Menú Principal"] { display: none; }
  html.ui-menu-compacto #appBody #mobileTitle {
    position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; border: 0;
    overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
  }
  html.ui-menu-compacto #appBody #uiMenuModuloMovil { display: block; }
}

/* Secciones del menú lateral (9 módulos o más): título discreto sobre cada grupo. */
#sidebar .ui-menu-seccion { margin: 0; padding: 14px 16px 4px; font-size: 12px; line-height: 16px; font-weight: 600; color: var(--ui-muted); }
#sidebar .ui-menu-seccion[hidden] { display: none; }
html[data-ui-menu="uno"] #sidebar .ui-menu-seccion, html[data-ui-menu="pocos"] #sidebar .ui-menu-seccion { display: none; }
/* Con secciones, en escritorio los renglones se compactan (en el teléfono siguen de 46 px). */
@media (min-width: 768px) {
  html.ui-menu-secciones #sidebar nav > .sidebar-item { padding-block: 8px; }
  html.ui-menu-secciones #sidebar nav > .sidebar-item + .sidebar-item { margin-top: 2px; }
}
/* 6 a 8 módulos (capturista): renglones más holgados, sin secciones ni desplazamiento. */
html.ui-menu-holgado #sidebar nav { padding-top: 12px; }
html.ui-menu-holgado #sidebar nav > .sidebar-item { padding-block: 13px; font-size: 14px; }

/* Acción rápida según el rol: «Nuevo registro», arriba del menú. */
#appBody .ui-accion-rapida-caja { padding: 12px 12px 0; }
#appBody .ui-accion-rapida-caja[hidden] { display: none; }
#appBody .ui-accion-rapida {
  display: flex; align-items: center; justify-content: center; gap: 8px; width: 100%; min-height: 44px; padding: 10px 14px;
  border: 0; border-radius: 12px; background: var(--ui-primary); color: var(--ui-on-primary);
  font-size: 14px; line-height: 20px; font-weight: 600; cursor: pointer; transition: background var(--ui-fast) var(--ui-ease);
}
#appBody .ui-accion-rapida:hover { background: var(--ui-primary-hover); }
#appBody .ui-accion-rapida svg { width: 18px; height: 18px; flex-shrink: 0; }

@media (min-width: 768px) {
  /* 1 a 5 módulos: el menú es una barra superior a todo el ancho, con el logo,
     las pestañas (o el nombre del único módulo) y la cuenta como avatar. El título
     del sistema queda para el lector de pantalla. */
  html[data-ui-menu="uno"] #appScreen, html[data-ui-menu="pocos"] #appScreen { flex-direction: column; }
  html[data-ui-menu="uno"] #sidebar, html[data-ui-menu="pocos"] #sidebar {
    width: auto !important; min-width: 0 !important; height: auto; flex-direction: row; align-items: center; gap: 12px;
    padding-inline: 8px 16px; overflow: visible !important; border-right-width: 0 !important; border-bottom: 1px solid var(--ui-line);
  }
  html[data-ui-menu="uno"] #sidebar > div:first-child, html[data-ui-menu="pocos"] #sidebar > div:first-child { flex: none; padding: 10px 8px; border-bottom-width: 0; }
  html[data-ui-menu="uno"] #logoContainer, html[data-ui-menu="pocos"] #logoContainer { width: 36px; height: 36px; border-radius: 10px; }
  html[data-ui-menu="uno"] #appTitle, html[data-ui-menu="pocos"] #appTitle {
    position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; border: 0;
    overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
  }
  html[data-ui-menu="uno"] #appState, html[data-ui-menu="pocos"] #appState { display: none; }
  html[data-ui-menu="uno"] #appBody #uiMenuModulo { display: block; }
  html[data-ui-menu="uno"] #sidebar nav { display: none; }
  html[data-ui-menu="pocos"] #sidebar nav {
    display: flex; flex: 1; min-width: 0; flex-direction: row; align-items: center; gap: 4px;
    padding: 8px 0; overflow-x: auto; overflow-y: hidden;
  }
  html[data-ui-menu="pocos"] #sidebar nav > * + * { margin-top: 0; }
  /* Pestañas: pastillas de texto; la actual, con el fondo de selección. */
  html[data-ui-menu="pocos"] #sidebar .sidebar-item { width: auto; flex: none; gap: 0; min-height: 36px; padding: 6px 12px; border-radius: 10px; }
  html[data-ui-menu="pocos"] #sidebar .sidebar-item > svg, html[data-ui-menu="pocos"] #sidebar .sidebar-item > div > svg { display: none; }
  html[data-ui-menu="pocos"] #sidebar .sidebar-item > div { gap: 0; }
  html[data-ui-menu="pocos"] #appBody #sidebar .sidebar-item[aria-current="page"] { box-shadow: none; }
  html[data-ui-menu="pocos"] #sidebar [data-nav="configuracion"] { margin-top: 0; padding-top: 6px; border-top-width: 0; }
  html[data-ui-menu="pocos"] #submenu-grupos, html[data-ui-menu="pocos"] #submenu-gremios,
  html[data-ui-menu="pocos"] #chevron-grupos, html[data-ui-menu="pocos"] #chevron-gremios { display: none !important; }
  /* La cuenta, como avatar redondo (nombre y rol, en el menú y para el lector). */
  html[data-ui-menu="uno"] #sidebar .ui-cuenta, html[data-ui-menu="pocos"] #sidebar .ui-cuenta {
    flex: none; margin-left: auto; padding: 0; border-top-width: 0; background: transparent;
  }
  html[data-ui-menu="uno"] #appBody .ui-cuenta-btn, html[data-ui-menu="pocos"] #appBody .ui-cuenta-btn {
    position: relative; width: 44px; min-height: 44px; height: 44px; padding: 4px; gap: 0; justify-content: center; border-radius: 50%; background: transparent;
  }
  html[data-ui-menu="uno"] #appBody .ui-cuenta-btn:hover, html[data-ui-menu="pocos"] #appBody .ui-cuenta-btn:hover { background: var(--ui-subtle); }
  html[data-ui-menu="uno"] #appBody .ui-cuenta-btn[aria-expanded="true"], html[data-ui-menu="pocos"] #appBody .ui-cuenta-btn[aria-expanded="true"] { background: transparent; box-shadow: 0 0 0 2px var(--ui-accent); }
  html[data-ui-menu="uno"] #appBody .ui-cuenta-texto, html[data-ui-menu="pocos"] #appBody .ui-cuenta-texto {
    position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; border: 0;
    overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
  }
  html[data-ui-menu="uno"] #appBody .ui-cuenta-flecha, html[data-ui-menu="pocos"] #appBody .ui-cuenta-flecha { display: none; }
  html[data-ui-menu="uno"] #sidebarAvatarContainer, html[data-ui-menu="pocos"] #sidebarAvatarContainer { width: 36px; height: 36px; }
  html[data-ui-menu="uno"] #btnMostrarSidebar, html[data-ui-menu="pocos"] #btnMostrarSidebar { display: none !important; }
  /* Orden en la barra: logo, pestañas, «Nuevo registro» y la cuenta. */
  html[data-ui-menu="pocos"] #sidebar nav { order: 1; }
  html[data-ui-menu="pocos"] #appBody .ui-accion-rapida-caja { order: 2; flex: none; padding: 0; }
  html[data-ui-menu="pocos"] #sidebar .ui-cuenta { order: 3; }
  html[data-ui-menu="pocos"] #appBody .ui-accion-rapida { width: auto; min-height: 36px; padding: 6px 14px; font-size: 13px; border-radius: 10px; }

  /* 6 o más, contraído: riel de iconos de 72 px (antes el menú desaparecía). El
     texto de cada botón queda para el lector de pantalla y como etiqueta al pasar. */
  html:not([data-ui-menu="uno"]):not([data-ui-menu="pocos"]) #sidebar.sidebar-colapsado {
    width: 72px !important; min-width: 72px !important; border-right-width: 1px !important;
    overflow-x: hidden !important; overflow-y: auto !important;
  }
  html:not([data-ui-menu="uno"]):not([data-ui-menu="pocos"]) #sidebar.sidebar-colapsado > div:first-child { justify-content: center; padding-inline: 14px; }
  html:not([data-ui-menu="uno"]):not([data-ui-menu="pocos"]) #sidebar.sidebar-colapsado > div:first-child > div:first-child { gap: 0; }
  html:not([data-ui-menu="uno"]):not([data-ui-menu="pocos"]) #sidebar.sidebar-colapsado > div:first-child > div:first-child > div:last-child { display: none; }
  html:not([data-ui-menu="uno"]):not([data-ui-menu="pocos"]) #sidebar.sidebar-colapsado nav { padding: 12px 14px; }
  html:not([data-ui-menu="uno"]):not([data-ui-menu="pocos"]) #sidebar.sidebar-colapsado .sidebar-item { position: relative; justify-content: center; gap: 0; width: 44px; height: 44px; padding: 0; }
  html:not([data-ui-menu="uno"]):not([data-ui-menu="pocos"]) #appBody #sidebar.sidebar-colapsado .sidebar-item[aria-current="page"] { box-shadow: none; }
  html:not([data-ui-menu="uno"]):not([data-ui-menu="pocos"]) #sidebar.sidebar-colapsado .sidebar-item > div { gap: 0; }
  html:not([data-ui-menu="uno"]):not([data-ui-menu="pocos"]) #sidebar.sidebar-colapsado .sidebar-item span,
  html:not([data-ui-menu="uno"]):not([data-ui-menu="pocos"]) #sidebar.sidebar-colapsado .ui-cuenta-texto {
    position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; border: 0;
    overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
  }
  html:not([data-ui-menu="uno"]):not([data-ui-menu="pocos"]) #sidebar.sidebar-colapsado #chevron-grupos,
  html:not([data-ui-menu="uno"]):not([data-ui-menu="pocos"]) #sidebar.sidebar-colapsado #chevron-gremios,
  html:not([data-ui-menu="uno"]):not([data-ui-menu="pocos"]) #sidebar.sidebar-colapsado #submenu-grupos,
  html:not([data-ui-menu="uno"]):not([data-ui-menu="pocos"]) #sidebar.sidebar-colapsado #submenu-gremios,
  html:not([data-ui-menu="uno"]):not([data-ui-menu="pocos"]) #sidebar.sidebar-colapsado .ui-cuenta-flecha { display: none !important; }
  /* En el riel, cada sección es una línea (su título sigue para el lector). */
  html:not([data-ui-menu="uno"]):not([data-ui-menu="pocos"]) #sidebar.sidebar-colapsado .ui-menu-seccion:not([hidden]) {
    height: 1px; margin: 10px 6px; padding: 0; overflow: hidden; color: transparent; background: var(--ui-line);
  }
  html:not([data-ui-menu="uno"]):not([data-ui-menu="pocos"]) #sidebar.sidebar-colapsado .ui-accion-rapida-caja { padding: 12px 14px 0; }
  html:not([data-ui-menu="uno"]):not([data-ui-menu="pocos"]) #appBody #sidebar.sidebar-colapsado .ui-accion-rapida { width: 44px; height: 44px; padding: 0; gap: 0; }
  html:not([data-ui-menu="uno"]):not([data-ui-menu="pocos"]) #sidebar.sidebar-colapsado .ui-accion-rapida span {
    position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; border: 0;
    overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
  }
  html:not([data-ui-menu="uno"]):not([data-ui-menu="pocos"]) #sidebar.sidebar-colapsado .ui-cuenta { padding: 12px 14px; }
  html:not([data-ui-menu="uno"]):not([data-ui-menu="pocos"]) #appBody #sidebar.sidebar-colapsado .ui-cuenta-btn {
    position: relative; justify-content: center; gap: 0; width: 44px; min-height: 44px; height: 44px; padding: 0; border-radius: 50%; background: transparent;
  }
  html:not([data-ui-menu="uno"]):not([data-ui-menu="pocos"]) #appBody #sidebar.sidebar-colapsado .ui-cuenta-btn:hover { background: var(--ui-subtle); }
  html:not([data-ui-menu="uno"]):not([data-ui-menu="pocos"]) #appBody #sidebar.sidebar-colapsado .ui-cuenta-btn[aria-expanded="true"] { background: transparent; box-shadow: 0 0 0 2px var(--ui-accent); }
  /* «Expandir menú»: botón redondo sobre el borde del riel, a la altura de la cabecera. */
  html:not([data-ui-menu="uno"]):not([data-ui-menu="pocos"]) #sidebar.sidebar-colapsado + #btnMostrarSidebar {
    left: 60px; top: 82px; transform: none; width: 24px; height: 24px;
    border: 1px solid var(--ui-control-line); border-radius: 50%; background: var(--ui-surface); color: var(--ui-ink); box-shadow: var(--ui-shadow);
  }
  html:not([data-ui-menu="uno"]):not([data-ui-menu="pocos"]) #sidebar.sidebar-colapsado + #btnMostrarSidebar:hover { width: 24px; background: var(--ui-selected); color: var(--ui-accent); }
  html:not([data-ui-menu="uno"]):not([data-ui-menu="pocos"]) #sidebar.sidebar-colapsado + #btnMostrarSidebar svg { width: 14px; height: 14px; }
}
/* Nombre de cada icono del riel (solo visual: el botón ya lo tiene como nombre). */
#appBody .ui-riel-etiqueta {
  position: fixed; z-index: 70; transform: translateY(-50%); padding: 6px 10px; border-radius: 8px;
  background: var(--ui-ink); color: var(--ui-surface); font-size: 13px; line-height: 18px; font-weight: 500;
  white-space: nowrap; box-shadow: 0 4px 12px rgb(0 0 0 / 15%);
}
#appBody .ui-riel-etiqueta[hidden] { display: none; }

/* ── Secciones electorales en el mapa del Panel Principal (28/09) ── */
/* Botón «Secciones» junto a Pines y Calor; su estado lo da aria-pressed. */
#appBody .ui-mapa-secciones-btn {
  display: inline-flex; align-items: center; gap: 6px; min-height: 32px; padding: 6px 12px;
  border: 1px solid var(--ui-line); border-radius: 10px; background: var(--ui-surface); color: var(--ui-muted);
  font-size: 12px; line-height: 16px; font-weight: 600; cursor: pointer; transition: background var(--ui-fast) var(--ui-ease);
}
#appBody .ui-mapa-secciones-btn:hover { background: var(--ui-subtle); color: var(--ui-ink); }
#appBody .ui-mapa-secciones-btn[aria-pressed="true"] { background: var(--ui-selected); border-color: transparent; color: var(--ui-accent-legible); }
#appBody .ui-mapa-secciones-btn svg { width: 14px; height: 14px; flex-shrink: 0; }
/* Aviso en la esquina del mapa: cartografía oficial o zonas aproximadas. */
#appBody .ui-mapa-aviso {
  margin: 10px; padding: 4px 10px; border-radius: 8px; background: var(--ui-surface); color: var(--ui-ink);
  font: 500 12px/18px var(--ui-font); box-shadow: 0 1px 4px rgb(0 0 0 / 20%);
}
#appBody .ui-mapa-aviso[hidden] { display: none; }
/* Número de cada sección: con halo para leerse sobre calles, pines y calor. */
#appBody .ui-mapa-seccion { text-shadow: 0 0 2px #fff, 0 0 3px #fff, 0 0 5px #fff; }
html.dark #appBody .ui-mapa-seccion { text-shadow: 0 0 2px #0f1621, 0 0 3px #0f1621, 0 0 5px #0f1621; }

/* ── Expediente: en modo edición, la foto se cambia tocándola (28/09) ── */
#appBody #mp_foto_container.ui-foto-editable { position: relative; cursor: pointer; }
#appBody #mp_foto_container.ui-foto-editable::after {
  content: "Cambiar foto"; position: absolute; left: 0; right: 0; bottom: 0; padding: 8px 0 14px;
  background: rgb(15 23 42 / 68%); color: #fff; font-size: 12px; line-height: 16px; font-weight: 600; text-align: center;
  transition: background var(--ui-fast) var(--ui-ease);
}
#appBody #mp_foto_container.ui-foto-editable:hover::after,
#appBody #mp_foto_container.ui-foto-editable:focus-visible::after { background: rgb(15 23 42 / 85%); }
#appBody #mp_foto_container.ui-foto-editable:focus-visible { outline: 3px solid var(--ui-accent); outline-offset: 3px; }

/* ── Padrón Electoral sin cabecera grande (28/09) ──
   El título y la frase ocupaban una franja entera y el nombre ya está en el menú
   (o en la pestaña de arriba): la página empieza con sus pestañas. El título se
   queda para el lector de pantalla y como destino del foco al cambiar de vista. */
#appBody #page-padron-electoral > div:first-child {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; border: 0;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}
#appBody #page-padron-electoral > div:first-child + div { margin-top: 0; }

/* ── Panel Principal rehecho (29/09): meta de votos, avance por sección, altas,
   simpatía, calidad del padrón, mapa de 320 px y capturistas (panel.py) ── */
#appBody .ui-panel-fila { display: grid; gap: 24px; grid-template-columns: minmax(0, 1fr); }
@media (min-width: 768px) and (max-width: 1023.98px) {
  #appBody .ui-panel-fila-3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (min-width: 1024px) {
  #appBody .ui-panel-fila-meta { grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); }
  #appBody .ui-panel-fila-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  #appBody .ui-panel-fila-mapa { grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); align-items: start; }
}
#appBody .ui-panel-columna { display: flex; flex-direction: column; gap: 24px; min-width: 0; }
#appBody .ui-panel-columna > [hidden] { display: none; }
#appBody .ui-panel-mapa { flex: none; height: 320px; }

#appBody .ui-panel-tarjeta {
  display: flex; flex-direction: column; gap: 12px; min-width: 0; padding: 22px 24px;
  background: var(--ui-surface); border: 1px solid var(--ui-line); border-radius: 24px; box-shadow: var(--ui-shadow);
}
#appBody .ui-panel-cabeza { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
#appBody .ui-panel-titulo { display: flex; align-items: center; gap: 8px; margin: 0; font-size: 15px; line-height: 20px; font-weight: 650; color: var(--ui-ink); }
#appBody .ui-panel-titulo svg { width: 18px; height: 18px; color: var(--ui-accent); flex-shrink: 0; }
#appBody .ui-panel-nota { margin: 0; font-size: 12px; line-height: 18px; color: var(--ui-muted); }
#appBody .ui-panel-boton {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px; min-height: 36px; padding: 6px 14px;
  border: 1px solid var(--ui-control-line); border-radius: 10px; background: var(--ui-surface); color: var(--ui-ink);
  font-size: 13px; line-height: 18px; font-weight: 600; cursor: pointer; align-self: flex-start;
}
#appBody .ui-panel-boton:hover { background: var(--ui-subtle); }
#appBody .ui-panel-boton[aria-expanded="true"] { background: var(--ui-selected); border-color: transparent; color: var(--ui-accent-legible); }
#appBody .ui-panel-boton svg { width: 16px; height: 16px; }
#appBody .ui-panel-boton-primario { background: var(--ui-primary); border-color: transparent; color: var(--ui-on-primary); }
#appBody .ui-panel-boton-primario:hover { background: var(--ui-primary-hover); }
#appBody .ui-panel-boton[hidden] { display: none; }

/* Meta de votos */
#appBody .ui-panel-meta { border: 2px solid var(--ui-accent); }
#appBody .ui-meta-cifras, #appBody .ui-calidad-cifra { display: flex; align-items: baseline; flex-wrap: wrap; gap: 4px 10px; }
#appBody .ui-meta-num { font-size: 34px; line-height: 40px; font-weight: 700; color: var(--ui-ink); letter-spacing: -.01em; }
#appBody .ui-meta-de { font-size: 14px; line-height: 20px; color: var(--ui-muted); }
#appBody .ui-meta-pct { margin-left: auto; font-size: 24px; line-height: 30px; font-weight: 700; color: var(--ui-accent-legible); }
#appBody .ui-meta-barra { height: 12px; border-radius: 999px; background: var(--ui-subtle); overflow: hidden; }
#appBody .ui-meta-barra i { display: block; height: 100%; border-radius: 999px; background: var(--ui-accent); transition: width var(--ui-enter) var(--ui-ease); }
#appBody .ui-meta-datos { display: flex; flex-wrap: wrap; gap: 6px; }
#appBody .ui-dato { font-size: 12px; line-height: 16px; padding: 4px 10px; border-radius: 999px; background: var(--ui-subtle); color: var(--ui-ink); }
#appBody .ui-meta-vacia { margin: 0; font-size: 18px; line-height: 24px; font-weight: 650; color: var(--ui-ink); }

/* Ajustar la meta */
#appBody .ui-panel-ajustes { display: flex; flex-direction: column; gap: 12px; padding: 16px; border-radius: 16px; background: var(--ui-canvas); border: 1px solid var(--ui-line); }
#appBody .ui-panel-ajustes[hidden] { display: none; }
#appBody .ui-panel-campos { display: grid; gap: 12px; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); }
#appBody .ui-panel-campo { display: flex; flex-direction: column; gap: 4px; font-size: 13px; line-height: 18px; font-weight: 600; color: var(--ui-ink); }
#appBody .ui-panel-campo input {
  height: 40px; padding: 0 12px; border: 1px solid var(--ui-control-line); border-radius: 10px;
  background: var(--ui-surface); color: var(--ui-ink); font-size: 14px; font-weight: 500;
}
#appBody .ui-panel-campo small { font-size: 12px; line-height: 16px; font-weight: 400; color: var(--ui-muted); }
#appBody .ui-panel-resultado { margin: 0; font-size: 14px; line-height: 20px; font-weight: 600; color: var(--ui-ink); }
#appBody .ui-panel-acciones { display: flex; flex-wrap: wrap; gap: 8px; }

/* Avance por sección */
#appBody .ui-panel-secciones { display: flex; flex-direction: column; gap: 4px; flex: 1 1 auto; min-height: 0; max-height: 380px; overflow-y: auto; margin: 0 -6px; padding: 0 6px; }
#appBody .ui-sec-fila {
  display: grid; grid-template-columns: 48px minmax(0, 1fr) auto; align-items: center; gap: 10px; width: 100%;
  min-height: 36px; padding: 4px 8px; border: 0; border-radius: 10px; background: transparent; color: var(--ui-ink); text-align: left; font: inherit;
}
#appBody button.ui-sec-fila { cursor: pointer; }
#appBody button.ui-sec-fila:hover { background: var(--ui-subtle); }
#appBody .ui-sec-num { font-size: 13px; font-weight: 650; }
#appBody .ui-sec-barra { height: 8px; border-radius: 999px; background: var(--ui-subtle); overflow: hidden; }
#appBody .ui-sec-barra i { display: block; height: 100%; border-radius: 999px; }
#appBody .ui-nivel-bajo i { background: #c2413a; }
#appBody .ui-nivel-medio i { background: #b86e00; }
#appBody .ui-nivel-cerca i { background: var(--ui-accent); }
#appBody .ui-nivel-ok i { background: #1f8a4c; }
html.dark #appBody .ui-nivel-bajo i { background: #ff8b82; }
html.dark #appBody .ui-nivel-medio i { background: #f5b94a; }
html.dark #appBody .ui-nivel-ok i { background: #5fd08c; }
#appBody .ui-sec-dato { font-size: 12px; line-height: 16px; color: var(--ui-muted); white-space: nowrap; }

/* Calidad del padrón y capturistas */
#appBody .ui-panel-lista { display: flex; flex-direction: column; margin: 0; padding: 0; list-style: none; }
#appBody .ui-panel-lista li { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 8px 0; border-top: 1px solid var(--ui-line); font-size: 13px; line-height: 18px; color: var(--ui-ink); }
#appBody .ui-panel-lista li:first-child { border-top: 0; }
#appBody .ui-panel-lista b { font-weight: 650; font-variant-numeric: tabular-nums; }
#appBody .ui-cap-nombre { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#appBody .ui-panel-vacio { color: var(--ui-muted); }
#appBody .ui-panel-tarjeta[hidden] { display: none; }

/* Línea bajo cada cifra de arriba */
#appBody .ui-kpi-extra { min-height: 18px; margin: 6px 0 0; font-size: 12px; line-height: 18px; font-weight: 500; color: var(--ui-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* Tarjeta de la meta: cifras, cuatro datos, proyección y parámetros (sin huecos). */
#appBody .ui-panel-meta-cuerpo { display: flex; flex-direction: column; gap: 14px; flex: 1 1 auto; }
#appBody .ui-meta-rejilla { display: grid; gap: 10px; grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (min-width: 640px) { #appBody .ui-meta-rejilla { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
#appBody .ui-meta-dato { display: flex; flex-direction: column; gap: 2px; padding: 12px 14px; border-radius: 14px; background: var(--ui-subtle); }
#appBody .ui-meta-dato b { font-size: 22px; line-height: 28px; font-weight: 700; color: var(--ui-ink); font-variant-numeric: tabular-nums; }
#appBody .ui-meta-dato span { font-size: 12px; line-height: 16px; color: var(--ui-muted); }
#appBody .ui-meta-dato-alerta b { color: #b42332; }
html.dark #appBody .ui-meta-dato-alerta b { color: #ffb4bc; }
#appBody .ui-meta-proyeccion { margin: 0; font-size: 14px; line-height: 20px; color: var(--ui-ink); }
#appBody .ui-meta-datos { margin-top: auto; }

/* Ventana «Ajustar la meta» (dialog nativo: foco atrapado, Escape y fondo). */
#appBody .ui-panel-ventana {
  width: min(640px, calc(100% - 32px)); max-height: calc(100% - 32px); padding: 0; border: 0; border-radius: 20px;
  background: var(--ui-surface); color: var(--ui-ink); box-shadow: 0 24px 60px rgb(0 0 0 / 30%);
}
#appBody .ui-panel-ventana::backdrop { background: rgb(15 23 42 / 55%); }
#appBody .ui-panel-ventana .ui-panel-ajustes { padding: 22px 24px; border: 0; border-radius: 0; background: transparent; }
#appBody .ui-panel-cerrar {
  display: inline-flex; align-items: center; justify-content: center; width: 36px; height: 36px; border: 0; border-radius: 10px;
  background: transparent; color: var(--ui-muted); cursor: pointer;
}
#appBody .ui-panel-cerrar:hover { background: var(--ui-subtle); color: var(--ui-ink); }
#appBody .ui-panel-cerrar svg { width: 18px; height: 18px; }

/* Cifras de arriba: la tarjeta completa abre su módulo. */
#appBody #dash_kpis > div { position: relative; }
#appBody #dash_kpis > div.ui-kpi-activa { cursor: pointer; }
#appBody .ui-kpi-ir {
  position: absolute; inset: 0; display: flex; align-items: flex-start; justify-content: flex-end; padding: 14px;
  border: 0; border-radius: inherit; background: transparent; color: var(--ui-muted); cursor: pointer;
}
#appBody .ui-kpi-ir[hidden] { display: none; }
#appBody .ui-kpi-ir svg { width: 18px; height: 18px; transition: color var(--ui-fast) var(--ui-ease); }
#appBody #dash_kpis > div.ui-kpi-activa:hover .ui-kpi-ir { color: var(--ui-accent); }
#appBody .ui-kpi-ir:focus-visible { outline: 3px solid var(--ui-accent); outline-offset: 2px; }

/* ── Etapa 2 · acceso (29/09): pantalla dividida — marca sobre el relieve del territorio y
   formulario limpio (acceso.py). En teléfono, franja de marca y hoja. El fondo de
   la marca se mezcla con --ui-primary y siempre queda oscuro: su texto es blanco.
   Los campos llevan #loginScreen delante para ganar a la regla general de campos
   (1,5,1). display solo con :not(.hidden): el JS muestra y oculta con .hidden. ── */
#appBody #loginScreen.ui-acceso {
  position: relative; width: 100%; height: 100%; overflow-x: hidden; overflow-y: auto;
  background: var(--ui-surface); color: var(--ui-ink);
}
#appBody #loginScreen.ui-acceso:not(.hidden) { display: flex; flex-direction: column; align-items: stretch; padding: 0; }

/* Fondo de marca del acceso y de la pantalla de carga. */
#appBody .ui-acceso-marca, #appBody #globalLoader.ui-carga {
  color: #fff; background: #0b1627;
  background:
    radial-gradient(110% 70% at 100% 0%, color-mix(in oklab, var(--ui-primary) 34%, transparent), transparent 70%),
    radial-gradient(90% 60% at 0% 100%, color-mix(in oklab, var(--ui-primary) 18%, transparent), transparent 70%),
    color-mix(in oklab, var(--ui-primary) 14%, #070e1a);
}
#appBody .ui-acceso-marca {
  position: relative; isolation: isolate; overflow: hidden; flex: none;
  display: flex; flex-direction: column; gap: 22px; padding: 26px 24px 58px;
}
#appBody .ui-acceso-relieve {
  position: absolute; inset: 0; z-index: -1; width: 100%; height: 100%; pointer-events: none;
  -webkit-mask-image: linear-gradient(205deg, #000 25%, rgb(0 0 0 / 45%) 70%, rgb(0 0 0 / 20%));
  mask-image: linear-gradient(205deg, #000 25%, rgb(0 0 0 / 45%) 70%, rgb(0 0 0 / 20%));
}
#appBody .ui-acceso-curvas {
  fill: none; stroke: color-mix(in oklab, var(--ui-primary) 40%, #fff); stroke-opacity: .2;
  stroke-width: 1; stroke-linejoin: round; stroke-linecap: round;
}
#appBody .ui-acceso-relieve path, #appBody .ui-acceso-relieve circle { vector-effect: non-scaling-stroke; }
#appBody .ui-acceso-curvas .ui-acceso-cota { stroke-opacity: .36; stroke-width: 1.3; }
#appBody .ui-acceso-ruta {
  fill: none; stroke: #fff; stroke-opacity: .42; stroke-width: 1.4; stroke-dasharray: 2 7; stroke-linecap: round;
}
#appBody .ui-acceso-sitio { fill: color-mix(in oklab, var(--ui-primary) 30%, #fff); stroke: #070e1a; stroke-width: 2; }
#appBody .ui-acceso-onda {
  fill: none; stroke: color-mix(in oklab, var(--ui-primary) 30%, #fff); stroke-width: 1.5;
  transform-box: fill-box; transform-origin: center; animation: ui-acceso-onda 3.6s var(--ui-ease) infinite;
}
#appBody .ui-acceso-onda-2 { animation-delay: 1.2s; }
#appBody .ui-acceso-onda-3 { animation-delay: 2.4s; }
@keyframes ui-acceso-onda { from { transform: scale(.5); opacity: .85; } to { transform: scale(2.8); opacity: 0; } }

#appBody .ui-acceso-identidad { display: flex; align-items: center; gap: 12px; }
#appBody .ui-acceso-logo {
  position: relative; display: grid; place-items: center; flex: none; width: 44px; height: 44px;
  overflow: hidden; border-radius: 12px; background: rgb(255 255 255 / 10%); box-shadow: 0 0 0 1px rgb(255 255 255 / 16%);
}
#appBody .ui-acceso-logo img { width: 100%; height: 100%; object-fit: cover; }
#appBody .ui-acceso-logo svg { width: 22px; height: 22px; color: #fff; }
#appBody .ui-acceso-nombre { display: flex; flex-direction: column; min-width: 0; line-height: 1.3; }
#appBody .ui-acceso-sistema { font-size: 15px; font-weight: 600; letter-spacing: -.01em; }
#appBody .ui-acceso-lugar { font-size: 13px; color: rgb(255 255 255 / 90%); }
#appBody .ui-acceso-mensaje { position: relative; }
#appBody #loginScreen .ui-acceso-lema {
  max-width: 24ch; margin: 0; font-size: 21px; line-height: 1.25; font-weight: 600; letter-spacing: -.02em;
  color: #fff; text-wrap: balance;
}
#appBody .ui-acceso-puntos, #appBody .ui-acceso-pie { display: none; }

#appBody .ui-acceso-panel {
  position: relative; z-index: 1; flex: 1 0 auto; display: flex; flex-direction: column; align-items: center;
  margin-top: -28px; padding: 34px 24px 22px; border-radius: 28px 28px 0 0; background: var(--ui-surface);
}
#appBody #loginScreen .ui-acceso-tema {
  position: absolute; top: 22px; right: 18px; display: grid; place-items: center; width: 44px; height: 44px; padding: 0;
  border: 1px solid var(--ui-line); border-radius: 999px; background: var(--ui-surface); color: var(--ui-muted);
}
#appBody #loginScreen .ui-acceso-tema:hover { background: var(--ui-subtle); color: var(--ui-ink); }
#appBody .ui-acceso-tema svg { width: 18px; height: 18px; }
html.dark #appBody .ui-acceso-sol, html:not(.dark) #appBody .ui-acceso-luna { display: none; }

#appBody #loginCard.ui-acceso-tarjeta {
  width: 100%; max-width: 400px; margin: 0; padding: 0;
  background: none; border: 0; border-radius: 0; box-shadow: none; backdrop-filter: none;
}
#appBody #loginScreen .ui-acceso-titulo {
  margin: 0; padding-right: 56px; font-size: 28px; line-height: 1.15; font-weight: 650; letter-spacing: -.03em; color: var(--ui-ink);
}
#appBody #loginScreen .ui-acceso-sub { margin: 8px 0 0; font-size: 15px; line-height: 1.45; color: var(--ui-muted); }
#appBody .ui-acceso-form { display: grid; gap: 18px; margin-top: 26px; }
#appBody #loginScreen .ui-acceso-campo label {
  display: block; margin: 0 0 7px; font-size: 13px; line-height: 1.3; font-weight: 550; letter-spacing: 0;
  text-transform: none; color: var(--ui-ink);
}
#appBody .ui-acceso-control { position: relative; }
#appBody .ui-acceso-control > svg {
  position: absolute; top: 50%; left: 14px; width: 18px; height: 18px; translate: 0 -50%;
  color: var(--ui-muted); pointer-events: none; transition: color var(--ui-fast) var(--ui-ease);
}
#appBody .ui-acceso-control:focus-within > svg { color: var(--ui-accent); }
#appBody #loginScreen .ui-acceso-control input {
  display: block; width: 100%; height: 50px; margin: 0; padding: 0 14px 0 44px;
  font-size: 16px; font-weight: 450; letter-spacing: 0; color: var(--ui-ink);
  background: var(--ui-surface); border: 1px solid var(--ui-control-line); border-radius: 12px; box-shadow: none;
}
#appBody #loginScreen .ui-acceso-control input::placeholder { color: var(--ui-muted); opacity: .8; font-weight: 400; }
#appBody #loginScreen .ui-acceso-control input:hover { border-color: var(--ui-ink); }
#appBody #loginScreen .ui-acceso-control input:focus {
  border-color: var(--ui-accent); outline-offset: -1px;
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--ui-accent) 18%, transparent);
}
#appBody #loginScreen .ui-acceso-control input:-webkit-autofill {
  border-radius: 12px !important; -webkit-box-shadow: 0 0 0 40px var(--ui-surface) inset !important;
  -webkit-text-fill-color: var(--ui-ink) !important;
}
#appBody #loginScreen .ui-acceso-control #password { padding-right: 52px; }
#appBody #loginScreen .ui-acceso-ojo {
  position: absolute; top: 5px; right: 5px; bottom: 5px; display: grid; place-items: center; width: 40px; padding: 0;
  border: 0; border-radius: 9px; background: transparent; color: var(--ui-muted);
}
#appBody #loginScreen .ui-acceso-ojo:hover, #appBody #loginScreen .ui-acceso-ojo[aria-pressed="true"] { background: var(--ui-subtle); color: var(--ui-ink); }
#appBody .ui-acceso-ojo svg { width: 18px; height: 18px; }
#appBody .ui-acceso-mayus { margin: 8px 0 0; font-size: 13px; line-height: 1.4; font-weight: 500; color: #8a5100; }
html.dark #appBody .ui-acceso-mayus { color: #f5b454; }
#appBody .ui-acceso-mayus:empty { display: none; }

#appBody #loginScreen .ui-acceso-error {
  align-items: flex-start; gap: 10px; margin: 0; padding: 12px 14px; font-size: 14px; line-height: 1.45; font-weight: 500;
  color: #a1122a; background: #fdf0f2; border: 1px solid #f3c1ca; border-radius: 12px; box-shadow: none; backdrop-filter: none;
}
#appBody #loginScreen .ui-acceso-error:not(.hidden) { display: flex; }
html.dark #appBody #loginScreen .ui-acceso-error { color: #ffc4ce; background: rgb(225 29 72 / 14%); border-color: rgb(251 113 133 / 32%); }
#appBody #loginScreen .ui-acceso-error svg { flex: none; width: 18px; height: 18px; margin-top: 1px; color: currentColor; }
#appBody #loginScreen .ui-acceso-error span { font-weight: 500; }

#appBody #loginScreen #loginBtn {
  display: flex; align-items: center; justify-content: center; gap: 8px; width: 100%; height: 50px; margin: 4px 0 0; padding: 0 20px;
  border: 0; border-radius: 12px; font-size: 15px; font-weight: 600; letter-spacing: 0;
  background: var(--ui-primary); color: var(--ui-on-primary); box-shadow: none;
}
#appBody #loginScreen #loginBtn:hover { background: var(--ui-primary-hover); }
#appBody #loginScreen #loginBtn:disabled { opacity: .85; cursor: progress; }
#appBody #loginScreen #loginBtn svg { width: 18px; height: 18px; transition: translate var(--ui-fast) var(--ui-ease); }
#appBody #loginScreen #loginBtn:not(:disabled):hover svg { translate: 3px 0; }
#appBody #loginScreen .ui-acceso-ayuda { margin: 22px 0 0; font-size: 13px; line-height: 1.5; color: var(--ui-muted); }
#appBody #loginScreen .ui-acceso-ayuda strong { font-weight: 600; color: var(--ui-ink); }
#appBody #loginScreen .ui-acceso-seguro {
  display: flex; align-items: center; justify-content: center; gap: 6px; margin: auto 0 0; padding-top: 28px;
  font-size: 12px; line-height: 1.4; color: var(--ui-muted); text-align: center;
}
#appBody .ui-acceso-seguro svg { flex: none; width: 14px; height: 14px; }

@media (min-width: 640px) and (max-width: 1023.98px) {
  #appBody .ui-acceso-marca { padding: 32px 40px 64px; }
  #appBody .ui-acceso-panel { padding-top: 44px; }
  #appBody #loginScreen .ui-acceso-tema { top: 24px; right: 24px; }
}
@media (max-width: 1023.98px) and (max-height: 700px) {
  #appBody .ui-acceso-mensaje { display: none; }
}
@media (min-width: 1024px) {
  #appBody #loginScreen.ui-acceso:not(.hidden) { display: grid; grid-template-columns: minmax(420px, 44%) minmax(0, 1fr); }
  #appBody .ui-acceso-marca { min-height: 100%; justify-content: space-between; gap: 40px; padding: 40px 56px 36px; }
  #appBody .ui-acceso-mensaje { margin-block: auto; }
  #appBody #loginScreen .ui-acceso-lema { max-width: 15ch; font-size: clamp(34px, 2.8vw, 46px); line-height: 1.08; letter-spacing: -.035em; }
  #appBody .ui-acceso-puntos { display: grid; gap: 14px; margin: 32px 0 0; padding: 0; list-style: none; }
  #appBody .ui-acceso-puntos li { display: flex; align-items: center; gap: 12px; font-size: 15px; line-height: 1.35; color: rgb(255 255 255 / 84%); }
  #appBody .ui-acceso-puntos svg {
    flex: none; box-sizing: content-box; width: 18px; height: 18px; padding: 8px; border-radius: 10px;
    background: rgb(255 255 255 / 9%); box-shadow: inset 0 0 0 1px rgb(255 255 255 / 10%);
    color: color-mix(in oklab, var(--ui-primary) 30%, #fff);
  }
  #appBody .ui-acceso-pie { display: block; margin: 0; font-size: 13px; color: rgb(255 255 255 / 64%); }
  #appBody .ui-acceso-panel { justify-content: center; min-height: 100%; margin: 0; padding: 48px 40px 28px; border-radius: 0; }
  #appBody #loginCard.ui-acceso-tarjeta { margin-block: auto; }
  #appBody #loginScreen .ui-acceso-tema { top: 28px; right: 28px; }
  #appBody #loginScreen .ui-acceso-titulo { padding-right: 0; font-size: 32px; }
  #appBody #loginScreen .ui-acceso-seguro { margin-top: 32px; padding-top: 0; }
}
@media (prefers-reduced-motion: reduce) {
  #appBody .ui-acceso-onda { animation: none; opacity: 0; }
  #appBody #loginScreen #loginBtn svg { transition: none; }
}
@media (forced-colors: active) {
  #appBody .ui-acceso-relieve { display: none; }
}

/* Pantalla de carga («Conectando...», #globalLoader) con el fondo de la marca
   del acceso (regla compartida, arriba). El JS la muestra y oculta con .hidden y restaura
   su contenido; la recuperación de la conexión la reemplaza por .ui-carga-aviso.
   Hijos con margin: auto: centrados, y desplazables si no caben. */
#appBody #globalLoader.ui-carga {
  position: fixed; inset: 0; z-index: 99999; overflow-x: hidden; overflow-y: auto; isolation: isolate;
  padding: 24px 16px;
}
#appBody #globalLoader.ui-carga:not(.hidden) { display: flex; }
#appBody .ui-carga-relieve {
  -webkit-mask-image: radial-gradient(60% 55% at 50% 50%, rgb(0 0 0 / 12%), #000 85%);
  mask-image: radial-gradient(60% 55% at 50% 50%, rgb(0 0 0 / 12%), #000 85%);
}
#appBody .ui-carga-centro { display: flex; flex-direction: column; align-items: center; margin: auto; text-align: center; }
#appBody .ui-carga-logo {
  position: relative; display: block; width: 72px; height: 72px; margin-bottom: 20px; border-radius: 20px;
  box-shadow: 0 0 0 1px rgb(255 255 255 / 16%), 0 18px 50px -12px rgb(0 0 0 / 60%);
}
#appBody .ui-carga-logo img { display: block; width: 100%; height: 100%; object-fit: cover; border-radius: inherit; }
#appBody .ui-carga-logo::before, #appBody .ui-carga-logo::after {
  content: ""; position: absolute; inset: 0; border-radius: inherit; pointer-events: none;
  border: 1.5px solid color-mix(in oklab, var(--ui-primary) 30%, #fff); opacity: 0;
  animation: ui-carga-onda 2.4s var(--ui-ease) infinite;
}
#appBody .ui-carga-logo::after { animation-delay: 1.2s; }
@keyframes ui-carga-onda { from { transform: scale(1); opacity: .6; } to { transform: scale(1.75); opacity: 0; } }
#appBody .ui-carga-sistema { font-size: 17px; line-height: 1.3; font-weight: 600; letter-spacing: -.01em; }
#appBody .ui-carga-lugar { margin-top: 2px; font-size: 13px; line-height: 1.4; color: rgb(255 255 255 / 84%); }
#appBody .ui-carga-barra {
  position: relative; display: block; width: 168px; height: 3px; margin-top: 28px; overflow: hidden;
  border-radius: 3px; background: rgb(255 255 255 / 14%);
}
#appBody .ui-carga-barra::before {
  content: ""; position: absolute; top: 0; bottom: 0; left: 0; width: 40%; border-radius: inherit;
  background: color-mix(in oklab, var(--ui-primary) 30%, #fff);
  animation: ui-carga-barra 1.5s cubic-bezier(.45, 0, .25, 1) infinite;
}
@keyframes ui-carga-barra { from { transform: translateX(-100%); } to { transform: translateX(250%); } }
#appBody #globalLoader .ui-carga-estado {
  margin: 14px 0 0; font-size: 13px; line-height: 1.4; font-weight: 500; letter-spacing: 0; color: rgb(255 255 255 / 84%);
}

/* Recuperación de la conexión: tarjeta clara sobre el fondo de marca. */
#appBody #globalLoader .ui-carga-aviso {
  width: 100%; max-width: 440px; margin: auto; padding: 28px 24px 20px; color: var(--ui-ink);
  background: var(--ui-surface); border: 1px solid var(--ui-line); border-radius: 20px;
  box-shadow: 0 30px 80px -30px rgb(0 0 0 / 65%);
}
#appBody #globalLoader .ui-carga-aviso .text-\[9px\], #appBody #globalLoader .ui-carga-aviso .text-\[10px\],
#appBody #globalLoader .ui-carga-aviso .text-\[11px\] { font-size: 12px; }
#appBody #globalLoader .ui-carga-aviso .text-sm { font-size: 16px; line-height: 1.35; }
#appBody #globalLoader .ui-carga-aviso button { min-height: 40px; font-size: 13px; }

@media (prefers-reduced-motion: reduce) {
  #appBody .ui-carga-logo::before, #appBody .ui-carga-logo::after { animation: none; display: none; }
  #appBody .ui-carga-barra::before { animation: none; width: 100%; transform: none; opacity: .5; }
}
html.dv-quieto #appBody .ui-carga-logo::before, html.dv-quieto #appBody .ui-carga-logo::after { animation: none; display: none; }
html.dv-quieto #appBody .ui-carga-barra::before { animation: none; width: 100%; transform: none; opacity: .5; }

/* La columna de texto de cada cifra usa todo el ancho disponible: así su título se
   parte igual cargando y con datos, y la tarjeta no cambia de alto (R5). */
#appBody #dash_kpis > div > div:nth-child(2) { flex: 1 1 auto; min-width: 0; }

/* ── Padrón Electoral: una sola barra (29/09, padron.py) ──
   Búsqueda, Sección, Casilla y Barrio a la vista; debajo, las cifras grandes
   (Total, A favor, Indecisos, En contra), que filtran, y Completos / Incompletos.
   Los filtros de antes quedan ocultos y guardan el estado (Panel, Día D, chips de
   filtros activos, paginación). */
#appBody #pe-consulta > .ui-pe-barra + div { display: none; }
#appBody #page-padron-electoral #pe-consulta table > thead > tr:has(#pe_filtro_nombre) { display: none !important; }
#appBody #pe-consulta div:has(> #pe_total_resultados) { display: none; }
/* «Resultados de Búsqueda» queda para lectores de pantalla: arriba ya se ve el conteo. */
#appBody #pe-consulta div:has(> div > #pe_total_resultados) {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0;
}
#appBody #pe_alcance_tabla { display: none; }

#appBody .ui-pe-barra {
  display: flex; flex-direction: column; gap: 14px; padding: 16px 18px;
  background: var(--ui-surface); border: 1px solid var(--ui-line); border-radius: 18px; box-shadow: var(--ui-shadow);
}
#appBody .ui-pe-barra-fila { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 10px 12px; }
#appBody .ui-pe-buscar { position: relative; display: flex; align-items: center; flex: 1 1 280px; min-width: 0; }
#appBody .ui-pe-buscar > svg { position: absolute; left: 12px; width: 18px; height: 18px; color: var(--ui-muted); pointer-events: none; }
#appBody .ui-pe-buscar input {
  width: 100%; height: 40px; padding: 0 12px 0 38px; border: 1px solid var(--ui-control-line); border-radius: 10px;
  background: var(--ui-surface); color: var(--ui-ink); font-size: 14px; font-weight: 500;
}
#appBody .ui-pe-buscar input::placeholder { color: var(--ui-muted); opacity: 1; }
#appBody .ui-pe-campo { display: flex; flex-direction: column; gap: 4px; flex: 0 1 150px; min-width: 110px; font-size: 12px; line-height: 16px; font-weight: 600; color: var(--ui-muted); }
#appBody .ui-pe-campo-ancho { flex: 0 1 220px; }
#appBody .ui-pe-campo select {
  width: 100%; min-height: 40px; padding: 9px 10px; border: 1px solid var(--ui-control-line); border-radius: 10px;
  background-color: var(--ui-surface); color: var(--ui-ink); font-size: 14px; line-height: 20px; font-weight: 600; cursor: pointer;
}

/* Cifras grandes que filtran y, a un lado, el estado del expediente. */
#appBody .ui-pe-cifras { display: grid; gap: 10px; grid-template-columns: minmax(0, 1fr); }
@media (min-width: 1024px) { #appBody .ui-pe-cifras { grid-template-columns: minmax(0, 1fr) auto; } }
#appBody .ui-pe-tarjetas { display: grid; gap: 10px; grid-template-columns: repeat(4, minmax(0, 1fr)); }
#appBody .ui-pe-seg {
  border: 1px solid var(--ui-line); background: var(--ui-surface); color: var(--ui-ink); cursor: pointer;
  transition: background-color var(--ui-fast) var(--ui-ease), border-color var(--ui-fast) var(--ui-ease), box-shadow var(--ui-fast) var(--ui-ease);
}
#appBody .ui-pe-seg[aria-pressed="true"] { border-color: var(--ui-accent); box-shadow: inset 0 0 0 2px var(--ui-accent); }
#appBody .ui-pe-tarjeta {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px; min-width: 0;
  padding: 12px 8px; border-radius: 14px; background: var(--ui-subtle); text-align: center;
}
#appBody .ui-pe-tarjeta > span {
  display: inline-flex; align-items: center; gap: 5px; font-size: 12px; line-height: 16px; font-weight: 650;
  letter-spacing: .04em; text-transform: uppercase; color: var(--ui-muted);
}
#appBody .ui-pe-tarjeta > span svg { width: 14px; height: 14px; flex-shrink: 0; }
#appBody .ui-pe-tarjeta > b { font-size: 28px; line-height: 32px; font-weight: 750; font-variant-numeric: tabular-nums; color: var(--ui-ink); }
#appBody .ui-pe-tarjeta:hover { filter: brightness(.97); }
#appBody .ui-pe-seg-favor { background: #e9f6ee; border-color: #bfe3cd; }
#appBody .ui-pe-seg-favor > span, #appBody .ui-pe-seg-favor > b { color: #1b7a43; }
#appBody .ui-pe-seg-indeciso { background: #fdf3e2; border-color: #f1d6a6; }
#appBody .ui-pe-seg-indeciso > span, #appBody .ui-pe-seg-indeciso > b { color: #8f5400; }
#appBody .ui-pe-seg-contra { background: #fdecee; border-color: #f4c3c9; }
#appBody .ui-pe-seg-contra > span, #appBody .ui-pe-seg-contra > b { color: #b42332; }
html.dark #appBody .ui-pe-seg-favor { background: rgb(31 138 76 / 16%); border-color: rgb(95 208 140 / 30%); }
html.dark #appBody .ui-pe-seg-favor > span, html.dark #appBody .ui-pe-seg-favor > b { color: #6fd79b; }
html.dark #appBody .ui-pe-seg-indeciso { background: rgb(184 110 0 / 18%); border-color: rgb(245 185 74 / 30%); }
html.dark #appBody .ui-pe-seg-indeciso > span, html.dark #appBody .ui-pe-seg-indeciso > b { color: #f5b94a; }
html.dark #appBody .ui-pe-seg-contra { background: rgb(194 65 58 / 18%); border-color: rgb(255 139 130 / 30%); }
html.dark #appBody .ui-pe-seg-contra > span, html.dark #appBody .ui-pe-seg-contra > b { color: #ffb4bc; }
html.dark #appBody .ui-pe-tarjeta:hover { filter: brightness(1.12); }

#appBody .ui-pe-segmentos { display: flex; flex-wrap: wrap; gap: 8px; }
@media (min-width: 1024px) { #appBody .ui-pe-segmentos { flex-direction: column; justify-content: center; } }
#appBody .ui-pe-segmentos .ui-pe-seg {
  display: inline-flex; align-items: baseline; justify-content: center; gap: 6px; min-height: 36px; padding: 7px 14px;
  border-radius: 999px; font-size: 13px; line-height: 18px; font-weight: 500;
}
#appBody .ui-pe-segmentos .ui-pe-seg b { font-size: 15px; font-weight: 700; font-variant-numeric: tabular-nums; }
#appBody .ui-pe-segmentos .ui-pe-seg:hover { background: var(--ui-subtle); }
#appBody .ui-pe-segmentos .ui-pe-seg[aria-pressed="true"] { background: var(--ui-selected); }

@media (max-width: 767.98px) {
  #appBody .ui-pe-tarjetas { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  #appBody .ui-pe-segmentos { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); }
  #appBody .ui-pe-segmentos .ui-pe-seg { min-height: 44px; }
}
@media (max-width: 639.98px) {
  #appBody .ui-pe-barra { padding: 14px; }
  #appBody .ui-pe-buscar { flex-basis: 100%; }
  #appBody .ui-pe-campo { flex: 1 1 calc(50% - 6px); min-width: 0; }
  #appBody .ui-pe-campo-ancho { flex-basis: 100%; }
  #appBody .ui-pe-campo select { min-height: 44px; padding-block: 11px; }
  #appBody .ui-pe-tarjeta > b { font-size: 24px; line-height: 28px; }
}

/* ── Etapa 2 · fotos (29/09): foto de la persona ──
   Expediente: marco de retrato 4:5 (144 × 180) en lugar del círculo con aro
   blanco, que cortaba coronilla y barbilla. Tamaño fijo: la foto no mueve nada
   al cargar. Las fotos viejas (retrato 3:4) se ajustan hacia la cara. Sin foto,
   las iniciales de la persona (o una silueta) y «Sin foto» o «Foto no
   disponible». En edición, un consejo y el estado de la foto nueva bajo el
   campo de archivo (mejoras/fotos.py). */
#appBody #mp_foto_container {
  width: 9rem; height: 11.25rem; border-radius: 14px;
  border: 1px solid var(--ui-line); background: var(--ui-subtle);
  box-shadow: 0 1px 3px rgb(25 32 45 / 10%);
  flex-direction: column; gap: 2px;
}
#appBody #mp_foto_container img,
#appBody #geo_foto_container img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 30%; }
#appBody .ui-foto-iniciales { font: 600 40px/1 var(--ui-font); letter-spacing: .02em; color: var(--ui-muted); }
#appBody .ui-foto-sin-texto { font-size: 12px; line-height: 16px; font-weight: 500; color: var(--ui-muted); }
#appBody .ui-foto-icono { width: 48px; height: 48px; color: var(--ui-muted); }
/* Ficha territorial (módulo ubicacion): miniatura chica. */
#appBody #geo_foto_container .ui-foto-iniciales { font-size: 16px; }
#appBody #geo_foto_container .ui-foto-icono { width: 22px; height: 22px; }
/* «Cambiar foto» (sección expediente) sobre el borde recto del marco. */
#appBody #mp_foto_container.ui-foto-editable::after { padding: 8px 0; }
/* Edición: el campo de archivo (23 px) y «Quitar foto» (32 px) se tocan con el
   dedo en el teléfono: 44 px de alto; el botón del archivo, a 12 px (tenía 10). */
#appBody #mp_foto_input { min-height: 44px; }
#appBody #mp_foto_input::file-selector-button { min-height: 44px; font-size: 12px; line-height: 16px; }
#appBody #btnEliminarFoto { min-height: 44px; }
/* Oscuro: el botón del archivo (file:bg-indigo-50) y «Quitar foto» (bg-red-50)
   quedaban claros sobre la tarjeta; mismo trato que «Escanear INE». */
html.dark #appBody #mp_foto_input::file-selector-button { background: var(--ui-selected); color: var(--ui-accent-legible, var(--ui-accent)); }
html.dark #appBody #btnEliminarFoto { background: rgb(127 29 29 / 30%); border-color: rgb(153 27 27 / 60%); color: #f87171; }
html.dark #appBody #btnEliminarFoto:hover { background: rgb(127 29 29 / 50%); color: #fca5a5; }
/* Edición: consejo y estado de la foto nueva. */
#appBody .ui-foto-consejo,
#appBody .ui-foto-estado { margin: 0; max-width: 16rem; font-size: 12px; line-height: 16px; color: var(--ui-muted); text-align: center; }
/* Vacío, el estado no ocupa lugar pero sigue en el árbol accesible: con
   display: none, el primer aviso («Preparando la foto…») no se anunciaba. */
#appBody .ui-foto-estado:empty {
  position: absolute; width: 1px; height: 1px; margin: 0; padding: 0;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}
/* «Ese archivo no es una foto…»: tono 700 en claro y 400 en oscuro (DISENO_UI). */
#appBody .ui-foto-estado[data-tipo="error"] { color: #b91c1c; font-weight: 600; }
html.dark #appBody .ui-foto-estado[data-tipo="error"] { color: #f87171; }
/* ── fin · Etapa 2 · fotos ── */

/* ── Etapa 2 · ubicación (29/09): ficha «Ubicación y evidencias» y vista de calle ──
   Marcado de mejoras/ubicacion.py (clases ui-ubic-*). Nada propio flota sobre el
   mapa: la barra de herramientas va encima y el estado del punto debajo. En la
   vista de calle (.ui-vista-calle, que pone window.UIMapas) se ocultan los
   [data-ui-solo-mapa] y aparece la barra [data-ui-solo-calle] «Volver al mapa».
   En el teléfono la ventana es la hoja de la capa móvil; desde 1024 px, el mapa
   ocupa la izquierda (58 %) y los datos la derecha. Sin animaciones propias. ── */
/* .ui-ubic-boton y otros fijan display: el atributo hidden tiene que ganar. */
#appBody #modalMapaEvidencias [hidden] { display: none !important; }
#appBody [data-ui-solo-calle] { display: none; }
#appBody .ui-vista-calle [data-ui-solo-calle] { display: flex; }
#appBody .ui-vista-calle [data-ui-solo-mapa] { display: none !important; }

#appBody .ui-ubic { background: var(--ui-surface); color: var(--ui-ink); font-family: var(--ui-font); }

/* Encabezado: foto, «Ubicación y evidencias», nombre, sección y casilla. */
#appBody .ui-ubic-cabeza {
  display: flex; flex: none; align-items: center; gap: 12px; padding: 12px 16px;
  border-bottom: 1px solid var(--ui-line); background: var(--ui-subtle);
}
#appBody .ui-ubic-foto {
  flex: none; display: flex; align-items: center; justify-content: center; width: 44px; height: 44px;
  border-radius: 50%; overflow: hidden; border: 1px solid var(--ui-line); background: var(--ui-surface); color: var(--ui-muted);
}
#appBody .ui-ubic-foto img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 30%; }
#appBody .ui-ubic-foto svg { width: 22px; height: 22px; }
#appBody .ui-ubic-titulos { flex: 1 1 auto; min-width: 0; }
#appBody .ui-ubic-ceja { margin: 0 0 4px; font-size: 12px; line-height: 16px; font-weight: 500; color: var(--ui-muted); }
/* Al abrir, el foco va al nombre (UIAccesibilidad): su anillo no tapa «Ubicación y evidencias». */
#appBody #modalMapaEvidencias .ui-ubic-nombre:focus { outline-offset: 1px; border-radius: 4px; }
#appBody .ui-ubic-nombre {
  margin: 0; font-size: 17px; line-height: 22px; font-weight: 700; letter-spacing: 0; color: var(--ui-ink);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
#appBody .ui-ubic-sub {
  margin: 0; font-size: 13px; line-height: 18px; color: var(--ui-muted);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* Botones de la ficha. */
#appBody .ui-ubic-boton {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px; min-height: 44px; padding: 0 16px;
  border: 1px solid var(--ui-control-line); border-radius: 12px; background: var(--ui-surface); color: var(--ui-ink);
  font: 600 14px/20px var(--ui-font); text-align: center; cursor: pointer;
}
#appBody .ui-ubic-boton:hover { background: var(--ui-subtle); }
#appBody .ui-ubic-boton svg { flex: none; width: 18px; height: 18px; }
#appBody .ui-ubic-primario { border-color: var(--ui-primary); background: var(--ui-primary); color: var(--ui-on-primary); }
#appBody .ui-ubic-primario:hover { background: var(--ui-primary); box-shadow: inset 0 0 0 999px rgb(0 0 0 / 8%); }
#appBody .ui-ubic-boton[aria-disabled="true"] {
  border-color: var(--ui-line); background: var(--ui-subtle); color: var(--ui-muted); box-shadow: none; cursor: default;
}
#appBody .ui-ubic-cerrar {
  flex: none; display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; min-width: 44px; min-height: 44px; padding: 0; border-radius: 50%;
  border: 1px solid var(--ui-control-line); background: var(--ui-surface); color: var(--ui-ink); cursor: pointer;
}
#appBody .ui-ubic-cerrar:hover { background: var(--ui-subtle); }
#appBody .ui-ubic-expediente { flex: none; }
#appBody .ui-ubic-cerrar svg { width: 20px; height: 20px; }
#appBody .ui-ubic-enlace {
  display: inline-flex; align-items: center; min-height: 44px; padding: 0 4px; border: 0; background: none;
  color: var(--ui-accent-legible, var(--ui-accent)); font: 600 14px/20px var(--ui-font);
  text-decoration: underline; text-underline-offset: 3px; cursor: pointer;
}
/* Foco de 3 px (el general es de 2 px con !important). */
#appBody #modalMapaEvidencias .ui-ubic-boton:focus-visible, #appBody #modalMapaEvidencias .ui-ubic-cerrar:focus-visible,
#appBody #modalMapaEvidencias .ui-ubic-enlace:focus-visible, #appBody #modalMapaEvidencias .ui-ubic-borrar:focus-visible,
#appBody #modalMapaEvidencias .ui-ubic-foto-ver:focus-visible { outline: 3px solid var(--ui-accent) !important; outline-offset: 2px; }
/* «Poner el punto en el centro del mapa»: solo aparece al llegar con el teclado. */
#appBody .ui-ubic-solo-teclado { position: absolute; left: -10000px; top: auto; }
#appBody .ui-ubic-solo-teclado:focus-visible { position: static; }

/* Cuerpo: en el teléfono todo se desplaza en una columna. */
#appBody .ui-ubic-cuerpo {
  display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0;
  overflow-y: auto; overscroll-behavior: contain;
}
#appBody .ui-ubic-mapa { display: flex; flex-direction: column; flex: none; min-width: 0; border-bottom: 1px solid var(--ui-line); }
#appBody .ui-ubic-herramientas { display: flex; }
#appBody .ui-ubic-herramientas, #appBody .ui-ubic-barra-calle { flex-wrap: wrap; align-items: center; gap: 8px; padding: 10px 12px; }
#appBody .ui-ubic-barra-calle { justify-content: space-between; background: var(--ui-selected); }
#appBody .ui-ubic-barra-calle p { margin: 0; font-size: 14px; line-height: 20px; font-weight: 600; color: var(--ui-ink); }
#appBody .ui-ubic-buscar { position: relative; flex: 1 1 200px; min-width: 0; }
#appBody .ui-ubic-buscar > svg {
  position: absolute; left: 12px; top: 50%; width: 18px; height: 18px; margin-top: -9px;
  color: var(--ui-muted); pointer-events: none;
}
#appBody #modalMapaEvidencias .ui-ubic-buscar-campo {
  width: 100%; height: 44px; padding: 0 12px 0 38px; font-size: 16px; line-height: 24px;
  border: 1px solid var(--ui-control-line); border-radius: 10px; background: var(--ui-surface); color: var(--ui-ink);
}
#appBody #modalMapaEvidencias .ui-ubic-buscar-campo::placeholder { color: var(--ui-muted); opacity: 1; }

/* Mapa: altura fija en el teléfono; nada propio encima salvo la mira y el aviso. */
#appBody .ui-ubic-lienzo {
  position: relative; flex: none; overflow: hidden; background: var(--ui-subtle);
  height: clamp(240px, 42vh, 440px); height: clamp(240px, 42dvh, 440px);
}
/* Google pone position:relative en línea al contenedor del mapa. */
#appBody #mapaGeolocalizacion { position: absolute !important; inset: 0; }
#appBody .ui-ubic-mapa-aviso {
  position: absolute; inset: 0; z-index: 1; display: flex; align-items: center; justify-content: center;
  margin: 0; padding: 24px; text-align: center; font-size: 14px; line-height: 20px; color: var(--ui-ink); background: var(--ui-subtle);
}
#appBody .ui-ubic-mira {
  display: none; position: absolute; left: 50%; top: 50%; z-index: 2; width: 28px; height: 28px; margin: -14px 0 0 -14px;
  pointer-events: none; filter: drop-shadow(0 0 1px rgb(0 0 0 / 90%)) drop-shadow(0 0 2px rgb(0 0 0 / 70%));
}
#appBody .ui-ubic-mira::before, #appBody .ui-ubic-mira::after { content: ''; position: absolute; background: #fff; }
#appBody .ui-ubic-mira::before { left: 13px; top: 0; width: 2px; height: 28px; }
#appBody .ui-ubic-mira::after { left: 0; top: 13px; width: 28px; height: 2px; }
#appBody .ui-ubic-lienzo:focus-within .ui-ubic-mira, #appBody .ui-ubic-mira-activa .ui-ubic-mira { display: block; }

/* Estado del punto, debajo del mapa; sus enlaces («Ver la dirección sugerida»,
   «Regresar al punto guardado») en una fila que se parte si no caben. */
#appBody .ui-ubic-punto { display: flex; flex-direction: column; align-items: flex-start; gap: 4px; padding: 8px 12px 12px; }
#appBody .ui-ubic-punto-acciones { display: flex; flex-wrap: wrap; align-items: center; gap: 0 16px; }
#appBody .ui-ubic-punto-texto { margin: 0; font-size: 13px; line-height: 18px; font-variant-numeric: tabular-nums; color: var(--ui-ink); }
#appBody .ui-ubic-punto-texto[data-tono="aviso"] { color: #8a5a00; }
#appBody .ui-ubic-punto-texto[data-tono="error"] { color: #b42332; font-weight: 600; }
html.dark #appBody .ui-ubic-punto-texto[data-tono="aviso"] { color: #ffd58a; }
html.dark #appBody .ui-ubic-punto-texto[data-tono="error"] { color: #ffb4bc; }

/* Datos: domicilio y visita. */
#appBody .ui-ubic-datos { display: flex; flex-direction: column; gap: 16px; min-width: 0; padding: 16px; }
#appBody .ui-ubic-seccion {
  display: flex; flex-direction: column; gap: 12px; padding: 16px;
  border: 1px solid var(--ui-line); border-radius: 16px; background: var(--ui-surface);
}
#appBody .ui-ubic-h { margin: 0; font-size: 15px; line-height: 20px; font-weight: 700; letter-spacing: 0; text-transform: none; color: var(--ui-ink); }
#appBody .ui-ubic-campo { display: flex; flex-direction: column; gap: 6px; }
#appBody .ui-ubic-campo > label, #appBody .ui-ubic-etq { margin: 0; font-size: 14px; line-height: 20px; font-weight: 600; color: var(--ui-ink); }
#appBody #modalMapaEvidencias .ui-ubic-input {
  width: 100%; min-height: 44px; padding: 10px 12px; font-size: 16px; line-height: 22px;
  border: 1px solid var(--ui-control-line); border-radius: 10px; background: var(--ui-surface); color: var(--ui-ink);
}
#appBody #modalMapaEvidencias .ui-ubic-mayus { text-transform: uppercase; }
#appBody #modalMapaEvidencias .ui-ubic-mayus::placeholder { text-transform: none; color: var(--ui-muted); opacity: 1; }
#appBody #modalMapaEvidencias .ui-ubic-input:disabled, #appBody #modalMapaEvidencias .ui-ubic-input[readonly] {
  background: var(--ui-subtle); color: var(--ui-ink); -webkit-text-fill-color: var(--ui-ink); opacity: 1;
}
/* El combo del catálogo marca el error con border-rose-400. */
#appBody #modalMapaEvidencias .ui-ubic-input.border-rose-400, #appBody #modalMapaEvidencias .ui-ubic-input.ui-ubic-invalido { border-color: #b42332; }
html.dark #appBody #modalMapaEvidencias .ui-ubic-input.border-rose-400, html.dark #appBody #modalMapaEvidencias .ui-ubic-input.ui-ubic-invalido { border-color: #ffb4bc; }
#appBody .ui-ubic-ayuda { margin: 0; font-size: 13px; line-height: 18px; color: var(--ui-muted); }
#appBody .ui-ubic-nota { margin: 0; font-size: 13px; line-height: 18px; color: #8a5a00; }
#appBody .ui-ubic-error { margin: 0; font-size: 13px; line-height: 18px; font-weight: 600; color: #b42332; }
html.dark #appBody .ui-ubic-nota { color: #ffd58a; }
html.dark #appBody .ui-ubic-error { color: #ffb4bc; }

/* Dirección que sugiere Google (solo se copia al tocar «Usar esta dirección»). */
#appBody .ui-ubic-sugerencia {
  display: flex; flex-direction: column; gap: 6px; padding: 12px;
  border: 1px solid var(--ui-accent); border-left-width: 4px; border-radius: 12px; background: var(--ui-selected);
}
#appBody .ui-ubic-sugerencia-titulo { margin: 0; font-size: 13px; line-height: 18px; font-weight: 600; color: var(--ui-muted); }
#appBody .ui-ubic-sugerencia-valor { margin: 0; font-size: 15px; line-height: 20px; font-weight: 700; text-transform: uppercase; overflow-wrap: break-word; color: var(--ui-ink); }
#appBody .ui-ubic-sugerencia-botones { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; margin-top: 4px; }

/* Simpatía: el color acompaña al texto de la opción (va después de :disabled). */
#appBody #modalMapaEvidencias .ui-ubic-simpatia[data-simpatia="A FAVOR"] { border-color: #2e7d4f; background: #e8f5ee; color: #0d5c36; -webkit-text-fill-color: #0d5c36; }
#appBody #modalMapaEvidencias .ui-ubic-simpatia[data-simpatia="EN CONTRA"] { border-color: #c2413f; background: #fdecee; color: #9b1c2c; -webkit-text-fill-color: #9b1c2c; }
#appBody #modalMapaEvidencias .ui-ubic-simpatia[data-simpatia="INDECISO"] { border-color: #b7791f; background: #fff5e0; color: #7a4b00; -webkit-text-fill-color: #7a4b00; }
html.dark #appBody #modalMapaEvidencias .ui-ubic-simpatia[data-simpatia="A FAVOR"] { border-color: #5fbf8a; background: #183626; color: #a7e3c0; -webkit-text-fill-color: #a7e3c0; }
html.dark #appBody #modalMapaEvidencias .ui-ubic-simpatia[data-simpatia="EN CONTRA"] { border-color: #e0707a; background: #3a1a1f; color: #ffb4bc; -webkit-text-fill-color: #ffb4bc; }
html.dark #appBody #modalMapaEvidencias .ui-ubic-simpatia[data-simpatia="INDECISO"] { border-color: #d9a441; background: #3a2a10; color: #ffd58a; -webkit-text-fill-color: #ffd58a; }

/* Fotos de la visita: el campo de archivo cubre toda la etiqueta (objetivo de 48 px). */
#appBody .ui-ubic-subir {
  position: relative; display: flex; align-items: center; justify-content: center; gap: 8px; min-height: 48px; padding: 8px 16px;
  border: 2px dashed var(--ui-control-line); border-radius: 12px; background: var(--ui-surface); color: var(--ui-ink);
  font: 600 15px/20px var(--ui-font); text-align: center; cursor: pointer;
}
#appBody .ui-ubic-subir:hover { background: var(--ui-subtle); }
#appBody .ui-ubic-subir:focus-within { outline: 3px solid var(--ui-accent); outline-offset: 2px; }
#appBody .ui-ubic-subir[aria-busy="true"] { opacity: .7; cursor: progress; }
#appBody .ui-ubic-subir svg { flex: none; width: 20px; height: 20px; }
#appBody #modalMapaEvidencias .ui-ubic-subir-archivo {
  position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; padding: 0; opacity: 0; cursor: pointer;
}
#appBody .ui-ubic-fotos-estado { margin: 0; font-size: 14px; line-height: 20px; font-weight: 600; color: var(--ui-ink); }
#appBody .ui-ubic-fotos-estado:empty { display: none; }
#appBody .ui-ubic-galeria {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: 12px;
  margin: 0; padding: 0; list-style: none;
}
#appBody .ui-ubic-galeria:empty { display: none; }
#appBody .ui-ubic-foto-item { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
#appBody .ui-ubic-foto-ver {
  display: block; aspect-ratio: 4 / 3; overflow: hidden; border-radius: 10px;
  border: 1px solid var(--ui-line); background: var(--ui-subtle);
}
#appBody .ui-ubic-foto-ver img { display: block; width: 100%; height: 100%; object-fit: cover; }
#appBody .ui-ubic-borrar {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px; width: 100%; min-height: 44px; padding: 0 12px;
  border: 1px solid #b42332; border-radius: 10px; background: var(--ui-surface); color: #b42332;
  font: 600 14px/20px var(--ui-font); cursor: pointer;
}
#appBody .ui-ubic-borrar:hover { background: #fdecee; }
#appBody .ui-ubic-borrar svg { flex: none; width: 16px; height: 16px; }
html.dark #appBody .ui-ubic-borrar { border-color: #ff8a97; color: #ffb4bc; }
html.dark #appBody .ui-ubic-borrar:hover { background: #3a1a1f; }

/* Pie: estado del guardado (escrito, con un punto de color) y «Guardar cambios». */
#appBody .ui-ubic-pie {
  display: flex; flex: none; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px 12px;
  padding: 12px 16px; border-top: 1px solid var(--ui-line); background: var(--ui-surface);
}
#appBody .ui-ubic-estado { display: flex; align-items: flex-start; gap: 8px; flex: 1 1 200px; margin: 0; font-size: 13px; line-height: 18px; color: var(--ui-ink); }
#appBody .ui-ubic-estado::before { content: ''; flex: none; width: 8px; height: 8px; margin-top: 5px; border-radius: 50%; background: var(--ui-muted); }
#appBody .ui-ubic-estado[data-tipo="neutro"] { color: var(--ui-muted); }
#appBody .ui-ubic-estado[data-tipo="pendiente"]::before { background: #b7791f; }
#appBody .ui-ubic-estado[data-tipo="ok"]::before { background: #1e7a4a; }
#appBody .ui-ubic-estado[data-tipo="error"] { color: #b42332; font-weight: 600; }
#appBody .ui-ubic-estado[data-tipo="error"]::before { background: #b42332; }
html.dark #appBody .ui-ubic-estado[data-tipo="pendiente"]::before { background: #e0a84a; }
html.dark #appBody .ui-ubic-estado[data-tipo="ok"]::before { background: #5fbf8a; }
html.dark #appBody .ui-ubic-estado[data-tipo="error"] { color: #ffb4bc; }
html.dark #appBody .ui-ubic-estado[data-tipo="error"]::before { background: #ffb4bc; }
#appBody .ui-ubic-guardar { min-width: 200px; min-height: 48px; }
#appBody .ui-ubic-solo-lectura { display: none; margin: 0; font-size: 13px; line-height: 18px; color: var(--ui-muted); }
#appBody.modo-solo-lectura .ui-ubic-solo-lectura { display: block; }
#appBody.modo-solo-lectura #geo_estado_guardado { display: none; }

/* Sugerencias de Places: encima de la hoja (mismo valor que 'pac-container-fix') y tocables. */
#appBody > .pac-container { z-index: 999999 !important; }
#appBody > .pac-container .pac-item { padding: 10px 12px; font-size: 15px; line-height: 22px; }

@media (max-width: 767.98px) {
  /* La manija de la hoja queda encima del encabezado. */
  #appBody .ui-ubic-cabeza { padding-top: 18px; }
  #appBody .ui-ubic-guardar { flex: 1 1 100%; }
}
@media (max-width: 479.98px) {
  #appBody .ui-ubic-texto-ancho { display: none; }
  #appBody .ui-ubic-expediente { width: 44px; min-width: 44px; padding: 0; }
  /* El nombre en dos renglones: en una familia los apellidos se repiten y el nombre
     de pila queda en el segundo (con uno solo se cortaba en «HERNÁNDEZ LÓP…»). */
  #appBody .ui-ubic-cabeza { gap: 8px; }
  #appBody .ui-ubic-nombre {
    font-size: 16px; line-height: 20px; white-space: normal; overflow-wrap: break-word;
    display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2;
  }
  #appBody .ui-ubic-sub { white-space: normal; }
}
@media (min-width: 768px) and (max-width: 1023.98px) {
  #appBody .ui-ubic-lienzo { height: 380px; }
}
/* Teléfono acostado: el mapa cabe en la zona que se desplaza (con gestos
   'cooperative', un dedo desplaza la hoja; ver gestos() en ubicacion.py). */
@media (orientation: landscape) and (max-height: 520px) and (max-width: 1023.98px) {
  #appBody .ui-ubic-lienzo { height: max(160px, calc(90vh - 170px)); height: max(160px, calc(90dvh - 170px)); }
}
@media (min-width: 1024px) {
  #appBody .ui-ubic-cuerpo { flex-direction: row; overflow: hidden; }
  /* En escritorios bajos (1366×657, 1280×600) el mapa cede altura antes que el estado
     del punto; si aun así no cabe, la columna se desplaza. */
  #appBody .ui-ubic-mapa { flex: 0 0 58%; min-height: 0; border-bottom: 0; border-right: 1px solid var(--ui-line); overflow-y: auto; overscroll-behavior: contain; }
  #appBody .ui-ubic-lienzo { flex: 1 1 auto; height: auto; min-height: 200px; }
  #appBody .ui-ubic-datos { flex: 1 1 42%; min-width: 0; overflow-y: auto; overscroll-behavior: contain; }
  /* La tarjeta de la sugerencia está a la vista, en la columna de la derecha. */
  #appBody #geo_btn_ver_sugerencia { display: none; }
}
/* ── fin · Etapa 2 · ubicacion ── */
/* Control del guardado: colores propios, disponibles sin recompilar Tailwind. */
#appBody #servicio-activar, #appBody #servicio-desactivar {
  padding: .75rem 1rem;
  border: 1px solid transparent;
  border-radius: .75rem;
  color: #fff;
  font-weight: 700;
  cursor: pointer;
  transition: none;
}
#appBody #servicio-activar { background-color: #166534; }
#appBody #servicio-desactivar { background-color: #b91c1c; }
#appBody #servicio-activar:disabled, #appBody #servicio-desactivar:disabled {
  background-color: #e2e8f0;
  border-color: #94a3b8;
  color: #475569;
  opacity: 1;
  cursor: not-allowed;
}
#appBody #servicio-activar:focus-visible, #appBody #servicio-desactivar:focus-visible { outline: 3px solid #2563eb; outline-offset: 3px; }
