/* Usa tokens de DaisyUI para que cambie con el tema.
   OJO con la función de color: DaisyUI 4 publica los tokens como componentes
   oklch (--p: 51.97% 0.0936 223.13), así que hay que escribir oklch(var(--p)).
   Con hsl(...) el valor es inválido y el navegador descarta la declaración
   entera, sin avisar: así estuvieron muertas la píldora del ítem activo del
   sidebar y el anillo de foco. */
.typography h1 {
  font-size: 2.25rem;      /* ~ text-4xl */
  line-height: 2.5rem;
  font-weight: 700;        /* bold */
  color: oklch(var(--bc));   /* base-content */
  margin-bottom: 1rem;     /* mb-4 */
}

.typography h2 {
  font-size: 1.5rem;       /* ~ text-2xl */
  line-height: 2rem;
  font-weight: 600;        /* semibold */
  color: oklch(var(--bc));
  margin-bottom: .75rem;   /* mb-3 */
}

.typography h3 {
  font-size: 1.25rem;      /* ~ text-xl */
  line-height: 1.75rem;
  font-weight: 500;        /* medium */
  color: oklch(var(--bc));
  margin-bottom: .5rem;    /* mb-2 */
}

/* Encabezado de página (parcial includes/page_header.php): título y subtítulo
   juntos. Mantiene el tamaño de h1 de .typography y solo ajusta el margen. */
.page-header h1 {
  margin-bottom: 0.25rem;
}

/* En móvil el h1 del encabezado se achica para no comerse la primera pantalla. */
@media (max-width: 640px) {
  .page-header h1 {
    font-size: 1.5rem;   /* ~ text-2xl */
    line-height: 2rem;
  }
}

/* Acciones de fila (tablas JS): en móvil son un menú "⋯" (toggle con .hidden en
   ui.js) para que la fila no crezca; en ≥sm los mismos controles se muestran en
   línea a la derecha. Una sola instancia de cada control (sin duplicar). */
/* Móvil: el menú está oculto y se abre con la clase .row-actions-open (ui.js). */
@media (max-width: 639px) {
  .row-actions-list { display: none; }
  .row-actions-list.row-actions-open { display: flex; flex-direction: column; }
}

/* Acciones de fila renderizadas en el servidor: siempre en línea (no hay menú
   "⋯" porque no hay JS que lo abra), alineadas a la derecha como en las de JS. */
.acciones-fila {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 0.5rem;
}

/* Escritorio: los botones con ícono (Editar/Eliminar) muestran solo el ícono y su
   tooltip; la etiqueta queda oculta pero legible por lectores de pantalla. En el
   menú "⋯" de móvil la etiqueta sí se ve (un menú de solo íconos es ilegible), y
   en las tablas del servidor la etiqueta también se ve en móvil. */
@media (min-width: 640px) {
  .row-actions .btn-label,
  .acciones-fila .btn-label {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border-width: 0;
  }
}

/* nowrap a propósito: con `wrap`, la columna angosta partía los controles en
   tres renglones y dejaba filas de ~90px con el borde derecho irregular. Ahora
   la columna se ensancha lo que necesite y la fila mide una línea. */
@media (min-width: 640px) {
  .row-actions .row-actions-trigger { display: none; }
  .row-actions .row-actions-list {
    position: static;
    display: flex;
    flex-direction: row;
    flex-wrap: nowrap;
    align-items: center;
    justify-content: flex-end;
    gap: 0.5rem;
    margin: 0;
    padding: 0;
    width: auto;
    /* max-content, no 0: con `min-width: 0` el navegador puede encoger el grupo
       por debajo de su contenido, y como ya no envuelve, los controles se salían
       por la izquierda y pisaban la columna vecina. Así la tabla está obligada a
       reservarle el ancho que necesita. */
    min-width: max-content;
    border-width: 0;
    background: transparent;
    box-shadow: none;
  }
}

