/* Overrides globales del panel sobre Mosaic (cargar DESPUÉS de mosaic.css).
   Correcciones de tema que las utilidades purgadas de Tailwind no cubren. */

/* Cursor de mano en los elementos interactivos. Tailwind v4 dejó los <button> con
   `cursor: default`; se restaura el `pointer` (el mismo de los enlaces) en botones y
   elementos con rol de botón. Los deshabilitados mantienen su cursor por defecto. */
button:not(:disabled),
[type="button"]:not(:disabled),
[type="submit"]:not(:disabled),
[type="reset"]:not(:disabled),
[role="button"]:not([aria-disabled="true"]) {
  cursor: pointer;
}

/* `<select>` nativo en modo oscuro: `.form-select` fija fondo blanco y no recibe el dark
   (las utilidades dark:* no están en el CSS purgado). Se ennegrece el control y, con
   color-scheme dark, el desplegable nativo de opciones también sale oscuro. */
.dark select,
.dark select.form-select {
  color-scheme: dark;
  background-color: var(--color-gray-800);
  color: var(--color-gray-300);
  border-color: var(--color-gray-700);
}
.dark select option,
.dark select optgroup {
  background-color: var(--color-gray-800);
  color: var(--color-gray-300);
}

/* Tooltip propio de [data-tooltip] (lo monta panel.js en <body> con position:fixed).
   Sus estilos vivían en panel.css, que dejó de cargarse en la migración a Mosaic y además
   usaba variables de Tabler (--tblr-*): el tooltip se creaba sin estilo y no se veía. Se
   reescribe aquí (CSS global ya cargado) con el aspecto del componente Tooltip de Mosaic:
   caja blanca con borde, sombra y esquinas redondeadas; sin flecha. */
.panel-tooltip {
  position: fixed;
  z-index: 1080;
  max-width: 20rem;
  padding: 0.5rem;
  border: 1px solid var(--color-gray-200);
  border-radius: 0.5rem;
  background: #fff;
  color: var(--color-gray-600);
  font-size: 0.75rem;
  line-height: 1rem;
  box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
  pointer-events: none;
}
.dark .panel-tooltip {
  border-color: var(--color-gray-700);
  background: var(--color-gray-800);
  color: var(--color-gray-300);
}

/* Barra de fortaleza de contraseña (alta/edición de usuario, cambio de contraseña...). El JS
   (user-form-validate / user-edit-validate / account-password) sigue marcando los segmentos con
   is-weak/is-fair/is-good/is-strong, pero sus estilos también se quedaron en panel.css: sin
   ellos los segmentos median 0px y no se veía nada. Colores del tema en vez de vars de Tabler. */
.pw-strength {
  display: flex;
  gap: 4px;
}
.pw-strength-seg {
  flex: 1;
  height: 4px;
  border-radius: 2px;
  background: var(--color-gray-200);
  transition: background 0.15s ease-in-out;
}
.dark .pw-strength-seg {
  background: var(--color-gray-700);
}
.pw-strength-seg.is-weak {
  background: var(--color-red-500);
}
.pw-strength-seg.is-fair {
  background: var(--color-yellow-500);
}
.pw-strength-seg.is-good {
  background: var(--color-sky-500);
}
.pw-strength-seg.is-strong {
  background: var(--color-green-500);
}

/* Barra de progreso superior en las navegaciones (page-loader.js). Mismo caso: su CSS estaba en
   panel.css y el color venía de --tblr-primary. */
.page-progress {
  position: fixed;
  top: 0;
  left: 0;
  height: 3px;
  width: 0;
  z-index: 2147483647;
  background: var(--color-violet-500);
  opacity: 0;
  transition:
    width 0.3s ease-out,
    opacity 0.15s 0.15s ease-in;
  transform: translate3d(0, 0, 0);
}

/* Cabeceras de tabla ordenables: el <thead> lleva `uppercase`, pero el reset de formularios
   fija `text-transform: none` en <button>, que gana a la herencia y dejaba las columnas con
   botón de orden (p. ej. Nombre, Último acceso) en minúsculas mientras el resto salía en
   mayúsculas. */
thead th button {
  text-transform: inherit;
}

/* Item "peligroso" (rojo) de los menús de acciones. Los items comparten una base con
   `dark:text-gray-300`, cuya especificidad (:is(.dark *)) gana a `text-red-500` en oscuro y
   los volvía grises. Este hook fija el rojo en ambos temas con especificidad suficiente. */
