/* ============================================================================
   P4S — COMPONENTES DE LA APP PRIVADA SOBRE EL TEMA CORK

   Hace que el template Cork consuma los tokens de marca. Sin esto, Cork pinta
   sus componentes con su propia paleta y las vistas migradas NO se parecen a
   las de auth, que es justamente el objetivo de la migracion.

   Lo carga `private/privateLayout.jsp` DESPUES de
   `templatev3/css/light/main.css`, porque ahi es donde hay que ganar.

   Regla: aqui no se escribe ni un hex. Todo sale de css/p4s-tokens.css.
   Ver la seccion de migracion de vistas en CLAUDE.md.
   ========================================================================= */

/* ----- Botones: ya NO viven aqui ----------------------------------------
   Se movieron a css/p4s-boton.css, definicion UNICA del boton para toda la
   plataforma, que cargan tanto layoutBase.jsp como privateLayout.jsp.

   Estaban escritos tres veces (aqui, en css/auth/login.css y en el <style> de
   inicioV2.jsp) y ya habian divergido. Ref ENA-1.17 (#163). */

/* ----- Enlaces dentro del contenido --------------------------------------
   Acotado al area de contenido a proposito: tenir enlaces a nivel de <body>
   alcanza tambien al menu lateral, cuyos items tienen su propio color, y los
   deja ilegibles. Ocurrio al intentarlo sobre el layout legado.

   ⚠️ SE EXCLUYE TODO LO QUE SEA UN BOTON, y por prefijo, no por lista.

   Un <a> con pinta de boton ya trae SU PROPIO relleno, casi siempre del
   acento. Si esta regla tambien le pinta el TEXTO del acento, queda acento
   sobre acento: el texto desaparece. Paso de verdad -- BUG-1.15 (#161) --
   con `.btn-action` del dashboard, en los dos temas a la vez.

   Y no se pierde por poco: esta regla suma 0-4-1 de especificidad (una clase
   mas tres :not(), que cuenta cada uno como clase), asi que le gana a
   cualquier `.mi-boton { color: ... }` normal, que es 0-1-0. El autor del
   boton escribe el color correcto y no se aplica, sin ningun aviso.

   Antes se listaban las clases una a una (`:not(.btn):not(.nav-link)...`).
   Eso obliga a acordarse de venir aqui cada vez que nace una clase de boton
   -- y nadie se acuerda: asi entro `.btn-action`. Con el selector de atributo
   la familia entera queda fuera de una vez: .btn, .btn-primary, .btn-action,
   y las que vengan.

   `.page-link` entra a la lista por el mismo motivo, mismo bug (ENA-1.26):
   cada numero de la paginacion ES un <a>, con su propio fondo y color ya
   resueltos en la seccion "DataTables (paginacion de /colectivo)" mas
   abajo. Esta regla, con CUATRO :not(), suma mas especificidad de la que
   aparenta (0-5-1) y le ganaba en silencio al `color` de esa seccion
   (0-3-0): la pagina activa quedaba con el mismo color de texto que de
   fondo -- literalmente invisible, contraste 1:1, confirmado en el
   inspector.

   `[class*="p4s-boton"]` entra por el mismo motivo, TERCERA vez que pasa
   (HU-1.40, 2026-09-14): el prefijo "por si vienen mas" solo cubria la
   familia .btn/.btn-*, no la OTRA convencion de boton que ya vive en el
   codigo (`p4s-boton`/`p4s-boton--principal`/`p4s-boton--pequeno`,
   css/p4s-componentes.css) -- "Vincularme" en la tarjeta de Propuestas
   quedaba con el texto del mismo tono que su propio relleno, literalmente
   invisible, exactamente el patron de BUG-1.15. Dos convenciones de boton
   conviviendo es deuda real (candidato a ENA-1.17 ampliado, unificar en
   una sola), pero mientras exista la segunda, esta regla tiene que saber
   excluirla tambien. */
.main-content a:not([class~="btn"]):not([class*="btn-"]):not([class*="p4s-boton"]):not(.nav-link):not(.dropdown-item):not(.page-link) {
    color: var(--p4s-accent);
}

.main-content a:not([class~="btn"]):not([class*="btn-"]):not([class*="p4s-boton"]):not(.nav-link):not(.dropdown-item):not(.page-link):hover {
    color: var(--p4s-accent-light);
}

/* ----- Superficies: la escala de elevacion -------------------------------
   Cork trae sus tarjetas (.card, .statbox, .widget-content-area) con SU
   paleta, no con la nuestra. Mientras las vistas migradas fueron el dashboard
   —tarjetas sueltas sobre el fondo— no se noto. En cuanto una vista anida una
   tarjeta dentro de otra (una lista de resultados dentro de su panel), las
   tres superficies quedan del MISMO color y la composicion se aplana: no se
   distingue el panel de su contenido.

   Los tokens ya traian la escala; nadie la estaba consumiendo:

       --p4s-bg  <  --p4s-surface  <  --p4s-surface-alt  <  --p4s-field

   En oscuro eso es ink-900 < ink-800 < ink-700 < ink-500: cada nivel se
   despega del anterior. En claro, paper < blanco < paper-alt.

   Se cablea aqui, UNA vez, y lo hereda toda vista migrada. Nunca por modulo.
   Ref #39 */
.main-content .card,
.main-content .statbox,
.main-content .widget-content-area,
.main-content .esquinasRedondas,
.main-content .esquinasRedondas3,
.main-content .esquinasRedondas4 {
    background-color: var(--p4s-surface);
    border-color: var(--p4s-border);
    color: var(--p4s-text);
}

/* Bootstrap 5 NO acota las imagenes: solo `.img-fluid` lleva
   `max-width:100%`, y Foundation si lo hacia de serie para cualquier <img>.
   Al migrar el marco, toda imagen legada sin `width` pasa a pintarse a su
   tamano NATURAL y se sale de su columna.

   No es teorico: /admonParticipante trae dos iconos decorativos servidos
   desde `cdn-icons-png.flaticon.com/512/...` -- PNG de **512 px** sin
   `width` ni clase -- dentro de una columna `col-3`. En la revision visual
   salio un calendario gigante a color partiendo el formulario por la mitad.
   Hay `flaticon.com` en 25 vistas, asi que se acota aqui una vez.

   `height:auto` para que al limitar el ancho no se deforme. */
.main-content img {
    max-width: 100%;
    height: auto;
}

/* Los iconos decorativos que acompanan a un campo o a un titulo de seccion
   no deben competir con el dato: se les da un techo de icono, no de imagen.
   Van por atributo, no por clase, porque el marcado legado no les pone
   ninguna y anadirsela a mano en 25 vistas es el trabajo que esta regla
   evita. */
.main-content img[src*="cdn-icons-png.flaticon.com"] {
    max-width: 48px;
}

/* `.esquinasRedondas*` es LA caja de las vistas legadas -- la usan **113
   vistas**. Su definicion vive en `css/p4s.css`, que privateLayout NO carga
   a proposito: es la piel vieja, con `background:white` fijo y degradados de
   2012 que en tema oscuro serian un parche blanco.

   Pero al no cargarla, esos contenedores se quedan SIN borde, SIN fondo y
   SIN padding: el contenido flota suelto sobre el fondo de pagina en vez de
   ir en una tarjeta. Es lo que se vio en la revision visual de
   /admonParticipante -- "el formulario esta ahi tirado, sin caja".

   Se resuelve dando a esas tres clases la misma superficie tokenizada que
   `.card`/`.statbox`, en vez de editar el marcado de 113 vistas o de cargar
   la hoja vieja entera. Cada vista que se migre de verdad a componentes de
   Cork ira soltando esta clase; mientras tanto se ve como el resto.
   Ref HU-1.7 (#39) */
.main-content .esquinasRedondas,
.main-content .esquinasRedondas3,
.main-content .esquinasRedondas4 {
    border: 1px solid var(--p4s-border);
    border-radius: 8px;
    padding: 20px;
    margin-bottom: 1.5rem;
    box-shadow: var(--p4s-shadow-card);
}