/* Si quieres banda de fondo en headers (opcional) */
.typography .heading-band {
  background-color: oklch(var(--b2)); /* base-200 */
  color: oklch(var(--bc));
  padding: .25rem .5rem;
  border-radius: .375rem;
}

/* =========================================================================
   Estados de proyecto y campaña (.estado-*), acompañan a la clase `badge`.
   Las asigna estados_catalogo() en includes/helpers.php, que es la fuente
   única (el JS las recibe vía window.ESTADOS).

   Por qué existen en vez de usar badge-success/badge-neutral: `success` se
   estaba usando a la vez para el ESTADO "Abierto" y para el FEEDBACK "se
   guardó". Al separarlos, el verde vuelve a significar una sola cosa y el
   estado puede tomar el color de la marca.

   Aquí abajo va el aspecto de siempre, para que los temas existentes no
   cambien. La variante sobria se define más abajo, acotada a su tema.
   ========================================================================= */
.estado-abierto {
  background-color: oklch(var(--su));
  color: oklch(var(--suc));
  border-color: transparent;
}

.estado-cerrado {
  background-color: oklch(var(--n));
  color: oklch(var(--nc));
  border-color: transparent;
}

.estado-borrador {
  background-color: transparent;
  color: oklch(var(--bc) / 0.8);
  border-color: oklch(var(--b3));
}

/* Tema "sobrio": el estado se dice con tres tonos del mismo azul en vez de con
   colores distintos. Al escribirse con oklch(var(--p) / α) el chip se tiñe solo
   con el primario del tema, así que sigue funcionando si la marca cambia.

   El color-mix del texto no es un adorno: el primario puro sobre su propio
   tinte al 10 % queda en ~4.3:1, apenas bajo el mínimo AA para 14 px.
   Oscurecerlo un 22 % lo lleva a ~6:1. */
[data-theme="sobrio"] .estado-abierto {
  background-color: oklch(var(--p) / 0.10);
  color: color-mix(in oklab, oklch(var(--p)), black 22%);
  border-color: oklch(var(--p) / 0.30);
}

/* Los alfas del texto están puestos por contraste medido, no a ojo: a 0.65 y
   0.55 —que es lo que "se ve" atenuado— estos dos chips daban 4.46:1 y 3.49:1,
   por debajo del mínimo AA. Atenuado no puede querer decir ilegible. */
[data-theme="sobrio"] .estado-cerrado {
  background-color: oklch(var(--bc) / 0.06);
  color: oklch(var(--bc) / 0.75);
  border-color: oklch(var(--bc) / 0.22);
}

[data-theme="sobrio"] .estado-borrador {
  background-color: transparent;
  color: oklch(var(--bc) / 0.70);
  border-color: oklch(var(--bc) / 0.30);
  border-style: dashed;
}

/* Select que hace de celda de ESTADO: lleva las mismas clases .estado-* que el
   chip, así que el control ES el indicador y el dato no está dos veces en la
   fila. Sin `select-bordered`, porque el borde lo pone .estado-*. */
.select-estado {
  border-width: 1px;
  border-style: solid;
  font-weight: 600;
  min-height: 2rem;
  height: 2rem;
  padding-top: 0;
  padding-bottom: 0;
}

/* Ficha de terreno: las secciones numeradas comparten una tarjeta, así que se
   separan entre sí con una regla en vez de con más cajas. La primera no la
   lleva, para que no quede una línea suelta bajo el borde de la tarjeta. */
.ficha-secciones > h2 {
  margin-top: 1.75rem;
  padding-top: 1.25rem;
  border-top: 1px solid oklch(var(--b3));
}

.ficha-secciones > h2:first-child {
  margin-top: 0;
  padding-top: 0;
  border-top: 0;
}