.menu-item-danger {
  color: var(--color-red-500);
}
.dark .menu-item-danger {
  color: var(--color-red-400);
}

/* Zebra de la lista de metadatos del Drawer de colas. Se usa `nth-of-type(div)` en vez de
   `nth-child`/Tailwind `odd:` porque Alpine deja los `<template x-if>` de las filas condicionales
   en el DOM: `nth-child` los contaría y desalinearía las bandas; `div:nth-of-type` solo cuenta las
   filas reales (los <div>), respetando el orden visual. */
.qd-meta > div:nth-of-type(odd) {
  background-color: var(--color-gray-50);
}
.dark .qd-meta > div:nth-of-type(odd) {
  background-color: rgb(55 65 81 / 0.35);
}

/* Filas alternas (zebra) para tablas de listado. Añade la clase `zebra-rows` al <tbody>.
   Se usa `tr:nth-of-type(even)` (no `nth-child`/Tailwind `even:`) para IGNORAR el `<template
   x-for>` y las <tr> de estado vacío/error que Alpine deja en el DOM: contarlas desalinearía las
   bandas. El `:hover` va DESPUÉS y con la misma especificidad, así gana por orden y resalta la fila
   apuntada por encima de la banda. */
.zebra-rows > tr:nth-of-type(even),
.zebra-rows > label:nth-of-type(even),
.zebra-rows > button:nth-of-type(even),
.zebra-rows > li:nth-of-type(even),
.zebra-rows > div:nth-of-type(even) {
  background-color: var(--color-gray-50);
}
.dark .zebra-rows > tr:nth-of-type(even),
.dark .zebra-rows > label:nth-of-type(even),
.dark .zebra-rows > button:nth-of-type(even),
.dark .zebra-rows > li:nth-of-type(even),
.dark .zebra-rows > div:nth-of-type(even) {
  background-color: rgb(55 65 81 / 0.25);
}
.zebra-rows > tr:hover,
.zebra-rows > label:hover,
.zebra-rows > button:hover,
.zebra-rows > li:hover,
.zebra-rows > div:hover {
  background-color: var(--color-gray-100);
}
.dark .zebra-rows > tr:hover,
.dark .zebra-rows > label:hover,
.dark .zebra-rows > button:hover,
.dark .zebra-rows > div:hover {
  background-color: rgb(55 65 81 / 0.45);
}

/* ── Icono de calendario en TODOS los campos de fecha ──────────────────────────────────────
   Air Datepicker se engancha a `input[data-datepicker]`; el icono va como background para
   que lo herede cualquier campo de fecha del panel, incluidos los que Alpine crea al vuelo
   (alta por IA, filas de componentes…), sin repetir el <span> en cada plantilla.
   Es el mismo trazo de calendario que se usaba a mano, en gray-400 (vale en claro y oscuro). */
input[data-datepicker] {
  padding-right: 2.5rem;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%239ca3af' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 7a2 2 0 0 1 2 -2h12a2 2 0 0 1 2 2v12a2 2 0 0 1 -2 2h-12a2 2 0 0 1 -2 -2v-12z'/%3E%3Cpath d='M16 3v4'/%3E%3Cpath d='M8 3v4'/%3E%3Cpath d='M4 11h16'/%3E%3Cpath d='M11 15h1'/%3E%3Cpath d='M12 15v3'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.75rem center;
  background-size: 1.3rem 1.3rem;
}

/* ── Texto que nunca desborda su caja ──────────────────────────────────────────────────────
   Para nombres largos en anchos fijos (el nombre del equipo en su sidebar, p. ej.). No existe
   como utilidad de Tailwind: `break-words` es `break-word` y no parte una palabra larguísima
   sin espacios (referencias, códigos), mientras que `break-all` rompe siempre. `anywhere` es
   el punto medio: parte solo cuando de verdad no cabe. */
.break-anywhere {
  overflow-wrap: anywhere;
}

/* ── Avatar de iniciales de los listados ───────────────────────────────────────────────────
   Mismos tonos que el placeholder de avatar de Mosaic (add-user.html): fondo gris suave y
   contenido en gris medio, en vez del violeta sólido. Va como clase porque `dark:bg-gray-700`
   sólido no está en el CSS purgado de Tailwind (solo las variantes translúcidas). */
