/* ═══════════════════════════════════════════════════════════════════════════
 * lhm.css — lo propio de LHM Litigios, SIEMPRE por encima del tema.
 *
 * Regla de oro: no se toca ni un byte de `assets/css/*.min.css` ni de
 * `assets/js/app.js`. Todo lo nuestro se añade aquí, después. Así una
 * actualización de la plantilla no borra nuestro trabajo, y un test comprueba
 * por checksum que esos ficheros siguen intactos.
 * ═══════════════════════════════════════════════════════════════════════════ */

/* ───────────────────────────────────────────────────────────────────────────
 * 1 · El color de marca de cada cliente
 *
 * 🔴 Por qué esta sección existe: el tema compila sus componentes con colores
 * LITERALES, no con variables. Por ejemplo:
 *
 *     .badge-soft-primary{color:#5156be;background-color:rgba(81,86,190,.18)}
 *     .btn-primary{--bs-btn-bg:#5156be; …}
 *
 * De modo que hacer `setProperty('--bs-primary', color)` desde JavaScript
 * recolorea los enlaces y poco más: los botones primarios y toda la familia
 * `soft-*` se quedan con el violeta de la plantilla. Aquí se redeclaran en
 * términos de la variable, que es lo que hace que la marca del cliente llegue
 * de verdad a la pantalla.
 * ─────────────────────────────────────────────────────────────────────────── */
:root {
  --lhm-primario: #5156be;
  --lhm-primario-rgb: 81, 86, 190;
  --lhm-primario-oscuro: #414598;
}