/* Motivo por el que un terreno espera reasignación. No usa `badge` porque un
   badge es de una línea y no envuelve: frases como "El inspector (nombre) está
   desactivado" se salían del contorno. Mismo ámbar de atención, en versión
   suave para que una columna entera de motivos no grite. */
.chip-motivo {
  display: inline-block;
  max-width: 100%;
  white-space: normal;
  line-height: 1.25;
  padding: 0.25rem 0.5rem;
  border: 1px solid oklch(var(--wa) / 0.35);
  border-radius: var(--rounded-badge, 1.9rem);
  background-color: oklch(var(--wa) / 0.12);
  color: color-mix(in oklab, oklch(var(--wa)), black 25%);
  font-size: 0.75rem;
  font-weight: 600;
}

/* Papelera de las filas: neutra en reposo, roja al apuntarla. El rojo tiene que
   aparecer cuando hay algo que perder, no como decoración permanente de cada
   fila: con una papelera roja por registro, un listado de veinte filas trae
   veinte señales de peligro que no señalan nada. La confirmación destructiva
   (confirm.js) sigue en rojo, que es donde el color sí informa. */
.btn-eliminar {
  color: oklch(var(--bc) / 0.55);
}

.btn-eliminar:hover,
.btn-eliminar:focus-visible {
  color: oklch(var(--er));
}

/* Nota explicativa permanente: no es una alerta. Se usaba `alert-info`, que
   pinta un bloque saturado del color de información para un texto que está
   siempre ahí y que nadie tiene que atender. Destaca sin gritar. */
.nota {
  background-color: oklch(var(--b2));
  border: 1px solid oklch(var(--b3));
  border-radius: var(--rounded-box, 1rem);
  padding: 1rem;
}

/* Matriz de permisos: primera columna fija al desplazar en horizontal. La tabla
   ya no cabe en escritorio con seis roles y crece con cada rol nuevo; sin esto
   se pierde de vista qué permiso se está marcando.
   Las celdas fijas necesitan fondo opaco (si no, el contenido pasa por debajo),
   y se excluyen las filas de grupo, que llevan colspan y ocupan todo el ancho. */
.matriz-permisos thead th:first-child,
.matriz-permisos tbody td:first-child {
  position: sticky;
  left: 0;
  z-index: 1;
  border-right: 1px solid oklch(var(--b3));
}

.matriz-permisos tbody td:first-child {
  background-color: oklch(var(--b1));
}

.matriz-permisos thead th:first-child {
  z-index: 2;
  background-color: oklch(var(--b3));
}

/* La fila de grupo ocupa todo el ancho, así que fijar la celda no sirve: se fija
   su texto, que si no se escapaba por la izquierda al desplazar. */
.matriz-permisos tbody th[colspan] {
  position: static;
}

.matriz-permisos tbody th[colspan] > span {
  position: sticky;
  left: 0;
  display: inline-block;
}

/* Ítem activo del menú lateral: "pill" suave con el primario del tema (theme-aware).
   Se usa !important para ganarle al estado activo por defecto de DaisyUI. */
.sidebar-menu li > a.active,
.sidebar-menu li > a.active:hover {
  background-color: oklch(var(--p) / 0.12) !important;
  color: oklch(var(--p)) !important;
  font-weight: 600;
}

/* Títulos de sección del sidebar: gris tenue, como en la referencia. */
.sidebar-menu .menu-title {
  color: oklch(var(--bc) / 0.5);
}

/* Fondo oscuro de los <dialog> (modal de crear/editar y de confirmación). */
dialog::backdrop {
  background: rgba(0, 0, 0, 0.45);
}

/* Modal ancho: lo pide el fragmento con [data-modal-ancho] (js/modal.js).
   El id gana especificidad sobre la utilidad max-w-lg del <dialog>. */
#modal-app.modal-ancho {
  max-width: 48rem;
}

/* Foco visible por teclado, con el primario del tema. */
:focus-visible {
  outline: 2px solid oklch(var(--p));
  outline-offset: 2px;
}