.avatar-initials {
  background-color: var(--color-gray-100);
  color: var(--color-gray-600); /* el 400 daba 2,3:1 sobre el gris-100 */
}
.dark .avatar-initials {
  background-color: var(--color-gray-700);
  color: var(--color-gray-300); /* el 500 daba 2,1:1 sobre el gris-700 */
}

/* Selector de ciclo de facturación (mensual / anual) de los add-ons del portal.

   El resaltado sale del propio radio (`.peer:checked ~ span`) y no del servidor: calculado en
   Jinja se quedaba congelado hasta recargar la página, y el build CSP de Alpine no evalúa
   expresiones dentro de un atributo para arreglarlo por JavaScript.

   Va aquí y no como utilidades de Tailwind porque `mosaic.css` se genera purgado: las clases que
   no estaban ya en una plantilla al construirlo no existen en el fichero, y `peer-checked:bg-
   violet-500` es una de ellas. */
.period-toggle > label > input.peer:checked ~ span {
  background-color: var(--color-violet-500);
  color: #fff;
}
.period-toggle > label > input.peer:focus-visible ~ span {
  outline: 2px solid var(--color-violet-400);
  outline-offset: -2px;
}


/* Tarjeta recomendada («el más contratado»): la cinta va sobre el marco de color y la tarjeta
   blanca cuelga debajo.

   El hueco superior se fija aquí y no con una utilidad de Tailwind porque `mosaic.css` se genera
   purgado y no llegó a entrar ninguna `pt-` mayor que `pt-5` (1,25rem), que deja el texto de la
   cinta pegado al borde de la tarjeta. */
.ribbon-card {
  padding: 0.25rem;
  /* 0,5rem por encima del texto, 0,75rem de línea y 0,5rem hasta la tarjeta: el mismo aire
     arriba y abajo. La banda no puede medir menos que su propio texto. */
  padding-top: 1.75rem;
}
.ribbon-card > .ribbon-label {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  padding: 0.5rem;
  line-height: 1;
}

/* Tarjeta con el canto de arriba recto y el de abajo redondeado.

   Existe aquí y no como utilidad de Tailwind porque `mosaic.css` se genera purgado: de todas las
   variantes de radio solo entraron `rounded-xl` y `rounded-none`, así que `rounded-t-none` o
   `rounded-b-xl` se escribirían en la plantilla sin que aplicaran, y el fallo sería mudo. El
   valor es el mismo `--radius-xl` que usa `rounded-xl`, para que las dos esquinas de abajo
   midan exactamente lo que miden en el resto de tarjetas. */
.card-flat-top {
  border-top-left-radius: 0;
  border-top-right-radius: 0;
  border-bottom-left-radius: var(--radius-xl);
  border-bottom-right-radius: var(--radius-xl);
}

/* ── Contraste en modo oscuro (Ismael, 21-10-2026) ──────────────────────────────────────────
   Medido con WCAG AA (4,5:1 texto normal) sobre el gris-800 de las tarjetas: el azul de marca
   (violet-500/600, #0d39ff) daba 1,7–2,1 y el `dark:text-violet-400` de los nombres enlazados,
   3,2–3,4; los grises 500, el rojo de los errores y el azul cielo de los avisos tampoco
   llegaban. Están en cientos de plantillas, muchos sin variante oscura, así que se corrige aquí
   y no plantilla a plantilla: en oscuro, cada uno pasa al tono claro de SU rampa. El modo claro
   no cambia. (Al ser una hoja sin capa, gana a las utilidades de Tailwind.) */
.dark .text-violet-500,
.dark .text-violet-600,
.dark .text-violet-700,
.dark .dark\:text-violet-400 {
  color: var(--color-violet-300); /* #8fa4ff ≈ 7:1 */
}
.dark .hover\:text-violet-500:hover,
.dark .hover\:text-violet-600:hover,
.dark .hover\:text-violet-700:hover,
.dark .dark\:hover\:text-violet-300:hover {
  color: var(--color-violet-200);
}
.dark .text-gray-500,
.dark .dark\:text-gray-500 {
  color: var(--color-gray-400); /* 3,0 → 5,9 */
}
.dark .text-red-500,
.dark .dark\:text-red-400 {
  color: var(--color-red-300);
}
.dark .dark\:text-sky-400 {
  color: var(--color-sky-300);
}

/* ── Contraste en modo claro (21-10-2026) ──
   El gris-400 de los textos pequeños (cabeceras de tabla en mayúsculas, fechas, rótulos) daba
   2,3–2,5:1 sobre blanco. El 500 llega (4,8 sobre blanco, 4,6 sobre el gris-50 de las cabeceras).
   Solo en claro: en oscuro el gris-400 ya es el tono legible. */