/* Anidada dentro de otra no repite sombra ni margen: ya esta sobre una
   superficie con elevacion (mismo criterio que `.card .card`). */
.main-content .esquinasRedondas .esquinasRedondas,
.main-content .esquinasRedondas .esquinasRedondas3,
.main-content .esquinasRedondas3 .esquinasRedondas3,
.main-content .widget-content-area .esquinasRedondas,
.main-content .widget-content-area .esquinasRedondas3 {
    box-shadow: none;
    background-color: var(--p4s-surface-alt);
}

/* Cork trae su propia sombra SIN desplazamiento (`0 0 40px rgba(...,.06)` en
   dt-global_style.css y templatev3/structure.scss): es un halo, no una
   sombra de elevacion, y a esa opacidad casi no se ve -- la tarjeta queda
   pegada a la pagina en vez de flotar sobre ella. Con offset+blur reales se
   nota la profundidad en los dos temas.

   Va SOLO en el contenedor mas externo. `.widget-content-area` a veces ES
   la tarjeta completa (patron usado en varias vistas ya migradas) y a veces
   es solo la mitad inferior de una tarjeta `.statbox.widget` con su propio
   `.widget-header` arriba (crearStartupNew.jsp, y ahora colectivoNew.jsp,
   ENA-1.26) -- en ese segundo caso el padre YA pone la sombra sobre la
   tarjeta entera; ponerla tambien en la mitad de abajo duplica el efecto y
   deja una costura visible donde el header se une con el contenido. */
.main-content .card,
.main-content .statbox {
    box-shadow: var(--p4s-shadow-card);
}

.main-content .widget-content-area:not(.widget .widget-content-area) {
    box-shadow: var(--p4s-shadow-card);
}

/* Una tarjeta anidada (`.widget-content-area .card`, ver mas abajo) no
   necesita su propia sombra: ya esta DENTRO de una superficie con sombra,
   duplicarla la hace ver como si flotara sobre su propio contenedor. */
.main-content .widget-content-area .card,
.main-content .card .card {
    box-shadow: none;
}

/* Una tarjeta DENTRO de otra sube un peldano, o las dos se funden. */
.main-content .card .card,
.main-content .widget-content-area .card {
    background-color: var(--p4s-surface-alt);
}

/* ----- Texto secundario --------------------------------------------------
   Bootstrap resuelve .text-muted contra --bs-secondary-color, que solo cambia
   con [data-bs-theme=dark]. Nuestro conmutador es `body.dark` (HU-1.5), asi
   que en oscuro se quedaba con el gris del tema CLARO: casi invisible sobre
   la tarjeta. Es lo que hacia desaparecer el eslogan y el «Mi Rol». */
.main-content .text-muted {
    color: var(--p4s-muted) !important;
}

/* ----- Campos de formulario ---------------------------------------------- */
/* Misma piel que en auth. El borde llega a 3:1 contra la tarjeta, que es el
   minimo para el limite de un componente de interfaz; el de Cork se queda por
   debajo y los campos casi no se ven sobre la tarjeta blanca.

   ⚠️ El FONDO tambien va aqui, y faltaba. Bootstrap 5 pinta
   `.form-control { background-color: var(--bs-body-bg) }`, y `--bs-body-bg`
   solo conmuta con [data-bs-theme=dark] — un selector que esta plataforma no
   usa. En tema oscuro el campo se quedaba con el fondo del tema CLARO
   mientras el texto ya era el oscuro: el peor par posible. */
/* `.ui-dialog-content` va en la misma lista: es el otro sitio que trae
   `.form-control` fuera de `.main-content` (el formulario de comentarios
   del dialogo "Ver mas"; ver la seccion del dialogo mas abajo). */
.main-content .form-control,
.main-content .form-select,
.ui-dialog-content .form-control,
.ui-dialog-content .form-select {
    background-color: var(--p4s-field);
    border-color: var(--p4s-field-border);
    color: var(--p4s-text);
    /* Mismo radio que `.btn` (p4s-boton.css) y que los chips de paginacion:
       un solo lenguaje de esquinas para toda la plataforma. `!important`
       porque `dt-global_style.css` (ENA-1.26) trae su propio
       `.dataTables_wrapper .form-control{border-radius:6px}` con la MISMA
       especificidad que esta regla (dos clases) y se sirve despues en el
       documento (su <link> va en el body, no en el head) -- en un empate de
       especificidad gana el que carga despues, y sin esto los campos
       "Buscar:"/"Mostrar N registros" se quedaban con el radio del tema de
       terceros en vez del de la plataforma. */
    border-radius: 8px !important;
}

.main-content .form-control::placeholder,
.ui-dialog-content .form-control::placeholder {
    color: var(--p4s-muted);
    opacity: 1;   /* Firefox lo baja a 0.54 por su cuenta */
}

/* `.input-group` (campo + etiqueta/boton pegados, ej. "Codigo" + input +
   "Validar") queda con un hueco visible entre cada pieza: el `border-radius:
   8px !important` de arriba se aplica a TODOS los `.form-control` por igual,
   sin excluir los que estan dentro de un `.input-group` — y con !important
   le gana a las reglas propias de Bootstrap que aplanan el lado que no va en
   la punta (`.input-group > :not(:first-child)` / `:not(:last-child)`).
   Fallo real, HU-1.7 (#39), primera vista migrada que usa `.input-group`
   (`verificarCodigoUnico`, !70). Se reafirman aqui las mismas reglas que ya
   trae bootstrap.min.css, con !important para ganarle a la de arriba. */
.main-content .input-group > .form-control:not(:last-child),
.main-content .input-group > .form-select:not(:last-child),
.main-content .input-group > .input-group-text:not(:last-child) {
    border-top-right-radius: 0 !important;
    border-bottom-right-radius: 0 !important;
}
.main-content .input-group > .form-control:not(:first-child),
.main-content .input-group > .form-select:not(:first-child),
.main-content .input-group > .input-group-text:not(:first-child),
.main-content .input-group > .btn:not(:first-child) {
    border-top-left-radius: 0 !important;
    border-bottom-left-radius: 0 !important;
}

/* Un campo de solo lectura tiene que PARECER de solo lectura: es la mitad del
   formulario de ecosistema (ciudad, pais, lat, lon los rellena geocomplete). */
.main-content .form-control[readonly],
.ui-dialog-content .form-control[readonly] {
    background-color: var(--p4s-surface-alt);
    color: var(--p4s-text-soft);
}

/* ----- Formularios legados con `.input-text` / `.my-input` ---------------
   32 vistas usan esta clase (no es de Bootstrap ni de Foundation -- es una
   convencion propia del proyecto) y NUNCA tuvo CSS: el campo queda con el
   input nativo del navegador, sin borde visible ni relleno, y como el
   <label> es inline por defecto, toda la secuencia label-input-label-input
   se apelmaza en una sola linea corrida en vez de un formulario vertical.
   /admonParticipante (HU-1.7 #39) es el caso mas visible, con ~30 campos
   asi seguidos, pero el arreglo es el mismo para las otras 31 vistas.

   Se soluciona con CSS unicamente, sin tocar el marcado de ninguna vista:
   misma piel que `.form-control` para el campo, y el <label> a bloque.
   Se excluyen casillas/radios/botones porque esos SI deben quedar inline
   junto a su texto (ej. "Eres vegetariano" en admonParticipante). */
.main-content fieldset label,
.ui-dialog-content fieldset label {
    display: block;
    margin-top: 0.75rem;
    margin-bottom: 0.25rem;
    font-weight: 600;
    color: var(--p4s-text);
}
.main-content fieldset label:has(> input[type="checkbox"]),
.main-content fieldset label:has(> input[type="radio"]) {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    font-weight: 400;
}
.main-content .input-text,
.main-content .my-input,
.main-content fieldset select,
.main-content fieldset textarea,
.ui-dialog-content .input-text,
.ui-dialog-content .my-input {
    display: block;
    width: 100%;
    background-color: var(--p4s-field);
    border: 1px solid var(--p4s-field-border);
    color: var(--p4s-text);
    border-radius: 8px;
    padding: 0.5rem 0.75rem;
    margin-bottom: 0.5rem;
}
.main-content .input-text:not([type="checkbox"]):not([type="radio"]):focus,
.main-content .my-input:focus,
.main-content fieldset select:focus,
.main-content fieldset textarea:focus {
    outline: none;
    border-color: var(--p4s-accent-fill);
    box-shadow: 0 0 0 3px var(--p4s-accent-glow);
}
.main-content .input-text[type="checkbox"],
.main-content .input-text[type="radio"] {
    display: inline-block;
    width: auto;
    margin: 0;
}

