/* ═══════════════════════════════════════════════════════
   Alfin Mailer — main.css
   Paleta: azul oscuro #1A3A5C, verde #27AE60, naranja #E67E22
   ═══════════════════════════════════════════════════════ */

:root {
  --blue:       #1A3A5C;
  --sidebar-bg: #507ba9;       /* v0.8.9 — antes #1d4e82, más clarito */
  --sidebar-flyout-bg: #578bc2; /* v0.8.9 — submenú flotante un punto más claro */
  --blue-light: #2E6DA4;
  --blue-pale:  #D6E4F0;
  --green:      #27AE60;
  --green-pale: #D5F5E3;
  --orange:     #E67E22;
  --orange-pale:#FDEBD0;
  --red:        #C0392B;
  --red-pale:   #FADBD8;
  --gray-bg:    #F4F6F8;
  --gray-border:#DDE1E7;
  --text:       #1C1C1C;
  --text-muted: #666;
  --white:      #FFFFFF;
  --sidebar-w:  200px;
  --topbar-h:   52px;
}

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

body {
  font-family: Arial, Helvetica, sans-serif;
  font-size: 15px;
  color: var(--text);
  background: var(--gray-bg);
  min-height: 100vh;
  /* v0.14.17 — Red de seguridad: si un futuro elemento ancho rompe
     el contenido (ej. tabla con muchas columnas, imagen grande,
     pre/code sin wrap, etc.), aquí se previene el scrollbar
     horizontal a nivel BODY. El sidebar es `position: fixed;
     bottom: 0`, y `bottom: 0` se ancla al borde superior del
     scrollbar horizontal cuando existe — provocando un "hueco"
     visible bajo el sidebar. Mejor evitarlo en raíz.
     Nota: las tablas internas que sí necesitan scroll horizontal
     usan `.table-scroll-container` con `overflow-x: auto` local
     (en su propio contenedor), no a nivel página — esto NO las
     rompe. */
  overflow-x: hidden;
}

a { color: var(--blue-light); text-decoration: none; }
a:hover { text-decoration: underline; }

/* ── TOPBAR ────────────────────────────────────────────── */
.topbar {
  position: fixed;
  top: 0; left: 0; right: 0;
  height: var(--topbar-h);
  background: var(--blue);
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 20px;
  z-index: 100;
  box-shadow: 0 2px 8px rgba(0,0,0,0.3);
}
.topbar-logo {
  font-size: 18px;
  font-weight: 700;
  color: var(--white);
  letter-spacing: 0.5px;
}
.topbar-accent { color: #5DADE2; }
.topbar-right {
  display: flex;
  align-items: center;
  gap: 12px;
}
.user-avatar {
  width: 32px; height: 32px;
  border-radius: 50%;
  object-fit: cover;
  border: 2px solid rgba(255,255,255,0.3);
}
.user-name { color: var(--white); font-size: 13px; }
.btn-logout {
  color: rgba(255,255,255,0.7);
  font-size: 12px;
  padding: 4px 10px;
  border: 1px solid rgba(255,255,255,0.3);
  border-radius: 4px;
  transition: all 0.15s;
}
.btn-logout:hover {
  background: rgba(255,255,255,0.15);
  color: var(--white);
  text-decoration: none;
}

/* ── LAYOUT ────────────────────────────────────────────── */
.layout {
  display: flex;
  min-height: 100vh;
  padding-top: var(--topbar-h);
}

/* ── SIDEBAR ───────────────────────────────────────────── */
.sidebar {
  width: var(--sidebar-w);
  background: var(--sidebar-bg);
  position: fixed;
  top: var(--topbar-h);
  bottom: 0;
  left: 0;
  display: flex;
  flex-direction: column;
  padding: 12px 0;
  overflow-y: auto;
  z-index: 90;
}
.nav-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 16px;
  color: rgba(255,255,255,0.75);
  font-size: 13px;
  transition: background 0.15s, color 0.15s;
  border-left: 3px solid transparent;
  text-decoration: none;
}
.nav-item:hover {
  background: rgba(255,255,255,0.1);
  color: var(--white);
  text-decoration: none;
}
.nav-item.active {
  background: rgba(255,255,255,0.15);
  color: var(--white);
  border-left-color: #5DADE2;
  font-weight: 600;
.nav-icon {
  font-size: 16px;
  width: 28px; height: 28px;
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
  /* v0.13.97 — Sin caja blanca por defecto. La caja blanca aparece
     SOLO en la opción activa (donde el usuario está) o en grupos
     pinned/open por clic del usuario. */
  background: transparent;
  border-radius: 6px;
  transition: background-color .15s, box-shadow .15s;
}
/* La caja blanca aparece SOLO en estos casos: item activo (página
   actual), grupo padre de un sub-item activo (.nav-group-header.open
   añadido server-side cuando `active in [sub-items]`), grupo con
   submenú pinned u open por clic del usuario. */
.nav-item.active .nav-icon,
.nav-group-header.open .nav-icon,
.nav-group.is-pinned > .nav-group-header .nav-icon,
.nav-group.is-open   > .nav-group-header .nav-icon {
  background: #ffffff;
  box-shadow: 0 1px 3px rgba(0,0,0,0.18);
}
.nav-label {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  flex: 1;
}

  background: rgba(255,255,255,.13);
  border-radius: 6px;
}
.nav-spacer { flex: 1; }
.nav-divider { height: 1px; background: rgba(255,255,255,.12); margin: 6px 12px; }
.nav-logout  { border-top: 1px solid rgba(255,255,255,0.1); margin-top: 8px; }

/* ── NAV GROUP (Mantenimientos colapsable) ──────────────────── */
.nav-group-header {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 16px;
  color: rgba(255,255,255,.6);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .07em;
  text-transform: uppercase;
  cursor: pointer;
  border-left: 3px solid transparent;
  transition: background .15s, color .15s;
  user-select: none;
}
.nav-group-header:hover { background: rgba(255,255,255,.10); color: #fff; }
.nav-group-header.open  {
  color: #fff;
  background: rgba(255,255,255,0.20);   /* v0.9.1 — destacado claro al tener submenú abierto */
  border-left-color: #5DADE2;
}
.nav-group-header.open .nav-icon {
  background: #ffffff;
  box-shadow: 0 1px 3px rgba(0,0,0,0.18);
}
.nav-group-header .nav-icon { font-size: 16px; background: rgba(255,255,255,.10); }
.nav-group-arrow {
  margin-left: auto;
  font-size: 10px;
  transition: transform .2s;
  opacity: .5;
}
.nav-group-header.open .nav-group-arrow { transform: rotate(180deg); }

/* ── Subgrupos: 2 modos (v0.13.97) ─────────────────────────────────────
   EXPANDIDO: accordion inline (se abre hacia abajo dentro del sidebar).
   COLAPSADO: flyout flotante a la derecha, centrado verticalmente sobre
   el icono padre (top calculado por JS con clamping a viewport).
   Sin position:fixed en expandido (era una invención que daba problemas).
   Toda la coordinación cliente-side via .is-pinned y .is-active en el
   .nav-group (single source of truth, sin race conditions). */
.nav-group { position: relative; }

/* ── EXPANDIDO: accordion inline ────────────────────────────────── */
.sidebar:not(.sidebar-collapsed) .nav-group-children {
  background: var(--sidebar-flyout-bg);
  overflow: hidden;
  max-height: 0;
  transition: max-height .2s ease;
}
.sidebar:not(.sidebar-collapsed) .nav-group.is-open > .nav-group-children {
  max-height: 600px;  /* generoso: ningún grupo real llega */
}
.sidebar:not(.sidebar-collapsed) .nav-group-children .nav-item {
  padding-left: 38px;
  font-size: 13px;
}
.sidebar:not(.sidebar-collapsed) .nav-group-children .nav-icon {
  width: 24px; height: 24px; font-size: 14px;
  background: transparent;  /* sin caja blanca en sub-items */
  box-shadow: none;
}
.sidebar:not(.sidebar-collapsed) .nav-group-children .nav-flyout-title {
  display: none;  /* en expandido no hace falta título — ya lo da el header del grupo */
}

/* ── MAIN CONTENT ──────────────────────────────────────── */
.main-content {
  margin-left: var(--sidebar-w);
  flex: 1;
  padding: 24px;
  min-height: calc(100vh - var(--topbar-h) - 40px);
}

/* ── FOOTER ────────────────────────────────────────────── */
.footer {
  margin-left: var(--sidebar-w);
  text-align: center;
  padding: 12px;
  font-size: 12px;
  color: var(--text-muted);
  border-top: 1px solid var(--gray-border);
  background: var(--white);
}
.footer .footer-link {
  color: #1d4e82;
  text-decoration: none;
  font-weight: 600;
  padding: 2px 8px;
  border-radius: 6px;
  transition: background-color .12s, color .12s;
}
.footer .footer-link:hover {
  background: #1d4e82;
  color: #fff;
}

/* ── PAGE HEADER ───────────────────────────────────────── */
.page-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 20px;
  flex-wrap: wrap;
  gap: 8px;
}
.page-header h2 {
  font-size: 20px;
  color: var(--blue);
  font-weight: 700;
}
.page-subtitle {
  font-size: 15px;            /* v0.10.49 — antes 13px, demasiado discreto */
  color: var(--text);          /* v0.10.49 — antes muted; el subtítulo es info principal */
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}
.page-subtitle strong { font-size: 16px; }   /* v0.10.49 nombre del item un punto mayor */
.badge-tipo {
  padding: 4px 12px;             /* v0.10.49 — antes 2px 10px */
  border-radius: 12px;
  font-size: 12px;               /* v0.10.49 — antes 11px */
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .03em;
}
.badge-caso         { background: var(--blue-pale);  color: var(--blue); }
.badge-comunicacion { background: var(--green-pale); color: var(--green); }
.badge-id {
  background: var(--gray-bg);
  border: 1px solid var(--gray-border);
  padding: 1px 8px;
  border-radius: 10px;
  font-size: 11px;
  color: var(--text-muted);
}