:root:not(.dark) .text-gray-400 {
  color: var(--color-gray-500);
}
:root:not(.dark) .text-yellow-600 {
  color: var(--color-yellow-700); /* 3,8 → 5,6 */
}
:root:not(.dark) .text-green-600 {
  color: var(--color-green-700); /* 4,4 → 6,3 */
}
:root:not(.dark) .text-red-500 {
  color: var(--color-red-600);
}
/* El fondo suave de lo activo (menú principal, barras de sección, recuadros de marca): el azul
   de marca al 10 % casi no se distinguía del gris-800 en oscuro. Al 35 % (Ismael), el bloque se
   ve y el texto en violet-300 de encima sigue por encima de 4,5:1. */
.dark .bg-violet-500\/10 {
  background-color: color-mix(in oklab, var(--color-violet-500) 35%, transparent);
}

/* ── PRUEBA (21-10-2026): pills de listas solo con icono ──
   En el cuerpo de una tabla el distintivo se queda en su icono; el texto no se borra (lo siguen
   leyendo los lectores de pantalla), solo se encoge a cero, y `panel.js` lo enseña en el globo al
   pasar el ratón. Fuera de las tablas (fichas, cabeceras) no cambia. */
.panel-pill {
  /* La marca necesita existir como clase para la prueba de clases del CSS purgado. */
}
/* Por la marca del kit o por la forma de las copias a mano (`_badge` en muchas plantillas), y solo
   si llevan icono: un contador sin icono se quedaría en un punto vacío. */
tbody :is(.panel-pill, .rounded-full.text-xs.px-2\.5, .rounded-full.text-xs.px-2):not(.pill-con-fecha):has(svg),
tbody :is(.panel-pill, .rounded-full.text-xs.px-2\.5, .rounded-full.text-xs.px-2):not(.pill-con-fecha):has(svg) * {
  gap: 0;
}
/* Los que pueden llevar una FECHA (revisión, bloqueo) se quedan con su texto: `pill-con-fecha`. */
.pill-con-fecha {
}
tbody :is(.panel-pill, .rounded-full.text-xs.px-2\.5, .rounded-full.text-xs.px-2):not(.pill-con-fecha):has(svg) {
  font-size: 0;
  line-height: 0;
  gap: 0;
  padding: 0.3rem;
  cursor: default;
}

/* ── PRUEBA (21-10-2026): pills de fecha en texto (columna Revisión, Último acceso) ──
   Sin pill: el texto con su color y, en lugar del icono, un cuadrado de 8×8 px del mismo
   color (`currentColor`). La clase va en la celda (`texto-con-cuadro`); solo toca los pills
   (`rounded-full`), no el «—» de cuando no hay fecha. */
.texto-con-cuadro > span.rounded-full {
  background-color: transparent;
  padding: 0;
  border-radius: 0;
  gap: 0.375rem;
}
.texto-con-cuadro > span.rounded-full * {
  gap: 0;
}
.texto-con-cuadro > span.rounded-full::before {
  content: "";
  flex: none;
  width: 8px;
  height: 8px;
  background-color: currentColor;
}
.texto-con-cuadro svg {
  display: none;
}
/* El «yellow» del tema es naranja (#fb6a1c / #b44210): sin el fondo del pill, «Próxima» se leía
   rojo junto a «Caducada». En esta columna, ámbar de verdad: cuadrado #f59e0b y texto #a16207
   (4,9:1 sobre blanco); en oscuro, #fbbf24 para los dos. */
:root:not(.dark) .texto-con-cuadro > span.rounded-full.text-yellow-700 {
  color: #a16207;
}
:root:not(.dark) .texto-con-cuadro > span.rounded-full.text-yellow-700::before {
  background-color: #f59e0b;
}
.dark .texto-con-cuadro > span.rounded-full.text-yellow-700 {
  color: #fbbf24;
}

/* PRUEBA (21-10-2026): columna de solo iconos, centrada con su cabecera. La clase la pone
   `panel.js` mirando lo que se ve en las celdas. */
.columna-icono {
  text-align: center !important;
}
.columna-icono > .flex,
.columna-icono > div,
.columna-icono > button {
  justify-content: center;
  margin-inline: auto;
}
/* Un icono suelto va en un <span> sin flex y el <svg> es de bloque (preflight): sin esto se
   queda a la izquierda aunque la celda esté centrada. */