/* ----- Navegacion de anclas `dl.sub-nav` (Magellan de Foundation) --------
   `data-magellan-expedition`/`data-magellan-arrival` es el scroll-spy de
   Foundation: sin su JS (no viaja al marco nuevo) los enlaces siguen
   saltando a su ancla (comportamiento nativo del navegador, se conserva),
   pero pierden TODO el estilo -- queda una lista de enlaces azules sueltos
   en vez de la barra de pestanas que se ve en 12 vistas (`admonParticipante`,
   `admonCertamenNew`, `admonProyectoNew`, las fichas `p5_*_sola`...).
   Se les da una piel de pildoras, sin depender de JS de Foundation. */
.main-content dl.sub-nav {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
    margin: 0.75rem 0 0;
    padding: 0;
}
.main-content dl.sub-nav dd {
    margin: 0;
}
.main-content dl.sub-nav dd a {
    display: inline-block;
    padding: 0.35rem 0.9rem;
    border-radius: 999px;
    background: var(--p4s-surface-alt);
    color: var(--p4s-text-soft);
    font-size: 0.85rem;
    text-decoration: none;
}
.main-content dl.sub-nav dd a:hover {
    background: var(--p4s-accent-fill);
    color: #fff;
}

/* ----- Acordeon `li.accordion-navigation` (Foundation Accordion) ---------
   Mismo problema que `dl.sub-nav` arriba, componente distinto: sin el JS de
   Foundation (no viaja al marco nuevo) el clic en el encabezado sigue
   saltando a su ancla (nativo del navegador, se conserva) pero nada aplica
   `display:none` a los paneles inactivos ni alterna la clase `.active` --
   queda una lista plana con el icono de flecha (Font Awesome si carga) sin
   poder colapsar/expandir. Se le da piel + un manejador de clic minimo en
   jQuery (ya cargado en los dos marcos), sin depender de JS de Foundation.
   Usado en `p5_certamen_sola_new.jsp` (Convocatoria/Verticales/Condiciones/
   Ganadores/Multimedios) -- ver el manejador de clic en ese mismo archivo.

   El estado inicial (que paneles arrancan abiertos) lo decide Java en el
   servidor (`activeDescripcion`/`activeCondiciones`/`activeMedios`) escribiendo
   la clase `active` en `.content` -- aqui solo se respeta esa clase, nunca se
   decide de cero. */
.main-content li.accordion-navigation {
    border: 1px solid var(--p4s-border);
    border-radius: 8px;
    margin-bottom: 0.6rem;
    overflow: hidden;
}

.main-content li.accordion-navigation > a {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.75rem 1rem;
    background: var(--p4s-surface-alt);
    color: var(--p4s-text);
    font-weight: 600;
    text-decoration: none;
    cursor: pointer;
}

.main-content li.accordion-navigation > a:hover {
    background: var(--p4s-accent-glow);
}

.main-content li.accordion-navigation > .content {
    display: none;
    padding: 1rem;
}

.main-content li.accordion-navigation > .content.active {
    display: block;
}

/* El icono ya trae su propio `content:before` (chevron derecho/abajo) en un
   `<style>` local del JSP -- aqui solo se resuelve CUAL de los dos se ve.
   `.active .accordion-icon:before` (el `<style>` local) nunca puede aplicar:
   `.active` cae en `.content`, un HERMANO del icono, no un ancestro. El
   manejador de clic pone `.is-open` en el propio encabezado -- ahi si hay
   relacion ancestro-descendiente real. */
.main-content li.accordion-navigation > a .accordion-icon:before {
    content: "\f105";
}

.main-content li.accordion-navigation > a.is-open .accordion-icon:before {
    content: "\f107";
}

/* ----- `.row.collapse` (idioma de Foundation, NO de Bootstrap) -----------
   En Foundation `collapse` sobre un `.row` solo quitaba el gutter entre
   columnas. En Bootstrap 5 `.collapse` es el panel colapsable del
   componente Collapse: `.collapse:not(.show){display:none}`. El nombre
   choca -- 17 vistas usan `class="row collapse"` para pares campo+boton
   (username, slogan, fecha de nacimiento en admonParticipante...) y
   Bootstrap los oculta ENTEROS, sin ningun error ni rastro en consola.
   No es que se vean mal: no se ven, punto. Se restaura el display de
   `.row` y se conserva la intencion original (sin gutter). */
.main-content .row.collapse,
.ui-dialog-content .row.collapse {
    display: flex !important;
    margin-right: 0;
    margin-left: 0;
}

.main-content .form-control:focus,
.main-content .form-select:focus,
.ui-dialog-content .form-control:focus,
.ui-dialog-content .form-select:focus {
    border-color: var(--p4s-accent);
    box-shadow: 0 0 0 3px var(--p4s-accent-glow);
}

/* ----- msDropdown (jquery.dd.js) -----------------------------------------
   El plugin SUSTITUYE el <select> por su propio widget y le fija un ancho EN
   PIXELES al inicializar, medido sobre el select original. Dentro de una
   rejilla fluida de Bootstrap ese numero deja de valer en cuanto cambia el
   ancho del contenedor: el desplegable se sale de la tarjeta y la lista
   abierta no coincide con el control cerrado. Es justo lo que se veia en
   /creaEvento.

   `!important` es necesario y no es pereza: el ancho lo escribe el plugin
   como estilo EN LINEA, y una regla de hoja normal no le gana.

   Ademas trae su propia piel (dd.css, de 2011): fondo #e2e2e4, lista blanca,
   texto #333 y una flecha en GIF oscuro. Sobre la tarjeta oscura quedaba un
   recuadro claro con la flecha invisible. Se cablea a los tokens, como se
   hizo con .card y .form-control. Ref #39 */
.main-content .dd.ddcommon {
    width: 100% !important;
    box-sizing: border-box;
    border-color: var(--p4s-field-border);
    border-radius: .25rem;
}

.main-content .dd .ddTitle {
    /* `background` entero, no solo -color: hay que matar tambien el GIF. */
    background: var(--p4s-field);
    color: var(--p4s-text);
}

.main-content .dd .ddTitle .ddTitleText {
    display: block;
    padding: .375rem 2rem .375rem .75rem;
}

.main-content .dd .ddChild {
    width: 100% !important;
    left: 0;
    background-color: var(--p4s-surface);
    border-color: var(--p4s-border);
}

.main-content .dd .ddChild li {
    background-color: var(--p4s-surface);
    border-bottom-color: var(--p4s-divider);
}

.main-content .dd .ddChild li.hover,
.main-content .dd .ddChild li.selected {
    background-color: var(--p4s-surface-alt);
}

.main-content .dd .ddTitle .ddlabel,
.main-content .dd .ddChild li .ddlabel {
    color: var(--p4s-text);
}

.main-content .dd .ddTitle .description,
.main-content .dd .ddChild li .description {
    color: var(--p4s-muted);
}

/* La flecha era un GIF oscuro, invisible sobre campo oscuro. Triangulo CSS,
   que toma el color del tema. */
.main-content .dd .ddArrow {
    background: none;
    width: 0;
    height: 0;
    right: 12px;
    margin-top: -2px;
    border-left: 5px solid transparent;
    border-right: 5px solid transparent;
    border-top: 6px solid var(--p4s-text-soft);
}

/* El separador vertical de dd.css era #c3c3c3 + #fff fijos. */
.main-content .dd .divider {
    display: none;
}

.main-content .ddcommon input.text {
    background: var(--p4s-field);
    color: var(--p4s-text);
}