/* ── ALERTS ────────────────────────────────────────────── */
.alert {
  /* v0.15.63 — añadido layout flex + boton cerrar.
     Pedido por Javi 2026-05-28: los banners de "Mail enviado",
     "SMS disparado", etc. no se podian cerrar. */
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 16px;
  border-radius: 6px;
  margin-bottom: 16px;
  font-size: 13px;
  border-left: 4px solid;
}
.alert-success { background: var(--green-pale);  border-color: var(--green); color: #1A5C38; }
.alert-error   { background: var(--red-pale);    border-color: var(--red);   color: #6B1A1A; }
.alert-warning { background: var(--orange-pale); border-color: var(--orange);color: #7D3C00; }
.alert > .alert-body { flex: 1; min-width: 0; }
.alert > .alert-close {
  /* v0.15.63 — boton cerrar reutilizable. JS delegado en base.html
     escucha clicks y oculta el .alert padre con animacion suave. */
  background: none;
  border: none;
  cursor: pointer;
  font-size: 18px;
  line-height: 1;
  padding: 4px 8px;
  color: inherit;
  opacity: .55;
  transition: opacity .15s, transform .15s;
  flex-shrink: 0;
  border-radius: 4px;
}
.alert > .alert-close:hover  { opacity: 1; transform: scale(1.1); background: rgba(0,0,0,.06); }
.alert > .alert-close:active { transform: scale(.95); }
.alert.alert-closing {
  /* Animacion de salida al cerrar (opacity + max-height a 0). */
  opacity: 0;
  max-height: 0 !important;
  margin-bottom: 0 !important;
  padding-top: 0 !important;
  padding-bottom: 0 !important;
  overflow: hidden;
  transition: opacity .2s ease-out, max-height .25s ease-out,
              margin-bottom .2s, padding .2s;
}

/* ── CARDS DASHBOARD ───────────────────────────────────── */
.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 16px;
  margin-bottom: 24px;
}
.card {
  background: var(--white);
  border-radius: 10px;
  padding: 24px 20px;
  text-align: center;
  box-shadow: 0 2px 8px rgba(0,0,0,0.07);
  text-decoration: none;
  transition: transform 0.15s, box-shadow 0.15s;
  display: block;
}
.card:hover { transform: translateY(-2px); box-shadow: 0 6px 16px rgba(0,0,0,0.12); text-decoration: none; }
.card-icon  { font-size: 36px; margin-bottom: 10px; }
.card-label { font-size: 16px; font-weight: 700; margin-bottom: 4px; }
.card-desc  { font-size: 12px; color: var(--text-muted); }
.card-blue   { border-top: 4px solid var(--blue);   color: var(--blue); }
.card-green  { border-top: 4px solid var(--green);  color: var(--green); }
.card-orange { border-top: 4px solid var(--orange); color: var(--orange); }

/* ── INFO BOX ──────────────────────────────────────────── */
.info-box {
  background: var(--blue-pale);
  border: 1px solid #A9CCE3;
  border-radius: 8px;
  padding: 14px 18px;
  font-size: 13px;
  color: var(--blue);
  line-height: 1.6;
}

/* ── FORM CARD ─────────────────────────────────────────── */
.form-card {
  background: var(--white);
  border-radius: 10px;
  padding: 24px;
  margin-bottom: 20px;
  box-shadow: 0 2px 8px rgba(0,0,0,0.06);
}
.form-section-title {
  font-size: 13px;
  font-weight: 700;
  color: var(--blue);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  margin-bottom: 16px;
  padding-bottom: 8px;
  border-bottom: 2px solid var(--blue-pale);
}
.form-row {
  margin-bottom: 14px;
}
.form-row label {
  display: block;
  font-size: 14px;
  font-weight: 600;
  color: var(--text-muted);
  margin-bottom: 5px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.form-control {
  width: 100%;
  padding: 8px 12px;
  border: 1.5px solid var(--gray-border);
  border-radius: 6px;
  font-size: 15px;
  font-family: inherit;
  color: var(--text);
  background: #FAFAFA;
  transition: border-color 0.15s;
  outline: none;
}
.form-control:focus { border-color: var(--blue-light); background: var(--white); }
textarea.form-control { resize: vertical; }
.form-hint { font-size: 11px; color: var(--text-muted); margin-top: 4px; }
.req { color: var(--red); }

/* v0.15.93 — Fila de label con boton "Copiar direccion" a la derecha
   (notarias / registros en el formulario de mail). */
.nr-label-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 5px;
}
.nr-label-row label { margin-bottom: 0; }
.nr-copy-btn {
  font-size: 13px;
  font-weight: 600;
  text-transform: none;
  white-space: nowrap;
  padding: 3px 10px;
  border: 1px solid var(--border, #cbd5e1);
  border-radius: 6px;
  background: #fff;
  color: #2563eb;
  cursor: pointer;
}
.nr-copy-btn:hover { background: #eff6ff; }

/* ALFIN-83 — Boton compacto "Copiar correo" (texto plano, compatible Outlook).
   Aparece junto a los emails de contacto en Informacion general / Contactos. */
.btn-copy-email {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin-left: 6px;
  padding: 0 6px;
  height: 20px;
  min-width: 24px;
  font-size: 13px;
  line-height: 1;
  vertical-align: middle;
  background: #eef2f7;
  color: #334155;
  border: 1px solid var(--border, #cbd5e1);
  border-radius: 5px;
  cursor: pointer;
}
.btn-copy-email:hover { background: #e2e8f0; }
.btn-copy-email.copiado { background: #e8f5e9; border-color: #a5d6a7; color: #2e7d32; }
.nr-copy-btn.copiado {
  background: #ecfdf5;
  border-color: #10b981;
  color: #065f46;
}

.form-grid-2 {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0 20px;
}
@media (max-width: 640px) {
  .form-grid-2 { grid-template-columns: 1fr; }
}

/* Asunto con prefijo */
.asunto-wrapper {
  display: flex;
  align-items: center;
  gap: 8px;
}
.asunto-prefix {
  background: var(--blue-pale);
  color: var(--blue);
  padding: 8px 10px;
  border-radius: 6px;
  font-size: 12px;
  font-weight: 700;
  white-space: nowrap;
  border: 1.5px solid #A9CCE3;
}

/* v0.11.21 — Botón ↻ adyacente al Asunto del compose mail.
   Toggle entre default y valor previo. */
.btn-asunto-toggle {
  flex-shrink: 0;
  background: transparent;
  border: 1.5px solid var(--gray-border);
  color: var(--text-muted);
  width: 36px; height: 36px;
  border-radius: 6px;
  font-size: 16px; font-weight: 700;
  cursor: pointer;
  transition: all .12s;
}
.btn-asunto-toggle:hover {
  background: var(--blue-pale);
  border-color: var(--blue);
  color: var(--blue);
}
.btn-asunto-toggle:active {
  transform: rotate(-180deg);
  transition: transform .25s;
}

/* ── FORM ACTIONS ──────────────────────────────────────── */
.form-actions {
  display: flex;
  gap: 12px;
  margin-top: 8px;
}

/* ── BUTTONS ───────────────────────────────────────────── */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 9px 18px;
  border-radius: 6px;
  font-size: 13px;
  font-weight: 600;
  font-family: inherit;
  cursor: pointer;
  border: none;
  text-decoration: none;
  transition: background 0.15s, opacity 0.15s;
}
.btn:hover { opacity: 0.88; text-decoration: none; }
.btn:disabled { opacity: 0.55; cursor: not-allowed; }

.btn-primary   { background: var(--green);      color: var(--white); }
.btn-secondary { background: var(--gray-border); color: var(--text); }
.btn-danger    { background: var(--red);         color: var(--white); }
.btn-edit      { background: var(--blue-pale);   color: var(--blue);  border: 1px solid #A9CCE3; }

/* v1.4.68 — Botón "Vista previa" de facturación (emisión individual y
   varios herederos): antes .btn-secondary gris con el icono 📄, que
   apenas se apreciaba. Rayas diagonales verde-pálido/gris (mismo verde
   que .btn-primary) — evocan la marca de agua "VISTA PREVIA" del propio
   PDF. Mockup aprobado: docs/mockups/boton_vista_previa_v1.html
   (Opción A). Un único selector para que los dos sitios sean SIEMPRE
   visualmente idénticos (regla 36). */
.btn-preview-fac {
  color: #14532d;
  background: repeating-linear-gradient(
    45deg,
    var(--green-pale) 0px, var(--green-pale) 10px,
    #eef2f0 10px, #eef2f0 20px
  );
  border: 1px solid #bbdfc9;
}
/* v1.4.70 — icono 👁️ más grande sin que el botón crezca de alto: el
   glyph usa font-size mayor que el texto pero un line-height FIJO menor
   (no depende de line-height:1 = font-size, que sí podría empujar la
   caja). Verificado con getBoundingClientRect en Chrome real: los 4
   candidatos midieron 37.00px de alto igual que el botón sin icono —
   se eligió este por ser el determinista, no por coincidencia de fuente. */
.btn-preview-fac-ico {
  font-size: 17px;
  line-height: 14px;
  display: inline-block;
  /* v1.4.70 (code-review) — vertical-align:middle no tenia efecto real:
     .btn es display:inline-flex (linea ~556), el centrado lo da
     align-items:center del padre, no vertical-align. Quitado (CSS
     inerte). Centrado optico verificado con captura real, no solo con
     la altura del boton (getBoundingClientRect no basta — regla 35). */
}

.btn-sm { padding: 5px 10px; font-size: 12px; }

/* ── FICHEROS GRID ─────────────────────────────────────── */
.ficheros-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 8px;
}
.fichero-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  background: var(--gray-bg);
  border: 1.5px solid var(--gray-border);
  border-radius: 6px;
  cursor: pointer;
  font-size: 13px;
  transition: border-color 0.15s, background 0.15s;
}
.fichero-item:hover { border-color: var(--blue-light); background: var(--blue-pale); }
.fichero-item input[type="checkbox"] { width: 16px; height: 16px; accent-color: var(--blue); }
.fichero-name { flex: 1; word-break: break-all; line-height: 1.3; }

/* Subgrupos Facturas / Minutas */
.ficheros-subgrupo {
  margin-top: 16px;
  padding-top: 14px;
  border-top: 1.5px solid var(--gray-border);
}
.ficheros-subgrupo-titulo {
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-muted, #666);
  margin-bottom: 10px;
}

/* ── TABLE CARD ────────────────────────────────────────── */
.table-card {
  background: var(--white);
  border-radius: 10px;
  padding: 20px;
  box-shadow: 0 2px 8px rgba(0,0,0,0.06);
}
.search-input {
  max-width: 360px;
  margin-bottom: 16px;
}
.tabla {
  width: 100%;
  border-collapse: collapse;
  font-size: 14px;
}
.tabla thead tr {
  background: var(--blue);
  color: var(--white);
}
.tabla th {
  padding: 8px 12px;
  text-align: left;
  font-weight: 600;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

/* v0.10.51 — Cabeceras ordenables (clase .sortable). El JS hace el sort
   y aplica .s-asc / .s-desc para el indicador. La cabecera responde con
   un fondo más claro al pasar y la flecha aparece pegada al texto. */
.tabla th.sortable {
  cursor: pointer; user-select: none;
  transition: background .12s;
  position: relative;
}
.tabla th.sortable:hover { background: rgba(255,255,255,.08); }
.tabla th.sortable::after {
  content: ' ⇅';
  font-size: 9px;
  opacity: .35;
  letter-spacing: 0;
}
.tabla th.sortable.s-asc::after  { content: ' ▲'; opacity: .9; }
.tabla th.sortable.s-desc::after { content: ' ▼'; opacity: .9; }

/* v0.10.51 — Segunda fila de descripciones en thead (tipografía clara,
   distinta de la cabecera principal pero coherente con ella). Se aplica
   añadiendo <tr class="thead-desc"> dentro del <thead>. */
.tabla thead tr.thead-desc th {
  background: #f1f5f9;
  color: var(--text-muted);
  font-size: 11px;
  font-weight: 500;
  text-transform: none;
  letter-spacing: 0;
  padding: 5px 12px;
  font-style: italic;
  border-top: 1px solid #cbd5e1;
  border-bottom: 1px solid #cbd5e1;
}
.tabla td {
  padding: 8px 12px;
  border-bottom: 1px solid var(--gray-border);
  vertical-align: middle;
}
.tabla tbody tr:hover { background: var(--blue-pale); }
.tabla tbody tr:last-child td { border-bottom: none; }
.actions-cell { white-space: nowrap; display: flex; gap: 6px; align-items: center; }
.empty-row { text-align: center; color: var(--text-muted); padding: 32px; }

/* ── Search input con botón ×  para limpiar ─────────────── */
.search-wrap {
  position: relative;
  display: inline-flex;
  align-items: center;
}
.search-wrap .quick-search {
  padding-right: 26px;
}
.btn-clear-search {
  position: absolute;
  right: 5px;
  background: none;
  border: none;
  cursor: pointer;
  color: var(--text-muted);
  font-size: 14px;
  line-height: 1;
  padding: 2px 4px;
  border-radius: 3px;
  display: none;
}
.btn-clear-search:hover { color: var(--text); background: var(--gray-border); }

/* v0.14.49 — Quick-search modo "búsqueda global" (≥5 chars).
   v0.14.53 — Ahora es AJAX puro (sin recarga). El input cambia de
   color para indicar modo global; un spinner sutil se muestra
   durante la fetch. */
.search-wrap .quick-search.quick-search-global {
  background: #eff6ff;          /* azul muy claro */
  border-color: #2563eb;        /* azul */
  box-shadow: 0 0 0 2px rgba(37, 99, 235, 0.15);
}
.search-wrap .quick-search.quick-search-global:focus {
  outline: none;
  box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.25);
}
/* v0.14.53 — Spinner sutil mientras hay una fetch en curso. */
.search-wrap {
  position: relative;
}
.search-wrap .quick-search.quick-search-searching {
  background-image: linear-gradient(90deg,
    transparent 0%, rgba(37, 99, 235, 0.15) 50%, transparent 100%);
  background-size: 200% 100%;
  animation: quick-search-shimmer 1.2s linear infinite;
}
@keyframes quick-search-shimmer {
  0%   { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}

/* ── Tabla comunicaciones: padding compacto, sólo aquí ───── */
.tabla-com td,
.tabla-com th { padding: 4px 8px; }

/* ── Cabecera doble (dos campos en una columna) ───────────── */
.th-double-sort {
  padding: 0;
  vertical-align: top;
  cursor: default;
  min-width: 160px;
}
.th-sort-line {
  display: block;
  padding: 4px 8px;
  cursor: pointer;
  font-size: 12px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  line-height: 1.3;
  white-space: nowrap;
  transition: background 0.12s;
  user-select: none;
}
.th-sort-line:first-child {
  border-bottom: 1px solid rgba(255,255,255,0.20);
}
.th-sort-line:hover { background: rgba(255,255,255,0.13); }
.th-sort-line .sort-icon { font-style: normal; }

/* ────────────────────────────────────────────────────────────
   v0.13.69 — Hint de cabecera para columnas clicables
   ────────────────────────────────────────────────────────────
   Convención visual: cuando las CELDAS de una columna abren un
   detalle (al hacer click sobre el texto), su CABECERA lleva un
   icono pequeño junto al título — NO se repite en cada celda
   (eso sería ruido).

   - new-tab: gris claro sobre la cabecera azul oscura → indica
              "click abre en pestaña nueva".
   - same-tab: negro sobre azul oscuro → indica "click abre en la
              misma pestaña, vas a salir de aquí".

   Decisión del usuario (chat 2026-05-15) tras consensuar que el
   rojo carga semántica de error y no encaja con la idea de
   "abrir fuera". A muchos usuarios les molestan demasiadas
   pestañas — el icono ayuda a decidir antes de hacer click.

   USO EN HTML:
     <th> Tipo <i class="th-link-hint new-tab"
                  title="Click abre expediente en pestaña nueva">↗</i> </th>
     <th> Fuente <i class="th-link-hint same-tab"
                    title="Click navega a la fuente">↗</i> </th>
*/
.th-link-hint {
  display: inline-block;
  margin-left: 4px;
  font-style: normal;
  font-size: 11px;
  vertical-align: 1px;
  line-height: 1;
  opacity: 0.85;
}
.th-link-hint.new-tab  { color: #cbd5e1; }  /* gris claro sobre azul oscuro */
.th-link-hint.same-tab { color: #000;    }  /* negro sobre azul oscuro */

/* Hint en cabecera con fondo claro (p.ej. thead-desc o paneles
   no-azul). Usa la opacidad y el color base mejor. */
.thead-desc .th-link-hint.new-tab  { color: var(--text-muted); }
.thead-desc .th-link-hint.same-tab { color: #000; }

/* ── Celda doble (Fallecido arriba, Contacto abajo) ──────── */
.td-double { vertical-align: middle; }
.td-line1 {
  font-weight: 600;
  line-height: 1.35;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.td-line2 {
  color: var(--text-muted);
  line-height: 1.35;
  margin-top: 2px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.td-line2 a { color: var(--text-muted); }
.td-line2 a:hover { color: var(--blue); }

/* ── LOGIN ─────────────────────────────────────────────── */
.login-body {
  background: var(--blue);
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 100vh;
}
.login-card {
  background: var(--white);
  border-radius: 14px;
  padding: 40px 36px;
  width: 100%;
  max-width: 380px;
  text-align: center;
  box-shadow: 0 8px 32px rgba(0,0,0,0.25);
}
.login-header { margin-bottom: 28px; }
.login-logo {
  font-size: 48px;
  margin-bottom: 8px;
  display: block;
}
.login-header h1 {
  font-size: 26px;
  color: var(--blue);
  font-weight: 700;
  margin-bottom: 4px;
}
.login-header p { color: var(--text-muted); font-size: 13px; }
.accent { color: #5DADE2; }

.btn-google {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  padding: 12px;
  background: var(--white);
  border: 2px solid var(--gray-border);
  border-radius: 8px;
  font-size: 14px;
  font-weight: 600;
  color: var(--text);
  cursor: pointer;
  text-decoration: none;
  transition: border-color 0.15s, box-shadow 0.15s;
  margin-bottom: 16px;
}
.btn-google:hover {
  border-color: var(--blue-light);
  box-shadow: 0 2px 8px rgba(0,0,0,0.1);
  text-decoration: none;
}
.login-note { font-size: 11px; color: var(--text-muted); margin-top: 12px; }

/* v0.11.19 — Toggle Marca AVISO (pill switch 1-clic).
   Render JSON: <span class="aviso-toggle [aviso-on]"> con .aviso-track,
   .aviso-thumb y .aviso-label. JS en static/js/aviso-toggle.js. */
.aviso-toggle {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  cursor: pointer;
  user-select: none;
  vertical-align: middle;
}
.aviso-toggle:focus-visible {
  outline: 2px solid #1d4e82;
  outline-offset: 2px;
  border-radius: 16px;
}
.aviso-toggle .aviso-track {
  position: relative;
  display: inline-block;
  width: 42px;
  height: 22px;
  background: #d1d5db;             /* gris OFF */
  border-radius: 22px;
  transition: background-color .15s ease;
}
.aviso-toggle .aviso-thumb {
  position: absolute;
  top: 3px;
  left: 3px;
  width: 16px;
  height: 16px;
  background: #fff;
  border-radius: 50%;
  box-shadow: 0 1px 2px rgba(0,0,0,0.2);
  transition: left .15s ease;
}
.aviso-toggle .aviso-label {
  font-size: 12px;
  font-weight: 700;
  color: var(--text-muted);
  letter-spacing: .03em;
}
.aviso-toggle.aviso-on .aviso-track {
  background: #dc2626;             /* rojo ON — coherente con red text en listas */
}
.aviso-toggle.aviso-on .aviso-thumb {
  left: 23px;
}
.aviso-toggle.aviso-on .aviso-label {
  color: #dc2626;
}
.aviso-toggle.aviso-busy {
  opacity: 0.6;
  cursor: wait;
}

/* v0.12.17 — Toggle de Documentación (carpeta verde/roja).
   Mismo patrón delegated que .aviso-toggle. El SVG cambia entre
   carpeta cerrada (verde, activo) y carpeta abierta (roja, inactivo)
   sólo con clases CSS — sin recargar el SVG. */
.doc-toggle {
  display: inline-flex;
  align-items: center; justify-content: center;
  cursor: pointer; user-select: none;
  padding: 2px;
  border-radius: 6px;
  transition: background-color 0.15s ease;
  outline: none;
}
.doc-toggle:hover { background: #f1f5f9; }
.doc-toggle:focus-visible {
  background: #e0e7ff;
  box-shadow: 0 0 0 2px var(--blue, #2563eb);
}
.doc-toggle .doc-icon {
  width: 22px; height: 22px;
  transition: color 0.15s ease, transform 0.15s ease;
}
.doc-toggle:hover .doc-icon { transform: scale(1.08); }

/* Estado por defecto (INACTIVO): mostramos carpeta abierta roja. */
.doc-toggle .doc-icon-on  { display: none;  color: #16a34a; }
.doc-toggle .doc-icon-off { display: block; color: #dc2626; }
/* Estado ACTIVO: mostramos carpeta cerrada verde. */
.doc-toggle.doc-on .doc-icon-on  { display: block; }
.doc-toggle.doc-on .doc-icon-off { display: none; }

.doc-toggle.doc-busy { opacity: 0.55; cursor: wait; }

/* Variantes de tamaño */
.doc-toggle-sm .doc-icon { width: 18px; height: 18px; }
.doc-toggle-lg .doc-icon { width: 26px; height: 26px; }

/* Cabecera de tabla con el icono — más pequeño, sin hover */
.tabla th.th-doc { width: 38px; text-align: center; }
.tabla td.td-doc { text-align: center; padding: 2px 4px; }

/* v0.11.21 — Item del sidebar deshabilitado (consulta en desarrollo).
   No clicable, color tenue, badge "Próximamente" a la derecha. */
.sidebar .nav-item.nav-disabled {
  color: var(--text-muted);
  opacity: 0.55;
  cursor: not-allowed;
  pointer-events: auto; /* mantenemos hover para tooltip nativo */
}
.sidebar .nav-item.nav-disabled:hover {
  background: transparent;
  color: var(--text-muted);
}
.sidebar .nav-item.nav-disabled .nav-badge-soon {
  margin-left: auto;
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: #b45309;
  background: #fef3c7;
  padding: 1px 6px;
  border-radius: 9px;
  white-space: nowrap;
}
/* En sidebar colapsado el badge se oculta (solo se ve el icono). */
.sidebar.sidebar-collapsed .nav-badge-soon { display: none; }

/* v0.11.21 — Barra del breadcrumb del detalle con botón Recordatorio
   alineado a la derecha. Reemplaza el div suelto del breadcrumb sin
   tocar el resto del layout. */
.detalle-breadcrumb-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 8px;
}
.detalle-breadcrumb-bar .breadcrumb-text {
  font-size: 12px;
  color: var(--text-muted);
  flex: 1;
  min-width: 0;
}
.detalle-breadcrumb-bar > button {
  flex-shrink: 0;
}

/* v0.14.3 — Badge "⚠️ Documentación Revocada" en el `div.tabs` de los
   detalles. Se posiciona como ÚLTIMO HIJO del .tabs con margin-left:auto
   (alineado al extremo derecho, en el espacio sobrante después de las
   pestañas). Solo aparece si la entidad tiene ≥1 documento Drive revocado.
   Click → abre Drive Compartido en pestaña nueva, pre-filtrado.
   Partial: templates/_badge_doc_revocada.html. */
.tab-doc-revocada {
  margin-left: auto;
  align-self: center;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: #fff3f3;
  color: #c53030;
  border: 1px solid #fca5a5;
  padding: 5px 12px;
  border-radius: 14px;
  font-size: 11px;
  font-weight: 700;
  text-decoration: none;
  margin-right: 6px;
  margin-bottom: 4px;
  cursor: pointer;
  transition: background-color .15s, color .15s, border-color .15s, transform .15s;
  white-space: nowrap;
}
.tab-doc-revocada:hover {
  background: #fee2e2;
  color: #991b1b;
  border-color: #f87171;
  text-decoration: none;
  transform: translateY(-1px);
}
.tab-doc-revocada-count {
  background: #c53030;
  color: #fff;
  border-radius: 9px;
  padding: 1px 7px;
  font-size: 10px;
  font-weight: 800;
}
.tab-doc-revocada-ext {
  font-size: 10px;
  opacity: .7;
  margin-left: 2px;
}

/* v0.11.43 — Botón ↺ refresh en cabecera verde de detalle.
   Posicionado absolute top-right, casi invisible en reposo (opacity .55),
   rota 180° en hover como feedback visual de "recargar". */
.dh-refresh {
  position: absolute;
  top: 7px;
  right: 10px;
  background: none;
  border: none;
  cursor: pointer;
  font-size: 15px;
  line-height: 1;
  padding: 4px 5px;
  border-radius: 4px;
  opacity: .55;
  transition: opacity .15s, transform .3s;
  color: inherit;
}
.dh-refresh:hover {
  opacity: 1;
  transform: rotate(180deg);
}
/* v1.4.59 — Pildora "📖 Guía" en las fichas: arriba a la derecha, a la IZQUIERDA
   del ↺ (que NO se toca). Posicionamiento absoluto igual que .dh-refresh. */
.dh-guia { position: absolute; top: 5px; right: 44px; }

/* v0.11.49 — Estados del refresh parcial (botones .dh-refresh y .cola-refresh-btn).
   - is-refreshing: rotación continua mientras se hace fetch
   - refresh-success: pulso verde 600ms tras éxito
   - refresh-error: shake horizontal + color rojo
   El selector aplica a CUALQUIER botón con esas clases para que la misma
   animación valga para los botones del footer/cola/etc. */
@keyframes alfin-spin {
  from { transform: rotate(0deg);   }
  to   { transform: rotate(360deg); }
}
@keyframes alfin-pulse-success {
  0%   { box-shadow: 0 0 0 0 rgba(22, 163, 74, .55); }
  100% { box-shadow: 0 0 0 10px rgba(22, 163, 74, 0); }
}
@keyframes alfin-shake {
  0%, 100% { transform: translateX(0); }
  20%      { transform: translateX(-4px); }
  40%      { transform: translateX(4px); }
  60%      { transform: translateX(-3px); }
  80%      { transform: translateX(3px); }
}
.dh-refresh.is-refreshing,
.cola-refresh-btn.is-refreshing {
  animation: alfin-spin .8s linear infinite;
  opacity: 1;
  cursor: progress;
  /* Anular el rotate(180deg) del :hover para que no choque con la animación */
  transform: none;
  pointer-events: none;
}
.dh-refresh.refresh-success,
.cola-refresh-btn.refresh-success {
  color: #16a34a;
  opacity: 1;
  animation: alfin-pulse-success .6s ease-out;
}
.dh-refresh.refresh-error,
.cola-refresh-btn.refresh-error {
  color: #dc2626;
  opacity: 1;
  animation: alfin-shake .4s;
}
.dh-refresh[disabled],
.cola-refresh-btn[disabled] { cursor: progress; }

/* v0.11.49 — Indicador "Actualizado hace X" en el footer.
   Posicionado absolute en el extremo derecho del footer (que está fixed
   en bottom y centrado). No interfiere con el contenido centrado
   (copyright + versión + FAQ) cuando el ancho es suficiente; en pantallas
   estrechas pasa a esconderse vía media query. */
.footer-refresh-indicator {
  position: absolute;
  right: 14px;
  top: 50%;
  transform: translateY(-50%);
  font-size: 11px;
  color: #94a3b8;
  font-style: italic;
  user-select: none;
  pointer-events: auto;
  cursor: default;
}
@media (max-width: 900px) {
  .footer-refresh-indicator { display: none; }
}

/* v0.11.19 — Columna y fila marcadas con AVISO en los listados.
   - .th-aviso / .td-aviso: ancho compacto, centrado.
   - .aviso-flag: icono 🚩 con un toque más grande para legibilidad.
   - tr.aviso-on: todo el texto del registro en rojo. Los badges con
     color explícito (estado, tipoCaso) conservan su color porque
     usan inline color, no inherit.
*/
.tabla .th-aviso,
.tabla .td-aviso {
  width: 30px;
  text-align: center;
  padding-left: 4px;
  padding-right: 4px;
}
.tabla .aviso-flag {
  font-size: 14px;
  line-height: 1;
}
.tabla tr.aviso-on { color: #dc2626; }
.tabla tr.aviso-on a { color: #dc2626; }
.tabla tr.aviso-on a:hover { color: #991b1b; }
.tabla tr.aviso-on .td-line2 { color: #dc2626; }

/* v0.14.47 — Bandera 🚩 INLINE clickable en consultas.
   v0.14.51 — FIX: el emoji 🚩 no respeta CSS `color`. Sustituido por
   SVG inline con `fill="currentColor"` para que el color del span
   sí se herede al icono. Ahora el color del usuario activador se
   ve correctamente en la bandera (antes se veía igual a todos).

   - .aviso-flag-inline (sin .on): bandera "fantasma", gris #9ca3af
     desde el inline style, opacidad reducida para sugerir "inactiva
     pero clickable".
   - .aviso-flag-inline.on: bandera activa, saturada, con el color
     hex del usuario activador en el inline style.
   - hover: scale + opacidad plena (también en fantasma para feedback).
*/
.tabla .aviso-flag-inline {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  cursor: pointer;
  user-select: none;
  padding: 2px;
  border-radius: 4px;
  transition: transform .12s, opacity .12s, background-color .12s;
  opacity: 0.45;       /* fantasma cuando inactiva */
}
.tabla .aviso-flag-inline .aviso-flag-svg {
  width: 100%;
  height: 100%;
  fill: currentColor;  /* heredamos el color inline del span */
  display: block;
}
.tabla .aviso-flag-inline.on {
  opacity: 1;          /* saturado cuando activa */
}
.tabla .aviso-flag-inline:hover {
  transform: scale(1.18);
  opacity: 1;          /* hover muestra siempre color plenamente */
  background-color: rgba(0, 0, 0, 0.05);
}
.tabla .aviso-flag-inline:active {
  transform: scale(0.92);
}
.tabla .aviso-flag-inline:focus-visible {
  outline: 2px solid #2563eb;
  outline-offset: 2px;
}
.tabla .aviso-flag-inline.aviso-busy {
  opacity: 0.5;
  pointer-events: none;
}

/* v0.14.51 — Atribución de aviso en páginas de DETALLE (caso,
   comunicación, expediente). Filas con fecha + usuario.
   v0.14.57 — Estandarizadas al tamaño del resto de info-row:
   info-value 14px (heredado), info-label 13px (heredado). Sin
   reducir 12px (decisión del cliente: legibilidad uniforme). */
.info-row.aviso-atrib-row {
  color: var(--text-muted, #64748b);
}
[data-aviso-atrib-fecha] {
  font-family: ui-monospace, SFMono-Regular, Consolas, monospace;
}
.aviso-atrib-sep {
  margin: 0 6px;
  opacity: 0.5;
}
[data-aviso-atrib-usuario] strong {
  font-weight: 700;
  letter-spacing: 0.02em;
}

/* v0.11.19 — Footer en la pantalla de login (standalone, sin sidebar).
   No usa la clase .footer común porque esa tiene margin-left para alinear
   con el sidebar; en login no hay sidebar y queremos centrado puro. */
.login-footer {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  text-align: center;
  padding: 10px 12px;
  font-size: 12px;
  color: rgba(255, 255, 255, 0.85);
  background: transparent;
}

/* ── ERROR PAGE ────────────────────────────────────────── */
.error-page {
  text-align: center;
  padding: 60px 20px;
}
.error-icon { font-size: 56px; margin-bottom: 16px; }
.error-page h2 { color: var(--red); margin-bottom: 20px; }

/* ═══════════════════════════════════════════════════════
   v0.2.0 — Nuevos estilos
   ═══════════════════════════════════════════════════════ */

/* ── BUSCADOR GLOBAL ───────────────────────────────────── */
.topbar-search {
  flex: 1;
  max-width: 520px;
  margin: 0 24px;
  position: relative;
}
.search-wrapper { position: relative; }
.search-input-top {
  width: 100%;
  padding: 7px 14px;
  border: 1.5px solid rgba(255,255,255,0.25);
  border-radius: 20px;
  background: rgba(255,255,255,0.12);
  color: #fff;
  font-size: 13px;
  outline: none;
  transition: background 0.15s, border-color 0.15s;
}
.search-input-top::placeholder { color: rgba(255,255,255,0.55); }
.search-input-top:focus {
  background: rgba(255,255,255,0.2);
  border-color: rgba(255,255,255,0.5);
}
.search-results {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  /* v1.4.67 — el panel ya no hereda el ancho del input (antes left:0;right:0):
     720px de sitio para nombre + código + fecha + A/C sin cortes ni scroll
     horizontal. min() lo protege en ventanas estrechas. */
  width: min(720px, calc(100vw - 40px));
  background: #fff;
  border-radius: 8px;
  box-shadow: 0 8px 24px rgba(0,0,0,0.18);
  z-index: 9999;
  max-height: 420px;
  overflow-y: auto;
  overflow-x: hidden;
  border: 1px solid #e2e8f0;
}
.sr-group {
  padding: 8px 14px 4px;
  font-size: 13px;  /* v1.4.66 — regla 30 (antes 11px) */
  font-weight: 700;
  color: var(--blue);
  text-transform: uppercase;
  letter-spacing: .06em;
  background: var(--blue-pale);
}
/* v1.4.67 — AQUI vivia un .sr-item duplicado (display:flex fila +
   align-items:center + flex-wrap) anterior al bloque definitivo de mas
   abajo. Su align-items:center nunca fue anulado y, al quitar v1.4.66 el
   envoltorio .sr-body, centraba y encogia cada linea del resultado (la
   "chapuza" que vio Javi en TEST). Duplicados .sr-code/.sr-name/.sr-contact/
   .sr-phone eliminados tambien: la definicion unica esta en el bloque
   "diseño C". NO redefinir .sr-* aqui. */
.sr-empty { padding: 16px; text-align: center; color: var(--text-muted); font-size: 13px; }
.sr-more  { padding: 6px 12px 8px; text-align: center; color: var(--text-muted); font-size: 13px; font-style: italic; background: #f9fafb; }  /* v1.4.64 */
/* v1.4.66 — el botón de la app antigua es el icono «A» (.sr-favicon);
   el ↗ de v1.4.65 se eliminó a petición de Javi. */

/* ── Zebra stripes para tablas ────────────────────────── */
.tabla-std tbody tr:nth-child(even) { background-color: #f9fafb; }
.tabla-std tbody tr:hover { background-color: #f3f4f6; }

/* ── Changelog scroll container (v0.6.3) ──────────────── */
.cl-scroll-container {
  max-height: calc(100vh - 240px);
  overflow-y: auto;
  border-radius: 0 0 10px 10px;
}

/* ── MENÚ USUARIO DROPDOWN ─────────────────────────────── */
.user-menu { position: relative; }
.user-menu-btn {
  display: flex;
  align-items: center;
  gap: 8px;
  background: none;
  border: none;
  cursor: pointer;
  padding: 4px 8px;
  border-radius: 6px;
  transition: background 0.15s;
}
.user-menu-btn:hover { background: rgba(255,255,255,0.1); }
.user-chevron { color: rgba(255,255,255,0.6); font-size: 11px; }
.user-dropdown {
  display: none;
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  background: #fff;
  border-radius: 8px;
  box-shadow: 0 8px 24px rgba(0,0,0,0.15);
  border: 1px solid #e2e8f0;
  min-width: 250px;
  max-width: 400px;
  z-index: 9999;
  overflow: hidden;
  white-space: nowrap;
}
.user-dropdown.open { display: block; }
.user-dropdown-header {
  padding: 12px 16px;
  background: var(--gray-bg);
}
.user-dropdown-header strong { display: block; font-size: 13px; color: var(--text); }
.user-dropdown-header small  { font-size: 11px; color: var(--text-muted); }
.dropdown-divider { border: none; border-top: 1px solid #e2e8f0; margin: 0; }
.dropdown-item {
  display: block;
  width: 100%;
  padding: 10px 16px;
  text-align: left;
  background: none;
  border: none;
  font-size: 13px;
  color: var(--text);
  cursor: pointer;
  text-decoration: none;
  transition: background 0.1s;
  font-family: inherit;
}
.dropdown-item:hover { background: var(--blue-pale); text-decoration: none; }
.dropdown-item-danger { color: var(--red); }
.dropdown-item-danger:hover { background: var(--red-pale); }

/* ── TOAST ─────────────────────────────────────────────── */
#toast {
  position: fixed;
  bottom: 24px;
  right: 24px;
  padding: 12px 20px;
  border-radius: 8px;
  font-size: 13px;
  font-weight: 600;
  z-index: 99999;
  box-shadow: 0 4px 16px rgba(0,0,0,0.15);
  display: none;
}
.toast-success { background: var(--green); color: #fff; }
.toast-error   { background: var(--red);   color: #fff; }

/* ── FILTROS PANEL ─────────────────────────────────────── */
.filtros-panel {
  background: #fff;
  border-radius: 10px;
  box-shadow: 0 2px 8px rgba(0,0,0,0.06);
  margin-bottom: 16px;
  overflow: hidden;
}
/* v0.13.71 — Cuando el panel de filtros está abierto, permitir
   `overflow: visible` para que los popovers del multiselect
   Opción D (`.msd-pop` con position:absolute) puedan sobresalir
   hacia abajo del panel sin que el `overflow: hidden` global los
   recorte. Si el panel está cerrado, se mantiene `overflow: hidden`
   para que las esquinas redondeadas top recorten bien la cabecera
   azul. Bug detectado en /expedientes/por-notaria-registro pero la
   solución es global y beneficia a cualquier listado futuro que
   incluya multiselect (o cualquier popover/dropdown) dentro del
   panel de filtros. */
.filtros-panel.open {
  overflow: visible;
}
.filtros-header {
  display: flex;
  justify-content: space-between;
  /* v0.14.21 — `align-items: flex-start` permite que el resumen
     multilínea (.filtros-resumen) crezca sin centrarse mal con el
     título "🔍 Filtros [activos]". Para 1 línea sigue viéndose igual
     porque no hay diferencia entre flex-start y center cuando todos
     los items tienen la misma altura. */
  align-items: flex-start;
  /* v0.14.21 — gap entre las 3 zonas: título, resumen, chevron. */
  gap: 10px;
  /* v0.13.59 — padding reducido (era 12px 20px) — sin cambiar font-size. */
  padding: 8px 16px;
  cursor: pointer;
  font-size: 13px;
  font-weight: 600;
  color: var(--blue);
  background: var(--blue-pale);
  user-select: none;
}
.filtros-header-titulo {
  /* v0.14.21 — Nuevo wrap del "🔍 Filtros [activos]". `flex: 0 0 auto`
     evita que se encoja cuando el resumen es muy ancho. Antes el
     <span> directo no necesitaba esto porque no había hermanos
     flexibles. */
  flex: 0 0 auto;
}

/* v0.14.33 — Botón "quitar filtros" inline (icono ✕) visible en el
   header del panel CERRADO cuando hay filtros activos.
   Atajo para no tener que abrir el panel y pulsar el "✖ Quitar
   filtros" de abajo. Decisión usuario v0.14.33:
   - Sin texto, solo el icono ✕.
   - Estilo rojo destructivo (convención de "limpiar formulario").
   - Sin confirmación previa (los filtros se re-aplican fácilmente).
   - Posición: a la izquierda del título (antes del 🔍).
   El click NO debe disparar el `toggleFiltros()` del padre — se hace
   con `event.stopPropagation()` en el onclick del propio botón. */
.filtros-quitar-inline {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  background: #dc2626;       /* rojo destructivo */
  color: #fff;
  border-radius: 4px;
  font-size: 12px;
  font-weight: 700;
  line-height: 1;
  text-decoration: none;
  cursor: pointer;
  transition: background 0.12s, transform 0.12s;
  user-select: none;
}
.filtros-quitar-inline:hover {
  background: #b91c1c;       /* hover más oscuro */
  text-decoration: none;
  color: #fff;
  transform: scale(1.08);
}
.filtros-quitar-inline:active {
  transform: scale(0.95);
}
.filtros-chevron {
  transition: transform 0.2s;
  font-size: 16px;
  /* v0.14.21 — el chevron va siempre a la derecha y nunca se encoge. */
  flex: 0 0 auto;
  margin-left: auto;
}
.filtros-panel.open .filtros-chevron { transform: rotate(180deg); }

/* v0.14.21 — Resumen inline de filtros activos en la cabecera.
   - Aparece cuando el panel está CERRADO (default) y hay filtros activos.
   - Se oculta cuando el panel está abierto (los inputs ya muestran todo).
   - Wrap a multilínea si hay muchos items (decisión del usuario:
     prefiere multilínea a truncar con `…`).
   - El JS `filtros_resumen.js` rellena dinámicamente este div leyendo
     el `<form id="filtrosForm">`. Si el JS no se carga, queda vacío
     (degrado elegante — el badge "activos" sigue avisando). */
.filtros-resumen {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 6px 14px;                  /* row-gap 6px, col-gap 14px */
  font-size: 13px;
  font-weight: 500;
  color: var(--text);
  /* Pequeño ajuste vertical para alinear con el badge "activos". */
  padding-top: 1px;
}
.filtros-resumen-item {
  white-space: nowrap;             /* el item entero no se parte */
}
.filtros-resumen-key {
  font-weight: 700;
  color: var(--blue);
}
/* Cuando el panel está abierto, el resumen se oculta — los inputs ya
   muestran los valores. */
.filtros-panel.open .filtros-resumen { display: none; }
.filtros-body {
  display: none;
  /* v0.13.59 — padding reducido (era 16px 20px). */
  padding: 10px 14px;
}
.filtros-panel.open .filtros-body { display: block; }
/* v0.13.59 — badge "activos" más legible (13 px en lugar de 10 px,
   se quedaba microscópico) y con una animación intermitente cada 5 s:
   la mayor parte del tiempo está quieto (92 % del ciclo), y en el último
   8 % hace un pulse breve (halo box-shadow + ligero scale) que llama la
   atención periféricamente sin distraer al usuario que está trabajando.
   Sólo afecta al badge cuando hay filtros activos — si no, ni se renderiza. */
.filtros-activos-badge {
  background: var(--orange);
  color: #fff;
  padding: 2px 10px;
  border-radius: 10px;
  font-size: 13px;
  font-weight: 600;
  margin-left: 8px;
  display: inline-block;
  animation: activosTwinkle 5s ease-out infinite;
  transform-origin: center;
}
@keyframes activosTwinkle {
  /* 0-92 %: reposo absoluto */
  0%, 92% {
    background: var(--orange);
    box-shadow: 0 0 0 0 rgba(230, 126, 34, 0);
    transform: scale(1);
  }
  /* 94 %: punto álgido del pulse (0,2 s del ciclo) */
  94% {
    background: #F5B041;
    box-shadow: 0 0 0 6px rgba(230, 126, 34, 0.35);
    transform: scale(1.08);
  }
  /* 100 %: vuelta a reposo (continuidad con el siguiente ciclo) */
  100% {
    background: var(--orange);
    box-shadow: 0 0 0 12px rgba(230, 126, 34, 0);
    transform: scale(1);
  }
}
/* Respeta `prefers-reduced-motion`: si el SO tiene "reducir movimiento"
   activado (accesibilidad), se desactiva la animación pero se conserva
   el color y tamaño legible. */
@media (prefers-reduced-motion: reduce) {
  .filtros-activos-badge { animation: none; }
}
.filtros-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  /* v0.13.59 — gap y margin-bottom reducidos. */
  gap: 8px 12px;
  margin-bottom: 10px;
}
.filtro-item label {
  display: block;
  font-size: 14px;
  font-weight: 600;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: .04em;
  margin-bottom: 4px;
}
.filtro-check { display: flex; align-items: center; padding-top: 18px; }
.filtro-check label {
  display: flex;
  align-items: center;
  gap: 6px;
  text-transform: none;
  font-size: 15px;
  color: var(--text);
  cursor: pointer;
}
.form-control-sm {
  padding: 5px 10px;
  font-size: 15px;
}
.filtros-actions {
  display: flex;
  gap: 10px;
  padding-top: 4px;
}
.btn-sm { padding: 6px 14px; font-size: 13px; }

/* ── TABLA MEJORADA ────────────────────────────────────── */
.table-toolbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 12px;
  flex-wrap: wrap;
  gap: 8px;
}
.table-info { font-size: 15px; color: var(--text-muted); }
.per-page-selector {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 15px;
  color: var(--text-muted);
}
.per-page-btn {
  padding: 3px 8px;
  border: 1px solid var(--gray-border);
  border-radius: 4px;
  font-size: 15px;
  color: var(--text-muted);
  text-decoration: none;
  transition: all 0.1s;
}
.per-page-btn:hover { border-color: var(--blue-light); color: var(--blue); text-decoration: none; }
.per-page-btn.active { background: var(--blue); color: #fff; border-color: var(--blue); }
.table-responsive { overflow-x: auto; }
.tabla-striped tbody tr:nth-child(odd) { background: var(--gray-bg); }
.td-num { color: var(--text-muted); font-size: 14px; text-align: right; width: 40px; }
.td-center { text-align: center; }
.badge-count {
  background: var(--blue-pale);
  color: var(--blue);
  padding: 3px 12px;
  border-radius: 12px;
  font-size: 15px;
  font-weight: 600;
}
.badge-estado {
  background: var(--gray-bg);
  border: 1px solid var(--gray-border);
  padding: 2px 8px;
  border-radius: 10px;
  font-size: 14px;
  white-space: nowrap;
}
a.badge-estado-link {
  text-decoration: none;
  color: inherit;
  cursor: pointer;
}
a.badge-estado-link:hover {
  background: #e2e8f0;
  text-decoration: none;
}
.td-truncate {
  display: inline-block;
  max-width: 130px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  vertical-align: bottom;
}
.link-fecha {
  color: #374151;
  text-decoration: none;
  white-space: nowrap;
}
.link-fecha:hover { text-decoration: underline; color: var(--primary); }
.link-drive {
  color: #374151;
  text-decoration: none;
}
.link-drive:hover { color: #1a73e8; text-decoration: underline; }

/* ── PAGINACIÓN ────────────────────────────────────────── */
.pagination {
  display: flex;
  gap: 4px;
  justify-content: center;
  padding: 16px 0 4px;
  flex-wrap: wrap;
}
.page-btn {
  padding: 5px 10px;
  border: 1px solid var(--gray-border);
  border-radius: 5px;
  font-size: 15px;
  color: var(--text-muted);
  text-decoration: none;
  transition: all 0.1s;
  min-width: 34px;
  text-align: center;
}
.page-btn:hover { border-color: var(--blue-light); color: var(--blue); text-decoration: none; }
.page-btn.active { background: var(--blue); color: #fff; border-color: var(--blue); }

/* ── TOGGLE LINKS/ADJUNTOS ─────────────────────────────── */
.toggle-links-wrapper {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-left: auto;
  float: right;
}
.toggle-label { font-size: 12px; color: var(--text-muted); font-weight: 600; }
.toggle-switch { position: relative; display: inline-block; width: 42px; height: 22px; }
.toggle-switch input { opacity: 0; width: 0; height: 0; }
.toggle-slider {
  position: absolute; cursor: pointer;
  top: 0; left: 0; right: 0; bottom: 0;
  background: var(--gray-border);
  border-radius: 22px;
  transition: .2s;
}
.toggle-slider:before {
  content: "";
  position: absolute;
  height: 16px; width: 16px;
  left: 3px; bottom: 3px;
  background: white;
  border-radius: 50%;
  transition: .2s;
}
input:checked + .toggle-slider { background: var(--green); }
input:checked + .toggle-slider:before { transform: translateX(20px); }

/* ── QUILL OVERRIDES ───────────────────────────────────── */
.ql-container { font-family: Arial, sans-serif; font-size: 14px; }
.ql-toolbar { border-radius: 6px 6px 0 0; border-color: var(--gray-border) !important; }
.ql-container { border-radius: 0 0 6px 6px; border-color: var(--gray-border) !important; }

/* ═══════════════════════════════════════════════════════
   v0.3.0 — Sidebar colapsable, sticky header, filtros inline
   ═══════════════════════════════════════════════════════ */

/* ── SIDEBAR TOGGLE BUTTON ─────────────────────────────── */
.sidebar-toggle {
  background: none;
  border: none;
  color: rgba(255,255,255,0.8);
  font-size: 18px;
  cursor: pointer;
  padding: 4px 8px;
  border-radius: 4px;
  margin-right: 8px;
  transition: background 0.15s;
  line-height: 1;
}
.sidebar-toggle:hover { background: rgba(255,255,255,0.15); }

/* ── SIDEBAR COLAPSADO ─────────────────────────────────── */
.sidebar.sidebar-collapsed {
  width: 52px;
}
.sidebar.sidebar-collapsed .nav-label { display: none; }
.sidebar.sidebar-collapsed .nav-item  { justify-content: center; padding: 12px 0; }
.sidebar.sidebar-collapsed .nav-icon  { font-size: 18px; width: auto; }

.main-content.sidebar-collapsed { margin-left: 52px; }
.footer.sidebar-collapsed       { margin-left: 52px; }

/* ── Sidebar colapsado: flyout de grupos al hover ──────── */
.sidebar.sidebar-collapsed .nav-group { position: relative; }
.sidebar.sidebar-collapsed .nav-group-header {
  justify-content: center;
  padding: 12px 0;
}
.sidebar.sidebar-collapsed .nav-group-header .nav-icon { font-size: 18px; }
.sidebar.sidebar-collapsed .nav-group-arrow { display: none; }
/* v0.13.97 — Flotante en sidebar COLAPSADO. La posición top la calcula
   JS centrando vertically sobre el icono padre con clamping a viewport.
   Visibilidad controlada por clases .is-pinned / .is-active en el
   .nav-group (puestas por JS), no por server-side .open. */
.sidebar.sidebar-collapsed .nav-group-children {
  /* anular accordion del modo expandido */
  max-height: none;
  overflow: visible;

  position: fixed;
  left: 52px;            /* el JS no toca esto */
  /* top → lo pone JS */
  width: 240px;
  background: var(--sidebar-flyout-bg);
  border-left: 1px solid rgba(255,255,255,0.18);
  border-radius: 0 8px 8px 0;
  box-shadow: 6px 6px 18px rgba(0,0,0,0.28);
  display: none;
  max-height: calc(100vh - 16px);
  overflow-y: auto;
  z-index: 200;
  padding: 4px 0;
}
.sidebar.sidebar-collapsed .nav-group.is-pinned > .nav-group-children,
.sidebar.sidebar-collapsed .nav-group.is-active > .nav-group-children {
  display: block;
}

.sidebar.sidebar-collapsed .nav-group-children .nav-flyout-title {
  display: block;
  font-size: 11px; font-weight: 700;
  color: rgba(255,255,255,0.85);
  text-transform: uppercase;
  letter-spacing: .07em;
  padding: 8px 18px;
  border-bottom: 1px solid rgba(255,255,255,0.18);
  margin-bottom: 4px;
}
.sidebar.sidebar-collapsed .nav-group-children .nav-item {
  padding: 10px 18px !important;
  justify-content: flex-start !important;
  font-size: 14px;
}
.sidebar.sidebar-collapsed .nav-group-children .nav-label {
  display: block !important;
  font-size: 14px;
  font-weight: 500;
}
.sidebar.sidebar-collapsed .nav-group-children .nav-icon {
  width: 26px; height: 26px; font-size: 15px;
}
/* Ocultar title en sidebar expandido cuando NO está dentro del flyout */
.nav-flyout-title { display: none; }

/* Transición suave */
.sidebar, .main-content, .footer {
  transition: width 0.2s, margin-left 0.2s;
}

/* ── STICKY TABLE HEADER ───────────────────────────────── */
.tabla-sticky thead tr.thead-cols th {
  position: sticky;
  top: 0;
  z-index: 30;
  background: var(--blue);
  color: var(--white);
  will-change: transform;
}
.tabla-sticky thead tr.thead-inline-filters th {
  position: sticky;
  top: 41px; /* altura de la fila de cabeceras */
  z-index: 29;
  background: #f0f4f8;
  padding: 4px 6px;
  will-change: transform;
}
.table-responsive {
  max-height: calc(100vh - 300px);
  overflow-y: auto;
}

/* ── FILTROS INLINE ────────────────────────────────────── */
.inline-filter {
  width: 100%;
  padding: 3px 6px;
  font-size: 11px;
  border: 1px solid var(--gray-border);
  border-radius: 4px;
  background: var(--white);
  outline: none;
}
.inline-filter:focus { border-color: var(--blue-light); }

/* ── TABLA TOOLBAR DERECHA ─────────────────────────────── */
.table-toolbar-right {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}
.quick-search {
  width: 200px;
}

/* ── CABECERAS ORDENABLES ──────────────────────────────── */
.th-sort {
  user-select: none;
  white-space: nowrap;
}
.th-sort:hover { background: #2E5A8E !important; }
.sort-icon { font-size: 10px; opacity: 0.8; }

/* ── FICHEROS 4 COLUMNAS ───────────────────────────────── */
.ficheros-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 8px;
}
@media (max-width: 900px) {
  .ficheros-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 540px) {
  .ficheros-grid { grid-template-columns: 1fr; }
}

/* ═══════════════════════════════════════════════════════
   v0.3.0 — Sidebar colapsable, sticky header, filtros inline
   ═══════════════════════════════════════════════════════ */

/* ── SIDEBAR COLAPSABLE ────────────────────────────────── */
.sidebar-toggle {
  background: none;
  border: none;
  color: rgba(255,255,255,0.8);
  font-size: 18px;
  cursor: pointer;
  padding: 4px 8px;
  border-radius: 4px;
  margin-right: 8px;
  transition: background 0.15s;
}
.sidebar-toggle:hover { background: rgba(255,255,255,0.15); color: #fff; }

.sidebar {
  transition: width 0.2s ease;
}
.sidebar.collapsed {
  width: 52px;
}
.sidebar.collapsed .nav-label {
  display: none;
}
.sidebar.collapsed .nav-item {
  justify-content: center;
  padding: 12px 0;
}
.sidebar.collapsed .nav-icon {
  font-size: 18px;
  width: auto;
}

.layout.sidebar-collapsed .main-content {
  margin-left: 52px;
}
.footer.sidebar-collapsed {
  margin-left: 52px;
}

/* ── STICKY HEADER ─────────────────────────────────────── */
.tabla-sticky thead tr.thead-main th {
  position: sticky;
  top: 0;
  z-index: 30;
  background: var(--blue);
  color: var(--white);
  box-shadow: 0 2px 4px rgba(0,0,0,0.15);
  will-change: transform;
}
.tabla-sticky thead tr.thead-inline-filters th {
  position: sticky;
  top: 41px; /* altura de la fila de cabeceras */
  z-index: 29;
  background: #f0f4f8;
  padding: 4px 6px;
  will-change: transform;
}
.table-responsive {
  max-height: calc(100vh - 280px);
  overflow-y: auto;
}

/* ── FILTROS INLINE ────────────────────────────────────── */
.thead-inline-filters .inline-filter {
  width: 100%;
  padding: 3px 6px;
  font-size: 11px;
  border: 1px solid var(--gray-border);
  border-radius: 4px;
  background: #fff;
  outline: none;
}
.thead-inline-filters .inline-filter:focus {
  border-color: var(--blue-light);
}

/* ── TOOLBAR MEJORADA ──────────────────────────────────── */
.table-toolbar-right {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}
.quick-search {
  width: 220px;
}

/* ── TH SORT ───────────────────────────────────────────── */
.th-sort {
  user-select: none;
  white-space: nowrap;
}
.th-sort:hover {
  background: #16314f !important;
}
.sort-icon {
  font-size: 10px;
  color: rgba(255,255,255,0.7);
}

/* ── FICHEROS 4 COLUMNAS ───────────────────────────────── */
.ficheros-grid {
  grid-template-columns: repeat(4, 1fr) !important;
}
@media (max-width: 900px) {
  .ficheros-grid { grid-template-columns: repeat(2, 1fr) !important; }
}
@media (max-width: 600px) {
  .ficheros-grid { grid-template-columns: 1fr !important; }
}

/* ═══════════════════════════════════════════════════════
   v0.3.1 — Toggle activo, layout fullpage, localidad badge
   ═══════════════════════════════════════════════════════ */

/* ── LAYOUT PÁGINA ALTURA FIJA (sin scroll de página) ─── */
html, body { height: 100%; overflow: hidden; }
.layout { height: calc(100vh - var(--topbar-h)); overflow: hidden; }
.main-content { overflow: hidden; display: flex; flex-direction: column; padding: 0; }
/* ── Contenedor de scroll interior (todas las páginas) ── */
.content-scroll {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  padding: 24px 24px 44px;
}
.footer { position: fixed; bottom: 0; left: var(--sidebar-w); right: 0;
          z-index: 80; padding: 6px 12px; font-size: 11px; }
.footer.sidebar-collapsed { left: 52px; }

/* Table fullpage: ocupa el espacio disponible */
.table-fullpage {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
  margin-bottom: 32px; /* espacio para footer fijo */
}
/* v0.13.59 — Padding interno reducido SOLO cuando es listado a página
   completa (table-card + table-fullpage). Los .table-card normales
   (p. ej. dentro de pestañas de detalle) mantienen su padding 20.
   Gana ~16 px de altura visible en cada listado — útil para ver una
   fila más sin scroll. */
.table-card.table-fullpage {
  padding: 12px;
}
.table-scroll-container {
  flex: 1;
  overflow-y: auto;
  overflow-x: auto;
  min-height: 0;
}

/* Sticky header relativo al scroll container.
   v0.11.45 — z-index subido a 30 (era 10) y will-change:transform para
   forzar stacking context propio en cada th. Sin esto, con border-collapse:collapse
   y scroll horizontal+vertical simultáneo, los tbody rows pueden aparecer
   encima del thead sticky (bug reproducible en Chrome/Edge). */
.table-scroll-container thead tr.thead-main th {
  position: sticky;
  top: 0;
  z-index: 30;
  background: var(--blue);
  color: var(--white);
  box-shadow: 0 2px 4px rgba(0,0,0,0.15);
  will-change: transform;
}
.table-scroll-container thead tr.thead-inline-filters th {
  position: sticky;
  top: 37px;
  z-index: 29;
  background: #f0f4f8;
  padding: 3px 4px;
  will-change: transform;
}

/* Quitar el max-height anterior que causaba doble scroll */
.table-responsive { max-height: none; overflow: visible; }

/* ── TOGGLE ACTIVO/INACTIVO EN LISTA ───────────────────── */
.toggle-activo-btn {
  padding: 3px 10px;
  border-radius: 12px;
  font-size: 11px;
  font-weight: 600;
  border: none;
  cursor: pointer;
  transition: all 0.15s;
  white-space: nowrap;
}
.toggle-activo-btn.activo {
  background: var(--green-pale);
  color: var(--green);
  border: 1px solid #9ae6b4;
}
.toggle-activo-btn.activo:hover {
  background: var(--red-pale);
  color: var(--red);
  border-color: #feb2b2;
}
.toggle-activo-btn.inactivo {
  background: var(--red-pale);
  color: var(--red);
  border: 1px solid #feb2b2;
}
.toggle-activo-btn.inactivo:hover {
  background: var(--green-pale);
  color: var(--green);
  border-color: #9ae6b4;
}
.row-inactivo td { opacity: 0.5; }

/* ── TOGGLE EN FORMULARIO ──────────────────────────────── */
.toggle-form-label {
  display: flex;
  align-items: center;
  gap: 10px;
  cursor: pointer;
  font-size: 13px;
}
.toggle-form-label input[type="checkbox"] {
  width: 18px; height: 18px;
  accent-color: var(--green);
  cursor: pointer;
}
.toggle-form-text { font-weight: 600; color: var(--text); }
.toggle-form-hint { font-size: 11px; color: var(--text-muted); }

/* ── LOCALIDAD BADGE CON TOOLTIP ───────────────────────── */
/* v0.14.7 — font-size 11px → 13px. Decisión usuario (A3): el badge
   se veía DEMASIADO pequeño en todas las pantallas que lo usan
   (comunicaciones, casos, expedientes, expedientes_por_notaria_registro,
   facturas, por_facturar). 13px lo acerca al 14px de la celda sin
   cambiar el resto del estilo (chip pastel, border, padding). */
.loc-badge {
  display: inline-block;
  padding: 2px 6px;
  background: var(--blue-pale);
  color: var(--blue);
  border-radius: 4px;
  font-size: 13px;
  font-weight: 700;
  cursor: default;
  border: 1px solid #a9cce3;
}

/* v0.14.15 — Iniciales de usuario en todas las celdas Usuario de las 6
   consultas (comunicaciones, casos, expedientes, expedientes_por_notaria_
   registro, facturas, por_facturar). Antes vivía como style inline solo
   en el partial _tabla_expedientes_por_notaria_registro.html — ahora
   clase global para evitar drift. Decisión 5A del informe Usuario.
   - font-family monospace: alineación visual entre filas (todas las
     iniciales tienen mismo ancho).
   - font-weight 700: las iniciales son el único dato corto en su
     columna; la negrita las hace identificables de un vistazo.
   - color var(--blue): coherente con el resto de elementos clicables/
     identitarios de la app (loc-badge usa el mismo blue).
   No lleva tooltip (decisión 4B — si el usuario quiere saber a quién
   corresponden las iniciales, abre el filtro y ve "INI - Nombre"). */
.user-iniciales {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-weight: 700;
  color: var(--blue);
  cursor: default;
}

/* ── PAGINACIÓN MEJORADA ──────────────────────────────── */
.pagination-inline {
  display: inline-flex;
  margin-left: 16px;
  padding: 0;
}
.toolbar-left {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 4px;
}
.page-btn.disabled {
  opacity: 0.35;
  pointer-events: none;
}

/* ── BUSCADOR GLOBAL MEJORADO v0.3.2 ──────────────────── */
.topbar-search { max-width: 640px; }
.search-results { min-width: 560px; }

.sr-item {
  display: flex;
  flex-direction: column;
  align-items: stretch;   /* v1.4.67 — cada linea ocupa todo el ancho (nada centrado) */
  gap: 2px;
  padding: 8px 14px;
  border-bottom: 1px solid #f0f0f0;
  cursor: pointer;
  font-size: 13px;
}
.sr-item:hover { background: var(--blue-pale); }

/* v1.4.66 — diseño C (mockup v4): línea 1 = «A» · (*) · fallecido · código
   ····· fecha · A/C; debajo, renglones de contacto indentados a la altura
   del fallecido. Tipografía regla 30: nada por debajo de 13 px. */
.sr-l1 {
  display: flex;
  align-items: center;
  gap: 10px;
}
.sr-sec {
  display: flex;
  align-items: baseline;
  gap: 14px;
  flex-wrap: wrap;
  font-size: 13px;
  color: var(--text-muted);
  padding-left: 28px;   /* icono 18px + hueco 10px = a la altura del fallecido */
  margin-top: 2px;
}
.sr-code {
  font-family: Consolas, Menlo, monospace;
  font-weight: 600;
  color: #475569;
  white-space: nowrap;
  font-size: 13px;
  flex: 0 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;  /* códigos kilométricos (TMP-…) no expulsan fecha y A/C */
}
.sr-name {
  color: var(--text);
  font-size: 14px;
  font-weight: 700;
  flex: 0 1 auto;       /* anula el flex:1 antiguo; el hueco lo pone .sr-spacer */
  min-width: 250px;
}
.sr-spacer { flex: 1; }
.sr-fch {
  font-size: 13px;
  color: var(--text-muted);
  white-space: nowrap;
  flex-shrink: 0;
}
.sr-ac {
  width: 22px; height: 22px; border-radius: 50%; flex-shrink: 0; cursor: help;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 13px; font-weight: 800; border: 1.5px solid;
}
.sr-ac-a { background: #dcfce7; color: #166534; border-color: #86efac; }
.sr-ac-c { background: #e2e8f0; color: #475569; border-color: #cbd5e1; }
.sr-tipoexp { font-size: 14px; font-weight: 700; color: var(--text); }
.sr-contact { color: #334155; font-size: 13px; }
.sr-email   { color: #718096; font-style: italic; font-size: 13px; }
.sr-phone   { color: var(--green); white-space: nowrap; font-size: 13px; }

/* ── MAIL FORM SCROLL CONTAINER ────────────────────────── */
.mail-scroll-container {
  flex: 1;
  overflow-y: auto;
  overflow-x: hidden;
  min-height: 0;
  padding-bottom: 32px;
}

/* ── FICHEROS TITLE ROW v0.3.4 ─────────────────────────── */
.ficheros-title-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
}
.ficheros-title-actions {
  display: flex;
  align-items: center;
  gap: 16px;
}
.select-all-label {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  font-weight: 600;
  color: var(--text-muted);
  cursor: pointer;
  white-space: nowrap;
}
.select-all-label input[type="checkbox"] {
  width: 15px;
  height: 15px;
  accent-color: var(--blue);
  cursor: pointer;
}

/* ── DETALLE v0.3.9 ────────────────────────────────────── */
.link-detalle {
  color: var(--blue);
  text-decoration: none;
  font-weight: 600;
}
.link-detalle:hover { text-decoration: underline; }
.link-fallecido { color: var(--text); font-weight: 700; }
.link-fallecido:hover { color: var(--blue); }

/* ═══════════════════════════════════════════════════════
   v0.4.4 — Buscador mejorado: colores por tipo,
            botones de filtro, items con favicon
   ═══════════════════════════════════════════════════════ */

/* ── Barra de búsqueda: restaurar flex:1 y añadir filtros ─ */
.topbar-search {
  flex: 1;
  max-width: 640px;
  margin: 0 16px 0 24px;
  display: flex;
  align-items: center;
  gap: 8px;
}
.search-wrapper { flex: 1; position: relative; }

/* ── Botones de filtro junto al buscador ───────────────── */
.search-filter-btns {
  display: flex;
  gap: 3px;
  flex-shrink: 0;
}
.search-filter-btn {
  background: rgba(0,0,0,0.25);
  border: 1.5px solid rgba(255,255,255,0.15);
  color: rgba(255,255,255,0.3);
  border-radius: 8px;
  padding: 4px 8px;
  font-size: 14px;
  cursor: pointer;
  transition: all 0.15s;
  user-select: none;
  filter: grayscale(100%) opacity(40%);
}
.search-filter-btn.active {
  background: rgba(255,255,255,0.2);
  border-color: rgba(255,255,255,0.75);
  color: #fff;
  filter: none;
  box-shadow: inset 0 2px 4px rgba(0,0,0,0.25), 0 1px 0 rgba(255,255,255,0.15);
}
.search-filter-btn:hover { filter: none; color: #fff; background: rgba(255,255,255,0.15); }

/* ── Items del buscador con colores por tipo ───────────── */
.sr-item-caso { background: #ddeeff; }              /* azul  (= cabecera caso)        */
.sr-item-exp  { background: #fdecea; }              /* rojo  (= cabecera expediente)  v1.4.12 */
.sr-item-com  { background: #edfff4; }              /* verde (= cabecera comunicacion)*/

.sr-item-caso:hover { background: #cce3f8; }
.sr-item-exp:hover  { background: #f9d8d3; }        /* v1.4.12 */
.sr-item-com:hover  { background: #d5f7e4; }

/* ── Separación de items en gris oscuro ────────────────── */
.sr-item { border-bottom: 1px solid #aaa !important; cursor: pointer; text-align: left; }
.sr-item:last-child { border-bottom: none !important; }

/* ── Headers de grupo con colores ──────────────────────── */
.sr-group-caso { background: #c5d8f0; color: var(--blue); }
.sr-group-exp  { background: #f2cbc5; color: #8a2218; }   /* rojo, igual que la cabecera de expediente — v1.4.12 (antes azul por error) */
.sr-group-com  { background: #c5edd6; color: #1a5c38; }

/* ── Layout interno del item ────────────────────────────── */
.sr-item { cursor: pointer; }
.sr-l1   { text-align: left; }
.sr-sec  { text-align: left; }

/* ── Icono «A» de Alfin en la línea 1 — botón de la app antigua (v1.4.66) ── */
.sr-favicon {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
  border-radius: 3px;
  cursor: pointer;
  opacity: 0.75;
  transition: opacity 0.1s, transform 0.1s, box-shadow 0.1s;
  vertical-align: middle;
}
.sr-favicon:hover { opacity: 1; transform: scale(1.15); box-shadow: 0 0 0 2px #93c5fd; }

/* ── Check búsqueda ampliada ────────────────────────────── */
.search-ampliado-wrap {
  display: flex;
  align-items: center;
  gap: 3px;
  margin-left: 5px;
  padding-left: 5px;
  border-left: 1px solid rgba(255,255,255,0.2);
  cursor: pointer;
  user-select: none;
}
.search-ampliado-wrap input[type="checkbox"] {
  width: 11px;
  height: 11px;
  margin: 0;
  cursor: pointer;
  accent-color: #ffd700;
}
.sr-amp-lbl {
  font-size: 13px;
  font-weight: 700;
  color: rgba(255,255,255,0.4);
  line-height: 1;
  transition: color 0.15s;
}
.search-ampliado-wrap:has(input:checked) .sr-amp-lbl {
  color: #ffd700;
}

/* ── Marcador * en resultados de búsqueda ampliada ──────── */
.sr-ampliado {
  color: #e07b00;
  font-weight: 900;
  font-size: 13px;
  line-height: 1;
  flex-shrink: 0;
  cursor: default;
}

/* ── Mensaje buscando (búsqueda ampliada) ───────────────── */
.sr-buscando {
  padding: 10px 14px;
  color: #64748b;
  font-size: 13px;  /* v1.4.66 — regla 30 (antes 12px) */
  font-style: italic;
  text-align: center;
}

/* ── Página config búsquedas defecto ───────────────────── */
.config-card {
  background: #fff;
  border: 1px solid var(--gray-border);
  border-radius: 10px;
  padding: 28px 32px;
  max-width: 560px;
  margin: 0 auto;
}

/* ══════════════════════════════════════════════════
   v0.4.5 — Reenvío automático + mejoras Intentos
   ══════════════════════════════════════════════════ */
.ri { display:inline-flex;align-items:center;cursor:pointer;vertical-align:middle; }
.ri svg { width:28px;height:28px; }
.ri-sm svg { width:18px;height:18px; }
.ri-lg svg { width:32px;height:32px; }
.ri-activo { color:#16a34a; }
.ri-completo { color:#9ca3af; }
.ri-cancelado { color:#dc2626; }
.ri-reenviar-btn { color:#6b7280; text-decoration:none; }
.ri-reenviar-btn:hover { color:var(--blue); }
.reenvio-toggle { display:inline-flex;align-items:center;gap:6px;padding:5px 12px;border-radius:20px;cursor:pointer;font-size:12px;font-weight:600;border:2px solid #d1d5db;color:#6b7280;background:#f9fafb;transition:all 0.2s;user-select:none; }
.reenvio-toggle.activo { border-color:#16a34a;color:#16a34a;background:#f0fdf4; }
.reenvio-toggle svg { width:16px;height:16px; }
.th-reenvio,.td-reenvio { width:30px;text-align:center !important;padding:4px 2px !important; }

/* ── DÍAS SIN RESPUESTA — columna lista (v0.5.5) ───────── */
.th-dias { width:70px;text-align:center !important;white-space:nowrap; }
.td-dias { text-align:center !important;white-space:nowrap;padding:4px 4px !important; }
.badge-dias { display:inline-block;padding:2px 6px;border-radius:10px;font-size:11px;font-weight:700;vertical-align:middle; }
.badge-dias-auto { background:#fef3c7;color:#92400e;border:1px solid #fcd34d; }
.badge-dias-manual { background:#f3f4f6;color:#6b7280;border:1px solid #d1d5db; }
.btn-res-lista { display:inline-flex;align-items:center;justify-content:center;width:18px;height:18px;margin-left:3px;padding:0;border:none;border-radius:50%;background:#16a34a;color:#fff;font-size:10px;font-weight:700;cursor:pointer;vertical-align:middle;line-height:1;transition:background 0.15s,transform 0.1s; }
.btn-res-lista:hover { background:#15803d;transform:scale(1.15); }
/* ── Modal respondido desde lista ──────────────────────── */
/* v0.10.19 — eliminada regla duplicada `.modal-overlay { display:flex }` que
   pisaba a la regla canónica más abajo (línea ~2097, display:none) según
   el orden de aparición pero generaba dudas de cascada en cargas parciales.
   La definición buena vive en la sección "v0.9.7 — Modal genérico". */
/* ── Modal genérico reutilizable ────────────────────── */
.modal-box { background:#fff;border-radius:12px;box-shadow:0 8px 36px rgba(0,0,0,.25);width:min(780px,96vw);max-height:90vh;display:flex;flex-direction:column;overflow:hidden; }
.modal-header { display:flex;align-items:center;justify-content:space-between;padding:14px 20px 12px;border-bottom:1px solid #e5e7eb; }
.modal-header h3 { margin:0;font-size:16px;font-weight:700;color:#111827; }
.modal-close { background:none;border:none;font-size:22px;color:#6b7280;cursor:pointer;line-height:1;padding:0 4px;border-radius:4px; }
.modal-close:hover { background:#f3f4f6;color:#111827; }
.modal-body { flex:1;overflow-y:auto; }
.modal-footer { padding:10px 20px 14px;border-top:1px solid #e5e7eb;display:flex;justify-content:flex-end;gap:8px; }
.modal-respondido-box { background:#fff;border-radius:10px;box-shadow:0 8px 32px rgba(0,0,0,.22);width:min(520px,95vw);max-height:85vh;display:flex;flex-direction:column;overflow:hidden; }
.modal-respondido-hdr { display:flex;align-items:center;justify-content:space-between;padding:14px 18px 10px;border-bottom:1px solid #e5e7eb; }
.modal-respondido-hdr h3 { margin:0;font-size:15px;font-weight:700;color:#111827; }
.modal-respondido-close { background:none;border:none;font-size:20px;color:#6b7280;cursor:pointer;line-height:1;padding:0 4px;border-radius:4px; }
.modal-respondido-close:hover { background:#f3f4f6;color:#111827; }
.modal-respondido-sub { margin:0;padding:10px 18px 6px;font-size:12px;color:#6b7280;line-height:1.5; }
#modal-respondido-lista { overflow-y:auto;max-height:340px;padding:4px 10px 8px; }
.mri { display:flex;align-items:center;gap:10px;padding:9px 10px;border-radius:7px;cursor:pointer;transition:background 0.12s;border:1px solid transparent; }
.mri:hover,.mri:focus { background:#f0fdf4;border-color:#bbf7d0;outline:none; }
.mri-num { flex-shrink:0;width:22px;height:22px;border-radius:50%;background:#e5e7eb;color:#374151;font-size:11px;font-weight:700;display:flex;align-items:center;justify-content:center; }
.mri-body { flex:1;min-width:0; }
.mri-asunto { font-size:13px;font-weight:600;color:#111827;white-space:nowrap;overflow:hidden;text-overflow:ellipsis; }
.mri-dest { font-size:11px;color:#6b7280;margin-top:2px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis; }
.mri-dias { color:#d97706;font-weight:600; }
.mri-check { flex-shrink:0;width:22px;height:22px;border-radius:50%;background:#16a34a;color:#fff;font-size:12px;font-weight:700;display:flex;align-items:center;justify-content:center;opacity:0;transition:opacity 0.12s; }
.mri:hover .mri-check,.mri:focus .mri-check { opacity:1; }
.modal-respondido-ftr { padding:10px 18px 14px;border-top:1px solid #e5e7eb;display:flex;justify-content:space-between;align-items:center;gap:8px; }
/* v0.7.0 — Columnas check auto (verde) / manual (azul) */
.th-check-auto,.td-check-auto { width:26px;text-align:center !important;padding:4px 2px !important; }
.th-check-manual,.td-check-manual { width:26px;text-align:center !important;padding:4px 2px !important; }
.th-check-auto { color:#16a34a; }
.th-check-manual { color:#2563eb; }
.btn-res-auto { display:inline-flex;align-items:center;justify-content:center;width:18px;height:18px;padding:0;border:none;border-radius:50%;background:#16a34a;color:#fff;font-size:10px;font-weight:700;cursor:pointer;vertical-align:middle;line-height:1;transition:background 0.15s,transform 0.1s; }
.btn-res-auto:hover { background:#15803d;transform:scale(1.15); }
.btn-res-manual { display:inline-flex;align-items:center;justify-content:center;width:18px;height:18px;padding:0;border:none;border-radius:50%;background:#2563eb;color:#fff;font-size:10px;font-weight:700;cursor:pointer;vertical-align:middle;line-height:1;transition:background 0.15s,transform 0.1s; }
.btn-res-manual:hover { background:#1d4ed8;transform:scale(1.15); }
/* v0.7.0 — Modal azul mails manuales */
.modal-mails-box { background:#fff;border-radius:10px;box-shadow:0 8px 32px rgba(0,0,0,.22);width:min(580px,95vw);max-height:85vh;display:flex;flex-direction:column;overflow:hidden; }
.modal-mails-hdr { display:flex;align-items:center;justify-content:space-between;padding:14px 18px 10px;border-bottom:2px solid #bfdbfe;background:#eff6ff; }
.modal-mails-hdr h3 { margin:0;font-size:15px;font-weight:700;color:#1e40af; }
.modal-mails-close { background:none;border:none;font-size:20px;color:#3b82f6;cursor:pointer;line-height:1;padding:0 4px;border-radius:4px; }
.modal-mails-close:hover { background:#dbeafe;color:#1e40af; }
.modal-mails-sub { margin:0;padding:10px 18px 6px;font-size:12px;color:#3b82f6;line-height:1.5; }
#modal-mails-lista { overflow-y:auto;max-height:360px;padding:4px 10px 8px; }
.mri-azul { display:flex;align-items:center;gap:10px;padding:9px 10px;border-radius:7px;cursor:pointer;transition:background 0.12s;border:1px solid transparent; }
.mri-azul:hover,.mri-azul:focus { background:#eff6ff;border-color:#bfdbfe;outline:none; }
.mri-num-azul { flex-shrink:0;width:22px;height:22px;border-radius:50%;background:#dbeafe;color:#1e40af;font-size:11px;font-weight:700;display:flex;align-items:center;justify-content:center; }
.mri-check-azul { flex-shrink:0;width:22px;height:22px;border-radius:50%;background:#2563eb;color:#fff;font-size:12px;font-weight:700;display:flex;align-items:center;justify-content:center;opacity:0;transition:opacity 0.12s; }
.mri-azul:hover .mri-check-azul,.mri-azul:focus .mri-check-azul { opacity:1; }
.modal-mails-ftr { padding:10px 18px 14px;border-top:1px solid #dbeafe;display:flex;justify-content:space-between;align-items:center;gap:8px; }
/* Ampliar modal respondido verde */
.modal-respondido-box { width:min(580px,95vw); }

.notas-filtros { display:flex;gap:6px;margin-bottom:10px;flex-wrap:wrap;align-items:center; }
.nf-btn { padding:4px 10px;font-size:11px;font-weight:600;border:1px solid var(--gray-border);border-radius:14px;background:#fff;color:var(--text-muted);cursor:pointer;transition:all 0.15s; }
.nf-btn.active { background:var(--blue);color:#fff;border-color:var(--blue); }
.notas-toolbar { display:flex;justify-content:space-between;align-items:center;margin-bottom:10px;gap:8px;flex-wrap:wrap; }
.nota-tipo-03 { border-left:3px solid #3b82f6 !important; }
.nota-tipo-02 { border-left:3px solid #f97316 !important; }
.nota-tipo-01 { border-left:3px solid #9ca3af !important; }
.nota-reenvio-activo { background:linear-gradient(90deg,#f0fdf4,#fff) !important; }
.nota-reenvio-completo { opacity:0.85; }
.nota-body.collapsed { display:none; }
.nota-header { cursor:pointer; }
.nota-header:hover { background:#f8fafc !important; }
.nota-toggle-icon { font-size:10px;color:var(--text-muted);margin-right:5px; }
.badge-smtp { font-size:10px;padding:2px 6px;border-radius:10px;font-weight:700;margin-left:4px; }
.badge-smtp.ok { background:#dcfce7;color:#166534; }
.badge-smtp.err { background:#fee2e2;color:#991b1b; }
.nota-menu { position:relative;display:inline-block; }
.nota-menu-btn { background:none;border:none;cursor:pointer;color:var(--text-muted);font-size:16px;padding:0 6px;border-radius:4px;line-height:1; }
.nota-menu-btn:hover { background:var(--gray-border); }
.nota-menu-dropdown { display:none;position:absolute;right:0;top:100%;background:#fff;border:1px solid var(--gray-border);border-radius:6px;box-shadow:0 4px 12px rgba(0,0,0,.12);z-index:200;min-width:190px; }
.nota-menu-dropdown.open { display:block; }
.nota-menu-item { display:block;padding:8px 14px;font-size:12px;color:var(--text);cursor:pointer;white-space:nowrap;border:none;background:none;width:100%;text-align:left; }
.nota-menu-item:hover { background:var(--gray-bg); }
.nota-reenvio-hijo { margin-left:20px; }

/* ── DETALLE SCROLL (v0.4.6) ───────────────────────────── */
.detalle-scroll-container {
  flex: 1;
  overflow-y: auto;
  overflow-x: hidden;
  min-height: 0;
  padding-bottom: 40px;
}

/* ── REENVIO ESTADOS (v0.4.6) ──────────────────────────── */
.ri-pausado   { color: #f59e0b; }          /* amarillo */
.ri-enviado   { color: #3b82f6; }          /* azul     */
.ri-cancelado { color: #9ca3af; }          /* gris (override del rojo anterior) */
.nota-reenvio-pausado { background: linear-gradient(90deg,#fffbeb,#fff) !important; }

/* ── ADJUNTOS EN CARD NOTA (v0.4.6) ───────────────────── */
.nota-adjuntos { display:inline-flex;gap:4px;flex-wrap:wrap;margin-top:2px; }
.nota-adjunto-icon {
  display:inline-flex;align-items:center;
  color:var(--text-muted);text-decoration:none;
  padding:1px 3px;border-radius:3px;
  transition:color 0.15s,background 0.15s;
}
.nota-adjunto-icon:hover { color:var(--blue);background:var(--blue-pale); }
.nota-adjunto-icon svg  { width:24px;height:28px; }

/* ══════════════════════════════════════════════════════
   TIMELINE NOTAS / INTENTOS  (v0.5.7)
   ══════════════════════════════════════════════════════ */
/* Toolbar */
.tl-toolbar { display:flex;align-items:center;justify-content:space-between;margin-bottom:12px;gap:10px;flex-wrap:wrap; }
.tl-toolbar-left  { display:flex;align-items:center;gap:8px; }
/* v0.11.42 — grupo derecho: Cola Reenvíos + Leyenda + Expandir + Ordenar */
.tl-toolbar-right { display:flex;align-items:center;gap:8px;flex-wrap:wrap; }
/* v0.11.31 — align-items:center para que el widget de estado quede alineado con los botones */
.tl-filtros { display:flex;gap:6px;margin-bottom:14px;flex-wrap:wrap;align-items:center; }
/* ── Estado quick-change widget (v0.11.31) ─────────────────── */
.estado-quick-widget { display:inline-flex;align-items:center;gap:6px;padding:2px 0; }
.estado-quick-label { font-size:12px;font-weight:600;color:#6b7280;white-space:nowrap; }
.estado-quick-select { font-size:12px;padding:4px 8px;border:1px solid #d1d5db;border-radius:6px;background:#fff;color:#374151;cursor:pointer;outline:none;transition:border-color 0.15s; }
.estado-quick-select:hover { border-color:#93c5fd; }
.estado-quick-select:focus { border-color:var(--blue);box-shadow:0 0 0 2px rgba(59,130,246,.2); }
.estado-quick-fb { font-size:11px;font-weight:600;min-width:70px; }
.eq-guardando { color:#6b7280; }
.eq-ok  { color:#16a34a; }
.eq-error { color:#dc2626; }
/* Variante de etiqueta "Reenvío manual" (v0.11.31) */
.tl-lbl-manual { color:#7c3aed; }

/* Separador fecha */
.fecha-sep { display:flex;align-items:center;gap:10px;margin:18px 0 8px; }
.fecha-sep-line { flex:1;height:1px;background:#dde3ec; }
.fecha-sep-label { font-size:11px;font-weight:700;color:#94a3b8;text-transform:uppercase;letter-spacing:.07em;white-space:nowrap; }

/* Línea vertical del timeline */
.timeline-notas { position:relative;padding-left:58px; }
.timeline-notas::before { content:'';position:absolute;left:23px;top:0;bottom:0;width:2px;background:#e2e8f0; }

/* Item */
.tl-item { position:relative;margin-bottom:5px; }
.tl-icon { position:absolute;left:-45px;top:12px;width:38px;height:38px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:18px;border:2.5px solid #fff;box-shadow:0 1px 5px rgba(0,0,0,.14);z-index:1; }
.tl-icon-email   { background:#dbeafe; }
.tl-icon-llamada { background:#ffedd5; }
.tl-icon-nota    { background:#f1f5f9; }
.tl-icon-sms     { background:#f5f3ff; }
/* v0.13.85 — Notas con calendario (tipoNota='02') */
.tl-icon-calendar { background:#fef3c7; }
.tl-item.es-hijo { margin-left:32px; }
.tl-item.es-hijo .tl-icon { width:28px;height:28px;font-size:13px;left:-40px;top:14px; }

/* Tarjeta */
.tl-card-tl { background:#fff;border-radius:9px;border:1px solid #e2e8f0;overflow:visible;transition:box-shadow .13s; }
.tl-card-tl:hover { box-shadow:0 2px 10px rgba(0,0,0,.08); }
.tl-item.tipo-email   .tl-card-tl { border-left:3px solid #3b82f6; }
.tl-item.tipo-llamada .tl-card-tl { border-left:3px solid #f97316; }
.tl-item.tipo-nota    .tl-card-tl { border-left:3px solid #94a3b8; }
.tl-item.tipo-sms     .tl-card-tl { border-left:3px solid #8b5cf6; }
/* v0.13.85 — Calendario: naranja Google Calendar */
.tl-item.tipo-calendar .tl-card-tl { border-left:3px solid #f59e0b; }
.tl-evento-fecha {
  /* v0.13.89/v0.13.93 — `flex-basis:100%` + el `flex-wrap:wrap` que
     se añadió a `.tl-r1r` en v0.13.93 fuerzan a este sub-bloque a
     ocupar toda la fila, rompiendo a una segunda línea bajo la fecha
     de grabación. Antes (con solo width:100% y sin flex-wrap en el
     padre) los flex items quedaban en la misma línea apretados. */
  display: flex; align-items: center; gap: 6px;
  flex-basis: 100%;
  width: 100%;
  justify-content: flex-end;
  font-size: 11px; color: #b45309; margin-top: 2px;
  font-variant-numeric: tabular-nums;
}
.tl-evento-fecha a {
  color: #b45309; text-decoration: none; font-weight: 600;
}
.tl-evento-fecha a:hover { text-decoration: underline; }
.tl-item.tl-rev-activo    .tl-card-tl { background:#f7fdf9; }
.tl-item.tl-rev-pausado   .tl-card-tl { background:#fffdf5; }
.tl-item.tl-rev-respondido .tl-card-tl { background:#f0f9ff;border-left-color:#0891b2; }
/* v0.15.89 (ALFIN-9) — estados de reenvio SMS (tonos morados) */
.tl-item.tl-rev-activo-sms .tl-card-tl { background:#faf5ff; }
.tl-item.tl-rev-stop-sms   .tl-card-tl { background:#f5edff;border-left-color:#7c3aed; }
.tl-btn-stopsms { font-size:13px;border:1px solid #ddd6fe;background:#fff;color:#7c3aed;border-radius:8px;padding:5px 11px;cursor:pointer;font-weight:600; }
.tl-btn-stopsms:hover { background:#f5edff; }

/* Cabecera grid 3 col × 3 fil */
.tl-head { display:grid;grid-template-columns:36px 1fr auto;grid-template-rows:auto auto auto;column-gap:10px;row-gap:4px;padding:8px 12px;cursor:pointer;border-radius:8px 8px 0 0; }
.tl-head:hover { background:rgba(0,0,0,.015); }
.tl-avatar-tl { grid-row:1/4;grid-column:1;width:36px;height:36px;border-radius:50%;background:#1a3a5c;color:#fff;font-size:11px;font-weight:700;display:flex;align-items:center;justify-content:center;overflow:visible;align-self:center;flex-shrink:0;position:relative; }
.tl-avatar-tl img { position:absolute;inset:0;width:100%;height:100%;object-fit:cover;border-radius:50%; }
.tl-av-label { position:absolute;top:calc(100% + 2px);left:50%;transform:translateX(-50%);font-size:9px;font-weight:700;color:#94a3b8;white-space:nowrap;line-height:1;pointer-events:none; }
.tl-r1c { grid-row:1;grid-column:2;display:flex;align-items:center;gap:8px;min-width:0; }
/* v0.13.93 — flex-wrap:wrap añadido para que el sub-bloque
   `.tl-evento-fecha` (width:100%) pueda romper a una nueva línea
   bajo la fecha de grabación. Sin esto, `width:100%` en un flex item
   con flex-wrap:nowrap (default) NO fuerza un wrap; los items se
   aprietan unos contra otros. */
.tl-r1r { grid-row:1;grid-column:3;display:flex;flex-wrap:wrap;align-items:center;justify-content:flex-end;white-space:nowrap;gap:6px; }
.tl-r2c { grid-row:2;grid-column:2;min-width:0; }
.tl-r2r { grid-row:2;grid-column:3;display:flex;align-items:center;justify-content:flex-end;gap:6px;flex-wrap:wrap; }
.tl-r3c { grid-row:3;grid-column:2;min-width:0;display:flex;align-items:center;gap:8px;flex-wrap:wrap; }
.tl-r3r { grid-row:3;grid-column:3;display:flex;align-items:center;justify-content:flex-end;gap:4px; }

/* Textos */
.tl-asunto-txt { font-size:13px;font-weight:700;color:#1a2332;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;flex:1;min-width:0; }
.tl-ti         { font-size:9px;color:#94a3b8;margin-right:3px; }
.tl-smtp-ok    { font-size:12px;font-weight:600;color:#16a34a;flex-shrink:0; }
.tl-smtp-err   { font-size:12px;font-weight:600;color:#dc2626;flex-shrink:0; }
/* v0.15.19 — Badge azul para mail programado (logMailStatusCode IS NULL +
   fechaEnvioProgramada). Pildora con fondo azul tenue, texto azul oscuro. */
.tl-smtp-prog  { display:inline-flex;align-items:center;gap:4px;
                 font-size:11px;font-weight:700;color:#1e40af;
                 background:#dbeafe;border:1px solid #93c5fd;
                 padding:1px 8px;border-radius:999px;flex-shrink:0; }
/* v0.15.25 — Estado intermedio "Enviando" (logMailStatusCode=100,
   set por mail_dispatcher justo antes de llamar a SMTP). Pildora
   naranja para que el usuario sepa que esta en proceso. */
.tl-smtp-enviando { display:inline-flex;align-items:center;gap:4px;
                 font-size:11px;font-weight:700;color:#92400e;
                 background:#fef3c7;border:1px solid #f59e0b;
                 padding:1px 8px;border-radius:999px;flex-shrink:0; }
/* v0.15.29 Card C — Fiel al mockup
   docs/mockups/enviar_mail_programado_v1.html seccion C.
   La card entera (tl-card-tl) toma fondo azul claro cuando la nota
   esta programada pendiente. Botones grandes en fila propia bajo
   tl-head para que sean siempre visibles sin expandir. */
.tl-card-tl.tl-card-programado {
  background:#eff6ff;
  border:1px solid #bfdbfe;
  border-radius:6px;
}
.tl-card-tl.tl-card-programado-error {
  background:#fef2f2;
  border:1px solid #fecaca;
  border-radius:6px;
}
/* Fila de acciones grandes — colocada bajo tl-head, antes de
   tl-content. Visible siempre. */
.tl-prog-acciones {
  display:flex;
  gap:8px;
  flex-wrap:wrap;
  padding:8px 12px 10px 12px;
  border-top:1px solid #dbeafe;
  background:transparent;
}
.tl-prog-acciones-error {
  border-top:1px solid #fecaca;
}
.tl-prog-action {
  padding:5px 12px;
  border-radius:4px;
  cursor:pointer;
  font-size:12px;
  font-weight:600;
  border:1px solid var(--gray-border);
  background:#fff;
  color:#1a2332;
  line-height:1.4;
  transition:filter .12s, background .12s;
}
.tl-prog-action:hover { filter:brightness(0.97); }
.tl-prog-action:disabled { opacity:0.55; cursor:wait; }
.tl-prog-action-enviar    { color:#15803d;border-color:#86efac;font-weight:700; }
.tl-prog-action-enviar:hover { background:#dcfce7; }
.tl-prog-action-editar    { color:#6b21a8;border-color:#d8b4fe; }
.tl-prog-action-editar:hover { background:#f3e8ff; }
.tl-prog-action-cancelar  { color:#dc2626;border-color:#fca5a5; }
.tl-prog-action-cancelar:hover { background:#fee2e2; }
.tl-prog-action-reintentar { color:#1d4ed8;border-color:#93c5fd; }
.tl-prog-action-reintentar:hover { background:#dbeafe; }

/* v0.15.31 — Soporte para clases Quill en la vista del detalle.
   El editor del form aplica `ql-size-small/large/huge` y
   `ql-align-center/right/justify`. La hoja `quill.snow.css` solo se
   carga en el editor; cuando luego mostramos el HTML guardado en
   notas/intentos via el detalle, las clases NO tendrian estilo si
   no las definimos aqui. (Para mail enviado: se convierten a
   style inline en services/mail_builder.py, porque los clientes de
   email ignoran <style>.) */
.ql-size-small   { font-size: 0.75em; }
.ql-size-large   { font-size: 1.5em; }
.ql-size-huge    { font-size: 2.5em; }
.ql-align-center { text-align: center; }
.ql-align-right  { text-align: right; }
.ql-align-justify{ text-align: justify; }
.tl-badge-nueva{ display:inline-block;margin-left:8px;padding:1px 6px;border-radius:8px;
                 font-size:10px;font-weight:700;color:#0c4a6e;background:#e0f2fe;
                 border:1px solid #7dd3fc;letter-spacing:.3px;vertical-align:middle; }
.tl-fecha-txt  { font-size:13px;color:#1a2332; }  /* v0.11.33 — antes 12px/#94a3b8 */
.tl-cred-txt   { font-size:11px;color:#94a3b8; }
.tl-nota-preview { font-size:13px;color:#374151;white-space:nowrap;overflow:hidden;text-overflow:ellipsis; }  /* v0.11.33 — 13px/dark, sin italic */
/* v0.10.81 / v0.13.89 — Iconos edit/delete por nota manual.
   v0.13.89: mejor contraste (colores plenos azul/rojo en lugar del gris
   pálido anterior), borde visible, hover destacado. */
.tl-nota-actions { display:inline-flex;gap:4px;margin-left:6px; }
.tl-nota-btn {
  background:#f8fafc;
  border:1px solid #cbd5e1;
  border-radius:4px;
  padding:2px 7px;
  font-size:12px;
  line-height:1.2;
  cursor:pointer;
  color:#1d4e82;            /* azul Alfin — "editar" claramente clicable */
  transition:all .12s;
}
.tl-nota-btn:hover {
  background:#dbeafe;
  border-color:#1d4e82;
  color:#0c2d4d;
}
.tl-nota-btn-del {
  color:#b91c1c;            /* rojo — "borrar" claramente destructivo */
}
.tl-nota-btn-del:hover {
  background:#fee2e2;
  border-color:#dc2626;
  color:#7f1d1d;
}
.tl-nota-body { font-size:13.5px;color:#1e293b;line-height:1.5; }
/* SMS destinatarios en timeline */
.tl-sms-dests { display:flex;flex-direction:column;gap:2px; }
.tl-sms-dest-item { font-size:12px;color:#64748b;line-height:1.4; }
.tl-sms-dest-link { color:#1a3a5c;text-decoration:none;font-size:12px; }
.tl-sms-dest-link:hover { color:#3b82f6;text-decoration:underline; }
/* Popup consulta persona */
.persona-popup-overlay { display:none;position:fixed;inset:0;z-index:9000;background:rgba(0,0,0,.25); }
.persona-popup-overlay.open { display:block; }
.persona-popup { position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);background:#fff;border-radius:10px;box-shadow:0 8px 32px rgba(0,0,0,.18);padding:20px 24px;z-index:9001;min-width:340px;max-width:460px;width:90%; }
.persona-popup-header { display:flex;align-items:center;justify-content:space-between;margin-bottom:14px;border-bottom:1px solid #e2e8f0;padding-bottom:10px; }
.persona-popup-title { font-size:15px;font-weight:700;color:#1a2332; }
.persona-popup-close { background:none;border:none;font-size:18px;cursor:pointer;color:#94a3b8;padding:0 4px;line-height:1; }
.persona-popup-close:hover { color:#334155; }
.persona-popup-grid { display:grid;grid-template-columns:auto 1fr;gap:5px 14px;font-size:13px; }
.pp-lbl { color:#94a3b8;font-weight:500;white-space:nowrap;padding:1px 0; }
.pp-val { color:#334155;padding:1px 0; }
.persona-popup-footer { margin-top:14px;display:flex;justify-content:flex-end; }
.persona-popup-edit { font-size:12px;font-weight:600;color:#1a3a5c;background:#f0f4f8;border:1px solid #dde3ec;padding:4px 12px;border-radius:6px;text-decoration:none; }
.persona-popup-edit:hover { background:#dbeafe;border-color:#93c5fd;text-decoration:none; }
.tl-dests-txt  { font-size:12px;color:#64748b;white-space:nowrap;overflow:hidden;text-overflow:ellipsis; }
.tl-adj-lbl    { font-size:12px;font-weight:700;color:#0369a1; }
.tl-rev-lbl    { font-size:12px;font-weight:500; }
.tl-lbl-activo     { color:#15803d; }
.tl-lbl-pausado    { color:#b45309; }
.tl-lbl-cancel     { color:#94a3b8; }
.tl-lbl-done       { color:#3b82f6; }
.tl-lbl-hijo       { color:#7c3aed; }
.tl-lbl-respondido { color:#0891b2;font-weight:600; }
.tl-dias-lbl       { font-size:11px;font-weight:500;color:#94a3b8; }
.tl-dias-resp      { font-size:11px;font-weight:600;color:#0891b2; }

/* Botones acciones */
.tl-btn-reenviar { font-size:12px;font-weight:600;color:#1a3a5c;background:#f0f4f8;border:1px solid #dde3ec;padding:3px 9px;border-radius:6px;cursor:pointer;text-decoration:none;white-space:nowrap;transition:background .12s; }
.tl-btn-reenviar:hover { background:#dbeafe;border-color:#93c5fd;color:#1a3a5c;text-decoration:none; }
.tl-btn-respondido { font-size:12px;font-weight:600;color:#15803d;background:#dcfce7;border:1px solid #86efac;padding:3px 9px;border-radius:6px;cursor:pointer;white-space:nowrap;transition:background .12s; }
.tl-btn-respondido:hover { background:#bbf7d0;border-color:#4ade80; }

/* Contenido expandido */
.tl-content { border-top:1px solid #f1f5f9; }
.tl-content.hidden { display:none; }

/* Label-botón cadena de reenvíos */
.tl-rev-chain-btn { display:inline-flex;align-items:center;gap:5px;cursor:pointer;border:1px solid currentColor;border-radius:5px;padding:1px 7px 1px 6px;transition:background .12s;text-decoration:none;font-size:12px;font-weight:500; }
.tl-rev-chain-btn:hover { background:rgba(0,0,0,.04);text-decoration:none; }
.tl-carrow { font-size:8px;transition:transform .15s; }
.tl-rev-chain-btn.open .tl-carrow { transform:rotate(90deg); }
/* Sección cadena (dentro del tl-content) */
.tl-rev-chain-section { border-bottom:1px solid #f1f5f9; }
.tl-rev-chain-section.hidden { display:none; }
.tl-rev-chain-list { padding:8px 14px 10px;display:flex;flex-direction:column;gap:4px; }
.tl-rev-chain-item { display:flex;align-items:center;gap:10px;padding:5px 10px;border-radius:6px;background:#f8fafc;border:1px solid #e2e8f0;font-size:12px;color:#334155; }
.tl-rc-num { font-weight:700;color:#7c3aed;min-width:32px; }
.tl-rc-status { font-weight:600; }
.tl-rc-ok { color:#16a34a; }
.tl-rc-pdte { color:#94a3b8;font-style:italic; }
.tl-rc-err { color:#dc2626; }
/* v0.11.56 — Slot que NO se llegó a enviar porque la cola fue cancelada.
   Gris medio + tachado para indicar visualmente que no aplica/se anuló. */
.tl-rc-cancel { color:#94a3b8; font-style:italic; text-decoration:line-through; }
.tl-rc-fecha { margin-left:auto;color:#94a3b8; }

.tl-adj-section     { padding:10px 14px 8px;border-bottom:1px solid #f1f5f9; }
.tl-adj-section-lbl { font-size:11px;font-weight:600;color:#94a3b8;text-transform:uppercase;letter-spacing:.06em;margin-bottom:7px; }
.tl-adj-list { display:flex;gap:6px;flex-wrap:wrap; }
.tl-adj-item { display:flex;align-items:center;gap:5px;padding:5px 11px;border-radius:6px;border:1px solid #dde3ec;background:#f8fafc;font-size:12px;color:#1d4ed8;text-decoration:none; }
.tl-adj-item:hover { background:#dbeafe; }
.tl-msg-section { padding:10px 14px 14px;font-size:13px;line-height:1.7;color:#334155; }
.tl-msg-section ol { list-style-type:decimal;padding-left:2em; }
.tl-msg-section ul { list-style-type:disc;padding-left:2em; }

/* v0.10.57 — Cuerpo SMS al expandir: el tituloNota ES el SMS enviado y
   debe verse completo (no truncado como en la cabecera). descripcionNota
   se muestra debajo como notas internas si tiene contenido distinto. */
.tl-sms-body {
  background:#f5f3ff; border-left:3px solid #7c3aed;
  padding:10px 14px; border-radius:6px;
  white-space:pre-wrap; word-break:break-word;
  font-size:13.5px; color:#1e1b4b; line-height:1.55;
}
.tl-sms-extra {
  margin-top:10px; padding:8px 12px;
  background:#f8fafc; border:1px dashed var(--gray-border);
  border-radius:6px; font-size:12.5px; color:#475569;
}
.tl-sms-extra-lbl {
  font-size:11px; font-weight:700; color:#64748b;
  text-transform:uppercase; letter-spacing:.04em; margin-right:6px;
}

/* Popup leyenda */
.tl-popup-overlay { display:none;position:fixed;inset:0;background:rgba(0,0,0,.35);z-index:1100;align-items:flex-start;justify-content:center;padding:32px 16px;overflow-y:auto; }
.tl-popup-overlay.open { display:flex; }
.tl-popup-box { background:#fff;border-radius:12px;padding:20px 24px;max-width:700px;width:100%;box-shadow:0 12px 40px rgba(0,0,0,.18);position:relative;margin:auto; }
.tl-popup-box h4 { font-size:15px;font-weight:700;color:#1a3a5c;margin-bottom:14px;padding-bottom:10px;border-bottom:1px solid #e2e8f0; }
.tl-popup-close { position:absolute;top:14px;right:16px;background:none;border:none;font-size:20px;color:#94a3b8;cursor:pointer;line-height:1;padding:2px 6px;border-radius:4px; }
.tl-popup-close:hover { background:#f0f4f8;color:#1a3a5c; }
.leyenda-grid { display:grid;grid-template-columns:1fr 1fr;gap:0 24px; }
.leyenda-section { margin-bottom:12px; }
.leyenda-section h5 { font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.07em;color:#94a3b8;margin-bottom:6px; }
.leyenda-row { display:flex;align-items:flex-start;gap:10px;padding:5px 0;border-bottom:1px solid #f1f5f9; }
.leyenda-row:last-child { border-bottom:none; }
.leyenda-icon { font-size:15px;flex-shrink:0;width:22px;text-align:center;margin-top:2px; }
.leyenda-text strong { display:block;font-weight:600;color:#1a2332;font-size:13px; }
.leyenda-text span { color:#64748b;font-size:12px; }

/* ══════════════════════════════════════════════════
   v1.4.44 (ALFIN-12) — Buscador en vivo del timeline (notas/intentos).
   UI v5: lupa en la toolbar → fila con la barra completa (oculta por defecto).
   ══════════════════════════════════════════════════ */
.tl-lupa { display:inline-flex; align-items:center; justify-content:center;
  width:32px; height:29px; border:1px solid var(--gray-border); background:#f1f5f9;
  color:#334155; border-radius:7px; cursor:pointer; font-size:14px; padding:0; }
.tl-lupa:hover { background:#e2e8f0; }
.tl-lupa.active { background:#dbeafe; border-color:#93c5fd; color:#1d4ed8; }
/* La barra vive en su propia fila, oculta hasta pulsar la lupa. */
.tl-searchrow { display:none; align-items:center; gap:9px; background:#fff;
  border:1px solid #93c5fd; box-shadow:0 0 0 3px rgba(59,130,246,.12);
  border-radius:10px; padding:8px 13px; margin:0 0 12px; }
.tl-searchrow.open { display:flex; }
.tl-searchrow-ico { font-size:15px; color:#1d4ed8; flex:0 0 auto; }
.tl-searchrow .tl-search-input { flex:1; border:none; outline:none; background:transparent;
  font-size:14px; color:#1a2332; min-width:0; padding:0; height:24px; }
.tl-searchrow .tl-search-input::placeholder { color:#94a3b8; }
.tl-search-clear { border:none; background:transparent; cursor:pointer; color:#94a3b8;
  font-size:15px; width:28px; height:24px; display:none; padding:0; }
.tl-searchrow .tl-search-clear.show { display:block; }
.tl-search-clear:hover { color:#334155; }
.tl-search-count { font-size:12px; font-weight:700; color:#0c4a6e; background:#e0f2fe;
  border:1px solid #7dd3fc; border-radius:999px; padding:2px 9px; white-space:nowrap; display:none; }
.tl-search-count.show { display:inline-block; }
.tl-search-count.zero { color:#9f1239; background:#ffe4e6; border-color:#fda4af; }
.tl-search-nav { display:none; align-items:center; gap:3px; }
.tl-search-nav.show { display:inline-flex; }
.tl-search-nav button { width:24px; height:24px; border:1px solid var(--gray-border);
  background:#fff; border-radius:6px; color:#334155; font-size:16px; line-height:1; cursor:pointer; padding:0; }
.tl-search-nav button:hover { background:#eef2f7; border-color:#93c5fd; }
mark.tl-hl { background:#fde68a; color:inherit; border-radius:3px; padding:0 1px; }
.tl-item.tl-current > .tl-card-tl { outline:2px solid #f59e0b; outline-offset:1px;
  box-shadow:0 0 0 4px rgba(245,158,11,.18); }

/* ══════════════════════════════════════════════════
   v0.5.22 — CRUD Plantillas Mail/SMS
   ══════════════════════════════════════════════════ */
/* Badges de tipo en lista plantillas */
.badge-tipo {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 10px;
  font-size: 11px;
  font-weight: 600;
  white-space: nowrap;
}
.badge-tipo-mail  { background: #dbeafe; color: #1e40af; }
.badge-tipo-sms   { background: #dcfce7; color: #15803d; }
.badge-tipo-other { background: #f1f5f9; color: #64748b; }

/* Celda asunto en lista — texto truncado con elipsis */
.pl-asunto-cell {
  max-width: 320px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 13px;
  color: #475569;
  cursor: default;
}

/* ══════════════════════════════════════════════════
   v0.5.21 — Página Changelog
   ══════════════════════════════════════════════════ */
.cl-latest td { background:#f0f7ff; }
.cl-version { font-weight:700; color:#1d4e82; font-size:13px; }
.cl-fecha { color:#64748b; font-size:12px; white-space:nowrap; }
.cl-resumen { font-size:13px; color:#334155; line-height:1.45; }

/* ══════════════════════════════════════════════════
   v0.7.9 — Botonera de listas + selección de fila
   ══════════════════════════════════════════════════ */

/* Cabecera de la página: título + botonera alineada en las 3 listas */
.list-header-bar {
  display: flex;
  align-items: center;
  gap: 18px;
  margin: 0 0 12px 0;
}
.list-header-bar h2 {
  margin: 0;
  /* min-width 220px mantiene la botonera alineada en la misma X cuando el
     titulo cabe (caso comun: "Casos", "Comunicaciones", "Recordatorios").
     Si el titulo es mas largo (ej. "Envios programados"), el h2 crece y
     NO trunca el texto. Antes era `flex: 0 0 220px` + ellipsis, lo que
     mostraba "⏰ Envíos programa…" — bug detectado por Javi 2026-05-27. */
  flex: 0 0 auto;
  min-width: 220px;
  white-space: nowrap;
}
@media (max-width: 900px) {
  .list-header-bar h2 { flex-basis: auto; }
}

/* v1.4.56 — Pildora "📖 Guía": acceso unificado a la guia de ayuda de cada
   pagina (consultas y entidades), arriba a la derecha. Macro _btn_guia.html. */
.btn-guia {
  display: inline-flex; align-items: center; gap: 6px;
  background: #fff; color: var(--blue); border: 1px solid #cbd5e1;
  border-radius: 999px; padding: 5px 12px; font-size: 13px; font-weight: 700;
  line-height: 1; white-space: nowrap; text-decoration: none; cursor: pointer;
}
.btn-guia:hover { background: #f1f5f9; border-color: #94a3b8; }
.btn-guia-ic { font-size: 15px; }
/* v1.4.58 — Grupo derecho de la cabecera de lista: [N registros] + [📖 Guía]
   envueltos en UN solo hijo, para que el justify-content:space-between de
   .page-header siga repartiendo titulo (izq) / botonera (centro) / grupo (der).
   OJO: en v1.4.56 puse margin-left:auto en la pildora -> como .page-header hace
   space-between con 4 hijos, descoloco la botonera y los registros. NO repetir. */
.lhb-right { display: inline-flex; align-items: center; gap: 14px; }

/* Botonera con botones cuadrados pequeños (icono + tooltip) */
.list-toolbar {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  background: #e8eef5;
  border: 1px solid #cdd9e6;
  border-radius: 8px;
  padding: 4px;
}
.list-tb-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  /* Activo: fondo blanco, borde tenue azul → contrasta con el fondo gris */
  background: #ffffff;
  border: 1px solid #b8c7da;
  border-radius: 6px;
  cursor: pointer;
  font-size: 17px;
  line-height: 1;
  color: #1d4e82;
  transition: background-color .12s, color .12s, transform .08s, border-color .12s, box-shadow .12s;
  padding: 0;
  filter: none;
  box-shadow: 0 1px 0 rgba(0,0,0,0.04);
}
.list-tb-btn:hover:not(:disabled):not(.is-pending) {
  background: #1d4e82;
  color: #fff;
  border-color: #1d4e82;
  box-shadow: 0 2px 6px rgba(29,78,130,0.35);
}
.list-tb-btn:active:not(:disabled):not(.is-pending) { transform: scale(.95); }

/* Estado: deshabilitado total (próxima funcionalidad)
   - Fondo plano gris, sin borde realzado, emojis en B/N por filter:grayscale */
.list-tb-btn:disabled,
.list-tb-btn.is-pending {
  background: transparent;
  border-color: transparent;
  color: #94a3b8;
  cursor: not-allowed;
  opacity: 0.50;
  filter: grayscale(1);
  box-shadow: none;
}

/* Estado: requiere fila seleccionada y NO hay → apagado, no clicable */
.list-toolbar.no-selection .list-tb-btn.needs-selection {
  background: transparent;
  border-color: transparent;
  color: #94a3b8;
  cursor: not-allowed;
  pointer-events: none;
  opacity: 0.50;
  filter: grayscale(1);
  box-shadow: none;
}

/* Separador visual entre grupos */
.list-tb-sep {
  width: 1px;
  height: 18px;
  background: var(--gray-border);
  margin: 0 2px;
}

/* Selección de fila: clic activa, estilo persistente que vence al hover */
.tabla tbody tr.row-selected td {
  background-color: #dbeafe !important;
}
.tabla tbody tr.row-selected td:first-child {
  box-shadow: inset 3px 0 0 #1d4e82;
}
.tabla tbody tr.row-selected:hover td {
  background-color: #c7dcfa !important;   /* hover sobre seleccionada: un punto más oscuro */
}
.tabla tbody tr.row-selectable { cursor: pointer; }

/* Reaprovechamos columnas dobles también en casos y expedientes */
.tabla-cas td, .tabla-cas th,
.tabla-exp td, .tabla-exp th { padding: 4px 8px; }

/* ══════════════════════════════════════════════════
   v0.9.7 — Modal genérico (overlay + box) — CSS GLOBAL
   ══════════════════════════════════════════════════
   Antes vivía dentro del <style> de cada formulario (notaria_form, registro_form,
   _modal_comunicacion). Eso provocaba que el modal incluido globalmente en
   base.html (v0.9.5) apareciese visible al cargar cualquier página porque NO
   tenía display:none por defecto. */
.modal-overlay {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.45);
  z-index: 9000;
  align-items: center;
  justify-content: center;
  padding: 20px;
}
.modal-overlay[style*="display:flex"],
.modal-overlay[style*="display: flex"] { display: flex !important; }

.modal-box {
  background: #fff;
  border-radius: 12px;
  width: 100%;
  max-width: 560px;
  max-height: 90vh;
  display: flex;
  flex-direction: column;
  box-shadow: 0 12px 48px rgba(0,0,0,0.32);
  overflow: hidden;
}
.modal-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 18px;
  background: var(--blue);
  color: #fff;
}
.modal-head h3 { font-size: 15px; color: #fff; margin: 0; }
.modal-close {
  background: none; border: none; color: #fff;
  font-size: 18px; cursor: pointer; padding: 0 4px;
}
/* v0.12.51 — Acciones en la cabecera del modal (↺ Limpiar + ✕ Cerrar).
   Patrón estándar: cerrar mantiene los datos para volver luego, limpiar
   vacía explícitamente el formulario. Originalmente solo en
   _modal_comunicacion / _modal_caso; movido aquí para reutilizar en
   modales de gasto, honorario y futuros. */
.modal-head-actions { display: flex; align-items: center; gap: 6px; }
.modal-clear {
  background: rgba(255,255,255,0.15);
  color: #fff;
  border: 1px solid rgba(255,255,255,0.30);
  border-radius: 4px;
  font-size: 12px;
  padding: 3px 10px;
  cursor: pointer;
}
.modal-clear:hover { background: rgba(255,255,255,0.30); }
.modal-body { padding: 14px 18px; overflow-y: auto; }
.modal-foot {
  padding: 10px 18px;
  border-top: 1px solid var(--gray-border);
  display: flex; gap: 8px; justify-content: flex-end;
  background: #f8fafc;
}

/* ══════════════════════════════════════════════════
   v0.10.33 — Módulo Feedback (overlay con spinner)
   Usado por static/js/feedback.js. API: Feedback.show/hide/wrap.
   ══════════════════════════════════════════════════ */
.fb-overlay {
  position: absolute; inset: 0;
  background: rgba(0,0,0,0.18);
  display: flex; align-items: center; justify-content: center;
  z-index: 8500;
  opacity: 0; transition: opacity 0.18s ease;
  pointer-events: all;
}
.fb-overlay.fb-full {
  position: fixed; inset: 0;
  background: rgba(0,0,0,0.30);
  z-index: 9500;
}
.fb-overlay.fb-visible { opacity: 1; }

.fb-box {
  background: #fff;
  border-radius: 10px;
  padding: 22px 28px;
  box-shadow: 0 6px 28px rgba(0,0,0,0.18);
  display: flex; flex-direction: column; align-items: center; gap: 12px;
  min-width: 220px; max-width: 380px;
}

.fb-spinner {
  width: 36px; height: 36px;
  border: 3px solid #cbd5e1;
  border-top-color: #1d4e82;
  border-radius: 50%;
  animation: fb-spin 0.9s linear infinite;
}
@keyframes fb-spin { to { transform: rotate(360deg); } }

.fb-text {
  color: #1e293b; font-size: 14px; font-weight: 500;
  text-align: center;
}
.fb-text-largo {
  color: #94a3b8; font-size: 12px; font-style: italic;
  text-align: center;
}

/* ── v0.10.95 — Badges de tipo de caso (no-herencia) ────────────────────── */
.caso-tipo-badge {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 7px;
  border-radius: 999px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .03em;
  vertical-align: 1px;
  border: 1px solid;
}
.caso-tipo-ci { background: #eff6ff; color: #1e40af; border-color: #93c5fd; }  /* azul - civil */
.caso-tipo-me { background: #f0fdf4; color: #166534; border-color: #86efac; }  /* verde - mercantil */
.caso-tipo-la { background: #fef3c7; color: #92400e; border-color: #fbbf24; }  /* amarillo - laboral */
.caso-tipo-pe { background: #fef2f2; color: #991b1b; border-color: #fca5a5; }  /* rojo - penal */
.caso-tipo-ad { background: #f3e8ff; color: #6b21a8; border-color: #d8b4fe; }  /* violeta - admin */
.caso-tipo-fi { background: #fff7ed; color: #9a3412; border-color: #fdba74; }  /* naranja - fiscal */

.td-na {
  color: #cbd5e1;
  font-style: italic;
}

/* Modal Caso General — botón close (reutiliza estilos del modal genéricos) */
.modal-caso-general .modal-close {
  background: none; border: none; cursor: pointer;
  font-size: 18px; color: #fff;
}
.modal-caso-general .modal-head {
  background: var(--blue);
  color: #fff;
  padding: 14px 22px;
  border-radius: 12px 12px 0 0;
  display: flex; align-items: center; justify-content: space-between;
}
.modal-caso-general .modal-head h3 {
  margin: 0; font-size: 16px; font-weight: 600;
}

/* v0.12.25 — Aviso informativo bajo inputs de teléfono.
   Lo pinta dinámicamente static/js/tel-warning.js. Diseño cálido en ámbar
   (variante C de docs/mockups/tel-warning-colors.html). Padding compacto
   (4px vertical) y misma tipografía 12.5px tanto al pintar como al
   actualizar, para no marear con cambios de tamaño. Contraste AAA
   (7.7:1) — accesible.

   NO interfiere con la validación existente (normPhone en listas,
   _esMovilES en mail_form). Es 100% aditivo.

   Si surge un problema, kill-switch en consola:
     window.AlfinTelWarn.enabled = false; */
.tel-info-tip {
  font-size: 12.5px;
  line-height: 1.45;
  padding: 4px 12px;
  margin-top: 4px;
  color: #92400E;             /* amber-800 */
  background: #FFFBEB;        /* amber-50 */
  border-left: 4px solid #F59E0B;  /* amber-500 */
  border-radius: 0 6px 6px 0;
}
.tel-info-tip strong { font-weight: 700; }

/* v0.12.27 — Contador en vivo bajo el textarea de plantillas SMS.
   Aparece SOLO cuando tipoNota='06' (lo controla el JS del formulario,
   no este CSS). Muestra:
     "N / 1000 caracteres · X SMS · GSM-7|UCS-2"
   Si se acerca al límite cambia a amarillo (warn); si lo supera, rojo
   (error). El maxlength="1000" del textarea ya impide superar, esto es
   redundancia defensiva. */
.sms-counter {
  font-size: 12px;
  color: #64748b;             /* slate-500 */
  margin-top: 4px;
  font-variant-numeric: tabular-nums;
}
.sms-counter-enc {
  margin-left: 4px;
  color: #94a3b8;             /* slate-400 */
}
.sms-counter.sms-counter-warn {
  color: #92400E;             /* amber-800 — coherente con .tel-info-tip */
}
.sms-counter.sms-counter-error {
  color: #b91c1c;             /* red-700 */
  font-weight: 600;
}

/* v0.12.29 — Mini-aviso bajo el toggle "Aviso SMS" cuando se desactiva
   automáticamente porque no hay contactos del caso/comu/exp entre los
   destinatarios. Coherente con la paleta ámbar de .tel-info-tip.
   Aparece solo si el usuario ya añadió algún destinatario pero ninguno
   es contacto. Si toca el toggle a mano, se oculta y deja de aparecer
   (manual override). */
/* v0.15.65 — Banner amarillo prominente. Javi reporto que la version
   v0.12.x era "sutil" y los usuarios no se daban cuenta de que SMS
   aviso se autodesactivaba (caso C8516-2026 con Inma: escribio el
   mail manualmente sin seleccionar contacto del dropdown, SMS aviso
   se autodesactivo, se entero al dia siguiente cuando reviso).
   Ahora: full width, 14px, fondo amarillo solido, borde grueso,
   icono prominente. */
.sms-auto-aviso {
  font-size: 14px;
  font-weight: 600;
  line-height: 1.5;
  padding: 14px 18px;
  margin: 10px 0;
  color: #78350F;             /* amber-900 — mas oscuro para contraste */
  background: #FEF3C7;        /* amber-100 — solido visible */
  border: 2px solid #F59E0B;  /* amber-500 — borde completo, no solo izq */
  border-radius: 8px;
  display: flex;
  align-items: flex-start;
  gap: 10px;
}
.sms-auto-aviso::before {
  content: '⚠';
  font-size: 22px;
  line-height: 1;
  flex-shrink: 0;
  margin-top: 1px;
}

/* ── v0.15.1 — Botón Liquidación de Impuestos (card "Otros datos"
   del detalle expediente). Fila ancho completo verde. ───────────── */
.info-row-liq {
  display: block;
  padding: 6px 0;
}
.btn-liquidacion-impuestos {
  display: block;
  width: 100%;
  padding: 9px 14px;
  font-size: 13px;
  font-weight: 600;
  color: #1f3a26;
  background: linear-gradient(180deg, #a7d3b3 0%, #8ec39d 100%);
  border: 1px solid #5f9c73;
  border-radius: 6px;
  cursor: pointer;
  text-align: center;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.06);
  transition: background 0.15s ease, box-shadow 0.15s ease;
}
.btn-liquidacion-impuestos:hover:not(:disabled) {
  background: linear-gradient(180deg, #9ccbab 0%, #7fb791 100%);
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.btn-liquidacion-impuestos:active:not(:disabled) {
  background: #7fb791;
  box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.15);
}
.btn-liquidacion-impuestos:disabled {
  cursor: progress;
  opacity: 0.6;
}
.btn-liquidacion-impuestos:focus-visible {
  outline: 2px solid #2563eb;
  outline-offset: 2px;
}

/* ════════════════════════════════════════════════════════════════
   v0.15.43 — Patrón 3+6 para placeholders en formularios
   ════════════════════════════════════════════════════════════════
   Combina las alternativas 3 (fondo amarillo + dashed cuando vacío)
   y 6 (placeholder con prefijo "Ej." en naranja) del mockup
   docs/mockups/placeholders_alternativas_v1.html (cerrado por Javi
   2026-05-27).
   Es OPT-IN: para activarlo en un formulario o fieldset, añadir la
   clase contenedora `.pat36`. Eso evita aplicar el tinte a inputs
   que NO esperan instrucciones visuales (login, search global, etc.).
   Cobertura: <input type="text|email|tel|number|search|url|password">
   y <textarea>. Date/datetime-local NO entran porque su placeholder
   no es visible — esos llevan `.field-hint` debajo (regla aparte).
   ──────────────────────────────────────────────────────────────── */
.pat36 input[type="text"]:placeholder-shown,
.pat36 input[type="email"]:placeholder-shown,
.pat36 input[type="tel"]:placeholder-shown,
.pat36 input[type="number"]:placeholder-shown,
.pat36 input[type="search"]:placeholder-shown,
.pat36 input[type="url"]:placeholder-shown,
.pat36 textarea:placeholder-shown {
  background-color: #fffbeb;       /* amber-50 — tinte muy suave */
  border-color: #fde68a;            /* amber-200 */
  border-style: dashed;
}
.pat36 input::placeholder,
.pat36 textarea::placeholder {
  color: #b45309;                   /* amber-700 — contraste suficiente */
  font-style: italic;
  opacity: 1;                       /* Firefox baja a 0.54 por defecto */
}
/* Al hacer focus o tipear, el input recupera su aspecto normal — el
   :placeholder-shown deja de matchear automáticamente cuando hay valor. */
.pat36 input:focus,
.pat36 textarea:focus {
  border-style: solid;
}

/* Hint gris debajo de inputs date/datetime-local (no admiten
   ::placeholder visible). Patrón Alt 1 del v1. */
.pat36 .field-hint,
.field-hint {
  font-size: 11px;
  color: #94a3b8;
  margin-top: 3px;
  font-style: italic;
  line-height: 1.4;
}

/* v0.15.49 — Marca visual de heredero (✓ + % opcional). Decisión Javi
   2026-05-27: clase global reusable. Verde negrita para que destaque.
   Se usa en la pestaña Contactos (caso + comunicación) y en cualquier
   tabla futura que liste personas con flag esHeredero. */
.es-heredero-ok {
  color: #16a34a;            /* verde 600 — buen contraste sobre blanco */
  font-weight: 700;
  white-space: nowrap;       /* "✓ 25,00 %" no se parte en dos líneas */
}
.es-heredero-ok .pct {
  /* v0.15.57 — Javi pidio 14 px (tamaño base de la tabla). Antes 11px
     se veia muy pequeño al lado del check. Quitando la regla
     `font-size` el span hereda los 14 px del `<td>`. */
  margin-left: 4px;
  font-weight: 600;          /* el % algo menos pesado que el check */
}