.columna-icono > span {
  display: inline-flex;
  vertical-align: middle;
}

/* PRUEBA (21-10-2026): filas cebra con borde, en todos los listados. La fila gris lleva una raya
   discontinua arriba y otra abajo y la blanca ninguna, en lugar del `divide-y` entre todas (esta
   regla le gana: la de Tailwind va en `:where`). La última fila gris no lleva la de abajo: ahí ya
   está el borde del pie. «Última» es la última VISIBLE: las filas de vacío y error siguen en el
   DOM con `display: none` (x-show). */
.zebra-rows > tr {
  border-top-width: 0;
  border-bottom-width: 0;
}
.zebra-rows > tr:nth-of-type(even) {
  border-top: 2px dashed var(--color-gray-200);
  border-bottom: 2px dashed var(--color-gray-200);
}
.zebra-rows > tr:nth-of-type(even):not(:has(~ tr:not([style*="display: none"]))) {
  border-bottom-width: 0;
}
.dark .zebra-rows > tr:nth-of-type(even) {
  border-color: rgb(55 65 81 / 0.6);
}

/* La cebra en una LISTA de <div> (los ficheros de Logs, 23-10-2026): la misma raya discontinua que
   las filas de tabla, arriba y abajo de la gris, y sin la de abajo en la última. La fila activa
   lleva su violeta por encima de la banda: estas reglas no van en capa y le ganan a la utilidad. */
.zebra-lista > div:nth-of-type(even) {
  border-top: 2px dashed var(--color-gray-200);
  border-bottom: 2px dashed var(--color-gray-200);
}
.zebra-lista > div:nth-of-type(even):last-of-type {
  border-bottom-width: 0;
}
.dark .zebra-lista > div:nth-of-type(even) {
  border-color: rgb(55 65 81 / 0.6);
}
.zebra-lista > div.is-activa,
.zebra-lista > div.is-activa:hover {
  background-color: color-mix(in oklab, var(--color-violet-500) 10%, transparent);
}
.dark .zebra-lista > div.is-activa,
.dark .zebra-lista > div.is-activa:hover {
  background-color: color-mix(in oklab, var(--color-violet-500) 35%, transparent);
}

/* Cabecera de grupo activa en Logs, en oscuro: con el mismo violeta al 35 % que el fichero abierto
   no se distinguían (Ismael, 23-10-2026). La cabecera va más tenue y con el borde marcado. */
.dark .cabecera-grupo.bg-violet-500\/10 {
  background-color: color-mix(in oklab, var(--color-violet-500) 18%, transparent);
  border-color: var(--color-violet-400);
}

/* Consola SQL del gestor de base de datos (22-10-2026): el editor CodeMirror con la letra y los
   colores del panel, también en oscuro. */
.db-console-editor .CodeMirror {
  height: 18rem;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.875rem;
  background: transparent;
  color: var(--color-gray-800);
}
.db-console-editor .CodeMirror-gutters {
  background: var(--color-gray-50);
  border-right: 1px solid var(--color-gray-200);
}
.dark .db-console-editor .CodeMirror {
  color: var(--color-gray-100);
}
.dark .db-console-editor .CodeMirror-gutters {
  background: color-mix(in oklab, var(--color-gray-700) 30%, transparent);
  border-right-color: color-mix(in oklab, var(--color-gray-700) 60%, transparent);
}
.dark .db-console-editor .CodeMirror-cursor {
  border-left-color: var(--color-gray-100);
}
.dark .db-console-editor .CodeMirror-selected,
.dark .db-console-editor .CodeMirror-focused .CodeMirror-selected {
  background: color-mix(in oklab, var(--color-violet-500) 30%, transparent);
}
.dark .db-console-editor .cm-keyword { color: var(--color-violet-300); }
.dark .db-console-editor .cm-string { color: var(--color-green-400); }
.dark .db-console-editor .cm-number { color: var(--color-sky-300); }
.dark .db-console-editor .cm-comment { color: var(--color-gray-400); }
.dark .db-console-editor .cm-builtin,
.dark .db-console-editor .cm-type { color: var(--color-yellow-300); }
.dark .CodeMirror-hints {
  background: var(--color-gray-800);
  border-color: var(--color-gray-700);
}
.dark .CodeMirror-hint { color: var(--color-gray-100); }