/* ----- Paginacion --------------------------------------------------------
   Mismo caso que .text-muted: Bootstrap la resuelve contra --bs-pagination-*,
   que solo conmutan con [data-bs-theme=dark]. Con `body.dark` se quedaba con
   la piel del tema claro — pagina blanca sobre tarjeta oscura. */
.main-content .page-link {
    background-color: var(--p4s-surface);
    border-color: var(--p4s-border);
    color: var(--p4s-accent);
}

.main-content .page-link:hover {
    background-color: var(--p4s-surface-alt);
    border-color: var(--p4s-border);
    color: var(--p4s-accent-light);
}

.main-content .page-link:focus {
    box-shadow: 0 0 0 3px var(--p4s-accent-glow);
}

/* ----- Marca de campo obligatorio ---------------------------------------- */
.main-content .text-danger {
    color: var(--p4s-danger) !important;
}

/* ----- Migas de pan (breadcrumbs) -----------------------------------------
   Las vistas legadas traen `<ul class="breadcrumbs"><li>`, marcado de
   Foundation. Cork no trae nada para esa clase (su breadcrumb es
   `.breadcrumb`/`.breadcrumb-item`, otro nombre), asi que sin esta regla la
   lista se pinta con los bullets y el interlineado por defecto del navegador:
   una columna vertical en vez de una migaja horizontal. No se reescribe el
   marcado de cada vista (serian decenas) — se tokeniza aqui una vez, como el
   resto de componentes de Cork que hereda toda vista migrada. */
.main-content ul.breadcrumbs {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    list-style: none;
    margin: 0 0 1rem;
    padding: 0;
    font-size: 0.875rem;
}

.main-content ul.breadcrumbs li {
    color: var(--p4s-text-soft);
}

.main-content ul.breadcrumbs li:not(:last-child)::after {
    content: "/";
    margin: 0 0.5rem;
    color: var(--p4s-text-soft);
}

.main-content ul.breadcrumbs li a {
    color: var(--p4s-accent);
    text-decoration: none;
}

.main-content ul.breadcrumbs li a:hover {
    color: var(--p4s-accent-light);
    text-decoration: underline;
}

.main-content ul.breadcrumbs li.current {
    color: var(--p4s-text);
    font-weight: 600;
}

/* ----- Acordeon ----------------------------------------------------------
   Bootstrap 5.3 expone el acordeon por variables propias, asi que basta
   redefinirlas: no hace falta pelear la cascada con `!important`.

   Sin esto quedan dos cosas fuera de la marca: el panel abierto se pinta con
   el azul de Bootstrap (#0d6efd sobre #cfe2ff), que no es de la paleta, y en
   tema oscuro el cuerpo del acordeon sale BLANCO -- Cork no lo cubre y
   Bootstrap solo conmuta con `[data-bs-theme=dark]`, atributo que este
   template no pone (usa la clase body.dark). */
.main-content .accordion {
    --bs-accordion-bg: var(--p4s-surface);
    --bs-accordion-color: var(--p4s-text);
    --bs-accordion-border-color: var(--p4s-border);
    --bs-accordion-btn-color: var(--p4s-text);
    --bs-accordion-active-bg: var(--p4s-surface-alt);
    --bs-accordion-active-color: var(--p4s-accent);
    --bs-accordion-btn-focus-box-shadow: 0 0 0 3px var(--p4s-accent-glow);
}

/* La flecha de Bootstrap es un SVG incrustado con su color escrito dentro, asi
   que no puede leer un token: en tema oscuro quedaria una flecha casi negra
   sobre una tarjeta casi negra. Se invierte, que es lo unico que resuelve el
   contraste sin escribir un hex nuevo. */
body.dark .main-content .accordion-button::after {
    filter: invert(1);
}

/* ----- Tablas -------------------------------------------------------------
   Mismo motivo que el acordeon: las variables de tabla de Bootstrap traen el
   blanco y el gris de su propia paleta, y en tema oscuro dejan texto oscuro
   sobre fondo oscuro. */
.main-content .table {
    --bs-table-color: var(--p4s-text);
    --bs-table-bg: transparent;
    --bs-table-border-color: var(--p4s-divider);
    --bs-table-hover-color: var(--p4s-text);
    --bs-table-hover-bg: var(--p4s-surface-alt);
}

/* ----- Filtros del portfolio (jquery.mixitup) -----------------------------
   `scripts/jquery/portfolio/css/layout.css` (plugin de terceros, HU-1.7:
   networkMiRed.jsp y mentoresNew.jsp) trae el filtro activo en un rojo/coral
   fijo (`#e95a44`) que no sale de ningun token -- ni siquiera es el rojo de
   `--p4s-danger`, es un tercer rojo que solo vive en ese CSS. Se pisa con el
   mismo relleno de acento que ya usan los botones y el resto de estados
   "activo/resaltado" del marco. */
.main-content #filters li span.active {
    background: var(--p4s-accent-fill);
    color: var(--p4s-on-accent-fill);
}

/* ----- DataTables (paginacion de /colectivo) ------------------------------
   `dt-global_style.css` (plugin de terceros, ENA-1.26 #175) trae su propia
   paleta fija (`#4361ee` para la pagina activa, `#1b2e4b` para
   anterior/siguiente, `rgba(0,23,55,.08)` para los numeros de pagina, sin
   ningun equivalente para tema oscuro salvo un segundo archivo con sus
   propios hex). Se pisa con los tokens, una vez, para las dos cosas que
   pidio el usuario: que la pagina activa SI contraste con el boton
   siguiente (son roles distintos: "donde estoy" vs. "avanzar", no pueden
   verse igual), y que responda a claro/oscuro sin una segunda hoja. */
.main-content .page-link {
    background: var(--p4s-surface-alt);
    color: var(--p4s-text-soft);
    border-color: var(--p4s-border);
}

/* Bootstrap dibuja la paginacion como tira fundida a proposito
   (`.page-link{margin-left:-1px}`, para que los bordes se solapen y parezca
   una sola pildora). `dt-global_style.css` en cambio da a cada numero
   `margin-right:5px` y esquinas redondeadas -- pensado como chips sueltos,
   no como tira. Con las dos reglas activas el margen negativo de Bootstrap
   se come el positivo de Cork: nada distingue un boton del siguiente aunque
   cada uno SI tenga fondo/radio propios. Se fuerza el modelo de chips
   (gap en el contenedor + margen en cero) en vez de arbitrar cual de las
   dos hojas de terceros gana la cascada.

   Se aplica a CUALQUIER `ul.pagination` de `.main-content`, no solo a la de
   DataTables: `grupos.jsp`/`eventosNew.jsp`/`otrosEventosNew.jsp` traen su
   propia paginacion Bootstrap plana (paginas por `?pagina=N`, sin
   DataTables) con el mismo `.page-item.page-link` -- y el mismo
   margin-left:-1px de Bootstrap fundiendolos.

   Doble mecanismo a proposito, no solo `gap`: si el margen negativo de
   Bootstrap ganara la cascada en algun caso no previsto, un margen positivo
   explicito en el propio `.page-link` sigue separando los chips aunque el
   `gap` del contenedor fallara por alguna razon. Cinturon y tirantes, no
   arbitrar cual hoja de terceros gana. */
.main-content ul.pagination {
    gap: 6px;
}

.main-content .page-link {
    margin: 0 3px !important;
    border-radius: 8px !important;
}

.main-content .page-item:first-child .page-link,
.main-content .page-item:last-child .page-link {
    margin: 0 !important;
}

/* La pagina activa no solo cambia de color: gana un anillo (mismo token que
   el foco de campos) y letra en negrita para que se lea como "aqui estoy"
   incluso pegada a sus vecinos -- iguales en forma y tamano, solo el color
   no bastaba para que se notara como seleccionada. */
.main-content .page-item.active .page-link {
    background-color: var(--p4s-accent-fill) !important;
    border-color: var(--p4s-accent-fill);
    color: var(--p4s-on-accent-fill);
    font-weight: 700;
    box-shadow: 0 0 0 3px var(--p4s-accent-glow);
}