.btn-primary {
  --bs-btn-bg: var(--lhm-primario);
  --bs-btn-border-color: var(--lhm-primario);
  --bs-btn-hover-bg: var(--lhm-primario-oscuro);
  --bs-btn-hover-border-color: var(--lhm-primario-oscuro);
  --bs-btn-active-bg: var(--lhm-primario-oscuro);
  --bs-btn-active-border-color: var(--lhm-primario-oscuro);
  --bs-btn-disabled-bg: var(--lhm-primario);
  --bs-btn-disabled-border-color: var(--lhm-primario);
  --bs-btn-focus-shadow-rgb: var(--lhm-primario-rgb);
}
.btn-outline-primary {
  --bs-btn-color: var(--lhm-primario);
  --bs-btn-border-color: var(--lhm-primario);
  --bs-btn-hover-bg: var(--lhm-primario);
  --bs-btn-hover-border-color: var(--lhm-primario);
  --bs-btn-active-bg: var(--lhm-primario);
  --bs-btn-active-border-color: var(--lhm-primario);
}
.badge-soft-primary { color: var(--lhm-primario); background-color: rgba(var(--lhm-primario-rgb), .18); }
.btn-soft-primary   { color: var(--lhm-primario); background-color: rgba(var(--lhm-primario-rgb), .10); }
.btn-soft-primary:hover,
.btn-soft-primary:focus { color: #fff; background-color: var(--lhm-primario); }
.bg-primary         { background-color: var(--lhm-primario) !important; }
.text-primary       { color: var(--lhm-primario) !important; }
.border-primary     { border-color: var(--lhm-primario) !important; }
.bg-primary-subtle  { background-color: rgba(var(--lhm-primario-rgb), .12) !important; }
.text-bg-primary    { background-color: var(--lhm-primario) !important; color: #fff !important; }
a { color: var(--lhm-primario); }
a:hover { color: var(--lhm-primario-oscuro); }
.page-item.active .page-link { background-color: var(--lhm-primario); border-color: var(--lhm-primario); }
.form-check-input:checked { background-color: var(--lhm-primario); border-color: var(--lhm-primario); }
.form-control:focus, .form-select:focus {
  border-color: rgba(var(--lhm-primario-rgb), .5);
  box-shadow: 0 0 0 .15rem rgba(var(--lhm-primario-rgb), .25);
}

/* ───────────────────────────────────────────────────────────────────────────
 * 2 · Contraste
 *
 * El `--bs-secondary-color` del tema no llega a AA sobre los fondos claros que
 * usa la aplicación (4,41:1 sobre #F7F8FB). Este sí, y está medido.
 * ─────────────────────────────────────────────────────────────────────────── */
.text-muted { color: #5A6274 !important; }

/* ───────────────────────────────────────────────────────────────────────────
 * 3 · Un dato que no se tiene se DICE
 *
 * Un hueco en blanco y un cero no son lo mismo, y en un expediente esa
 * diferencia importa: «sin fecha de fallo» no es «fallo el 00/00/0000».
 * ─────────────────────────────────────────────────────────────────────────── */
.sin-dato { color: #8A91A3; font-style: italic; }

/* ───────────────────────────────────────────────────────────────────────────
 * 4 · Utilidades propias
 *
 * Aquí viven las medidas que de otro modo irían en un atributo `style=`, para
 * no depender de `style-src 'unsafe-inline'`.
 * ─────────────────────────────────────────────────────────────────────────── */
.lhm-scroll-230  { max-height: 230px; }
.lhm-truncada-18 { max-width: 18rem; }
.lhm-truncada-26 { max-width: 26rem; }
.lhm-truncada-28 { max-width: 28rem; }
.lhm-celda-dia   { height: 6.5rem; vertical-align: top; }
.lhm-vacio-img   { max-width: 260px; opacity: .9; }

/* La franja de la cabecera de una ficha, con el color del cliente. */
.lhm-ficha-cabecera { background-color: rgba(var(--lhm-primario-rgb), .10); }

/* Fila de tabla que enlaza a su ficha: el cursor lo anuncia. */
.lhm-fila-enlace { cursor: pointer; }
.lhm-barra-fuerza { height: 4px; }

/* Prosa devuelta por la IA: conserva los saltos de línea del modelo sin
   interpretarlos como HTML (el texto se escapa antes de insertarse). */
.lhm-prosa { white-space: pre-wrap; line-height: 1.7; }

/* Línea de tiempo de actuaciones: 50 hechos no caben en pantalla, así que la
   lista hace su propio scroll y el resto de la ficha sigue accesible. */
.lhm-scroll-560 { max-height: 560px; overflow-y: auto; }

/* La ilustración de la página de error, acotada para que no domine la pantalla. */
.lhm-error-img { max-width: 260px; }

/* El avatar de la ficha monta sobre la banda de color de la cabecera.
   🔴 Aquí estuvo `mt-n4`, que no existe: este build de Bootstrap no genera las
   utilidades de margen negativo, así que la clase se ignoraba en silencio y el
   avatar quedaba debajo de la banda en vez de encima. */
.lhm-solapa { margin-top: -1.5rem; }

/* Choices esconde el `<select>`, así que el estado inválido se pinta sobre su
   propia caja: el borde rojo tiene que estar donde el usuario mira. */
.choices.is-invalid .choices__inner { border-color: #f56e6e; }

/* Choices trae `margin-bottom: 24px` de serie, y en una fila con el botón al
   lado eso lo dejaba medio centímetro más abajo que el campo. El hueco lo pone
   la rejilla del formulario, no el componente. */
.gpa-fila-choices .choices, .row.g-3 .choices, .row.g-2 .choices { margin-bottom: 0; }

/* 🔴 Y trae `min-height: 44px` más su relleno: 46 px frente a los 38 px de un
   `.form-select`. En el formulario del litigio un select con buscador y uno
   nativo comparten fila, y los dos campos quedaban a alturas distintas (validación
   de /litigios, 2026-10-02). Se iguala a la altura del control del tema. */
.choices__inner { min-height: 38px; padding: 4px 7.5px; }
.choices[data-type*="select-one"] .choices__inner { padding-bottom: 4px; }
.choices__list--single { padding: 3px 16px 3px 4px; }
/* Y el mismo fondo y la misma flecha que el `.form-select` del tema: con su caja
   blanca y su triángulo, el select con buscador parecía otro control al lado de
   uno nativo. El chevrón es el del propio Bootstrap, en claro y en oscuro. */
/* El tema pinta el fondo con `var(--bs-input-bg) !important`, una variable que Bootstrap
   5.3 ya no define: salía transparente. Se define aquí con la del `.form-select`. */
.choices { --bs-input-bg: var(--bs-tertiary-bg); }
.choices .choices__inner { border-color: var(--bs-border-color); }
/* Choices parte las opciones por cualquier letra (`break-all`): «CUNDINAM / ARCA».
   Se parte por palabras, y solo una palabra que no quepa entera se corta. */
/* Y lo mismo en lo ELEGIDO: las etiquetas de un select múltiple (las personas de un área en las plantillas de trámites,
   «Presentación de la demo / stración») y el valor de uno simple, que en un celular se partían a mitad de palabra. */
.choices__list--dropdown .choices__item, .choices__list[aria-expanded] .choices__item,
.choices__list--multiple .choices__item, .choices__list--single .choices__item { word-break: normal; overflow-wrap: anywhere; }
.choices[data-type*="select-one"]::after { display: none; }
.choices[data-type*="select-one"] .choices__inner {
  padding-right: 2.25rem;
  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%232c302e' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e");
  background-repeat: no-repeat; background-position: right .75rem center; background-size: 16px 12px;
}
[data-bs-theme="dark"] .choices[data-type*="select-one"] .choices__inner {
  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23adb5bd' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e");
}

/* El último elemento de una línea de tiempo no tiene a quién unirse: su tramo
   punteado (80 px, del tema) asomaba por debajo de la tarjeta, sobre el pie. */
.activity-wid .activity-list.activity-border:last-child::before { display: none; }

/* Una etiqueta de dos renglones baja su campo respecto al vecino de una (trampa
   139). Donde el formulario no puede reservar la altura en toda la fila, se reserva
   en las columnas de esa línea visual. */
.lhm-etiqueta-alta { min-height: 3em; margin-bottom: .3rem; align-content: end; }
@media (max-width: 767.98px) { .lhm-etiqueta-alta { min-height: 0; } }

/* La campana de avisos.
   🔴 `overflow-x: hidden` explícito: sin él, un título largo ensancha el
   contenido y SimpleBar dibuja una barra horizontal en un panel de 320 px —se
   ve una barra que nadie quiere arrastrar y el texto queda cortado—. */
.lhm-scroll-320 { max-height: 320px; overflow-y: auto; overflow-x: hidden; }

/* Un título de aviso cabe en dos líneas: a una se pierde la mitad de las
   actuaciones, y sin límite una sola ocupa el panel entero. */
.lhm-dos-lineas {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  line-height: 1.35;
}

/* Un hijo de flex no se encoge por debajo de su contenido salvo que se le diga:
   sin esto, `text-truncate` no trunca nada dentro de un `.flex-grow-1`. */
.min-w-0 { min-width: 0; }

/* ════════════════════════════════════════════════════════════════════════
   El skin activo.

   Las variables las emite el servidor en el `<html>` (App\Core\Tema). Aquí solo
   se USAN: el tema de la plantilla compila sus componentes con colores
   literales, así que cambiar `--bs-primary` recolorea los enlaces y poco más —
   esta capa es la otra mitad, y las dos son necesarias.
   ════════════════════════════════════════════════════════════════════════ */

body { font-family: var(--lhm-tipografia, inherit); }

/* El fondo del tema. `#f8f8fb` de Minia contra el crema de LHM 2026. */
body, .main-content, .page-content { background-color: var(--lhm-fondo, #f8f8fb); }

/* El menú lateral oscuro toma el color del tema. */
[data-sidebar="dark"] .vertical-menu,
[data-sidebar="dark"] .navbar-brand-box { background: var(--lhm-sidebar, #2a3042); }

/* 🔴 El acento SOLO como texto en su versión legible. `--lhm-acento` es el
   color de marca —vale para un filete, un fondo o un icono sobre color— y
   `--lhm-acento-texto` es el que cumple 4,5:1 sobre fondo claro. Usar el
   primero para texto es escribir algo que alguien no va a poder leer. */
.lhm-acento        { color: var(--lhm-acento-texto, #8a6410); }
.lhm-acento-fondo  { background-color: var(--lhm-acento, #f1b44c); }
.lhm-acento-borde  { border-color: var(--lhm-acento, #f1b44c); }
/* Sobre el menú oscuro y sobre cualquier fondo azul o negro, el otro tono. */
[data-sidebar="dark"] .lhm-acento,
.bg-primary .lhm-acento { color: var(--lhm-acento-oscuro, #f1b44c); }

/* El logotipo de LHM 2026 es dorado sobre el azul del menú. */
[data-tema="lhm2026"] .logo-txt { letter-spacing: .02em; font-weight: 600; }

/* Las muestras de skin: un menú, una barra y dos líneas. Se elige viendo el
   azul al lado del violeta, no leyendo dos nombres propios. */
.lhm-tema-opcion {
  /* 🔴 `flex` en columna y `height: 100%`, no `block`: las descripciones tienen
     distinta longitud —una línea en «Minia», dos en «LHM 2026»— y en una rejilla
     eso deja tres fichas de tres alturas. La muestra de color queda a distinta
     altura en cada una y la comparación, que es para lo que están, se vuelve
     incómoda. La columna que las contiene también estira. */
  display: flex; flex-direction: column; cursor: pointer; width: 100%; height: 100%;
  border: 2px solid var(--bs-border-color, #e9e9ef); border-radius: .5rem;
  padding: .75rem; margin-bottom: 0; transition: border-color .15s, box-shadow .15s;
}
.lhm-tema-opcion:hover  { border-color: var(--lhm-primario, #5156be); }
.lhm-tema-opcion.activa { border-color: var(--lhm-primario, #5156be);
                          box-shadow: 0 0 0 .2rem rgba(var(--lhm-primario-rgb, 81,86,190), .18); }
.lhm-tema-opcion input[type=radio] { float: right; margin-left: .5rem; }

.lhm-tema-muestra { display: flex; height: 76px; border-radius: .375rem; overflow: hidden;
                    border: 1px solid rgba(0,0,0,.08); }
.lhm-tema-menu   { width: 26%; display: block; }
.lhm-tema-cuerpo { width: 74%; display: block; position: relative; padding: 8px; }
.lhm-tema-barra  { display: block; height: 10px; width: 46%; border-radius: 3px; }
.lhm-tema-punto  { display: block; width: 12px; height: 12px; border-radius: 50%;
                   position: absolute; top: 8px; right: 8px; }
.lhm-tema-linea  { display: block; height: 6px; width: 72%; border-radius: 3px;
                   background: rgba(0,0,0,.10); margin-top: 9px; }
.lhm-tema-linea.corta { width: 48%; margin-top: 6px; }

/* El aviso de contraste bajo cada color. Es un gancho de JS, pero se le da
   estilo propio para que no dependa de una excepción en el gate de clases. */
.lhm-contraste { min-height: 1.2em; }

/* Menú horizontal.
   🔴 El tema calcula el margen izquierdo del contenido a partir de
   `data-sidebar-size`, que sigue puesto aunque no haya menú lateral: sin esto,
   con el menú arriba queda una franja vacía de 250 px a la izquierda. */
[data-layout="horizontal"] .main-content { margin-left: 0 !important; }
[data-layout="horizontal"] .page-content { padding-top: 1rem; }
/* Y el botón de plegar el lateral no tiene nada que plegar. */
[data-layout="horizontal"] #vertical-menu-btn { display: none; }

/* 🔴 `arrow-none` la usa el markup de Minia y NO está en su CSS compilado: sin
   definirla, cada ítem del menú horizontal sale con DOS flechas —la `::after`
   que Bootstrap añade a todo `.dropdown-toggle` y la `.arrow-down` del tema—.
   `navbar-light` tampoco existe (Bootstrap 5.3 la retiró) y se quitó del markup
   en vez de inventarle un estilo. */
.topnav .dropdown-toggle.arrow-none::after { display: none; }

/* El disparador del menú horizontal es un `<button>` (ver el comentario de
   `topnav.php`): se le quita la apariencia de botón para que se lea como lo que
   es, un ítem de menú. */
.topnav .navbar-nav > .nav-item > button.nav-link {
  background: none; border: 0; text-decoration: none;
  display: flex; align-items: center;
}
.topnav .navbar-nav > .nav-item > button.nav-link:focus-visible {
  outline: 2px solid var(--lhm-primario, #5156be); outline-offset: -2px;
}

/* Con el menú arriba, la caja de marca del topbar mostraba solo el símbolo: el
   tema oculta el logotipo largo según el tamaño del menú LATERAL, que aquí no
   existe. Con el menú horizontal hay sitio de sobra para el nombre.

   🔴 Y hay que ACOTAR su altura. El tema la calcula para acompañar al menú
   lateral —140 px— dentro de un topbar de 70: sin límite, la caja se derrama
   por debajo del topbar y, como este lleva `z-index: 1054` contra el 100 del
   menú de arriba, **tapa los primeros ítems**. En un móvil eso era un menú que
   se abría, se veía y no respondía al pulsarlo: el peor fallo posible, porque
   parece que el sistema está roto. */
[data-layout="horizontal"] .navbar-brand-box .logo-sm { display: none; }
[data-layout="horizontal"] .navbar-brand-box .logo-lg { display: inline-block; }
[data-layout="horizontal"] .navbar-brand-box {
  width: auto; padding-right: 1.25rem;
  height: 70px; overflow: hidden;
  display: flex; align-items: center;
}

/* El código QR de vinculación: legible sin ocupar la pantalla entera. */
.lhm-qr { max-width: 280px; border: 1px solid var(--bs-border-color, #e9e9ef); border-radius: .5rem; }

/* ── El recorrido guiado ──────────────────────────────────────────────────
   Sin librería: una capa oscura, un elemento resaltado y un globo. Traer una
   dependencia entera para esto sería pagar 40 KB por un rectángulo. */
.lhm-tour-capa {
  position: fixed; inset: 0; z-index: 1080;
  background: rgba(17, 24, 35, .55);
}
.lhm-tour-globo {
  position: fixed; z-index: 1082; width: min(340px, calc(100vw - 24px));
  background: #fff; border-radius: .5rem; padding: 1rem;
  box-shadow: 0 .5rem 1.5rem rgba(0, 0, 0, .25);
}
.lhm-tour-cab { display: flex; justify-content: space-between; align-items: center; margin-bottom: .5rem; }
/* Dentro de un capítulo del recorrido interactivo (`?capitulo=`): de qué capítulo es, la nota de quien presenta
   (solo en modo presentador) y el botón que cruza a la pantalla siguiente. */
.lhm-tour-capitulo { display: block; margin-bottom: .35rem; color: var(--bs-primary); font-size: .75rem; font-weight: 600; }
.lhm-tour-nota {
  margin: 0 0 .75rem; padding: .5rem .65rem; border-radius: .375rem; font-size: .8125rem;
  background: var(--bs-warning-bg-subtle, #fff3cd); border-left: 3px solid var(--bs-warning, #ffbf53);
}
.lhm-tour-continuar { display: block; width: 100%; margin-top: .5rem; }
/* 🔴 El elemento señalado sube POR ENCIMA de la capa oscura y se recorta con un
   halo: si solo se le pusiera un borde, seguiría atenuado bajo la capa y el
   recorrido señalaría algo que no se ve. */
.lhm-tour-destacado {
  position: relative; z-index: 1081;
  border-radius: .375rem;
  box-shadow: 0 0 0 4px rgba(var(--lhm-primario-rgb, 81, 86, 190), .55),
              0 0 0 9999px rgba(17, 24, 35, .55);
}

/* 🔴 Un `.badge` mide `0.75em`: RELATIVO a su padre. Dentro de un contenedor a
   13px queda en 9,75, y dentro de uno a 12 en 9 — justo el tamaño de las
   etiquetas que llevan el dato que más importa («en 9 días», «venció hace 16»).
   Nadie lo escribió así: sale de multiplicar dos decisiones razonables por
   separado.
   El suelo se pone aquí, en el sistema, y no vista por vista: el patrón se
   repite en cada tarjeta que combine texto pequeño con una etiqueta. */
.badge { font-size: max(0.75em, 11px); }

/* ── La disposición del menú ──────────────────────────────────────────────
   Los dos menús están en el DOM y aquí se decide cuál se ve. Así el cambio
   desde el panel de apariencia surte efecto al instante, sin recargar y sin
   pasar por un estado intermedio en el que no hay ninguno —o hay dos—. */
[data-layout="vertical"]   .topnav        { display: none !important; }
[data-layout="horizontal"] .vertical-menu { display: none !important; }

/* Cada disposición enseña su propio botón de menú. */
[data-layout="vertical"]   .lhm-solo-horizontal { display: none !important; }
[data-layout="horizontal"] .lhm-solo-vertical   { display: none !important; }
/* En pantalla ancha el menú de arriba está siempre desplegado: su botón sobra. */
@media (min-width: 992px) {
  [data-layout="horizontal"] .lhm-solo-horizontal { display: none !important; }
}

/* ── Procedencia de un análisis de IA ──────────────────────────────────────
   El detalle de con qué se hizo un análisis va plegado: quien solo quiere
   leerlo no tiene que pasar por encima, y quien necesita contrastarlo lo tiene
   a un clic. El triángulo por defecto del navegador queda pequeño y descolgado
   junto al icono, así que se sustituye por el propio. */
.lhm-procedencia > summary {
  list-style: none;
  display: inline-flex;
  align-items: center;
  gap: .25rem;
  user-select: none;
}
.lhm-procedencia > summary::-webkit-details-marker { display: none; }
.lhm-procedencia > summary::after {
  content: "\ea4a";                 /* boxicons: chevron-down */
  font-family: "boxicons";
  font-size: 1.1em;
  transition: transform .15s ease;
}
.lhm-procedencia[open] > summary::after { transform: rotate(180deg); }
.lhm-procedencia > summary:hover { text-decoration: underline; }
.lhm-procedencia > summary:focus-visible {
  outline: 2px solid var(--bs-primary);
  outline-offset: 2px;
  border-radius: 2px;
}

/* ── Área táctil de los indicadores del carrusel ───────────────────────────
   El tema los deja en 10×10 px (`carousel-indicators-rounded button`, con
   `!important`). WCAG 2.2 «Target Size» (AA) pide 24×24 px, y era el fallo de
   accesibilidad más caro de esta pantalla.

   🔴 Un pseudo-elemento MÁS GRANDE no sirve: el área que cuenta es la del
   elemento clicable, y ni Lighthouse ni el dedo del usuario ven un `::after`
   que sobresale. Hay que invertirlo — el BOTÓN pasa a medir 24×24 px y es
   transparente, y el punto visible de 10 px lo dibuja el pseudo-elemento
   centrado dentro. Se ve igual; lo que cambia es dónde se puede pulsar.

   Los `!important` son obligados: el tema los usa en esa misma regla. */
.carousel-indicators .lhm-indicador {
  width: 24px !important;
  height: 24px !important;
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: 0 !important;
  background-color: transparent !important;
  position: relative;
}
.carousel-indicators .lhm-indicador::before {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background-color: #fff;
}

/* ── DataTables 3 ──────────────────────────────────────────────────────────
   Detecta el tipo de cada columna y alinea a la DERECHA las de fecha y número
   (`dt-type-date`, `dt-type-numeric`), con el icono de orden a la izquierda del
   título. La primera columna del listado —radicado con su fecha en
   `data-order`— cae en «fecha» y salía pegada al borde derecho, distinta de
   las demás. Aquí todo se lee de izquierda a derecha, como siempre. */
table.dataTable th.dt-type-date, table.dataTable td.dt-type-date,
table.dataTable th.dt-type-numeric, table.dataTable td.dt-type-numeric { text-align: left; }
table.dataTable th.dt-type-date div.dt-column-header,
table.dataTable th.dt-type-numeric div.dt-column-header { flex-direction: row; }

/* ── El centro de ayuda y el manual por familia ───────────────────────────
   Sobre las tarjetas y utilidades del tema; solo lo que Minia no trae: los
   bloques «razón de ser / para qué sirve / cómo se usa», el flujo numerado, la
   figura ampliable, el índice pegajoso y la versión impresa. */
.lhm-man-hero { border-left: 4px solid var(--bs-primary); }
.lhm-man-tarjeta { transition: box-shadow .15s ease, transform .15s ease; text-decoration: none; }
.lhm-man-tarjeta:hover { box-shadow: 0 .5rem 1rem rgba(0, 0, 0, .12); transform: translateY(-2px); }
.lhm-man-lista li { line-height: 1.7; }
.lhm-man-lista .bx { vertical-align: -2px; }
.lhm-man-busca { flex: 1 1 220px; max-width: 320px; }
.lhm-man-toc { position: sticky; top: 90px; max-height: calc(100vh - 110px); overflow: auto; }
.lhm-man-toc .nav-link { padding: .3rem .5rem; font-size: .8125rem; color: var(--bs-body-color); border-left: 2px solid transparent; }
.lhm-man-toc .nav-link.active { color: var(--bs-primary); border-left-color: var(--bs-primary); background: var(--bs-primary-bg-subtle, rgba(81, 86, 190, .08)); }
.lhm-man-toc .nav-link .bx { vertical-align: -2px; margin-right: .25rem; }
.lhm-man-progreso { height: 4px; }
.lhm-man-seccion { scroll-margin-top: 90px; }
.lhm-man-num {
  display: inline-flex; align-items: center; justify-content: center;
  width: 1.9rem; height: 1.9rem; border-radius: 50%; font-size: .9rem; font-weight: 600;
  background: var(--bs-primary); color: #fff; vertical-align: middle; margin-right: .25rem;
}
.lhm-man-bloque { border-left: 3px solid var(--bs-border-color); padding: .6rem .9rem; margin-bottom: .9rem; border-radius: 0 .375rem .375rem 0; background: var(--bs-tertiary-bg, #f8f9fa); }
.lhm-man-bloque h6 { font-size: .8125rem; text-transform: uppercase; letter-spacing: .02em; margin-bottom: .4rem; }
.lhm-man-bloque h6 .bx { vertical-align: -2px; margin-right: .2rem; }
.lhm-man-por-que  { border-left-color: var(--bs-warning); }
.lhm-man-para-que { border-left-color: var(--bs-success); }
.lhm-man-como     { border-left-color: var(--bs-primary); }
.lhm-man-faq      { border-left-color: var(--bs-info); }
.lhm-man-pasos { padding-left: 1.2rem; }
.lhm-man-pasos li { margin-bottom: .3rem; }
.lhm-man-flujo { display: grid; gap: .6rem; }
.lhm-man-paso { display: flex; gap: .6rem; align-items: flex-start; }
.lhm-man-paso-num {
  flex: 0 0 1.6rem; width: 1.6rem; height: 1.6rem; border-radius: 50%; font-size: .8rem; font-weight: 600;
  display: inline-flex; align-items: center; justify-content: center; background: var(--bs-primary); color: #fff;
}
.lhm-man-figura { margin: 0 0 1rem; }
.lhm-man-figura img { border: 1px solid var(--bs-border-color); border-radius: .375rem; box-shadow: 0 .25rem .75rem rgba(0, 0, 0, .08); cursor: zoom-in; }
.lhm-man-figura figcaption { margin-top: .35rem; }
.lhm-man-nota .bx { vertical-align: -2px; }
.lhm-man-barra { position: sticky; top: 70px; z-index: 5; }

/* Impreso o guardado en PDF: sin menú, sin topbar, sin índice, sin botones;
   cada sección empieza en página nueva y las figuras no se parten. */
@media print {
  .vertical-menu, #page-topbar, .topnav, .footer, .lhm-man-barra, .lhm-man-toc, .page-title-box, .d-print-none { display: none !important; }
  .main-content { margin-left: 0 !important; }
  .page-content { padding: 0 !important; }
  .lhm-man-seccion { break-before: page; box-shadow: none; border: 0; }
  .lhm-man-seccion:first-of-type { break-before: auto; }
  .lhm-man-figura, .lhm-man-bloque, .lhm-man-paso { break-inside: avoid; }
  .col-xl-7, .col-xl-5 { width: 100%; max-width: 100%; flex: 0 0 100%; }
  .lhm-man-figura img { cursor: default; box-shadow: none; }
}

/* El aviso de privacidad en la pantalla de entrada: texto legal legible, no un muro. */
.lhm-privacidad { max-width: 640px; margin: 0 auto; text-align: left; line-height: 1.6; }
.lhm-privacidad p { margin-bottom: .75rem; }

/* Informe a medida: grupos de columnas elegibles */
.lhm-grupo-columnas {
  border: 1px solid var(--bs-border-color, #e9e9ef);
  border-radius: .5rem;
  padding: .75rem 1rem;
}
.lhm-grupo-columnas > legend {
  float: none;
  width: auto;
  padding: 0 .5rem;
  margin-bottom: .25rem;
}

/* Bandeja de notificaciones: el asunto y el remitente pueden ser larguísimos —un correo
   institucional completo ocupa media pantalla— y empujaban la tabla hasta dejar fuera el
   estado y el botón de clasificar. Se vio en la captura, no en ningún gate. El ancho se
   acota y el texto se trunca con su `title`, que conserva el dato completo. */
.lhm-not-asunto { max-width: 26rem; }
@media (max-width: 1399.98px) { .lhm-not-asunto { max-width: 18rem; } }

/* Formularios en línea de la ficha y la bandeja: etiqueta arriba, campo debajo, ayuda al
   pie, y los campos a la misma altura en toda la fila.

   🔴 Por qué existe. Estas filas usaban `align-items-end`, que alinea por la BASE del
   elemento: un campo con dos líneas de ayuda empuja su etiqueta muy por encima de la del
   vecino que no tiene ninguna, y la fila se lee como si estuviera rota. Se vio en la
   pantalla de clasificación de notificaciones, donde «¿Qué es?», «Radicado del
   expediente» y «Plazo (días hábiles)» quedaban a tres alturas distintas. Ningún gate
   podía verlo: no hay error de consola, ni clase inexistente, ni desborde. Lo encontró
   una persona mirando la pantalla, y solo mirándola se comprueba el arreglo.

   La medida es la LÍNEA, no un número redondo: la etiqueta usa 13 px con interlínea de
   19,5 px, así que dos renglones son 39 px = 3em. Reservarlos hace que la etiqueta que se
   parte en dos —«Plazo (días hábiles)», en una columna estrecha— quepa sin empujar su
   campo por debajo de los vecinos. `align-content: end` pega la de un solo renglón al
   fondo de esa reserva, de modo que todas terminan a la misma altura y el aire sobrante
   queda arriba, junto al borde de la tarjeta, donde se lee como margen y no como salto.

   🔴 Y por qué no se reparte el alto con `margin-bottom: auto` en la etiqueta, que
   parecía la solución elegante —el navegador iguala solo, sin ninguna medida escrita a
   mano—: la ayuda va DEBAJO del campo, así que el margen automático empuja el bloque
   «campo + ayuda» al fondo y la columna que lleva ayuda sube su campo respecto a la que
   no. Se probó: en la pestaña de pruebas dejó los cuatro campos a cuatro alturas, peor
   que antes, y estiró el botón a todo el ancho. Una reserva fija es más tosca y acierta. */
.lhm-form-linea .form-label { min-height: 3em; margin-bottom: .3rem; align-content: end; }
.lhm-form-linea .form-text  { min-height: 2.6em; margin-top: .25rem; }

/* En pantalla estrecha las columnas se apilan y las alturas mínimas solo dejarían
   huecos: cada campo vuelve a ocupar lo que necesita. */
@media (max-width: 767.98px) {
  .lhm-form-linea .form-label,
  .lhm-form-linea .form-text { min-height: 0; }
}

/* Una columna cuyo único contenido es un botón no tiene etiqueta que la empuje, así que
   el botón queda arriba mientras los campos de al lado están abajo. Se baja a su línea.
   Pasaba con «Archivar» en la bandeja de notificaciones. */
.lhm-form-linea .lhm-col-boton { display: flex; align-items: flex-end; }
.lhm-form-linea .lhm-col-boton .btn { width: 100%; }
@media (max-width: 767.98px) { .lhm-form-linea .lhm-col-boton { display: block; } }

/* ── Consulta a la Rama Judicial ───────────────────────────────────────────────
   El selector, el campo y el botón van en UN `.input-group`: misma altura por
   construcción, sin depender de cómo se alineen dos columnas (trampa 139). Los
   selectores no se estiran: el que crece es el campo. */
.lhm-rj-buscar .lhm-rj-modo,
.lhm-rj-buscar .lhm-rj-tipo { flex: 0 0 auto; width: auto; max-width: 14rem; }
.lhm-rj-buscar .input-group > .form-control { min-width: 12rem; }
/* En el móvil no caben cuatro piezas en una fila: cada una ocupa la suya, con sus
   esquinas, en vez de partirse a medias. */
@media (max-width: 575.98px) {
  .lhm-rj-buscar .input-group { flex-wrap: wrap; gap: .5rem; }
  .lhm-rj-buscar .input-group > * { flex: 1 1 100%; max-width: none; width: 100%;
                                     margin-left: 0 !important; border-radius: var(--bs-border-radius) !important; }
}
.lhm-rj-sujetos { min-width: 16rem; }
.lhm-rj-proceso + .lhm-rj-proceso { margin-top: 1rem; }
.lhm-rj-docs { border-left: 2px solid var(--bs-border-color); padding-left: .75rem; }

/* ── El asistente de IA de cada pantalla (panel lateral) ─────────────────────── */
.lhm-asistente { --bs-offcanvas-width: 440px; }
.lhm-asistente-ctx { font-size: .78rem; color: var(--bs-secondary-color); margin-top: .25rem; line-height: 1.35; }
.lhm-asistente-cuerpo { display: flex; flex-direction: column; padding: 0; }
.lhm-asistente-chat { flex: 1 1 auto; overflow-y: auto; padding: 1rem; display: flex; flex-direction: column; gap: .6rem; }
.lhm-asistente-msg { max-width: 92%; padding: .55rem .8rem; border-radius: .6rem; font-size: .86rem; line-height: 1.45; }
.lhm-asistente-msg p { margin: 0 0 .4rem; }
.lhm-asistente-msg p:last-child { margin-bottom: 0; }
.lhm-asistente-msg ul { margin: .2rem 0 .4rem; padding-left: 1.1rem; }
.lhm-asistente-bot { align-self: flex-start; background: var(--bs-tertiary-bg); }
.lhm-asistente-yo  { align-self: flex-end; background: var(--bs-primary); color: #fff; }
.lhm-asistente-pensando { color: var(--bs-secondary-color); }
.lhm-asistente-proc { margin-top: .45rem; font-size: .72rem; color: var(--bs-secondary-color); }
.lhm-asistente-sug { padding: .5rem 1rem; border-top: 1px solid var(--bs-border-color); }
.lhm-asistente-chip { margin: 0 .3rem .3rem 0; font-size: .76rem; }
.lhm-asistente-form { display: flex; gap: .5rem; align-items: flex-end; padding: .6rem 1rem; border-top: 1px solid var(--bs-border-color); }
.lhm-asistente-form textarea { resize: none; font-size: .86rem; }
.lhm-asistente-form .btn { flex: 0 0 auto; min-width: 44px; min-height: 44px; }
.lhm-asistente-pie { padding: .4rem 1rem .8rem; font-size: .7rem; color: var(--bs-secondary-color); }
@media (max-width: 575.98px) { .lhm-asistente { --bs-offcanvas-width: 100vw; } }

/* ── Videotutoriales (galería y manual) ───────────────────────────────────────
   Un vídeo por procedimiento (docs/videos/). El reproductor es 16:9 a lo ancho de su
   columna; los capítulos, botones; impreso, el reproductor desaparece y queda el aviso
   con el título, la duración y dónde verlo (`.lhm-video-impreso`). */
.lhm-video { position: relative; }
.lhm-man-videos { border-left-color: var(--bs-info); }
.lhm-video-marco { position: relative; border-radius: .5rem; overflow: hidden; background: #111823; box-shadow: 0 .5rem 1.25rem rgba(17, 24, 35, .18); }
.lhm-video-reproductor { display: block; width: 100%; aspect-ratio: 16 / 9; background: #111823; }
/* La pantalla completa PROPIA del reproductor (trampa 256): la del MARCO, no la nativa del `<video>`, que en Chrome sobre
   macOS congelaba la página al salir de ella cuando el vídeo terminaba. El botón queda arriba a la derecha, lejos de los
   controles nativos de abajo; 36 px de área (trampa 8). */
.lhm-video-completa {
  position: absolute; top: .5rem; right: .5rem; z-index: 2; width: 36px; height: 36px; padding: 0; border: 0;
  border-radius: .4rem; background: rgba(17, 24, 35, .65); color: #fff; font-size: 1.25rem;
  display: inline-flex; align-items: center; justify-content: center; opacity: .75; transition: opacity .2s;
}
.lhm-video-completa:hover, .lhm-video-completa:focus-visible { opacity: 1; }
.lhm-video-marco:fullscreen { display: flex; align-items: center; justify-content: center; background: #000; border-radius: 0; box-shadow: none; }
.lhm-video-marco:fullscreen .lhm-video-reproductor { width: 100%; height: 100%; aspect-ratio: auto; object-fit: contain; background: #000; }
.lhm-video-marco:-webkit-full-screen { display: flex; align-items: center; justify-content: center; background: #000; border-radius: 0; box-shadow: none; }
.lhm-video-marco:-webkit-full-screen .lhm-video-reproductor { width: 100%; height: 100%; aspect-ratio: auto; object-fit: contain; background: #000; }
@media (prefers-reduced-motion: reduce) { .lhm-video-completa { transition: none; } }
.lhm-video-datos { margin-top: .9rem; }
.lhm-video-capitulos { display: flex; flex-wrap: wrap; gap: .35rem; }
.lhm-video-capitulos .btn { text-align: left; }
.lhm-video-capitulos .btn[aria-current] { background: var(--bs-primary); color: #fff; }
.lhm-video-t { font-variant-numeric: tabular-nums; font-weight: 600; opacity: .8; margin-right: .2rem; }
.lhm-video-transcripcion summary { cursor: pointer; color: var(--bs-primary); }
.lhm-video-impreso { display: none; }
.lhm-video-tarjeta { overflow: hidden; }
.lhm-video-tarjeta-actual { outline: 2px solid var(--bs-primary); }
.lhm-video-mini { position: relative; display: block; aspect-ratio: 16 / 9; background: #111823; }
.lhm-video-mini img { width: 100%; height: 100%; object-fit: cover; display: block; }
.lhm-video-duracion { position: absolute; right: .5rem; bottom: .5rem; padding: .05rem .4rem; border-radius: .25rem; background: rgba(17, 24, 35, .85); color: #fff; font-size: .75rem; font-variant-numeric: tabular-nums; }
.lhm-video-pendiente { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: .25rem; color: rgba(255, 255, 255, .75); font-size: .8rem; }
.lhm-video-pendiente .bx { font-size: 2rem; }
.lhm-man-videos-lista { display: flex; flex-direction: column; gap: .6rem; }
.lhm-man-video-fila { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; }
@media print {
  .lhm-video-marco, .lhm-video-capitulos, .lhm-video-transcripcion { display: none !important; }
  .lhm-video-impreso { display: block !important; font-style: italic; }
}

/* ── Tarjetas de una misma fila: todas con el alto de la más alta (2026-10-03) ───────────────────────────────────
   Bootstrap estira las COLUMNAS de una fila (flex, align-items: stretch), pero no la tarjeta que llevan dentro: la que
   traía dos renglones de ayuda quedaba más alta que sus vecinas y la fila se leía torcida (los recuadros de un lote
   de cargue, las cifras de notificaciones, los vídeos del centro de ayuda). Cuando la tarjeta es lo ÚNICO de su
   columna, la columna pasa a flex vertical y la tarjeta crece hasta el alto de la fila; su margen inferior se respeta.
   🔴 Solo columnas DE VERDAD (`col`, `col-*`): `[class*="col"]` casaría con `.collapse` y lo mostraría plegado.
   Quedan fuera, a propósito: dos tarjetas apiladas en una columna (se reparten la columna), una fila con
   `align-items-*` (no estira sus columnas) y `.lhm-fila-libre` —el contenido principal y su panel lateral (la ficha,
   tareas, el análisis con IA, los vídeos)—, donde estirar el panel dejaría un recuadro vacío del alto de la página.
   Lo mide tests/ui/tarjetas.py en todas las vistas de los tres clientes, y exige que toda fila libre tenga columnas
   de anchos distintos: la excepción no puede esconder una rejilla de tarjetas.
   🔴 Y no solo `.card`: las cajas de cifras con borde (`div.border.rounded`, en el informe de equipo, la cartera, la
   provisión y el material probatorio) tenían el mismo defecto y la regla no las veía — «Promedio» con su línea de
   denominador era más alta que «El que más tardó». Cuenta toda caja con `.border` que sea lo único de su columna. */
.row:not(.lhm-fila-libre) > :is(.col, [class^="col-"], [class*=" col-"]):has(> :is(.card, .border):only-child) { display: flex; flex-direction: column; }
.row:not(.lhm-fila-libre) > :is(.col, [class^="col-"], [class*=" col-"]) > :is(.card, .border):only-child { flex: 1 1 auto; }

/* ── La calculadora de términos (herramientas/terminos.php, 2026-10-03) ─────────────────────────────────────────
   Los días que no se cuentan van en gris y con fondo, para que el ojo siga solo los numerados. Con las variables del
   tema y no con `bg-light`, que no cambia en el modo oscuro y dejaría filas blancas sobre fondo oscuro. El gris del
   texto es el de `.text-muted` (sección 2): el `--bs-secondary-color` del tema no llega a AA sobre fondo claro. */
.lhm-termino-saltado > td { color: #5A6274; background-color: var(--bs-tertiary-bg); }
[data-bs-theme="dark"] .lhm-termino-saltado > td { color: var(--bs-secondary-color); }

/* ── El menú «Herramientas» de la barra superior (2026-10-03): las 20 herramientas por categoría y la calculadora.
   Más ancho que un desplegable normal y con su propio desplazamiento: no puede salirse de la pantalla. */
.lhm-herr-menu { width: 560px; max-width: calc(100vw - 24px); }
.lhm-herr-menu-cuerpo { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 2px 12px; padding: 8px 10px 10px;
                        max-height: min(70vh, 640px); overflow-y: auto; }
.lhm-herr-menu-grupo { min-width: 0; }
.lhm-herr-menu-cat { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: var(--bs-secondary-color);
                     padding: 8px 8px 4px; }
.lhm-herr-menu-item { display: flex; align-items: center; gap: 8px; padding: 6px 8px; border-radius: 6px; font-size: 13px;
                      white-space: normal; }
.lhm-herr-menu-item i { font-size: 17px; color: var(--bs-primary); flex: 0 0 auto; }

/* ── Menú plegable (migración 225) ─────────────────────────────────────────────────────────────────────────────────
   El subtítulo de un grupo dentro de una categoría plegable del lateral (Datos Maestros → «Territorio»). No es un
   enlace: no se pulsa ni recibe foco. Mismo color que los títulos de sección, más pequeño, alineado con los ítems. */
#sidebar-menu .sub-menu > li.lhm-menu-grupo { padding: .6rem 1.5rem .15rem 3.3rem; font-size: .68rem; font-weight: 600;
                                              letter-spacing: .04em; text-transform: uppercase; pointer-events: none;
                                              color: var(--bs-sidebar-menu-item-icon-color); }
[data-sidebar="dark"] #sidebar-menu .sub-menu > li.lhm-menu-grupo { color: var(--bs-sidebar-dark-menu-item-icon-color); }
#sidebar-menu .sub-menu > li.lhm-menu-grupo:first-child { padding-top: .2rem; }
body[data-sidebar-size="sm"] #sidebar-menu .sub-menu > li.lhm-menu-grupo { padding-left: 1.5rem; }
/* El menú horizontal: cada grupo es un bloque que no se parte, y la categoría larga va en dos columnas. */
.topnav .dropdown-menu.lhm-topnav-columnas { column-count: 2; column-gap: 0; min-width: 32rem; }
.topnav .lhm-topnav-grupo { break-inside: avoid; }
/* Un rótulo de dos renglones («Herramientas de documentos») dejaba el segundo debajo del icono. Con el menú normal,
   sangría francesa: el texto en su columna y la flecha de los plegables al final. No en «Compacto» ni en «Iconos»,
   que maquetan el enlace a su manera. */
body:not([data-sidebar-size="sm"]):not([data-sidebar-size="md"]) #side-menu > li > a { display: flex; align-items: flex-start; }
body:not([data-sidebar-size="sm"]):not([data-sidebar-size="md"]) #side-menu > li > a > i { flex: 0 0 auto; }
body:not([data-sidebar-size="sm"]):not([data-sidebar-size="md"]) #side-menu > li > a > span { flex: 1 1 auto; min-width: 0; }
body:not([data-sidebar-size="sm"]):not([data-sidebar-size="md"]) #side-menu > li > a.has-arrow::after { margin-left: auto; padding-left: .25rem; }
/* En «Compacto» el plegable flota a la derecha del icono; uno largo (Datos Maestros, 19 enlaces) va en dos columnas
   para que quepa en el alto de un portátil. `lhm-menu.js` lo sube si aun así no cabe debajo. */
body[data-sidebar-size="sm"] .vertical-menu #sidebar-menu > ul > li:hover > ul.lhm-sub-largo { width: 430px; column-count: 2; column-gap: 0; }
body[data-sidebar-size="sm"] #sidebar-menu ul.lhm-sub-largo > li { break-inside: avoid; }
body[data-sidebar-size="sm"] #sidebar-menu ul.lhm-sub-largo > li.lhm-menu-grupo { break-after: avoid; }

/* ── La ayuda a la vista (titulo.php, lhm-ayuda-vista.js) ─────────────────────────────────────────────────────────
   Tres botones junto al título: «Cómo funciona», «Manual» y «Vídeo». Pequeños para no competir con el título, pero de
   32 px de alto: es lo que pide un dedo (WCAG 2.2 exige 24 como mínimo; trampa 8). */
.lhm-ayuda-vista .btn { display: inline-flex; align-items: center; gap: .3rem; min-height: 2rem; padding: .2rem .55rem;
                        font-size: .75rem; line-height: 1.2; }
.lhm-ayuda-vista .btn i { font-size: 1rem; }
/* La bienvenida de la primera visita: abajo a la derecha, por encima del contenido y por debajo de los modales. */
.lhm-bienvenida { position: fixed; right: 1.5rem; bottom: 1.5rem; z-index: 1045; width: min(24rem, calc(100vw - 2rem));
                  margin: 0; border: 1px solid var(--bs-border-color); }
@media (max-width: 575.98px) {
  .lhm-bienvenida { left: 1rem; right: 1rem; bottom: 1rem; width: auto; }
}
.lhm-titulo-pagina { min-width: 0; }
.lhm-ayuda-rotulo { white-space: nowrap; }

/* ── Trámites por pasos: lo que también sale en la pestaña de la ficha (que no carga lhm-tramites.css) ───────────
   El semáforo dice sus cifras («1 crítica pendiente · vence en 6 días hábiles»): una insignia de una sola línea se
   salía del teléfono. Parte líneas, y en la pestaña el bloque no pasa de la mitad del ancho en escritorio. */
.lhm-tramite-fila .lhm-tramite-progreso { height: .35rem; }
.lhm-tramite-semaforo { white-space: normal; text-align: right; line-height: 1.4; }
.lhm-tramite-estado { max-width: 100%; }
@media (min-width: 576px) { .lhm-tramite-estado { max-width: 50%; } }
.lhm-tramite-insignia { white-space: normal; line-height: 1.4; text-align: left; }

/* ── Indicadores de gestión (informes/gestion.php) ─────────────────────────────────────────────────────────────────────
   Las tarjetas del resumen llevan a su sección (stretched-link); la barra de las etapas procesales es una proporción,
   no un logro: va en el color primario, sin verde ni rojo. */
.lhm-gestion-tarjeta .card-body { position: relative; }
.lhm-gestion-barra { height: .5rem; min-width: 4rem; }
.lhm-gestion-etapas td:first-child { min-width: 9rem; }
/* En un celular pequeño, dos cifras por fila parten las palabras («Extemporáne-as»): una por fila. */
@media (max-width: 374.98px) { .lhm-gestion-cifra { flex: 0 0 100%; max-width: 100%; } }
/* Y las tablas, compactas: con el relleno de escritorio la columna «Evaluables» quedaba cortada dentro de su scroll. */
@media (max-width: 575.98px) {
  .lhm-gestion-seccion > .card-body { padding: 1rem .75rem; }
  .lhm-gestion-tabla, .lhm-gestion-tabla th, .lhm-gestion-tabla td { font-size: .75rem; }
  .lhm-gestion-tabla > :not(caption) > * > * { padding: .3rem .25rem; }
  .lhm-gestion-etapas td:first-child { min-width: 7rem; }
}
.lhm-gestion-etapas-lista li:last-child { border-bottom: 0 !important; }

/* La hora junto a la fecha (pestaña Tutela): lo justo para «11:30», sin quitarle ancho a la fecha. */
.lhm-hora-corta { flex: 0 0 auto; width: 6.5rem; }
/* Una ayuda que explica dos campos de la fila de arriba, pegada a ellos (Bootstrap del tema no trae márgenes negativos). */
.lhm-ayuda-pegada { margin-top: -.5rem; }

/* ── Líneas de tiempo (perfil, panel, Rama Judicial, actuaciones) en el celular ─────────────────────────────────────────
   🔴 La fecha (y los botones) al lado del texto le dejaban unos 80 px a 360 de ancho y el navegador partía las palabras
   («Abrió», «expediente») sin desbordar: ninguna auditoría de desbordes lo veía (la de palabras partidas, sí). En el
   celular la fecha va ENCIMA, en una línea. */
@media (max-width: 575.98px) {
  .timeline-list-item > .d-flex { flex-direction: column; }
  .timeline-list-item > .d-flex > .flex-shrink-0 { order: -1; text-align: left !important; margin: 0 0 .25rem 0 !important;
                                                   display: flex; flex-wrap: wrap; align-items: center; gap: .25rem .5rem; }
  .timeline-list-item > .d-flex > .flex-shrink-0 > h6 { margin: 0 !important; }
  .timeline-list-item > .d-flex > .flex-grow-1 { margin-right: 0 !important; }
}

/* ── Normativa del cómputo de términos (herramientas/normativa.php) ─────────────────────────────────────────────────────
   El texto literal se lee como cita: borde a la izquierda, sin cursiva (es la norma, no un comentario). */
.lhm-norma-texto { border-left: 3px solid var(--bs-primary); padding: .5rem 0 .5rem .9rem; margin: 0; font-size: .875rem;
                   background: var(--bs-tertiary-bg, transparent); }
.lhm-norma-texto p { margin-bottom: .5rem; }
.lhm-norma-texto p:last-child { margin-bottom: 0; }
.lhm-norma { scroll-margin-top: 90px; }

/* Los derechos: el artículo de la Constitución, un botón que abre su texto literal (`lhm-constitucion.js`). */
.lhm-cp-boton { padding: .1rem .45rem; font-size: 12px; margin: 0 .15rem .15rem 0; white-space: nowrap; }
.lhm-cp-sugerido { font-size: 12px; text-decoration: underline dotted; vertical-align: baseline; }
.lhm-cp-texto { font-family: Georgia, "Times New Roman", serif; font-size: 15px; line-height: 1.6; color: var(--bs-body-color);
  border-left: 3px solid rgba(var(--lhm-primario-rgb), .35); padding-left: 1rem; margin-bottom: 1rem; }
.lhm-cp-texto p { margin-bottom: .75rem; }
.lhm-cp-texto p:last-child { margin-bottom: 0; }
.lhm-cp-datos { display: grid; grid-template-columns: max-content 1fr; gap: .25rem 1rem; }
.lhm-cp-datos dt { font-weight: 600; color: var(--bs-secondary-color); }
.lhm-cp-datos dd { margin: 0; overflow-wrap: anywhere; }
.lhm-cp-datos [hidden] { display: none; }
@media (max-width: 575.98px) {
  .lhm-cp-datos { grid-template-columns: 1fr; }
  .lhm-cp-datos dd { margin-bottom: .4rem; }
}

/* ── LHM Contratos (Hito 1, 2026-11-02) ─────────────────────────────────────────────────────────────────────────── */
/* El objeto de un contrato puede ser un párrafo largo: en el listado y en la cabecera de la ficha se parte por
   palabras (no a mitad de palabra, trampa 235) y nunca empuja la tabla fuera de la pantalla. */
.lhm-contrato-objeto { overflow-wrap: break-word; word-break: normal; hyphens: manual; max-width: 60ch; }
/* La huella de un documento: monoespaciada y legible, sin partir a mitad de los 16 caracteres que se enseñan. */
.lhm-huella { font-family: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: .8125rem; white-space: nowrap; color: var(--bs-body-color); }
/* La cita literal de un contrato en la matriz de riesgo: se distingue del texto del producto y no desborda. */
.lhm-cita-contrato { border-left: 3px solid var(--bs-warning); padding: .4rem .8rem; margin: 0; background: var(--bs-tertiary-bg, rgba(0,0,0,.03));
  font-family: "Source Serif 4", Georgia, "Times New Roman", serif; font-size: .9375rem; overflow-wrap: break-word; }
/* El texto literal de un artículo, desplegado bajo su hallazgo. */
.lhm-norma-texto { border-left: 3px solid var(--bs-info); padding: .3rem .8rem; font-family: "Source Serif 4", Georgia, serif; overflow-wrap: break-word; }
.lhm-hallazgo { overflow-wrap: break-word; }
