/* ============================================================================
   PANEL DE ADMINISTRACIÓN — Estilos propios.
   Sin Bootstrap, sin jQuery — mismo criterio que portal_usuarios y crm_emails.
   ========================================================================= */

:root {
  --azul: #0064A2;
  --azul-oscuro: #004b7a;
  --azul-noche: #00263E;
  --celeste: #5BA4C5;
  --tinta: #1c2733;
  --gris: #64748b;
  --linea: #dbe4ec;
  --papel: #ffffff;
  --fondo: #f4f7fa;
  --error: #b3261e;
  --error-fondo: #fdecea;
  --ok: #1e7e34;
  --ok-fondo: #e9f7ef;
  --info: #0064A2;
  --info-fondo: #e8f2fa;
  --radio: 10px;
  --radio-chico: 6px;
  --sombra: 0 4px 18px rgba(28, 39, 51, .08);
  --fuente: "Poppins", "Segoe UI", system-ui, sans-serif;

  --header-alto: 60px;
  --menu-ancho: 280px;
  --menu-ancho-colapsado: 60px;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  min-height: 100vh;
  background: var(--fondo);
  color: var(--tinta);
  font-family: var(--fuente);
  font-size: 15px;
  font-weight: 400;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

/* Todo el texto arranca en peso normal; solo los selectores puntuales que
   ya existen (h1-h4, .is-activa, encabezados de tabla, etc.) suben el
   peso. Sin esto, si Poppins tarda en cargar o no carga, el navegador
   puede caer a una fuente del sistema con apariencia más pesada. */
p, span, td, th, label, a, li, dt, dd, div { font-weight: inherit; }

/* Altura fija al viewport (no min-height): sin esto, cuando el contenido de
   una pestaña desborda, es la PÁGINA ENTERA la que crece y scrollea —
   arrastrando el header, el menú lateral y la barra de pestañas con ella,
   en vez de quedar fijos mientras solo el contenido interno (.panel-tabs__contenido)
   hace scroll. La pantalla de login (.panel-body--login) es la excepción:
   ahí sí puede crecer y scrollear como una página normal. */
/* height: 100dvh (con el 100vh de arriba como respaldo en navegadores que no
   la soportan) — en móvil, 100vh se calcula sobre el viewport SIN la barra de
   direcciones, así que al cargar con la barra visible el contenedor real queda
   más alto de lo que se ve en pantalla: el pie terminaba "flotando" a mitad de
   camino con una franja blanca (el fondo crudo de <body>, no de .panel-body)
   debajo, en vez de pegado al borde inferior real. dvh sigue el viewport visible
   de verdad. */
.panel-body { display: flex; flex-direction: column; height: 100vh; height: 100dvh; overflow: hidden; }
.panel-body--login { height: auto; min-height: 100vh; overflow: visible; }

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

svg { width: 18px; height: 18px; flex: none; }

/* La barra de herramientas de TinyMCE vive directo en la página (solo el
   área de edición va en <iframe>), así que la regla genérica de arriba le
   aprieta los íconos propios — se ven amontonados/superpuestos. .tox es la
   raíz de TinyMCE; acá se le devuelve su propio tamaño, sin tocar la regla
   general (que sigue aplicando a los íconos del panel, ej. urb_icono()). */
.tox svg { width: auto; height: auto; flex: initial; }

/* Mismo problema que TinyMCE arriba: ApexCharts (Informes) dibuja su propio
   <svg>, y la regla genérica de la línea 67 lo aplastaba a 18x18 — el gráfico
   quedaba invisible aunque el HTML sí se generara (confirmado inspeccionando
   el DOM: el <svg> traía width/height="1577"/"360" en sus atributos, pero el
   bounding rect real medía 18x18). .apexcharts-canvas es la raíz que la
   propia librería pone alrededor de cada gráfico. */
.apexcharts-canvas svg { width: auto; height: auto; flex: initial; }

/* ---------------------------------------------------------------------
   Botones y avisos, compartidos entre las tres pantallas
   ------------------------------------------------------------------- */

.boton, .panel-boton {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  border: 1px solid var(--linea);
  background: var(--papel);
  color: var(--tinta);
  border-radius: var(--radio-chico);
  padding: 10px 16px;
  font-weight: 500;
  cursor: pointer;
  text-decoration: none;
  transition: background .15s, border-color .15s;
}
.boton:hover, .panel-boton:hover { border-color: var(--azul); }

.boton--primario, .panel-boton--primario {
  background: var(--azul);
  border-color: var(--azul);
  color: #fff;
  justify-content: center;
}
.boton--primario:hover, .panel-boton--primario:hover { background: var(--azul-oscuro); }

/* El botón de login ocupa todo el ancho de su tarjeta; los botones
   primarios sueltos (header, dentro de una fila) no deben estirarse. */
.boton--primario { width: 100%; }

.panel-boton--chico { padding: 7px 14px; font-size: .85rem; }

.panel-boton--fantasma {
  border-color: transparent;
  background: transparent;
  padding: 8px 12px;
  font-size: .9rem;
  color: var(--gris);
}
.panel-boton--fantasma:hover { color: var(--azul); border-color: var(--linea); }

.panel-form-casilla { display: inline-flex; margin: 0; }

.aviso {
  border-radius: var(--radio-chico);
  padding: 12px 14px;
  margin-bottom: 16px;
  font-size: .92rem;
}
.aviso--error, .panel-aviso--error { background: var(--error-fondo); color: var(--error); }
.aviso--info, .panel-aviso--info { background: var(--info-fondo); color: var(--info); }
.aviso--ok, .panel-aviso--ok { background: var(--ok-fondo); color: var(--ok); }
.panel-aviso { border-radius: var(--radio-chico); padding: 10px 14px; margin: 0 0 14px; font-size: .9rem; }

.panel-toast {
  position: fixed;
  right: 18px;
  bottom: 18px;
  z-index: 80;
  padding: 12px 18px;
  border-radius: var(--radio-chico);
  box-shadow: var(--sombra);
  font-size: .9rem;
  animation: panel-toast-in .2s ease-out;
}
.panel-toast--ok { background: var(--ok-fondo); color: var(--ok); }
.panel-toast--error { background: var(--error-fondo); color: var(--error); }
@keyframes panel-toast-in { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }

/* ---------------------------------------------------------------------
   1. Login
   ------------------------------------------------------------------- */

.acceso {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
}

.acceso__tarjeta {
  display: grid;
  grid-template-columns: 1fr 1fr;
  max-width: 880px;
  width: 100%;
  background: var(--papel);
  border-radius: 18px;
  box-shadow: var(--sombra);
  overflow: hidden;
}

/* Misma receta visual que el login del portal de residentes: zona de
   logo en blanco arriba, identidad en azul-noche abajo. Con un solo
   logo (Urbanizando — todavía no hay unidad elegida en este punto)
   queda centrado en su propia caja en vez de repartirse con un segundo
   logo, que es lo que portal_usuarios hace cuando sí hay dos. */
.acceso__marca {
  display: grid;
  grid-template-rows: auto 1fr;
  min-height: 0;
  background-color: var(--azul-noche);
  color: #fff;
}

.acceso__logos {
  display: grid;
  place-items: center;
  background: var(--papel);
  border-bottom: 1px solid var(--linea);
  padding: 26px 18px;
}
.acceso__logo {
  margin: 0;
  width: auto;
  max-width: 170px;
  max-height: 84px;
  object-fit: scale-down;
}

.acceso__identidad {
  padding: 40px 34px;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: 16px;
}
.acceso__unidad { margin: 0; font-size: 1.6rem; font-weight: 600; }
.acceso__lema { margin: 0; color: rgba(255, 255, 255, .82); font-size: .92rem; line-height: 1.6; }

.acceso__panel { padding: 40px 34px; }
.acceso__titulo { margin: 0 0 20px; font-size: 1.15rem; }
.acceso__pie { margin-top: 18px; text-align: center; font-size: .85rem; }
.acceso__pie a { color: var(--gris); }
.acceso__pie a:hover { color: var(--azul); }

.campo { display: flex; flex-direction: column; gap: 6px; margin-bottom: 16px; }
.campo__etiqueta { font-size: .85rem; color: var(--gris); font-weight: 500; }
.campo__control {
  border: 1px solid var(--linea);
  border-radius: var(--radio-chico);
  padding: 11px 12px;
  font-size: .95rem;
  width: 100%;
}
.campo__control:focus { outline: 2px solid var(--azul); outline-offset: 1px; }
.campo__grupo { position: relative; display: flex; }
.campo__grupo .campo__control { padding-right: 40px; }
.campo__ojo {
  position: absolute;
  right: 6px;
  top: 50%;
  transform: translateY(-50%);
  border: none;
  background: none;
  padding: 6px;
  cursor: pointer;
  color: var(--gris);
  border-radius: 6px;
}
.campo__ojo:hover { color: var(--azul); }

.campo--casilla { flex-direction: row; align-items: center; gap: 8px; font-size: .9rem; margin-bottom: 20px; }
.campo--casilla input { width: 16px; height: 16px; }

.acceso__mayus {
  display: none;
  margin: -8px 0 14px;
  font-size: .8rem;
  color: var(--error);
}
.acceso__mayus--visible { display: block; }

/* ---------------------------------------------------------------------
   2 y 3. Header común
   ------------------------------------------------------------------- */

.panel-header {
  height: var(--header-alto);
  flex: none;
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 16px;
  padding: 0 18px;
  background: var(--papel);
  border-bottom: 1px solid var(--linea);
  position: sticky;
  top: 0;
  z-index: 20;
}

/* Agrupa hamburguesa (si la hay) + marca en la primera columna del grid,
   para que el buscador de la columna del medio quede centrado de verdad
   sin importar cuánto pese cada lado. */
.panel-header__inicio { display: flex; align-items: center; gap: 12px; min-width: 0; }

.panel-header__hamburguesa {
  display: none;
  border: none;
  background: none;
  padding: 6px;
  cursor: pointer;
  color: var(--tinta);
}

.panel-header__marca { display: flex; flex-direction: column; line-height: 1.2; min-width: 0; }
.panel-header__marca--urbanizando {
  flex-direction: row;
  align-items: center;
  gap: 12px;
}
.panel-header__logo-img { flex: none; border-radius: 6px; width: 36px; height: 36px; object-fit: contain; background: #fff; }
.panel-header__marca--urbanizando .panel-header__logo-texto {
  font-size: 1.15rem;
  font-weight: 600;
  color: var(--azul);
}
.panel-header__marca--unidad { flex-direction: row; align-items: center; gap: 12px; }
.panel-header__marca--unidad .panel-header__logo-img { width: 40px; height: 40px; }
.panel-header__marca-texto { display: flex; flex-direction: column; min-width: 0; }
.panel-header__logo-unidad {
  font-weight: 600;
  font-size: 1rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 34vw;
}
.panel-header__logo-urbanizando {
  font-size: .72rem;
  color: var(--gris);
  letter-spacing: .02em;
}

.panel-header__buscador {
  display: flex;
  align-items: center;
  gap: 8px;
  background: var(--fondo);
  border: 1px solid var(--linea);
  border-radius: 999px;
  padding: 8px 14px;
  width: 100%;
  max-width: 420px;
  /* Vive en la columna central (1fr) del grid del header: centrarla ahí
     adentro es lo que la deja centrada de verdad en toda la barra,
     sin depender de cuánto pesen los lados. */
  margin: 0 auto;
  color: var(--gris);
  /* Sin esto, un ítem de grid no se achica por debajo del min-content de su
     contenido (spec) — el <input> de abajo tiene un ancho mínimo propio del
     navegador (~180-200px) que la columna 1fr terminaba respetando siempre,
     así que en móvil el buscador se salía de su columna y tapaba la de al
     lado (logo/hamburguesa), además del scroll horizontal resultante. */
  min-width: 0;
}
.panel-header__buscador svg { color: var(--gris); flex: none; }
.panel-header__buscador input {
  border: none;
  background: none;
  flex: 1;
  min-width: 0;
  outline: none;
  color: var(--tinta);
}

/* Botón que envuelve el ícono de lupa (antes era un <svg> suelto) — en
   escritorio se ve idéntico al ícono de siempre; en el selector de unidad, en
   móvil, se vuelve el disparador de la búsqueda en pantalla completa (ver
   media query más abajo). El de cerrar solo existe para ese modo. */
.panel-header__buscador-boton {
  display: inline-flex;
  align-items: center;
  border: none;
  background: none;
  padding: 0;
  margin: 0;
  cursor: pointer;
  color: var(--gris);
  flex: none;
}
.panel-header__buscador-cerrar {
  display: none;
  align-items: center;
  border: none;
  background: none;
  padding: 4px;
  margin-left: auto;
  cursor: pointer;
  color: var(--gris);
  flex: none;
}

/* Copia del buscador que vive DENTRO del cajón de menú (móvil, pantalla 4 —
   dentro de una unidad): pedido explícito del usuario, para no competir por
   espacio con el resto del header en pantallas angostas. Oculta en
   escritorio, donde el buscador del header ya cumple esa función. */
.panel-menu__buscador {
  display: none;
  align-items: center;
  gap: 8px;
  margin: 10px 10px 4px;
  padding: 8px 12px;
  background: var(--fondo);
  border: 1px solid var(--linea);
  border-radius: 999px;
  color: var(--gris);
  flex: none;
}
.panel-menu__buscador svg { color: var(--gris); flex: none; }
.panel-menu__buscador input {
  border: none;
  background: none;
  flex: 1;
  min-width: 0;
  outline: none;
  color: var(--tinta);
}

.panel-header__usuario { display: flex; align-items: center; gap: 10px; flex: none; position: relative; }

/* Botón de usuario en píldora (avatar + nombre) y su desplegable — mismo
   patrón que portal_usuarios (usuario__*). */
.usuario__boton {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 5px 9px 5px 5px;
  border: 1px solid transparent;
  border-radius: 999px;
  background: none;
  cursor: pointer;
  color: inherit;
}
.usuario__boton:hover { background: var(--fondo); border-color: var(--linea); }
.usuario__boton:focus-visible { outline: 2px solid var(--azul); outline-offset: 1px; }

/* Botón "Cambiar unidad": vive suelto en el header, a la izquierda del
   usuario, no dentro de su desplegable — es una acción frecuente. */
.panel-header__cambiar-unidad {
  display: flex;
  align-items: center;
  gap: 7px;
  flex: none;
  padding: 8px 14px;
  border: none;
  border-radius: 999px;
  background: var(--azul);
  color: #fff;
  font-size: .82rem;
  font-weight: 500;
  white-space: nowrap;
  cursor: pointer;
}
.panel-header__cambiar-unidad:hover { background: var(--azul-oscuro); }
.panel-header__cambiar-unidad svg { color: #fff; width: 15px; height: 15px; }

/* Botón "Calendario" del header (2026-08-30): mismo lugar que la
   campanita, visible con o sin unidad activa — a diferencia de "Cambiar
   unidad" no es la acción principal de la pantalla, así que va en tono
   neutro (fondo transparente, como usuario__boton) en vez del azul sólido. */
.panel-header__calendario {
  display: flex;
  align-items: center;
  gap: 6px;
  flex: none;
  padding: 8px 12px;
  border: 1px solid transparent;
  border-radius: 999px;
  background: none;
  color: inherit;
  font-size: .82rem;
  font-weight: 500;
  white-space: nowrap;
  cursor: pointer;
}
.panel-header__calendario:hover { background: var(--fondo); border-color: var(--linea); }
.panel-header__calendario svg { width: 17px; height: 17px; }
@media (max-width: 720px) {
  .panel-header__calendario span { display: none; }
  .panel-header__calendario { padding: 8px; }
}

.usuario__avatar {
  width: 34px;
  height: 34px;
  flex: none;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--azul);
  color: #fff;
  font-size: .78rem;
  font-weight: 600;
}

.usuario__texto { display: flex; flex-direction: column; align-items: flex-start; line-height: 1.25; min-width: 0; }
.usuario__nombre { font-weight: 500; font-size: .85rem; white-space: nowrap; }
.usuario__apto { font-size: .74rem; color: var(--gris); }
.usuario__flecha, .usuario__boton svg { width: 15px; height: 15px; color: var(--gris); flex-shrink: 0; }

.usuario__panel {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  min-width: 15rem;
  background: var(--papel);
  border: 1px solid var(--linea);
  border-radius: var(--radio);
  box-shadow: 0 12px 32px rgba(15, 23, 32, .18);
  overflow: hidden;
  z-index: 30;
}
.usuario__cabecera {
  padding: 13px 15px;
  border-bottom: 1px solid var(--linea);
  background: var(--fondo);
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.usuario__cabecera strong { font-size: .87rem; }
.usuario__cabecera span { font-size: .76rem; color: var(--gris); }

.usuario__panel form { margin: 0; }
.usuario__item {
  display: flex;
  align-items: center;
  gap: 11px;
  width: 100%;
  padding: 11px 15px;
  border: 0;
  background: none;
  text-align: left;
  font-size: .87rem;
  color: var(--tinta);
  text-decoration: none;
  cursor: pointer;
}
.usuario__item svg { width: 16px; height: 16px; color: var(--gris); flex: none; }
.usuario__item:hover { background: var(--info-fondo); color: var(--azul); }
.usuario__item--salir { border-top: 1px solid var(--linea); color: var(--error); }
.usuario__item--salir:hover { background: var(--error-fondo); color: var(--error); }
/* Campanita de Notificaciones (Módulo C, Fase 1) — mismo lenguaje visual
   que el desplegable de usuario (usuario__panel/usuario__item) de arriba,
   con su propio botón redondo (sin texto, a diferencia de usuario__boton
   que sí lleva nombre). */
.panel-notif { position: relative; flex: none; }
.panel-notif__boton {
  position: relative;
  display: grid;
  place-items: center;
  width: 38px;
  height: 38px;
  border: 1px solid transparent;
  border-radius: 50%;
  background: none;
  color: inherit;
  cursor: pointer;
}
.panel-notif__boton:hover { background: var(--fondo); border-color: var(--linea); }
.panel-notif__boton:focus-visible { outline: 2px solid var(--azul); outline-offset: 1px; }
.panel-notif__boton svg { width: 19px; height: 19px; }
.panel-notif__contador {
  position: absolute;
  top: 2px;
  right: 2px;
  min-width: 16px;
  height: 16px;
  padding: 0 3px;
  border-radius: 999px;
  background: var(--error);
  color: #fff;
  font-size: .64rem;
  font-weight: 700;
  line-height: 16px;
  text-align: center;
}
.panel-notif__desplegable {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  width: 22rem;
  max-width: calc(100vw - 24px);
  background: var(--papel);
  border: 1px solid var(--linea);
  border-radius: var(--radio);
  box-shadow: 0 12px 32px rgba(15, 23, 32, .18);
  overflow: hidden;
  z-index: 30;
}
.panel-notif__cabecera {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 15px;
  border-bottom: 1px solid var(--linea);
  background: var(--fondo);
}
.panel-notif__cabecera strong { font-size: .87rem; }
.panel-notif__lista { max-height: 22rem; overflow-y: auto; }
.panel-notif__vacio { padding: 20px 15px; text-align: center; color: var(--gris); font-size: .85rem; }
.panel-notif__item { padding: 11px 15px; border-bottom: 1px solid var(--linea); font-size: .85rem; }
.panel-notif__item:last-child { border-bottom: none; }
.panel-notif__item--pendiente { background: var(--info-fondo); }
.panel-notif__item-cuerpo--clicable { cursor: pointer; margin: -11px -15px; padding: 11px 15px; }
.panel-notif__item-cuerpo--clicable:hover { background: var(--fondo); }
.panel-notif__item-cuerpo strong { display: block; font-size: .87rem; }
.panel-notif__item-cuerpo p { margin: 3px 0 0; color: var(--tinta); }
.panel-notif__item-cuerpo time { display: block; margin-top: 4px; font-size: .74rem; color: var(--gris); }
.panel-notif__unidad {
  display: inline-block;
  margin: 2px 0 0;
  padding: 1px 7px;
  border-radius: 999px;
  background: var(--azul);
  color: #fff;
  font-size: .68rem;
}
.panel-notif__item-acciones { display: flex; gap: 14px; margin-top: 7px; }

/* Calendario (Gestión administrativa Fase 5 / Notificaciones Fase 4). */
.panel-cal-nav { display: flex; gap: 10px; margin: 12px 0; }
.panel-cal-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 1px;
  background: var(--linea);
  border: 1px solid var(--linea);
  border-radius: var(--radio);
  overflow: hidden;
}
.panel-cal-grid__encabezado {
  padding: 8px 6px;
  background: var(--fondo);
  text-align: center;
  font-size: .78rem;
  font-weight: 600;
  color: var(--gris);
}
.panel-cal-dia {
  min-height: 6.5rem;
  padding: 6px;
  background: var(--papel);
  cursor: pointer;
  display: flex;
  flex-direction: column;
  gap: 3px;
}
.panel-cal-dia:hover { background: var(--fondo); }
.panel-cal-dia--fuera { background: var(--fondo); opacity: .5; }
.panel-cal-dia--fuera:hover { opacity: .8; }
.panel-cal-dia--hoy { box-shadow: inset 0 0 0 2px var(--azul); }
.panel-cal-dia__numero { font-size: .82rem; font-weight: 600; color: var(--tinta); }
.panel-cal-evento {
  display: block;
  width: 100%;
  border: none;
  border-radius: 4px;
  padding: 2px 5px;
  color: #fff;
  font-size: .72rem;
  text-align: left;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  cursor: pointer;
}

@media (max-width: 720px) {
  .panel-cal-dia { min-height: 4rem; }
  .panel-cal-grid__encabezado { font-size: .68rem; }
}

/* Visibilidad del evento (2026-08-30): radios "Solo yo / Equipo / Elegir
   usuarios" + lista de invitados externos por correo. */
.panel-cal-visibilidad {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 18px;
  margin: 0;
  padding: 10px 12px;
  border: 1px solid var(--linea);
  border-radius: var(--radio);
}
.panel-cal-visibilidad legend { padding: 0 6px; font-size: .8rem; font-weight: 600; color: var(--gris); }
.panel-cal-visibilidad .panel-campo--casilla-inline { margin: 0; }
[data-cal-lista-usuarios] { margin-top: 8px; }
[data-cal-usuarios-checks] { display: flex; flex-direction: column; gap: 4px; max-height: 9rem; overflow-y: auto; }
.panel-cal-invitados { border-top: 1px dashed var(--linea); padding-top: 10px; }
.panel-cal-invitado-fila {
  display: flex;
  gap: 8px;
  align-items: flex-end;
  margin-bottom: 10px;
}
.panel-cal-invitado-fila .panel-campo { flex: 1 1 0; min-width: 0; }
.panel-cal-invitado-fila .panel-enlace--peligro { flex: none; padding-bottom: 10px; white-space: nowrap; }

.panel-avatar {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: var(--azul);
  color: #fff;
  display: grid;
  place-items: center;
  font-size: .78rem;
  font-weight: 600;
  flex: none;
}
.panel-header__nombre { font-size: .88rem; font-weight: 500; }

/* ---------------------------------------------------------------------
   2. Selector de unidad
   ------------------------------------------------------------------- */

/* flex:1 + overflow-y:auto: .panel-body es height:100dvh + overflow:hidden
   (el header queda fijo), así que este <main> necesita su PROPIO scroll para
   la lista completa — sin esto, con más unidades de las que caben en una
   pantalla, las de más abajo quedaban recortadas en silencio (overflow:hidden
   del padre) en vez de alcanzables con scroll. El ancho máximo/centrado se
   mueve a .panel-selector__interior: si el max-width vive en el CONTENEDOR
   con scroll, la barra de scroll del navegador se pinta en el borde derecho
   de esa columna angosta (a mitad de pantalla en un monitor ancho) en vez del
   borde real del viewport — feo y poco intuitivo. */
.panel-selector { width: 100%; flex: 1; min-height: 0; overflow-y: auto; }
.panel-selector__interior { max-width: 900px; margin: 0 auto; padding: 40px 24px; width: 100%; box-sizing: border-box; }
.panel-selector h1 { margin: 0 0 6px; font-size: 1.4rem; }
.panel-selector__ayuda { margin: 0 0 26px; color: var(--gris); }
.panel-selector__vacio { color: var(--gris); text-align: center; padding: 30px 0; }

.panel-lista-unidades {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 14px;
}

.panel-tarjeta-unidad {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 18px 16px;
  background: var(--papel);
  border: 1px solid var(--linea);
  border-radius: var(--radio);
  cursor: pointer;
  text-align: left;
  font-weight: 500;
  transition: box-shadow .15s, border-color .15s;
}
.panel-tarjeta-unidad:hover { box-shadow: var(--sombra); border-color: var(--azul); }
.panel-tarjeta-unidad svg { color: var(--azul); }
.panel-tarjeta-unidad__logo {
  width: 36px;
  height: 36px;
  flex: none;
  object-fit: contain;
  border-radius: 6px;
  background: #fff;
}
.panel-tarjeta-unidad__icono-respaldo { flex: none; display: flex; }

/* ---------------------------------------------------------------------
   3. Shell (menú + pestañas)
   ------------------------------------------------------------------- */

.panel-cuerpo { flex: 1; display: flex; min-height: 0; }

.panel-menu {
  width: var(--menu-ancho);
  flex: none;
  display: flex;
  flex-direction: column;
  background: var(--papel);
  border-right: 1px solid var(--linea);
  transition: width .15s ease;
}

.panel-menu__cabecera { display: flex; justify-content: flex-end; flex: none; padding: 10px 10px 0; }

.panel-menu__colapsar {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  flex: none;
  border: none;
  background: none;
  border-radius: var(--radio-chico);
  cursor: pointer;
  color: var(--gris);
}
.panel-menu__colapsar:hover { background: var(--fondo); color: var(--tinta); }
.panel-menu__colapsar svg { width: 17px; height: 17px; }

.panel-menu__lista { flex: 1; overflow-y: auto; padding: 10px 10px 14px; }

.menu-item {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  border: none;
  background: none;
  text-align: left;
  padding: 10px 12px;
  border-radius: var(--radio-chico);
  cursor: pointer;
  font-size: .92rem;
  color: var(--tinta);
}
.menu-item:hover { background: var(--fondo); }
.menu-item.is-activa { background: var(--info-fondo); color: var(--azul); font-weight: 600; }
.menu-item svg { color: var(--gris); flex: none; }
.menu-item.is-activa svg { color: var(--azul); }
.menu-item--hijo { padding-left: 30px; }
.menu-item.is-oculto { display: none; }

/* "Propietarios" y "Movimientos" son hojas (sin submenú) pero pesan como
   los ítems padre del menú — mismo tratamiento visual que .menu-grupo
   summary (pedido explícito), aunque estructuralmente siguen siendo un
   .menu-item normal (un solo clic, sin desplegar nada). Se apunta por
   data-clave a propósito en vez de un color genérico para "hoja de primer
   nivel": "Inicio" es igual de hoja de primer nivel y debe seguir viéndose
   como un ítem común. "Movimientos" se sumó acá 2026-08 (antes tenía el
   mismo tono con un truco distinto: una carpeta padre vacía por encima —
   ver CLAUDE.md — antes de que se cambiara por una hoja directa como
   Propietarios; se quedó sin este estilo hasta ahora). */
.menu-item[data-clave="propietarios"], .menu-item[data-clave="movimientos"] { font-weight: 600; color: var(--azul); background: var(--fondo); margin: 6px 0; } /* mismo aire vertical que .menu-grupo */
.menu-item[data-clave="propietarios"] svg, .menu-item[data-clave="movimientos"] svg { color: var(--azul); }
.menu-item[data-clave="propietarios"].is-activa, .menu-item[data-clave="movimientos"].is-activa { background: var(--info-fondo); }

.menu-grupo { margin: 6px 0; }

.menu-grupo summary {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  cursor: pointer;
  font-size: .92rem;
  font-weight: 600;
  color: var(--azul);
  background: var(--fondo);
  border-radius: var(--radio-chico);
  list-style: none;
}
.menu-grupo summary::-webkit-details-marker { display: none; }
.menu-grupo summary:hover { background: var(--linea); }
.menu-grupo.is-oculto { display: none; }
/* Carpeta dentro de otra carpeta (2026-09, urb_menu_lista_html() ya
   recursiva — ver CLAUDE.md §2.16b): sangría extra para que se note la
   jerarquía, ya que .menu-item--hijo por sí solo no distingue niveles. */
.menu-grupo .menu-grupo { margin-left: 12px; }
.menu-grupo .menu-grupo .menu-item--hijo { padding-left: 42px; }

.menu-grupo__flecha { display: flex; margin-left: auto; color: var(--gris); flex: none; transition: transform .15s ease; }
.menu-grupo__flecha svg { width: 15px; height: 15px; }
.menu-grupo[open] > summary .menu-grupo__flecha { transform: rotate(180deg); }

/* División "Menú Sistema" / "Menú Unidad" (2026-09) — solo se pinta si el
   usuario tiene permiso sobre al menos una de las 3 carpetas centrales
   (Seguridad/Configuración global/API Urban, ver urb_menu_claves_sistema()).
   "Menú Sistema" es un <details> más (se puede esconder, como cualquier
   .menu-grupo); "Menú Unidad" es un simple rótulo fijo — pedido explícito
   del usuario: la sección de la unidad activa NUNCA se colapsa. */
.menu-seccion { margin: 8px 0 6px; }
.menu-seccion.is-oculto { display: none; }
.menu-seccion__resumen {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 12px;
  cursor: pointer;
  list-style: none;
  font-size: .72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .05em;
  color: var(--gris);
}
.menu-seccion__resumen::-webkit-details-marker { display: none; }
.menu-seccion__resumen:hover { color: var(--tinta); }
.menu-seccion__flecha { display: flex; margin-left: auto; flex: none; transition: transform .15s ease; }
.menu-seccion__flecha svg { width: 13px; height: 13px; }
.menu-seccion[open] > .menu-seccion__resumen .menu-seccion__flecha { transform: rotate(180deg); }
.menu-seccion__cuerpo { display: flex; flex-direction: column; gap: 2px; }

.menu-seccion-unidad.is-oculto { display: none; }
.menu-seccion__divisor {
  margin: 12px 12px 6px;
  padding-bottom: 6px;
  border-bottom: 1px solid var(--linea);
  font-size: .72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .05em;
  color: var(--gris);
}

/* Menú contraído (botón "colapsar" del encabezado): solo quedan los
   iconos de las opciones de primer nivel; los hijos de un grupo y todo
   el texto se ocultan hasta volver a expandir. La división Sistema/Unidad
   tampoco tiene sentido en modo solo-iconos — el rótulo/resumen se esconde
   y el cuerpo de "Menú Sistema" queda SIEMPRE visible sin importar si el
   usuario lo había cerrado (un <details> cerrado escondería sus iconos). */
.panel-menu--colapsado { width: var(--menu-ancho-colapsado); }
.panel-menu--colapsado .panel-menu__cabecera { justify-content: center; padding: 10px 0 0; }
.panel-menu--colapsado .panel-menu__lista { padding: 10px 6px 14px; }
.panel-menu--colapsado .menu-item,
.panel-menu--colapsado .menu-grupo summary { justify-content: center; gap: 0; padding: 10px; }
.panel-menu--colapsado .menu-item span,
.panel-menu--colapsado .menu-grupo summary span,
.panel-menu--colapsado .menu-grupo__flecha { display: none; }
.panel-menu--colapsado .menu-grupo .menu-item--hijo { display: none; }
.panel-menu--colapsado .menu-grupo summary { cursor: default; }
.panel-menu--colapsado .menu-seccion__resumen,
.panel-menu--colapsado .menu-seccion__divisor { display: none; }
.panel-menu--colapsado .menu-seccion { margin: 0; }
.panel-menu--colapsado .menu-seccion__cuerpo { display: flex; flex-direction: column; }

.panel-menu-fondo { display: none; }

/* ---------------------------------------------------------------------
   Pestañas
   ------------------------------------------------------------------- */

/* min-height: 0 es necesario aquí: sin él, un flex item en columna se
   estira para caber su contenido (min-height:auto por defecto) en vez de
   respetar la altura que le da .panel-cuerpo, y su hijo .panel-tabs__contenido
   nunca llega a necesitar scroll propio porque nunca se queda sin espacio. */
.panel-tabs { flex: 1; display: flex; flex-direction: column; min-width: 0; min-height: 0; }

.panel-tabs__barra {
  display: flex;
  align-items: stretch;
  gap: 2px;
  background: var(--papel);
  border-bottom: 1px solid var(--linea);
  overflow-x: auto;
  scrollbar-width: thin;
  flex: none;
}

.tab-chip {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 10px 10px 16px;
  border: none;
  border-bottom: 2px solid transparent;
  background: none;
  white-space: nowrap;
  cursor: pointer;
  font-size: .88rem;
  color: var(--gris);
  flex: none;
}
.tab-chip:hover { color: var(--tinta); background: var(--fondo); }
.tab-chip.is-activa { color: var(--azul); border-bottom-color: var(--azul); font-weight: 600; background: var(--info-fondo); }

.tab-chip__cerrar {
  border: none;
  background: none;
  color: inherit;
  opacity: .6;
  padding: 3px;
  border-radius: 4px;
  cursor: pointer;
  display: grid;
  place-items: center;
}
.tab-chip__cerrar:hover { opacity: 1; background: rgba(0,0,0,.08); }
.tab-chip__cerrar svg { width: 13px; height: 13px; }

.panel-tabs__contenido { flex: 1; overflow: auto; position: relative; }

.tab-panel { display: none; padding: 24px; }
.tab-panel.is-activa { display: block; }

.tab-panel--error {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 10px;
  color: var(--error);
}

/* Pantalla de carga de una pestaña: mismo spinner circular que ya se usaba
   al entrar a crm_emails, para que la espera se sienta igual en todo el
   sitio. CSS puro (sin gif ni dependencias) — ver tabs.js:crearPanel()/
   cargarContenido(), únicos dos lugares que pintan este marcado. */
.tab-panel--cargando {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 16px;
  min-height: 220px;
  color: var(--gris);
  text-align: center;
}
.tab-panel--cargando__spinner {
  width: 42px;
  height: 42px;
  border: 4px solid var(--info-fondo);
  border-top-color: var(--azul);
  border-radius: 50%;
  animation: tab-panel-girar .8s linear infinite;
}
.tab-panel--cargando__texto { font-size: .88rem; }

@keyframes tab-panel-girar { to { transform: rotate(360deg); } }

/* Respeta a quien pidió menos animación en su sistema operativo. */
@media (prefers-reduced-motion: reduce) {
  .tab-panel--cargando__spinner { animation-duration: 2.5s; }
}

/* Secciones de CRM Emails embebidas por <iframe> (ver lib/crm_emails.php:
   urb_crm_emails_marco()). El spinner de carga queda encima del iframe
   hasta su onload, en vez de ocupar el panel completo. */
.panel-marco-envoltorio { position: relative; min-height: 70vh; }
/* Pestaña con un módulo incrustado (CRM Emails): el marco usa toda la vista y no dibuja otra tarjeta alrededor de la
   página de adentro (antes se veía una pantalla metida dentro de otra). */
.panel-marco {
  display: block;
  width: 100%;
  height: calc(100vh - 150px);
  min-height: 520px;
  border: none;
  border-radius: 0;
  background: transparent;
}
/* Dentro de un modal sí lleva su marco y una altura propia. */
.panel-dialog .panel-marco { height: 70vh; border: 1px solid var(--linea); border-radius: var(--radio); background: var(--papel); }
.panel-marco-envoltorio .tab-panel--cargando {
  position: absolute;
  inset: 0;
  min-height: 0;
  background: var(--papel);
  border: 1px solid var(--linea);
  border-radius: var(--radio);
  z-index: 1;
}
.tab-panel--vacio {
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--gris);
  font-size: .92rem;
}
/* Selector de unidad reusado como "pantalla de inicio" del menú global (ver
   tabs.js) — necesita ocupar y desplazarse por su cuenta (.panel-selector ya
   trae flex:1 + overflow-y:auto), no quedar centrado como el texto de
   respaldo genérico. */
.tab-panel--vacio:has(.panel-selector) {
  display: block;
  height: 100%;
  overflow: hidden;
}
.tab-panel--vacio:has(.panel-selector) .panel-selector { height: 100%; }

/* ---------------------------------------------------------------------
   Contenido de los fragmentos (vistas/*.php)
   ------------------------------------------------------------------- */

.panel-frag h2 { margin: 0 0 8px; font-size: 1.25rem; }
.panel-frag h3 { margin: 26px 0 10px; font-size: 1rem; }
.panel-frag__lead { color: var(--gris); max-width: none; }
.panel-frag--angosto { max-width: 480px; margin: 0 auto; }
.panel-frag--angosto h2 { text-align: center; }

.panel-cards { display: flex; gap: 14px; flex-wrap: wrap; margin-top: 18px; }
.panel-card {
  background: var(--papel);
  border: 1px solid var(--linea);
  border-radius: var(--radio);
  padding: 16px 18px;
  min-width: 180px;
}
.panel-card h3 { margin: 0 0 8px; display: flex; align-items: center; gap: 8px; font-size: .85rem; color: var(--gris); }
.panel-card p { margin: 0; font-weight: 600; }

/* overflow-x: auto por sí solo NO basta para un encabezado "sticky": el
   navegador igual convierte overflow-y en "auto" (nunca se queda en
   "visible" cuando el otro eje no lo es), así que .panel-tabla-envoltorio
   YA era, sin querer, el contenedor con scroll más cercano al <th> — pero
   como antes no tenía una altura acotada, ese scroll nunca se activaba
   dentro de él (scrolleaba .panel-tabs__contenido, uno más arriba), y el
   sticky no tenía dónde "pegarse". Con max-height + overflow-y:auto
   explícitos, la tabla scrollea DENTRO de su propio recuadro y el
   encabezado se pega ahí, sin depender de ningún ancestro más arriba. */
.panel-tabla-envoltorio {
  overflow: auto;
  max-height: 65vh;
  border: 1px solid var(--linea);
  border-radius: var(--radio);
}
/* border-collapse: separate (no collapse) + spacing 0: con collapse,
   position:sticky en <th> es poco confiable entre navegadores. Como todos
   los bordes de esta tabla son horizontales (border-bottom, sin bordes
   verticales), separate + spacing:0 se ve idéntico a collapse — cero
   diferencia visual, un modo de fallo menos. */
.panel-tabla { width: 100%; border-collapse: separate; border-spacing: 0; font-size: .88rem; background: var(--papel); }
.panel-tabla th, .panel-tabla td { padding: 10px 12px; text-align: left; border-bottom: 1px solid var(--linea); }
.panel-tabla th {
  color: var(--gris); font-weight: 600; font-size: .78rem; text-transform: uppercase; letter-spacing: .03em;
  /* Encabezado siempre visible al hacer scroll: la tabla ahora scrollea
     DENTRO de su propio .panel-tabla-envoltorio (ver esa regla, más
     arriba), que es el contenedor exacto al que este sticky se pega. */
  position: sticky;
  top: 0;
  background: var(--papel);
  z-index: 1;
}
.panel-tabla tr:last-child td { border-bottom: none; }
.panel-tabla--compacta th, .panel-tabla--compacta td { padding: 7px 10px; text-align: center; }
.panel-tabla--compacta td:first-child, .panel-tabla--compacta th:first-child { text-align: left; }

/* Encabezados ordenables (window.urbTablaOrdenar): flechita que aparece
   tenue siempre y se marca en la columna por la que se está ordenando. */
.panel-tabla th[data-ordenable] { cursor: pointer; user-select: none; white-space: nowrap; }
.panel-tabla th[data-ordenable]:hover { color: var(--tinta); }
.panel-tabla th[data-ordenable]::after { content: '\2195'; margin-left: 5px; opacity: .35; font-size: .95em; }
.panel-tabla th[data-ordenable][data-orden="asc"]::after { content: '\2191'; opacity: 1; color: var(--azul); }
.panel-tabla th[data-ordenable][data-orden="desc"]::after { content: '\2193'; opacity: 1; color: var(--azul); }

.panel-grupos-usuario { display: flex; flex-wrap: wrap; gap: 4px; }

.panel-chip {
  border: 1px solid var(--linea);
  background: var(--fondo);
  color: var(--gris);
  border-radius: 999px;
  padding: 4px 10px;
  font-size: .76rem;
  cursor: pointer;
}
.panel-chip--on { background: var(--info-fondo); border-color: var(--azul); color: var(--azul); font-weight: 600; }

.panel-check {
  width: 26px;
  height: 26px;
  border-radius: 6px;
  border: 1px solid var(--linea);
  background: var(--papel);
  cursor: pointer;
  color: var(--azul);
  font-weight: 700;
}
.panel-check--on { background: var(--info-fondo); border-color: var(--azul); }

/* Checkbox "marcar todo" arriba de cada columna de la matriz de permisos. */
.panel-check-cabecera {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  cursor: pointer;
  text-transform: none;
  letter-spacing: normal;
}
.panel-check-cabecera input { width: 15px; height: 15px; cursor: pointer; accent-color: var(--azul); }

.panel-permiso-grupo { margin-bottom: 22px; }
.panel-permiso-grupo h4 { margin: 0 0 8px; font-size: .9rem; }

.panel-form {
  display: flex;
  flex-direction: column;
  gap: 14px;
  max-width: 420px;
  margin: 14px auto 0;
  background: var(--papel);
  border: 1px solid var(--linea);
  border-radius: var(--radio);
  box-shadow: var(--sombra);
  padding: 24px;
}
/* El botón de guardar/crear es la ACCIÓN, no un campo más — pedido
   explícito del usuario (2026-09, auditoría de formularios): sin este
   margen extra queda pegado al último campo con el mismo gap que separa
   dos campos cualquiera, y se pierde esa distinción visual. Antes solo
   vivía en .panel-wizard__contenido; generalizado acá a TODO .panel-form
   (plano, --2col, dentro o fuera de un <dialog>). Si el botón fuera el
   PRIMER hijo (caso raro, un formulario que abre con la acción arriba),
   el margen se voltea hacia abajo en vez de hacia arriba. */
.panel-form > button[type="submit"] { width: 100%; margin-top: 15px; }
.panel-form > button[type="submit"]:first-child { margin-top: 0; margin-bottom: 15px; }
/* Dentro de un <details> (alta/edición inline en tablas) o de un <dialog>
   el marco ya lo pone el contenedor: el form no necesita su propia
   tarjeta encima de otra tarjeta. */
.panel-expandible > .panel-form,
dialog .panel-form,
.panel-form--plano {
  margin: 0;
  border: none;
  box-shadow: none;
  padding: 0;
  max-width: none;
}
.panel-campo { display: flex; flex-direction: column; gap: 6px; font-size: .85rem; color: var(--gris); }
.panel-campo input, .panel-campo select, .panel-campo textarea {
  border: 1px solid var(--linea);
  border-radius: var(--radio-chico);
  padding: 10px 12px;
  font-size: .95rem;
  color: var(--tinta);
  background: var(--papel);
  width: 100%;
  box-sizing: border-box;
}
/* Error de validación EN VIVO junto al campo (window.urbCampoError en
   panel.js) — no esperar al toast de después de "Guardar". El borde rojo
   en el input mismo (:has) es una ayuda visual extra; el mensaje de abajo
   es lo que de verdad comunica el motivo. */
.panel-campo-error { color: var(--error); font-size: .8rem; }
.panel-campo-aviso { color: #92400e; background: #fef3c7; border-radius: 6px; padding: 4px 8px; font-size: .8rem; }
.panel-campo:has(.panel-campo-error) input,
.panel-campo:has(.panel-campo-error) select {
  border-color: var(--error);
}
.panel-campo select {
  /* El navegador dibuja su propia flecha muy pegada al borde si no se le
     da aire; con el padding normal de arriba se ve consistente con los
     input de texto. */
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2364748b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 10px center;
  background-size: 16px;
  padding-right: 32px;
}
.panel-campo input:focus, .panel-campo select:focus, .panel-campo textarea:focus {
  outline: 2px solid var(--azul);
  outline-offset: 1px;
}
/* Campo con sufijo fijo no editable (ej. "<algo>.urbanizando.com.co") — el
   borde/radio/foco vive en el envoltorio, no en el <input>, para que el
   sufijo se vea pegado como si fuera parte del mismo campo. Reusa
   .panel-campo-error/:has(...) de arriba tal cual (el <small> sigue siendo
   hijo directo de .panel-campo). */
.panel-campo-sufijo {
  display: flex;
  align-items: stretch;
  border: 1px solid var(--linea);
  border-radius: var(--radio-chico);
  background: var(--papel);
  overflow: hidden;
}
.panel-campo-sufijo:focus-within { outline: 2px solid var(--azul); outline-offset: 1px; }
.panel-campo:has(.panel-campo-error) .panel-campo-sufijo { border-color: var(--error); }
.panel-campo-sufijo input {
  border: none !important;
  border-radius: 0 !important;
  flex: 1;
  min-width: 0;
}
.panel-campo-sufijo input:focus { outline: none !important; }
.panel-campo-sufijo span {
  padding: 10px 12px 10px 0;
  color: var(--gris);
  white-space: nowrap;
  font-size: .95rem;
  align-self: center;
}

.panel-campo--casilla-inline {
  flex-direction: row;
  align-items: center;
  gap: 8px;
}
.panel-campo--casilla-inline input { width: auto; flex: none; }

/* Fase 5 (2026-08-23, corregido tras 2ª revisión del usuario): fila del
   checklist "a qué servicios aplicar" de Aplicar pago/NC. El campo de valor
   va PEGADO al texto del servicio (el span NO crece — sin flex:1 el input
   queda justo a su derecha, no flotando al borde del diálogo), angosto (ch
   = ancho de un dígito) y bajo (padding propio, más chico que el de un
   campo de formulario normal — la 1ª versión heredaba el padding de
   `.panel-campo input`, que se veía "muy alto" para una fila de checklist).
   Cada fila lleva su propio margen inferior para no verse apeñuscada. */
.panel-mov-doc-fila { width: 100%; margin-bottom: 8px; }
.panel-mov-doc-fila:last-child { margin-bottom: 0; }
.panel-mov-doc-valor-inline {
  width: 11ch !important;
  flex: 0 0 auto;
  padding: 4px 8px !important;
  font-size: .85rem !important;
}

.panel-datos {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 10px 18px;
  margin: 14px 0 24px;
  background: var(--papel);
  border: 1px solid var(--linea);
  border-radius: var(--radio);
  box-shadow: var(--sombra);
  padding: 20px 24px;
}
.panel-datos dt { color: var(--gris); font-size: .85rem; }
.panel-datos dd { margin: 0; font-weight: 500; }
/* Dentro de un <dialog> el marco ya lo pone el modal: no hace falta una
   tarjeta encima de otra (mismo criterio que .panel-form ahí adentro). */
dialog .panel-datos {
  background: none;
  border: none;
  box-shadow: none;
  padding: 0;
  margin: 0 0 16px;
}

/* ---------------------------------------------------------------------
   Hito 3: cabecera de fragmento, modales <dialog>, exportar
   ------------------------------------------------------------------- */

.panel-frag__cabecera {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 12px;
  margin-bottom: 8px;
}
.panel-frag__cabecera h2, .panel-frag__cabecera h3 { margin: 0; }
.panel-frag__acciones { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }

.panel-exportar { display: flex; align-items: center; gap: 8px; font-size: .82rem; color: var(--gris); }
.panel-exportar a {
  color: var(--azul);
  text-decoration: none;
  border: 1px solid var(--linea);
  border-radius: 6px;
  padding: 4px 9px;
}
.panel-exportar a:hover { border-color: var(--azul); background: var(--info-fondo); }

/* Exportar de Movimientos (modo 'select', ver lib/exportar.php) — pedido
   explícito del usuario (2026-08-23): flota a la derecha, etiqueta y
   `<select>` en la misma línea (no apilados como un `.panel-campo` normal),
   más bajo que un campo de formulario común, con aire antes de la tabla de
   abajo. */
.panel-exportar--select { justify-content: flex-end; margin: 4px 0 16px; }
.panel-exportar--select .panel-campo {
  flex-direction: row;
  align-items: center;
  gap: 8px;
  width: auto;
}
.panel-exportar--select select {
  width: auto;
  padding: 5px 28px 5px 10px;
  font-size: .82rem;
}

/* Enlaces de exportar sin permiso: siguen ahí (para que quede claro que la
   acción existe), pero no se pueden usar y explican por qué al pasar el
   mouse — mismo criterio que los botones deshabilitados de abajo. */
.panel-exportar a[aria-disabled="true"] {
  color: var(--gris);
  opacity: .55;
  cursor: not-allowed;
  pointer-events: none;
}

/* Controles deshabilitados por falta de permiso (Editar/Eliminar/Exportar/
   etc.): se quedan visibles en vez de desaparecer, para que quede claro que
   la acción existe pero no está permitida — el title explica por qué. */
.panel-enlace:disabled,
.panel-boton:disabled,
.panel-chip:disabled,
.panel-check:disabled {
  opacity: .45;
  cursor: not-allowed;
}
.panel-enlace:disabled:hover { text-decoration: none; }

/* <dialog> nativo: el navegador ya centra y bloquea el scroll de fondo.
   Solo se le da la piel visual — tarjeta blanca, bordes, sombra — y un
   fondo (::backdrop) consistente con el resto del panel. */
.panel-dialog {
  border: none;
  border-radius: var(--radio);
  box-shadow: 0 12px 40px rgba(15, 23, 32, .25);
  padding: 24px;
  width: min(520px, calc(100vw - 48px));
  max-height: min(680px, calc(100vh - 64px));
  overflow-y: auto;
  /* Corrección 2026-08-29: `overflow-y: auto` sin un overflow-x explícito
     hace que el navegador calcule overflow-x como `auto` también (regla del
     spec: si un eje no es "visible", el otro deja de serlo). Un texto largo
     sin cortes (ej. el detalle de una nota de gestión) entonces empujaba el
     diálogo a lo ancho y el scroll horizontal resultante arrastraba consigo
     la cabecera con el título (cabecera y contenido comparten el mismo
     contenedor con scroll) — "se esconde el título" al desplazar. Cualquier
     contenido ancho de verdad (tablas) ya trae su propio scroll horizontal
     interno vía .panel-tabla-envoltorio, así que el diálogo en sí nunca
     necesita desplazarse de lado. */
  overflow-x: hidden;
  /* Varios <dialog> del panel viven, en el DOM, dentro de un <td> (ej.
     .panel-celda-acciones, que fija white-space:nowrap para que los
     botones de una fila no salten de línea) — mostrar el diálogo con
     showModal() lo saca visualmente de la tabla (top layer), pero NO lo
     saca del árbol para la herencia de CSS: `white-space` se sigue
     heredando del <td> real y cortaba/desbordaba cualquier texto largo
     adentro. El diálogo resetea la herencia acá, una sola vez. */
  white-space: normal;
}
.panel-dialog::backdrop { background: rgba(15, 23, 32, .45); }
.panel-dialog--ancho { width: min(900px, calc(100vw - 48px)); max-height: min(760px, calc(100vh - 64px)); }
/* Formulario de 2 columnas dentro de un modal (CLAUDE.md §2.18: 6 campos o más → más ancho y repartido). */
.panel-dialog--form { width: min(720px, calc(100vw - 48px)); }

/* Modales de Movimientos (2026-09, pedido del usuario): más grandes para que
   quepa el contenido sin apretarse, con aire entre bloques (mismo criterio
   de CLAUDE.md §2.18: nada pegado al borde del <dialog>) y los botones del
   pie SIEMPRE uno al lado del otro. `--mov-grande` = detalle/pasos con
   tablas; `--mov-medio` = confirmaciones y anulaciones. Van después de
   `--ancho` a propósito: misma especificidad, gana la última. */
.panel-dialog--mov-grande { width: min(1180px, calc(100vw - 48px)); max-height: min(920px, calc(100vh - 48px)); min-height: min(640px, calc(100vh - 48px)); }
.panel-dialog--mov-medio { width: min(760px, calc(100vw - 48px)); max-height: min(860px, calc(100vh - 48px)); }
.panel-dialog--mov-grande,
.panel-dialog--mov-medio { padding: 28px 32px; }
.panel-dialog--mov-grande .panel-dialog__cabecera,
.panel-dialog--mov-medio .panel-dialog__cabecera { margin-bottom: 18px; }
.panel-dialog--mov-medio > div > p,
.panel-dialog--mov-grande > div > p { margin: 0 0 16px; line-height: 1.5; }
.panel-dialog--mov-medio .panel-tabla-envoltorio,
.panel-dialog--mov-grande .panel-tabla-envoltorio { margin: 8px 0 16px; }
#form-mov-doc-anular,
#form-mov-ajuste-anular { display: flex; flex-direction: column; gap: 16px; }
/* Fieldset "¿De dónde se toman los saldos...?" (Cuentas de cobro): el radio
   va arriba a la izquierda del bloque, no centrado con solo la primera línea
   del texto — pedido explícito del usuario tras verlo centrado y separado. */
[data-mov-cc-modo] label {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  margin: 10px 0;
  cursor: pointer;
}
/* El fieldset es `.panel-campo` (para heredar su tipografía/color), pero esa
   clase da `width:100%` + borde + padding a TODO input/select adentro — en
   un radio eso dibuja una caja enorme con el punto perdido en el centro en
   vez de un círculo pequeño (bug real, reportado por el usuario). Se resetea
   solo acá, sin tocar `.panel-campo input` en general. */
[data-mov-cc-modo] label input[type="radio"] {
  width: auto;
  height: auto;
  padding: 0;
  border: none;
  border-radius: 0;
  background: none;
  margin: 3px 0 0;
  flex-shrink: 0;
}
[data-mov-cc-modo] label span {
  flex: 1;
  min-width: 0;
}
[data-mov-cc-modo] label small {
  display: block;
  margin-top: 2px;
}

.panel-dialog .panel-asignar-card__pie {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  gap: 12px;
  padding: 18px 0 0;
  margin-top: 6px;
}
.panel-dialog .panel-asignar-card__pie .panel-boton { min-width: 150px; }

/* Modal "grande" (window.urbFragmentoModalAbrir(), panel.js) — incrusta una
   pantalla REAL del panel (tab.php?clave=X) dentro de un modal, para el
   checklist de "Configuración mínima" de Crear nueva unidad (2026-09): la
   pantalla necesita casi todo el ancho/alto disponible, a diferencia de un
   formulario chico de .panel-dialog normal. */
.panel-dialog--grande {
  width: min(1200px, calc(100vw - 48px));
  height: min(820px, calc(100vh - var(--header-alto) - 48px));
  /* Solo margin-top fijo (el resto sigue "auto", que es lo que ya centra
     horizontalmente por defecto un <dialog> mostrado con showModal()) —
     así el borde superior SIEMPRE queda por debajo de .panel-header
     (position:sticky, 60px, z-index:20). Bug real reportado por el
     usuario, 2026-09: en un viewport bajo (típico con las DevTools
     abiertas) el centrado automático del navegador dejaba el <dialog>
     empezando a los pocos píxeles del borde superior, MONTADO sobre el
     header del panel — un <dialog> con showModal() se pinta por encima de
     cualquier z-index normal, así que visualmente el botón "Cerrar" se
     veía perfecto, pero document.elementFromPoint() en esas coordenadas
     devolvía el <header>, no el botón: el header se quedaba con el clic
     real del mouse (verificado en vivo). Ya no puede solaparse: con este
     margen, el <dialog> arranca SIEMPRE por debajo del header, sin
     importar la altura del viewport. */
  margin-top: calc(var(--header-alto) + 24px);
}
/* `display: flex` va en [open], NO en la clase sola — el navegador oculta
   un <dialog> cerrado con la regla `dialog:not([open]) { display: none }`
   de su propia hoja de estilos, pero un `display` sin condicionar en una
   regla de autor (esta) puede ganarle a esa regla del navegador y dejar el
   modal VISIBLE aunque ya esté cerrado (open=false) — que es EXACTAMENTE
   lo que pasaba: dlg.close() sí cerraba el <dialog> en el DOM (verificado
   con dlg.open === false), pero seguía pintado en pantalla porque nada
   revertía este display:flex. El botón "Cerrar" en la práctica NUNCA
   había funcionado desde que existe esta pantalla — bug real, encontrado
   recién en vivo (2026-09) probando con el usuario en su propia sesión.
   Con el display condicionado a [open], al cerrar deja de calzar esta
   regla y la de `dialog:not([open])` del navegador aplica sin estorbo. */
.panel-dialog--grande[open] {
  display: flex;
  flex-direction: column;
}
.panel-dialog--grande__cabecera {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin: -24px -24px 16px;
  padding: 16px 24px;
  border-bottom: 1px solid var(--linea);
  flex-shrink: 0;
}
.panel-dialog--grande__cabecera h3 { margin: 0; font-size: 1.05rem; }
.panel-dialog--grande__cuerpo { flex: 1; overflow-y: auto; min-height: 0; }

/* Checklist de "Configuración mínima" — Crear nueva unidad, paso 6 (2026-09) */
.panel-checklist { max-width: 800px; margin: 14px auto 0; display: flex; flex-direction: column; gap: 8px; }
.panel-checklist__grupo { margin: 12px 0 0; font-weight: 600; color: var(--gris); font-size: .85rem; text-transform: uppercase; letter-spacing: .03em; }
.panel-checklist__item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  padding: 12px 14px;
  border: 1px solid var(--linea);
  border-radius: var(--radio-chico);
  background: var(--papel);
}
.panel-checklist__item.is-listo { border-color: var(--ok); background: var(--ok-fondo); }
.panel-checklist__item [data-checklist-estado] { color: var(--gris); font-size: .9rem; }
.panel-checklist__item.is-listo [data-checklist-estado] { color: var(--ok); font-weight: 600; }

/* Diálogo de confirmación genérico (window.urbConfirmar(), panel.js) —
   reemplaza confirm() nativo en todo el panel. Un solo <dialog>, creado por
   JS y reutilizado, así que estas reglas son las únicas que necesita. */
.panel-dialog--confirmar { width: min(420px, calc(100vw - 48px)); }
.panel-dialog__mensaje { margin: 0 0 20px; line-height: 1.5; white-space: pre-line; }
/* Diálogo "Procesando…" (urbProcesando) y de resultado (urbResultado) */
.panel-dialog--proceso { display: none; text-align: center; }
.panel-dialog--proceso[open] { display: flex; flex-direction: column; align-items: center; gap: 14px; padding: 28px 24px; }
.panel-dialog--proceso .panel-dialog__mensaje { margin: 0; }
.panel-dialog--proceso .tab-panel--cargando__spinner { width: 34px; height: 34px; }
.panel-dialog--resultado { width: min(460px, calc(100vw - 48px)); text-align: center; }
.panel-resultado__icono { width: 46px; height: 46px; margin: 0 auto 10px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 1.6rem; font-weight: 700; color: #fff; }
.panel-resultado__icono--ok { background: #2e9e5b; }
.panel-resultado__icono--aviso { background: #d98a00; }
.panel-resultado__icono--error { background: #cf3a3a; }
.panel-resultado__titulo { margin: 0 0 14px; font-size: 1.1rem; }
.panel-resultado__filas { display: grid; grid-template-columns: auto 1fr; gap: 6px 14px; margin: 0 0 20px; text-align: left; font-size: .92rem; }
.panel-resultado__filas dt { color: #5b6b7b; }
.panel-resultado__filas dd { margin: 0; font-weight: 600; overflow-wrap: anywhere; }
.panel-resultado__lista { margin: 0 0 20px; padding-left: 18px; text-align: left; max-height: 180px; overflow: auto; font-size: .88rem; }
.panel-dialog--resultado .panel-dialog__acciones { justify-content: center; }
.panel-dialog__acciones { display: flex; justify-content: flex-end; gap: 10px; }

/* Spinner de botón (window.urbBotonCargando(), panel.js) — mismo giro que
   .tab-panel--cargando__spinner, a tamaño de botón. Color claro por
   defecto porque los botones que más lo usan (primario/peligro) tienen
   fondo de color con texto blanco; secundario/fantasma lo invierten. */
.panel-boton__spinner {
  display: inline-block;
  width: 13px;
  height: 13px;
  border: 2px solid rgba(255, 255, 255, .45);
  border-top-color: #fff;
  border-radius: 50%;
  animation: tab-panel-girar .8s linear infinite;
  vertical-align: -2px;
}
.panel-boton--secundario .panel-boton__spinner,
.panel-boton--fantasma .panel-boton__spinner {
  border-color: var(--linea);
  border-top-color: var(--azul);
}
@media (prefers-reduced-motion: reduce) {
  .panel-boton__spinner { animation-duration: 2.5s; }
}

/* Notas de gestión (módulo Abogado, "Ver / Gestionar" y "Ver notas") — el
   detalle es texto libre, puede venir sin espacios largos (una URL, un
   número largo) que sin overflow-wrap desbordaría el ancho fijo del
   diálogo. Ver también el overflow-x:hidden de .panel-dialog arriba. */
[id^="abg-notas-"] ul { margin: 0; padding-left: 20px; }
[id^="abg-notas-"] li { overflow-wrap: anywhere; word-break: break-word; margin-bottom: 10px; }
[id^="abg-notas-"] li:last-child { margin-bottom: 0; }

/* Cobro de honorarios (2026-08-29, corregido — pedido explícito del
   usuario: los campos numéricos/select de "Valor base"/"%"/"Calcular sobre"
   en tabla-abg-honorarios se veían "feos", con el aspecto crudo del
   navegador (sin heredar nada de .panel-campo, que es para formularios
   verticales, no para una celda de tabla). Mismo lenguaje visual (borde,
   radio, color) que el resto del panel, pero con el padding más bajo de
   .panel-mov-doc-valor-inline (celda de tabla, no campo de formulario) para
   CONSERVAR la altura de fila que ya tenía la tabla. */
.panel-input-tabla {
  width: 12ch;
  padding: 6px 8px;
  font-size: .85rem;
  border: 1px solid var(--linea);
  border-radius: var(--radio-chico);
  color: var(--tinta);
  background: var(--papel);
  box-sizing: border-box;
}
.panel-input-tabla--chico { width: 9ch; }
.panel-input-tabla--ancho { width: 100%; min-width: 18ch; }
.panel-casilla-tabla { width: 18px; height: 18px; accent-color: var(--azul); vertical-align: middle; }
.panel-input-tabla:focus { outline: 2px solid var(--azul); outline-offset: 1px; }
.panel-select-tabla {
  padding: 6px 28px 6px 8px;
  font-size: .85rem;
  border: 1px solid var(--linea);
  border-radius: var(--radio-chico);
  color: var(--tinta);
  background-color: var(--papel);
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2364748b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 8px center;
  background-size: 14px;
}
.panel-select-tabla:focus { outline: 2px solid var(--azul); outline-offset: 1px; }

/* Nota de ajuste (2026-08-21, motor de cruce real) — un bloque por apto
   destino agregado (traslado_saldo_apto / distribucion_pago), cada uno con
   su propio widget de reparto por servicio debajo. */
.panel-ajuste-destino {
  border: 1px solid var(--linea);
  border-radius: var(--radio-chico);
  padding: 12px 14px;
  margin: 10px 0;
  background: var(--fondo);
}
.panel-ajuste-destino__fila { display: flex; gap: 12px; align-items: flex-end; flex-wrap: wrap; }
.panel-ajuste-destino__fila .panel-campo { flex: 1; min-width: 140px; }
.panel-ajuste-destino [data-destino-reparto]:not(:empty) { margin-top: 10px; }
[data-reparto-valor], [data-linea-valor] { max-width: 110px; }
.panel-dialog__cabecera {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 14px;
}
.panel-dialog__cabecera h3 { margin: 0; font-size: 1.1rem; }
.panel-dialog__cerrar {
  border: none;
  background: var(--fondo);
  border-radius: 8px;
  padding: 6px;
  cursor: pointer;
  color: var(--gris);
  display: grid;
  place-items: center;
}
.panel-dialog__cerrar:hover { color: var(--tinta); }
.panel-dialog__seccion {
  margin: 20px 0 10px;
  padding-top: 14px;
  border-top: 1px solid var(--linea);
  font-size: .85rem;
  color: var(--gris);
  text-transform: uppercase;
  letter-spacing: .03em;
}
.panel-dialog form.panel-form { gap: 10px; }

.panel-form-grupo { gap: 8px; align-items: center; }
.panel-form-grupo select { min-width: 180px; }

/* ---------------------------------------------------------------------
   Hito 2: formularios de alta/edición inline, filtros, paginación
   ------------------------------------------------------------------- */

.panel-form--ancho { max-width: 640px; }
/* Formularios de 2 columnas con campos largos (ej. Info unidad, 12 campos):
   640px reparte cada columna en ~300px, apretado — 920px da a cada campo
   el mismo aire que uno de 1 sola columna, incluso con ventanas no muy
   anchas. Las etiquetas más largas de cada pantalla (ej. "Nombre de la
   empresa / unidad") igual van con panel-campo-ancho — ensanchar el
   formulario solo no evita que una etiqueta larga salte de línea y
   deslinee su fila contra el campo vecino, hay que sacarla del par. */
.panel-form--muyancho { max-width: 920px; }

/* Alta/edición inline con <details>: sin modal, sin JS. El summary hace
   de botón; al abrirlo aparece el formulario justo debajo. */
.panel-expandible { margin: 14px 0; }
/* Cuenta de cobro Urbanizando (2026-09): lista de "Marcadores disponibles"
   dentro de un <details> de un formulario — mismo criterio visual que los
   chips "Variables disponibles" de Certificados, pero como lista simple. */
.panel-lista-marcadores { margin: 8px 0 0; padding-left: 18px; font-size: .85rem; color: var(--gris); }
.panel-lista-marcadores code { background: var(--fondo); border: 1px solid var(--linea); border-radius: 4px; padding: 1px 5px; color: #1c2733; }
/* Comunicaciones de Urbanizando: fila destacada al llegar desde el deep-link
   de una notificación (?cuenta=N), ver vistas/comunicaciones_urbanizando.php. */
.panel-fila-destacada { background: #fff6da !important; }
.panel-expandible summary { cursor: pointer; list-style: none; }
.panel-expandible summary::-webkit-details-marker { display: none; }
.panel-expandible[open] summary.panel-boton { margin-bottom: 14px; }
.panel-expandible > form {
  border: 1px solid var(--linea);
  border-radius: var(--radio);
  padding: 16px;
  background: var(--fondo);
}
.panel-expandible--chica { display: inline-block; margin: 0 6px 0 0; }
.panel-expandible--chica summary { font-size: .82rem; color: var(--azul); }
.panel-expandible--chica summary:hover { text-decoration: underline; }
.panel-expandible--chica > form {
  position: relative;
  margin-top: 8px;
  max-width: 280px;
  box-shadow: var(--sombra);
}

.panel-celda-acciones { white-space: nowrap; }
.panel-celda-angosta { max-width: 220px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Botón de texto para acciones secundarias en una fila de tabla
   (editar, generar temporal, eliminar) — no compite visualmente con los
   botones primarios. */
.panel-enlace {
  border: none;
  background: none;
  color: var(--azul);
  font-size: .82rem;
  cursor: pointer;
  padding: 4px 6px;
  text-decoration: none;
}
.panel-enlace:hover { text-decoration: underline; }
.panel-enlace--peligro { color: var(--error); }
/* Número de Meses de mora / Cobros vencidos que abre su detalle (tablas de Cartera para gestión). */
.panel-enlace[data-mora-detalle] { font-size: inherit; font-weight: 600; text-decoration: underline dotted; padding: 0; }
.panel-enlace[data-mora-detalle]:hover { text-decoration: underline; }

.panel-etiqueta {
  display: inline-block;
  font-size: .68rem;
  padding: 2px 7px;
  border-radius: 999px;
  background: var(--fondo);
  color: var(--gris);
  margin-left: 6px;
  vertical-align: middle;
}
.panel-etiqueta--aviso { background: #fff3cd; color: #8a6100; }
.panel-etiqueta--ok { background: var(--ok-fondo); color: var(--ok); }

.panel-vacio-linea { color: var(--gris); font-style: italic; font-size: .88rem; }
.panel-imp-totales { margin: 0 0 10px; padding: 8px 12px; border-radius: 8px; background: var(--papel, #f4f7fa); border: 1px solid var(--linea, #dbe3ea); font-size: .92rem; }
.panel-texto-suave { display: block; margin-top: 4px; color: var(--gris); font-size: .8rem; line-height: 1.4; }

/* Informes (gráficas drill-down, ApexCharts) — ver lib/informes.php.
   Fondo blanco propio (pedido explícito del usuario, 2026-08-27) — antes la
   gráfica quedaba directo sobre el fondo gris de la pestaña. */
.panel-informe {
  margin-top: 14px;
  background: var(--papel);
  border: 1px solid var(--linea);
  border-radius: var(--radio);
  box-shadow: var(--sombra);
  padding: 18px;
}
.panel-informe__herramientas {
  display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between;
  gap: 12px; margin-bottom: 12px;
}
.panel-informe__exportar { display: flex; gap: 8px; }
.panel-informe__herramientas { margin-top: 22px; }
.panel-informe__breadcrumb {
  font-size: .85rem; margin: 0 0 12px;
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
}
/* Pedido explícito del usuario: que se vea claramente que ahí se da clic
   para retroceder en la gráfica — antes era texto azul subrayable, poco
   obvio como control. Cada paso previo es un botón real; el separador "›"
   se dibuja con ::after en vez de un nodo de texto aparte, así no hay uno
   "suelto" después del último botón (el paso activo). */
.panel-informe__breadcrumb-boton {
  font: inherit; font-size: .82rem; font-weight: 600;
  border: 1px solid var(--linea); background: var(--papel); color: var(--azul);
  border-radius: 999px; padding: 5px 12px; cursor: pointer;
}
.panel-informe__breadcrumb-boton:not(:last-child)::after { content: '›'; margin-left: 8px; color: var(--gris); font-weight: 400; }
.panel-informe__breadcrumb-boton:hover:not(:disabled) { border-color: var(--azul); background: var(--info-fondo); }
.panel-informe__breadcrumb-boton.is-activo,
.panel-informe__breadcrumb-boton:disabled {
  background: var(--azul); border-color: var(--azul); color: #fff; cursor: default;
}

/* Distintivo junto al título de cada informe "Edad de la cartera" — pedido
   explícito del usuario: que sea MUY fácil identificar cuál es "Por tiempo"
   y cuál es "Cuotas" a simple vista, no solo por el texto del título. */
.panel-etiqueta-informe {
  display: inline-block; vertical-align: middle; margin-left: 10px;
  font-size: .68rem; font-weight: 700; letter-spacing: .02em;
  padding: 4px 12px; border-radius: 999px; text-transform: uppercase;
}
.panel-etiqueta-informe--tiempo { background: var(--info-fondo); color: var(--azul); }
.panel-etiqueta-informe--cuotas { background: #f3e8ff; color: #6d28d9; }
.panel-etiqueta-informe--evolucion { background: #dcfce7; color: #15803d; }

.panel-texto-ok { color: var(--ok); font-size: .88rem; }
.panel-texto-error { color: var(--error); font-size: .88rem; }
.panel-check-linea { display: block; padding: 4px 0; font-size: .9rem; }

/* Botón "visible pero no primario" (Verificar apto, Validar al día,
   Cargar pagos, Abrir editor...) — --fantasma es casi invisible a
   propósito para lo terciario; esto es para acciones que sí hay que ver. */
.panel-boton--secundario {
  background: var(--info-fondo);
  border-color: var(--info-fondo);
  color: var(--azul);
  font-weight: 600;
}
.panel-boton--secundario:hover { background: var(--azul); border-color: var(--azul); color: #fff; }

/* Confirmación de una anulación — la única acción "destructiva" (revierte dinero/cruces) del panel hoy. */
.panel-boton--peligro { background: var(--error); border-color: var(--error); color: #fff; font-weight: 600; }
.panel-boton--peligro:hover { filter: brightness(0.9); }

/* Formulario a 2 columnas (Certificados: Generar/Configuración) — evita el
   scroll largo de tener todo apilado en una sola columna. */
.panel-form--2col {
  display: grid;
  grid-template-columns: 1fr 1fr;
  /* Vertical 14px, igual que el gap de .panel-form de 1 columna — el
     espacio vertical en 0 (bug real, 2026-09) pegaba cada fila contra la
     siguiente sin aire, el botón de guardar incluido, en TODAS las
     pantallas que usan esta clase (ver hallazgo de auditoría del usuario:
     botones "Guardar" pegados al último campo en Info unidad, Config.
     intereses, Certificados · Configuración). */
  gap: 14px 24px;
  align-items: start;
}
.panel-form--2col > .panel-campo-ancho { grid-column: 1 / -1; }
/* Un <h4 class="panel-dialog__seccion"> DENTRO de .panel-form--2col (ej. la
   pestaña "Funcionalidades" de Conexiones de unidades, que agrupa
   "Funcionalidades" + "Botón de pago PSE" en la misma pestaña, CLAUDE.md
   raíz §2.18) debe atravesar las 2 columnas — si no, cae en una sola celda
   y deja huérfano un hueco al lado. */
.panel-form--2col > h4 { grid-column: 1 / -1; }
@media (max-width: 780px) {
  .panel-form--2col { grid-template-columns: 1fr; }
}

.panel-separador { border: none; border-top: 1px solid var(--linea); margin: 20px 0 16px; }

/* Pestañas dentro de un <dialog> (Servicios: "Servicio" / "Cuentas
   Contables") — mismo criterio visual que .panel-cert-submenu, pero más
   simple (solo subraya la pestaña activa, sin fondo lleno). */
.panel-dialog__tabs { display: flex; gap: 4px; margin-bottom: 16px; border-bottom: 1px solid var(--linea); }
.panel-dialog__tab {
  padding: 8px 16px;
  border: none;
  background: transparent;
  cursor: pointer;
  font-weight: 600;
  font-size: .95rem;
  color: var(--gris);
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
}
.panel-dialog__tab:hover { color: var(--azul); }
.panel-dialog__tab.is-activo { color: var(--azul); border-bottom-color: var(--azul); }

/* Formulario de cuentas contables (Servicios): 4 columnas — etiqueta+valor,
   Naturaleza, etiqueta+valor, Naturaleza — mismo layout que traía ScriptCase. */
.panel-form--4col { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px 16px; align-items: end; }
@media (max-width: 900px) { .panel-form--4col { grid-template-columns: 1fr 1fr; } }
@media (max-width: 560px) { .panel-form--4col { grid-template-columns: 1fr; } }

/* Tarjeta de Asignar (vistas/asignar.php): ancha y dividida en filas, cada
   una con su propio borde — mismo espíritu que el formulario de ScriptCase
   que trajo el usuario (Torre/Propietario/Cédula · Periodo/Servicio/Valor ·
   Meses · Observación), pero con el lenguaje visual normal del panel
   (tarjeta con sombra, bordes suaves) en vez de líneas negras duras.
   max-width mayor que .panel-form (420px) a propósito: con 3 columnas +
   la grilla de 12 meses, el formulario angosto por defecto se veía chico y
   los campos se salían del recuadro. */
.panel-asignar-card {
  max-width: 960px;
  margin: 14px auto 24px;
  background: var(--papel);
  border: 1px solid var(--linea);
  border-radius: var(--radio);
  box-shadow: var(--sombra);
  overflow: hidden;
}
.panel-asignar-card__cabecera {
  background: var(--azul);
  color: #fff;
  text-align: center;
  font-weight: 600;
  padding: 10px;
}
.panel-asignar-card__pie { padding: 16px 24px; border-top: 1px solid var(--linea); text-align: center; }
.panel-asignar-card__pie .panel-boton { min-width: 240px; }
.panel-asignar-fila {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 16px;
  padding: 18px 24px;
  border-top: 1px solid var(--linea);
}
.panel-asignar-fila:first-of-type { border-top: none; }
.panel-asignar-fila--simple { grid-template-columns: 1fr; }
@media (max-width: 700px) { .panel-asignar-fila { grid-template-columns: 1fr; } }

/* Checkboxes de meses en Asignar: 12 casillas en grilla, no en columna. */
.panel-fieldset-meses { border: none; padding: 0; display: grid; grid-template-columns: repeat(6, 1fr); gap: 8px; }
.panel-fieldset-meses legend { padding: 0 0 8px; font-weight: 600; color: var(--gris); font-size: .85rem; }
@media (max-width: 700px) { .panel-fieldset-meses { grid-template-columns: repeat(3, 1fr); } }

/* Submenú interno de una pestaña (Certificados: Parámetros generales /
   Paz y salvo / Constancia / Pagos / Libre / Volver) — sin precedente
   previo, primera vez que una sola pestaña cambia de sección por dentro
   en vez de abrir otra pestaña del menú. */
.panel-cert-submenu {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 4px 0 20px;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--linea);
}
.panel-cert-submenu__item {
  border: 1px solid var(--linea);
  background: var(--papel);
  color: var(--gris);
  border-radius: 999px;
  padding: 7px 16px;
  font-size: .85rem;
  font-weight: 600;
  cursor: pointer;
}
.panel-cert-submenu__item:hover { border-color: var(--azul); color: var(--azul); }
.panel-cert-submenu__item.is-activo { background: var(--azul); border-color: var(--azul); color: #fff; }
.panel-cert-submenu__item--volver { margin-left: auto; background: transparent; border-color: transparent; }

/* Dato de solo lectura (ej. Torre, que ya no se edita) presentado como
   etiqueta en vez de <input>. */
.panel-cert-dato { display: flex; flex-direction: column; gap: 4px; font-size: .85rem; color: var(--gris); }
.panel-cert-dato strong { font-size: .95rem; color: var(--tinta); font-weight: 500; }

/* Fila apto + botón "Verificar apto" al lado, en vez de apilados. */
.panel-cert-fila-apto { display: flex; gap: 10px; align-items: flex-end; }
.panel-cert-fila-apto .panel-campo { flex: 1; }

/* Generar: dos paneles EXPLÍCITOS lado a lado (izquierda = datos del
   propietario, derecha = contenido del tipo elegido + vista previa) — a
   diferencia de .panel-form--2col (que reparte campos sueltos alternando
   columna), acá cada mitad es un contenedor propio, así que un formulario
   de propietarios que crece (agregar propietario/correo) no empuja al
   editor/preview lejos hacia abajo. */
.panel-cert-generar-grid {
  display: grid;
  grid-template-columns: minmax(280px, 340px) minmax(0, 1fr);
  gap: 24px;
  align-items: start;
  /* max-width:100% en vez de heredar .panel-form--ancho (640px, pensado
     para formularios de un campo por fila): con dos columnas + una "hoja"
     de vista previa de ancho fijo, 640px la hacía reventar el ancho de la
     tarjeta blanca y la vista previa quedaba flotando sobre el fondo gris. */
  max-width: 100%;
  width: 100%;
}
/* min-width:0 es necesario porque, por spec, un ítem de grid no se achica
   por debajo del ancho de SU CONTENIDO más ancho (acá, la "hoja" de 520px)
   a menos que se le diga explícitamente — sin esto, la columna empujaba el
   grid entero más allá de la tarjeta blanca en vez de dejar que
   .panel-cert-vista scrollee por su cuenta. */
.panel-cert-generar-grid > div { min-width: 0; }
@media (max-width: 900px) {
  .panel-cert-generar-grid { grid-template-columns: 1fr; }
}

/* Configuración de un tipo de certificado: editor a la izquierda, vista
   previa sola a la derecha — a diferencia de Generar (columna izquierda
   angosta, son solo controles), acá las dos columnas cargan contenido
   comparable (editor vs. "hoja") y deben verse del mismo tamaño, no una
   angosta/chica contra una ancha/alta. 1fr 1fr en vez de reusar
   .panel-cert-generar-grid — esa reserva la izquierda a 280-340px, que
   dejaba el editor diminuto contra la vista previa (671px de alto por la
   proporción carta real). */
.panel-cert-config-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 24px;
  align-items: start;
  max-width: 100%;
  width: 100%;
}
.panel-cert-config-grid > div { min-width: 0; }
@media (max-width: 900px) {
  .panel-cert-config-grid { grid-template-columns: 1fr; }
}
/* La "hoja" de vista previa ya trae su propio ancho fijo (520px, ver
   .panel-cert-hoja) — dentro de una columna 1fr más ancha que eso, se
   centra en vez de estirarse a lo ancho y deformar la proporción carta. */
.panel-cert-config-grid .panel-cert-vista { display: flex; flex-direction: column; align-items: center; }
.panel-cert-config-grid .panel-cert-vista__barra { align-self: stretch; }
.panel-cert-config-grid .panel-cert-hoja { margin: 0; }
/* Propietario 2/3/4: mismo patrón apilado (nombre, después cédula) que el
   propietario principal — un renglón nombre+cédula+Quitar quedaba
   apretado en la columna izquierda (280-340px) y se veía inconsistente
   con el resto del formulario. */
.panel-cert-propietario-extra {
  padding: 10px 12px;
  margin-bottom: 10px;
  border-left: 2px solid var(--linea);
  background: var(--fondo);
  border-radius: var(--radio-chico);
}

/* Radios/checkbox de las 3 opciones de "Certificado de pagos" (automático/
   manual/discriminar) — más grandes y más separadas entre sí que el resto
   de casillas del panel (que son chicas a propósito para no llamar la
   atención; estas SÍ son una decisión importante, deben notarse). */
.panel-cert-opcion-grande { margin-bottom: 14px; gap: 10px; }
.panel-cert-opcion-grande input[type="radio"],
.panel-cert-opcion-grande input[type="checkbox"] { width: 19px; height: 19px; }

/* Vista previa "chica" (Certificado libre: el editor manda, la vista
   previa es de apoyo, debajo). */
.panel-cert-hoja--chica { width: 100%; min-height: 380px; padding: 22px 20px; font-size: 8.5pt; }

/* Panel de marcadores clicables (Variables) — inserta en el editor al
   cursor, mismo espíritu que el panel de variables de
   crm_emails/vistas/redactar.php. */
.panel-cert-marcadores { display: flex; flex-wrap: wrap; gap: 6px; margin: 10px 0; }
.panel-cert-marcadores button {
  border: 1px solid var(--linea);
  background: var(--fondo);
  color: var(--azul);
  border-radius: 999px;
  padding: 4px 12px;
  font-size: .78rem;
  font-family: monospace;
  cursor: pointer;
}
.panel-cert-marcadores button:hover { background: var(--info-fondo); border-color: var(--azul); }

/* Vista previa "hoja impresa" — mismo criterio visual que
   crm_emails/vistas/mensaje_cc.php (mcc__hoja/mcc__vista), pero sin la
   línea de "límite media hoja" (no aplica acá) y sin escalado por JS: se
   deja horizontal-scroll dentro de su propio marco si no cabe. */
.panel-cert-vista { overflow-x: auto; border: 1px solid var(--linea); border-radius: var(--radio); background: var(--fondo); padding: 0 0 12px; }
.panel-cert-vista__barra {
  font-size: .74rem;
  font-weight: 600;
  color: var(--gris);
  padding: 8px 12px;
  border-bottom: 1px solid var(--linea);
  margin-bottom: 12px;
}
/* Simula el tamaño/proporción de una hoja carta (más angosta que antes —
   700px era más ancha que la columna que la contiene y reventaba el
   grid). display:flex column + el cuerpo a flex:1 es lo que deja el pie
   SIEMPRE al fondo de la "hoja", sin importar cuánto contenido tenga el
   cuerpo — antes, al no tener esto, el pie quedaba pegado justo debajo
   del contenido (arriba, no al fondo, cuando el certificado era corto). */
.panel-cert-hoja {
  display: flex;
  flex-direction: column;
  width: 520px;
  /* Proporción carta real (216 × 279 mm): a 520px de ancho, el alto
     exacto es 520 × (279/216) ≈ 671px — aspect-ratio lo mantiene ahí como
     mínimo, pero un certificado más largo puede seguir creciendo (no es
     un límite de una sola "hoja", solo el punto de partida a escala). */
  aspect-ratio: 216 / 279;
  min-height: 671px;
  margin: 0 auto;
  background: #fff;
  box-shadow: 0 1px 4px rgba(0,0,0,.12);
  padding: 32px 28px;
  box-sizing: border-box;
  font-size: 10pt;
  line-height: 1.5;
  color: #222;
}
/* Certificados y cartas (Configuración y Generar): la hoja a TAMAÑO CARTA REAL (216 × 279 mm a 96 dpi = 816 × 1056 px), con
   los márgenes laterales del PDF (15 mm) y la letra por defecto de TCPDF (12 pt). Así el texto guarda con la hoja la misma
   proporción que en el PDF; window.urbCertHojaEscalar() (panel.js) le pone `zoom` hasta que quepa en su marco. Antes la
   hoja medía 520 px con letra de 10 pt (≈ 64 % de la hoja real) y el texto se veía desproporcionado. La base
   .panel-cert-hoja no se toca: también la usan Cuenta de cobro Urbanizando y otras vistas. */
.panel-cert-hoja--carta {
  width: 816px;
  aspect-ratio: auto;
  flex: 0 0 auto;
  min-height: 1056px;
  padding: 12mm 15mm 10mm;
  font-size: 12pt;
  line-height: 1.3;
}
.panel-cert-hoja--carta .panel-cert-hoja__marca { font-size: 7.5pt; }
.panel-cert-hoja--carta .panel-cert-hoja__cabecera-texto { font-size: 10pt; line-height: 1.4; }
.panel-cert-hoja--carta .panel-cert-hoja__logo img { max-height: 70px; max-width: 140px; }
.panel-cert-hoja--carta .panel-cert-hoja__pie-defecto { font-size: 7.5pt; line-height: 1.4; }
.panel-cert-hoja__cuerpo { flex: 1 0 auto; }
.panel-cert-hoja img { max-width: 100%; height: auto; }
.panel-cert-hoja table { border-collapse: collapse; max-width: 100%; }
.panel-cert-hoja td, .panel-cert-hoja th { padding: 3px 6px; vertical-align: top; }
.panel-cert-hoja hr { border: 0; border-top: 1px solid #dbe4ec; margin: 10px 0; }

/* Encabezado/pie de la vista previa (por defecto o imagen subida) — mismo
   criterio visual que el PDF real (api-urban/lib/certificados.php). */
.panel-cert-hoja__marca { text-align: center; font-size: 7pt; color: #9aa7b2; margin-bottom: 6px; }
.panel-cert-hoja__marca img { width: 12px; height: 12px; vertical-align: middle; margin-right: 4px; object-fit: contain; }
.panel-cert-hoja__cabecera-defecto { display: flex; justify-content: space-between; align-items: flex-start; gap: 14px; }
.panel-cert-hoja__cabecera-texto { font-size: 9.5pt; line-height: 1.5; }
.panel-cert-hoja__logo img { max-height: 46px; max-width: 90px; object-fit: contain; }
.panel-cert-hoja__cabecera-img img, .panel-cert-hoja__pie-img img { width: 100%; display: block; margin-bottom: 8px; }
.panel-cert-hoja__pie-defecto { text-align: center; font-size: 8.5pt; color: #5a6b78; line-height: 1.5; margin-bottom: 6px; }
.panel-cert-vista-vacia { color: var(--gris); font-style: italic; text-align: center; padding: 40px 0; }

.panel-select-chica { font-size: .85rem; padding: 6px 8px; border: 1px solid var(--linea); border-radius: var(--radio-chico); }

/* Medidor de fortaleza de contraseña (cosmético, ver urbMedirFuerza en panel.js) */
.panel-fuerza { margin-top: -6px; }
.panel-fuerza__pista { height: 6px; border-radius: 999px; background: var(--linea); overflow: hidden; }
.panel-fuerza__barra { height: 100%; width: 0; border-radius: 999px; transition: width .15s ease, background .15s ease; background: var(--error); }
.panel-fuerza__barra.panel-fuerza--muy-debil { background: var(--error); }
.panel-fuerza__barra.panel-fuerza--debil { background: #e07a1f; }
.panel-fuerza__barra.panel-fuerza--media { background: #d4a10a; }
.panel-fuerza__barra.panel-fuerza--fuerte { background: #4f9d3a; }
.panel-fuerza__barra.panel-fuerza--muy-fuerte { background: var(--ok); }
.panel-fuerza__texto { display: block; margin-top: 4px; font-size: .76rem; color: var(--gris); }

.panel-buscador-local { max-width: 320px; margin-bottom: 16px; }

/* Filtros de la Bitácora: fila que se envuelve en pantallas angostas. */
.panel-filtros {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 12px;
  margin-bottom: 16px;
  padding: 14px;
  background: var(--papel);
  border: 1px solid var(--linea);
  border-radius: var(--radio);
}
.panel-campo--chico { min-width: 140px; margin: 0; }
.panel-campo--flex { flex: 1; min-width: 200px; }

/* Filtro de RANGO (mínimo/máximo) dentro de un .panel-campo--chico — dos
   <input type="number"> con un guion entre medio (ej. "Meses de mora entre
   1.5 y 3.2" en abg_cartera.php/ga_cartera.php). Ver
   window.urbRepTablaFiltrar (data-filtro-tope="minimo"/"maximo"). */
.panel-campo-rango { display: flex; align-items: center; gap: 6px; }
.panel-campo-rango input[type="number"] { width: 92px; }

/* Filtros avanzados, colapsados por defecto detrás de un botón (pedido
   explícito del usuario: los filtros de rango de mora se veían "apeñuscados"
   siempre visibles junto a Torre/Mora/Frente). width:100% fuerza una fila
   propia dentro del .panel-filtros (flex-wrap) cuando está abierto — nunca
   [hidden] para el toggle, mismo motivo que .panel-columnas__lista (una
   regla con display:flex de mayor prioridad que el [hidden] del navegador
   dejaría el toggle roto). */
.panel-filtros__avanzados {
  width: 100%;
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  padding-top: 12px;
  margin-top: 2px;
  border-top: 1px dashed var(--linea);
}
.panel-filtros__avanzados.is-cerrada { display: none; }
.panel-frag__contador { color: var(--gris); font-size: .85rem; margin: 0 0 10px; }

.panel-paginacion { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-top: 16px; }
.panel-paginacion__salto { color: var(--gris); padding: 0 2px; }
.panel-paginacion__estado { color: var(--gris); font-size: .85rem; margin-left: 8px; }
.panel-boton--pagina:disabled { opacity: .45; cursor: not-allowed; }
.panel-boton--pagina { padding: 6px 12px; min-width: 36px; text-align: center; }
.panel-boton--pagina.is-activa { background: var(--azul); border-color: var(--azul); color: #fff; }

/* Pie de página del panel, igual al de portal_usuarios: fijo debajo de
   todo (menú + pestañas), visible en cualquier pestaña, no solo en
   Inicio — mismo criterio que el menú lateral, que tampoco depende de
   qué pestaña esté activa. */
.pie {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 12px;
  flex: none;
  padding: 12px 24px;
  background: var(--azul-noche);
  color: rgba(255, 255, 255, .6);
  font-size: .8rem;
}
.pie__marca { display: flex; align-items: center; gap: 11px; color: var(--celeste); text-decoration: none; }
.pie__marca:hover { text-decoration: underline; }
.pie__logo {
  height: 26px;
  width: auto;
  max-width: 110px;
  object-fit: scale-down;
  /* El logo trae su propio azul; en un fondo azul-noche desaparecería.
     brightness(0) invert(1) lo deja blanco sin necesitar otro archivo. */
  filter: brightness(0) invert(1);
}
.pie__nota { color: rgba(255, 255, 255, .6); }

/* ---------------------------------------------------------------------
   Responsive
   ------------------------------------------------------------------- */

@media (max-width: 1100px) {
  .panel-header__buscador { max-width: 280px; }
}

@media (max-width: 860px) {
  .panel-header__hamburguesa { display: inline-flex; }

  .panel-menu {
    position: fixed;
    top: var(--header-alto);
    bottom: 0;
    left: 0;
    z-index: 40;
    box-shadow: var(--sombra);
    transform: translateX(-100%);
    transition: transform .2s ease;
  }
  .panel-menu.is-abierto { transform: none; }

  /* En móvil el menú ya es un cajón que la hamburguesa abre/cierra por
     completo: el botón de contraer (pensado para escritorio) sobra. */
  .panel-menu__cabecera { display: none; }
  .panel-menu.panel-menu--colapsado { width: var(--menu-ancho); }

  .panel-menu-fondo {
    display: none;
    position: fixed;
    inset: var(--header-alto) 0 0 0;
    background: rgba(15, 23, 32, .35);
    z-index: 30;
  }
  .panel-menu-fondo.is-visible { display: block; }

  .panel-header__nombre { display: none; }
  .usuario__texto, .usuario__boton > svg { display: none; }
  .usuario__boton { padding: 4px; }

  /* Poco espacio: el botón de cambiar unidad se queda solo con el ícono. */
  .panel-header__cambiar-unidad span { display: none; }
  .panel-header__cambiar-unidad { padding: 8px; }

  /* Pedido explícito del usuario: dentro de una unidad, en móvil, el
     buscador "Buscar en el menú" se muda al cajón del menú (arriba de la
     lista, visible al abrir la hamburguesa) en vez de competir por espacio
     en el header. La copia de escritorio (.panel-header__buscador) se
     oculta; la del cajón (.panel-menu__buscador) ya tenía display:none por
     defecto y se muestra acá. */
  .panel-header--shell .panel-header__buscador { display: none; }
  .panel-menu__buscador { display: flex; }
}

@media (max-width: 640px) {
  .acceso__tarjeta { grid-template-columns: 1fr; }
  .acceso__logos { padding: 18px; }
  .acceso__identidad { padding: 22px 24px; gap: 8px; }
  .acceso__panel { padding: 26px 24px; }

  .panel-header__logo-urbanizando { display: none; }
  .panel-header { gap: 10px; padding: 0 12px; }

  /* Selector de unidad, en móvil: el buscador pasa de "pill" fijo (sin
     espacio real para escribir junto al logo/usuario) a un botón-lupa que
     abre una búsqueda de pantalla completa — pedido explícito del usuario
     tras ver que el pill fijo, ya sin overlap (ver min-width:0 arriba),
     seguía quedando demasiado angosto para ser cómodo de usar. */
  .panel-header--selector #buscador-caja {
    background: none;
    border: none;
    padding: 8px;
    margin: 0;
    width: auto;
    max-width: none;
  }
  .panel-header--selector #buscador-caja input { display: none; }
  /* Solo cubre la FRANJA del header (top/left/right + alto fijo, sin
     "bottom"/inset:0) — no toda la pantalla. Corregido 2026-09: la primera
     versión tapaba también la lista de resultados de abajo (inset:0 = toda
     la pantalla en blanco, sin forma de ver lo que se estaba filtrando). Al
     dejar visible el resto de la página, la lista de unidades (que ya se
     repinta sola por AJAX en cada tecla, ver panel.js:pintarUnidades) queda
     visible debajo mientras se escribe. */
  .panel-header--selector #buscador-caja.is-abierto {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    height: var(--header-alto);
    z-index: 25;
    background: var(--papel);
    border: none;
    border-bottom: 1px solid var(--linea);
    border-radius: 0;
    padding: 0 16px;
    margin: 0;
    max-width: none;
  }
  .panel-header--selector #buscador-caja.is-abierto .panel-header__buscador-boton { display: none; }
  .panel-header--selector #buscador-caja.is-abierto input { display: block; font-size: 1rem; }
  .panel-header--selector #buscador-caja.is-abierto .panel-header__buscador-cerrar { display: inline-flex; }
}

@media (prefers-reduced-motion: reduce) {
  .panel-menu, .panel-toast { transition: none; animation: none; }
}

/* Wizard de la ficha de Propietarios (vistas/propietarios.php): indicador
   de pasos con círculo numerado + Siguiente/Atrás al final de cada paso.
   Deliberadamente más "llamativo" que .panel-cert-submenu (círculo grande,
   línea de conexión) — el pedido explícito fue que se vea como pasos de un
   formulario, no como pestañas discretas. */
.panel-wizard__pasos {
  display: flex;
  flex-wrap: wrap;
  gap: 2px;
  margin: 4px 0 24px;
  padding-bottom: 14px;
  border-bottom: 1px solid var(--linea);
}
.panel-wizard__paso {
  display: flex;
  align-items: center;
  gap: 8px;
  border: none;
  background: transparent;
  cursor: pointer;
  padding: 6px 12px 6px 6px;
  border-radius: 999px;
  color: var(--gris);
  font-size: .82rem;
  font-weight: 600;
  white-space: nowrap;
}
.panel-wizard__paso:hover { background: var(--fondo); color: var(--tinta); }
.panel-wizard__paso__num {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  flex: none;
  border-radius: 50%;
  border: 2px solid var(--linea);
  font-size: .78rem;
  color: var(--gris);
}
.panel-wizard__paso.is-activo { color: var(--azul); }
.panel-wizard__paso.is-activo .panel-wizard__paso__num { border-color: var(--azul); background: var(--azul); color: #fff; }

/* Selector de columnas visibles del listado de Propietarios. Arranca
   CERRADO (.is-cerrada en el <div>, ver la vista) — la visibilidad la
   maneja esa clase, NUNCA el atributo [hidden]: [hidden] tiene la misma
   especificidad que una clase, y como esta regla de abajo YA necesita
   fijar display:flex para el layout en columna, esa declaración pisaba
   [hidden] (que solo pone display:none en la hoja de estilos por defecto
   del navegador, de MENOR prioridad que cualquier regla de esta hoja) —
   el botón "Columnas" quedaba con el toggle roto: nunca se veía cerrado. */
.panel-columnas { position: relative; margin: 10px 0; }
.panel-columnas__lista {
  position: absolute;
  z-index: 5;
  top: calc(100% + 4px);
  left: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 220px;
  padding: 12px 14px;
  background: var(--papel);
  border: 1px solid var(--linea);
  border-radius: var(--radio-chico);
  box-shadow: 0 8px 24px rgba(0,0,0,.12);
}
.panel-columnas__lista.is-cerrada { display: none; }
.panel-columnas__lista { max-height: 340px; overflow-y: auto; }
.panel-columnas__todas { padding-bottom: 6px; border-bottom: 1px solid var(--linea); }

/* Pasos 1 y 2 (Propietario principal / Datos del apartamento) tienen más
   campos que el resto — 420px (.panel-form) los dejaba muy angostos y
   apilados en una sola columna real aunque .panel-form--2col pidiera dos.
   Escenario a esta pantalla nada más, no se toca .panel-form ni
   .panel-form--ancho (640px, usado en otras 5 pantallas). */
.panel-wizard__contenido .panel-form { max-width: 800px; }
/* El margen del botón de guardar ya es general (.panel-form > button[type="submit"],
   arriba) — este escenario puntual quedó cubierto sin necesitar su propia regla. */

.panel-wizard__titulo { margin: 0 0 4px; font-size: 1.05rem; }
.panel-wizard__nav {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-top: 22px;
  padding-top: 16px;
  border-top: 1px solid var(--linea);
}

/* Control "transfer" (Dual Listbox) de Unidades por usuario — reemplaza el
   <select> + botón "Agregar" de antes (pedido explícito del usuario,
   2026-09: recargaba la página en cada asignación). Dos <select multiple>
   con los botones de mover en medio; ver urb_unidades_transfer_html()
   (lib/unidades.php) y window.urbTransferMover()/urbUnidadesGuardar()
   (panel.js). */
.panel-transfer { display: flex; align-items: stretch; gap: 10px; margin: 10px 0; }
.panel-transfer__col { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.panel-transfer__titulo { margin: 0; font-size: .78rem; font-weight: 600; color: var(--gris); }
.panel-transfer__col select {
  flex: 1;
  min-height: 220px;
  padding: 4px;
  border: 1px solid var(--linea);
  border-radius: var(--radio-chico);
  background: var(--papel);
  font-size: .85rem;
}
.panel-transfer__botones {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 6px;
  flex: none;
}
.panel-transfer__botones button {
  width: 36px;
  height: 32px;
  border: 1px solid var(--linea);
  border-radius: var(--radio-chico);
  background: var(--fondo);
  color: var(--tinta);
  cursor: pointer;
  font-size: .95rem;
}
.panel-transfer__botones button:hover:not(:disabled) { background: var(--linea); }
.panel-transfer__botones button:disabled { opacity: .4; cursor: not-allowed; }
.panel-transfer-form > button[type="submit"] { margin-top: 12px; }

/* Selector visual de íconos (urb_icono_selector_html(), lib/vista.php) —
   Menú del portal / Menú del sistema. El botón "actual" se ve como un
   .panel-campo normal para no desentonar al lado de los demás inputs. */
.panel-icono-selector__actual {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  border: 1px solid var(--linea);
  border-radius: var(--radio-chico);
  background: var(--papel);
  color: var(--tinta);
  cursor: pointer;
  font-size: .85rem;
}
.panel-icono-selector__actual svg { width: 18px; height: 18px; flex: none; }
.panel-icono-selector__actual:hover { background: var(--fondo); }
.panel-icono-dialogo { width: min(520px, calc(100vw - 48px)); }
.panel-icono-grilla {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(84px, 1fr));
  gap: 8px;
  margin-top: 12px;
  max-height: 320px;
  overflow-y: auto;
}
.panel-icono-grilla__item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  padding: 10px 4px;
  border: 1px solid var(--linea);
  border-radius: var(--radio-chico);
  background: var(--papel);
  color: var(--tinta);
  cursor: pointer;
  font-size: .68rem;
  text-align: center;
}
.panel-icono-grilla__item svg { width: 22px; height: 22px; }
.panel-icono-grilla__item:hover { background: var(--fondo); border-color: var(--azul); }
.panel-icono-grilla__item span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%; }
/* Mismo gotcha ya documentado en Propietarios (CLAUDE.md §2.8): el
   [hidden] nativo del navegador no le gana a un display:flex de autor con
   la misma especificidad — sin esto, window.urbIconoBuscar() marcaba
   hidden=true en los botones filtrados pero seguían viéndose igual. */
.panel-icono-grilla__item[hidden] { display: none; }

/* ---------------------------------------------------------------------
   Movimientos: dos paneles (buscador de apto | tabla del año). El panel
   izquierdo se colapsa para que la tabla dinámica (columnas de grupo
   variables) tenga todo el ancho disponible en pantallas angostas.
   ------------------------------------------------------------------- */
.panel-mov-layout {
  display: grid;
  grid-template-columns: 260px 1fr;
  gap: 18px;
  align-items: start;
  margin-top: 14px;
}
/* [hidden] del navegador (display:none) pierde contra el display:grid de
   arriba porque las dos reglas tienen la misma especificidad y esta gana
   por selector más específico — sin esto, window.urbMovIncrustarAbrir()
   (panel.js) pone hidden=true pero la tabla de Movimientos se queda
   visible igual, y el contenido incrustado (Certificados/Serv. asignados)
   aparece debajo sin que la vista anterior desaparezca (bug real, se veía
   como que el botón "no hacía nada"). */
.panel-mov-layout[hidden] { display: none; }
/* Pantalla completa (tecla Z / botón): la vista cubre toda la ventana; solo queda una barrita con el botón para salir, la lista de
   propietarios y los movimientos. */
.panel-mov.panel-mov--pantalla { position: fixed; inset: 0; z-index: 70; margin: 0; padding: 8px 14px 14px; max-width: none; background: var(--fondo); overflow: auto; }
.panel-mov--pantalla > .panel-frag__lead, .panel-mov--pantalla > .panel-frag__cabecera h2 { display: none; }
.panel-mov--pantalla > .panel-frag__cabecera { justify-content: flex-end; margin-bottom: 0; }
.panel-mov--pantalla .panel-mov-layout { margin-top: 6px; }
.panel-mov--pantalla .panel-mov-lista { max-height: calc(100vh - 150px); }
[data-mov-pantalla-btn][aria-pressed="true"] { background: var(--azul); color: #fff; border-color: var(--azul); }
[data-mov-pantalla-btn] kbd { font: inherit; font-size: .75em; padding: 0 5px; margin-left: 4px; border: 1px solid currentColor; border-radius: 4px; opacity: .75; }
/* Al colapsar la lista (botón ‹/›), el panel deja de reservar 260px —
   la tabla dinámica (columnas de grupo variables) pasa a usar casi todo
   el ancho, que era la intención original del botón. */
.panel-mov-layout:has(.panel-mov-lateral--colapsada) { grid-template-columns: 52px 1fr; }
.panel-mov-lateral {
  position: relative;
  background: var(--papel);
  border: 1px solid var(--linea);
  border-radius: var(--radio);
  padding: 14px;
  min-width: 0;
}
.panel-mov-lateral--colapsada { padding: 14px 8px; }
.panel-mov-lateral--colapsada .panel-mov-lateral__cuerpo { display: none; }
.panel-mov-lateral__colapsar {
  border: 1px solid var(--linea);
  background: var(--fondo);
  border-radius: 50%;
  width: 26px;
  height: 26px;
  line-height: 1;
  cursor: pointer;
  color: var(--gris);
  margin-bottom: 10px;
}
.panel-mov-lateral--colapsada .panel-mov-lateral__colapsar { transform: rotate(180deg); }
.panel-mov-buscador { display: flex; flex-direction: column; gap: 8px; margin-bottom: 10px; }
/* El <select> del buscador vivía sin ninguna de las reglas de
   .panel-campo select (se veía "plano y cuadrado", según el usuario) —
   mismo tratamiento visual (flecha propia, radio, foco) que el resto de
   selects del panel. */
.panel-mov-select {
  width: 100%;
  border: 1px solid var(--linea);
  border-radius: var(--radio-chico);
  padding: 9px 32px 9px 12px;
  font-size: .88rem;
  color: var(--tinta);
  background-color: var(--papel);
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2364748b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 10px center;
  background-size: 16px;
}
.panel-mov-select:focus { outline: 2px solid var(--azul); outline-offset: 1px; }
.panel-mov-lista { list-style: none; margin: 0; padding: 0; max-height: 60vh; overflow-y: auto; }
.panel-mov-lista__item {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 1px;
  width: 100%;
  text-align: left;
  border: none;
  background: none;
  border-radius: var(--radio-chico);
  padding: 7px 9px;
  cursor: pointer;
  font-size: .82rem;
}
.panel-mov-lista__item:hover { background: var(--fondo); }
.panel-mov-lista__item.is-activo { background: var(--info-fondo); }
.panel-mov-lista__apto { font-weight: 600; color: var(--tinta); }
.panel-mov-lista__torre { color: var(--gris); font-size: .78rem; }
.panel-mov-lista__nombre { color: var(--gris); font-size: .78rem; }

.panel-mov-principal { min-width: 0; }
.panel-mov-cabecera { margin-bottom: 12px; }
.panel-mov-enlaces { display: flex; gap: 8px; margin-top: 8px; flex-wrap: wrap; }
/* "Reportes": desplegable nativo (<details>) que agrupa Detalle de cartera y Movimientos. */
.panel-mov-reportes { position: relative; }
.panel-mov-reportes > summary { list-style: none; cursor: pointer; display: inline-flex; align-items: center; gap: 6px; }
.panel-mov-reportes > summary::-webkit-details-marker { display: none; }
.panel-mov-reportes > summary svg { width: 15px; height: 15px; }
/* El ícono "flecha" apunta a la derecha: hacia abajo cerrado, hacia arriba abierto. */
.panel-mov-reportes > summary svg:last-child { transform: rotate(90deg); }
.panel-mov-reportes[open] > summary svg:last-child { transform: rotate(-90deg); }
.panel-mov-reportes__lista {
  position: absolute; z-index: 6; top: calc(100% + 4px); left: 0; min-width: 190px;
  display: flex; flex-direction: column; padding: 6px;
  background: var(--papel); border: 1px solid var(--linea); border-radius: var(--radio-chico);
  box-shadow: 0 6px 18px rgba(15, 23, 42, .12);
}
.panel-mov-reportes__lista button {
  text-align: left; background: none; border: 0; padding: 8px 10px; border-radius: 6px;
  font: inherit; color: var(--azul); cursor: pointer;
}
.panel-mov-reportes__lista button:hover { background: var(--fondo); }
/* El select "Opciones" (responsive) y sus contrapartes ("Año consultado")
   solo se muestran en pantalla angosta — ver el media query 860px más
   abajo, junto al resto del responsive de Movimientos. */
.panel-mov-enlaces-select { display: none; margin-top: 8px; }

.panel-mov-incrustado__barra { margin-bottom: 12px; }

.panel-mov-cartera-periodo { display: flex; align-items: flex-end; gap: 10px; flex-wrap: wrap; margin-bottom: 14px; }
.panel-mov-cartera-periodo__hasta { color: var(--gris); padding-bottom: 9px; }
.panel-mov-cartera-columnas { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; margin-bottom: 14px; }
.panel-mov-cartera-col { display: block; font-size: .85rem; padding: 2px 0; }
.panel-mov-cartera-acciones { display: flex; gap: 8px; }
@media (max-width: 640px) {
  .panel-mov-cartera-columnas { grid-template-columns: 1fr; }
}
.panel-mov-anos { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 12px; font-size: .85rem; color: var(--gris); }
.panel-mov-anos__chips { display: flex; gap: 8px; flex-wrap: wrap; }
.panel-mov-anos__select { display: none; max-width: 140px; }

.panel-mov-tabla-envoltorio { overflow-x: auto; }
.panel-mov-tabla th, .panel-mov-tabla td { white-space: nowrap; text-align: right; }
.panel-mov-tabla th:first-child, .panel-mov-tabla td:first-child { text-align: left; }
.panel-mov-tabla .panel-mov-fila-cierre td { font-style: italic; color: var(--gris); text-align: right; }
.panel-mov-tabla .panel-mov-fila-cierre td:first-child { text-align: left; }
.panel-mov-tabla .panel-mov-fila-total td { font-weight: 700; border-top: 2px solid var(--linea); }
/* "Que la fila alumbre al pasar por encima, para saber en qué fila
   estoy" — azul clarito (--info-fondo), no tan fuerte como para tapar
   el verde de un saldo a favor debajo. */
.panel-mov-tabla tbody tr:hover td { background: var(--info-fondo); }
.panel-mov-valor {
  border: none;
  background: none;
  color: var(--azul);
  cursor: pointer;
  font: inherit;
  padding: 0;
}
.panel-mov-valor:hover { text-decoration: underline; }
.panel-mov-valor--fuerte { font-weight: 600; }
/* Saldo negativo = saldo a favor del apto: verde, no rojo (pedido explícito del usuario, 2026-10). La clase conserva su nombre. */
.panel-mov-negativo { color: var(--ok); background: var(--ok-fondo); font-weight: 600; }
.panel-mov-nota { color: var(--gris); font-size: .8rem; margin-top: 10px; }

/* Resumen anual (Saldo al cierre / Facturación acumulada / ... / Valor a
   pagar / Total pagos anticipados) — misma referencia visual que pidió
   el usuario (captura de ScriptCase), con los estilos propios del panel. */
/* Recuadro blanco tipo tabla, ABAJO de los movimientos (pedido explícito
   del usuario) — mismo criterio visual que .panel-tabla-envoltorio, para
   que se sienta parte de la misma familia de componentes, no una caja
   suelta transparente como antes. */
.panel-mov-resumen {
  margin: 18px 0 4px;
  overflow-x: auto;
  background: var(--papel);
  border: 1px solid var(--linea);
  border-radius: var(--radio);
}
.panel-mov-resumen table { border-collapse: collapse; font-size: .88rem; width: 100%; }
.panel-mov-resumen td { padding: 8px 14px; border-bottom: 1px solid var(--linea); }
.panel-mov-resumen tr:last-child td { border-bottom: none; }
.panel-mov-resumen__lbl { color: var(--gris); white-space: nowrap; }
.panel-mov-resumen__val { text-align: right; font-weight: 600; white-space: nowrap; padding-left: 24px; }
.panel-mov-resumen__fuerte td { background: var(--info-fondo); font-weight: 700; }
/* Ícono "ver detalle" en vez del texto "Detalle de..." — el title (tooltip
   nativo) es lo que hoy dice "Ver detalle de facturación", etc. */
.panel-mov-resumen__ver {
  border: none;
  background: none;
  color: var(--azul);
  cursor: pointer;
  padding: 4px;
  display: flex;
  border-radius: var(--radio-chico);
}
.panel-mov-resumen__ver svg { width: 16px; height: 16px; }
.panel-mov-resumen__ver:hover { background: var(--fondo); }

/* Tarjeta de recibo (pago / nota crédito) en los modales de detalle, en
   modo lista — franja de cabecera + tabla del cruce discriminado debajo,
   mismo espíritu que la vista de ScriptCase anexada, con la paleta del
   panel en vez de la suya. */
.panel-mov-recibo { border: 1px solid var(--linea); border-radius: var(--radio-chico); margin-bottom: 14px; overflow: hidden; }
.panel-mov-recibo:last-child { margin-bottom: 0; }
.panel-mov-recibo__cabecera {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 10px 14px;
  background: var(--fondo);
  border-bottom: 1px solid var(--linea);
  font-size: .85rem;
  color: var(--gris);
  flex-wrap: wrap;
}
.panel-mov-recibo__icono { color: var(--azul); display: flex; }
.panel-mov-recibo__icono svg { width: 18px; height: 18px; }
.panel-mov-recibo__num { font-weight: 700; color: var(--tinta); }
.panel-mov-recibo__valor { font-weight: 700; color: var(--azul); margin-left: auto; }
/* Botón 🖨 "Imprimir recibo en PDF" — en la cabecera de la tarjeta
   (pagos/NC) y también suelto en una celda de tabla (ND, una fila = un
   documento, sin tarjeta). Deshabilitado (permiso visible, ver CLAUDE.md)
   se pinta más tenue en vez de esconderse. */
.panel-mov-recibo__imprimir {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border-radius: var(--radio-chico);
  color: var(--azul);
  flex-shrink: 0;
}
.panel-mov-recibo__imprimir svg { width: 16px; height: 16px; }
a.panel-mov-recibo__imprimir:hover { background: var(--info-fondo); }
.panel-mov-recibo__imprimir.is-deshabilitado { color: var(--linea); cursor: not-allowed; }
.panel-mov-recibo table { margin: 0; }
.panel-mov-recibo table th, .panel-mov-recibo table td { border-bottom: 1px solid var(--linea); }

/* Botón "Anular" (icono) junto al de imprimir — mismo tamaño, color de aviso. */
.panel-mov-recibo__anular {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border-radius: var(--radio-chico);
  color: var(--error);
  flex-shrink: 0;
  background: none;
  border: none;
  cursor: pointer;
}
.panel-mov-recibo__anular svg { width: 16px; height: 16px; }
.panel-mov-recibo__anular:hover { background: var(--info-fondo); }

/* Marca de "este documento fue anulado" dentro de la tarjeta del recibo. */
.panel-mov-recibo p.panel-vacio-linea { margin: 10px 14px; }
.panel-mov-anulado {
  padding: 8px 14px;
  font-size: .82rem;
  color: var(--error);
  background: var(--error-fondo);
  border-left: 3px solid var(--error);
}
.panel-mov-anulado__motivo { margin-top: 2px; color: var(--tinta); }
/* Fila de un documento anulado dentro de las tablas de detalle (Total/ND). */
.panel-mov-fila-anulada td { color: var(--gris); text-decoration: line-through; }
.panel-mov-fila-anulada td:last-child { text-decoration: none; }
.panel-mov-fila-anulada-motivo td { padding: 0; }
/* Chip "⊘ N" en la matriz: hay N documentos anulados en ese mes/columna. */
.panel-mov-anulado-chip {
  margin-left: 6px;
  padding: 1px 6px;
  font-size: .72rem;
  color: var(--error);
  background: none;
  border: 1px solid var(--error);
  border-radius: 10px;
  cursor: pointer;
}
.panel-mov-anulado-chip:hover { background: var(--info-fondo); }
/* "Datos del pago" / "Detalle del cruce" — dos tablas dentro de la misma
   tarjeta, cada una con su propio título para que no se confundan (pedido
   explícito del usuario: la info del pago en sí, no solo el cruce). */
.panel-mov-recibo__seccion {
  padding: 8px 14px 4px;
  font-size: .74rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .03em;
  color: var(--gris);
  background: var(--fondo);
}
.panel-mov-recibo__seccion:first-of-type { padding-top: 10px; }

/* "Detalle del cruce" arranca cerrado (pedido explícito del usuario,
   2026-08-21) — <details> nativo, mismo espíritu que .menu-grupo del menú
   lateral pero con la tipografía de .panel-mov-recibo__seccion. */
.panel-mov-recibo__cruce summary {
  display: flex;
  align-items: center;
  cursor: pointer;
  list-style: none;
}
.panel-mov-recibo__cruce summary::-webkit-details-marker { display: none; }
.panel-mov-recibo__flecha { display: flex; margin-left: auto; color: var(--gris); flex: none; transition: transform .15s ease; }
.panel-mov-recibo__flecha svg { width: 14px; height: 14px; }
.panel-mov-recibo__cruce[open] > summary .panel-mov-recibo__flecha { transform: rotate(180deg); }

/* Sub-título dentro del desplegable "Columnas" cuando hay más de un grupo
   de columnas (pagos/NC: "Datos del pago" + "Detalle del cruce"). */
.panel-columnas__grupo-titulo {
  font-size: .74rem;
  font-weight: 700;
  text-transform: uppercase;
  color: var(--gris);
  margin: 8px 0 2px;
  padding-top: 6px;
  border-top: 1px solid var(--linea);
}
.panel-columnas__grupo-titulo:first-child { margin-top: 0; padding-top: 0; border-top: none; }

/* Barra "Columnas / Exportar" arriba de una tabla de detalle dentro del
   modal (facturación/ND/NC/pagos) — el selector de columnas es el mismo
   .panel-columnas de Propietarios, reusado tal cual. */
.panel-mov-detalle-herramientas { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; margin-bottom: 4px; flex-wrap: wrap; }
.panel-mov-detalle-herramientas .panel-columnas { margin: 0; }
.panel-mov-detalle-herramientas .panel-exportar { margin: 0; }

@media (max-width: 860px) {
  .panel-mov-layout { grid-template-columns: 1fr; }
  .panel-mov-lateral { order: -1; }

  /* "Opciones" (Certificados/Servicios asignados/etc.) y "Año consultado"
     pasan de una fila de botones a un <select> — ahorra espacio vertical
     en pantalla angosta (pedido explícito del usuario). */
  .panel-mov-enlaces { display: none; }
  .panel-mov-enlaces-select { display: block; }
  .panel-mov-anos__chips { display: none; }
  .panel-mov-anos__select { display: block; }

  /* El panel de la izquierda (buscador de apto) se vuelve SOLO buscador:
     no muestra ningún apto hasta que se escribe algo — evita que la lista
     completa (hasta 80 filas) ocupe toda la pantalla antes de la tabla de
     movimientos, que es lo que de verdad se vino a consultar. En cuanto el
     input deja de estar vacío (:not(:placeholder-shown)) la lista
     reaparece con los resultados filtrados, sin JS adicional. */
  .panel-mov-lista { display: none; }
  .panel-mov-buscador:has(input:not(:placeholder-shown)) ~ .panel-mov-lista { display: block; }
}

/* Facturación (módulo nuevo) — dashboard con ÁREAS de grid (mockup del
   usuario, 2026-08-25):
     previa   | generar
     errores  | detalle
   Con grid-template-areas, "previa"/"generar" quedan de la MISMA altura
   automáticamente (align-items:stretch, default de grid) sin fijar un alto
   a mano — igual "errores" (la suma de las 3 cajas de error) y "detalle".
   Se apila a 1 columna en pantalla angosta. */
.panel-fact-columnas {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-areas:
    "previa generar"
    "errores detalle";
  gap: 18px;
  margin-top: 18px;
}
.panel-fact-area-previa { grid-area: previa; }
.panel-fact-area-generar { grid-area: generar; }
.panel-fact-area-errores { grid-area: errores; display: flex; flex-direction: column; gap: 18px; }
.panel-fact-area-detalle { grid-area: detalle; }
/* Gotcha real de CSS Grid/Flex (ya documentado en administracionunidades…/
   CLAUDE.md §2.5 para .panel-cert-generar-grid): un ítem de grid o flex NO
   se achica por debajo del ancho de su contenido más ancho — acá, una
   tabla — a menos que tenga min-width:0 explícito. Sin esto, en pantalla
   angosta la tabla de detalle/errores reventaba el ancho de TODO
   ".panel-fact-columnas" en vez de quedar contenida por el
   overflow-x:auto de .panel-tabla-envoltorio (verificado: 604px de ancho
   real con un viewport de 375px). */
.panel-fact-columnas > *,
.panel-fact-area-errores > * { min-width: 0; }
@media (max-width: 900px) {
  .panel-fact-columnas {
    grid-template-columns: 1fr;
    grid-template-areas: "previa" "generar" "errores" "detalle";
  }
}

/* Mismo lenguaje visual que .panel-card, pero pensadas para contener
   formularios y tablas completas, no solo una cifra suelta. */
.panel-fact-caja {
  background: var(--papel);
  border: 1px solid var(--linea);
  border-radius: var(--radio);
  padding: 20px 22px;
}
.panel-fact-caja h3 { margin: 0 0 14px; font-size: 1rem; }

/* Cajas de error (2026-08-25, pedido explícito del usuario): SIEMPRE
   visibles, con "No hay errores." cuando no hay filas — nunca se ocultan
   por completo, para que el layout no salte de tamaño. Altura uniforme
   (300px) con scroll propio en la tabla; el rojo solo aparece cuando SÍ
   hay algo que corregir (.panel-fact-caja--con-error, la agrega JS). */
.panel-fact-caja--errores {
  display: flex;
  flex-direction: column;
  height: 300px;
}
.panel-fact-caja--errores .panel-tabla-envoltorio { flex: 1; overflow-y: auto; }
.panel-fact-caja--con-error { border-color: var(--error); }
.panel-fact-caja--con-error h3 { color: var(--error); }

/* El detalle y "Generar facturación" ya no necesitan un alto fijo a mano —
   al ser items de la misma fila de grid que "errores"/"previa", se estiran
   solos a la altura de esa fila (align-items:stretch). display:flex acá es
   para que su contenido interno (tabla con scroll propio) sí aproveche esa
   altura completa. */
.panel-fact-area-generar,
.panel-fact-caja--detalle {
  display: flex;
  flex-direction: column;
  height: 100%;
}
.panel-fact-caja--detalle [data-fact-detalle-cuerpo] { display: flex; flex-direction: column; flex: 1; min-height: 0; }
.panel-fact-caja--detalle .panel-tabla-envoltorio { flex: 1; overflow-y: auto; }

.panel-fact-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 14px;
  margin-bottom: 16px;
}
.panel-fact-grid .panel-campo p { margin: 4px 0 0; font-weight: 600; }

/* Las 5 tarjetas de "Facturación previa" SIEMPRE en una sola línea (pedido
   explícito del usuario, con mockup) — columnas fijas, no auto-fit, para
   que nunca se acomoden en 2-3 filas aunque la columna quede angosta. */
.panel-fact-previa-cards {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 10px;
  margin-top: 18px;
  margin-bottom: 16px;
}
.panel-fact-previa-cards .panel-card { min-width: 0; padding: 14px 10px; text-align: center; }
.panel-fact-previa-cards .panel-card h3 { justify-content: center; }
@media (max-width: 640px) {
  .panel-fact-previa-cards { grid-template-columns: repeat(2, 1fr); }
}

/* Mismo gotcha ya documentado más arriba (.panel-mov-layout[hidden]): un
   botón (.panel-boton, display:inline-flex) y el spinner reusado
   (.tab-panel--cargando, display:flex) le ganan a [hidden] por especificidad
   empatada + orden de cascada — sin esto, "Facturar mes" y el spinner de
   "Facturando el mes..." se ven los DOS a la vez aunque JS ya haya puesto
   hidden=true en el que no toca. */
[data-fact-boton-facturar][hidden],
[data-fact-spinner][hidden],
[data-fact-gen-cuerpo][hidden],
[data-fact-detalle-cuerpo][hidden] { display: none; }

/* Mismo gotcha otra vez, en Reportes: los bloques de filtro "mes"/"fecha"
   (vistas/reporte_*.php) llevan `style="display:flex; gap:12px"` inline
   para poner sus campos en fila. La primera corrección acá (sin
   !important) NO alcanzaba: un estilo INLINE en el mismo elemento le gana
   SIEMPRE a cualquier regla de hoja de estilos externa, sin importar la
   especificidad del selector — a diferencia del gotcha "clásico" de este
   panel (.panel-mov-layout[hidden], etc.), que es un empate de
   especificidad entre dos reglas de hoja de estilos (ahí sí gana la que
   viene después en el archivo). Un estilo inline solo se puede vencer con
   `!important` en la regla externa. Verificado en vivo (navegador real,
   sesión logueada): sin `!important` el bloque "fecha" seguía visible en
   pantalla aunque `hidden` estuviera puesto y esta regla ya existiera. */
[data-rep-bloque][hidden] { display: none !important; }

/* Fila de totales de Reportes (<tfoot data-totales>, ver urbTablaTotalizar
   en panel.js) — mismo fondo que el encabezado azul de la tabla pero con el
   texto oscuro, para que se lea como cierre de la tabla, no como una fila
   de datos más. */
.panel-tabla tfoot[data-totales] td { font-weight: 600; background: var(--fondo); border-top: 2px solid var(--linea); }

/* Facturación de intereses (Fase 2): 3 tarjetas apiladas, una por caso
   (nuevo / facturado de menos / facturado de más) — a diferencia de Fase 1
   no hay un layout de 2 columnas por áreas (no hay "previa"/"generar" que
   igualar en altura), así que es una pila simple, no un grid-template-areas
   nuevo. Reusa .panel-fact-caja para el mismo lenguaje visual de caja. */
.panel-int-columnas {
  display: flex;
  flex-direction: column;
  gap: 18px;
  margin-top: 18px;
}

/* Config. intereses (2026-08-26, pedido explícito del usuario): el formulario
   + Historial de tasas a la izquierda, Excepciones a la derecha, ambas
   columnas a la par — reemplaza el layout de una sola columna angosta
   (.panel-frag--angosto) que forzaba todo a apilarse en el centro. */
.panel-int-config-columnas {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 24px;
  align-items: start;
  margin-top: 18px;
}
.panel-int-config-col { display: flex; flex-direction: column; gap: 20px; min-width: 0; }
.panel-int-config-col .panel-form { margin-top: 0; }
@media (max-width: 900px) {
  .panel-int-config-columnas { grid-template-columns: 1fr; }
}
/* Mismo gotcha de [hidden] vs. display: explícito (ver arriba) — el spinner
   reusado de esta fase tiene su propio atributo, data-int-spinner. */
[data-int-spinner][hidden] { display: none; }

/* Tarjetas de intereses como <details> — inician cerradas (pedido explícito
   del usuario, 2026-08-26): solo título + flecha visibles hasta que el
   operador decide abrir una. Padding se mueve del <details> (que lo aplicaría
   también al <summary>, agrandando la barra colapsada sin necesidad) al
   <summary> y al cuerpo por separado. */
.panel-fact-caja--colapsable { padding: 0; }
.panel-fact-caja--colapsable > summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 16px 22px;
  cursor: pointer;
  list-style: none;
}
.panel-fact-caja--colapsable > summary::-webkit-details-marker,
.panel-fact-caja--colapsable > summary::marker { display: none; content: ''; }
.panel-fact-caja--colapsable > summary h3 { margin: 0; }
.panel-fact-caja--colapsable > summary .panel-fact-caja__flecha {
  display: inline-flex;
  flex-shrink: 0;
  color: var(--gris);
  transition: transform .15s ease;
}
.panel-fact-caja--colapsable[open] > summary .panel-fact-caja__flecha { transform: rotate(180deg); }
.panel-fact-caja--colapsable[open] > summary { border-bottom: 1px solid var(--linea); }
.panel-fact-caja--colapsable > .panel-fact-caja__cuerpo { padding: 18px 22px 20px; }

/* Importadores (Facturación, Fase 3): selector de tipo + banner con el
   color del tipo activo — MISMOS colores que ya identifican cada documento
   en los recibos PDF (lib/recibos_pdf.php:urb_recibo_variante()), para que
   "verde = pago", "naranja = ND", etc. sea un lenguaje visual consistente
   en todo el panel, no un color nuevo inventado acá. */
.panel-imp-selector { display: flex; flex-wrap: wrap; gap: 10px; margin: 16px 0; }
.panel-imp-boton-tipo {
  padding: 10px 18px;
  border-radius: var(--radio-chico);
  border: 2px solid var(--linea);
  background: var(--papel);
  font-weight: 600;
  cursor: pointer;
  color: var(--tinta);
}
.panel-imp-boton-tipo--verde.is-activo   { border-color: rgb(22, 163, 74);  background: rgb(22, 163, 74);  color: #fff; }
.panel-imp-boton-tipo--azul.is-activo    { border-color: var(--azul);       background: var(--azul);       color: #fff; }
.panel-imp-boton-tipo--naranja.is-activo { border-color: rgb(217, 119, 6);  background: rgb(217, 119, 6);  color: #fff; }
.panel-imp-boton-tipo--morado.is-activo  { border-color: rgb(30, 64, 175);  background: rgb(30, 64, 175);  color: #fff; }
.panel-imp-boton-tipo--gris.is-activo    { border-color: var(--gris);       background: var(--gris);       color: #fff; }

.panel-imp-banner {
  padding: 12px 18px;
  border-radius: var(--radio);
  color: #fff;
  font-weight: 600;
  margin-bottom: 16px;
}
.panel-imp-banner h3 { margin: 0; color: #fff; }
.panel-imp-banner--verde   { background: rgb(22, 163, 74); }
.panel-imp-banner--azul    { background: var(--azul); }
.panel-imp-banner--naranja { background: rgb(217, 119, 6); }
.panel-imp-banner--morado  { background: rgb(30, 64, 175); }
.panel-imp-banner--gris    { background: var(--gris); }

.panel-imp-acciones-masivas { display: flex; flex-wrap: wrap; gap: 10px; margin: 12px 0; }

/* Pie de "2. Revisar y procesar" (Datos iniciales/Importadores, 2026-09):
   "Eliminar archivo importado" y "Procesar archivo plano" van SIEMPRE
   juntos al final, alineados a la derecha — antes "Eliminar" quedaba
   arriba (repetido en cada pestaña Sin novedades/Alertas/Errores) y
   "Procesar" abajo, sueltos y sin relación visual entre sí. Pedido
   explícito del usuario. */
.panel-imp-acciones-pie { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 10px; margin-top: 16px; }

/* Contabilidad · Recibos generales — grupo de checkboxes/radios en fila,
   reusable para cualquier formulario con "elige uno o varios". */
.panel-checklist { display: flex; flex-wrap: wrap; gap: 6px 18px; }
.panel-checklist__item {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: .9rem;
  color: var(--tinta);
  font-weight: 400;
}

/* Config. global · Esquema de unidades — matriz unidad × migrador. */
.panel-esquema-acciones { display: flex; align-items: center; gap: 14px; margin: 4px 0 16px; flex-wrap: wrap; }
.panel-esquema-progreso { font-size: .85rem; color: var(--gris); }
.panel-esquema-referencia { display: flex; align-items: center; gap: 8px; font-size: .85rem; color: var(--gris); }
.panel-esquema-referencia select { border: 1px solid var(--linea); border-radius: var(--radio-chico); padding: 6px 10px; font-size: .85rem; color: var(--tinta); background: var(--papel); }
.panel-esquema-tabla th, .panel-esquema-tabla td { white-space: nowrap; }
.panel-esquema-estado {
  display: inline-block;
  padding: 3px 10px;
  border-radius: 999px;
  font-size: .78rem;
  font-weight: 500;
  border: none;
}
.panel-esquema-estado--sin-diagnostico { background: var(--fondo); color: var(--gris); }
.panel-esquema-estado--diagnosticando { background: var(--fondo); color: var(--gris); }
.panel-esquema-estado--al_dia { background: #dcfce7; color: #166534; }
.panel-esquema-estado--no_aplica { background: var(--fondo); color: var(--gris); }
.panel-esquema-estado--error { background: #fee2e2; color: #991b1b; }
button.panel-esquema-estado--pendiente {
  background: #fef3c7;
  color: #92400e;
  cursor: pointer;
}
button.panel-esquema-estado--pendiente:hover { background: #fde68a; }
.panel-esquema-salida {
  white-space: pre-wrap;
  font-family: ui-monospace, Consolas, monospace;
  font-size: .8rem;
  max-height: 60vh;
  overflow-y: auto;
  background: var(--fondo);
  border: 1px solid var(--linea);
  border-radius: var(--radio-chico);
  padding: 12px;
}
.panel-checklist__item input { width: auto; }

/* ==========================================================================
   Conciliación bancaria (vistas/conciliacion.php, assets/js/conciliacion.js)
   Hoja tipo Excel: encabezado fijo, fila seleccionada, edición en la celda,
   panel de detalle a la derecha y barra de cuadre pegada abajo.
   ========================================================================== */
.conc { --conc-sel: #d6e8f6; --conc-aviso: #9a6200; --conc-aviso-fondo: #fff4dc; --conc-transito: #6b3fa0; --conc-transito-fondo: #f1eafa; }
.conc-subtitulo { font-size: 1rem; margin: 22px 0 8px; }
.conc-acciones { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.conc-meta { display: flex; flex-wrap: wrap; gap: 6px 18px; align-items: center; font-size: .85rem; color: var(--gris); margin: 4px 0 10px; }
.conc-meta b { color: var(--tinta); font-weight: 500; }
.conc-carga__lista { display: flex; flex-wrap: wrap; gap: 6px; }
.conc-archivo { font-size: .78rem; padding: 3px 9px; border-radius: 999px; background: var(--fondo); border: 1px solid var(--linea); }
.conc-archivo b { font-weight: 600; margin-right: 4px; }
.conc-archivo--extracto b { color: var(--azul); }
.conc-archivo--recaudos b { color: var(--ok); }
.conc-archivo--avalpay b { color: var(--conc-transito); }
.conc-archivo--otro b { color: var(--error); }

.conc-controles { list-style: none; margin: 0 0 12px; padding: 0; display: flex; flex-wrap: wrap; gap: 6px; }
.conc-controles li { font-size: .78rem; padding: 4px 10px; border-radius: var(--radio-chico); background: var(--papel); border: 1px solid var(--linea); display: inline-flex; gap: 6px; align-items: center; }
.conc-controles li::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: var(--gris); flex: none; }
.conc-controles li.ok::before { background: var(--ok); }
.conc-controles li.aviso::before { background: var(--conc-aviso); }
.conc-controles li.error::before { background: var(--error); }

.conc-cifras { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 10px; margin-bottom: 14px; }
.conc-cifra { background: var(--papel); border: 1px solid var(--linea); border-radius: 8px; padding: 9px 12px; display: grid; gap: 1px; }
.conc-cifra span { font-size: .7rem; color: var(--gris); text-transform: uppercase; letter-spacing: .04em; }
.conc-cifra strong { font-weight: 600; font-size: 1rem; font-variant-numeric: tabular-nums; }
.conc-cifra small { font-size: .72rem; color: var(--gris); }
.conc-cifra--clave { border-color: var(--azul); }

.conc-barra { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: 8px; background: var(--papel); border: 1px solid var(--linea); border-bottom: none; border-radius: 8px 8px 0 0; padding: 8px 10px; }
.conc-tabs { display: flex; flex-wrap: wrap; gap: 2px; }
.conc-tabs button { font: inherit; font-size: .82rem; border: 0; background: transparent; color: var(--gris); padding: 6px 11px; border-radius: 6px; cursor: pointer; }
.conc-tabs button span { font-size: .72rem; margin-left: 5px; opacity: .8; font-variant-numeric: tabular-nums; }
.conc-tabs button[aria-selected="true"] { background: var(--info-fondo); color: var(--azul); font-weight: 600; }
.conc-herramientas { display: flex; flex-wrap: wrap; gap: 6px; }

.conc section[data-conc-panel] { background: var(--papel); border: 1px solid var(--linea); border-radius: 0 0 8px 8px; padding: 10px; }
.conc-filtros { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 8px; margin-bottom: 8px; }
.conc-chips { display: flex; flex-wrap: wrap; gap: 4px; }
.conc-chip { font: inherit; font-size: .78rem; padding: 4px 10px; border-radius: 999px; border: 1px solid var(--linea); background: var(--papel); color: var(--tinta); cursor: pointer; }
.conc-chip span { font-variant-numeric: tabular-nums; color: var(--gris); margin-left: 3px; }
.conc-chip.is-on { background: var(--azul); border-color: var(--azul); color: #fff; }
.conc-chip.is-on span { color: #d8ecfa; }
.conc-buscar { font: inherit; font-size: .82rem; padding: 5px 10px; border: 1px solid var(--linea); border-radius: 6px; width: 260px; max-width: 100%; }

.conc-trabajo { display: grid; grid-template-columns: minmax(0, 1fr); gap: 10px; align-items: start; }
.conc-trabajo.con-detalle { grid-template-columns: minmax(0, 1fr) 360px; }
@media (max-width: 1100px) { .conc-trabajo.con-detalle { grid-template-columns: 1fr; } }
.conc-barra { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; }
.conc-barra .conc-totales { flex: 1 1 auto; min-width: 0; }
.conc-btn-detalle kbd { font: inherit; font-size: .7rem; border: 1px solid var(--linea); border-radius: 3px; padding: 0 4px; margin-left: 4px; background: var(--papel); }
.conc-hoja { overflow: auto; max-height: 62vh; border: 1px solid var(--linea); border-radius: 6px; outline: none; }
.conc-hoja:focus-visible { box-shadow: 0 0 0 2px var(--celeste); }
.conc-grilla { border-collapse: collapse; width: 100%; min-width: 1120px; font-size: .78rem; }
.conc-grilla thead th { position: sticky; top: 0; z-index: 1; background: #eaf0f5; text-align: left; font-weight: 600; font-size: .7rem; text-transform: uppercase; letter-spacing: .03em; color: var(--gris); padding: 6px 8px; border-right: 1px solid var(--linea); border-bottom: 1px solid var(--linea); white-space: nowrap; }
.conc-grilla td { padding: 4px 8px; border-right: 1px solid var(--linea); border-bottom: 1px solid var(--linea); white-space: nowrap; cursor: default; }
.conc-grilla tbody tr:hover td { background: #f6f9fc; }
.conc-grilla tr.is-sel td { background: var(--conc-sel); }
.conc-grilla tr.is-cambio td { background: #e6f5ec; }
.conc-n { text-align: right; font-size: .7rem; width: 38px; color: var(--gris); white-space: nowrap; }
.conc-n input[type=checkbox] { vertical-align: middle; margin: 0 4px 0 0; cursor: pointer; }
.conc-lote { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; padding: 8px 10px; background: var(--info-fondo); border: 1px solid var(--linea); border-top: none; font-size: .82rem; }
.conc-lote[hidden] { display: none; }
.conc-grilla tr.is-marca td { background: #fff6d6; }
.conc-grilla td.conc-n { background: #eef3f7; }
.conc-num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.conc-desc { max-width: 280px; overflow: hidden; text-overflow: ellipsis; }
.conc-apto { font-weight: 600; cursor: text; border-bottom: 1px dashed transparent; }
.conc-grilla tr.is-sel .conc-apto { border-bottom-color: var(--azul); }
.conc-metodo { max-width: 300px; overflow: hidden; text-overflow: ellipsis; color: var(--gris); }
.conc-celda-input { width: 90px; font: inherit; font-weight: 600; padding: 1px 4px; border: 1px solid var(--azul); border-radius: 3px; }
.conc-conf { display: inline-block; width: 8px; height: 8px; border-radius: 50%; margin-right: 6px; background: var(--linea); vertical-align: middle; }
.conc-conf--alta { background: var(--ok); }
.conc-conf--media { background: #e0a100; }
.conc-conf--baja { background: #e56b1f; }
.conc-conf--ninguna { background: var(--error); }
.conc-conf--manual { background: var(--azul); }
.conc-vacio { padding: 18px; text-align: center; color: var(--gris); }

.conc-pill { display: inline-block; font-size: .7rem; padding: 1px 8px; border-radius: 999px; background: var(--fondo); color: var(--gris); white-space: nowrap; }
.conc-pill--ok, .conc-pill--conciliado, .conc-pill--importada { background: var(--ok-fondo); color: var(--ok); }
.conc-pill--revisar, .conc-pill--borrador, .conc-pill--montado { background: var(--conc-aviso-fondo); color: var(--conc-aviso); }
.conc-pill--pendiente, .conc-pill--descuadre { background: var(--error-fondo); color: var(--error); }
.conc-pill--transito { background: var(--conc-transito-fondo); color: var(--conc-transito); }
.conc-pill--otro, .conc-pill--egreso { background: var(--fondo); color: var(--gris); }

.conc-detalle { background: var(--papel); border: 1px solid var(--linea); border-radius: 6px; padding: 12px; font-size: .8rem; position: sticky; top: 0; max-height: 62vh; overflow: auto; }
.conc-detalle h4 { font-size: .74rem; text-transform: uppercase; letter-spacing: .04em; color: var(--gris); margin: 12px 0 6px; }
.conc-detalle h4:first-child { margin-top: 0; }
.conc-detalle dl { display: grid; grid-template-columns: auto 1fr; gap: 3px 10px; margin: 0; }
.conc-detalle dt { color: var(--gris); }
.conc-detalle dd { margin: 0; overflow-wrap: anywhere; }
.conc-detalle__vacio { color: var(--gris); margin: 0; }
.conc-cands { list-style: none; margin: 0; padding: 0; display: grid; gap: 5px; }
.conc-cands li { display: grid; grid-template-columns: 58px 1fr auto; gap: 8px; align-items: center; padding: 6px 8px; border: 1px solid var(--linea); border-radius: 6px; }
.conc-cands li small { color: var(--gris); }
.conc-cands li.is-coincide { border-color: var(--ok); }
.conc-cands li.is-actual { background: var(--info-fondo); }
.conc-editar { display: flex; gap: 6px; }
.conc-editar input { flex: 1; min-width: 0; font: inherit; padding: 5px 8px; border: 1px solid var(--linea); border-radius: 6px; }
.conc-verif { display: block; margin-top: 4px; min-height: 1em; color: var(--gris); }
.conc-verif.ok { color: var(--ok); }
.conc-verif.error { color: var(--error); }
.conc-check { display: flex; gap: 6px; align-items: flex-start; margin-top: 6px; }
.conc-botones { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
.conc-ayuda { font-size: .76rem; color: var(--gris); margin: 8px 0 0; }
.conc-tabla-alta { max-height: 62vh; overflow: auto; }
.conc-egreso td { color: var(--gris); }
.conc-nota { color: var(--error); }
.conc-archivos { margin: 0; padding-left: 18px; font-size: .85rem; }

.conc-pie { position: sticky; bottom: 0; z-index: 2; margin-top: 12px; display: flex; flex-wrap: wrap; gap: 6px 18px; align-items: center; padding: 10px 14px; border-radius: 8px; background: var(--azul-noche); color: #e6eef5; font-size: .8rem; }
.conc-pie b { color: #fff; font-weight: 600; font-variant-numeric: tabular-nums; }
.conc-pie__cuadre.ok { color: #8fd3a4; font-weight: 600; }
.conc-pie__cuadre.error { color: #ffb4ab; font-weight: 600; }
.conc-pie__der { margin-left: auto; }

.conc-reparto__info { color: var(--gris); margin: 0 0 8px; }
.conc-reparto input[type="number"] { width: 130px; text-align: right; font: inherit; padding: 3px 6px; border: 1px solid var(--linea); border-radius: 4px; }
.conc-reparto__barra { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 8px; margin-top: 10px; }
.conc-reparto__agregar { display: flex; gap: 6px; }
.conc-reparto__agregar input { width: 120px; font: inherit; padding: 4px 8px; border: 1px solid var(--linea); border-radius: 6px; }
.conc-reparto__dif b.ok { color: var(--ok); }
.conc-reparto__dif b.error { color: var(--error); }
.conc-etapas { margin-top: 18px; background: var(--papel); border: 1px solid var(--linea); border-radius: 8px; padding: 10px 14px; }
.conc-etapas summary { cursor: pointer; font-weight: 600; color: var(--azul); }
.conc-etapas__tabla input { width: 90px; font: inherit; padding: 3px 6px; }
.conc-archivo__quitar { border: 0; background: transparent; color: inherit; cursor: pointer; font-size: 16px; line-height: 1; padding: 0 2px 0 6px; opacity: .6; }
.conc-archivo__quitar:hover { opacity: 1; color: #b3261e; }
/* Conciliaciones — Historial aprendido (vistas/conciliacion_historial.php) */
.chist-cifras { display: flex; flex-wrap: wrap; gap: 10px; margin: 8px 0 14px; }
.chist-cifras > div { display: flex; flex-direction: column; min-width: 150px; padding: 10px 14px; border: 1px solid var(--linea); border-radius: 8px; background: var(--fondo); }
.chist-cifras b { font-size: 1.35rem; font-weight: 600; }
.chist-cifras span { font-size: .78rem; color: var(--gris); }
.chist-cifras .chist-cifras--aviso { border-color: var(--conc-aviso, #9a6200); background: var(--conc-aviso-fondo, #fff4dc); }
.chist-buscar { min-width: 280px; }
.chist-lote { position: sticky; top: 0; z-index: 5; display: flex; flex-wrap: wrap; align-items: center; gap: 8px; padding: 8px 12px; margin: 8px 0; border: 1px solid var(--conc-sel, #d6e8f6); border-radius: 8px; background: var(--conc-sel, #d6e8f6); }
.chist-lote[hidden] { display: none; }
.chist-lote input { width: 190px; }
.chist-lote__sep { flex: 0 0 1px; align-self: stretch; background: var(--linea); }
.chist-tabla { max-height: 62vh; overflow: auto; }
.chist-col-chk { width: 34px; text-align: center; }
.chist-fila--marcada { background: var(--conc-sel, #d6e8f6); }
.chist-marca { display: inline-block; font-size: .72rem; padding: 2px 8px; border-radius: 999px; border: 1px solid var(--linea); background: var(--fondo); margin-right: 4px; }
.chist-marca--aviso { color: var(--conc-aviso, #9a6200); background: var(--conc-aviso-fondo, #fff4dc); border-color: var(--conc-aviso, #9a6200); }
.chist-marca--error { color: #b3261e; border-color: #b3261e; }
.conc-cifra--aviso { border-color: var(--conc-aviso, #9a6200); background: var(--conc-aviso-fondo, #fff4dc); }
/* Conciliación: pestañas como el Excel (Resumen, Extracto original, Ingresos…) */
.conc-pill--sinid { background: var(--error-fondo); color: var(--error); }
.conc-tabs button.conc-tab--aviso { color: var(--conc-aviso); }
.conc-tabs button.conc-tab--aviso span { font-weight: 700; }
.conc-resumen { display: grid; grid-template-columns: minmax(0, 560px) minmax(0, 1fr); gap: 18px; align-items: start; }
.conc-resumen__tabla td:first-child { white-space: normal; }
.conc-resumen__vacio td { height: 10px; padding: 0; border: 0; background: transparent; }
.conc-resumen__dif td { font-weight: 600; }
.conc-resumen__lado .conc-subtitulo:first-child { margin-top: 0; }
.conc-controles--lista { flex-direction: column; align-items: flex-start; }
.conc-controles--lista li { white-space: normal; }
.conc-total { display: block; font-size: .68rem; color: var(--gris); line-height: 1.1; }
.conc-se-acciones { display: flex; flex-wrap: wrap; gap: 4px; }
@media (max-width: 900px) { .conc-resumen { grid-template-columns: 1fr; } }

.conc-grilla thead th[data-ordenable] { cursor: pointer; user-select: none; }
.conc-grilla thead th[data-ordenable]:hover { color: var(--tinta); }
.conc-grilla thead th[data-ordenable]::after { content: '\2195'; margin-left: 5px; opacity: .35; }
.conc-grilla thead th[data-ordenable][data-orden="asc"]::after { content: '\2191'; opacity: 1; color: var(--azul); }
.conc-grilla thead th[data-ordenable][data-orden="desc"]::after { content: '\2193'; opacity: 1; color: var(--azul); }
.conc-rel__aviso { color: var(--conc-aviso); }
.conc-rel__distinto { background: var(--conc-aviso-fondo); color: var(--conc-aviso); font-weight: 600; }
/* Conciliación: celda activa, totales, control de tránsito, motivo de revisión */
.conc-grilla td.is-celda { outline: 2px solid var(--azul); outline-offset: -2px; }
.conc-totales { display: flex; flex-wrap: wrap; gap: 4px 18px; font-size: .82rem; padding: 6px 10px; margin: 0 0 8px; background: var(--info-fondo); border-radius: 6px; }
.conc-totales:empty { display: none; }
.conc-transito { display: grid; gap: 6px; margin: 0 0 10px; padding: 8px 12px; border: 1px solid var(--linea); border-radius: 8px; background: var(--papel); font-size: .82rem; }
.conc-transito > div { display: flex; flex-wrap: wrap; gap: 4px 14px; align-items: baseline; }
.conc-transito .conc-ok { color: var(--ok); }
.conc-transito .conc-mal { color: var(--error); font-weight: 600; }
.conc-transito__faltan ul { margin: 6px 0 0 18px; padding: 0; }
.conc-motivo { max-width: 340px; }
.conc-motivo-aviso { background: var(--conc-aviso-fondo); color: var(--conc-aviso); border: 1px solid var(--conc-aviso); border-radius: 6px; padding: 8px 10px; margin-bottom: 10px; font-size: .82rem; }
.conc-grilla { min-width: 1900px; }

/* Ventanas de la conciliación: se arrastran por la cabecera. */
[data-conc-hoja] dialog .panel-dialog__cabecera { cursor: move; user-select: none; touch-action: none; }
[data-conc-hoja] dialog .panel-dialog__cabecera button { cursor: pointer; }

/* Vista previa del cierre de la conciliación. */
.conc-previa__resumen { display: flex; flex-wrap: wrap; gap: 8px 18px; padding: 8px 10px; background: var(--papel); border: 1px solid var(--linea); border-radius: 6px; font-size: .84rem; margin-bottom: 8px; }
.conc-previa__titulo { margin: 12px 0 6px; font-size: .86rem; }
.conc-previa__nota { margin: 6px 0; font-size: .82rem; color: var(--gris); }
.conc-previa__error td { background: #fdecea; }
.conc-previa .conc-tabla-alta { max-height: 34vh; }

/* Parámetros de conciliación (vistas/conciliacion_parametros.php). */
.cpar-barra { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin: 10px 0; }
.cpar-cuenta { color: var(--gris); font-size: .84rem; }
.cpar-inactivo td { opacity: .6; }
.cpar-campos { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px 14px; margin: 8px 0; }
.cpar-ancho { grid-column: 1 / -1; }
@media (max-width: 700px) { .cpar-campos { grid-template-columns: 1fr; } }
.cpar-nota { font-size: .8rem; color: var(--gris); margin: 6px 0; }
/* Cancelar a la izquierda y Guardar a la derecha, bien separados: pegados se pulsaba Cancelar por error. */
.cpar-dialogo .panel-dialog__acciones { justify-content: space-between; margin-top: 16px; }
.cpar-ayuda { margin-top: 14px; font-size: .86rem; }
.cpar-ayuda ul { margin: 6px 0 0 18px; padding: 0; }
.cpar-ayuda li { margin: 4px 0; }
.cpar-campos [hidden] { display: none !important; }

/* Columnas movibles de la conciliación (arrastrar el encabezado) */
[data-conc-hoja] th[draggable="true"] { cursor: grab; }
[data-conc-hoja] th.conc-col-arrastrando { opacity: .45; }
[data-conc-hoja] th.conc-col-izq { box-shadow: inset 3px 0 0 var(--azul); }
[data-conc-hoja] th.conc-col-der { box-shadow: inset -3px 0 0 var(--azul); }
.conc-cols-barra { display: flex; justify-content: flex-end; margin: 0 0 4px; }
.conc-cols-barra[hidden] { display: none; }

/* Columna «¿Se monta?» de la conciliación */
.conc-acciones .conc-nc-servicio, .panel-barra .conc-nc-servicio { display: inline-block; margin-top: 0; font-size: 12px; max-width: 230px; }
.conc-semonta { font-weight: 600; text-align: center; }
.conc-semonta--si { color: #1b7a3d; }
.conc-semonta--no { color: #8a4b1f; }

/* Conciliación: barra fija con lo que se sube, botón «Ver movimiento» siempre a la derecha, ventana de movimiento con su X */
.conc-barra--ingresos { position: sticky; top: 0; z-index: 6; }
.conc-btn-detalle { margin-left: auto; order: 99; }
.conc-asubir { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 8px; padding: 3px 10px; border-radius: 6px; background: var(--ok-fondo); color: var(--ok); font-size: .82rem; }
.conc-asubir b { font-size: 1rem; font-variant-numeric: tabular-nums; }
.conc-asubir small { color: inherit; opacity: .8; font-size: .72rem; }
.conc-asubir:empty { display: none; }
.conc-detalle { position: sticky; padding-right: 34px; }
.conc-detalle__cerrar { position: absolute; top: 6px; right: 8px; width: 24px; height: 24px; border: 0; border-radius: 50%; background: transparent; color: var(--gris); font-size: 18px; line-height: 1; cursor: pointer; }
.conc-detalle__cerrar:hover { background: var(--fondo); color: var(--tinta); }
.conc-pill--excluida { background: var(--fondo); color: var(--gris); text-decoration: line-through; }
.conc-grilla tr[data-excluida="1"] td { color: var(--gris); }
.conc-lote__sep { flex: 0 0 1px; align-self: stretch; background: var(--linea); }
.conc-check[hidden] { display: none; }

/* Columnas de Ingresos: anclar, ensanchar y filtrar */
.conc-th-acc { margin-left: 6px; white-space: nowrap; }
.conc-th-btn { border: 0; background: transparent; cursor: pointer; padding: 0 2px; font-size: .72rem; opacity: .3; color: inherit; }
.conc-grilla thead th:hover .conc-th-btn, .conc-th-btn.is-on { opacity: 1; }
.conc-th-btn.is-on[data-colfiltro] { color: var(--azul); }
.conc-th-resize { position: absolute; top: 0; right: 0; bottom: 0; width: 6px; cursor: col-resize; z-index: 5; }
.conc-th-resize:hover { background: var(--azul); opacity: .35; }
.conc-grilla thead th.conc-th-filtrada { box-shadow: inset 0 -3px 0 var(--azul); }
.conc-grilla.conc-grilla--fija { table-layout: fixed; min-width: 0; width: auto; }
.conc-grilla--fija td, .conc-grilla--fija th { overflow: hidden; text-overflow: ellipsis; }
.conc-grilla--fija .conc-desc, .conc-grilla--fija .conc-motivo, .conc-grilla--fija .conc-metodo { max-width: none; }
.conc-grilla td.conc-fijo { position: sticky; z-index: 2; background: var(--papel); }
.conc-grilla td.conc-n.conc-fijo { background: #eef3f7; }
.conc-grilla thead th.conc-fijo { z-index: 4; }
.conc-grilla .conc-fijo--ultimo { box-shadow: 2px 0 0 rgba(0, 0, 0, .12); }
.conc-colfil { position: fixed; z-index: 1000; width: 260px; max-height: 330px; display: flex; flex-direction: column; gap: 6px; padding: 8px; background: var(--papel); border: 1px solid var(--linea); border-radius: 8px; box-shadow: 0 8px 24px rgba(0, 0, 0, .18); }
.conc-colfil[hidden] { display: none; }
.conc-colfil__buscar { font: inherit; font-size: .8rem; padding: 4px 8px; border: 1px solid var(--linea); border-radius: 6px; }
.conc-colfil__todo { display: flex; gap: 6px; align-items: center; font-size: .8rem; font-weight: 600; padding: 2px 4px; }
.conc-colfil__lista { overflow: auto; max-height: 190px; display: flex; flex-direction: column; gap: 1px; border-top: 1px solid var(--linea); border-bottom: 1px solid var(--linea); padding: 4px 0; }
.conc-colfil__item { display: flex; gap: 6px; align-items: center; font-size: .78rem; padding: 2px 4px; cursor: pointer; }
.conc-colfil__item[hidden] { display: none; }
.conc-colfil__item:hover { background: var(--fondo); }
.conc-colfil__item small { margin-left: auto; color: var(--gris); font-variant-numeric: tabular-nums; }
.conc-colfil__acc { display: flex; gap: 6px; justify-content: flex-end; }

/* Ventana «Editar el movimiento» */
.conc-editar-form { display: grid; grid-template-columns: 1fr 1fr; gap: 6px 14px; }
@media (max-width: 560px) { .conc-editar-form { grid-template-columns: 1fr; } }
[data-conc-editar] input:disabled { background: var(--fondo); color: var(--gris); }
.conc-riesgo { margin: 10px 0; padding: 10px 12px; border: 1px solid var(--conc-aviso); border-radius: 8px; background: var(--conc-aviso-fondo); color: var(--tinta); font-size: .82rem; }
.conc-riesgo[hidden] { display: none; }
.conc-riesgo__t { margin: 0 0 4px; color: var(--conc-aviso); }
.conc-riesgo ul { margin: 4px 0 8px 18px; padding: 0; }
[data-conc-editar] .panel-boton[disabled] { opacity: .5; cursor: not-allowed; }
.conc-colfil__ayuda { font-size: .68rem; color: var(--gris); padding: 0 2px; }
.conc-colfil__item:focus-within { background: var(--conc-sel); }
.conc-colfil__todo:focus-within { background: var(--conc-sel); }
/* Pantalla completa de la conciliación (tecla Z): solo filtros, totales y tabla, sobre todo el panel. Por debajo de los avisos (z 80). */
.conc.conc--pantalla { position: fixed; inset: 0; z-index: 70; margin: 0; padding: 10px 14px; max-width: none; background: var(--fondo); display: flex; flex-direction: column; overflow: hidden; }
.conc--pantalla > .panel-frag__cabecera, .conc--pantalla > .conc-meta, .conc--pantalla > .conc-barra, .conc--pantalla > .conc-pie,
.conc--pantalla > section:not([data-conc-panel="ingresos"]), .conc--pantalla .conc-transito, .conc--pantalla .conc-ayuda { display: none; }
.conc--pantalla > section[data-conc-panel="ingresos"] { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; }
.conc--pantalla > section[data-conc-panel="ingresos"][hidden] { display: none; }
.conc--pantalla .conc-trabajo { flex: 1 1 auto; min-height: 0; grid-template-rows: minmax(0, 1fr); align-items: stretch; }
.conc--pantalla .conc-hoja, .conc--pantalla .conc-detalle { max-height: none; height: 100%; }
.conc-chip[aria-pressed="true"][data-conc-pantalla-btn] { background: var(--celeste); color: #fff; border-color: var(--celeste); }

/* Menú del sistema: flechas de mover y resaltado de la fila recién movida */
.panel-menu-flecha { min-width: 26px; font-size: 1rem; line-height: 1; }
.panel-menu-flecha:disabled { opacity: .3; cursor: default; }
@keyframes panel-menu-fila-movida { from { background: var(--info-fondo); } to { background: transparent; } }
.panel-menu-fila--movida { animation: panel-menu-fila-movida 1.6s ease-out; }
.panel-menu-zonabarra { display: flex; align-items: flex-end; gap: 14px; flex-wrap: wrap; margin-bottom: 10px; font-size: .82rem; }
.panel-menu-zonacampo { min-width: 220px; }
.panel-menu-zonaayuda { color: var(--texto-suave, #6b7a89); }
.is-zona-oculta { display: none; }
.panel-zona--header { background: #fdf0d9; color: #8a5a00; }
.panel-zona--sistema { background: var(--info-fondo); color: var(--azul); }
.panel-zona--unidad { background: #e6f4ea; color: #1e6b3a; }
.panel-zona { white-space: nowrap; }

/* Resumen "Mostrando N de M · Total" arriba de una tabla filtrable (el <tfoot> queda muy abajo en tablas largas). */
.panel-informe__resumen { margin: 10px 0; padding: 8px 12px; background: var(--fondo); border: 1px solid var(--linea); border-radius: 8px; font-size: .9rem; }

/* Facturación vs Recaudo por apartamento: las dos primeras columnas (apto, nombre) quedan fijas al desplazarse. */
.panel-tabla--matriz th, .panel-tabla--matriz td { white-space: nowrap; }
.panel-tabla--matriz td:first-child, .panel-tabla--matriz th:first-child { position: sticky; left: 0; background: var(--papel); z-index: 1; }
.panel-tabla--matriz th:first-child { z-index: 2; }

/* Buscador de tabla sobre caja blanca, igual que los filtros (.panel-filtros): sobre el fondo gris de la página
   no se distinguía. El aro redondeado pasa al campo de adentro. */
.panel-buscador-caja {
  max-width: none;
  width: 100%;
  box-sizing: border-box;
  margin: 0 0 16px;
  padding: 14px;
  background: var(--papel);
  border: 1px solid var(--linea);
  border-radius: var(--radio);
}
.panel-buscador-caja input {
  border: 1px solid var(--linea);
  border-radius: var(--radio-chico);
  background: var(--papel);
  padding: 10px 12px;
  font-size: .95rem;
}
.panel-buscador-caja input:focus { outline: 2px solid var(--azul); outline-offset: 1px; }

/* ==========================================================================
   Cierre mensual guiado (2026-10): chip del header, modal con los pasos y
   pantalla de configuración. Ver assets/js/flujo.js y lib/flujo_mensual.php.
   ========================================================================== */
.panel-header__flujo {
  display: flex; align-items: center; gap: 8px; flex: none; padding: 7px 14px;
  border: 1px solid var(--linea); border-radius: 999px; background: var(--papel); color: var(--tinta);
  font-size: .8rem; font-weight: 500; white-space: nowrap; cursor: pointer;
}
.panel-header__flujo:hover { border-color: var(--azul); }
.panel-header__flujo-punto { width: 9px; height: 9px; border-radius: 50%; background: #b8c4cf; flex: none; }
.panel-header__flujo--activo { border-color: #e0a100; background: #fff8e1; }
.panel-header__flujo--activo .panel-header__flujo-punto { background: #e0a100; animation: flujo-latido 1.6s ease-in-out infinite; }
@keyframes flujo-latido { 0%, 100% { opacity: 1; } 50% { opacity: .35; } }
@media (prefers-reduced-motion: reduce) { .panel-header__flujo--activo .panel-header__flujo-punto { animation: none; } }
@media (max-width: 900px) { .panel-header__flujo-texto { display: none; } .panel-header__flujo { padding: 8px 10px; } }

.flujo-modal { max-height: min(900px, calc(100vh - 48px)); }
.flujo-lead { margin: 0 0 8px; }
.flujo-iniciar { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 14px; }
.flujo-resumen { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 12px 24px; margin-bottom: 16px; }
.flujo-barra { flex: 1 1 180px; max-width: 280px; height: 8px; border-radius: 999px; background: var(--linea); overflow: hidden; }
.flujo-barra span { display: block; height: 100%; background: var(--ok); border-radius: 999px; }
.flujo-pasos { list-style: none; margin: 0 0 18px; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.flujo-paso {
  display: grid; grid-template-columns: 34px 1fr auto; gap: 12px; align-items: start;
  padding: 12px 14px; border: 1px solid var(--linea); border-radius: var(--radio); background: var(--papel);
}
.flujo-paso--hecho { background: var(--ok-fondo); border-color: #bfe3cb; }
.flujo-paso--omitido { background: var(--fondo); }
.flujo-paso--actual { border-color: var(--azul); box-shadow: 0 0 0 2px var(--info-fondo); }
.flujo-paso--detectado { border-style: dashed; }
.flujo-paso__n {
  display: inline-flex; align-items: center; justify-content: center; width: 30px; height: 30px; border-radius: 50%;
  background: var(--fondo); border: 1px solid var(--linea); font-size: .82rem; font-weight: 600; color: var(--gris);
}
.flujo-paso--hecho .flujo-paso__n { background: var(--ok); border-color: var(--ok); color: #fff; }
.flujo-paso--actual .flujo-paso__n { background: var(--azul); border-color: var(--azul); color: #fff; }
.flujo-paso__titulo { font-weight: 600; }
.flujo-etiqueta { margin-left: 6px; padding: 1px 8px; border-radius: 999px; background: var(--info-fondo); color: var(--azul); font-size: .7rem; font-weight: 500; white-space: nowrap; }
.flujo-paso__meta { margin-top: 3px; font-size: .86rem; color: var(--gris); overflow-wrap: anywhere; }
.flujo-paso__evidencia { margin-top: 2px; color: var(--tinta); }
.flujo-paso__ayuda { margin-top: 6px; padding: 8px 10px; border-radius: var(--radio-chico); background: var(--info-fondo); color: var(--tinta); }
.flujo-ok { color: var(--ok); font-weight: 600; }
.flujo-omitido { color: #8a6100; font-weight: 600; }
.flujo-detectado { color: var(--azul); font-weight: 600; }
.flujo-paso__acciones { display: flex; flex-wrap: wrap; justify-content: flex-end; align-items: center; gap: 8px; max-width: 340px; }
.flujo-nota { flex: 1 1 160px; min-width: 140px; padding: 6px 10px; border: 1px solid var(--linea); border-radius: var(--radio-chico); font-size: .85rem; }
.flujo-motivo { grid-column: 2 / -1; margin-top: 8px; }
.flujo-motivo label { display: block; margin-bottom: 4px; font-size: .85rem; font-weight: 600; }
.flujo-motivo textarea { width: 100%; padding: 8px 10px; border: 1px solid var(--linea); border-radius: var(--radio-chico); font: inherit; resize: vertical; }
.flujo-motivo__acc { display: flex; justify-content: flex-end; gap: 8px; margin-top: 8px; }
.flujo-pie { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 10px; margin-top: 4px; }
.flujo-historial { margin-top: 18px; font-size: .85rem; }
.flujo-historial summary { cursor: pointer; color: var(--azul); }
.flujo-historial ul { margin: 8px 0 0; padding-left: 18px; }
@media (max-width: 720px) {
  .flujo-paso { grid-template-columns: 30px 1fr; }
  .flujo-paso__acciones { grid-column: 2; justify-content: flex-start; max-width: none; }
}

/* Pantalla de configuración del flujo */
.flujo-config__filas { list-style: none; margin: 0 0 18px; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.flujo-config__fila { display: grid; grid-template-columns: auto auto 1fr; gap: 12px; align-items: center; padding: 10px 14px; border: 1px solid var(--linea); border-radius: var(--radio); background: var(--papel); }
.flujo-config__mover { display: flex; flex-direction: column; gap: 2px; }
.flujo-config__mover button { border: 1px solid var(--linea); background: var(--fondo); border-radius: 4px; padding: 0 8px; line-height: 1.2; cursor: pointer; }
.flujo-config__nombre input[type="text"] { width: 100%; padding: 7px 10px; border: 1px solid var(--linea); border-radius: var(--radio-chico); font: inherit; }
.flujo-config__fila--inactiva { opacity: .6; }
.flujo-config__auto { border: 0; padding: 0; margin: 0; min-width: 0; }
.flujo-config__auto[disabled] { opacity: .5; }
.flujo-config__fechas { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 10px 14px; margin: 8px 0 18px; }
.flujo-config__disparadores { display: flex; flex-direction: column; gap: 6px; margin: 8px 0 18px; }

/* ==========================================================================
   Registro de novedades (2026-10). Ver assets/js/novedades.js y lib/novedades.php.
   ========================================================================== */
.nov-cabecera__acc { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.nov-tabs { display: flex; flex-wrap: wrap; gap: 6px; margin: 6px 0 4px; border-bottom: 1px solid var(--linea); }
.nov-tab {
  padding: 10px 16px; border: 1px solid transparent; border-bottom: none; border-radius: var(--radio-chico) var(--radio-chico) 0 0;
  background: none; color: var(--gris); font: inherit; font-weight: 500; cursor: pointer; margin-bottom: -1px;
}
.nov-tab:hover { color: var(--azul); }
.nov-tab.is-activa { background: var(--papel); border-color: var(--linea); color: var(--azul); font-weight: 600; }
.nov-cuenta { display: inline-block; min-width: 22px; padding: 0 7px; border-radius: 999px; background: var(--info-fondo); color: var(--azul); font-size: .75rem; text-align: center; }
.nov-tab-ayuda { margin: 6px 0 12px; }
.nov-filtros { margin-bottom: 14px; }
.nov-limpiar { align-self: flex-end; }
.nov-lote { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-bottom: 10px; padding: 10px 14px; border-radius: var(--radio); background: var(--info-fondo); }
.nov-lote[hidden] { display: none; }
.nov-tabla .panel-celda-acciones { white-space: normal; }
.nov-tabla .panel-celda-acciones .panel-boton { margin: 0 4px 4px 0; }
.nov-col-sel { width: 34px; }
.nov-cat { margin-left: 4px; padding: 1px 8px; border-radius: 999px; background: var(--fondo); border: 1px solid var(--linea); color: var(--gris); font-size: .72rem; }
.nov-resumen { color: var(--tinta); }
.nov-fila--atrasada { background: #fff8e1; }
.nov-atrasada { color: #8a6100; font-weight: 600; }
.nov-badge { display: inline-block; padding: 1px 9px; border-radius: 999px; font-size: .72rem; font-weight: 500; background: var(--fondo); color: var(--gris); border: 1px solid var(--linea); }
.nov-badge--automatica { background: var(--ok-fondo); color: var(--ok); border-color: #bfe3cb; }
.nov-badge--asistida { background: var(--info-fondo); color: var(--azul); border-color: #c4def0; }
.nov-estado { padding: 2px 10px; border-radius: 999px; font-size: .78rem; font-weight: 600; background: var(--fondo); color: var(--gris); }
.nov-estado--aplicada, .nov-estado--activa { background: var(--ok-fondo); color: var(--ok); }
.nov-estado--no_aplica, .nov-estado--cerrada { background: #fff3cd; color: #8a6100; }
.nov-estado--anulada { background: var(--error-fondo); color: var(--error); }
.nov-dialogo { max-height: min(860px, calc(100vh - 48px)); }
.nov-form__tipo { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.nov-form__ayuda { margin: 0 0 14px; padding: 10px 12px; border-radius: var(--radio-chico); background: var(--info-fondo); font-size: .88rem; }
.nov-form__ayuda:empty { display: none; }
.nov-bloque { margin: 14px 0; padding: 12px 14px; border: 1px solid var(--linea); border-radius: var(--radio); }
.nov-bloque legend { padding: 0 8px; font-weight: 600; font-size: .9rem; }
.nov-radios { display: flex; flex-wrap: wrap; gap: 14px; margin-bottom: 10px; }
.nov-torres, .nov-meses { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 6px 14px; margin-top: 8px; }
.nov-meses__todos { grid-column: 1 / -1; font-weight: 600; }
.nov-req { color: var(--error); font-style: normal; }
.nov-pista { display: block; min-height: 1em; margin-top: 3px; font-size: .78rem; color: var(--gris); }
.nov-pista--ok { color: var(--ok); }
.nov-pista--mal { color: var(--error); font-weight: 600; }
.nov-detalle th { width: 28%; text-align: left; vertical-align: top; color: var(--gris); font-weight: 500; }
.nov-lista { margin: 0 0 14px; padding-left: 18px; }
.nov-lista li { margin-bottom: 6px; }
.nov-pre { white-space: pre-line; color: var(--gris); }
@media (max-width: 720px) { .nov-form__tipo { grid-template-columns: 1fr; } }
/* El atributo hidden debe ganarle a los display: grid/flex de arriba (campos condicionales). */
.nov [hidden], .flujo-config [hidden] { display: none !important; }
/* Descuentos por pronto pago */
/* Los campos, filtros y el buscador usan los componentes de siempre del panel (.panel-filtros, .panel-campo, .panel-buscador-caja); aquí solo lo propio. */
.dpp-fecha { margin: 0 0 8px; align-self: flex-end; }
.dpp-servicio { max-width: 460px; }
.dpp-lote { margin-top: 12px; }
.dpp-acc { white-space: nowrap; }
/* Valor editable dentro de la tabla: mismo borde, radio y foco que .panel-campo, en tamaño de celda. */
.dpp-valor { width: 130px; text-align: right; box-sizing: border-box; border: 1px solid var(--linea); border-radius: var(--radio-chico); padding: 6px 10px; font-size: .9rem; color: var(--tinta); background: var(--papel); }
.dpp-valor:focus { outline: 2px solid var(--azul); outline-offset: 1px; }
.dpp-importar { align-items: center; }
.dpp-importar h4, .dpp-importar > p, .dpp-importar [data-dpp-imp-resultado] { flex-basis: 100%; margin: 0; }
.dpp-importar .panel-campo { align-self: flex-end; }

/* Novedades: nombres de las listas y años adicionales de «¿Cuándo aplica?» */
.nov-nombres { max-height: 60vh; overflow: auto; display: grid; gap: 10px; margin: 10px 0; }
.nov-extra { border-top: 1px dashed var(--linea); margin-top: 10px; padding-top: 10px; display: grid; gap: 8px; }
[data-nov-vig-agregar] { margin-top: 10px; }

/* Cierres mensuales · Todas las unidades (Menú Sistema) */
.fg-cabecera__acc { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.fg-filtros { display: flex; flex-wrap: wrap; gap: 12px 18px; align-items: end; margin: 10px 0 14px; }
.fg [hidden] { display: none !important; }
.fg-tarjeta { background: var(--papel); border: 1px solid var(--linea); border-radius: var(--radio); padding: 14px 16px; margin-bottom: 12px; }
.fg-tarjeta__cab { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 8px; align-items: flex-start; }
.fg-tarjeta__cab h3 { margin: 0 0 2px; font-size: 1.05rem; }
.fg-tarjeta__cab p { margin: 0; }
.fg-tarjeta__acc { display: flex; flex-wrap: wrap; gap: 6px; }
.fg-tarjeta__resumen { margin: 8px 0 2px; }
.fg-progreso { height: 8px; background: var(--fondo); border-radius: 99px; overflow: hidden; margin-top: 10px; }
.fg-progreso span { display: block; height: 100%; background: var(--azul); border-radius: 99px; }
.fg-pasos { margin-top: 10px; }
.fg-pasos summary { cursor: pointer; color: var(--azul); font-size: .9rem; }
.fg-pasos ol { list-style: none; margin: 10px 0 0; padding: 0; display: grid; gap: 6px; }
.fg-paso { display: flex; gap: 10px; padding: 8px 10px; border: 1px solid var(--linea); border-radius: 8px; background: var(--fondo); }
.fg-paso--actual { border-color: var(--azul); background: #fff; box-shadow: 0 0 0 1px var(--azul) inset; }
.fg-paso__n { min-width: 22px; height: 22px; border-radius: 50%; background: var(--linea); display: inline-flex; align-items: center; justify-content: center; font-size: .75rem; font-weight: 600; }
.fg-paso__cuerpo { flex: 1; min-width: 0; }
.fg-paso__nombre { font-weight: 600; }
.fg-paso__detalle { font-size: .85rem; margin-top: 2px; }
.fg-paso__nota { font-style: italic; color: var(--gris); }
.fg-paso__acc { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; margin-top: 8px; }
.fg-paso__acc input[type="text"] { flex: 1; min-width: 160px; }
.fg-badge { display: inline-block; font-size: .72rem; font-weight: 600; padding: 1px 8px; border-radius: 99px; }
.fg-badge--ok { background: #dff3e4; color: #1d6b34; }
.fg-badge--omitido { background: #ececec; color: #555; }
.fg-badge--pend { background: #fdf1d6; color: #8a5a00; }
.fg-sub { margin: 18px 0 6px; }
.fg-otras { list-style: none; margin: 0; padding: 0; display: grid; gap: 4px; }
.fg-resumen { margin: 0 0 10px; }
/* Pantalla completa (tecla Z / botón): solo queda la barrita con el botón para salir y las novedades. */
.nov.nov--pantalla { position: fixed; inset: 0; z-index: 70; margin: 0; padding: 8px 14px 14px; max-width: none; background: var(--fondo); overflow: auto; }
.nov--pantalla > .panel-frag__lead, .nov--pantalla > .panel-frag__cabecera h2 { display: none; }
.nov--pantalla > .panel-frag__cabecera { justify-content: flex-end; margin-bottom: 0; }
[data-nov-pantalla-btn][aria-pressed="true"] { background: var(--azul); color: #fff; border-color: var(--azul); }
[data-nov-pantalla-btn] kbd { font: inherit; font-size: .75em; padding: 0 5px; margin-left: 4px; border: 1px solid currentColor; border-radius: 4px; opacity: .75; }

/* Registro de novedades · Fase 3: vista previa de los ejecutores y resultado de lo que hizo el sistema. */
.nov-previa__item { margin: 0 0 14px; padding: 12px 14px; border: 1px solid var(--linea); border-radius: var(--radio); background: var(--papel); }
.nov-previa__item--bloq { background: var(--fondo); }
.nov-previa__item h4 { margin: 0 0 4px; font-size: 1rem; }
.nov-previa__item h4 small { color: var(--gris); font-weight: 400; margin-left: 6px; }
.nov-previa__lineas { margin: 8px 0; padding-left: 18px; font-size: .9rem; }
.nov-previa__lineas li { margin-bottom: 3px; }
.nov-previa__avisos, .nov-previa__bloqueos { margin-top: 8px; padding: 8px 12px; border-radius: var(--radio-chico); font-size: .88rem; }
.nov-previa__avisos { background: #fff8e1; border-left: 4px solid #e0a100; }
.nov-previa__bloqueos { background: var(--error-fondo); border-left: 4px solid var(--error); }
.nov-previa__avisos ul, .nov-previa__bloqueos ul { margin: 4px 0 0; padding-left: 18px; }
.nov-resultado { color: var(--gris); }

/* Importar novedades por archivo (Fase 4) */
.nov-imp__fila { display: flex; gap: 12px; align-items: flex-end; flex-wrap: wrap; margin-top: 12px; }
.nov-imp__fila .panel-campo { flex: 1 1 260px; }
.nov-imp__resumen { margin: 14px 0 8px; }
.nov-imp__tabla { max-height: 320px; overflow: auto; }
.nov-imp__ok { color: var(--ok); font-weight: 600; }
.nov-imp__error { color: var(--error); font-weight: 600; }
.nov-imp__omite { color: var(--gris); font-weight: 600; }

/* Sugerido de una novedad en Identificar pagos / alerta en el conciliador (Fase 5) */
.pxi-sugerido { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin-top: 6px; padding: 6px 8px; border-radius: 6px; background: var(--info-fondo); color: var(--azul); font-size: .85rem; }
.pxi-sugerido--fuerte { background: var(--ok-fondo); color: var(--ok); }
.nov-alerta { margin: 0 0 12px; }
.nov-alerta ul { margin: 6px 0 0; padding-left: 18px; }
.nov-adj__subir { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; margin-top: 8px; }

/* ---- Seguimiento de correos (CRM Emails) ---- */
.cseg-tarjetas { display: grid; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); gap: 10px; margin: 14px 0 6px; }
.cseg-tarjeta { background: var(--papel); border: 1px solid var(--linea); border-radius: var(--radio); padding: 10px 14px; display: flex; flex-direction: column; gap: 2px; }
.cseg-tarjeta span { font-size: .78rem; color: var(--gris); }
.cseg-tarjeta strong { font-size: 1.35rem; color: var(--tinta); }
.cseg-tarjeta small { color: var(--gris); }
.cseg-tarjeta--ok strong { color: var(--ok); }
.cseg-tarjeta--mal strong { color: var(--error); }
.cseg-estado { display: inline-block; padding: 2px 9px; border-radius: 999px; font-size: .78rem; font-weight: 600; background: var(--fondo); color: var(--gris); white-space: nowrap; }
.cseg-estado--entregado { background: var(--ok-fondo); color: var(--ok); }
.cseg-estado--rebotado, .cseg-estado--rechazado, .cseg-estado--sup-pendiente { background: var(--error-fondo); color: var(--error); }
.cseg-estado--queja { background: #fff1d6; color: #8a5a00; }
.cseg-estado--retrasado, .cseg-estado--sup-revisado { background: #fff8e1; color: #8a6d00; }
.cseg-estado--enviado { background: var(--info-fondo); color: var(--info); }
.cseg-estado--sup-corregido { background: var(--ok-fondo); color: var(--ok); }
.cseg-ficha { display: grid; grid-template-columns: max-content 1fr; gap: 4px 14px; margin: 0 0 10px; }
.cseg-ficha dt { color: var(--gris); font-size: .85rem; }
.cseg-ficha dd { margin: 0; word-break: break-word; }
.cseg-tiempo { list-style: none; margin: 0; padding: 0 0 0 14px; border-left: 3px solid var(--linea); }
.cseg-tiempo__item { position: relative; padding: 0 0 12px 12px; }
.cseg-tiempo__item::before { content: ''; position: absolute; left: -22px; top: 5px; width: 11px; height: 11px; border-radius: 50%; background: var(--celeste); border: 2px solid var(--papel); }
.cseg-tiempo__item--delivery::before, .cseg-tiempo__item--open::before, .cseg-tiempo__item--click::before { background: var(--ok); }
.cseg-tiempo__item--bounce::before, .cseg-tiempo__item--complaint::before, .cseg-tiempo__item--reject::before { background: var(--error); }
.cseg-tiempo__item--delay::before { background: #e0a100; }
.cseg-tiempo__hora { color: var(--gris); font-size: .8rem; margin-left: 8px; }
.cseg-tiempo__detalle { color: var(--gris); font-size: .85rem; word-break: break-word; }

/* Ventanas de Movimientos (pago, NC, ND, ajuste…): se mueven por la cabecera, se minimizan a una barra y se expanden. */
.panel-dialog--mov-grande > .panel-dialog__cabecera,
.panel-dialog--mov-medio > .panel-dialog__cabecera { cursor: move; user-select: none; touch-action: none; }
.panel-dialog--mov-grande .panel-dialog__cabecera button,
.panel-dialog--mov-medio .panel-dialog__cabecera button { cursor: pointer; }
.panel-dialog__ventana-grupo { display: flex; align-items: center; gap: 6px; }
.panel-dialog__ventana {
  border: none; background: var(--fondo); border-radius: 8px; width: 32px; height: 32px;
  color: var(--gris); font-size: 1.05rem; line-height: 1; display: grid; place-items: center; padding: 0;
}
.panel-dialog__ventana:hover { color: var(--tinta); }
/* Minimizada: solo la barra del título, abajo a la izquierda; la página queda usable (la ventana pasa a no modal). */
.panel-dialog[data-ventana="min"] {
  position: fixed; inset: auto auto 16px 16px; margin: 0; z-index: 70;
  width: min(380px, calc(100vw - 32px)); max-height: none; padding: 12px 16px; overflow: hidden;
}
.panel-dialog[data-ventana="min"] > :not(.panel-dialog__cabecera) { display: none !important; }
.panel-dialog[data-ventana="min"] > .panel-dialog__cabecera { margin-bottom: 0; }
.panel-dialog[data-ventana="min"] h3 { font-size: .95rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* Expandida: casi toda la pantalla (sin importar dónde se hubiera movido). */
.panel-dialog[data-ventana="max"] {
  width: calc(100vw - 24px) !important; max-width: none !important;
  height: calc(100vh - 24px); max-height: calc(100vh - 24px) !important; translate: none !important;
}
.panel-dialog[data-ventana="max"] > .panel-dialog__cabecera { cursor: default; }

/* Casilla con su texto en una línea: dentro de .panel-campo el input heredaba el ancho completo y se veía enorme (Acuerdos de pago). */
.panel-casilla-linea { display: flex; align-items: flex-start; gap: 10px; margin: 4px 0; cursor: pointer; line-height: 1.4; }
.panel-casilla-linea input[type="checkbox"] { width: 18px; height: 18px; min-height: 0; flex: none; margin: 1px 0 0; padding: 0; accent-color: var(--azul); }
.panel-casilla-linea span { flex: 1; }

/* Info unidad: el formulario va en dos bloques lado a lado (uno solo en pantallas angostas). */
.panel-info-bloques { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; align-items: start; }
.panel-info-bloques > .panel-fact-caja { min-width: 0; }
@media (max-width: 980px) { .panel-info-bloques { grid-template-columns: 1fr; } }
/* Info unidad con tres cajas: la de datos ocupa el alto de las dos de la derecha (cuentas de cobro + logo) y se estira para igualarlas. */
.panel-info-bloques--tres { align-items: stretch; }
.panel-info-bloques--tres > .panel-info-izq { grid-row: 1 / span 2; }
@media (max-width: 980px) { .panel-info-bloques--tres > .panel-info-izq { grid-row: auto; } }

/* Propietarios · Validar correos (assets/js/propietarios_correos.js) */
.pcv-dialogo { width: min(1100px, 96vw); max-width: none; }
.pcv-barra { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; margin: 10px 0; }
.pcv-ver { font-size: 13px; color: var(--texto-suave, #5b6472); cursor: pointer; }
.pcv-correo { min-width: 210px; font-family: ui-monospace, Menlo, Consolas, monospace; font-size: 12.5px; word-break: break-all; }
.pcv-acciones { min-width: 230px; }
.pcv-acciones.pcv-abierto { white-space: normal; }
.pcv-acciones .panel-boton { margin: 0 4px 4px 0; }
.pcv-editar { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; margin-top: 6px; }
.pcv-editar__campo { min-width: 240px; }
.pcv-descartado td { opacity: .55; }
.pcv-dudosa { color: var(--aviso, #b45309); }