.main-content .page-item.next:not(.disabled) .page-link,
.main-content .page-item.previous:not(.disabled) .page-link {
    background: var(--p4s-surface-alt);
    color: var(--p4s-text);
}

.main-content .page-item.disabled .page-link {
    background: transparent;
    color: var(--p4s-muted);
}

.main-content div.dataTables_wrapper div.dataTables_paginate ul.pagination {
    align-items: center;
}

.main-content .dataTables_wrapper .dataTables_length select,
.main-content .dataTables_wrapper .dataTables_filter input {
    background-color: var(--p4s-field);
    border-color: var(--p4s-field-border);
    color: var(--p4s-text);
}

/* Solo color: es un rotulo ("Mostrando 1 a 10 de 515"), no un control.
   Llevaba `background` + `border-radius`, que con el `dom` por defecto
   pasaban desapercibidos porque el bloque ocupaba el ancho de su `.row`.
   Dentro de `.dt--bottom-section`, que es flex, el elemento se encoge a su
   contenido y ese fondo redondeado lo convierte en un CHIP -- con la misma
   forma, el mismo radio y el mismo fondo que los botones de paginacion que
   tiene justo al lado. Parece pulsable y no lo es. */
.main-content .dataTables_wrapper .dataTables_info {
    color: var(--p4s-text-soft);
}

.main-content .dataTables_wrapper .dataTables_length,
.main-content .dataTables_wrapper .dataTables_filter label {
    color: var(--p4s-text-soft);
}

/* Aqui vivian dos reglas que separaban a mano los tres bloques que genera
   DataTables (`> .row { margin: 0 }` y `> .row:nth-child(1),(2)
   { margin-bottom: 2rem }`), enganchadas por POSICION porque "un div
   generado por JS no se edita desde el JSP".

   Esa premisa era falsa y por eso se retiran: el `dom` de DataTables ES
   como se edita esa estructura, y Cork ya trae el suyo
   (`window.P4S_DT_DOM`, ver colectivoNew.jsp). Con el, los controles salen
   envueltos en `.dt--top-section` / `.dt--bottom-section`, que es donde
   `dt-global_style.css` pone su espaciado (20px 21px / 15px). El aire lo da
   la piel del template, no una regla nuestra a medida.

   Es el caso de libro de la regla del propio HU-1.7: ante "no cuadra",
   mirar primero si el componente de Cork esta cableado como el template
   espera -- no maquillarlo desde fuera. Ref ENA-1.26 (#175). */

/* ----- Alertas ------------------------------------------------------------
   Bootstrap 5 resuelve `.alert-*` contra `--bs-danger-bg-subtle`,
   `--bs-warning-border-subtle` y compania, y esas variables SOLO conmutan
   con `[data-bs-theme=dark]`. Esta plataforma conmuta con `body.dark`
   (HU-1.5), asi que sin esto toda alerta del marco privado se queda con la
   piel del tema CLARO -- un recuadro amarillo palido o rosa palido sobre
   tarjeta casi negra. Es el mismo mecanismo que ya dejo `.form-control`,
   `.text-muted` y `.pagination` descolgados (hallazgo 2 de la spec de
   HU-1.7); aqui se cierra para las alertas.

   Se cablean las TRES variantes que las vistas usan de verdad
   (`alert-danger`, `alert-warning`, `alert-success`). `alert-info` no se
   cablea porque ninguna vista lo usa.

   Especificidad `.alert.alert-x` (0-2-0) para ganar a la de Bootstrap
   (0-1-0) sin recurrir a !important. Ref BUG-1.29 (#177). */
.main-content .alert.alert-danger {
    color: var(--p4s-danger);
    background-color: var(--p4s-danger-tint);
    border-color: var(--p4s-danger-edge);
}

.main-content .alert.alert-warning {
    color: var(--p4s-warning);
    background-color: var(--p4s-warning-tint);
    border-color: var(--p4s-warning-edge);
}

.main-content .alert.alert-success {
    color: var(--p4s-success);
    background-color: var(--p4s-success-tint);
    border-color: var(--p4s-success-edge);
}

/* El aspa de `alert-dismissible` (la usan las alertas de /otrosEventos, ruta
   ya migrada) es un SVG NEGRO fijo incrustado en Bootstrap. Sobre la alerta
   clara se ve; sobre la oscura desaparece. Bootstrap lo resuelve invirtiendo
   el icono, pero su variable de inversion depende otra vez de
   `[data-bs-theme=dark]`, asi que hay que dispararlo desde `body.dark`. */
body.dark .main-content .alert .btn-close {
    filter: invert(1) grayscale(100%) brightness(200%);
}

/* Zona propia dentro de una tarjeta que YA contiene una grilla de Cork
   (hoy "Agregar una categoria/necesidad nueva" en /colectivo).

   Cork inserta sus controles con `margin: 20px 21px` (`.dt--top-section`).
   Un bloque nuestro pegado al padding de la tarjeta arranca 21px mas a la
   izquierda que "Mostrar N registros" y que el texto de la primera columna:
   dentro de la MISMA caja se ven dos margenes izquierdos distintos y el ojo
   lo lee como un descuadre, aunque cada pieza por separado este bien
   puesta. Se hereda el valor de la piel en vez de elegir uno nuevo.

   El divisor y el aire estaban antes en la vista (`mt-4 pt-4` + un
   `border-top` en linea, mas dos `<br>` sueltos heredados del JSP viejo).
   Suelto, eso sumaba mas de 100px de vacio entre la paginacion y el
   formulario. Aqui va una vez y las dos vistas quedan iguales. */
.main-content .p4s-zona-tarjeta {
    margin: 1rem 21px 0;
    padding-top: 1.5rem;
    border-top: 1px solid var(--p4s-border);
}

/* Las filas del cuerpo traian el mismo alto compacto (10px) que trae Cork
   por defecto -- suficiente para no encimarse, pero corto para leerse
   "espaciosas" junto al resto del sistema (sidebar, tarjetas). Un poco mas
   de aire vertical sin tocar el horizontal, que ya es generoso (21px). */
.main-content .table > tbody > tr > td {
    padding-top: 14px !important;
    padding-bottom: 14px !important;
}

/* ----- Iconos de orden de las cabeceras (DataTables) ----------------------
   `dt-global_style.css` ya trae un par claro/oscuro propio para el trazo del
   SVG (`stroke='%233b3f5c'` en claro, `stroke='%23bfc9d4'` en oscuro, este
   ultimo bien encerrado en `body.dark`) -- ese problema NO aplica aqui, a
   diferencia de la flecha del acordeon.

   El problema real es otro: la regla que el propio tema trae para
   "resaltar" la columna activa (`.sorting_asc:before, .sorting_desc:after
   { color: #0e1726 }`) no hace nada, porque `color` no pinta un
   `background-image`. Las dos flechas de CUALQUIER columna, activa o no,
   quedan siempre igual de oscuras -- no hay forma de saber cual esta
   ordenando. Se diferencia con opacidad, que si funciona sobre un
   background-image sin tocar el SVG ni el color de cada tema. */
.main-content table.dataTable thead .sorting:before,
.main-content table.dataTable thead .sorting:after,
.main-content table.dataTable thead .sorting_asc:after,
.main-content table.dataTable thead .sorting_desc:before {
    opacity: .35;
}

.main-content table.dataTable thead .sorting_asc:before,
.main-content table.dataTable thead .sorting_desc:after {
    opacity: 1;
}

/* ----- Preloader ----------------------------------------------------------
   Es lo PRIMERO que ve el usuario, asi que su fondo tiene que ser el de la
   pagina que va a aparecer debajo; si no, la carga empieza con un cambio de
   color.

   Y eso era justo lo que pasaba en tema oscuro: `templatev3/css/dark/loader.css`
   trae `body.dark div#load_screen { background: rgb(236,239,255) }` -- casi
   BLANCO. Entrar en oscuro daba un destello claro a pantalla completa antes de
   cada vista. Misma familia que el bug del fondo fijo de body que ya esta
   documentado en CLAUDE.md.

   No se acota a `.main-content`: el preloader cuelga de <body> y ademas lo tapa
   entero. */
div#load_screen,
body.dark div#load_screen {
    background: var(--p4s-bg);
}

/* La hoja oscura del template es la de la version ANTERIOR del loader, cuando
   `.loader` era el contenedor a pantalla completa y el spinner iba dentro:

     body.dark div#load_screen .loader { display: flex; height: 100vh }

   Con el marcado actual `.loader` YA NO es el contenedor, es la figura de 40px.
   Esa altura la estiraba a todo el alto de la ventana y dejaba los tres arcos
   repartidos por la pantalla en vez de formando un circulo. Se devuelve a las
   medidas que declara la hoja clara. */
body.dark div#load_screen .loader {
    display: block;
    width: 40px;
    height: auto;
    aspect-ratio: 1;
}

/* El color del spinner venia de `--dark_500`, variable de Cork, no de la marca.
   Basta redefinir `--c` -- la propiedad que la hoja de Cork interpola dentro de
   sus tres `conic-gradient` -- porque las propiedades personalizadas se
   resuelven al calcular el valor: cambiando `--c` cambia el degradado sin
   reescribir la regla `background` entera.

   Se usa el acento de TEXTO y no el de relleno: aqui no hay nada encima del
   color, es la propia forma sobre el fondo de pagina. */
.loader::before {
    --c: #0000, var(--p4s-accent) 1deg 120deg, #0000 121deg;
}

/* ----- Toasts (jquery-notice) --------------------------------------------
   `alrt()` y `alrtError()` (myAlrt.js) son el unico canal de respuesta de casi
   toda la app: guardar, borrar, vincular... todo termina en uno de estos, y
   seguian con la piel de 2012 -- Arial, `text-shadow` negro y un azul #2b65ae
   que no sale de la paleta.

   Esto NO es un diseño nuevo: es el MISMO tratamiento que login.css ya le dio
   al plugin en las vistas de auth (HU-1.2), traducido de los `--auth-*` a los
   `--p4s-*`. Las dos mitades usan el mismo componente, asi que deben verse
   igual; inventar aqui un tercer lenguaje de aviso era justo lo contrario del
   objetivo de la epica.

   La clave del tratamiento: tarjeta SOLIDA con texto de alto contraste (~13:1),
   y el tipo de aviso se distingue por el COLOR DEL BORDE, no bajando el
   contraste del texto sobre un relleno saturado.

   Como este archivo SOLO lo carga privateLayout, las vistas que siguen en el
   layout legado conservan su toast de siempre. Tampoco se acota a
   `.main-content`: el toast cuelga de <body>. */
.notice-wrap {
    /* Ancho segun contenido (con techo): "Eliminada" no debe reservar el mismo
       ancho que un mensaje largo. */
    width: fit-content;
    max-width: calc(100vw - 40px);
}

.notice-item {
    background: var(--p4s-surface) !important;
    border: 1px solid var(--p4s-border);
    border-radius: 8px;
    color: var(--p4s-text) !important;
    max-width: 320px;
    padding: 0.875rem 2rem 0.875rem 1rem;
    font-family: inherit;
    font-size: 0.9rem !important;
    font-weight: 600;
    text-shadow: none;
    box-shadow: 0 12px 28px -12px rgba(0, 0, 0, 0.5);
}

.notice-item p {
    color: inherit !important;
    width: auto;
    /* El plugin genera un <p> plano; sin resetear su margen, el margin-top por
       defecto del navegador se suma al padding y rompe la simetria vertical. */
    margin: 0;
}

.notice-item-close {
    font-family: inherit;
    font-weight: 700;
    color: var(--p4s-muted);
    right: 10px;
    top: 8px;
}

.notice-item-close:hover {
    color: var(--p4s-text);
}

.notice-success {
    border-color: var(--p4s-accent);
}

.notice-error {
    border-color: var(--p4s-danger);
}

/* ----- Dialogos de confirmacion (jquery-confirm) -------------------------
   OJO: estas reglas NO se acotan a `.main-content`. jquery-confirm inyecta su
   marcado como hijo de <body> y en `position: fixed`, asi que ahi no llega.

   1) CENTRADO. La libreria centra la caja con `col-md-offset-4`, que es una
      clase de BOOTSTRAP 3. Bootstrap 5 la renombro a `offset-md-4`, de modo que
      el desplazamiento no se aplica NUNCA y el dialogo aparece pegado al borde
      izquierdo (medido: left 36px en una ventana de 1512px). No se toca el
      marcado que genera la libreria; se centra el contenedor por margen, que es
      independiente de como se llame la clase de rejilla. */
.jconfirm .jconfirm-box-container {
    margin-left: auto;
    margin-right: auto;
    float: none;
}

/* 2) TEMA. jquery-confirm solo trae piel clara: sobre el dashboard en oscuro
      salia una tarjeta blanca, y su titulo -- gris muy claro sobre blanco --
      quedaba casi ilegible en los dos temas. Se alimenta de los tokens para que
      el dialogo siga al tema como el resto del marco. */
.jconfirm .jconfirm-box {
    background: var(--p4s-surface);
    color: var(--p4s-text);
    border: 1px solid var(--p4s-border);
}

.jconfirm .jconfirm-box .jconfirm-title-c .jconfirm-title,
.jconfirm .jconfirm-box .jconfirm-title {
    color: var(--p4s-text);
}

.jconfirm .jconfirm-box div.jconfirm-content,
.jconfirm .jconfirm-box .jconfirm-content-pane {
    color: var(--p4s-text-soft);
}

/* 3) TEMA 'supervan'. `$.alert({theme: 'supervan'})` se usa en 39 sitios de
   la app (ej. validacionEmail.jsp) y trae su PROPIA piel con mas
   especificidad que la regla generica de arriba (`.jconfirm.jconfirm-supervan
   .jconfirm-box` son 3 clases, `.jconfirm .jconfirm-box` son 2) — le gana
   pase lo que pase, asi que hay que pisarla con su mismo selector.

   El fondo (`.jconfirm-bg`) queda opaco al 95% con un azul marino fijo
   (`rgba(54,70,93,.95)`), sin relacion con el tema activo, y la caja queda
   TRANSPARENTE (`background-color:transparent`) para que se vea ese fondo a
   traves — asi que en tema claro aparece un dialogo azul marino que no
   pertenece a ninguna paleta de la plataforma. Los botones tampoco escapan:
   `background:#303f53` es casi el mismo azul marino que el fondo, y con la
   opacidad del backdrop detras el conjunto se ve gris lavado y sin
   contraste (reportado 2026-09-02, HU-1.7 #39). */
.jconfirm.jconfirm-supervan .jconfirm-bg {
    background-color: color-mix(in srgb, var(--p4s-text) 55%, transparent);
}
.jconfirm.jconfirm-supervan .jconfirm-box {
    background-color: var(--p4s-surface);
    color: var(--p4s-text);
}
.jconfirm.jconfirm-supervan .jconfirm-box div.jconfirm-closeIcon,
.jconfirm.jconfirm-supervan .jconfirm-box div.jconfirm-title-c,
.jconfirm.jconfirm-supervan .jconfirm-box div.jconfirm-content {
    color: var(--p4s-text);
}
.jconfirm.jconfirm-supervan .jconfirm-box .jconfirm-buttons button {
    /* --p4s-accent-fill, NO --p4s-accent: relleno de boton, no acento de
       texto -- son dos roles opuestos, ver p4s-boton.css. */
    background: var(--p4s-accent-fill);
    color: #fff;
}
.jconfirm.jconfirm-supervan .jconfirm-box .jconfirm-buttons button:hover {
    background: var(--p4s-accent-fill-hover);
}

/* ----- Dialogo flotante (jQuery UI Dialog) --------------------------------
   openDialogDesk* ("Ver mas" de startup/empresa/servicio, "Jugar" en crear
   proyecto) abre un jQuery UI Dialog sin overlay (`modal: false`): flota
   sobre el contenido, no lo bloquea. Antes traia el tema "overcast" de
   jQuery UI 1.8 (gradientes azules, Trebuchet MS, iconos de sprite) —
   coherente en 2013, disonante contra el resto del marco hoy.

   Como flota SIN overlay, el tratamiento correcto no es una tarjeta opaca
   mas: es cristal esmerilado tipo macOS, para que se note que sigue flotando
   sobre la pagina y no la tapa. `backdrop-filter` + una superficie translucida
   (`color-mix` sobre el propio token, no un hex nuevo) hacen ese trabajo;
   sin soporte de backdrop-filter el navegador se queda con la superficie
   translucida sola, que sigue siendo legible.

   NO se acota a `.main-content`: igual que jquery-confirm y los toasts (ver
   arriba), jQuery UI cuelga el dialogo de <body> en position:fixed, fuera
   de esa zona. Puente agregado en HU-1.7 (#39) — ver privateLayout.jsp para
   el porque de la version.

   La superficie se queda deliberadamente POR DEBAJO del 60% de opacidad:
   a la primera pasada (78%) el contraste con la pagina de fondo apenas se
   notaba fuera de una zona oscura — sobre fondo claro un blanco al 78% es
   indistinguible de un blanco solido. El vidrio solo se lee como vidrio
   si de verdad se ve lo de atras. */
.ui-dialog {
    font-family: inherit;
    font-size: 0.875rem;
    color: var(--p4s-text);
    background: color-mix(in srgb, var(--p4s-surface) 55%, transparent);
    border: 1px solid color-mix(in srgb, var(--p4s-border) 55%, transparent);
    border-radius: 12px;
    box-shadow:
        0 24px 60px -20px rgba(0, 0, 0, 0.55),
        inset 0 1px 0 color-mix(in srgb, var(--p4s-text) 8%, transparent);
    backdrop-filter: blur(28px) saturate(180%);
    -webkit-backdrop-filter: blur(28px) saturate(180%);
    padding: 0;
    overflow: hidden;
}

.ui-dialog .ui-dialog-titlebar {
    background: transparent;
    border: none;
    border-bottom: 1px solid color-mix(in srgb, var(--p4s-border) 55%, transparent);
    border-radius: 0;
    padding: 0.75rem 1.125rem;
}

.ui-dialog .ui-dialog-title {
    color: var(--p4s-text);
    font-weight: 600;
    font-size: 0.95rem;
}

.ui-dialog .ui-dialog-titlebar-close {
    background: transparent;
    border: none;
    right: 0.75rem;
    top: 50%;
    margin-top: -0.875rem;
    width: 1.75rem;
    height: 1.75rem;
    border-radius: 999px;
    transition: background-color 0.15s ease;
}

.ui-dialog .ui-dialog-titlebar-close:hover {
    background: color-mix(in srgb, var(--p4s-text) 12%, transparent);
    border: none;
}

/* El tema traia el icono "closethick" como recorte de un sprite PNG del
   2013. Se dibuja una X con dos barras en vez de cargar ese sprite.

   La 1.13.2 ya NO mete un <span class="ui-icon"> hijo dentro del boton
   (verificado con el inspector: <button class="ui-dialog-titlebar-close">
   vacio) -- la 1.10.3 si lo hacia. Las barras van sobre el BOTON mismo,
   no sobre un hijo que ya no existe; version anterior de esta regla
   apuntaba al span viejo y la X nunca se pintaba, solo quedaba el
   circulo de :hover -- sin ningun indicio de que el boton estuviera ahi. */
.ui-dialog .ui-dialog-titlebar-close::before,
.ui-dialog .ui-dialog-titlebar-close::after {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    width: 0.8rem;
    height: 2px;
    background: var(--p4s-text-soft);
    border-radius: 2px;
}

.ui-dialog .ui-dialog-titlebar-close::before { transform: translate(-50%, -50%) rotate(45deg); }
.ui-dialog .ui-dialog-titlebar-close::after  { transform: translate(-50%, -50%) rotate(-45deg); }

.ui-dialog .ui-dialog-titlebar-close:hover::before,
.ui-dialog .ui-dialog-titlebar-close:hover::after {
    background: var(--p4s-text);
}

.ui-dialog .ui-dialog-content {
    background: transparent;
    color: var(--p4s-text);
    padding: 1.125rem;
}

.ui-dialog .ui-dialog-content a:not([class~="btn"]):not([class*="btn-"]) {
    color: var(--p4s-accent);
}

.ui-dialog .ui-dialog-content a:not([class~="btn"]):not([class*="btn-"]):hover {
    color: var(--p4s-accent-light);
}

/* Tabla clave/valor de los fragmentos que se abren DENTRO del dialogo
   (juegoAsociacionForzada.jsp, verMasDesk.jsp): categoria/palabra,
   comunidad/evento. No se usa `.table` de Bootstrap porque esa regla esta
   acotada a `.main-content` (ver "Tablas" arriba) y este contenido cuelga
   de <body>, igual que el resto del dialogo. */
.p4s-tabla-dialogo {
    width: 100%;
    border-collapse: collapse;
}

.p4s-tabla-dialogo tr + tr {
    border-top: 1px solid color-mix(in srgb, var(--p4s-border) 55%, transparent);
}

.p4s-tabla-dialogo th,
.p4s-tabla-dialogo td {
    padding: 0.4rem 0.5rem;
    text-align: left;
    font-weight: normal;
}

.p4s-tabla-dialogo th {
    color: var(--p4s-text-soft);
    white-space: nowrap;
}

.p4s-tabla-dialogo td {
    color: var(--p4s-text);
}

.p4s-juego-acciones {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-top: 0.75rem;
}

.ui-dialog .ui-dialog-buttonpane {
    background: transparent;
    border-top: 1px solid color-mix(in srgb, var(--p4s-border) 55%, transparent);
    margin: 0;
    padding: 0.75rem 1.125rem;
}

.ui-dialog .ui-dialog-buttonpane button.ui-button {
    background: var(--p4s-accent-fill);
    color: var(--p4s-on-accent-fill);
    border: none;
    border-radius: 8px;
    padding: 0.4rem 1rem;
    font-size: 0.8125rem;
    font-weight: 600;
}

.ui-dialog .ui-dialog-buttonpane button.ui-button:hover {
    background: var(--p4s-accent-fill-hover);
}

/* Modal:true no lo usa openDialogDesk*, pero otras 16 llamadas de script.js
   comparten el widget: si alguna pide overlay, que tambien sea cristal. */
.ui-widget-overlay {
    background: rgba(0, 0, 0, 0.45);
    backdrop-filter: blur(2px);
}

/* ----- Banner de charla / certamen ---------------------------------------
   El banner generado es de 820x460 y a ancho completo domina la tarjeta
   entera, dejando el titulo y el autor como una nota al pie. Se le pone techo
   de altura y se recorta al centro: sigue siendo reconocible, pero la jerarquia
   vuelve al contenido -- el nombre de la charla, no su fondo decorativo. */
.main-content .charla-banner {
    width: 100%;
    /* ALTURA FIJA, no `max-height`. Con max-height la altura la decide la
       proporcion de la imagen, que el navegador no conoce hasta que la
       descarga: hasta ese momento el hueco vale 0 y, al llegar, empuja hacia
       abajo todo lo que tenia debajo. Fijandola, el espacio queda reservado
       desde el primer pintado y la pagina no salta.
       (En la practica siempre acababa en 180 de todos modos: un banner de
       820x460 al ancho de la tarjeta supera ese techo.) Ref HU-1.8 */
    height: 180px;
    object-fit: cover;
    border-radius: 8px;
    /* Color de espera mientras la imagen viaja, para que el hueco no sea un
       rectangulo en blanco. */
    background-color: var(--p4s-surface-alt);
}

/* ----- Esqueletos de carga -----------------------------------------------
   Para las zonas que se rellenan DESPUES del pintado inicial (las tablas que
   sustituye DWR). Antes cambiaban de golpe, sin decir que habia algo en curso.

   El brillo se apaga con `prefers-reduced-motion`: una animacion en bucle es
   justo lo que molesta a quien pide menos movimiento. */
.p4s-skeleton {
    background: linear-gradient(
        90deg,
        var(--p4s-surface-alt) 25%,
        var(--p4s-border) 37%,
        var(--p4s-surface-alt) 63%
    );
    background-size: 400% 100%;
    animation: p4s-brillo 1.4s ease infinite;
    border-radius: 6px;
}

@keyframes p4s-brillo {
    0%   { background-position: 100% 50%; }
    100% { background-position: 0 50%; }
}

.p4s-skeleton-fila {
    height: 2.5rem;
    margin-bottom: 0.5rem;
}

@media (prefers-reduced-motion: reduce) {
    .p4s-skeleton {
        animation: none;
        background: var(--p4s-surface-alt);
    }
}

/* ----- Chat de /messenger (mailing-chat.css) -------------------------------
   El plugin de terceros (ENA-1.29, #181) no trae NINGUNA regla `body.dark`:
   sus hex fijos (#0e1726, #191e3a...) son justo los tokens oscuros de p4s,
   asi que en tema oscuro coincidia por casualidad y en tema claro se veia
   como una caja oscura suelta dentro de un dashboard claro. Mismo patron que
   msDropdown/DataTables (HU-1.7): se tokeniza una vez aqui, no vista por
   vista. De paso se reemplaza el azul de Bootstrap (#1b55e2, burbuja propia)
   y el cian fuera de paleta (#25d5e4, hover/inputs) por el acento real de
   la plataforma -- no eran de p4s ni siquiera en el oscuro.

   Todo con !important, mismo motivo que p4s-boton.css: varios selectores de
   aqui EMPATAN en especificidad con los del plugin (mismo numero de clases),
   y el plugin se carga mas tarde en el HTML -- lo incluye la propia vista
   dentro del body, despues del <head> donde vive este archivo -- asi que en
   un empate gana el plugin. Se vio en la revision visual: el input de
   escribir y la burbuja propia seguian oscuros pese al override "normal". */
.main-content .chat-system .user-list-box {
    background: var(--p4s-surface-alt) !important;
    border-right-color: var(--p4s-border) !important;
}
.main-content .chat-system .user-list-box .search svg {
    color: var(--p4s-text-soft) !important;
}
.main-content .chat-system .user-list-box input,
.main-content .chat-system .chat-box .chat-input input {
    background: var(--p4s-surface) !important;
    color: var(--p4s-text) !important;
    border-color: var(--p4s-border) !important;
}
.main-content .chat-system .user-list-box .people .person {
    border-bottom-color: var(--p4s-border) !important;
}
.main-content .chat-system .user-list-box .people .person .user-info .f-body .meta-info .user-name {
    color: var(--p4s-text) !important;
}
.main-content .chat-system .user-list-box .people .person .user-info .f-body .meta-info .user-meta-time,
.main-content .chat-system .user-list-box .people .person .user-info .f-body .preview,
.main-content .chat-system .chat-box .chat-box-inner .chat-meta-user .current-chat-user-name span,
.main-content .chat-system .chat-box .chat-input svg,
.main-content .chat-system .chat-box .chat-box-inner .chat-meta-user.chat-active .chat-action-btn svg,
.main-content .chat-system .chat-box .chat-box-inner .chat-meta-user.chat-active .chat-action-btn .dropdown-menu a,
.main-content .chat-system .chat-box .chat-box-inner .chat-meta-user.chat-active .chat-action-btn .dropdown-menu a svg,
.main-content .chat-system .chat-box .chat-not-selected p svg {
    color: var(--p4s-text-soft) !important;
}
.main-content .chat-system .user-list-box .people .person:hover .user-info .f-body .meta-info .user-name,
.main-content .chat-system .user-list-box .people .person:hover .user-info .f-body .meta-info .user-meta-time,
.main-content .chat-system .chat-box .chat-box-inner .chat-meta-user.chat-active .chat-action-btn svg:hover,
.main-content .chat-system .chat-box .chat-box-inner .chat-meta-user.chat-active .chat-action-btn .dropdown-menu a:hover svg {
    color: var(--p4s-accent) !important;
}
.main-content .chat-system .chat-box .chat-box-inner .chat-meta-user .current-chat-user-name span .name {
    color: var(--p4s-text) !important;
}
.main-content .chat-system .chat-box .chat-not-selected p,
.main-content .chat-system .chat-box .chat-box-inner .chat-meta-user.chat-active,
.main-content .chat-system .chat-box .chat-footer.chat-active,
.main-content .chat-system .chat-box .conversation-start span,
.main-content .chat-system .chat-box .bubble.you {
    background: var(--p4s-surface-alt) !important;
    color: var(--p4s-text) !important;
}
.main-content .chat-system .chat-box .bubble.you:before {
    background-color: var(--p4s-surface-alt) !important;
}
.main-content .chat-system .chat-box .bubble.me,
.main-content .chat-system .chat-box .bubble.me:before {
    background-color: var(--p4s-accent-fill) !important;
    color: var(--p4s-on-accent-fill) !important;
}
.main-content .chat-system .chat-box .chat-box-inner .chat-meta-user.chat-active .chat-action-btn .dropdown-menu {
    background: var(--p4s-surface) !important;
    box-shadow: 0 6px 10px 0 rgba(0, 0, 0, 0.14), 0 1px 18px 0 rgba(0, 0, 0, 0.12), 0 3px 5px -1px rgba(0, 0, 0, 0.2);
}
.main-content .chat-system .chat-box .chat-box-inner .chat-meta-user.chat-active .chat-action-btn .dropdown-menu a:hover {
    background-color: var(--p4s-surface-alt) !important;
}

/* ----- Tarjetas de "Ruta de aprendizaje" (/tutoriales, infobox.css) --------
   Mismo patron que mailing-chat.css: infobox.css es de terceros, no trae
   ninguna regla body.dark, y su .infobox-2 fija `width: 50%` pensando en un
   contenedor ancho -- aqui vive dentro de una columna de Bootstrap
   (col-xl-4 col-lg-5), asi que el 50% la deja angostisima.

   El ancho YA estaba corregido -- `.card-ruta { width: 98% !important; }`
   vive en css/p4sBlack4.css -- pero ese archivo solo lo carga el layout
   legado integrator4Black, no privateLayout: se quedo atras al migrar
   /tutoriales (HU-1.7, #39). Nunca corrigio el color de fondo porque su
   propio dashboard tambien era oscuro y #3b3f5c pasaba desapercibido ahi.

   ALTURA: Bootstrap 5 SI estira las columnas del .row a la misma altura
   (es un contenedor flex con align-items:stretch por defecto), pero eso
   solo estira el DIV de la columna (.pixel-border) -- la tarjeta de
   adentro (.infobox-2) sigue creciendo segun su propio texto, asi que con
   descripciones de largo distinto (ej. "Ecosistema" vs "Usuarios") las
   tarjetas de una misma fila quedaban de alturas distintas y el boton
   "Consultar" en una posicion distinta en cada una -- eso, con el ancho al
   98%, es lo que se veia "roto" entre filas.

   `height` fija (primer intento) fue peor: la tarjeta con MAS texto
   ("Eventos y convocatorias") quedaba mas baja que su propio contenido, y
   "Consultar" se desbordaba por debajo del recuadro. `min-height` iguala
   contra la columna ya estirada sin techo -- la tarjeta crece si su texto
   lo pide, nunca se corta. */
.main-content .infobox-2.card-ruta {
    width: 98% !important;
    min-height: calc(100% - 35px) !important;
    box-sizing: border-box;
    background: var(--p4s-surface-alt) !important;
    border-color: var(--p4s-border) !important;
}
.main-content .infobox-2 .info-heading,
.main-content .infobox-2 .info-heading .info-link {
    color: var(--p4s-text) !important;
}
.main-content .infobox-2 .info-text {
    color: var(--p4s-text-soft) !important;
}
.main-content .infobox-2 .info-link {
    color: var(--p4s-accent) !important;
}
.main-content .pixel-border {
    color: var(--p4s-text) !important;
}
