/* njs/ui_v2.css — la capa UI v2 (todo lo scopeado a body.rxs-ui-v2 / .rxs-ui-vivid /
   .rxs-ui-accAB / .rxs-ui-compact y los @keyframes rxsV2*), separada de adm.css el
   2026-08-22 (P1 de docs/frontend/ui-v2.md). La emite index.php SOLO cuando
   rxsUiV2Enabled(), inmediatamente despues de adm.css (o del bundle app.css) y antes
   del CSS del tenant (cssStv), para que la cascada quede como estaba. El orden de los
   bloques "v2 pass N" es el mismo que tenian en adm.css. Los tokens --rx-v2-* de :root
   y las reglas sin scope siguen en adm.css. */

/* El padding reserva el alto de la topbar fija. Sin topbar no hay nada que reservar:
   `body.rxsContentOnly{padding:0}` (adm.css) lo decia, pero esta regla le gana por
   especificidad y dejaba 60 px muertos arriba de todo — en el shell de la app
   (docs/infra/app-shell-nativo.md) y tambien en el `?dsg=1` de siempre. */
body.rxs-ui-v2.thr-fix:not(.rxsContentOnly){padding-top:60px}



/* RXS UI v2 structural layer (opt-in) */
/* Graphite product skin: token-driven, light + dark (thr-dark), scoped to body.rxs-ui-v2 */

body.rxs-ui-v2 {
    /* auto-contraste del acento: hay sitios cuyo color1 es negro (o casi blanco) y
     * el pill accent desaparece contra la superficie (topbar "Ingresar", boton de
     * /login, paginacion...). Clampeamos SOLO la luminancia en OKLCH -tono y croma
     * de la marca intactos- y la tinta se elige por luminancia. Para un color
     * "normal" (#f28c28: L .74) los clamps no tocan nada. */
    --rx-v2-accent-src: var(--rx-accent-auto, var(--rx-color1, #f28c28));
    --rx-v2-accent: var(--rx-v2-accent-src);
    /* tinta = blanca o negra segun la luminancia del acento: el clamp hace de "if"
     * (l < .62 -> 1 -> blanca; l > .62 -> 0 -> negra). .62 es el cruce donde negro
     * pasa a contrastar mejor que blanco (naranja #f25c05: L .66 -> negra, como antes) */
    --rx-v2-accent-ink: #fff;
    --rx-v2-accent-soft: color-mix(in srgb, var(--rx-v2-accent) 14%, transparent);
    /* colores 2 y 3 del sitio: acento secundario (gradientes, hairlines) y
     * tinte sutil de superficies -> cada sitio "se siente" distinto en v2 */
    --rx-v2-accent-2: var(--rx-color3, #FFFFFF);
    --rx-v2-accent-2-soft: color-mix(in srgb, var(--rx-v2-accent-2) 15%, transparent);
    --rx-v2-grad: linear-gradient(90deg, var(--rx-v2-accent), var(--rx-v2-accent-2));
    /* --rx-v2-bg (el lienzo) NO se declara aca: vive en el `html:has(...)` de mas
     * abajo, con los dos numeros que lo mueven (knob `ui_surface`). El body lo
     * HEREDA, asi que las 14 reglas que lo leen no se enteran --- y de paso la
     * franja que asoma arriba del shell deja de ser un literal aparte. */
    --rx-v2-shell: #ffffff;
    --rx-v2-sidebar: color-mix(in srgb, var(--rx-color2, #58627a) 3%, #f8f9fb);
    --rx-v2-panel: #ffffff;
    --rx-v2-panel-2: #f4f5f7;
    --rx-v2-field: #ffffff;
    --rx-v2-head: #f1f3f5;
    --rx-v2-hover: #f3f5f8;
    --rx-v2-active: #e9ecf0;
    --rx-v2-ghost: rgba(18, 25, 33, .05);
    --rx-v2-border: rgba(18, 25, 33, .14);
    --rx-v2-border-soft: rgba(18, 25, 33, .08);
    --rx-v2-text: #1d242c;
    --rx-v2-muted: #5d6773;
    --rx-v2-faint: #8b94a1;
    --rx-v2-shadow: 0 8px 26px rgba(18, 25, 33, .08);
    /* La GAMA: todo lo que la UI pinta "por valor" (la pill de una columna enumerable,
     * `--rxp`) o "por sistema" (el chip, la pestania y la tarjeta del home, `--ch`)
     * sale de estos matices y de estos cinco numeros. El JS elige el matiz
     * (rxsHueGamut, njs/g.js: lee `--rx-hues` del body) y el CSS arma el color.
     * Oscuro y vivid solo REDEFINEN los numeros; ninguna regla de pill o de home
     * escribe un porcentaje a mano. Asi una fila de `ui_tokens` (`--rx-hues`,
     * `--rx-tint-s`...) mueve pills y home a la vez, y las combinaciones se
     * eligen en un solo lugar. Los tres tonos semanticos de la pill (rojo, ambar,
     * verde: rxsPillSemantics, ui_v2.js) NO entran en la gama: dicen estado, no
     * pertenencia. */
    --rx-hues: 214 152 274 28 340 188 96 254 8 168 310 44;
    --rx-tint-s: 60%;
    --rx-tint-l: 46%;
    --rx-tint-a: .13;
    --rx-tint-ink-s: 48%;
    --rx-tint-ink-l: 36%;
    /* El vidrio (knob `ui_glass`). Dos tokens porque son las dos mitades del
     * efecto y se apagan juntas: el desenfoque de lo que queda atras, y cuanto
     * de la superficie deja pasar. `none` / `100%` es una barra solida --- y no
     * `blur(0px)`, que sigue creando la capa de compositing y su costo.
     *
     * Hoy los lee UNA sola superficie: la topbar flotante del pass 23c. Las
     * otras tres del archivo con backdrop-filter --- las dos barras del mapa y la
     * tarjeta del login --- NO los leen a proposito: ahi el vidrio no es estilo,
     * es que abajo hay un mapa o el fondo del tenant y se tiene que ver. */
    --rx-v2-glass: blur(14px);
    --rx-v2-glass-a: 82%;
    --rx-v2-font: "Inter", "SF Pro Text", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;

    /* ---- Redondeo (knob `ui_radius` del tenant) ----------------------------
     * Este archivo tenia 199 `border-radius` con el numero escrito: 8px para las
     * tarjetas, 10 para los paneles, 7 para los campos, 12 para los modales...
     * No son arbitrarios --hay una escala-- pero al estar escritos uno por uno
     * no habia UNA cosa que mover para que un tenant tenga esquinas rectas o
     * bien redondeadas.
     *
     * Ahora cada medida es un token y todos salen del MISMO factor. `1` es lo
     * que se ve hoy: con el knob en `normal` cada radio computa exactamente el
     * numero que estaba escrito, y eso es lo que mide docs/repro/ui-radios.mjs
     * --el gate del cambio no es "se ve parecido", es "no se movio ni un radio".
     *
     * Lo que NO entra: `999px` (las pildoras) y `50%` (los avatares). Ahi el
     * radio no es una medida sino "todo lo que se pueda", y multiplicarlo por 0
     * dejaria una pildora cuadrada, que es otra cosa y no una esquina recta. */
    --rx-v2-radius-k: 1;
    --rx-v2-r2: calc(var(--rx-v2-radius-k) * 2px);
    --rx-v2-r4: calc(var(--rx-v2-radius-k) * 4px);
    --rx-v2-r6: calc(var(--rx-v2-radius-k) * 6px);
    --rx-v2-r7: calc(var(--rx-v2-radius-k) * 7px);
    --rx-v2-r8: calc(var(--rx-v2-radius-k) * 8px);
    --rx-v2-r9: calc(var(--rx-v2-radius-k) * 9px);
    --rx-v2-r10: calc(var(--rx-v2-radius-k) * 10px);
    --rx-v2-r12: calc(var(--rx-v2-radius-k) * 12px);
    --rx-v2-r14: calc(var(--rx-v2-radius-k) * 14px);
    --rx-v2-r16: calc(var(--rx-v2-radius-k) * 16px);
    --rx-v2-r18: calc(var(--rx-v2-radius-k) * 18px);
}
/* El acento con la luminancia acotada y la tinta por luminancia necesitan color relativo
 * (oklch(from ...): Chrome 119, Safari 18). Sin el, una variable con esa sintaxis queda
 * invalida ENTERA y el acento caia a la tinta: medido el 01-10 en el WebView 113 de Google TV.
 * Afuera queda el color crudo del sitio y tinta blanca. */
@supports (color: oklch(from red l c h)) {
    body.rxs-ui-v2 {
    --rx-v2-accent: oklch(from var(--rx-v2-accent-src) clamp(.22, l, .86) c h);
    --rx-v2-accent-ink: oklch(from var(--rx-v2-accent) clamp(.08, (.62 - l) * 100, .97) 0 h);
    }
}

/* Las dos elecciones que no son el default. El factor va en el <body>, asi que
 * lo hereda todo -- los modales que el theme cuelga del body incluidos.
 * 1,6 y no 2: a 2 los campos quedan en 14px de radio contra 20 del panel que los
 * contiene y el formulario se lee como burbujas adentro de una caja; 1,6 sube la
 * escala entera sin que las piezas chicas se coman a las grandes. */
/* `solida`: la barra deja de ser vidrio. Va en el <body> y no en la superficie
 * porque el dia que otra pieza del chrome sea vidrio, entra sola. */
body.rxs-ui-v2.rxs-ui-glass-solida {
    --rx-v2-glass: none;
    --rx-v2-glass-a: 100%;
}

body.rxs-ui-v2.rxs-ui-radius-recto {
    --rx-v2-radius-k: 0;
}

body.rxs-ui-v2.rxs-ui-radius-redondeado {
    --rx-v2-radius-k: 1.6;
}

/* Los que v2 no habia tomado y el redondeo si tiene que alcanzar. El radio de
 * estos lo pone el theme (style2.css) o Bootstrap, asi que el factor no los
 * tocaba y con el knob en `recto` quedaban 66 esquinas redondeadas en una
 * pantalla que se pidio recta. Cada valor es EL QUE YA COMPUTABAN --medido, no
 * elegido-- expresado en el factor: con el knob en `normal` no se mueve nada, y
 * es lo que comprueba docs/repro/ui-radios.mjs.
 *
 * Quedan afuera a proposito los que son circulos y no esquinas: el punto del
 * aviso (`.point`), el latido (`.heartbit`) y las pildoras de conteo. Ahi el
 * radio no es una medida, y aplanarlo no da "recto" sino un cuadradito. */
body.rxs-ui-v2 .dropdown-menu,
body.rxs-ui-v2 .rxsBtns,
body.rxs-ui-v2 .table-more-info,
body.rxs-ui-v2 .table-more-action {
    border-radius: var(--rx-v2-r10);
}

body.rxs-ui-v2 .dropdown-menu.scale-up,
body.rxs-ui-v2 .dropdown-menu.dropdown-menu-right.scale-up {
    border-radius: var(--rx-v2-r14);
}

body.rxs-ui-v2 .form-control,
body.rxs-ui-v2 .input-group-text,
body.rxs-ui-v2 .select2-search__field,
body.rxs-ui-v2 select.select2-hidden-accessible,
body.rxs-ui-v2 a.favMenu.btn {
    border-radius: var(--rx-v2-r4);
}

body.rxs-ui-v2 .modal-header {
    /* en rem, que es como lo trae el theme (.3rem): pasarlo a px le cambiaria el
     * valor al redondear */
    border-radius: calc(var(--rx-v2-radius-k) * .3rem) calc(var(--rx-v2-radius-k) * .3rem) 0 0;
}

/* Lo que este bloque NO toma, y por que
 * -------------------------------------
 * `.btn`, `.card` y los `input` sueltos estuvieron aca una version y hubo que
 * sacarlos: un selector de UNA clase (`body.rxs-ui-v2 .btn` = 0,2,0) le gana a
 * cualquier regla de una sola clase, y las que hacen REDONDO a un boton son
 * exactamente eso -- `.chat-button`, y las otras dos docenas de `999px` / `50%`
 * de este archivo, que valen 0,1,0. O sea que tomar `.btn` en general cuadra las
 * pildoras y los botones flotantes, que es justo lo que este knob promete NO
 * hacer.
 *
 * Y no se vio mirando: el burbujon del chat quedo cuadrado y el repro de radios
 * dio verde igual, porque compara elemento por elemento en orden y ese widget
 * entra tarde y corre los indices. Lo destapo el A/B de PIXELES con los knobs
 * apagados (docs/repro/ui-radios.mjs, bloque `pixeles`), que es el gate que
 * quedo para esto.
 *
 * Consecuencia asumida: con `recto`, lo que redondean el theme y Bootstrap y v2
 * no habia tomado --unos 30 botones a 4px-- se queda en 4px. El knob gobierna la
 * capa v2, no el theme entero, y 4px contra 0 se nota mucho menos que un FAB
 * cuadrado.
 */

body.rxs-ui-v2 .sidebar-nav a.treeview,
body.rxs-ui-v2 select.rxsTagsTable.select2-hidden-accessible {
    border-radius: var(--rx-v2-r8);
}

/* la barra del slimScroll trae su radio como estilo INLINE (lo escribe el plugin
 * de jQuery al construirla), asi que es lo unico de este bloque que necesita
 * !important para que el knob la alcance. El valor es el mismo 7px que escribe
 * el plugin: con el knob en `normal` no cambia nada. */
body.rxs-ui-v2 .slimScrollBar,
body.rxs-ui-v2 .slimScrollRail {
    border-radius: var(--rx-v2-r7) !important;
}

body.rxs-ui-v2.thr-dark {
    /* en dark el piso de luminancia sube: un acento oscuro (negro/azul noche) queda
     * indistinguible del panel */
    --rx-v2-accent: var(--rx-v2-accent-src);
    --rx-v2-accent-soft: color-mix(in srgb, var(--rx-v2-accent) 17%, transparent);
    /* la gama en oscuro: fondo mas claro y mas transparente, tinta clara */
    --rx-tint-s: 57%;
    --rx-tint-l: 58%;
    --rx-tint-a: .18;
    --rx-tint-ink-s: 62%;
    --rx-tint-ink-l: 72%;
    /* el lienzo en oscuro: idem, sale del html:has(...) de abajo. Tiene que ser
     * LA superficie mas oscura del dark --- con 14% sobre #101317 quedaba mas
     * claro que sidebar/shell y la franja de arriba cantaba. */
    --rx-v2-shell: #0b0e11;
    --rx-v2-sidebar: color-mix(in srgb, var(--rx-color2, #10192e) 10%, #0d1014);
    --rx-v2-panel: color-mix(in srgb, var(--rx-color2, #10192e) 7%, #171b20);
    --rx-v2-panel-2: color-mix(in srgb, var(--rx-color2, #10192e) 7%, #1b2026);
    --rx-v2-field: #10141a;
    --rx-v2-head: color-mix(in srgb, var(--rx-color2, #10192e) 7%, #13171c);
    --rx-v2-hover: #1e242b;
    --rx-v2-active: #232a32;
    --rx-v2-ghost: rgba(255, 255, 255, .06);
    --rx-v2-border: rgba(255, 255, 255, .09);
    --rx-v2-border-soft: rgba(255, 255, 255, .055);
    --rx-v2-text: #e8ecf1;
    --rx-v2-muted: #9aa4b1;
    --rx-v2-faint: #6d7784;
    --rx-v2-shadow: 0 14px 40px rgba(0, 0, 0, .35);
}
@supports (color: oklch(from red l c h)) {
    body.rxs-ui-v2.thr-dark {
    --rx-v2-accent: oklch(from var(--rx-v2-accent-src) clamp(.55, l, .92) c h);
    }
}

/* ---- El lienzo del admin (knob `ui_surface`) --------------------------------
 * Lo que pintan el <html>, el <body>, el .page-wrapper y --- salvo que
 * `ui_sidebar` diga otra cosa --- el sidebar es UN token, `--rx-v2-bg`. O sea
 * que el lienzo pasa el test del §1 de docs/frontend/ui-v2-config-del-tenant.md
 * mejor que ningun knob que ya exista: hay un solo lugar donde entra.
 *
 * Hasta hoy era un literal por tema y no habia perilla. Ahora sale de DOS
 * numeros, por lo mismo que el redondeo salio de uno solo (§3 de ese doc):
 * con tres bloques de CSS por variante el cuarto valor no llega nunca.
 *
 *   --rx-v2-bg-km   cuanto tinte de marca lleva el lienzo, como MULTIPLICADOR
 *                   del que trae el tema (`--rx-v2-bg-k0`: 5% en claro, 8% en
 *                   oscuro). Asi el knob es un numero solo y no una tabla de
 *                   dos columnas que se puede desincronizar: `1` es lo de hoy
 *                   en los dos temas, `0` saca el tinte y `2.6` lo sube.
 *   --rx-v2-bg-dk   cuanto se separa el lienzo de los paneles (negro sobre la
 *                   base del tema, en %). Es el otro eje: no tine, contrasta.
 *
 * Y viven en el <html> --- no en el <body>, donde estan los otros ~30 tokens ---
 * porque el <html> es el que pinta la franja de 60px que asoma arriba del shell
 * flotante y no puede leer un token declarado en el body. La clase la espeja
 * index.php en el <html>: preguntarla con `html:has(body.rxs-ui-v2)` costaba un
 * recalc de documento entero por CADA insercion de DOM de la pantalla (ver
 * docs/frontend/ui-v2-has-recalc.md). Estaba resuelto
 * repitiendo el valor a mano, y en claro los dos literales YA no coincidian:
 * medido en resumax, el html daba rgb(237,239,242) y el body rgb(226,228,233).
 * `--rx-color2` vive en `:root` (el <style> del tenant), asi que aca se lee. */
html.rxs-ui-v2 {
    --rx-v2-bg-k0: 5;
    --rx-v2-bg-km: 1;
    --rx-v2-bg-dk: 0;
    --rx-v2-bg-base: color-mix(in srgb, #eef0f3, #000 calc(var(--rx-v2-bg-dk) * 1%));
    --rx-v2-bg: color-mix(in srgb,
        var(--rx-color2, #58627a) calc(var(--rx-v2-bg-k0) * var(--rx-v2-bg-km) * 1%),
        var(--rx-v2-bg-base));
    background: var(--rx-v2-bg);
}

html.rxs-ui-v2.thr-dark {
    --rx-v2-bg-k0: 8;
    --rx-v2-bg-base: color-mix(in srgb, #0a0c10, #000 calc(var(--rx-v2-bg-dk) * 1%));
}

/* Las tres elecciones que no son el default. Cada una mueve UN numero, y por eso
 * el knob no tiene un bloque por tema: el multiplicador vale para los dos.
 * `normal` no emite clase --- lo que no se eligio no aparece en el HTML. */
html.rxs-ui-v2.rxs-ui-surface-neutro {
    --rx-v2-bg-km: 0;
}

html.rxs-ui-v2.rxs-ui-surface-marca {
    /* 2,6 y no 4: a 4 el lienzo compite con el acento y los paneles blancos
     * quedan flotando sobre un color, que es otra pantalla. 2,6 es el maximo
     * donde el gris sigue leyendose como gris tenido. */
    --rx-v2-bg-km: 2.6;
}

html.rxs-ui-v2.rxs-ui-surface-contraste {
    --rx-v2-bg-dk: 4;
}

/* ---- base / typography ---- */

body.rxs-ui-v2 {
    color: var(--rx-v2-text);
    color-scheme: light;
    font-family: var(--rx-v2-font);
}

body.rxs-ui-v2.thr-dark {
    color-scheme: dark;
}

body.rxs-ui-v2 h1,
body.rxs-ui-v2 h2,
body.rxs-ui-v2 h3,
body.rxs-ui-v2 h4,
body.rxs-ui-v2 h5,
body.rxs-ui-v2 h6,
body.rxs-ui-v2 label,
body.rxs-ui-v2 button,
body.rxs-ui-v2 input,
body.rxs-ui-v2 select,
body.rxs-ui-v2 textarea,
body.rxs-ui-v2 .btn,
body.rxs-ui-v2 .dropdown-menu {
    font-family: var(--rx-v2-font);
}

body.rxs-ui-v2 .page-wrapper {
    background: var(--rx-v2-bg);
}

/* en el layout horizontal el <main> es `container` pelada (index.php ~L594), no
 * `container-fluid`: sin este segundo selector se quedaba sin los paddings del shell */
body.rxs-ui-v2 #maincontent.container-fluid,
body.rxs-ui-v2.horizontal #maincontent.container {
    padding: 18px 20px 28px;
}

body.rxs-ui-v2 ::-webkit-scrollbar {
    height: 10px;
    width: 10px;
}

body.rxs-ui-v2 ::-webkit-scrollbar-track {
    background: transparent;
}

body.rxs-ui-v2 ::-webkit-scrollbar-thumb {
    background: var(--rx-v2-border);
    border: 2px solid transparent;
    background-clip: padding-box;
    border-radius: var(--rx-v2-r8);
}

body.rxs-ui-v2 ::-webkit-scrollbar-thumb:hover {
    background-color: var(--rx-v2-faint);
    background-clip: padding-box;
}

/* ---- topbar ---- */

/* topbar fundida con el fondo de la pagina (nada de "barra blanca" v1);
 * la separacion la da un hairline degrade con los colores del sitio */
body.rxs-ui-v2 .topbar {
    background: var(--rx-v2-bg) !important;
    border-bottom: 1px solid var(--rx-v2-border-soft);
    box-shadow: none;
}

body.rxs-ui-v2 .topbar::after {
    background: linear-gradient(90deg, var(--rx-v2-accent), var(--rx-v2-accent-2) 45%, transparent 80%);
    bottom: -1px;
    content: "";
    height: 2px;
    left: 0;
    opacity: .8;
    pointer-events: none;
    position: absolute;
    right: 0;
    z-index: 1;
}

body.rxs-ui-v2 .topbar .top-navbar {
    background: transparent !important;
    min-height: 60px;
    padding-right: 14px;
}

body.rxs-ui-v2 .topbar .top-navbar .navbar-header {
    background: transparent !important;
    border-right: 0;
    line-height:normal;
}

body.rxs-ui-v2 .topbar .navbar-brand.logo {
    align-items: center;
    display: inline-flex;
    gap: 10px;
    min-height: 60px;
}

body.rxs-ui-v2 .topbar .navbar-brand.logo img {
    max-height: 52px;
    width: auto;
}
/* con kit de marca index.php manda el positivo y el negativo: uno por tema (la topbar va del color del fondo) */
body.rxs-ui-v2 .topbar .navbar-brand.logo img.rxsLogoNeg { display: none; }
body.rxs-ui-v2.thr-dark .topbar .navbar-brand.logo img.rxsLogoPos,
body.rxs-ui-v2.rxs-ui-vivid .topbar .navbar-brand.logo img.rxsLogoPos { display: none; }
body.rxs-ui-v2.thr-dark .topbar .navbar-brand.logo img.rxsLogoNeg,
body.rxs-ui-v2.rxs-ui-vivid .topbar .navbar-brand.logo img.rxsLogoNeg { display: block; }

/* el nombre del sitio venia blanco hardcodeado (topbar oscura v1); con la
 * topbar fundida al fondo tiene que seguir al token en ambos modos */
body.rxs-ui-v2 .topbar .navbar-brand.logo span {
    color: var(--rx-v2-text) !important;
    font-weight: 600;
}

body.rxs-ui-v2 .topbar .navbar-light .navbar-nav .nav-link,
body.rxs-ui-v2 .topbar .top-navbar .navbar-nav > .nav-item > .nav-link {
    align-items: center;
    border-radius: var(--rx-v2-r8);
    color: var(--rx-v2-muted) !important;
    display: inline-flex;
    height: 36px;
    justify-content: center;
    margin: 0 1px;
    min-width: 36px;
    padding: 0 9px;
}

body.rxs-ui-v2 .topbar .navbar-light .navbar-nav .nav-link:hover,
body.rxs-ui-v2 .topbar .top-navbar .navbar-nav > .nav-item > .nav-link:hover {
    background: var(--rx-v2-ghost);
    color: var(--rx-v2-text) !important;
}

body.rxs-ui-v2 .topbar .profile-pic {
    border: 1px solid var(--rx-v2-border);
    border-radius: 50%;
    height: 30px !important;
    object-fit: cover;
    width: 30px !important;
}

body.rxs-ui-v2 .topbar .dropdown-menu {
    background: var(--rx-v2-panel);
    border: 1px solid var(--rx-v2-border);
    border-radius: var(--rx-v2-r10);
    box-shadow: var(--rx-v2-shadow);
}

/* ---- sidebar ---- */

/* sidebar tambien fundida con el fondo: chrome unificado, solo los paneles
 * de contenido "flotan" como cards */
body.rxs-ui-v2 .left-sidebar {
    background: var(--rx-v2-bg) !important;
    border-right: 1px solid var(--rx-v2-border-soft);
    box-shadow: none;
}

/* La regla de arriba pisa el fondo con el shorthand `background`, que de paso
 * resetea background-image y background-size - pero no toca `animation`. La
 * animacion "gradient" que njs/custom.css le pone a .thr-anim .left-sidebar
 * mueve background-position sobre un background-size de 600%, asi que al
 * quedarse sin ese 600% (vuelve a "auto", el fondo mide exacto la caja) mover
 * background-position ya no desplaza nada: sigue corriendo pero no se ve.
 * Comprobado sobre el login real: cuatro capturas a lo largo del ciclo de 5s
 * salen identicas pixel a pixel, y con animation:none sale el mismo hash.
 * Invisible no es gratis: background-position es trabajo del main thread, pide
 * un recalculo de estilo por frame (60/s) y no se frena cuando la pestana pasa
 * a segundo plano, asi que una pestana olvidada quema CPU para siempre. Medido
 * en el login: 60 recalc/s y 6.5% de CPU -> 0 recalc/s y 0.1%.
 * Va scopeado a rxs-ui-v2 a proposito: en los temas viejos, sin esta capa, el
 * background-size de 600% sigue en pie y ahi la animacion si se ve. */
body.rxs-ui-v2.thr-anim .left-sidebar,
body.rxs-ui-v2 .rxs-bg-theme,
body.rxs-ui-v2.thr-anim.no-logged {
    animation: none !important;
    -webkit-animation: none !important;
}

body.rxs-ui-v2 .scroll-sidebar {
    background: transparent !important;
    padding: 5px 8px 0px;
}

body.rxs-ui-v2 #sidebarEffect,
body.rxs-ui-v2 #sidebarEffect2 {
    display: none;
}

body.rxs-ui-v2 .sidebar-nav {
    background: transparent !important;
    /* el theme mete 15px de padding lateral que, sumado al de .scroll-sidebar y
     * al del propio link, desperdiciaba margen izquierdo: lo achicamos */
    padding-left: 3px;
    padding-right: 3px;
    padding-top:0;
}

body.rxs-ui-v2 .sidebar-nav ul li a {
    border-radius: var(--rx-v2-r8);
    font-size: 13.5px;
    font-weight: 500;
    margin: 2px 0;
    min-height: 40px;
    padding: 9px 7px;
}

body.rxs-ui-v2 .sidebar-nav > ul > li > a i {
    color: var(--rx-v2-faint);
    width: 26px;
}

/* OJO: el estado activo se ancla en li.active (que el framework SI mueve al
 * navegar), NO en a.active: esa clase queda pegada en el item anterior al hacer
 * loadpage y dejaba el item viejo "pintado" (barra accent + fondo) de mas. */
body.rxs-ui-v2 .sidebar-nav ul li a:hover {
    background: var(--rx-v2-ghost);
    color: var(--rx-v2-text);
    text-shadow: none;
}

/* !important: custom.css pinta .sidebar-nav>ul>li.active>a con el gradiente
 * color1->color2 !important (el mismo bloque que .treeview-menu.collapse) */
body.rxs-ui-v2 .sidebar-nav ul li.active > a,
body.rxs-ui-v2 .sidebar-nav > ul > li.active > a {
    background: var(--rx-v2-accent-soft) !important;
    color: var(--rx-v2-text);
    font-weight: 600;
    /* current48 (.thr-anim ... a:hover) mete text-shadow negro para texto
     * blanco en dark; en light embarra el texto (doble/borroso) */
    text-shadow: none;
}

/* barra accent solo en el item hoja activo (submenu) o un item de primer nivel
 * sin submenu; el grupo padre (has-arrow) queda solo resaltado por el fondo */
body.rxs-ui-v2 .sidebar-nav ul.treeview-menu li.active > a,
body.rxs-ui-v2 .sidebar-nav > ul > li.active > a:not(.has-arrow) {
    box-shadow: inset 3px 0 0 var(--rx-v2-accent);
}

body.rxs-ui-v2 .sidebar-nav ul li.active > a i,
body.rxs-ui-v2 .sidebar-nav > ul > li.active > a i {
    color: var(--rx-v2-accent);
}

/* submenu desplegado dentro del sidebar: custom.css le mete el gradiente
 * color1->color2 !important a .treeview-menu.collapse. Aca el submenu esta
 * anidado en el sidebar, no flota: tiene que seguir su fondo. Los dos casos en
 * que SI flota sobre el contenido (flyout del mini-sidebar y dropdown del
 * layout horizontal) llevan panel propio -- el mini mas abajo, en su media. */
body.rxs-ui-v2:not(.mini-sidebar):not(.horizontal) .sidebar-nav ul.treeview-menu,
body.rxs-ui-v2:not(.mini-sidebar):not(.horizontal) .sidebar-nav ul.treeview-menu.collapse {
    background: transparent !important;
}

body.rxs-ui-v2.horizontal .sidebar-nav #sidebarnav > li > ul,
body.rxs-ui-v2.horizontal .sidebar-nav #sidebarnav > li > ul.treeview-menu.collapse {
    background: var(--rx-v2-panel) !important;
    border: 1px solid var(--rx-v2-border);
    border-radius: 0 0 var(--rx-v2-r12) var(--rx-v2-r12);
    box-shadow: var(--rx-v2-shadow);
}

body.rxs-ui-v2.horizontal .sidebar-nav #sidebarnav > li > ul ul.treeview-menu,
body.rxs-ui-v2.horizontal .sidebar-nav #sidebarnav > li > ul ul.treeview-menu.collapse {
    background: transparent !important;
}

body.rxs-ui-v2 .sidebar-footer {
    background: var(--rx-v2-shell);
    border-top: 1px solid var(--rx-v2-border);
}

body.rxs-ui-v2 .footer {
    padding-left: 16px;
}

/* ---- tabs: barra segmentada de pills + transicion de panes ---- */

body.rxs-ui-v2 .nav-tabs-custom.card {
    background: transparent;
    border: 0;
    border-radius: 0;
    box-shadow: none;
    overflow: visible;
}

/* pestañas de contenido custom (reportes, dashboards, graficos: filterStv +
 * graphs/dashboard) no traen el <section.rxs-module> que dibuja el panel, asi que su
 * contenido quedaba flotando sobre el fondo de la pagina. Les damos el mismo panel que
 * un modulo de tabla. Selector estructural (NO .rxsDevTab, que solo existe con dev>0):
 * el pane visible que NO trae su propio contenedor con fondo -> modulo de tabla
 * (.rxs-module), formulario v2 (.rxs-form), sub-tabs de ficha (.nav-tabs-custom) ni
 * layout de cards masonry (.card-columns, que se quiere sin marco). */
body.rxs-ui-v2 .tab-content > .tab-pane.active:not(:empty):not(:has(.rxs-module)):not(:has(.rxs-form)):not(:has(.nav-tabs-custom)):not(:has(.card-columns)) {
    background: var(--rx-v2-panel);
    border: 1px solid var(--rx-v2-border);
    border-radius: var(--rx-v2-r12);
    box-shadow: var(--rx-v2-shadow);
    padding: 16px 14px;
}

body.rxs-ui-v2 .customtab,
body.rxs-ui-v2 .nav-tabs {
    background: var(--rx-v2-panel-2);
    border: 1px solid var(--rx-v2-border-soft);
    border-radius: var(--rx-v2-r12);
    display: inline-flex;
    flex-wrap: nowrap;
    gap: 2px;
    margin-bottom: 14px;
    max-width: 100%;
    overflow-x: auto;
    padding: 4px;
    scrollbar-width: none;
    width: auto;
}

body.rxs-ui-v2 .customtab::-webkit-scrollbar,
body.rxs-ui-v2 .nav-tabs::-webkit-scrollbar {
    display: none;
}

body.rxs-ui-v2 .nav-tabs .nav-item {
    flex: 0 0 auto;
    margin: 0;
}

body.rxs-ui-v2 .customtab li a.nav-link,
body.rxs-ui-v2 .nav-tabs .nav-link {
    align-items: center;
    background: transparent;
    border: 0;
    border-radius: var(--rx-v2-r9);
    box-shadow: none;
    color: var(--rx-v2-muted);
    display: inline-flex;
    font-size: 13px;
    font-weight: 600;
    gap: 7px;
    padding: 8px 14px;
    transition: background .16s ease, color .16s ease, box-shadow .16s ease;
    white-space: nowrap;
}

body.rxs-ui-v2 .customtab li a.nav-link i,
body.rxs-ui-v2 .nav-tabs .nav-link i {
    color: var(--rx-v2-faint);
    transition: color .16s ease;
}

body.rxs-ui-v2 .customtab li a.nav-link:hover,
body.rxs-ui-v2 .nav-tabs .nav-link:hover {
    background: var(--rx-v2-ghost);
    color: var(--rx-v2-text);
}

body.rxs-ui-v2 .customtab li a.nav-link.active,
body.rxs-ui-v2 .nav-tabs .nav-link.active {
    background: var(--rx-v2-panel);
    border: 0;
    box-shadow: 0 1px 4px rgba(0, 0, 0, .18), inset 0 0 0 1px var(--rx-v2-border);
    color: var(--rx-v2-text);
}

body.rxs-ui-v2 .customtab li a.nav-link.active i,
body.rxs-ui-v2 .nav-tabs .nav-link.active i {
    color: var(--rx-v2-accent);
}

/* transicion de contenido al cambiar de tab (solo entrada: el pane saliente
 * se oculta al instante via bootstrap, animar la salida requeriria .fade/JS) */
@keyframes rxsV2TabIn {
    from {
        opacity: 0;
        transform: translateY(5px);
    }
    to {
        opacity: 1;
        transform: none;
    }
}

body.rxs-ui-v2 .tab-content > .tab-pane.active {
    animation: rxsV2TabIn .22s ease-out;
}

@media (prefers-reduced-motion: reduce) {
    body.rxs-ui-v2 .tab-content > .tab-pane.active {
        animation: none;
    }

    body.rxs-ui-v2 .customtab li a.nav-link,
    body.rxs-ui-v2 .nav-tabs .nav-link {
        transition: none;
    }
}

/* ---- table module ---- */

body.rxs-ui-v2 .rxs-module {
    color: var(--rx-v2-text);
    display: flex;
    flex-direction: column;
    min-width: 0;
}

body.rxs-ui-v2 .rxs-module.rxs-table-module {
    background: var(--rx-v2-panel);
    border: 1px solid var(--rx-v2-border);
    border-radius: var(--rx-v2-r12);
    box-shadow: var(--rx-v2-shadow);
    overflow: hidden;
    /* clip recorta igual (las esquinas, el hairline de ::before) sin volverse contenedor de
     * scroll: con hidden, un panel lateral pegajoso adentro (.rxs-side-sticky) se anclaba al
     * modulo, que no scrollea, y no se pegaba nunca. hidden queda para un navegador sin clip. */
    overflow: clip;
}

/* firma v2: hairline degrade (colores del sitio) arriba de cada modulo de tabla;
 * primer item del flex column, el overflow:hidden lo redondea solo */
body.rxs-ui-v2 .rxs-module.rxs-table-module::before {
    background: var(--rx-v2-grad);
    content: "";
    flex: 0 0 auto;
    height: 3px;
    opacity: .9;
}

/* ---- filter bar ---- */

body.rxs-ui-v2 .rxs-module .rxs-filterbar,
body.rxs-ui-v2 .rxs-module .rxs-table-custom-filters {
    background: var(--rx-v2-panel-2);
    border-bottom: 1px solid var(--rx-v2-border);
    padding: 10px 14px;
}

body.rxs-ui-v2 .rxs-module .filtCon {
    background: transparent;
    border: 0;
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding: 0;
}

body.rxs-ui-v2 .rxs-module .allFiltersBtn {
    align-items: center;
    align-self: flex-start;
    background: var(--rx-v2-ghost) !important;
    border: 1px solid var(--rx-v2-border) !important;
    border-radius: var(--rx-v2-r8);
    box-shadow: none;
    color: var(--rx-v2-text) !important;
    display: inline-flex;
    font-size: 12.5px;
    font-weight: 600;
    gap: 7px;
    margin-bottom: 0 !important;
    min-height: 32px;
    padding: 5px 12px;
    width: auto;
}

body.rxs-ui-v2 .rxs-module .allFiltersBtn:hover {
    border-color: var(--rx-v2-accent) !important;
}

body.rxs-ui-v2 .rxs-module .allFiltersBtn .fa {
    color: var(--rx-v2-accent);
}

body.rxs-ui-v2 .rxs-module .allFilters {
    margin: 0 -4px;
    row-gap: 8px;
}

body.rxs-ui-v2 .rxs-module .allFilters.justify-content-center {
    justify-content: flex-start !important;
}

body.rxs-ui-v2 .rxs-module .rxs-filter-field {
    margin-top: 0 !important;
    padding: 0 4px;
}

body.rxs-ui-v2 .rxs-module .rxs-filter-field .input-group {
    background: var(--rx-v2-field);
    border: 1px solid var(--rx-v2-border);
    border-radius: var(--rx-v2-r8);
    flex-wrap: nowrap;
    /* height fija (no min-): el .filterReal interno mide ~50px por una linea
     * fantasma y en light inflaba la caja; dark ya la capaba en el bloque viejo
     * (body.thr-dark .filterStv .input-group) y quedaban desparejos */
    height: 38px;
    overflow: hidden;
    transition: border-color .12s ease;
}

body.rxs-ui-v2 .rxs-module .rxs-filter-field .input-group:focus-within {
    border-color: var(--rx-v2-accent);
}

body.rxs-ui-v2 .rxs-module .rxs-filter-field .input-group-prepend {
    flex: 0 0 32px;
    width: 32px;
}

body.rxs-ui-v2 .rxs-module .rxs-filter-field .input-group-text {
    background: transparent !important;
    border: 0 !important;
    border-right: 1px solid var(--rx-v2-border-soft) !important;
    border-radius: 0;
    color: var(--rx-v2-faint);
    font-size: 12px;
    justify-content: center;
    min-height: 34px;
    padding: 0;
}

body.rxs-ui-v2 .rxs-module .rxs-filter-field .filterReal {
    flex: 1 1 auto;
    min-width: 0;
}

body.rxs-ui-v2 .rxs-module .filterReal .yadcf-filter-wrapper {
    align-items: center;
    display: flex;
    width: 100%;
}

body.rxs-ui-v2 .rxs-module .filterReal .yadcf-filter-wrapper > div:first-child,
body.rxs-ui-v2 .rxs-module .filterReal .select2-container {
    flex: 1 1 auto;
    min-width: 0;
    width: 100% !important;
}

body.rxs-ui-v2 .rxs-module .filterReal input,
body.rxs-ui-v2 .rxs-module .filterReal .yadcf-filter,
body.rxs-ui-v2 .rxs-module .filterReal .select2-selection--multiple,
body.rxs-ui-v2 .rxs-module .filterReal .select2-selection--single {
    background: transparent !important;
    border: 0 !important;
    box-shadow: none !important;
    color: var(--rx-v2-text) !important;
    font-size: 13px;
    min-height: 34px !important;
    width: 100%;
}

body.rxs-ui-v2 .rxs-module .filterReal input.yadcf-filter {
    height: 34px !important;
    padding: 0 9px;
}

body.rxs-ui-v2 .rxs-module .filterReal .select2-selection__rendered,
body.rxs-ui-v2 .rxs-module .filterReal .select2-search__field {
    color: var(--rx-v2-text) !important;
}

body.rxs-ui-v2 .rxs-module .filterReal .select2-search__field::placeholder,
body.rxs-ui-v2 .rxs-module .filterReal input::placeholder {
    color: var(--rx-v2-faint);
}

body.rxs-ui-v2 .rxs-module .filterReal .yadcf-filter-reset-button {
    background: transparent;
    border: 0;
    border-radius: var(--rx-v2-r6);
    color: var(--rx-v2-faint);
    flex: 0 0 auto;
    font-size: 12px;
    height: 26px;
    margin: 0 3px;
    padding: 0;
    width: 22px;
}

body.rxs-ui-v2 .rxs-module .filterReal .yadcf-filter-reset-button:hover {
    background: var(--rx-v2-ghost);
    color: var(--rx-v2-text);
}

/* la vista Conversacion (el hilo social, rxsV2SocialFor en njs/g.js) trae su "Cargar mas":
 * el pie de la grilla (pagina, largo) no le corresponde */
body.rxs-ui-v2 .rxs-module.rxs-v2-view-social .rxs-table-footer {
    display: none !important;
}

/* la vista Carrusel (njs/rxs-carrusel.js sobre las cards, sitio-contrato-nativo.md §8.6): el riel muestra la tanda;
 * paginador, largo, info y «Cargar más» no le corresponden. El riel ocupa toda la fila del contenedor de cards. */
body.rxs-ui-v2 .rxs-module.rxs-v2-view-car .rxs-table-footer,
body.rxs-ui-v2 .rxs-v2-view-car .dataTables_paginate,
body.rxs-ui-v2 .rxs-v2-view-car .dataTables_info,
body.rxs-ui-v2 .rxs-v2-view-car .dataTables_length,
body.rxs-ui-v2 .rxs-v2-view-car .rxs-lista-mas {
    display: none !important;
}
/* el Calendario pide su propio rango (rxsV2CalFetch): el «Cargar más» de la lista de un sitio no le corresponde */
body.rxs-ui-v2 .rxs-v2-view-cal .rxs-lista-mas {
    display: none !important;
}
body.rxs-ui-v2 .rxsV2Cards > .rxs-v2-car {
    flex: 0 0 100%;
    max-width: 100%;
    width: 100%;
    min-width: 0;
}

/* ---- data panel / table ---- */

body.rxs-ui-v2 .rxs-module .rxs-data-panel {
    min-width: 0;
    overflow-x: auto;
    padding: 12px 14px;
}

/* overflow-x:auto lo hace contenedor de scroll en los dos ejes y atrapa al panel lateral pegajoso
 * (.rxs-side-sticky, njs/g_facetas.js) del hilo social: se anclaba al panel de datos y se iba con la
 * pagina. Mientras haya uno a la vista se suelta; uno adentro de una vista oculta (la de la grilla v2
 * en d-none) no cuenta, asi la tabla conserva su scroll horizontal. */
body.rxs-ui-v2 .rxs-module .rxs-data-panel:has(.rxs-side-sticky):not(:has(.d-none .rxs-side-sticky)) {
    overflow-x: clip;
}

body.rxs-ui-v2 .rxs-module .dataTables_wrapper {
    color: var(--rx-v2-text);
    padding: 0;
}

body.rxs-ui-v2 .rxs-module .dataTables_processing {
    background: var(--rx-v2-panel-2);
    border: 1px solid var(--rx-v2-border);
    border-radius: var(--rx-v2-r8);
    color: var(--rx-v2-text);
}

body.rxs-ui-v2 .rxs-module table.rxs-table {
    background: transparent;
    border: 1px solid var(--rx-v2-border-soft);
    border-collapse: separate;
    border-radius: var(--rx-v2-r10);
    border-spacing: 0;
    margin: 0 !important;
    width: 100% !important;
}

body.rxs-ui-v2 .rxs-module table.rxs-table thead th {
    background: var(--rx-v2-head) !important;
    border-bottom: 1px solid var(--rx-v2-border) !important;
    border-left: 0;
    border-right: 0;
    border-top: 0;
    color: var(--rx-v2-muted) !important;
    font-size: 10.5px;
    font-weight: 600;
    letter-spacing: .07em;
    padding: 10px 12px;
    position: sticky;
    text-transform: uppercase;
    top: 0;
    vertical-align: middle;
    white-space: nowrap;
    z-index: 3;
}

body.rxs-ui-v2 .rxs-module table.rxs-table thead th.dtfc-fixed-left {
    z-index: 4;
}

/* icono "filtrar esta columna": aparece al hover del encabezado (ui_v2.js lo
   inyecta solo en columnas que tienen filtro). Click = abrir busqueda + foco. */
body.rxs-ui-v2 .rxs-module table.rxs-table thead th .rxs-th-filter {
    color: var(--rx-v2-accent);
    cursor: pointer;
    display: inline-flex;
    font-size: 11px;
    margin-left: 6px;
    opacity: 0;
    transition: opacity .12s ease;
    vertical-align: middle;
}

body.rxs-ui-v2 .rxs-module table.rxs-table thead th:hover .rxs-th-filter {
    opacity: .65;
}

body.rxs-ui-v2 .rxs-module table.rxs-table thead th .rxs-th-filter:hover {
    opacity: 1;
}

/* --rx-rowcol es el color de estado de la fila, si el tenant declaro uno para ese estado
 * (ver el bloque "color de fila por estado" mas abajo). Sin color, el color-mix mezcla el
 * fondo consigo mismo y queda el fondo de siempre. */
body.rxs-ui-v2 .rxs-module table.rxs-table tbody tr,
body.rxs-ui-v2 .rxs-module table.rxs-table tbody tr.odd {
    background-color: color-mix(in srgb, var(--rx-rowcol, var(--rx-v2-panel)) var(--rx-v2-rowcol-mix), var(--rx-v2-panel)) !important;
}

/* zebra apenas perceptible: da ritmo de lectura sin ensuciar el panel */
body.rxs-ui-v2 .rxs-module table.rxs-table tbody tr.even {
    background-color: color-mix(in srgb, var(--rx-rowcol, var(--rx-v2-zebra)) var(--rx-v2-rowcol-mix-2), var(--rx-v2-zebra)) !important;
}

body.rxs-ui-v2 .rxs-module table.rxs-table tbody tr:hover,
body.rxs-ui-v2 .rxs-module table.rxs-table tbody tr.odd:hover,
body.rxs-ui-v2 .rxs-module table.rxs-table tbody tr.even:hover {
    background-color: color-mix(in srgb, var(--rx-rowcol, var(--rx-v2-hover)) var(--rx-v2-rowcol-mix-hover), var(--rx-v2-hover)) !important;
}

body.rxs-ui-v2 .rxs-module table.rxs-table tbody td {
    background: inherit;
    border-bottom: 1px solid var(--rx-v2-border-soft);
    border-left: 0;
    border-right: 0;
    border-top: 0;
    color: var(--rx-v2-text);
    font-size: 13px;
    font-variant-numeric: tabular-nums;
    padding: 9px 12px;
    vertical-align: middle;
}

body.rxs-ui-v2 .rxs-module table.rxs-table tbody td.dtfc-fixed-left {
    /* la columna principal (fija) un toque mas pesada: escaneo mas rapido */
    font-weight: 500;
    z-index: 1;
}

body.rxs-ui-v2 .rxs-module table.rxs-table tbody tr:last-child td {
    border-bottom: 0;
}

body.rxs-ui-v2 .rxs-module table.rxs-table .rxs-actions-th,
body.rxs-ui-v2 .rxs-module table.rxs-table .rxs-id-th,
body.rxs-ui-v2 .rxs-module table.rxs-table .rxs-tags-th {
    text-align: center;
    white-space: nowrap;
}

/* `.rxsBtns` marca DOS cosas distintas: el grupo de botones de la celda -- que va
 * como pastilla (custom.css: `border-radius:10px`, `overflow:hidden` y
 * `transition:all 1.2s` para el scale del hover) -- y el TH de esa columna, que es
 * un encabezado como cualquier otro. custom.css lo neutraliza con
 * `th.rxsBtns{border-radius:0}`, pero la regla de radios v2 (`body.rxs-ui-v2 .rxsBtns`,
 * 0-2-1) le gana por especificidad a ese `th.rxsBtns` (0-1-1) -> el encabezado de
 * acciones quedaba con 10px de radio y animando 1.2s cada cambio de fondo, mientras
 * los demas th no. Se le devuelve el aspecto de th. */
body.rxs-ui-v2 .rxs-module table.rxs-table thead th.rxsBtns {
    border-radius: 0;
    overflow: visible;
    transition: none;
}

body.rxs-ui-v2 .rxs-module table.rxs-table .badge {
    border-radius: 999px;
    font-size: 10.5px;
    font-weight: 600;
    letter-spacing: .02em;
    padding: 4px 8px;
}

body.rxs-ui-v2 .rxs-module table.rxs-table td .btn:not(:where(.rxsBtnsOwn .btn)),
body.rxs-ui-v2 .rxs-module .rxsBtns .btn:not(:where(.rxsBtnsOwn .btn)),
body.rxs-ui-v2 .rxs-search-page .rxsBtns .btn:not(:where(.rxsBtnsOwn .btn)) {
    align-items: center;
    background: var(--rx-v2-ghost) !important;
    border: 1px solid var(--rx-v2-border-soft) !important;
    border-radius: var(--rx-v2-r7);
    box-shadow: none;
    color: var(--rx-v2-muted) !important;
    display: inline-flex;
    height: 28px;
    justify-content: center;
    margin: 1px 2px;
    min-width: 28px;
    padding: 0;
    width: 28px;
}

body.rxs-ui-v2 .rxs-module table.rxs-table td .btn:not(:where(.rxsBtnsOwn .btn)):hover,
body.rxs-ui-v2 .rxs-module .rxsBtns .btn:not(:where(.rxsBtnsOwn .btn)):hover,
body.rxs-ui-v2 .rxs-search-page .rxsBtns .btn:not(:where(.rxsBtnsOwn .btn)):hover {
    background: var(--rx-v2-accent) !important;
    border-color: var(--rx-v2-accent) !important;
    color: var(--rx-v2-accent-ink) !important;
}

/* ---- dataTables footer controls ---- */

body.rxs-ui-v2 .rxs-module .dataTables_length,
body.rxs-ui-v2 .rxs-module .dataTables_filter,
body.rxs-ui-v2 .rxs-module .dataTables_info,
body.rxs-ui-v2 .rxs-module .dataTables_paginate {
    color: var(--rx-v2-muted) !important;
    font-size: 12.5px;
    padding-top: 10px;
}

body.rxs-ui-v2 .rxs-module .dataTables_length label,
body.rxs-ui-v2 .rxs-module .dataTables_filter label {
    color: var(--rx-v2-muted);
    font-weight: 500;
}

body.rxs-ui-v2 .rxs-module .dataTables_length select,
body.rxs-ui-v2 .rxs-module .dataTables_filter input {
    background: var(--rx-v2-field);
    border: 1px solid var(--rx-v2-border);
    border-radius: var(--rx-v2-r7);
    color: var(--rx-v2-text);
    margin: 0 6px;
    min-height: 30px;
    padding: 3px 8px;
}

body.rxs-ui-v2 .rxs-module .dataTables_paginate .paginate_button {
    background: transparent !important;
    border: 1px solid var(--rx-v2-border) !important;
    border-radius: var(--rx-v2-r7);
    color: var(--rx-v2-muted) !important;
    margin-left: 4px;
    min-width: 30px;
    padding: 4px 9px;
}

body.rxs-ui-v2 .rxs-module .dataTables_paginate .paginate_button:hover {
    background: var(--rx-v2-ghost) !important;
    border-color: var(--rx-v2-border) !important;
    color: var(--rx-v2-text) !important;
}

body.rxs-ui-v2 .rxs-module .dataTables_paginate .paginate_button.current,
/* con el paginado jQuery-UI (full_numbers) la pagina activa no lleva .current:
   llega como ui-state-disabled pelado — sin esta rama el boton activo queda
   blanco sobre blanco (los nav deshabilitados si traen .first/.previous/etc) */
body.rxs-ui-v2 .rxs-module .dataTables_paginate .paginate_button.ui-state-disabled:not(.first):not(.previous):not(.next):not(.last) {
    background: var(--rx-v2-accent) !important;
    border-color: var(--rx-v2-accent) !important;
    color: var(--rx-v2-accent-ink) !important;
    font-weight: 600;
}
body.rxs-ui-v2 .rxs-module .dataTables_paginate .paginate_button.ui-state-disabled.first,
body.rxs-ui-v2 .rxs-module .dataTables_paginate .paginate_button.ui-state-disabled.previous,
body.rxs-ui-v2 .rxs-module .dataTables_paginate .paginate_button.ui-state-disabled.next,
body.rxs-ui-v2 .rxs-module .dataTables_paginate .paginate_button.ui-state-disabled.last {
    opacity: .45;
    pointer-events: none;
}

/* ---- module footer (bulk actions, tags, group) ---- */

body.rxs-ui-v2 .rxs-module .row.justify-content-center:not(.allFilters):not(.listStvVue):not(.stvVueAction) {
    align-items: center;
    background: transparent;
    border: 0;
    border-top: 1px solid var(--rx-v2-border-soft);
    border-radius: 0;
    margin: 12px 0 0;
    padding: 10px 0 0;
}

body.rxs-ui-v2 .rxs-module .row.justify-content-center:not(.allFilters):not(.listStvVue):not(.stvVueAction) .btn {
    background: var(--rx-v2-ghost) !important;
    border: 1px solid var(--rx-v2-border) !important;
    border-radius: var(--rx-v2-r8);
    box-shadow: none;
    color: var(--rx-v2-muted) !important;
    min-height: 32px;
}

body.rxs-ui-v2 .rxs-module .row.justify-content-center:not(.allFilters):not(.listStvVue):not(.stvVueAction) .btn:hover {
    border-color: var(--rx-v2-accent) !important;
    color: var(--rx-v2-text) !important;
}

body.rxs-ui-v2 .rxs-module .row.justify-content-center:not(.allFilters):not(.listStvVue):not(.stvVueAction) .select2-container {
    min-width: 170px;
}

body.rxs-ui-v2 .rxs-module .row.justify-content-center:not(.allFilters):not(.listStvVue):not(.stvVueAction) .select2-selection--multiple,
body.rxs-ui-v2 .rxs-module .row.justify-content-center:not(.allFilters):not(.listStvVue):not(.stvVueAction) .select2-selection--single,
body.rxs-ui-v2 .rxs-module .row.justify-content-center:not(.allFilters):not(.listStvVue):not(.stvVueAction) select,
body.rxs-ui-v2 .rxs-module .row.justify-content-center:not(.allFilters):not(.listStvVue):not(.stvVueAction) input:not(.select2-search__field) {
    background: var(--rx-v2-field) !important;
    border: 1px solid var(--rx-v2-border) !important;
    border-radius: var(--rx-v2-r8);
    color: var(--rx-v2-text) !important;
    min-height: 32px;
}

/* ---- select2 dropdown (appended to body) ---- */

body.rxs-ui-v2 .select2-dropdown {
    background: var(--rx-v2-panel);
}

body.rxs-ui-v2 .select2-dropdown .select2-search__field {
    background: var(--rx-v2-field);
    border: 1px solid var(--rx-v2-border) !important;
    border-radius: var(--rx-v2-r6);
    color: var(--rx-v2-text);
}

body.rxs-ui-v2 .select2-results__option--highlighted[aria-selected] {
    background: var(--rx-v2-accent) !important;
    color: var(--rx-v2-accent-ink) !important;
}

body.rxs-ui-v2 .select2-selection__choice {
    background: var(--rx-v2-ghost) !important;
    border: 1px solid var(--rx-v2-border) !important;
    border-radius: var(--rx-v2-r6);
    color: var(--rx-v2-text) !important;
}
body.rxs-ui-v2 form.rxs-form {
    color: var(--rx-v2-text);
}
body.rxs-ui-v2  .input-group{
    line-height:normal;
}
body.rxs-ui-v2 form.rxs-form .rxs-form-grid {
    background: var(--rx-v2-panel);
    border: 1px solid var(--rx-v2-border);
    border-radius: var(--rx-v2-r12);
    box-shadow: var(--rx-v2-shadow);
    margin: 0;
    padding: 16px 14px;
}

body.rxs-ui-v2 form.rxs-form .rxs-form-grid .rxs-form-grid {
    border: 0;
    box-shadow: none;
    padding: 0;
}

body.rxs-ui-v2 .rxsGrupHead {
    background: var(--rx-v2-ghost);
    border-color: var(--rx-v2-border);
    border-left-color: var(--rx-v2-accent);
    color: var(--rx-v2-text);
}

body.rxs-ui-v2 .rxsGrupNum {
    background: var(--rx-v2-accent);
    color: var(--rx-v2-accent-ink);
}

/* sub-form de movimientos (fila Producto/Detalle/Cantidad/... dentro del box
   naranja de PRODUCTOS): hereda el bg de panel + radius pero con padding:0 de la
   regla de arriba, asi que los campos quedaban pegados a los bordes de la caja
   ("sin margenes"). Le devolvemos aire y lo dejamos como tarjeta de item legible.
   Los .rxs-field ya traen margin-bottom 13px -> sin padding-bottom para no doblar. */
body.rxs-ui-v2 form.rxs-form .rxsBarZone .rxs-form-grid {
    border: 1px solid var(--rx-v2-border);
    margin-top: 6px;
    padding: 13px 6px 0;
}

body.rxs-ui-v2 form.rxs-form .rxs-field {
    margin-bottom: 13px;
}
/* El ancho del CAMPO medido contra el form y no contra la pantalla (njs/g.js rxsFormAncho, que escribe data-rxs-w en el
 * form; sitio-contrato-nativo.md §8.5). Por escalon exacto: cada clase col-* hasta ese escalon vale lo que pide, y entre
 * dos clases gana la del corte mas alto (el orden de abajo), como en Bootstrap. Sin data-rxs-w (sin ResizeObserver) siguen
 * las media queries de siempre. Generado: un bloque por escalon, de xs a xl. */
form.rxs-form[data-rxs-w="xs"] .rxs-field[class*="col"]{flex:0 0 100%;max-width:100%;width:100%}
form.rxs-form[data-rxs-w="xs"] .rxs-field.col{flex:1 0 0%;max-width:100%;width:auto}form.rxs-form[data-rxs-w="xs"] .rxs-field.col-auto{flex:0 0 auto;max-width:100%;width:auto}
form.rxs-form[data-rxs-w="xs"] .rxs-field.col-1{flex:0 0 8.333333%;max-width:8.333333%;width:8.333333%}form.rxs-form[data-rxs-w="xs"] .rxs-field.col-2{flex:0 0 16.666667%;max-width:16.666667%;width:16.666667%}form.rxs-form[data-rxs-w="xs"] .rxs-field.col-3{flex:0 0 25%;max-width:25%;width:25%}form.rxs-form[data-rxs-w="xs"] .rxs-field.col-4{flex:0 0 33.333333%;max-width:33.333333%;width:33.333333%}form.rxs-form[data-rxs-w="xs"] .rxs-field.col-5{flex:0 0 41.666667%;max-width:41.666667%;width:41.666667%}form.rxs-form[data-rxs-w="xs"] .rxs-field.col-6{flex:0 0 50%;max-width:50%;width:50%}form.rxs-form[data-rxs-w="xs"] .rxs-field.col-7{flex:0 0 58.333333%;max-width:58.333333%;width:58.333333%}form.rxs-form[data-rxs-w="xs"] .rxs-field.col-8{flex:0 0 66.666667%;max-width:66.666667%;width:66.666667%}form.rxs-form[data-rxs-w="xs"] .rxs-field.col-9{flex:0 0 75%;max-width:75%;width:75%}form.rxs-form[data-rxs-w="xs"] .rxs-field.col-10{flex:0 0 83.333333%;max-width:83.333333%;width:83.333333%}form.rxs-form[data-rxs-w="xs"] .rxs-field.col-11{flex:0 0 91.666667%;max-width:91.666667%;width:91.666667%}form.rxs-form[data-rxs-w="xs"] .rxs-field.col-12{flex:0 0 100%;max-width:100%;width:100%}
form.rxs-form[data-rxs-w="sm"] .rxs-field[class*="col"]{flex:0 0 100%;max-width:100%;width:100%}
form.rxs-form[data-rxs-w="sm"] .rxs-field.col{flex:1 0 0%;max-width:100%;width:auto}form.rxs-form[data-rxs-w="sm"] .rxs-field.col-auto{flex:0 0 auto;max-width:100%;width:auto}
form.rxs-form[data-rxs-w="sm"] .rxs-field.col-1{flex:0 0 8.333333%;max-width:8.333333%;width:8.333333%}form.rxs-form[data-rxs-w="sm"] .rxs-field.col-2{flex:0 0 16.666667%;max-width:16.666667%;width:16.666667%}form.rxs-form[data-rxs-w="sm"] .rxs-field.col-3{flex:0 0 25%;max-width:25%;width:25%}form.rxs-form[data-rxs-w="sm"] .rxs-field.col-4{flex:0 0 33.333333%;max-width:33.333333%;width:33.333333%}form.rxs-form[data-rxs-w="sm"] .rxs-field.col-5{flex:0 0 41.666667%;max-width:41.666667%;width:41.666667%}form.rxs-form[data-rxs-w="sm"] .rxs-field.col-6{flex:0 0 50%;max-width:50%;width:50%}form.rxs-form[data-rxs-w="sm"] .rxs-field.col-7{flex:0 0 58.333333%;max-width:58.333333%;width:58.333333%}form.rxs-form[data-rxs-w="sm"] .rxs-field.col-8{flex:0 0 66.666667%;max-width:66.666667%;width:66.666667%}form.rxs-form[data-rxs-w="sm"] .rxs-field.col-9{flex:0 0 75%;max-width:75%;width:75%}form.rxs-form[data-rxs-w="sm"] .rxs-field.col-10{flex:0 0 83.333333%;max-width:83.333333%;width:83.333333%}form.rxs-form[data-rxs-w="sm"] .rxs-field.col-11{flex:0 0 91.666667%;max-width:91.666667%;width:91.666667%}form.rxs-form[data-rxs-w="sm"] .rxs-field.col-12{flex:0 0 100%;max-width:100%;width:100%}
form.rxs-form[data-rxs-w="sm"] .rxs-field.col-sm{flex:1 0 0%;max-width:100%;width:auto}form.rxs-form[data-rxs-w="sm"] .rxs-field.col-sm-auto{flex:0 0 auto;max-width:100%;width:auto}
form.rxs-form[data-rxs-w="sm"] .rxs-field.col-sm-1{flex:0 0 8.333333%;max-width:8.333333%;width:8.333333%}form.rxs-form[data-rxs-w="sm"] .rxs-field.col-sm-2{flex:0 0 16.666667%;max-width:16.666667%;width:16.666667%}form.rxs-form[data-rxs-w="sm"] .rxs-field.col-sm-3{flex:0 0 25%;max-width:25%;width:25%}form.rxs-form[data-rxs-w="sm"] .rxs-field.col-sm-4{flex:0 0 33.333333%;max-width:33.333333%;width:33.333333%}form.rxs-form[data-rxs-w="sm"] .rxs-field.col-sm-5{flex:0 0 41.666667%;max-width:41.666667%;width:41.666667%}form.rxs-form[data-rxs-w="sm"] .rxs-field.col-sm-6{flex:0 0 50%;max-width:50%;width:50%}form.rxs-form[data-rxs-w="sm"] .rxs-field.col-sm-7{flex:0 0 58.333333%;max-width:58.333333%;width:58.333333%}form.rxs-form[data-rxs-w="sm"] .rxs-field.col-sm-8{flex:0 0 66.666667%;max-width:66.666667%;width:66.666667%}form.rxs-form[data-rxs-w="sm"] .rxs-field.col-sm-9{flex:0 0 75%;max-width:75%;width:75%}form.rxs-form[data-rxs-w="sm"] .rxs-field.col-sm-10{flex:0 0 83.333333%;max-width:83.333333%;width:83.333333%}form.rxs-form[data-rxs-w="sm"] .rxs-field.col-sm-11{flex:0 0 91.666667%;max-width:91.666667%;width:91.666667%}form.rxs-form[data-rxs-w="sm"] .rxs-field.col-sm-12{flex:0 0 100%;max-width:100%;width:100%}
form.rxs-form[data-rxs-w="md"] .rxs-field[class*="col"]{flex:0 0 100%;max-width:100%;width:100%}
form.rxs-form[data-rxs-w="md"] .rxs-field.col{flex:1 0 0%;max-width:100%;width:auto}form.rxs-form[data-rxs-w="md"] .rxs-field.col-auto{flex:0 0 auto;max-width:100%;width:auto}
form.rxs-form[data-rxs-w="md"] .rxs-field.col-1{flex:0 0 8.333333%;max-width:8.333333%;width:8.333333%}form.rxs-form[data-rxs-w="md"] .rxs-field.col-2{flex:0 0 16.666667%;max-width:16.666667%;width:16.666667%}form.rxs-form[data-rxs-w="md"] .rxs-field.col-3{flex:0 0 25%;max-width:25%;width:25%}form.rxs-form[data-rxs-w="md"] .rxs-field.col-4{flex:0 0 33.333333%;max-width:33.333333%;width:33.333333%}form.rxs-form[data-rxs-w="md"] .rxs-field.col-5{flex:0 0 41.666667%;max-width:41.666667%;width:41.666667%}form.rxs-form[data-rxs-w="md"] .rxs-field.col-6{flex:0 0 50%;max-width:50%;width:50%}form.rxs-form[data-rxs-w="md"] .rxs-field.col-7{flex:0 0 58.333333%;max-width:58.333333%;width:58.333333%}form.rxs-form[data-rxs-w="md"] .rxs-field.col-8{flex:0 0 66.666667%;max-width:66.666667%;width:66.666667%}form.rxs-form[data-rxs-w="md"] .rxs-field.col-9{flex:0 0 75%;max-width:75%;width:75%}form.rxs-form[data-rxs-w="md"] .rxs-field.col-10{flex:0 0 83.333333%;max-width:83.333333%;width:83.333333%}form.rxs-form[data-rxs-w="md"] .rxs-field.col-11{flex:0 0 91.666667%;max-width:91.666667%;width:91.666667%}form.rxs-form[data-rxs-w="md"] .rxs-field.col-12{flex:0 0 100%;max-width:100%;width:100%}
form.rxs-form[data-rxs-w="md"] .rxs-field.col-sm{flex:1 0 0%;max-width:100%;width:auto}form.rxs-form[data-rxs-w="md"] .rxs-field.col-sm-auto{flex:0 0 auto;max-width:100%;width:auto}
form.rxs-form[data-rxs-w="md"] .rxs-field.col-sm-1{flex:0 0 8.333333%;max-width:8.333333%;width:8.333333%}form.rxs-form[data-rxs-w="md"] .rxs-field.col-sm-2{flex:0 0 16.666667%;max-width:16.666667%;width:16.666667%}form.rxs-form[data-rxs-w="md"] .rxs-field.col-sm-3{flex:0 0 25%;max-width:25%;width:25%}form.rxs-form[data-rxs-w="md"] .rxs-field.col-sm-4{flex:0 0 33.333333%;max-width:33.333333%;width:33.333333%}form.rxs-form[data-rxs-w="md"] .rxs-field.col-sm-5{flex:0 0 41.666667%;max-width:41.666667%;width:41.666667%}form.rxs-form[data-rxs-w="md"] .rxs-field.col-sm-6{flex:0 0 50%;max-width:50%;width:50%}form.rxs-form[data-rxs-w="md"] .rxs-field.col-sm-7{flex:0 0 58.333333%;max-width:58.333333%;width:58.333333%}form.rxs-form[data-rxs-w="md"] .rxs-field.col-sm-8{flex:0 0 66.666667%;max-width:66.666667%;width:66.666667%}form.rxs-form[data-rxs-w="md"] .rxs-field.col-sm-9{flex:0 0 75%;max-width:75%;width:75%}form.rxs-form[data-rxs-w="md"] .rxs-field.col-sm-10{flex:0 0 83.333333%;max-width:83.333333%;width:83.333333%}form.rxs-form[data-rxs-w="md"] .rxs-field.col-sm-11{flex:0 0 91.666667%;max-width:91.666667%;width:91.666667%}form.rxs-form[data-rxs-w="md"] .rxs-field.col-sm-12{flex:0 0 100%;max-width:100%;width:100%}
form.rxs-form[data-rxs-w="md"] .rxs-field.col-md{flex:1 0 0%;max-width:100%;width:auto}form.rxs-form[data-rxs-w="md"] .rxs-field.col-md-auto{flex:0 0 auto;max-width:100%;width:auto}
form.rxs-form[data-rxs-w="md"] .rxs-field.col-md-1{flex:0 0 8.333333%;max-width:8.333333%;width:8.333333%}form.rxs-form[data-rxs-w="md"] .rxs-field.col-md-2{flex:0 0 16.666667%;max-width:16.666667%;width:16.666667%}form.rxs-form[data-rxs-w="md"] .rxs-field.col-md-3{flex:0 0 25%;max-width:25%;width:25%}form.rxs-form[data-rxs-w="md"] .rxs-field.col-md-4{flex:0 0 33.333333%;max-width:33.333333%;width:33.333333%}form.rxs-form[data-rxs-w="md"] .rxs-field.col-md-5{flex:0 0 41.666667%;max-width:41.666667%;width:41.666667%}form.rxs-form[data-rxs-w="md"] .rxs-field.col-md-6{flex:0 0 50%;max-width:50%;width:50%}form.rxs-form[data-rxs-w="md"] .rxs-field.col-md-7{flex:0 0 58.333333%;max-width:58.333333%;width:58.333333%}form.rxs-form[data-rxs-w="md"] .rxs-field.col-md-8{flex:0 0 66.666667%;max-width:66.666667%;width:66.666667%}form.rxs-form[data-rxs-w="md"] .rxs-field.col-md-9{flex:0 0 75%;max-width:75%;width:75%}form.rxs-form[data-rxs-w="md"] .rxs-field.col-md-10{flex:0 0 83.333333%;max-width:83.333333%;width:83.333333%}form.rxs-form[data-rxs-w="md"] .rxs-field.col-md-11{flex:0 0 91.666667%;max-width:91.666667%;width:91.666667%}form.rxs-form[data-rxs-w="md"] .rxs-field.col-md-12{flex:0 0 100%;max-width:100%;width:100%}
form.rxs-form[data-rxs-w="lg"] .rxs-field[class*="col"]{flex:0 0 100%;max-width:100%;width:100%}
form.rxs-form[data-rxs-w="lg"] .rxs-field.col{flex:1 0 0%;max-width:100%;width:auto}form.rxs-form[data-rxs-w="lg"] .rxs-field.col-auto{flex:0 0 auto;max-width:100%;width:auto}
form.rxs-form[data-rxs-w="lg"] .rxs-field.col-1{flex:0 0 8.333333%;max-width:8.333333%;width:8.333333%}form.rxs-form[data-rxs-w="lg"] .rxs-field.col-2{flex:0 0 16.666667%;max-width:16.666667%;width:16.666667%}form.rxs-form[data-rxs-w="lg"] .rxs-field.col-3{flex:0 0 25%;max-width:25%;width:25%}form.rxs-form[data-rxs-w="lg"] .rxs-field.col-4{flex:0 0 33.333333%;max-width:33.333333%;width:33.333333%}form.rxs-form[data-rxs-w="lg"] .rxs-field.col-5{flex:0 0 41.666667%;max-width:41.666667%;width:41.666667%}form.rxs-form[data-rxs-w="lg"] .rxs-field.col-6{flex:0 0 50%;max-width:50%;width:50%}form.rxs-form[data-rxs-w="lg"] .rxs-field.col-7{flex:0 0 58.333333%;max-width:58.333333%;width:58.333333%}form.rxs-form[data-rxs-w="lg"] .rxs-field.col-8{flex:0 0 66.666667%;max-width:66.666667%;width:66.666667%}form.rxs-form[data-rxs-w="lg"] .rxs-field.col-9{flex:0 0 75%;max-width:75%;width:75%}form.rxs-form[data-rxs-w="lg"] .rxs-field.col-10{flex:0 0 83.333333%;max-width:83.333333%;width:83.333333%}form.rxs-form[data-rxs-w="lg"] .rxs-field.col-11{flex:0 0 91.666667%;max-width:91.666667%;width:91.666667%}form.rxs-form[data-rxs-w="lg"] .rxs-field.col-12{flex:0 0 100%;max-width:100%;width:100%}
form.rxs-form[data-rxs-w="lg"] .rxs-field.col-sm{flex:1 0 0%;max-width:100%;width:auto}form.rxs-form[data-rxs-w="lg"] .rxs-field.col-sm-auto{flex:0 0 auto;max-width:100%;width:auto}
form.rxs-form[data-rxs-w="lg"] .rxs-field.col-sm-1{flex:0 0 8.333333%;max-width:8.333333%;width:8.333333%}form.rxs-form[data-rxs-w="lg"] .rxs-field.col-sm-2{flex:0 0 16.666667%;max-width:16.666667%;width:16.666667%}form.rxs-form[data-rxs-w="lg"] .rxs-field.col-sm-3{flex:0 0 25%;max-width:25%;width:25%}form.rxs-form[data-rxs-w="lg"] .rxs-field.col-sm-4{flex:0 0 33.333333%;max-width:33.333333%;width:33.333333%}form.rxs-form[data-rxs-w="lg"] .rxs-field.col-sm-5{flex:0 0 41.666667%;max-width:41.666667%;width:41.666667%}form.rxs-form[data-rxs-w="lg"] .rxs-field.col-sm-6{flex:0 0 50%;max-width:50%;width:50%}form.rxs-form[data-rxs-w="lg"] .rxs-field.col-sm-7{flex:0 0 58.333333%;max-width:58.333333%;width:58.333333%}form.rxs-form[data-rxs-w="lg"] .rxs-field.col-sm-8{flex:0 0 66.666667%;max-width:66.666667%;width:66.666667%}form.rxs-form[data-rxs-w="lg"] .rxs-field.col-sm-9{flex:0 0 75%;max-width:75%;width:75%}form.rxs-form[data-rxs-w="lg"] .rxs-field.col-sm-10{flex:0 0 83.333333%;max-width:83.333333%;width:83.333333%}form.rxs-form[data-rxs-w="lg"] .rxs-field.col-sm-11{flex:0 0 91.666667%;max-width:91.666667%;width:91.666667%}form.rxs-form[data-rxs-w="lg"] .rxs-field.col-sm-12{flex:0 0 100%;max-width:100%;width:100%}
form.rxs-form[data-rxs-w="lg"] .rxs-field.col-md{flex:1 0 0%;max-width:100%;width:auto}form.rxs-form[data-rxs-w="lg"] .rxs-field.col-md-auto{flex:0 0 auto;max-width:100%;width:auto}
form.rxs-form[data-rxs-w="lg"] .rxs-field.col-md-1{flex:0 0 8.333333%;max-width:8.333333%;width:8.333333%}form.rxs-form[data-rxs-w="lg"] .rxs-field.col-md-2{flex:0 0 16.666667%;max-width:16.666667%;width:16.666667%}form.rxs-form[data-rxs-w="lg"] .rxs-field.col-md-3{flex:0 0 25%;max-width:25%;width:25%}form.rxs-form[data-rxs-w="lg"] .rxs-field.col-md-4{flex:0 0 33.333333%;max-width:33.333333%;width:33.333333%}form.rxs-form[data-rxs-w="lg"] .rxs-field.col-md-5{flex:0 0 41.666667%;max-width:41.666667%;width:41.666667%}form.rxs-form[data-rxs-w="lg"] .rxs-field.col-md-6{flex:0 0 50%;max-width:50%;width:50%}form.rxs-form[data-rxs-w="lg"] .rxs-field.col-md-7{flex:0 0 58.333333%;max-width:58.333333%;width:58.333333%}form.rxs-form[data-rxs-w="lg"] .rxs-field.col-md-8{flex:0 0 66.666667%;max-width:66.666667%;width:66.666667%}form.rxs-form[data-rxs-w="lg"] .rxs-field.col-md-9{flex:0 0 75%;max-width:75%;width:75%}form.rxs-form[data-rxs-w="lg"] .rxs-field.col-md-10{flex:0 0 83.333333%;max-width:83.333333%;width:83.333333%}form.rxs-form[data-rxs-w="lg"] .rxs-field.col-md-11{flex:0 0 91.666667%;max-width:91.666667%;width:91.666667%}form.rxs-form[data-rxs-w="lg"] .rxs-field.col-md-12{flex:0 0 100%;max-width:100%;width:100%}
form.rxs-form[data-rxs-w="lg"] .rxs-field.col-lg{flex:1 0 0%;max-width:100%;width:auto}form.rxs-form[data-rxs-w="lg"] .rxs-field.col-lg-auto{flex:0 0 auto;max-width:100%;width:auto}
form.rxs-form[data-rxs-w="lg"] .rxs-field.col-lg-1{flex:0 0 8.333333%;max-width:8.333333%;width:8.333333%}form.rxs-form[data-rxs-w="lg"] .rxs-field.col-lg-2{flex:0 0 16.666667%;max-width:16.666667%;width:16.666667%}form.rxs-form[data-rxs-w="lg"] .rxs-field.col-lg-3{flex:0 0 25%;max-width:25%;width:25%}form.rxs-form[data-rxs-w="lg"] .rxs-field.col-lg-4{flex:0 0 33.333333%;max-width:33.333333%;width:33.333333%}form.rxs-form[data-rxs-w="lg"] .rxs-field.col-lg-5{flex:0 0 41.666667%;max-width:41.666667%;width:41.666667%}form.rxs-form[data-rxs-w="lg"] .rxs-field.col-lg-6{flex:0 0 50%;max-width:50%;width:50%}form.rxs-form[data-rxs-w="lg"] .rxs-field.col-lg-7{flex:0 0 58.333333%;max-width:58.333333%;width:58.333333%}form.rxs-form[data-rxs-w="lg"] .rxs-field.col-lg-8{flex:0 0 66.666667%;max-width:66.666667%;width:66.666667%}form.rxs-form[data-rxs-w="lg"] .rxs-field.col-lg-9{flex:0 0 75%;max-width:75%;width:75%}form.rxs-form[data-rxs-w="lg"] .rxs-field.col-lg-10{flex:0 0 83.333333%;max-width:83.333333%;width:83.333333%}form.rxs-form[data-rxs-w="lg"] .rxs-field.col-lg-11{flex:0 0 91.666667%;max-width:91.666667%;width:91.666667%}form.rxs-form[data-rxs-w="lg"] .rxs-field.col-lg-12{flex:0 0 100%;max-width:100%;width:100%}
form.rxs-form[data-rxs-w="xl"] .rxs-field[class*="col"]{flex:0 0 100%;max-width:100%;width:100%}
form.rxs-form[data-rxs-w="xl"] .rxs-field.col{flex:1 0 0%;max-width:100%;width:auto}form.rxs-form[data-rxs-w="xl"] .rxs-field.col-auto{flex:0 0 auto;max-width:100%;width:auto}
form.rxs-form[data-rxs-w="xl"] .rxs-field.col-1{flex:0 0 8.333333%;max-width:8.333333%;width:8.333333%}form.rxs-form[data-rxs-w="xl"] .rxs-field.col-2{flex:0 0 16.666667%;max-width:16.666667%;width:16.666667%}form.rxs-form[data-rxs-w="xl"] .rxs-field.col-3{flex:0 0 25%;max-width:25%;width:25%}form.rxs-form[data-rxs-w="xl"] .rxs-field.col-4{flex:0 0 33.333333%;max-width:33.333333%;width:33.333333%}form.rxs-form[data-rxs-w="xl"] .rxs-field.col-5{flex:0 0 41.666667%;max-width:41.666667%;width:41.666667%}form.rxs-form[data-rxs-w="xl"] .rxs-field.col-6{flex:0 0 50%;max-width:50%;width:50%}form.rxs-form[data-rxs-w="xl"] .rxs-field.col-7{flex:0 0 58.333333%;max-width:58.333333%;width:58.333333%}form.rxs-form[data-rxs-w="xl"] .rxs-field.col-8{flex:0 0 66.666667%;max-width:66.666667%;width:66.666667%}form.rxs-form[data-rxs-w="xl"] .rxs-field.col-9{flex:0 0 75%;max-width:75%;width:75%}form.rxs-form[data-rxs-w="xl"] .rxs-field.col-10{flex:0 0 83.333333%;max-width:83.333333%;width:83.333333%}form.rxs-form[data-rxs-w="xl"] .rxs-field.col-11{flex:0 0 91.666667%;max-width:91.666667%;width:91.666667%}form.rxs-form[data-rxs-w="xl"] .rxs-field.col-12{flex:0 0 100%;max-width:100%;width:100%}
form.rxs-form[data-rxs-w="xl"] .rxs-field.col-sm{flex:1 0 0%;max-width:100%;width:auto}form.rxs-form[data-rxs-w="xl"] .rxs-field.col-sm-auto{flex:0 0 auto;max-width:100%;width:auto}
form.rxs-form[data-rxs-w="xl"] .rxs-field.col-sm-1{flex:0 0 8.333333%;max-width:8.333333%;width:8.333333%}form.rxs-form[data-rxs-w="xl"] .rxs-field.col-sm-2{flex:0 0 16.666667%;max-width:16.666667%;width:16.666667%}form.rxs-form[data-rxs-w="xl"] .rxs-field.col-sm-3{flex:0 0 25%;max-width:25%;width:25%}form.rxs-form[data-rxs-w="xl"] .rxs-field.col-sm-4{flex:0 0 33.333333%;max-width:33.333333%;width:33.333333%}form.rxs-form[data-rxs-w="xl"] .rxs-field.col-sm-5{flex:0 0 41.666667%;max-width:41.666667%;width:41.666667%}form.rxs-form[data-rxs-w="xl"] .rxs-field.col-sm-6{flex:0 0 50%;max-width:50%;width:50%}form.rxs-form[data-rxs-w="xl"] .rxs-field.col-sm-7{flex:0 0 58.333333%;max-width:58.333333%;width:58.333333%}form.rxs-form[data-rxs-w="xl"] .rxs-field.col-sm-8{flex:0 0 66.666667%;max-width:66.666667%;width:66.666667%}form.rxs-form[data-rxs-w="xl"] .rxs-field.col-sm-9{flex:0 0 75%;max-width:75%;width:75%}form.rxs-form[data-rxs-w="xl"] .rxs-field.col-sm-10{flex:0 0 83.333333%;max-width:83.333333%;width:83.333333%}form.rxs-form[data-rxs-w="xl"] .rxs-field.col-sm-11{flex:0 0 91.666667%;max-width:91.666667%;width:91.666667%}form.rxs-form[data-rxs-w="xl"] .rxs-field.col-sm-12{flex:0 0 100%;max-width:100%;width:100%}
form.rxs-form[data-rxs-w="xl"] .rxs-field.col-md{flex:1 0 0%;max-width:100%;width:auto}form.rxs-form[data-rxs-w="xl"] .rxs-field.col-md-auto{flex:0 0 auto;max-width:100%;width:auto}
form.rxs-form[data-rxs-w="xl"] .rxs-field.col-md-1{flex:0 0 8.333333%;max-width:8.333333%;width:8.333333%}form.rxs-form[data-rxs-w="xl"] .rxs-field.col-md-2{flex:0 0 16.666667%;max-width:16.666667%;width:16.666667%}form.rxs-form[data-rxs-w="xl"] .rxs-field.col-md-3{flex:0 0 25%;max-width:25%;width:25%}form.rxs-form[data-rxs-w="xl"] .rxs-field.col-md-4{flex:0 0 33.333333%;max-width:33.333333%;width:33.333333%}form.rxs-form[data-rxs-w="xl"] .rxs-field.col-md-5{flex:0 0 41.666667%;max-width:41.666667%;width:41.666667%}form.rxs-form[data-rxs-w="xl"] .rxs-field.col-md-6{flex:0 0 50%;max-width:50%;width:50%}form.rxs-form[data-rxs-w="xl"] .rxs-field.col-md-7{flex:0 0 58.333333%;max-width:58.333333%;width:58.333333%}form.rxs-form[data-rxs-w="xl"] .rxs-field.col-md-8{flex:0 0 66.666667%;max-width:66.666667%;width:66.666667%}form.rxs-form[data-rxs-w="xl"] .rxs-field.col-md-9{flex:0 0 75%;max-width:75%;width:75%}form.rxs-form[data-rxs-w="xl"] .rxs-field.col-md-10{flex:0 0 83.333333%;max-width:83.333333%;width:83.333333%}form.rxs-form[data-rxs-w="xl"] .rxs-field.col-md-11{flex:0 0 91.666667%;max-width:91.666667%;width:91.666667%}form.rxs-form[data-rxs-w="xl"] .rxs-field.col-md-12{flex:0 0 100%;max-width:100%;width:100%}
form.rxs-form[data-rxs-w="xl"] .rxs-field.col-lg{flex:1 0 0%;max-width:100%;width:auto}form.rxs-form[data-rxs-w="xl"] .rxs-field.col-lg-auto{flex:0 0 auto;max-width:100%;width:auto}
form.rxs-form[data-rxs-w="xl"] .rxs-field.col-lg-1{flex:0 0 8.333333%;max-width:8.333333%;width:8.333333%}form.rxs-form[data-rxs-w="xl"] .rxs-field.col-lg-2{flex:0 0 16.666667%;max-width:16.666667%;width:16.666667%}form.rxs-form[data-rxs-w="xl"] .rxs-field.col-lg-3{flex:0 0 25%;max-width:25%;width:25%}form.rxs-form[data-rxs-w="xl"] .rxs-field.col-lg-4{flex:0 0 33.333333%;max-width:33.333333%;width:33.333333%}form.rxs-form[data-rxs-w="xl"] .rxs-field.col-lg-5{flex:0 0 41.666667%;max-width:41.666667%;width:41.666667%}form.rxs-form[data-rxs-w="xl"] .rxs-field.col-lg-6{flex:0 0 50%;max-width:50%;width:50%}form.rxs-form[data-rxs-w="xl"] .rxs-field.col-lg-7{flex:0 0 58.333333%;max-width:58.333333%;width:58.333333%}form.rxs-form[data-rxs-w="xl"] .rxs-field.col-lg-8{flex:0 0 66.666667%;max-width:66.666667%;width:66.666667%}form.rxs-form[data-rxs-w="xl"] .rxs-field.col-lg-9{flex:0 0 75%;max-width:75%;width:75%}form.rxs-form[data-rxs-w="xl"] .rxs-field.col-lg-10{flex:0 0 83.333333%;max-width:83.333333%;width:83.333333%}form.rxs-form[data-rxs-w="xl"] .rxs-field.col-lg-11{flex:0 0 91.666667%;max-width:91.666667%;width:91.666667%}form.rxs-form[data-rxs-w="xl"] .rxs-field.col-lg-12{flex:0 0 100%;max-width:100%;width:100%}
form.rxs-form[data-rxs-w="xl"] .rxs-field.col-xl{flex:1 0 0%;max-width:100%;width:auto}form.rxs-form[data-rxs-w="xl"] .rxs-field.col-xl-auto{flex:0 0 auto;max-width:100%;width:auto}
form.rxs-form[data-rxs-w="xl"] .rxs-field.col-xl-1{flex:0 0 8.333333%;max-width:8.333333%;width:8.333333%}form.rxs-form[data-rxs-w="xl"] .rxs-field.col-xl-2{flex:0 0 16.666667%;max-width:16.666667%;width:16.666667%}form.rxs-form[data-rxs-w="xl"] .rxs-field.col-xl-3{flex:0 0 25%;max-width:25%;width:25%}form.rxs-form[data-rxs-w="xl"] .rxs-field.col-xl-4{flex:0 0 33.333333%;max-width:33.333333%;width:33.333333%}form.rxs-form[data-rxs-w="xl"] .rxs-field.col-xl-5{flex:0 0 41.666667%;max-width:41.666667%;width:41.666667%}form.rxs-form[data-rxs-w="xl"] .rxs-field.col-xl-6{flex:0 0 50%;max-width:50%;width:50%}form.rxs-form[data-rxs-w="xl"] .rxs-field.col-xl-7{flex:0 0 58.333333%;max-width:58.333333%;width:58.333333%}form.rxs-form[data-rxs-w="xl"] .rxs-field.col-xl-8{flex:0 0 66.666667%;max-width:66.666667%;width:66.666667%}form.rxs-form[data-rxs-w="xl"] .rxs-field.col-xl-9{flex:0 0 75%;max-width:75%;width:75%}form.rxs-form[data-rxs-w="xl"] .rxs-field.col-xl-10{flex:0 0 83.333333%;max-width:83.333333%;width:83.333333%}form.rxs-form[data-rxs-w="xl"] .rxs-field.col-xl-11{flex:0 0 91.666667%;max-width:91.666667%;width:91.666667%}form.rxs-form[data-rxs-w="xl"] .rxs-field.col-xl-12{flex:0 0 100%;max-width:100%;width:100%}


body.rxs-ui-v2 form.rxs-form .rxs-field > label {
    color: var(--rx-v2-muted);
    display: block;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .05em;
    margin-bottom: 5px;
    text-transform: uppercase;
}

body.rxs-ui-v2 form.rxs-form .rxs-field .form-control,
body.rxs-ui-v2 form.rxs-form .rxs-field select,
body.rxs-ui-v2 form.rxs-form .rxs-field textarea,
body.rxs-ui-v2 form.rxs-form .rxs-field .select2-selection--single,
body.rxs-ui-v2 form.rxs-form .rxs-field .select2-selection--multiple {
    background: var(--rx-v2-field) !important;
    border: 1px solid var(--rx-v2-border) !important;
    border-radius: var(--rx-v2-r8);
    color: var(--rx-v2-text) !important;
    font-size: 13.5px;
    min-height: 38px;
    transition: border-color .12s ease, box-shadow .12s ease;
}

body.rxs-ui-v2 form.rxs-form .rxs-field .form-control:focus,
body.rxs-ui-v2 form.rxs-form .rxs-field select:focus,
body.rxs-ui-v2 form.rxs-form .rxs-field textarea:focus {
    border-color: var(--rx-v2-accent) !important;
    box-shadow: 0 0 0 3px var(--rx-v2-accent-soft) !important;
    outline: 0;
}

/* Chrome: un <select> NATIVO con `transition` necesita 2 clicks para abrir el popup
 * (el :focus dispara la transition de border/shadow y el navegador se traga el primer
 * open). Sin transition en el select nativo -> abre a la primera. No aplica a
 * inputs/textarea (mantienen el fade) ni a select2 (es un div, el <select> real va
 * oculto). */
body.rxs-ui-v2 form.rxs-form .rxs-field select {
    transition: none !important;
}

/* has-error: las reglas con #maincontent (ID) ganan sobre las de clase pura;
 * se replica el ID en los selectores para restaurar el borde rojo.
 * El validador le pone la clase al PADRE DIRECTO del control, que con prepend de
 * icono es el .input-group, no el .rxs-field -> se ancla en .has-error a secas
 * (descendiente), igual que la regla vieja de custom.css, y no en .rxs-field.
 * La clase va repetida (.has-error.has-error) a proposito: la regla generica de
 * campos sueltos de mas abajo (`#maincontent select:not(...):not(...)`) suma dos
 * clases y pisaba el borde rojo con su `border:` shorthand !important. */
body.rxs-ui-v2 #maincontent .has-error.has-error .form-control,
body.rxs-ui-v2 #maincontent .has-error.has-error select,
body.rxs-ui-v2 #maincontent .has-error.has-error textarea,
body.rxs-ui-v2 #maincontent .has-error.has-error .select2-selection--single,
body.rxs-ui-v2 #maincontent .has-error.has-error .select2-selection--multiple,
body.rxs-ui-v2 #maincontent .has-error.has-error .file-drop-zone {
    border-color: #fc4b6c !important;
}
body.rxs-ui-v2 form.rxs-form .rxs-field.has-error > label {
    color: #fc4b6c !important;
}
body.rxs-ui-v2 #maincontent .has-success.has-success .form-control,
body.rxs-ui-v2 #maincontent .has-success.has-success select,
body.rxs-ui-v2 #maincontent .has-success.has-success textarea,
body.rxs-ui-v2 #maincontent .has-success.has-success .select2-selection--single,
body.rxs-ui-v2 #maincontent .has-success.has-success .select2-selection--multiple {
    border-color: #28a745 !important;
}
body.rxs-ui-v2 form.rxs-form .rxs-field.has-success > label {
    color: #28a745 !important;
}

/* el .input-group NO lleva fondo propio: como es un pelin mas alto/ancho que el
 * control interno, su fondo asomaba detras como un "sub-fondo"/halo. El fondo lo
 * ponen los hijos (prepend + control), cada uno con --rx-v2-field. */
body.rxs-ui-v2 form.rxs-form .rxs-field .input-group {
    background: transparent;
    border-radius: var(--rx-v2-r8);
}

body.rxs-ui-v2 form.rxs-form .rxs-field .input-group-text {
    background: var(--rx-v2-field) !important;
    border: 1px solid var(--rx-v2-border) !important;
    border-radius: var(--rx-v2-r8) 0 0 var(--rx-v2-r8);
    color: var(--rx-v2-faint);
}

body.rxs-ui-v2 form.rxs-form .rxs-field .help-block {
    color: var(--rx-v2-faint);
    font-size: 12px;
    margin-top: 5px;
}

body.rxs-ui-v2 form.rxs-form[data-mode="view"] .rxs-field .form-control,
body.rxs-ui-v2 form.rxs-form[data-mode="viewr"] .rxs-field .form-control {
    background: var(--rx-v2-ghost) !important;
    border-color: var(--rx-v2-border-soft) !important;
}

/* ---- mobile ---- */

@media (max-width: 767px) {
    body.rxs-ui-v2 #maincontent.container-fluid,
    body.rxs-ui-v2.horizontal #maincontent.container {
        padding: 14px 12px 112px;
    }

    body.rxs-ui-v2 .topbar .top-navbar {
        min-height: 56px;
    }

    body.rxs-ui-v2 .topbar .navbar-brand.logo {
        min-height: 56px;
    }

    body.rxs-ui-v2 .topbar .navbar-brand.logo img {
        max-height: 48px;
    }

    body.rxs-ui-v2 .nav-tabs-custom.card {
        margin-bottom: 72px;
    }

    body.rxs-ui-v2 .customtab,
    body.rxs-ui-v2 .nav-tabs {
        flex-wrap: nowrap;
        overflow-x: auto;
        padding: 4px;
    }

    /* la barra fija de abajo (dock) va de borde a borde, sin flotar */
    body.rxs-ui-v2 #maincontent > .stvModuleTable > .nav-tabs-custom > .nav.customtab,
    body.rxs-ui-v2 #maincontent > .stvModuleTable > .nav-tabs-custom > #tabtabs > .nav.customtab {
        background: var(--rx-v2-shell);
        border: 0;
        border-radius: 0;
        border-top: 1px solid var(--rx-v2-border);
        display: flex;
        margin-bottom: 0;
        max-width: none;
        width: 100%;
    }

    body.rxs-ui-v2 .customtab li a.nav-link,
    body.rxs-ui-v2 .nav-tabs .nav-link {
        min-height: 44px;
        padding: 11px 12px;
        white-space: nowrap;
    }

    body.rxs-ui-v2 .rxs-module.rxs-table-module,
    body.rxs-ui-v2 form.rxs-form .rxs-form-grid {
        border-radius: var(--rx-v2-r10);
    }

    body.rxs-ui-v2 .rxs-module .rxs-filterbar {
        padding: 10px 12px;
    }

    body.rxs-ui-v2 .rxs-module .rxs-data-panel {
        padding: 10px 12px;
    }

    body.rxs-ui-v2 .rxs-module table.rxs-table tbody td {
        padding: 8px 10px;
    }

    body.rxs-ui-v2 .rxs-module table.rxs-table td .btn:not(:where(.rxsBtnsOwn .btn)),
    body.rxs-ui-v2 .rxs-module .rxsBtns .btn:not(:where(.rxsBtnsOwn .btn)) {
        height: 28px;
        min-width: 28px;
        width: 28px;
    }

    body.rxs-ui-v2 .rxs-module .row.justify-content-center:not(.allFilters):not(.listStvVue):not(.stvVueAction) {
        display: grid !important;
        gap: 6px;
        grid-template-columns: repeat(2, minmax(0, 1fr));
        padding: 10px 0 0;
    }

    body.rxs-ui-v2 .rxs-module .row.justify-content-center:not(.allFilters):not(.listStvVue):not(.stvVueAction) > [class*="col-"] {
        flex: none;
        max-width: none;
        width: 100%;
    }

    body.rxs-ui-v2 .rxs-module .row.justify-content-center:not(.allFilters):not(.listStvVue):not(.stvVueAction) .btn {
        font-size: 12px;
        min-height: 36px;
        white-space: normal;
    }
}

/* ---- pantallas bajas (telefono apaisado) ----------------------------------
 * En apaisado el alto es lo unico que escasea y el ancho sobra, asi que la
 * cuenta se hace por max-height, no por max-width: un 667x375 ya entra en el
 * bloque mobile de arriba, ampliarlo no cambiaria nada.
 *
 * Medido en 667x375 con el calendario: de 375px de viewport, 57 se los llevaba
 * la topbar, 34 los paddings apilados de arriba (#maincontent 14 + el pane 14)
 * y 68 el dock de abajo. Al calendario le quedaban 108px, y 23 con los filtros
 * desplegados. Aca se recorta el aire vertical -no el horizontal, que sobra- y
 * el dock pasa a la mitad de alto sin perder ancho de target. */
@media (max-height: 500px) {
    body.rxs-ui-v2 #maincontent.container-fluid,
    body.rxs-ui-v2.horizontal #maincontent.container {
        padding-top: 8px;
    }

    body.rxs-ui-v2 .tab-content > #tab_graphs,
    body.rxs-ui-v2 .tab-content > [id^="tab_excel"],
    body.rxs-ui-v2 .tab-content > #tab_ds,
    body.rxs-ui-v2 .tab-content > #tab_calendar,
    body.rxs-ui-v2 .tab-content > .tab-pane:has(.fc) {
        padding: 8px;
    }
}

@media (max-width: 767px) and (max-height: 500px) {
    /* el dock conserva el ancho de target (que es el que se toca con el pulgar)
       y cede alto: 68px -> ~40px */
    body.rxs-ui-v2 .customtab li a.nav-link,
    body.rxs-ui-v2 .nav-tabs .nav-link {
        min-height: 34px;
        padding: 5px 12px;
    }

    body.rxs-ui-v2 .customtab,
    body.rxs-ui-v2 .nav-tabs {
        padding: 2px 4px;
    }

    /* los reservados para el dock, al alto real que pasa a tener */
    body.rxs-ui-v2 #maincontent.container-fluid,
    body.rxs-ui-v2.horizontal #maincontent.container {
        padding-bottom: 64px;
    }

    body.rxs-ui-v2 .nav-tabs-custom.card {
        margin-bottom: 48px;
    }
}

/* ---- v2 fixes: sticky column + dt-buttons ---- */

body.rxs-ui-v2 .rxs-module table.rxs-table tbody td.dtfc-fixed-left {
    background: var(--rx-v2-panel) !important;
}

body.rxs-ui-v2 .rxs-module table.rxs-table tbody tr:hover td.dtfc-fixed-left {
    background: var(--rx-v2-hover) !important;
}

/* La columna fija de la DERECHA (acciones, ID) la pinta custom.css con un gris fijo
   (#e9e9e9, pensado para v1) y el bloque dark viejo la pisa solo en oscuro: en v2 claro
   quedaba una banda gris contra el panel blanco. Mismos tokens que la fija de la izquierda. */
body.rxs-ui-v2 .rxs-module table.rxs-table tbody td.dtfc-fixed-right {
    background: var(--rx-v2-panel) !important;
}

body.rxs-ui-v2 .rxs-module table.rxs-table tbody tr:hover td.dtfc-fixed-right {
    background: var(--rx-v2-hover) !important;
}

/* Que se vea que el contenido pasa POR DEBAJO de la columna fija: sin ese corte, el texto
   que queda cortado a mitad de palabra se lee como un bug de la tabla. El borde va en el
   canto por donde entra lo que scrollea: a la derecha de la fija de la izquierda, y a la
   izquierda de la PRIMERA del grupo fijo de la derecha (que pueden ser dos: acciones e ID). */
body.rxs-ui-v2 .rxs-module table.rxs-table thead th.dtfc-fixed-left,
body.rxs-ui-v2 .rxs-module table.rxs-table tbody td.dtfc-fixed-left {
    border-right: 1px solid var(--rx-v2-border);
}

body.rxs-ui-v2 .rxs-module table.rxs-table thead th:not(.dtfc-fixed-right) + th.dtfc-fixed-right,
body.rxs-ui-v2 .rxs-module table.rxs-table tbody td:not(.dtfc-fixed-right) + td.dtfc-fixed-right {
    border-left: 1px solid var(--rx-v2-border);
}

/* Adentro del menu los botones no son solo-icono (hay algunos con texto, ej "Ausente"),
 * asi que el cuadrado de 28px de las acciones de fila los aplasta y el texto se desborda
 * encima del boton de al lado. Aca el ancho lo pone el contenido. */
body.rxs-ui-v2 .rxs-module .rxsBtns .dropdown-menu .btn,
body.rxs-ui-v2 .rxs-module table.rxs-table td .dropdown-menu .btn {
    gap: 4px;
    min-width: 28px;
    padding: 0 8px;
    width: auto;
}

body.rxs-ui-v2 .rxs-module .dt-buttons {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    padding-top: 10px;
}

body.rxs-ui-v2 .rxs-module .dt-buttons .dt-button {
    align-items: center;
    background: var(--rx-v2-ghost) !important;
    background-image: none !important;
    border: 1px solid var(--rx-v2-border) !important;
    border-radius: var(--rx-v2-r8);
    box-shadow: none !important;
    color: var(--rx-v2-muted) !important;
    display: inline-flex;
    height: 32px;
    justify-content: center;
    margin: 0;
    min-width: 34px;
    padding: 0 10px;
}

body.rxs-ui-v2 .rxs-module .dt-buttons .dt-button:hover {
    border-color: var(--rx-v2-accent) !important;
    color: var(--rx-v2-text) !important;
}

body.rxs-ui-v2 .rxs-module .dt-buttons .dt-button .fa {
    color: inherit;
}

body.rxs-ui-v2 .rxs-module .dataTables_length select,
body.rxs-ui-v2 .rxs-module .dataTables_filter input {
    background-color: var(--rx-v2-field) !important;
    background-image: none !important;
    color: var(--rx-v2-text) !important;
}

body.rxs-ui-v2 .sidebar-nav ul li a {
    color: var(--rx-v2-muted) !important;
}

body.rxs-ui-v2 .sidebar-nav ul li.active > a,
body.rxs-ui-v2 .sidebar-nav ul li a:hover,
body.rxs-ui-v2 .sidebar-nav > ul > li.active > a {
    color: var(--rx-v2-text) !important;
}

body.rxs-ui-v2 .left-sidebar .select2-selection--single,
body.rxs-ui-v2 .left-sidebar .select2-selection--multiple {
    background: var(--rx-v2-field) !important;
    border: 1px solid var(--rx-v2-border) !important;
    border-radius: var(--rx-v2-r8);
}

body.rxs-ui-v2 .left-sidebar .select2-selection__rendered {
    color: var(--rx-v2-text) !important;
}

body.rxs-ui-v2 .select2-selection__rendered {
    background: transparent !important;
    color: var(--rx-v2-text) !important;
}

body.rxs-ui-v2 .select2-container--default .select2-selection--single .select2-selection__placeholder,
body.rxs-ui-v2 .select2-selection__rendered .select2-selection__placeholder {
    color: var(--rx-v2-faint) !important;
}

body.rxs-ui-v2 .select2-container--default .select2-selection--single .select2-selection__arrow b {
    border-color: var(--rx-v2-faint) transparent transparent transparent;
}

body.rxs-ui-v2 .rxsFormSb {
    background: var(--rx-v2-accent) !important;
    background-image: none !important;
    border: 0 !important;
    border-radius: var(--rx-v2-r10);
    box-shadow: none !important;
    color: var(--rx-v2-accent-ink) !important;
    font-size: 15px;
    font-weight: 600;
    letter-spacing: .01em;
    min-height: 44px;
    padding: 10px 16px;
}

body.rxs-ui-v2 .rxsFormSb:hover {
    filter: brightness(1.08);
}

body.rxs-ui-v2 .rxs-module .dataTables_length select {
    -webkit-appearance: none;
    appearance: none;
    background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath fill='%238b94a1' d='M0 0l5 6 5-6z'/%3E%3C/svg%3E") !important;
    background-position: right 9px center;
    background-repeat: no-repeat;
    padding-right: 26px;
}

/* ---- v2 structural: module head + footer bar + collapsed filters ---- */

body.rxs-ui-v2 .rxs-module .rxs-module-head {
    align-items: center;
    background: var(--rx-v2-panel);
    border-bottom: 1px solid var(--rx-v2-border);
    display: flex;
    gap: 12px;
    justify-content: space-between;
    padding: 12px 16px;
}

body.rxs-ui-v2 .rxs-module .rxs-module-title {
    align-items: center;
    display: flex;
    gap: 11px;
    min-width: 0;
}

body.rxs-ui-v2 .rxs-module .rxs-module-icon {
    align-items: center;
    background: linear-gradient(135deg, var(--rx-v2-accent-soft), var(--rx-v2-accent-2-soft));
    border-radius: var(--rx-v2-r9);
    color: var(--rx-v2-accent);
    display: inline-flex;
    flex: 0 0 36px;
    font-size: 15px;
    height: 36px;
    justify-content: center;
    width: 36px;
}

body.rxs-ui-v2 .rxs-module .rxs-module-title h2 {
    color: var(--rx-v2-text);
    font-size: 16px;
    font-weight: 650;
    letter-spacing: -.01em;
    line-height: 1.2;
    margin: 0;
}

body.rxs-ui-v2 .rxs-module .rxs-module-count {
    background: var(--rx-v2-ghost);
    border-radius: 999px;
    color: var(--rx-v2-muted);
    display: inline-block;
    font-size: 11px;
    font-weight: 600;
    margin-top: 2px;
    padding: 1px 8px;
}

body.rxs-ui-v2 .rxs-module .rxs-module-tools {
    align-items: center;
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    justify-content: flex-end;
}

/* La caja de filtrar de una lista vue=4, en el header del modulo. Es la MISMA del buscador
   del menu (.rxs-menu-search, (4d)): fondo, borde, lupa y foco salen de alla. Lo unico que
   cambia es que aca no ocupa el ancho entero de un sidebar. */
body.rxs-ui-v2 .rxs-module .rxs-module-tools .rxs-menu-search {
    margin: 0;
    min-width: 190px;
}
body.rxs-ui-v2 .rxs-module .rxs-module-tools .rxs-menu-search input {
    height: 30px;
}

/* El item ACTIVO de una lista de botones --- cual de los 59 tipos de notificacion estoy
   editando. `.btn-themecolor.active` (custom.css:1144) le pone var(--rx-color1) DE FONDO, que
   es exactamente el color que el boton ya tiene: el degrade de marca gana igual y el activo
   salia identico al resto, medido computed-style byte por byte en 1349. Y ningun fondo sirve
   para todos, porque el color de marca puede ser blanco. El anillo no depende de la marca: se
   apoya en el acento de v2 y en el panel de atras. */
body.rxs-ui-v2 .rxs-data-panel > .btn.active {
    box-shadow: 0 0 0 2px var(--rx-v2-panel), 0 0 0 4px var(--rx-v2-accent);
    position: relative;
    z-index: 1;
}

body.rxs-ui-v2 .rxs-module .rxs-module-tools .dt-buttons {
    gap: 6px;
    padding: 0;
    margin-bottom:0;
}

body.rxs-ui-v2 .rxs-module .rxs-module-tools .allFiltersBtn {
    align-self: auto;
    margin: 0 !important;
}

body.rxs-ui-v2 .rxs-module .rxs-module-tools .filter_change {
    align-items: center;
    background: var(--rx-v2-ghost) !important;
    border: 1px solid var(--rx-v2-border) !important;
    border-radius: var(--rx-v2-r8);
    box-shadow: none;
    color: var(--rx-v2-muted) !important;
    display: inline-flex;
    height: 32px;
    justify-content: center;
    min-width: 34px;
    padding: 0 8px;
}

/* accesos directos a los favoritos con rid de la tabla (ui_v2.js: favBtns) */
body.rxs-ui-v2 .rxs-module .rxs-module-tools .rxs-fav-btns {
    align-items: center;
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}

body.rxs-ui-v2 .rxs-module .rxs-module-tools .rxs-fav-btn {
    align-items: center;
    background: var(--rx-v2-ghost);
    border: 1px solid var(--rx-v2-border);
    border-radius: var(--rx-v2-r8);
    color: var(--rx-v2-muted);
    display: inline-flex;
    font-size: 12.5px;
    gap: 6px;
    height: 32px;
    max-width: 200px;
    padding: 0 10px;
}

body.rxs-ui-v2 .rxs-module .rxs-module-tools .rxs-fav-btn:hover {
    border-color: var(--rx-v2-accent);
    color: var(--rx-v2-accent);
}

body.rxs-ui-v2 .rxs-module .rxs-module-tools .rxs-fav-btn .fa {
    font-size: 11px;
    opacity: .8;
}

body.rxs-ui-v2 .rxs-module .rxs-module-tools .rxs-fav-btn span {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* los favoritos que no entran quedan detras del "..." (igual que el kebab de fila) */
body.rxs-ui-v2 .rxs-module .rxs-fav-btns .rxs-hidden-action {
    display: none !important;
}

body.rxs-ui-v2 .rxs-module .rxs-module-tools .rxs-fav-btns .rxs-row-more {
    background: var(--rx-v2-ghost);
    border: 1px solid var(--rx-v2-border);
    border-radius: var(--rx-v2-r8);
    color: var(--rx-v2-muted);
    height: 32px;
    min-width: 34px;
    padding: 0 8px;
}

/* el popover de favoritos lista nombres: vertical, no la fila de iconos de la grilla */
body.rxs-ui-v2 .rxs-row-menu.rxs-fav-menu {
    flex-direction: column;
    max-width: 260px;
}

body.rxs-ui-v2 .rxs-row-menu.rxs-fav-menu .rxs-fav-btn {
    align-items: center;
    background: var(--rx-v2-ghost);
    border: 1px solid var(--rx-v2-border-soft);
    border-radius: var(--rx-v2-r7);
    color: var(--rx-v2-muted);
    display: flex;
    font-size: 12.5px;
    gap: 6px;
    height: 30px;
    padding: 0 10px;
}

body.rxs-ui-v2 .rxs-row-menu.rxs-fav-menu .rxs-fav-btn:hover {
    background: var(--rx-v2-accent);
    border-color: var(--rx-v2-accent);
    color: var(--rx-v2-accent-ink);
}

body.rxs-ui-v2 .rxs-row-menu.rxs-fav-menu .rxs-fav-btn span {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* en pantallas chicas el header viene apretado, pero dos cuadrados iguales sin texto no
 * dicen nada: queda el nombre recortado (pass 31; antes display:none) */
@media (max-width: 767.98px) {
    body.rxs-ui-v2 .rxs-module .rxs-module-tools .rxs-fav-btn {
        font-size: 12px;
        gap: 5px;
        height: 30px;
        max-width: 132px;
        padding: 0 8px;
    }
    body.rxs-ui-v2 .rxs-module .rxs-module-tools .rxs-fav-btn span {
        max-width: 96px;
    }
}

/* banda de filtros oculta mientras este colapsada (el toggle vive en el header) */
body.rxs-ui-v2 .rxs-module .rxs-filterbar:has(.allFilters.d-none) {
    display: none;
}

body.rxs-ui-v2 .rxs-module .rxs-table-footer {
    border-top: 1px solid var(--rx-v2-border-soft);
    justify-content: space-between;
    margin-top: 10px;
    padding-top: 10px;
}

body.rxs-ui-v2 .rxs-module .rxs-table-footer-right {
    align-items: center;
    flex-wrap: wrap;
    gap: 6px 14px;
}

body.rxs-ui-v2 .rxs-module .rxs-table-footer .dataTables_info,
body.rxs-ui-v2 .rxs-module .rxs-table-footer .dataTables_length,
body.rxs-ui-v2 .rxs-module .rxs-table-footer .dataTables_paginate {
    padding-top: 0;
}

/* acciones de fila discretas hasta el hover (solo dispositivos con puntero) */
@media (hover: hover) and (pointer: fine) {
    body.rxs-ui-v2 .rxs-module table.rxs-table tbody td .btn:not(:where(.rxsBtnsOwn .btn)) {
        opacity: .35;
        transition: opacity .12s ease;
    }

    body.rxs-ui-v2 .rxs-module table.rxs-table tbody tr:hover td .btn:not(:where(.rxsBtnsOwn .btn)) {
        opacity: 1;
    }
}

@media (max-width: 767px) {
    body.rxs-ui-v2 .rxs-module .rxs-module-head {
        align-items: flex-start;
        flex-direction: column;
        padding: 10px 12px;
    }

    body.rxs-ui-v2 .rxs-module .rxs-module-tools {
        justify-content: flex-start;
    }

    body.rxs-ui-v2 .rxs-module .rxs-table-footer,
    body.rxs-ui-v2 .rxs-module .rxs-table-footer-right {
        justify-content: center;
    }
}

body.rxs-ui-v2 .rxs-module .rxs-table-footer .dataTables_info,
body.rxs-ui-v2 .rxs-module .rxs-table-footer .dataTables_length {
    float: none;
}

body.rxs-ui-v2 .rxs-module .rxs-table-footer .dataTables_length {
    white-space: nowrap;
    margin-left:0;
}

/* el info puede ser largo ("(filtrados de un total de...)"): que envuelva
 * dentro de su celda del grid en vez de desbordar sobre los controles */
body.rxs-ui-v2 .rxs-module .rxs-table-footer .dataTables_info {
    min-width: 0;
    white-space: normal;
}

body.rxs-ui-v2 .rxs-module .rxs-table-footer .dataTables_length label {
    align-items: center;
    display: flex;
    gap: 6px;
    margin: 0;
    white-space: nowrap;
}

body.rxs-ui-v2 .rxs-module .rxs-table-footer .dataTables_paginate {
    align-items: center;
    display: inline-flex;
    flex-wrap: wrap;
    float: none;
    gap: 4px;
    justify-content: flex-end;
    white-space: nowrap;
}

body.rxs-ui-v2 .rxs-module .rxs-table-footer .dataTables_paginate .paginate_button {
    margin-left: 0;
}

body.rxs-ui-v2 .rxs-module .rxs-table-footer {
    grid-template-columns: minmax(0, 1fr) auto auto;
}

body.rxs-ui-v2 .rxs-module .rxs-table-footer-right {
    display: contents;
}

@media (max-width: 767px) {
    body.rxs-ui-v2 .rxs-module .rxs-table-footer {
        grid-template-columns: 1fr;
        justify-items: center;
    }
}

/* el "Mostrar N registros" traia margin del css base de DataTables y quedaba unos px
 * mas abajo que el paginador (el grid centra la celda, pero el margen la corre) */
body.rxs-ui-v2 .rxs-module .rxs-table-footer .dataTables_info,
body.rxs-ui-v2 .rxs-module .rxs-table-footer .dataTables_length,
body.rxs-ui-v2 .rxs-module .rxs-table-footer .dataTables_paginate {
    align-self: center;
    margin-bottom: 0;
    margin-top: 0;
}

/* los numeros de pagina van dentro de un <span> suelto que DataTables arma aparte:
 * no es hijo del flex del paginador, asi que no recibia el gap y 1-2-3 salian pegados */
body.rxs-ui-v2 .rxs-module .rxs-table-footer .dataTables_paginate > span {
    align-items: center;
    display: inline-flex;
    flex-wrap: wrap;
    gap: 4px;
}

body.rxs-ui-v2 .rxs-module:has(.allFilters.expanded) .allFiltersBtn {
    border-color: var(--rx-v2-accent) !important;
    color: var(--rx-v2-accent) !important;
}

/* ---- v2 pass 5: CTA nuevo + kebab de acciones + cards mobile ---- */

body.rxs-ui-v2 .rxs-module-tools .rxs-cta-new {
    align-items: center;
    background: var(--rx-v2-accent);
    border: 1px solid transparent;
    border-radius: var(--rx-v2-r8);
    color: var(--rx-v2-accent-ink);
    cursor: pointer;
    display: inline-flex;
    font-size: 12.5px;
    font-weight: 600;
    gap: 7px;
    height: 32px;
    letter-spacing: .01em;
    padding: 0 14px;
    white-space: nowrap;
}

body.rxs-ui-v2 .rxs-module-tools .rxs-cta-new:hover {
    filter: brightness(1.08);
}

body.rxs-ui-v2 .rxs-module-tools .rxs-cta-new .fa {
    font-size: 11px;
}

/* acciones colapsadas: solo la primaria + "..." quedan visibles en la celda */
body.rxs-ui-v2 .rxs-module .rxsBtns .rxs-hidden-action {
    display: none !important;
}

/* popover flotante de acciones (vive en body, fuera del modulo) */
body.rxs-ui-v2 .rxs-row-menu {
    background: var(--rx-v2-panel);
    border: 1px solid var(--rx-v2-border);
    border-radius: var(--rx-v2-r10);
    box-shadow: var(--rx-v2-shadow);
    display: flex;
    gap: 4px;
    padding: 6px;
    position: fixed;
    z-index: 10060;
}

body.rxs-ui-v2 .rxs-row-menu .btn,
body.rxs-ui-v2 .rxs-row-menu a > .btn {
    align-items: center;
    background: var(--rx-v2-ghost) !important;
    border: 1px solid var(--rx-v2-border-soft) !important;
    border-radius: var(--rx-v2-r7);
    box-shadow: none;
    color: var(--rx-v2-muted) !important;
    display: inline-flex;
    height: 30px;
    justify-content: center;
    margin: 0;
    min-width: 30px;
    opacity: 1 !important;
    padding: 0;
    width: 30px;
}

body.rxs-ui-v2 .rxs-row-menu .btn:hover {
    background: var(--rx-v2-accent) !important;
    border-color: var(--rx-v2-accent) !important;
    color: var(--rx-v2-accent-ink) !important;
}

/* ---- fix form: select2 con icono y boton "+" de alta relacionada ---- */

/* select2 dentro de input-group traia width inline fijo que no entraba al lado
 * del prepend y bootstrap lo bajaba de linea; con basis 0 ocupa el resto */
body.rxs-ui-v2 form.rxs-form .rxs-field .input-group .select2-container {
    flex: 1 1 0;
    min-width: 0;
    width: auto !important;
}

/* el "+" (addRel) suelto entre label y select quedaba en su propia linea;
 * lo anclamos a la linea del label, arriba a la derecha del campo */
body.rxs-ui-v2 form.rxs-form .rxs-field {
    position: relative;
}

/* la otra variante del markup: el "+" sale DENTRO del label. Ahi engordaba la linea del
 * label (23px vs 17px) y el control arrancaba 6px mas abajo que el de los campos vecinos,
 * o sea toda la fila del grid desalineada. Mismo anclaje absoluto que el suelto. */
body.rxs-ui-v2 form.rxs-form .rxs-field > label > .addRel,
body.rxs-ui-v2 form.rxs-form .rxs-field > .addRel {
    align-items: center;
    display: inline-flex;
    font-size: 11px;
    height: 20px;
    justify-content: center;
    position: absolute;
    /* 15px = padding lateral de la col: queda al ras del borde derecho del input */
    right: 15px;
    top: -2px;
    width: 20px;
}

/* el <br> tras el label mete una linea fantasma (el label v2 ya es block):
 * descuadraba la altura de los campos checkbox y file vs el resto */
body.rxs-ui-v2 form.rxs-form .rxs-field > label + br,
body.rxs-ui-v2 form.rxs-form .rxs-field > br:first-child {
    display: none;
}

/* checkbox (flat-redi + label.rxsCheck2): misma altura de fila que un input */
body.rxs-ui-v2 form.rxs-form .rxs-field > label.rxsCheck2 {
    align-items: center;
    display: inline-flex;
    margin-bottom: 0;
    min-height: 38px;
}

/* upload: input nativo + drop-zone quedaban apilados/amontonados (suelto o
 * dentro de un input-group con icono); en v2 el drop-zone (g.js) es el control
 * -su click delega al input- y el nativo se oculta. !important para pisar los
 * estilos inline que le pone g.js */
body.rxs-ui-v2 form.rxs-form .rxs-field input[type="file"].rxs-v2-dzin,
body.rxs-ui-v2 form.rxs-form .rxs-field .input-group > br {
    display: none;
}
body.rxs-ui-v2 form.rxs-form .rxs-field .input-group > .file-drop-zone {
    flex: 1 1 0;
    min-width: 0;
}
body.rxs-ui-v2 form.rxs-form .rxs-field .input-group > .file-drop-zone:not(:first-child) {
    border-bottom-left-radius: 0 !important;
    border-top-left-radius: 0 !important;
}
body.rxs-ui-v2 form.rxs-form .rxs-field .file-drop-zone {
    background: var(--rx-v2-field) !important;
    border: 1px dashed var(--rx-v2-border) !important;
    border-radius: var(--rx-v2-r8);
    margin-top: 0 !important;
    min-height: 38px !important;
}
body.rxs-ui-v2 form.rxs-form .rxs-field .file-drop-zone span {
    color: var(--rx-v2-muted) !important;
}
/* Campo con archivo YA cargado: al drop-zone se le suman el boton "Galería", el link
 * de preview (a.formphoto) y el "Eliminar", y los cinco peleaban el mismo renglon ->
 * el drop-zone se achicaba a la mitad y los controles se tocaban entre si. Se resuelve
 * SIN wrapear: el campo tiene que seguir midiendo un renglon como sus hermanos de la
 * grilla (col-md-6/col-xl-4), si se parte en dos filas descoloca toda la fila del form.
 * Los tres accesorios pasan a cuadrados de 32px y el drop-zone se queda con el resto. */
body.rxs-ui-v2 form.rxs-form .rxs-field .input-group.rxs-v2-dz {
    align-items: center;
    gap: 5px;
}
body.rxs-ui-v2 form.rxs-form .rxs-field .input-group.rxs-v2-dz > .file-drop-zone {
    flex: 1 1 60px;
    min-width: 0;
}
/* con gap propio el drop-zone deja de pegarse al prepend: recupera su radio entero */
body.rxs-ui-v2 form.rxs-form .rxs-field .input-group.rxs-v2-dz > .file-drop-zone:not(:first-child) {
    border-bottom-left-radius: 8px !important;
    border-top-left-radius: 8px !important;
}
body.rxs-ui-v2 form.rxs-form .rxs-field .rxsFileActBtn,
body.rxs-ui-v2 form.rxs-form .rxs-field .input-group > a.formphoto {
    flex: 0 0 auto;
    display: inline-flex !important;
    align-items: center;
    justify-content: center;
    gap: 5px;
    height: 32px;
    margin-top: 0 !important;
    margin-left: 0;
    border: 1px solid var(--rx-v2-border);
    border-radius: var(--rx-v2-r8);
    padding: 0 9px;
    background: transparent;
    color: var(--rx-v2-text);
    white-space: nowrap;
}
body.rxs-ui-v2 form.rxs-form .rxs-field .rxsFileActBtn:hover,
body.rxs-ui-v2 form.rxs-form .rxs-field .input-group > a.formphoto:hover {
    background: var(--rx-v2-hover);
    border-color: var(--rx-v2-accent);
    color: var(--rx-v2-accent);
}
/* Con dos o mas fuentes (galeria + micro + camara + nota) las etiquetas no entran: el
 * renglon del campo tiene que seguir midiendo un renglon como sus hermanos de la grilla
 * (col-md-6/col-xl-4). Pasan a cuadrados de 32px y el `title` sigue explicando cada uno.
 * Con una sola sobra lugar y conserva su etiqueta. */
body.rxs-ui-v2 form.rxs-form .rxs-field:has(.rxsFileActBtn ~ .rxsFileActBtn) .rxsFileActTx,
body.rxs-ui-v2 form.rxs-form .rxs-field:has(a.formphoto) .rxsFileActTx {
    display: none;
}
body.rxs-ui-v2 form.rxs-form .rxs-field:has(.rxsFileActBtn ~ .rxsFileActBtn) .rxsFileActBtn,
body.rxs-ui-v2 form.rxs-form .rxs-field:has(a.formphoto) .rxsFileActBtn {
    gap: 0;
    padding: 0;
    width: 32px;
}
body.rxs-ui-v2 form.rxs-form .rxs-field .rxsFileActBtn > .fa { font-size: 14px; }
/* Grabando, el boton de audio se sale del tratamiento neutro y recupera su etiqueta: es el
 * unico estado del campo que el usuario tiene que poder leer sin buscarlo, y ademas ahi la
 * etiqueta es el cronometro.
 * No alcanza con ir DESPUES de la regla de "solo icono": el :has(A ~ A) de aquella cuenta como
 * DOS clases (la especificidad de :has() es la de su argumento mas especifico, y ahi el
 * argumento son dos selectores de clase), asi que gana igual. El "Detener" quedaba adentro de
 * un cuadrado de 32px, pisado por los bordes. Por eso el estado repite el mismo prefijo para
 * empatarle y pasarla; la version corta queda para el campo con un solo boton. */
body.rxs-ui-v2 form.rxs-form .rxs-field:has(.rxsFileActBtn ~ .rxsFileActBtn) .rxsRecBtn.btn-danger,
body.rxs-ui-v2 form.rxs-form .rxs-field:has(a.formphoto) .rxsRecBtn.btn-danger,
body.rxs-ui-v2 form.rxs-form .rxs-field .rxsRecBtn.btn-danger {
    width: auto;
    gap: 5px;
    padding: 0 9px;
    background: #dc3545;
    border-color: #dc3545;
    color: #fff;
}
body.rxs-ui-v2 form.rxs-form .rxs-field:has(.rxsFileActBtn ~ .rxsFileActBtn) .rxsRecBtn.btn-danger .rxsFileActTx,
body.rxs-ui-v2 form.rxs-form .rxs-field:has(a.formphoto) .rxsRecBtn.btn-danger .rxsFileActTx,
body.rxs-ui-v2 form.rxs-form .rxs-field .rxsRecBtn.btn-danger .rxsFileActTx {
    display: inline;
}

/* estados del drop-zone: el borde base de v2 es !important, asi que las variantes
 * tambien tienen que serlo o se pierden */
body.rxs-ui-v2 form.rxs-form .rxs-field .file-drop-zone.rxsFileDzOver {
    border-color: var(--rx-v2-accent) !important;
    background: var(--rx-v2-hover) !important;
}
body.rxs-ui-v2 form.rxs-form .rxs-field .file-drop-zone.rxsFileDzFull {
    border-style: solid !important;
    border-color: #28a745 !important;
}
body.rxs-ui-v2 form.rxs-form .rxs-field .file-drop-zone.rxsFileDzFull .rxsFileDzHint {
    color: #28a745 !important;
}
/* Campo de archivo SIN input-group (el que no lleva icono de prepend): el renglon lo tiene
 * que armar el propio .rxs-field, o el drop-zone se queda con el ancho entero y los botones
 * caen a una segunda fila. Todo lo que no sea el drop-zone o un boton -label, lista, ayuda-
 * ocupa la fila completa. */
body.rxs-ui-v2 form.rxs-form .rxs-field.rxs-v2-dz {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 5px;
}
body.rxs-ui-v2 form.rxs-form .rxs-field.rxs-v2-dz > *:not(.file-drop-zone):not(.rxsFileActBtn):not(a.formphoto):not(.delfile) {
    flex: 0 0 100%;
}
body.rxs-ui-v2 form.rxs-form .rxs-field.rxs-v2-dz > .file-drop-zone {
    flex: 1 1 60px;
    min-width: 0;
}
/* En una columna angosta con cuatro fuentes, el texto del drop-zone se partia en dos lineas
 * y el campo quedaba mas alto que sus hermanos de la fila. Se recorta con puntos suspensivos:
 * el renglon del form es una grilla y todas las celdas tienen que medir lo mismo. */
body.rxs-ui-v2 form.rxs-form .rxs-field .file-drop-zone { overflow: hidden; }
body.rxs-ui-v2 form.rxs-form .rxs-field .rxsFileDzHint {
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* la lista de lo elegido cuelga debajo del renglon y ocupa el ancho del campo */
body.rxs-ui-v2 form.rxs-form .rxs-field .rxsFileStaged { margin-top: 5px; }
/* ...salvo en un campo de un solo archivo, donde va adentro del drop-zone (ahi no hay renglon
   nuevo que separar, y el .rxs-v2-dz de arriba la sacaria de la fila) */
body.rxs-ui-v2 form.rxs-form .rxs-field .rxsFileStagedIn { margin-top: 0; }
body.rxs-ui-v2 form.rxs-form .rxs-field .rxsFileStagedIn .file-preview-item,
body.rxs-ui-v2 form.rxs-form .rxs-field .file-drop-zone > .rxsResChip {
    background: none;
    border: none;
}
body.rxs-ui-v2 form.rxs-form .rxs-field .file-preview-item {
    background: var(--rx-v2-field);
    border: 1px solid var(--rx-v2-border);
}
body.rxs-ui-v2 form.rxs-form .rxs-field .file-preview-nm { color: var(--rx-v2-text); }
body.rxs-ui-v2 form.rxs-form .rxs-field .file-preview-sz { color: var(--rx-v2-muted); }
body.rxs-ui-v2 form.rxs-form .rxs-field .input-group > .delfile {
    flex: 0 0 auto;
    display: inline-flex !important;
    align-items: center;
    gap: 4px;
    height: 32px;
    white-space: nowrap;
    color: var(--rx-v2-muted);
}
body.rxs-ui-v2 form.rxs-form .rxs-field .input-group > .delfile input[type="checkbox"] {
    margin: 0;
    flex: 0 0 auto;
}
/* el help-block del grupo nunca ocupa lugar en el renglon */
body.rxs-ui-v2 form.rxs-form .rxs-field .input-group.rxs-v2-dz > .help-block:empty {
    display: none;
}
/* Lo ya guardado se ve (g.js rxsFileThumb): la imagen en vez del icono generico. El fondo a
 * cuadros es para las piezas blancas (los _neg de la marca), que sobre blanco no se verian. */
body.rxs-ui-v2 form.rxs-form .rxs-field a.formphoto.rxsFileThumb {
    flex: 0 0 auto !important;
    display: inline-flex !important;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 38px;
    margin: 0;
    padding: 2px;
    border: 1px solid var(--rx-v2-border);
    border-radius: var(--rx-v2-r8);
    background: repeating-conic-gradient(#e9ecef 0 25%, #fff 0 50%) 50% / 12px 12px;
    overflow: hidden;
}
body.rxs-ui-v2 form.rxs-form .rxs-field a.formphoto.rxsFileThumb img {
    display: block;
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
}
body.rxs-ui-v2 form.rxs-form .rxsFileHasThumb > .input-group-prepend { display: none; }
body.rxs-ui-v2 form.rxs-form .rxsFileHasThumb > .file-drop-zone {
    border-bottom-left-radius: 8px !important;
    border-top-left-radius: 8px !important;
}
/* form_v (la palanca visual del form, domain.php rxsFormVAttr): la foto se ve grande, como una
 * ficha, y el renglon entero toma su alto. Sin foto, el icono del prepend ocupa el mismo lugar
 * para que los campos de una fila midan lo mismo. */
body.rxs-ui-v2 form.rxs-form[data-form-v] .rxsFileRow > a.formphoto.rxsFileThumb,
body.rxs-ui-v2 form.rxs-form[data-form-v] .rxsFileRow > .input-group-prepend > .input-group-text {
    width: 96px;
    height: 72px;
    justify-content: center;
    font-size: 22px;
}
body.rxs-ui-v2 form.rxs-form[data-form-v] .rxsFileRow > .file-drop-zone {
    min-height: 72px !important;
}
/* tildado "Eliminar": la miniatura avisa que al guardar se va */
body.rxs-ui-v2 form.rxs-form .rxsFileDel > a.formphoto.rxsFileThumb {
    opacity: .35;
    outline: 2px solid #dc3545;
    outline-offset: -2px;
}
/* El ⋯ (g.js rxsFileCompact): solo cuando el renglon no alcanza (.rxsFileNarrow, que pone un
 * ResizeObserver). Entonces los accesorios salen del renglon y viven en su menu; el grabando no,
 * porque es el boton que para. Los !important empatan con los del renglon de arriba. */
body.rxs-ui-v2 form.rxs-form .rxsFileCmp > .rxsFileMoreBtn {
    display: none !important;
}
body.rxs-ui-v2 form.rxs-form .rxsFileNarrow.rxsFileNarrow > .rxsFileMoreBtn {
    flex: 0 0 auto !important;
    display: inline-flex !important;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    margin: 0 !important;
    padding: 0;
    border: 1px solid var(--rx-v2-border);
    border-radius: var(--rx-v2-r8);
    background: transparent;
    color: var(--rx-v2-text);
}
body.rxs-ui-v2 form.rxs-form .rxsFileNarrow.rxsFileNarrow > .rxsFileMoreBtn:hover,
body.rxs-ui-v2 form.rxs-form .rxsFileNarrow.rxsFileNarrow > .rxsFileMoreBtn[aria-expanded="true"] {
    background: var(--rx-v2-hover);
    border-color: var(--rx-v2-accent);
    color: var(--rx-v2-accent);
}
body.rxs-ui-v2 form.rxs-form .rxsFileNarrow.rxsFileDel > .rxsFileMoreBtn {
    border-color: #dc3545;
    color: #dc3545;
}
body.rxs-ui-v2 form.rxs-form .rxsFileNarrow.rxsFileNarrow > .rxsFileActBtn:not(.btn-danger),
body.rxs-ui-v2 form.rxs-form .rxsFileNarrow.rxsFileNarrow > .delfile {
    display: none !important;
}
.rxsFileMenu {
    position: fixed;
    z-index: 2060;
    min-width: 220px;
    padding: 4px;
    border: 1px solid var(--rx-v2-border, #dee2e6);
    border-radius: 10px;
    background: var(--rx-v2-panel, #fff);
    color: var(--rx-v2-text, #212529);
    box-shadow: 0 10px 28px rgba(0, 0, 0, .18);
}
.rxsFileMenuIt {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    padding: 8px 10px;
    border: 0;
    border-radius: 6px;
    background: none;
    color: inherit;
    font-size: 14px;
    text-align: left;
}
.rxsFileMenuIt:hover,
.rxsFileMenuIt:focus-visible {
    background: var(--rx-v2-hover, #f1f3f5);
    outline: none;
}
.rxsFileMenuIt > .fa {
    width: 16px;
    opacity: .8;
    text-align: center;
}
.rxsFileMenuDel { color: #dc3545; }
/* La caja de N archivos con imagenes (g.js rxsResRelThumbs): grilla de miniaturas con el nombre
 * abajo y la baja debajo de cada una. */
body.rxs-ui-v2 .rxsResRelList.rxsResRelThumbs {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
}
body.rxs-ui-v2 .rxsResRelThumbs > li {
    display: flex;
    flex-direction: column;
    gap: 4px;
    width: 104px;
    font-size: 12px;
}
body.rxs-ui-v2 .rxsResRelThumbs > li > a {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
body.rxs-ui-v2 .rxsResRelThumbs a.rxsResRelImg img {
    display: block;
    width: 104px;
    height: 78px;
    margin-bottom: 3px;
    border: 1px solid var(--rx-v2-border);
    border-radius: var(--rx-v2-r8);
    background: repeating-conic-gradient(#e9ecef 0 25%, #fff 0 50%) 50% / 12px 12px;
    object-fit: contain;
}

/* ---- CKEditor 4 en dark: chrome (toolbar/estado) via tokens. El area
 * editable es un iframe (el CSS de la pagina no entra): la pinta ui_v2.js
 * inyectando estilos en cada contentDom. ---- */
body.rxs-ui-v2.thr-dark .cke_chrome {
    border-color: var(--rx-v2-border) !important;
}
body.rxs-ui-v2.thr-dark .cke_top,
body.rxs-ui-v2.thr-dark .cke_bottom {
    background: var(--rx-v2-panel-2) !important;
    border-color: var(--rx-v2-border) !important;
}
body.rxs-ui-v2.thr-dark .cke_toolgroup,
body.rxs-ui-v2.thr-dark .cke_combo_button {
    background: var(--rx-v2-field) !important;
    border-color: var(--rx-v2-border) !important;
}
/* los iconos son sprites oscuros: invertidos quedan legibles sobre fondo oscuro */
body.rxs-ui-v2.thr-dark .cke_button_icon,
body.rxs-ui-v2.thr-dark .cke_combo_arrow {
    filter: invert(.85) hue-rotate(180deg);
}
body.rxs-ui-v2.thr-dark .cke_combo_text,
body.rxs-ui-v2.thr-dark .cke_path_item,
body.rxs-ui-v2.thr-dark .cke_path_empty {
    color: var(--rx-v2-muted) !important;
}

/* input-group con prepend (icono): el control (input o select2) heredaba
 * border-radius:8px en las 4 esquinas, chocando con el prepend redondeado a la
 * izquierda -> se veia el select2 redondo pero pegado a un icono cuadrado. Aca
 * quitamos el radio del lado del control que toca el prepend (no al primer hijo,
 * que es el prepend, ni cuando el control va solo sin prepend). */
body.rxs-ui-v2 form.rxs-form .rxs-field .input-group > .form-control:not(:first-child),
body.rxs-ui-v2 form.rxs-form .rxs-field .input-group > .select2-container:not(:first-child) .select2-selection,
body.rxs-ui-v2 form.rxs-form .rxs-field .input-group > .my-colorpicker2 .form-control {
    border-bottom-left-radius: 0 !important;
    border-top-left-radius: 0 !important;
}

/* select2 single: el texto ("Seleccione") tenia line-height 28 dentro de una caja
 * de ~36 -> quedaba pegado arriba, desalineado. Lo centramos verticalmente y
 * alineamos la flechita al centro. */
body.rxs-ui-v2 form.rxs-form .rxs-field .select2-selection--single {
    align-items: center;
    display: flex;
}
body.rxs-ui-v2 form.rxs-form .rxs-field .select2-selection--single .select2-selection__rendered {
    line-height: 1.4;
}
body.rxs-ui-v2 form.rxs-form .rxs-field .select2-selection--single .select2-selection__arrow {
    height: 100%;
    top: 0;
}

/* colorpicker: el swatch (.input-group-addon > i) rendia como un bloque negro de
 * ancho/alto completo (30x48) -> "color muy grande". El plugin lo posiciona absolute
 * (left) y pisaba el input; lo volvemos un chip chico anclado a la DERECHA del input,
 * como preview, y le damos padding-right al input para que el texto no lo tape. */
body.rxs-ui-v2 form.rxs-form .rxs-field .my-colorpicker2 {
    align-items: stretch;
    display: flex;
    flex: 1 1 0;
    min-width: 0;
    position: relative;
}
body.rxs-ui-v2 form.rxs-form .rxs-field .my-colorpicker2 .form-control {
    flex: 1 1 0;
    min-width: 0;
    padding-right: 36px;
}
body.rxs-ui-v2 form.rxs-form .rxs-field .my-colorpicker2 .input-group-addon {
    align-items: center;
    background: transparent !important;
    border: 0 !important;
    bottom: 0;
    display: flex;
    left: auto !important;
    padding: 0 8px;
    right: 0 !important;
    top: 0 !important;
}
body.rxs-ui-v2 form.rxs-form .rxs-field .my-colorpicker2 .input-group-addon > i {
    border: 1px solid var(--rx-v2-border);
    border-radius: var(--rx-v2-r4);
    box-shadow: none;
    display: block;
    height: 20px !important;
    width: 20px !important;
}

/* cards Vue del modo lista (shortmode): acomodarlas al look v2 */
body.rxs-ui-v2 .rxs-module .stvVueAction {
    background: var(--rx-v2-panel) !important;
    border-radius: var(--rx-v2-r12);
    box-shadow: none;
}

/* ---- vista card mobile: el thead desaparece y cada tr es una tarjeta ---- */

@media (max-width: 767px) {
    body.rxs-ui-v2 .rxs-module table.rxs-table,
    body.rxs-ui-v2 .rxs-module table.rxs-table tbody {
        border: 0;
        display: block;
        width: 100% !important;
    }

    body.rxs-ui-v2 .rxs-module table.rxs-table thead,
    body.rxs-ui-v2 .rxs-module table.rxs-table tfoot,
    body.rxs-ui-v2 .rxs-module table.rxs-table tbody > tr.child {
        display: none !important;
    }

    body.rxs-ui-v2 .rxs-module table.rxs-table tbody > tr {
        background-color: color-mix(in srgb, var(--rx-rowcol, var(--rx-v2-panel)) var(--rx-v2-rowcol-mix), var(--rx-v2-panel)) !important;
        border: 1px solid var(--rx-v2-border-soft);
        border-radius: var(--rx-v2-r12);
        display: block;
        margin: 0 0 10px;
        padding: 4px 14px;
    }

    body.rxs-ui-v2 .rxs-module table.rxs-table tbody > tr > td {
        align-items: baseline;
        background: transparent !important;
        border: 0 !important;
        border-bottom: 1px solid var(--rx-v2-border-soft) !important;
        box-shadow: none !important;
        display: flex !important;
        gap: 14px;
        justify-content: space-between;
        max-width: none !important;
        padding: 8px 0 !important;
        position: static !important;
        text-align: right;
        white-space: normal !important;
        width: auto !important;
    }

    body.rxs-ui-v2 .rxs-module table.rxs-table tbody > tr > td:last-child {
        border-bottom: 0 !important;
    }

    body.rxs-ui-v2 .rxs-module table.rxs-table tbody > tr > td:empty {
        display: none !important;
    }

    body.rxs-ui-v2 .rxs-module table.rxs-table tbody > tr > td::before {
        color: var(--rx-v2-faint);
        content: attr(data-label);
        flex: 0 0 auto;
        font-size: 10px;
        font-weight: 600;
        letter-spacing: .06em;
        max-width: 45%;
        overflow: hidden;
        text-align: left;
        text-overflow: ellipsis;
        text-transform: uppercase;
        white-space: nowrap;
    }

    /* celda de acciones: sin label, botones alineados a la derecha y sin kebab */
    body.rxs-ui-v2 .rxs-module table.rxs-table tbody > tr > td.rxs-v2-tdbtns {
        align-items: center;
        justify-content: flex-end;
    }

    body.rxs-ui-v2 .rxs-module table.rxs-table tbody > tr > td.rxs-v2-tdbtns::before {
        content: none;
    }

    body.rxs-ui-v2 .rxs-module .rxsBtns .rxs-hidden-action {
        display: inline-flex !important;
    }

    body.rxs-ui-v2 .rxs-module .rxsBtns .rxs-row-more {
        display: none !important;
    }

    body.rxs-ui-v2 .rxs-module table.rxs-table tbody td .btn:not(:where(.rxsBtnsOwn .btn)) {
        opacity: 1;
    }
}

/* ---- v2 pass 6: modales (popup forms, confirmaciones) ---- */
/* Con el flag persistido en sesion, table_edit.php ya devuelve el form v2;
 * esto viste el contenedor bootstrap del modal con los tokens */

body.rxs-ui-v2 .modal-content {
    background: var(--rx-v2-panel);
    border: 1px solid var(--rx-v2-border);
    border-radius: var(--rx-v2-r14);
    box-shadow: var(--rx-v2-shadow);
    color: var(--rx-v2-text);
}

body.rxs-ui-v2 .modal-header {
    align-items: center;
    border-bottom: 1px solid var(--rx-v2-border-soft);
    min-height: 44px;
    padding: 10px 16px;
}

body.rxs-ui-v2 .modal-header h3,
body.rxs-ui-v2 .modal-header h4,
body.rxs-ui-v2 .modal-header h5 {
    color: var(--rx-v2-text);
    font-size: 15px;
    font-weight: 600;
    margin: 0;
}

body.rxs-ui-v2 .modal-header .close {
    color: var(--rx-v2-muted);
    opacity: 1;
    text-shadow: none;
}

body.rxs-ui-v2 .modal-header .close:hover {
    color: var(--rx-v2-text);
}

/* bootstrap 5 usa .btn-close con un SVG negro embebido; en dark lo invertimos */
body.rxs-ui-v2.thr-dark .modal-header .btn-close {
    filter: invert(1) grayscale(1);
}

body.rxs-ui-v2 .modal-body {
    color: var(--rx-v2-text);
}

body.rxs-ui-v2 .modal-footer {
    border-top: 1px solid var(--rx-v2-border-soft);
}

body.rxs-ui-v2 .modal-backdrop {
    background: #05070a;
}

body.rxs-ui-v2 .modal-backdrop.show,
body.rxs-ui-v2 .modal-backdrop.in {
    opacity: .62;
}

/* entrada del modal acorde a la transicion de tabs */
body.rxs-ui-v2 .modal.fade .modal-dialog {
    transform: translateY(8px) scale(.99);
    transition: transform .18s ease-out;
}

body.rxs-ui-v2 .modal.fade.show .modal-dialog,
body.rxs-ui-v2 .modal.fade.in .modal-dialog {
    transform: none;
}

@media (prefers-reduced-motion: reduce) {
    body.rxs-ui-v2 .modal.fade .modal-dialog {
        transition: none;
    }
}

/* ---- v2 pass 7: overlays colgados de body (select2, datepicker, toasts, dropdowns) ---- */

/* select2 dropdown */
body.rxs-ui-v2 .select2-dropdown {
    background-color: var(--rx-v2-panel) !important;
    border: 1px solid var(--rx-v2-border) !important;
    border-radius: var(--rx-v2-r10);
    box-shadow: var(--rx-v2-shadow);
    color: var(--rx-v2-text);
    overflow: hidden;
}

/* juntura input <-> dropdown: sin esto quedan dos radios encontrados (el input
   redondeado y el dropdown redondeado) con un escaloncito feo. Cuadramos el
   lado que se toca segun el dropdown abra abajo o arriba. */
body.rxs-ui-v2 .select2-dropdown--below {
    border-top: none !important;
    border-top-left-radius: 0;
    border-top-right-radius: 0;
}
body.rxs-ui-v2 .select2-dropdown--above {
    border-bottom: none !important;
    border-bottom-left-radius: 0;
    border-bottom-right-radius: 0;
}
body.rxs-ui-v2 .select2-container--open.select2-container--below .select2-selection {
    border-bottom-left-radius: 0 !important;
    border-bottom-right-radius: 0 !important;
}
body.rxs-ui-v2 .select2-container--open.select2-container--above .select2-selection {
    border-top-left-radius: 0 !important;
    border-top-right-radius: 0 !important;
}

body.rxs-ui-v2 .select2-search--dropdown {
    padding: 8px;
}

body.rxs-ui-v2 .select2-search--dropdown .select2-search__field {
    background: var(--rx-v2-field) !important;
    border: 1px solid var(--rx-v2-border) !important;
    border-radius: var(--rx-v2-r8);
    color: var(--rx-v2-text) !important;
    min-height: 32px;
    outline: none;
    padding: 4px 10px;
}

body.rxs-ui-v2 .select2-results__option {
    color: var(--rx-v2-text);
    font-size: 13px;
    padding: 7px 12px;
}

body.rxs-ui-v2 .select2-results__option[aria-selected="true"],
body.rxs-ui-v2 .select2-results__option--selected {
    background: var(--rx-v2-ghost);
}

body.rxs-ui-v2 .select2-container--default .select2-results__option--highlighted[aria-selected],
body.rxs-ui-v2 .select2-results__option--highlighted {
    background: var(--rx-v2-accent) !important;
    color: var(--rx-v2-accent-ink) !important;
}

body.rxs-ui-v2 .select2-results__message {
    color: var(--rx-v2-muted);
}

/* dropdown-menu generico (topbar ya tiene el suyo, esto cubre el resto) */
body.rxs-ui-v2 .dropdown-menu {
    background: var(--rx-v2-panel);
    border: 1px solid var(--rx-v2-border);
    border-radius: var(--rx-v2-r10);
    box-shadow: var(--rx-v2-shadow);
    color: var(--rx-v2-text);
}

body.rxs-ui-v2 .dropdown-menu .dropdown-item {
    color: var(--rx-v2-text);
}

body.rxs-ui-v2 .dropdown-menu .dropdown-item:hover,
body.rxs-ui-v2 .dropdown-menu .dropdown-item:focus {
    background: var(--rx-v2-ghost);
    color: var(--rx-v2-text);
}

body.rxs-ui-v2 .dropdown-divider {
    border-color: var(--rx-v2-border-soft);
}

/* coleccion colvis / export de DataTables */
body.rxs-ui-v2 .dt-button-collection {
    background: var(--rx-v2-panel);
    border: 1px solid var(--rx-v2-border);
    border-radius: var(--rx-v2-r10);
    box-shadow: var(--rx-v2-shadow);
    padding: 6px;
}

body.rxs-ui-v2 .dt-button-collection .dt-button {
    background: transparent !important;
    border: 0 !important;
    border-radius: var(--rx-v2-r7);
    box-shadow: none;
    color: var(--rx-v2-text) !important;
    margin: 1px 0;
    text-align: left;
}

body.rxs-ui-v2 .dt-button-collection .dt-button:hover {
    background: var(--rx-v2-ghost) !important;
}

body.rxs-ui-v2 .dt-button-collection .dt-button.active {
    background: var(--rx-v2-accent-soft) !important;
    color: var(--rx-v2-text) !important;
}

body.rxs-ui-v2 .dt-button-background {
    background: transparent;
}

/* bootstrap-datepicker */
body.rxs-ui-v2 .datepicker.dropdown-menu {
    padding: 8px;
}

body.rxs-ui-v2 .datepicker table tr td,
body.rxs-ui-v2 .datepicker table tr th {
    border-radius: var(--rx-v2-r7);
    color: var(--rx-v2-text);
}

body.rxs-ui-v2 .datepicker table tr td.old,
body.rxs-ui-v2 .datepicker table tr td.new {
    color: var(--rx-v2-faint);
}

body.rxs-ui-v2 .datepicker table tr td.day:hover,
body.rxs-ui-v2 .datepicker table tr td span:hover,
body.rxs-ui-v2 .datepicker .datepicker-switch:hover,
body.rxs-ui-v2 .datepicker .prev:hover,
body.rxs-ui-v2 .datepicker .next:hover {
    background: var(--rx-v2-ghost);
}

body.rxs-ui-v2 .datepicker table tr td.active,
body.rxs-ui-v2 .datepicker table tr td.active:hover,
body.rxs-ui-v2 .datepicker table tr td span.active {
    background: var(--rx-v2-accent) !important;
    background-image: none !important;
    color: var(--rx-v2-accent-ink) !important;
    text-shadow: none;
}

body.rxs-ui-v2 .datepicker table tr td.today {
    background: var(--rx-v2-accent-soft) !important;
    background-image: none !important;
    color: var(--rx-v2-text) !important;
}

/* daterangepicker */
body.rxs-ui-v2 .daterangepicker {
    background: var(--rx-v2-panel);
    border: 1px solid var(--rx-v2-border);
    border-radius: var(--rx-v2-r10);
    box-shadow: var(--rx-v2-shadow);
    color: var(--rx-v2-text);
    font-family: var(--rx-v2-font);
}

body.rxs-ui-v2 .daterangepicker .calendar-table {
    background: transparent;
    border: 0;
}

body.rxs-ui-v2 .daterangepicker td,
body.rxs-ui-v2 .daterangepicker th {
    color: var(--rx-v2-text);
}

body.rxs-ui-v2 .daterangepicker td.off {
    background: transparent;
    color: var(--rx-v2-faint);
}

body.rxs-ui-v2 .daterangepicker td.available:hover,
body.rxs-ui-v2 .daterangepicker th.available:hover {
    background: var(--rx-v2-ghost);
    color: var(--rx-v2-text);
}

body.rxs-ui-v2 .daterangepicker td.in-range {
    background: var(--rx-v2-accent-soft);
    color: var(--rx-v2-text);
}

body.rxs-ui-v2 .daterangepicker td.active,
body.rxs-ui-v2 .daterangepicker td.active:hover {
    background: var(--rx-v2-accent);
    color: var(--rx-v2-accent-ink);
}

body.rxs-ui-v2 .daterangepicker .ranges li:hover {
    background: var(--rx-v2-ghost);
}

body.rxs-ui-v2 .daterangepicker .ranges li.active {
    background: var(--rx-v2-accent);
    color: var(--rx-v2-accent-ink);
}

body.rxs-ui-v2 .daterangepicker:after,
body.rxs-ui-v2 .daterangepicker:before {
    border-bottom-color: var(--rx-v2-border);
}

body.rxs-ui-v2 .daterangepicker .drp-buttons {
    border-top: 1px solid var(--rx-v2-border-soft);
}

body.rxs-ui-v2 .daterangepicker select.hourselect,
body.rxs-ui-v2 .daterangepicker select.minuteselect,
body.rxs-ui-v2 .daterangepicker select.secondselect,
body.rxs-ui-v2 .daterangepicker select.ampmselect,
body.rxs-ui-v2 .daterangepicker .calendar-table select {
    background: var(--rx-v2-field);
    border: 1px solid var(--rx-v2-border);
    border-radius: var(--rx-v2-r6);
    color: var(--rx-v2-text);
}

/* toasts jq-toast: panel + borde semantico, sin icono PNG blanco
 * (era invisible en claro); el heading ya dice exito/error */
body.rxs-ui-v2 .jq-toast-single {
    background: var(--rx-v2-panel) !important;
    background-image: none !important;
    border: 1px solid var(--rx-v2-border);
    border-left: 3px solid var(--rx-v2-accent);
    border-radius: var(--rx-v2-r10);
    box-shadow: var(--rx-v2-shadow);
    color: var(--rx-v2-text) !important;
    font-family: var(--rx-v2-font);
    font-size: 13px;
    line-height: 1.45;
    padding: 12px 14px;
}

body.rxs-ui-v2 .jq-toast-single.jq-icon-success {
    border-left-color: #2ecf6e;
}

body.rxs-ui-v2 .jq-toast-single.jq-icon-warning {
    border-left-color: #f5b83d;
}

body.rxs-ui-v2 .jq-toast-single.jq-icon-error {
    border-left-color: #f4506c;
}

body.rxs-ui-v2 .jq-toast-single.jq-icon-info {
    border-left-color: #4aa3f0;
}

body.rxs-ui-v2 .jq-toast-single h2,
body.rxs-ui-v2 .jq-toast-heading {
    color: var(--rx-v2-text);
    font-family: var(--rx-v2-font);
    font-size: 13px;
    font-weight: 600;
    margin: 0 0 3px;
}

body.rxs-ui-v2 .jq-toast-single a {
    color: var(--rx-v2-accent);
}

body.rxs-ui-v2 .close-jq-toast-single {
    color: var(--rx-v2-muted);
    font-size: 16px;
    top: 4px;
}

body.rxs-ui-v2 .jq-toast-loader {
    border-radius: var(--rx-v2-r10) var(--rx-v2-r10) 0 0;
    height: 3px;
}

/* tooltips bootstrap */
body.rxs-ui-v2 .tooltip-inner {
    background: var(--rx-v2-active);
    border: 1px solid var(--rx-v2-border);
    border-radius: var(--rx-v2-r7);
    color: var(--rx-v2-text);
    font-family: var(--rx-v2-font);
    font-size: 12px;
}

body.rxs-ui-v2 .tooltip .arrow::before,
body.rxs-ui-v2 .tooltip .tooltip-arrow::before {
    border-top-color: var(--rx-v2-active);
}

body.rxs-ui-v2 .daterangepicker .drp-buttons .btn.applyBtn {
    background: var(--rx-v2-accent) !important;
    border: 0;
    color: var(--rx-v2-accent-ink) !important;
}

body.rxs-ui-v2 .daterangepicker .drp-buttons .btn.cancelBtn {
    background: var(--rx-v2-ghost) !important;
    border: 1px solid var(--rx-v2-border) !important;
    color: var(--rx-v2-muted) !important;
}

body.rxs-ui-v2 .daterangepicker .drp-selected {
    color: var(--rx-v2-muted);
}

/* ---- v2 pass 8: chips de filtros activos ---- */

body.rxs-ui-v2 .rxs-module .rxs-filter-chips {
    display: none;
}

body.rxs-ui-v2 .rxs-module .rxs-filter-chips.rxs-has-chips {
    align-items: center;
    border-bottom: 1px solid var(--rx-v2-border-soft);
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    padding: 8px 16px;
}

body.rxs-ui-v2 .rxs-module .rxs-chip {
    align-items: center;
    background: var(--rx-v2-accent-soft);
    border: 1px solid transparent;
    border-radius: 999px;
    display: inline-flex;
    gap: 6px;
    height: 26px;
    max-width: 340px;
    padding: 0 4px 0 10px;
}

body.rxs-ui-v2 .rxs-module .rxs-chip-l {
    color: var(--rx-v2-muted);
    font-size: 10px;
    font-weight: 600;
    letter-spacing: .05em;
    text-transform: uppercase;
    white-space: nowrap;
}

body.rxs-ui-v2 .rxs-module .rxs-chip-v {
    color: var(--rx-v2-text);
    font-size: 12px;
    font-weight: 500;
    max-width: 220px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

body.rxs-ui-v2 .rxs-module .rxs-chip-x {
    align-items: center;
    background: transparent;
    border: 0;
    border-radius: 50%;
    color: var(--rx-v2-muted);
    cursor: pointer;
    display: inline-flex;
    font-size: 14px;
    height: 18px;
    justify-content: center;
    line-height: 1;
    padding: 0;
    width: 18px;
}

body.rxs-ui-v2 .rxs-module .rxs-chip-x:hover {
    background: var(--rx-v2-accent);
    color: var(--rx-v2-accent-ink);
}

body.rxs-ui-v2 .rxs-module .rxs-chips-clear,
body.rxs-ui-v2 .rxs-module .rxs-chips-order-reset {
    background: transparent;
    border: 0;
    border-radius: var(--rx-v2-r7);
    color: var(--rx-v2-muted);
    cursor: pointer;
    font-size: 11.5px;
    font-weight: 600;
    height: 26px;
    padding: 0 8px;
}

body.rxs-ui-v2 .rxs-module .rxs-chips-clear:hover,
body.rxs-ui-v2 .rxs-module .rxs-chips-order-reset:hover {
    background: var(--rx-v2-ghost);
    color: var(--rx-v2-text);
}

/* Barra del drill de un KPI (rxsDrillChipsHtml): las condiciones las puso el tablero, no el
   usuario, asi que sus chips no llevan boton de quitar — y sin ese boton el padding derecho
   vuelve a ser el mismo que el izquierdo. */
body.rxs-ui-v2 .rxs-module .rxs-drill-chips .rxs-chip {
    padding-right: 10px;
}

/* ---- v2 pass 8b: pills semanticas en columnas enumerables ---- */
/* --rxp = hue deterministico por valor (lo setea ui_v2.js) */

/* el tinte de la pill es translucido: sobre una fila con color de estado se mezclaba con
 * el fondo y la pill dejaba de leerse. Va sobre el panel opaco (background-color) y el
 * tinte encima como capa, asi la pill se ve igual con o sin color de fila.
 * `.rxs-v2-pills` es la puerta para un componente que dibuja sus propias pills fuera de la
 * grilla y de las cards (el hilo social, el panel de facetas): la misma pill, con su tono
 * en --rxp (rxsPillHue), y el modo oscuro sale solo de los --rx-tint-*. */
body.rxs-ui-v2 .rxs-module table.rxs-table .rxs-pill,
body.rxs-ui-v2 .rxs-v2-card .rxs-pill,
body.rxs-ui-v2 .rxs-v2-pills .rxs-pill {
    background-color: var(--rx-v2-panel);
    background-image: linear-gradient(hsl(var(--rxp) var(--rx-tint-s) var(--rx-tint-l) / var(--rx-tint-a)), hsl(var(--rxp) var(--rx-tint-s) var(--rx-tint-l) / var(--rx-tint-a)));
    border-radius: 999px;
    color: hsl(var(--rxp) var(--rx-tint-ink-s) var(--rx-tint-ink-l));
    display: inline-block;
    font-size: 12px;
    font-weight: 500;
    line-height: 1.5;
    max-width: 100%;
    overflow: hidden;
    padding: 2px 10px;
    text-overflow: ellipsis;
    vertical-align: middle;
    white-space: nowrap;
}

/* oscuro y vivid no repiten la regla: redefinen los --rx-tint-* del body */

/* ---- v2 pass 8c: login / register / recpw ---- */

body.rxs-ui-v2 .login-register {
    background: var(--rx-v2-bg);
}

body.rxs-ui-v2 .login-register .login-box.card,
body.rxs-ui-v2 .login-register .card {
    background: var(--rx-v2-panel);
    border: 1px solid var(--rx-v2-border);
    border-radius: var(--rx-v2-r16);
    box-shadow: var(--rx-v2-shadow);
    color: var(--rx-v2-text);
}

body.rxs-ui-v2 .login-register .box-title {
    color: var(--rx-v2-text);
}

/* inputs material -> campos v2 */
body.rxs-ui-v2 .login-register .form-material .form-control,
body.rxs-ui-v2 .login-register .form-control {
    background: var(--rx-v2-field) !important;
    background-image: none !important;
    border: 1px solid var(--rx-v2-border);
    border-radius: var(--rx-v2-r10);
    color: var(--rx-v2-text);
    height: 42px;
    padding: 8px 38px 8px 12px;
    transition: border-color .15s ease, box-shadow .15s ease;
}

body.rxs-ui-v2 .login-register .form-control:focus {
    outline: none;
}

body.rxs-ui-v2 .login-register .form-control::placeholder {
    color: var(--rx-v2-faint);
}

body.rxs-ui-v2 .login-register .form-group {
    margin-bottom: 14px;
}

body.rxs-ui-v2 .login-register .form-control-feedback {
    color: var(--rx-v2-faint);
    line-height: 42px;
    right: 12px;
    position: absolute;
}

body.rxs-ui-v2 .login-register .form-group.has-feedback {
    position: relative;
}

/* boton principal */
body.rxs-ui-v2 .login-register .stvLoginBtn {
    background: var(--rx-v2-accent) !important;
    border: 0;
    border-radius: var(--rx-v2-r10);
    box-shadow: none;
    color: var(--rx-v2-accent-ink) !important;
    font-size: 13px;
    font-weight: 650;
    height: 42px;
    letter-spacing: .04em;
}

body.rxs-ui-v2 .login-register .stvLoginBtn:hover {
    filter: brightness(1.08);
}

body.rxs-ui-v2 .login-register .stvLoginBtn.rxsDisabled {
    filter: grayscale(.5) brightness(.8);
}

/* social: circulos ghost */
body.rxs-ui-v2 .login-register .social .btn {
    align-items: center;
    background: var(--rx-v2-ghost) !important;
    border: 1px solid var(--rx-v2-border) !important;
    border-radius: 50%;
    color: var(--rx-v2-muted) !important;
    display: inline-flex;
    height: 40px;
    justify-content: center;
    margin: 0 3px;
    width: 40px;
}

body.rxs-ui-v2 .login-register .social .btn:hover {
    border-color: var(--rx-v2-accent) !important;
    color: var(--rx-v2-accent) !important;
}

body.rxs-ui-v2 .login-register a {
    color: var(--rx-v2-accent);
}

body.rxs-ui-v2 .login-register .alert-danger {
    background: rgba(244, 80, 108, .12);
    border: 1px solid rgba(244, 80, 108, .4);
    border-radius: var(--rx-v2-r10);
    color: #f4506c;
}

/* login: refuerzos contra current48 (usa !important) y variante input-group */

/* -- El fondo de las publicas (login / register / recpw) --------------------
 * Aca habia un `background: var(--rx-v2-bg) !important` que tapaba con un gris
 * plano el degrade de marca que current48 ya le da a esta pantalla
 * (`.thr-anim.no-logged`). El !important era contra current48, pero se llevo
 * puesto tambien el color del cliente: las tres pantallas publicas quedaron
 * grises en todos los tenants.
 *
 * El fondo lo pinta ahora `.rxsLoginBg`, una capa que el PHP emite ADENTRO del
 * fragmento (ver rxsLoginBgLayer() en functions/domain.php). No en el <body>:
 * el boton "Ingresar" del sitio publico no navega, pide /mo/login y el SPA
 * reemplaza solo el interior de #maincontent, asi que el body de esa pagina es
 * el de la home y una clase ahi se ve por una puerta y no por la otra.
 *
 * Del body queda solo el color de base, que es lo que ve el rebote del scroll
 * en el telefono -con la capa sola quedaba blanco en los bordes-. */
body.rxs-ui-v2.no-logged {
    background-color: var(--rx-color1, #1e88e5) !important;
    background-image: none !important;
}

/* La capa. El degrade y la trama salen de `--rxs-gr` / `--rxs-pt`, que ponen
 * las clases del catalogo de njs/custom.css: lo que el tenant elige en Sitios >
 * Parametros llega hasta aca sin una linea de CSS nueva. El fallback es el
 * degrade de los colores del sitio.
 *
 * Van los dos colores y no los tres: con `--rx-color3` adentro son cinco
 * paradas repartidas en el ancho de la pantalla y salen bandas duras (en
 * resumax el 3 es un amarillo claro y cortaba el medio en diagonal). Con 1-2-1
 * las dos transiciones son largas y el fondo queda parejo.
 *
 * Y sin animacion: current48 la mueve agrandando el fondo al 600%, que ademas
 * de dejar el encuadre adentro de UNA parada -la marca se ve monocromatica-
 * cuesta 60 recalc/s que no se frenan con la pestana en segundo plano (ver el
 * bloque de `animation: none` mas arriba). A tamano natural entran los dos
 * colores enteros y no hay nada que mover. */
/* el selector cuelga de #maincontent porque mas arriba v2 pone
 * `#maincontent > * { position: relative }`, y un id le gana a cualquier
 * cantidad de clases: sin el id la capa se quedaba en relative, el inset:0 no
 * hacia nada y quedaba con 0 de alto (invisible, pero con el fondo "puesto") */
body.rxs-ui-v2 #maincontent > .rxsLoginBg {
    background-image:
        var(--rxs-pt, none),
        var(--rxs-gr, linear-gradient(-45deg,
            var(--rx-color1, #1e88e5),
            var(--rx-color2, #10192e),
            var(--rx-color1, #1e88e5)));
    background-repeat: repeat, no-repeat;
    background-size: auto, cover;
    inset: 0;
    pointer-events: none;
    /* absolute: #maincontent es position:relative y en estas pantallas se queda
     * sin padding (ver el bloque del scroll), asi que su caja YA es exactamente
     * el area de contenido y la capa cae clavada entre la topbar y el footer.
     * Es lo que hace falta en las dos pantallas que TIENEN chrome: el sitio con
     * vidriera (.not-logged) y el admin que abre la vista publica con sesion.
     * Pintar el body ahi dejaria el degrade DEBAJO del sidebar y del footer. */
    position: absolute;
}
/* Sin chrome (`.no-logged`, el sitio con public=0) no hay nada que respetar y
 * la capa toma la pantalla entera: con absolute arrancaba recien abajo de los
 * 60px que `thr-fix` le reserva a una topbar que en esta pantalla ni existe, y
 * dejaba una banda mas clara cruzando el borde de arriba. */
body.rxs-ui-v2.no-logged #maincontent > .rxsLoginBg {
    position: fixed;
}
/* el wrapper y el page-wrapper pintan --rx-v2-bg y son posteriores a la capa en
 * el DOM: sin esto el gris la tapa desde adentro */
body.rxs-ui-v2 #maincontent > .login-register,
body.rxs-ui-v2.no-logged .page-wrapper {
    background: transparent !important;
    background-color: transparent !important;
}

body.rxs-ui-v2 .login-register .login-box.card,
body.rxs-ui-v2 .login-register .card {
    background: var(--rx-v2-panel) !important;
    border: 1px solid var(--rx-v2-border) !important;
}

body.rxs-ui-v2 .login-register .box-title,
body.rxs-ui-v2 .login-register .card-body,
body.rxs-ui-v2 .login-register label {
    color: var(--rx-v2-text) !important;
}

body.rxs-ui-v2 .login-register .input-group-text {
    background: var(--rx-v2-ghost) !important;
    border: 1px solid var(--rx-v2-border) !important;
    border-radius: var(--rx-v2-r10) 0 0 var(--rx-v2-r10);
    border-right: 0 !important;
    color: var(--rx-v2-muted) !important;
}

body.rxs-ui-v2 .login-register .input-group .form-control {
    border-radius: 0 var(--rx-v2-r10) var(--rx-v2-r10) 0;
}

body.rxs-ui-v2 .login-register .input-group .form-control:first-child {
    border-radius: var(--rx-v2-r10);
}

/* botones secundarios (admin / sin contraseña / biometria): ghost */
body.rxs-ui-v2 .login-register .btn-block:not(.stvLoginBtn):not(.rxsAuth-cta),
body.rxs-ui-v2 .login-register .btnMailLogin {
    background: var(--rx-v2-ghost) !important;
    background-image: none !important;
    border: 1px solid var(--rx-v2-border) !important;
    border-radius: var(--rx-v2-r10);
    color: var(--rx-v2-muted) !important;
    font-weight: 600;
}

body.rxs-ui-v2 .login-register .btn-block:not(.stvLoginBtn):not(.rxsAuth-cta):hover,
body.rxs-ui-v2 .login-register .btnMailLogin:hover {
    border-color: var(--rx-v2-accent) !important;
    color: var(--rx-v2-text) !important;
}

/* ---- v2 pass 8d: barra flotante de seleccion masiva ---- */

body.rxs-ui-v2 .rxs-bulkbar {
    align-items: center;
    background: var(--rx-v2-panel);
    border: 1px solid var(--rx-v2-border);
    border-radius: var(--rx-v2-r14);
    bottom: 18px;
    box-shadow: var(--rx-v2-shadow);
    display: flex;
    gap: 8px;
    left: 50%;
    opacity: 0;
    padding: 8px 10px 8px 16px;
    pointer-events: none;
    position: fixed;
    transform: translate(-50%, 70px);
    transition: transform .2s ease, opacity .2s ease;
    z-index: 10040;
}

body.rxs-ui-v2 .rxs-bulkbar.rxs-open {
    opacity: 1;
    pointer-events: auto;
    transform: translate(-50%, 0);
}

body:not(.rxs-ui-v2) .rxs-bulkbar {
    display: none;
}

body.rxs-ui-v2 .rxs-bulkbar-count {
    color: var(--rx-v2-accent);
    font-size: 13px;
    font-weight: 650;
    white-space: nowrap;
}

body.rxs-ui-v2 .rxs-bulkbar-sep {
    background: var(--rx-v2-border);
    height: 20px;
    width: 1px;
}

body.rxs-ui-v2 .rxs-bulkbar-btn {
    align-items: center;
    background: var(--rx-v2-ghost);
    border: 1px solid var(--rx-v2-border-soft);
    border-radius: var(--rx-v2-r9);
    color: var(--rx-v2-text);
    cursor: pointer;
    display: inline-flex;
    font-size: 12.5px;
    font-weight: 600;
    gap: 6px;
    height: 32px;
    padding: 0 12px;
    white-space: nowrap;
}

body.rxs-ui-v2 .rxs-bulkbar-btn:hover {
    border-color: var(--rx-v2-accent);
    color: var(--rx-v2-accent);
}

body.rxs-ui-v2 .rxs-bulkbar-btn.rxs-bulkbar-none {
    background: transparent;
    border-color: transparent;
    color: var(--rx-v2-muted);
}

body.rxs-ui-v2 .rxs-bulkbar-btn.rxs-bulkbar-none:hover {
    color: var(--rx-v2-text);
}

@media (max-width: 767px) {
    body.rxs-ui-v2 .rxs-bulkbar {
        bottom: 76px;
        flex-wrap: wrap;
        justify-content: center;
        max-width: calc(100vw - 24px);
    }
}

/* filas seleccionadas (DataTables select usa .dtSelected) */
body.rxs-ui-v2 .rxs-module table.rxs-table tbody tr.dtSelected > td {
    background: var(--rx-v2-accent-soft) !important;
    box-shadow: inset 3px 0 0 var(--rx-v2-accent);
}

body.rxs-ui-v2 .rxs-module table.rxs-table tbody tr.dtSelected > td ~ td {
    box-shadow: none;
}

/* select "¿Que hacer?" que aparece con seleccion activa */
body.rxs-ui-v2 .select-info.rehead select.tableFilterSelect,
body.rxs-ui-v2 select.tableFilterSelect {
    background: var(--rx-v2-field) !important;
    border: 1px solid var(--rx-v2-border) !important;
    border-radius: var(--rx-v2-r8);
    color: var(--rx-v2-text) !important;
    font-size: 12.5px;
    height: 32px;
    padding: 4px 10px;
}

/* ---- v2 pass 9: boton volver ---- */

/* boton "Ir atras": de barra azul full-width a ghost compacto */
body.rxs-ui-v2 a[onclick*="stvBackBtn"] {
    display: inline-block;
    margin: 4px 0 10px;
}

body.rxs-ui-v2 a[onclick*="stvBackBtn"] .btn {
    background: var(--rx-v2-ghost) !important;
    border: 1px solid var(--rx-v2-border) !important;
    border-radius: var(--rx-v2-r9);
    box-shadow: none;
    color: var(--rx-v2-muted) !important;
    display: inline-flex;
    align-items: center;
    gap: 7px;
    font-size: 12.5px;
    font-weight: 600;
    height: 32px;
    padding: 0 14px;
    width: auto;
}

body.rxs-ui-v2 a[onclick*="stvBackBtn"] .btn:hover {
    border-color: var(--rx-v2-accent) !important;
    color: var(--rx-v2-text) !important;
}

/* input de rango de fechas del tab de graficos.
   El !important del radio es por BS5: su regla .input-group > :not(:first-child)
   pone las esquinas izquierdas en 0 para CUALQUIER hijo, mientras que BS4 solo
   se lo hacia a .form-control / .custom-select — y este input no lleva ninguna
   de las dos. Sin esto el filtro de fechas pierde el redondeo bajo ?bs=5. */
body.rxs-ui-v2 .dateFilter,
body.rxs-ui-v2 input.dateFilter {
    background: var(--rx-v2-field) !important;
    border: 1px solid var(--rx-v2-border) !important;
    border-radius: var(--rx-v2-r8) !important;
    color: var(--rx-v2-text) !important;
}

/* ---- v2 pass 9b: modo excel / uploads / cards de busqueda ---- */

/* dropzone de bootstrap-fileinput (franja blanca) */
body.rxs-ui-v2 .file-drop-zone {
    background: var(--rx-v2-field) !important;
    border: 1px dashed var(--rx-v2-border) !important;
    border-radius: var(--rx-v2-r10);
    color: var(--rx-v2-muted) !important;
}

body.rxs-ui-v2 .file-drop-zone-title {
    color: var(--rx-v2-muted);
}

body.rxs-ui-v2 .file-preview {
    background: transparent;
    border: 0;
    padding: 0;
}

/* controles nativos sueltos en tab-panes (fuera de rxs-form): textarea de
 * pegado JSON, selects de tipo de carga, etc. */
body.rxs-ui-v2 .tab-pane textarea.form-control,
body.rxs-ui-v2 .tab-pane input.form-control:not([class*="yadcf"]),
body.rxs-ui-v2 .tab-pane select:not(.select2-hidden-accessible):not([class*="yadcf"]) {
    background: var(--rx-v2-field) !important;
    border: 1px solid var(--rx-v2-border) !important;
    border-radius: var(--rx-v2-r8);
    color: var(--rx-v2-text) !important;
}

/* CTA primario legacy (btn-success/btn-info block): al accent del sistema */
body.rxs-ui-v2 #maincontent .btn-success.btn-block,
body.rxs-ui-v2 #maincontent .btn-info.btn-block.btn-lg {
    background: var(--rx-v2-accent) !important;
    background-image: none !important;
    border: 0 !important;
    border-radius: var(--rx-v2-r10);
    color: var(--rx-v2-accent-ink) !important;
    font-weight: 650;
}

body.rxs-ui-v2 #maincontent .btn-success.btn-block:hover,
body.rxs-ui-v2 #maincontent .btn-info.btn-block.btn-lg:hover {
    filter: brightness(1.08);
}

/* botones de accion en cards Vue (busqueda / modo lista): ghost compactos */
body.rxs-ui-v2 .stvVueAction .btn:not(:where(.rxsBtnsOwn .btn)) {
    background: var(--rx-v2-ghost) !important;
    border: 1px solid var(--rx-v2-border-soft) !important;
    border-radius: var(--rx-v2-r7);
    box-shadow: none;
    color: var(--rx-v2-muted) !important;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    height: 30px;
    min-width: 30px;
    width: auto;
}

body.rxs-ui-v2 .stvVueAction .btn:not(:where(.rxsBtnsOwn .btn)):hover {
    background: var(--rx-v2-accent) !important;
    border-color: var(--rx-v2-accent) !important;
    color: var(--rx-v2-accent-ink) !important;
}

/* ---- v2 pass 9c: mysettings y paginas "box" ---- */

/* campos sueltos en cualquier contenido (mysettings, paneles legacy) */
body.rxs-ui-v2 #maincontent select:not(.select2-hidden-accessible):not([class*="yadcf"]),
body.rxs-ui-v2 #maincontent input.form-control:not([class*="yadcf"]),
body.rxs-ui-v2 #maincontent textarea.form-control {
    background: var(--rx-v2-field) !important;
    border: 1px solid var(--rx-v2-border) !important;
    border-radius: var(--rx-v2-r8);
    color: var(--rx-v2-text) !important;
}
body.rxs-ui-v2 #maincontent input.form-control:not([class*="yadcf"])::placeholder{
    color: var(--rx-v2-text) !important;
}
body.rxs-ui-v2 #maincontent label {
    color: var(--rx-v2-muted);
}

/* botones legacy azules/rosas en paginas box (mysettings): a tokens */
body.rxs-ui-v2 .box .btn-info,
body.rxs-ui-v2 .box .btn-primary {
    background: var(--rx-v2-accent-soft) !important;
    background-image: none !important;
    border: 1px solid var(--rx-v2-accent) !important;
    border-radius: var(--rx-v2-r9);
    box-shadow: none;
    color: var(--rx-v2-accent) !important;
    font-weight: 600;
}

body.rxs-ui-v2 .box .btn-info:hover,
body.rxs-ui-v2 .box .btn-primary:hover {
    background: var(--rx-v2-accent) !important;
    color: var(--rx-v2-accent-ink) !important;
}

body.rxs-ui-v2 .box .btn-danger {
    background: transparent !important;
    border: 1px solid rgba(244, 80, 108, .5) !important;
    border-radius: var(--rx-v2-r9);
    color: #f4506c !important;
    font-weight: 600;
}

body.rxs-ui-v2 .box .btn-danger:hover {
    background: rgba(244, 80, 108, .15) !important;
}

/* paginas "box" (mysettings, notificaciones, etc): el .box ES el panel de la pagina,
 * asi que se pinta como card. Solo se deja transparente cuando envuelve un modulo de
 * tabla propio (.rxs-module / .stvModuleTable), que ya dibuja su panel y duplicaria. */
body.rxs-ui-v2 .box.nav-tabs-custom.card {
    background: var(--rx-v2-panel);
    border: 1px solid var(--rx-v2-border);
    border-radius: var(--rx-v2-r12);
    box-shadow: var(--rx-v2-shadow);
}

body.rxs-ui-v2 .box.nav-tabs-custom.card:has(.rxs-module),
body.rxs-ui-v2 .box.nav-tabs-custom.card:has(.stvModuleTable) {
    background: transparent;
    border: 0;
    box-shadow: none;
}

/* ---- v2 pass 9d: /notifications y loadmore ---- */

/* .rxs-module es flex column: los col-* de bootstrap traen flex-basis 100%
 * que en columna se interpreta como ALTO -> neutralizar en hijos directos */
body.rxs-ui-v2 .rxs-module > [class*="col-"] {
    flex: 0 0 auto !important;
    width: 100%;
}

body.rxs-ui-v2 .rxs-module .stvLoadMore-Container {
    background: transparent !important;
    background-image: none !important;
    padding: 10px 16px 16px;
}

body.rxs-ui-v2 .rxs-module .stvLoadMore-Container .btn {
    background: var(--rx-v2-ghost) !important;
    background-image: none !important;
    border: 1px solid var(--rx-v2-border) !important;
    border-radius: var(--rx-v2-r9);
    box-shadow: none;
    color: var(--rx-v2-muted) !important;
    font-weight: 600;
}

body.rxs-ui-v2 .rxs-module .stvLoadMore-Container .btn:hover {
    border-color: var(--rx-v2-accent) !important;
    color: var(--rx-v2-text) !important;
}

/* ---- v2 pass 9e: panel de chat asistente ---- */

body.rxs-ui-v2 .chat-container.chat-whatsapp-style {
    background: var(--rx-v2-panel);
    border: 1px solid var(--rx-v2-border);
    border-radius: var(--rx-v2-r14);
    box-shadow: var(--rx-v2-shadow);
    overflow: hidden;
}

body.rxs-ui-v2 .chat-container .chatbox {
    background: var(--rx-v2-bg) !important;
    background-image: none !important;
}

body.rxs-ui-v2 .chat-container .message-content {
    background: var(--rx-v2-panel-2) !important;
    border: 1px solid var(--rx-v2-border-soft);
    color: var(--rx-v2-text) !important;
}

body.rxs-ui-v2 .chat-container .user-message .message-content {
    background: var(--rx-v2-accent-soft) !important;
    border-color: transparent;
}

body.rxs-ui-v2 .chat-container .chat-footer {
    background: var(--rx-v2-head) !important;
    border-top: 1px solid var(--rx-v2-border-soft);
}

body.rxs-ui-v2 .chat-container .chat-footer .btn-light {
    background: transparent !important;
    border: 0 !important;
    color: var(--rx-v2-muted) !important;
}

/* ---- v2 pass 9f: fullcalendar 6 (variables --fc-*) ---- */

body.rxs-ui-v2 .fc {
    --fc-border-color: var(--rx-v2-border-soft);
    --fc-page-bg-color: transparent;
    --fc-neutral-bg-color: var(--rx-v2-panel-2);
    --fc-today-bg-color: var(--rx-v2-accent-soft);
    --fc-button-bg-color: var(--rx-v2-ghost);
    --fc-button-border-color: var(--rx-v2-border);
    --fc-button-text-color: var(--rx-v2-text);
    --fc-button-hover-bg-color: var(--rx-v2-hover);
    --fc-button-hover-border-color: var(--rx-v2-accent);
    --fc-button-active-bg-color: var(--rx-v2-accent);
    --fc-button-active-border-color: var(--rx-v2-accent);
    --fc-event-bg-color: var(--rx-v2-accent);
    --fc-event-border-color: var(--rx-v2-accent);
    --fc-event-text-color: var(--rx-v2-accent-ink);
    --fc-list-event-hover-bg-color: var(--rx-v2-hover);
    --fc-highlight-color: var(--rx-v2-accent-soft);
}

body.rxs-ui-v2 .fc .fc-button {
    border-radius: var(--rx-v2-r8);
    box-shadow: none !important;
    font-weight: 600;
}

body.rxs-ui-v2 .fc .fc-button-active {
    color: var(--rx-v2-accent-ink) !important;
}

body.rxs-ui-v2 .fc .fc-toolbar-title {
    color: var(--rx-v2-text);
    font-size: 18px;
    font-weight: 650;
    letter-spacing: -.01em;
}

/* njs/custom.css ya baja el titulo a 15px en mobile, pero lo hace sin el
 * body.rxs-ui-v2 de esta regla, asi que en v2 nunca se aplicaba: el titulo
 * seguia en 18px y empujaba a los botones a otro renglon. */
@media (max-width: 767px) {
    body.rxs-ui-v2 .fc .fc-toolbar-title {
        font-size: 15px;
    }
}

body.rxs-ui-v2 .fc .fc-col-header-cell-cushion,
body.rxs-ui-v2 .fc .fc-timegrid-slot-label-cushion,
body.rxs-ui-v2 .fc .fc-timegrid-axis-cushion,
body.rxs-ui-v2 .fc .fc-daygrid-day-number {
    color: var(--rx-v2-muted);
    font-size: 12px;
    font-weight: 600;
}

body.rxs-ui-v2 .fc .fc-col-header-cell.fc-day-today .fc-col-header-cell-cushion {
    color: var(--rx-v2-accent);
}

/* ---- v2 pass 9g: botonera de tipos de grafico ---- */

body.rxs-ui-v2 .chart-mode-btn {
    background: var(--rx-v2-ghost) !important;
    border: 1px solid var(--rx-v2-border-soft) !important;
    border-radius: var(--rx-v2-r8);
    box-shadow: none;
    color: var(--rx-v2-muted) !important;
    font-weight: 600;
    margin: 0 2px 2px 0;
}

body.rxs-ui-v2 .chart-mode-btn:hover {
    border-color: var(--rx-v2-accent) !important;
    color: var(--rx-v2-text) !important;
}

body.rxs-ui-v2 .chart-mode-btn.active {
    background: var(--rx-v2-accent) !important;
    border-color: var(--rx-v2-accent) !important;
    color: var(--rx-v2-accent-ink) !important;
}

/* menu vertical de acciones masivas (comparte base con .rxs-row-menu) */
body.rxs-ui-v2 .rxs-bulk-menu {
    flex-direction: column;
    min-width: 200px;
    padding: 5px;
}

body.rxs-ui-v2 .rxs-bulk-menu-item {
    background: transparent;
    border: 0;
    border-radius: var(--rx-v2-r8);
    color: var(--rx-v2-text);
    cursor: pointer;
    font-size: 13px;
    padding: 8px 12px;
    text-align: left;
}

body.rxs-ui-v2 .rxs-bulk-menu-item:hover {
    background: var(--rx-v2-ghost);
}

/* campos y CTAs dentro de modales (sedit y similares, fuera de rxs-form) */
body.rxs-ui-v2 .modal select:not(.select2-hidden-accessible):not([class*="yadcf"]),
body.rxs-ui-v2 .modal input.form-control,
body.rxs-ui-v2 .modal textarea.form-control {
    background: var(--rx-v2-field) !important;
    border: 1px solid var(--rx-v2-border) !important;
    border-radius: var(--rx-v2-r8);
    color: var(--rx-v2-text) !important;
}

body.rxs-ui-v2 .modal .btn-success.btn-block,
body.rxs-ui-v2 .modal .btn-info.btn-block {
    background: var(--rx-v2-accent) !important;
    background-image: none !important;
    border: 0 !important;
    border-radius: var(--rx-v2-r10);
    color: var(--rx-v2-accent-ink) !important;
    font-weight: 650;
}

body.rxs-ui-v2 .modal .btn-success.btn-block:hover,
body.rxs-ui-v2 .modal .btn-info.btn-block:hover {
    filter: brightness(1.08);
}

body.rxs-ui-v2 .modal .alert,
body.rxs-ui-v2 .modal .callout {
    background: var(--rx-v2-accent-soft) !important;
    border: 1px solid var(--rx-v2-border-soft) !important;
    border-radius: var(--rx-v2-r10);
    color: var(--rx-v2-text) !important;
}

/* ---- v2 sweep fixes ---- */

/* seleccion: fondo OPACO (panel + tinte encima); el rgba solo dejaba ver
 * el contenido scrolleado debajo de las celdas sticky en light */
body.rxs-ui-v2 .rxs-module table.rxs-table tbody tr.dtSelected > td {
    background-color: var(--rx-v2-panel) !important;
    background-image: linear-gradient(var(--rx-v2-accent-soft), var(--rx-v2-accent-soft)) !important;
}

/* style.css (tema "Oscuro" por preferencia de usuario) pinta .fc-day sin scope;
 * en v2 mandan los tokens: celdas transparentes y hoy en accent-soft */
body.rxs-ui-v2 .fc .fc-day {
    background: transparent !important;
}

body.rxs-ui-v2 .fc .fc-day-today {
    background: var(--rx-v2-accent-soft) !important;
}

/* ---- v2 pass 10: fixes de auditoria general ---- */

/* /notifications y dropdown: las cards son <a class="notln">, el texto del
 * cuerpo y la fecha heredaban el naranja de link. Titulo en ink, resto muted */
body.rxs-ui-v2 a.notln,
body.rxs-ui-v2 a.notln:hover,
body.rxs-ui-v2 a.notln:focus {
    color: var(--rx-v2-muted);
}

body.rxs-ui-v2 a.notln h4,
body.rxs-ui-v2 a.notln h5 {
    color: var(--rx-v2-text);
}

/* btn-themecolor usado como SUPERFICIE (no boton): card-headers tipo la barra
 * "Mensajes" del componente de comentarios -> head token, sin gradiente */
body.rxs-ui-v2 .card-header.btn-themecolor {
    background: var(--rx-v2-head) !important;
    background-image: none !important;
    border-bottom: 1px solid var(--rx-v2-border-soft);
    color: var(--rx-v2-text) !important;
}

body.rxs-ui-v2 .card-header.btn-themecolor .bg-light {
    background: transparent !important;
    border: 0 !important;
}

body.rxs-ui-v2 .card-header.btn-themecolor .btn {
    background: var(--rx-v2-ghost);
    border: 1px solid var(--rx-v2-border-soft);
    border-radius: var(--rx-v2-r7);
    color: var(--rx-v2-muted);
}

body.rxs-ui-v2 .card-header.btn-themecolor .btn:hover,
body.rxs-ui-v2 .card-header.btn-themecolor .btn.active {
    background: var(--rx-v2-accent-soft);
    color: var(--rx-v2-accent);
}

/* circulo gigante de empty state (nof-icon): accent suave en vez del gradiente */
body.rxs-ui-v2 .nof-icon {
    background: var(--rx-v2-accent-soft) !important;
    background-image: none !important;
    color: var(--rx-v2-accent) !important;
}

/* fila "Modo Oscuro" del dropdown de usuario: color legacy #2c3e50 ilegible */
body.rxs-ui-v2 .dropdown-menu .rxsCheck2 {
    color: var(--rx-v2-muted);
}

/* buscador del topbar: panel tokenizado en vez del borde naranja legacy */
body.rxs-ui-v2 .app-search {
    background: var(--rx-v2-panel) !important;
    border: 1px solid var(--rx-v2-border-soft) !important;
    box-shadow: var(--rx-v2-shadow);
}

body.rxs-ui-v2 .app-search input.form-control {
    background: transparent !important;
    border: 0 !important;
    box-shadow: none !important;
    color: var(--rx-v2-text);
}

body.rxs-ui-v2 .app-search .srh-btn {
    color: var(--rx-v2-muted);
}

/* cards del modo lista / busqueda: acciones en una sola fila (los .col de
 * bootstrap dentro de la card angosta rompian a dos filas desalineadas) */
body.rxs-ui-v2 .stvVueAction {
    flex-wrap: nowrap;
    gap: 6px;
}

body.rxs-ui-v2 .stvVueAction .stvCol {
    flex: 0 0 auto !important;
    max-width: none;
    padding: 0;
    width: auto;
}

/* ---- vista card (listStvVue): toggle "Cambiar vista" del listado ----
 * OJO: estas reglas son para las cards VUE legacy. El contenedor de la grilla v2
 * (.rxsV2Cards) reusa las mismas clases de layout (.listStvVue/.rcol) pero trae su
 * propio diseño (§21/§22), así que queda excluido con :not(.rxsV2Cards) — si no, el
 * `height:130px` de la imagen de acá le comía la foto de la galería. */
/* El markup trae la row con align-items-center + imagenes floteadas sin
 * dimension: las cards quedaban a distinta altura (staggered) y las fotos
 * ovaladas. Las estiramos a igual alto y volvemos cada .rcol una card-column
 * tokenizada con thumbnail de aspecto fijo y botones pegados abajo. */
body.rxs-ui-v2 .listStvVue {
    align-items: stretch !important;
    row-gap: 14px;
}
body.rxs-ui-v2 .listStvVue:not(.rxsV2Cards) .rcol {
    display: flex;
    flex-direction: column;
    height: 100%;
    background: var(--rx-v2-panel);
    border: 1px solid var(--rx-v2-border);
    border-radius: var(--rx-v2-r14);
    padding: 12px;
    transition: box-shadow .15s, border-color .15s;
}
body.rxs-ui-v2 .listStvVue:not(.rxsV2Cards) .rcol:hover {
    border-color: var(--rx-v2-accent);
    box-shadow: 0 6px 18px rgba(0, 0, 0, .1);
}
body.rxs-ui-v2 .listStvVue:not(.rxsV2Cards) .rcol > a.populable {
    display: block;
    margin: 0;
}
body.rxs-ui-v2 .listStvVue:not(.rxsV2Cards) .rcol img {
    float: none !important;
    width: 100% !important;
    /* current48.css cap: .listStvVue .col img { max-height:100px; border-radius:50% } */
    height: 130px;
    max-height: 130px;
    max-width: 100%;
    object-fit: cover;
    border-radius: var(--rx-v2-r10);
    display: block;
    margin: 0 0 10px;
    background: var(--rx-v2-field);
}
body.rxs-ui-v2 .listStvVue:not(.rxsV2Cards) .rcol h3 {
    font-size: 15px;
    font-weight: 600;
    color: var(--rx-v2-text);
    margin: 0 0 2px;
    line-height: 1.3;
    display: -webkit-box;
    line-clamp: 2;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
body.rxs-ui-v2 .listStvVue:not(.rxsV2Cards) .rcol p {
    color: var(--rx-v2-muted);
    font-size: 13px;
    margin: 0;
}
body.rxs-ui-v2 .listStvVue:not(.rxsV2Cards) .rcol small {
    color: var(--rx-v2-faint);
    font-size: 12px;
    margin: 6px 0 10px;
    display: block;
}
body.rxs-ui-v2 .listStvVue:not(.rxsV2Cards) .rcol .stvVueAction {
    margin-top: auto;
}

/* ---- menu de servicio (right-sidebar / brujula): tokenizar en v2 ---- */
/* El panel trae los colores del tema Oscuro hardcodeados (bg #383f48, texto
 * claro) aunque estemos en light: lo pasamos a tokens para que respete
 * light/dark. El titulo (.rpanel-title.btn-themecolor) mantiene el degrade de
 * marca; el box de scan (.rxsBarZone) su tint naranja. */
body.rxs-ui-v2 .right-sidebar {
    background: var(--rx-v2-panel) !important;
    color: var(--rx-v2-text) !important;
}
body.rxs-ui-v2 .right-sidebar h4 {
    color: var(--rx-v2-text) !important;
}
body.rxs-ui-v2 .right-sidebar .text-center,
body.rxs-ui-v2 .right-sidebar .text-muted,
body.rxs-ui-v2 .right-sidebar small {
    color: var(--rx-v2-muted) !important;
}
body.rxs-ui-v2 .right-sidebar .rxsBcd,
body.rxs-ui-v2 .right-sidebar input[type="text"] {
    background: var(--rx-v2-field) !important;
    color: var(--rx-v2-text) !important;
    border: 1px solid var(--rx-v2-border) !important;
}
body.rxs-ui-v2 .right-sidebar .card {
    background: var(--rx-v2-panel-2);
    border-color: var(--rx-v2-border-soft);
    color: var(--rx-v2-text);
}

/* style.css (tema Oscuro) pinta .card/.card-header/.page-header sin scope y
 * sin importar thr-dark; bajo v2 esas superficies van con tokens (cubre las
 * cards de /notifications y el card del componente de comentarios en light) */
body.rxs-ui-v2 .card {
    background-color: var(--rx-v2-panel);
}

body.rxs-ui-v2 .card .card-header {
    background-color: var(--rx-v2-head);
}

body.rxs-ui-v2 .page-wrapper .page-header {
    color: var(--rx-v2-text) !important;
}

/* el h5 "Mensajes" lleva .text-white (color #fff !important de bootstrap):
 * dentro de un card-header tokenizado tiene que seguir al token */
body.rxs-ui-v2 .card-header.btn-themecolor .text-white {
    color: var(--rx-v2-text) !important;
}

/* tema Oscuro: borde de card (card-no-border .card) y h1-h6 blancos sin scope */
body.rxs-ui-v2 .card {
    border-color: var(--rx-v2-border-soft);
}

body.rxs-ui-v2 .card-header.btn-themecolor h5 {
    color: var(--rx-v2-text);
}

/* titulo del registro en fichas (/action): quedaba blanco en light */
body.rxs-ui-v2 h4.ftidtitle {
    color: var(--rx-v2-text);
}

/* mismo origen: style.css pinta TODOS los h1-h6 de blanco y el .card-body de negro
 * sin gate de tema -> en light los titulos de las cards del dashboard (h6) eran
 * ilegibles y los graficos quedaban sobre fondo oscuro. El .card ya esta tokenizado,
 * asi que al body le alcanza con ser transparente. .text-muted (con !important) gana. */
body.rxs-ui-v2 h1,
body.rxs-ui-v2 h2,
body.rxs-ui-v2 h3,
body.rxs-ui-v2 h4,
body.rxs-ui-v2 h5,
body.rxs-ui-v2 h6 {
    color: var(--rx-v2-text);
}

body.rxs-ui-v2 .card > .card-body,
body.rxs-ui-v2 .card > .card-footer {
    background-color: transparent;
    color: var(--rx-v2-text);
}

/* ---- v2 pass 11: inbox /messages (Rexcal) ---- */

/* marco general: panel con radio; el aside izquierdo traia un gradiente legacy.
 * OJO: .chat-wrapper es el widget flotante del asistente, NO el inbox; el
 * contenedor del inbox es .chat-main-box */
body.rxs-ui-v2 .chat-main-box {
    background: var(--rx-v2-panel);
    border: 1px solid var(--rx-v2-border-soft);
    border-radius: var(--rx-v2-r12);
    overflow: hidden;
}

body.rxs-ui-v2 .chat-left-aside {
    background: var(--rx-v2-panel) !important;
    background-image: none !important;
    border-right: 1px solid var(--rx-v2-border-soft);
}

body.rxs-ui-v2 .chat-right-aside {
    background: var(--rx-v2-bg);
}

/* CTA "Nuevo mensaje": es un div.btn-themecolor.btn-block con gradiente */
body.rxs-ui-v2 .chat-main-box .btn-themecolor.btn-block {
    background: var(--rx-v2-accent) !important;
    background-image: none !important;
    border: 0;
    color: var(--rx-v2-accent-ink) !important;
    font-weight: 600;
}

/* buscador y toggle del listado */
body.rxs-ui-v2 .chat-left-aside .form-control {
    background: var(--rx-v2-field) !important;
    border: 1px solid var(--rx-v2-border-soft) !important;
    color: var(--rx-v2-text) !important;
}

/* items de conversacion: matar el gradiente rojo legacy de no-leidas (el
 * tinte marron); la senal de unread queda en el ghost + badge de conteo */
body.rxs-ui-v2 ul.chatonline li.rxsCv {
    background-image: none !important;
}

body.rxs-ui-v2 ul.chatonline li.rxsCv > a {
    border-bottom: 1px solid var(--rx-v2-border-soft);
    color: var(--rx-v2-muted);
    transition: background .12s ease;
}

body.rxs-ui-v2 ul.chatonline li.rxsCv > a:hover {
    background: var(--rx-v2-hover);
}

body.rxs-ui-v2 ul.chatonline li.rxsCv.has-unread > a {
    background: var(--rx-v2-ghost);
}

/* seleccionada: accent suave + filo accent, no el naranja solido legacy */
body.rxs-ui-v2 ul.chatonline li.rxsCv > a.active {
    background: var(--rx-v2-panel) !important;
    background-image: linear-gradient(var(--rx-v2-accent-soft), var(--rx-v2-accent-soft)) !important;
    box-shadow: inset 3px 0 0 var(--rx-v2-accent);
}

body.rxs-ui-v2 ul.chatonline .conv-name {
    color: var(--rx-v2-text);
}

body.rxs-ui-v2 ul.chatonline .conv-time {
    color: var(--rx-v2-faint);
}

body.rxs-ui-v2 ul.chatonline .conv-preview {
    color: var(--rx-v2-muted);
}

/* chips (header del hilo Y estados del listado): pills suaves semanticas */
body.rxs-ui-v2 .chat-main-box .badge {
    border-radius: 999px;
    display: inline-flex;
    align-items: center;
    font-weight: 600;
    padding: 3px 9px;
}

body.rxs-ui-v2 .chat-main-box .badge-light {
    background: var(--rx-v2-ghost) !important;
    border: 1px solid var(--rx-v2-border-soft);
    color: var(--rx-v2-muted) !important;
}

body.rxs-ui-v2 .chat-main-box .badge-success {
    background: rgba(46, 207, 110, .16) !important;
    color: #2ecf6e !important;
}

body.rxs-ui-v2 .chat-main-box .badge-warning {
    background: rgba(245, 184, 61, .16) !important;
    color: #f5b83d !important;
}

body.rxs-ui-v2 .chat-main-box .badge-secondary {
    background: var(--rx-v2-ghost) !important;
    color: var(--rx-v2-muted) !important;
}

/* `badge-info` FALTABA en este juego, y es justo el estado mas comun de una conversacion:
   `getStatusBadgeClass('1')` devuelve badge-info y eso es "Activa". Sin la regla se quedaba
   con el fondo azul solido del theme viejo pero SIN su `color: #fff` —lo pierde contra las
   reglas de v2—, o sea gris rgb(103,117,124) sobre azul rgb(30,136,229): el estado de cada
   conversacion de la lista no se podia leer. Medido el 23-08 en /messages.
   `badge-danger` NO se ablanda: es el contador de no leidos, y ese tiene que seguir siendo
   una pastilla roja llena — es la señal mas fuerte que tiene una bandeja. Lo que si le
   falta es el texto: tenia el mismo gris heredado sobre el rojo. */
body.rxs-ui-v2 .chat-main-box .badge-info {
    background: rgba(30, 136, 229, .16) !important;
    color: #1e88e5 !important;
}

/* EN CLARO, LA TINTA VA MAS OSCURA QUE EL TINTE.
   Un chip de fondo al 16% sobre blanco queda casi blanco, y el mismo color al 100% encima
   no alcanza: `#2ecf6e` sobre `rgba(46,207,110,.16)` da **1,81 de contraste** — el estado
   "Aceptada" y el "Reserva Online" del panel de datos se leian con esfuerzo. Estos tres
   valores estan elegidos para pasar 4:1 sobre su propio tinte, y van solo en claro: en
   oscuro el tinte es oscuro y el color vivo es justo el que se lee. Lo mide el caso de
   contraste de docs/repro/chat-messages-layout.mjs. */
body.rxs-ui-v2:not(.thr-dark) .chat-main-box .badge-success { color: #14803f !important; }
body.rxs-ui-v2:not(.thr-dark) .chat-main-box .badge-warning { color: #a06a00 !important; }
body.rxs-ui-v2:not(.thr-dark) .chat-main-box .badge-info    { color: #1565c0 !important; }
body.thr-dark.rxs-ui-v2 .chat-main-box .badge-info,
body.rxs-ui-v2 .thr-dark .chat-main-box .badge-info {
    background: rgba(80, 170, 245, .18) !important;
    color: #6ab5f5 !important;
}
body.rxs-ui-v2 .chat-main-box .badge-danger { color: #fff !important; }

/* el bloque de meta (tags + estado + botones) del header comprime hacia la
 * izquierda y pisa avatar/titulo: va a su propia fila, alineado al titulo */
body.rxs-ui-v2 .chat-main-header .d-flex.flex-column.align-items-end.ml-2 {
    align-items: flex-start !important;
    flex: 1 1 100%;
    margin-left: 64px !important;
}

/* legacy fuerza nowrap sobre las filas .flex-wrap del header: restaurar el
 * wrap para que tags/estado/botones no se corten ni se pisen */
body.rxs-ui-v2 .chat-main-header .flex-wrap {
    flex-wrap: wrap !important;
    row-gap: 8px;
}

body.rxs-ui-v2 .chat-right-aside .btn-outline-secondary,
body.rxs-ui-v2 .chat-right-aside .btn-outline-success,
body.rxs-ui-v2 .chat-right-aside .btn-outline-info {
    background: var(--rx-v2-ghost) !important;
    border: 1px solid var(--rx-v2-border-soft) !important;
    border-radius: var(--rx-v2-r7);
    color: var(--rx-v2-muted) !important;
}

body.rxs-ui-v2 .chat-right-aside .btn-outline-secondary:hover,
body.rxs-ui-v2 .chat-right-aside .btn-outline-success:hover,
body.rxs-ui-v2 .chat-right-aside .btn-outline-info:hover {
    background: var(--rx-v2-accent-soft) !important;
    border-color: var(--rx-v2-accent) !important;
    color: var(--rx-v2-accent) !important;
}

/* burbujas: entrante panel-2, propia (reverse) accent suave sin gradiente */
body.rxs-ui-v2 .chat-list li .box {
    background: var(--rx-v2-panel-2) !important;
    background-image: none !important;
    border-radius: var(--rx-v2-r12);
    color: var(--rx-v2-text) !important;
}

body.rxs-ui-v2 .chat-list li.reverse .box {
    background: var(--rx-v2-panel) !important;
    background-image: linear-gradient(var(--rx-v2-accent-soft), var(--rx-v2-accent-soft)) !important;
}

/* composer */
body.rxs-ui-v2 .rxsMsgSendTx {
    background: var(--rx-v2-head);
    border-top: 1px solid var(--rx-v2-border-soft) !important;
}

body.rxs-ui-v2 .rxsMsgSendTx textarea.form-control {
    background: var(--rx-v2-field) !important;
    border: 1px solid var(--rx-v2-border-soft) !important;
    border-radius: var(--rx-v2-r10);
    color: var(--rx-v2-text) !important;
}

body.rxs-ui-v2 .rxsMsgSendTx .btn-circle {
    background: var(--rx-v2-ghost) !important;
    background-image: none !important;
    border: 1px solid var(--rx-v2-border-soft) !important;
    color: var(--rx-v2-muted) !important;
}

body.rxs-ui-v2 .rxsMsgSendTx .btn-circle:hover {
    background: var(--rx-v2-accent-soft) !important;
    color: var(--rx-v2-accent) !important;
}

/* enviar: el circulo grande queda accent solido */
body.rxs-ui-v2 .rxsMsgSendTx .btn-themecolor.btn-circle {
    background: var(--rx-v2-accent) !important;
    background-image: none !important;
    border: 0 !important;
    color: var(--rx-v2-accent-ink) !important;
}

/* titulo del hilo (h3.box-title): blanco del tema Oscuro, invisible en light */
body.rxs-ui-v2 .chat-main-header .box-title {
    color: var(--rx-v2-text) !important;
}

/* ---- v2 pass 12: icon-rail sidebar, empty state, loading, cards mobile ---- */

/* rail colapsado (body.mini-sidebar, toggler del topbar): el theme ya achica a 60px
   y saca labels; aca solo se re-skinea. El hover del theme pinta un gradiente
   naranja de 380px (current48 !important): se pisa con tokens. */
@media (min-width: 768px) {

    /* el select de sistema (#superselect) mide ~390px: no entra en el rail
       (!important: el div trae display inline-block en el style).
       Lo mismo con la barra de dev (.devBar/.devBtnSite, index.php): es otro
       select ancho mas un link con texto, y en 60px rompe la vista. */
    body.rxs-ui-v2.mini-sidebar .scroll-sidebar > div:has(> #superselect),
    body.rxs-ui-v2.mini-sidebar .scroll-sidebar > div.devBar,
    body.rxs-ui-v2.mini-sidebar .scroll-sidebar > div.devBtnSite {
        display: none !important;
    }

    body.rxs-ui-v2.mini-sidebar .scroll-sidebar {
        padding: 0;
    }

    body.rxs-ui-v2.mini-sidebar .sidebar-nav #sidebarnav > li > a {
        border-radius: var(--rx-v2-r8);
        color: var(--rx-v2-muted);
    }

    /* hover de item de primer nivel: el theme lo expande (muestra el label) y
       le mete gradiente !important; queda como header flotante del flyout */
    body.rxs-ui-v2.mini-sidebar .sidebar-nav #sidebarnav > li:hover > a {
        background: var(--rx-v2-panel-2) !important;
        border: 1px solid var(--rx-v2-border);
        border-radius: var(--rx-v2-r10) var(--rx-v2-r10) var(--rx-v2-r10) 0;
        box-shadow: var(--rx-v2-shadow);
        color: var(--rx-v2-text);
    }

    body.rxs-ui-v2.mini-sidebar .sidebar-nav #sidebarnav > li:hover > a i {
        color: var(--rx-v2-accent);
    }

    /* flyout de submenu: style.css lo pinta #f2f6f8 y current48 le mete el
       gradiente de .treeview-menu.collapse */
    body.rxs-ui-v2.mini-sidebar .sidebar-nav #sidebarnav > li > ul,
    body.rxs-ui-v2.mini-sidebar .sidebar-nav #sidebarnav > li > ul.treeview-menu.collapse {
        background: var(--rx-v2-panel) !important;
        border: 1px solid var(--rx-v2-border);
        border-radius: 0 var(--rx-v2-r12) var(--rx-v2-r12) var(--rx-v2-r12);
        box-shadow: var(--rx-v2-shadow);
        padding: 8px !important;
    }

    body.rxs-ui-v2.mini-sidebar .sidebar-nav #sidebarnav > li > ul li a {
        border-radius: var(--rx-v2-r7);
        color: var(--rx-v2-muted);
    }

    body.rxs-ui-v2.mini-sidebar .sidebar-nav #sidebarnav > li > ul li a:hover {
        background: var(--rx-v2-ghost);
        color: var(--rx-v2-text);
    }

    /* current48 fuerza blanco en los iconos de grupos del flyout */
    body.rxs-ui-v2.mini-sidebar .sidebar-nav #sidebarnav ul.treeview-menu li.treeview > a i,
    body.rxs-ui-v2.mini-sidebar .sidebar-menu li.active > a i {
        color: var(--rx-v2-accent) !important;
    }

    /* gradientes de current48 dentro del flyout: item activo y grupos (treeview) */
    body.rxs-ui-v2.mini-sidebar .sidebar-nav #sidebarnav > li > ul li.active > a {
        background: var(--rx-v2-accent-soft) !important;
        color: var(--rx-v2-text) !important;
    }

    body.rxs-ui-v2.mini-sidebar .sidebar-nav #sidebarnav ul.treeview-menu li.treeview > a {
        background: transparent !important;
        color: var(--rx-v2-muted) !important;
    }

    body.rxs-ui-v2.mini-sidebar .sidebar-nav #sidebarnav ul.treeview-menu li.treeview:hover > a {
        background: var(--rx-v2-ghost) !important;
        color: var(--rx-v2-text) !important;
    }
}

/* flyout anidado (li.treeview2, ej Configuraciones >): #272c33 hardcodeado */
body.rxs-ui-v2 li.treeview2:hover > ul {
    background: var(--rx-v2-panel) !important;
    border: 1px solid var(--rx-v2-border);
    border-radius: var(--rx-v2-r10);
    box-shadow: var(--rx-v2-shadow);
}

/* ---- estado vacio de tabla ---- */

body.rxs-ui-v2 table.rxs-table td.dataTables_empty {
    color: var(--rx-v2-muted);
    font-size: 14px;
    font-weight: 500;
    padding: 72px 16px !important;
    text-align: center;
}

/* icono en tile suave con los colores del sitio: el vacio se ve intencional */
body.rxs-ui-v2 table.rxs-table td.dataTables_empty::before {
    background: linear-gradient(135deg, var(--rx-v2-accent-soft), var(--rx-v2-accent-2-soft));
    border-radius: var(--rx-v2-r18);
    color: var(--rx-v2-accent);
    content: "\f002";
    display: block;
    font-family: "Font Awesome 5 Free";
    font-size: 22px;
    font-weight: 900;
    height: 60px;
    line-height: 60px;
    margin: 0 auto 16px;
    width: 60px;
}

/* ---- loading (processing.dt) ---- */

body.rxs-ui-v2 .dataTables_wrapper .dataTables_processing {
    background: var(--rx-v2-panel-2);
    border: 1px solid var(--rx-v2-border);
    border-radius: 999px;
    box-shadow: var(--rx-v2-shadow);
    color: var(--rx-v2-text);
    font-size: 12.5px;
    height: auto;
    left: 50%;
    margin: 0;
    padding: 8px 18px 8px 38px;
    top: 14px;
    transform: translateX(-50%);
    width: auto;
    z-index: 6;
}

body.rxs-ui-v2 .dataTables_wrapper .dataTables_processing::before {
    animation: rxsV2Spin .7s linear infinite;
    border: 2px solid var(--rx-v2-border);
    border-radius: 50%;
    border-top-color: var(--rx-v2-accent);
    content: "";
    height: 14px;
    left: 14px;
    margin-top: -7px;
    position: absolute;
    top: 50%;
    width: 14px;
}

@keyframes rxsV2Spin {
    to { transform: rotate(360deg); }
}

/* mientras procesa, atenuar el contenido actual (clase puesta por ui_v2.js) */
body.rxs-ui-v2 .dataTables_wrapper.rxs-loading table.rxs-table tbody {
    opacity: .45;
    transition: opacity .15s ease;
}

@media (prefers-reduced-motion: reduce) {
    body.rxs-ui-v2 .dataTables_wrapper .dataTables_processing::before {
        animation: none;
    }
}

/* ---- cards mobile: ocultar campos sin valor (clase puesta por ui_v2.js).
   Mismo selector base que la regla flex de pass 5 para ganarle. ---- */

@media (max-width: 767px) {
    body.rxs-ui-v2 .rxs-module table.rxs-table tbody > tr > td.rxs-td-empty {
        display: none !important;
    }
}

/* ============================================================
   Audit 3 fixes (2026-07-04)
   ============================================================ */

/* #3 Iconos de submenú (treeview): current48 (.thr-anim) los pinta blanco y en
   light mode quedan invisibles. Token faint como los de primer nivel; activo y
   hover al accent. */
body.rxs-ui-v2 .sidebar-nav ul.treeview-menu li a i {
    color: var(--rx-v2-faint) !important;
}

body.rxs-ui-v2 .sidebar-nav ul.treeview-menu li.active > a i,
body.rxs-ui-v2 .sidebar-nav ul.treeview-menu li a:hover i {
    color: var(--rx-v2-accent) !important;
}

/* #4 Barra QR / CTA full-width themecolor dentro de una ficha o módulo (ej
   "Escanear QR de Reserva" en /action .. #tab): el gradiente naranja queda feo,
   lo pasamos al accent sólido como el resto de los CTA v2. Acotado a btn-lg para
   no pisar los CTA de widgets con regla propia (chat, etc.). */
body.rxs-ui-v2 #maincontent .btn-themecolor.btn-block.btn-lg {
    background: var(--rx-v2-accent) !important;
    background-image: none !important;
    border: 0 !important;
    border-radius: var(--rx-v2-r10);
    color: var(--rx-v2-accent-ink) !important;
    font-weight: 650;
}

body.rxs-ui-v2 #maincontent .btn-themecolor.btn-block.btn-lg:hover {
    filter: brightness(1.08);
}

/* Bug title duplicado (ej /table/1253/57): el .rxs-module-head v2 ya muestra el
   titulo del modulo; ocultar el <h4 class="page-header"> legacy cuando el mismo
   tab-pane contiene un modulo v2. Los panes de formulario (alta) no tienen
   .rxs-module, asi que su page-header ("Nuevo X") se conserva. */
body.rxs-ui-v2 .tab-pane:has(.rxs-module) > .page-header {
    display: none;
}

/* Mismo titulo duplicado, variante de las pestañas apiladas (mode != 0): ahi el
   <h4 class="page-header"> con el nombre de la pestaña se emite DENTRO del html
   del modulo (domain.php, $templates["h2"]), asi que termina como primer hijo del
   .rxs-data-panel en vez de colgar del tab-pane. Si el modulo ya tiene head v2
   (mismo texto: el nombre de la pestaña), sobra. Sin head (notitle) se conserva. */
body.rxs-ui-v2 .rxs-module:has(> .rxs-module-head) > .rxs-data-panel > h4.page-header {
    display: none;
}

/* Modulos apilados sin titulo (notitle, tab_notab) cuya lista Vue quedo vacia:
   el .rxs-data-panel solo tiene los comentarios FOR_START/FOR_END y se veia como
   una barra/panel vacio ocupando espacio. Si el modulo no tiene head y su panel
   esta vacio, lo colapsamos. (Si luego se puebla, :empty deja de matchear y vuelve
   a mostrarse.) Los modulos con head/titulo no se tocan. */
body.rxs-ui-v2 .rxs-module:not(:has(.rxs-module-head)):has(> .rxs-data-panel:empty) {
    display: none;
}

/* ---- v2 pass 13: export en footer + pills clickeables ---- */

/* dt-buttons (export/print/colvis) viven en el footer de la tabla, no en el
   header: son acciones secundarias. Segunda fila del grid, a lo ancho. */
body.rxs-ui-v2 .rxs-module .rxs-table-footer .dt-buttons {
    display: inline-flex;
    flex-wrap: wrap;
    gap: 6px;
    grid-column: 1 / -1;
    justify-self: start;
    margin: 0;
    padding: 0;
}

@media (max-width: 767px) {
    body.rxs-ui-v2 .rxs-module .rxs-table-footer .dt-buttons {
        justify-content: center;
    }
}

/* pill clickeable: filtra la columna por ese valor (ui_v2.js pillFilter) */
body.rxs-ui-v2 .rxs-module table.rxs-table .rxs-pill,
body.rxs-ui-v2 .rxs-v2-card .rxs-pill {
    cursor: pointer;
    transition: box-shadow .12s ease, filter .12s ease;
}

body.rxs-ui-v2 .rxs-module table.rxs-table .rxs-pill:hover,
body.rxs-ui-v2 .rxs-v2-card .rxs-pill:hover {
    box-shadow: 0 0 0 1.5px hsl(var(--rxp) var(--rx-tint-s) var(--rx-tint-l) / .55);
    filter: brightness(1.05);
}

/* pill esperando la resolucion ajax del filtro (isbig/alredysel) */
body.rxs-ui-v2 .rxs-module table.rxs-table .rxs-pill.rxs-pill-wait,
body.rxs-ui-v2 .rxs-v2-card .rxs-pill.rxs-pill-wait {
    animation: rxsV2PillWait .8s ease-in-out infinite;
    cursor: progress;
}

@keyframes rxsV2PillWait {
    50% { opacity: .45; }
}

@media (prefers-reduced-motion: reduce) {
    body.rxs-ui-v2 .rxs-module table.rxs-table .rxs-pill.rxs-pill-wait,
    body.rxs-ui-v2 .rxs-v2-card .rxs-pill.rxs-pill-wait {
        animation: none;
        opacity: .6;
    }
}

/* pagina /search con template default (ppages/search.php) bajo v2 */
body.rxs-ui-v2 .rxs-search-page .rxs-search-title {
    color: var(--rx-v2-text);
    font-size: 19px;
    font-weight: 600;
    margin: 14px 0 4px;
}

body.rxs-ui-v2 .rxs-search-page .rxs-search-group {
    color: var(--rx-v2-muted);
    font-size: 12px;
    font-weight: 600;
    letter-spacing: .08em;
    margin: 22px 0 4px;
    text-transform: uppercase;
}

body.rxs-ui-v2 .rxs-search-page .rxs-search-count {
    background: var(--rx-v2-accent-soft);
    border-radius: 999px;
    color: var(--rx-v2-accent);
    display: inline-block;
    font-size: 11px;
    letter-spacing: 0;
    margin-left: 6px;
    min-width: 20px;
    padding: 2px 7px;
    text-align: center;
}

body.rxs-ui-v2 .rxs-search-page .rxs-search-card {
    background: var(--rx-v2-panel);
    border: 1px solid var(--rx-v2-border-soft);
    border-radius: var(--rx-v2-r12);
    margin: 6px;
    padding: 14px;
}

body.rxs-ui-v2 .rxs-search-page .rxs-search-card h3 {
    color: var(--rx-v2-text);
    font-size: 15px;
    font-weight: 600;
    margin: 4px 0;
}

body.rxs-ui-v2 .rxs-search-page .rxs-search-card p,
body.rxs-ui-v2 .rxs-search-page .rxs-search-card small {
    color: var(--rx-v2-muted);
    font-size: 12.5px;
}

body.rxs-ui-v2 .rxs-search-page .rxs-search-actions {
    display: flex;
    gap: 6px;
    margin-top: 8px;
}

body.rxs-ui-v2 .rxs-search-page .rxs-search-actions .btn {
    background: var(--rx-v2-ghost) !important;
    border: 1px solid var(--rx-v2-border) !important;
    border-radius: var(--rx-v2-r8);
    box-shadow: none;
    color: var(--rx-v2-muted) !important;
}

body.rxs-ui-v2 .rxs-search-page .rxs-search-actions .btn:hover {
    border-color: var(--rx-v2-accent) !important;
    color: var(--rx-v2-accent) !important;
}

/* cards v2 del /search: los botones van en fila (el template mete whitespace entre <a>) */
body.rxs-ui-v2 .rxs-search-page .rxs-v2-card-actions .rxsBtns {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    justify-content: flex-end;
}

/* el gap reemplaza al margin de la grilla; sin esto 3 botones suman justo el ancho y wrapean */
body.rxs-ui-v2 .rxs-search-page .rxs-v2-card-actions .rxsBtns .btn:not(:where(.rxsBtnsOwn .btn)) {
    margin: 0;
}

body.rxs-ui-v2 .rxs-search-page .rxs-search-empty {
    color: var(--rx-v2-muted);
    font-size: 13.5px;
    padding: 40px 0;
    text-align: center;
}

/* ============================================================
   v2 pass 14: filter_change inline, tab panes panel, table-tools
   toolbar, footer chips, ficha layout
   ============================================================ */

/* 1. .filter_change ya tiene display:inline-flex, solo falta position para que
   fluya junto a los demas controles del header (current48.css la pone absolute) */
body.rxs-ui-v2 .rxs-module .rxs-module-tools .filter_change {
    position: relative !important;
    top:0;
    left:0;
}

/* 2. Panes custom sin panel (graficos, excel, dashboard, calendario):
   fondo + borde + radio de panel en el pane, sin tocar internals.
   #tab_calendar cubre el calendario nativo; :has(.fc) cubre ftabs calendarios
   cuyo id es tab{ftab_id} (ej #tab58) y nunca matchearia por id literal. */
body.rxs-ui-v2 .tab-content > #tab_graphs,
body.rxs-ui-v2 .tab-content > [id^="tab_excel"],
body.rxs-ui-v2 .tab-content > #tab_ds,
body.rxs-ui-v2 .tab-content > #tab_calendar,
body.rxs-ui-v2 .tab-content > .tab-pane:has(.fc) {
    background: var(--rx-v2-panel);
    border: 1px solid var(--rx-v2-border-soft);
    border-radius: var(--rx-v2-r12);
    padding: 14px;
}

/* 3. Barra de herramientas del footer: flex coherente (reemplaza grid bootstrap suelto).
 * justify-content flex-start vence al .justify-content-center heredado de la row, que
 * junto al margin-auto tiraba los botones a otra fila descentrados. */
body.rxs-ui-v2 .rxs-table-tools {
    align-items: center;
    border-top: 1px solid var(--rx-v2-border-soft);
    display: flex !important;
    flex-wrap: wrap;
    gap: 8px;
    justify-content: flex-start !important;
    margin: 8px 0 0;
    padding: 10px 0 0;
}
body.rxs-ui-v2 .rxs-table-tools > [class*="col-"] {
    flex: 0 0 auto;
    max-width: none;
    padding: 0;
    width: auto;
}
body.rxs-ui-v2 .rxs-table-tools .select2-container {
    min-width: 150px !important;
    width: auto !important;
}
body.rxs-ui-v2 .rxs-table-tools .btn {
    align-items: center;
    display: inline-flex;
    gap: 6px;
    height: 36px;
    justify-content: center;
    line-height: 1;
    padding: 0 14px;
}
/* los botones de accion (Modificacion masiva / Crear filtro) vienen con btn-block
 * (width 100% de su col) -> estiraban y, con el margin-auto, saltaban a otra fila
 * desalineados. Al ancho de su contenido fluyen en linea con el resto de la barra. */
body.rxs-ui-v2 .rxs-table-tools .btn.btn-block {
    width: auto;
}
/* select2 (Tags / Agrupar por) rendian 46px de alto y fuente 16px -> descuadraban
 * contra los selects/botones de 36px. Los normalizamos a la altura de la barra con
 * un solo borde: el input de busqueda interno (.select2-search__field) traia su
 * propio borde+radio+fondo = el "doble borde" que se veia. */
body.rxs-ui-v2 .rxs-table-tools .select2-selection--multiple,
body.rxs-ui-v2 .rxs-table-tools .select2-selection--single {
    align-items: center;
    background: var(--rx-v2-field) !important;
    border: 1px solid var(--rx-v2-border) !important;
    border-radius: var(--rx-v2-r8) !important;
    display: flex !important;
    font-size: 13px;
    min-height: 36px !important;
    padding: 0 8px;
}
body.rxs-ui-v2 .rxs-table-tools .select2-selection--multiple .select2-selection__rendered {
    padding: 0;
}
body.rxs-ui-v2 .rxs-table-tools .select2-search__field {
    background: transparent !important;
    border: 0 !important;
    border-radius: 0 !important;
    font-size: 13px;
    height: 24px !important;
    margin: 0 !important;
}
/* checkbox "Filtrar por rango horario": la label materialize (rxsCheck2) media 41px
 * con el cuadrito dibujado en top:7px -> quedaba mas alto y desalineado del texto.
 * La volvemos flex centrada a 36px y anclamos el cuadro/tilde al centro vertical. */
body.rxs-ui-v2 .rxs-table-tools .rxsCheck2 {
    align-items: center;
    display: inline-flex !important;
    height: 36px !important;
    margin: 0 !important;
    padding: 0 0 0 28px !important;
}
body.rxs-ui-v2 .rxs-table-tools [type="checkbox"]:not(.filled-in) + label.rxsCheck2:before,
body.rxs-ui-v2 .rxs-table-tools [type="checkbox"]:not(.filled-in) + label.rxsCheck2:after {
    margin-top: -9px !important;
    top: 50% !important;
}

/* 4. Chips de footer (tags/agrupar/periodicidad): borde accent para distinguirlos */
body.rxs-ui-v2 .rxs-chip[data-kind] {
    border-color: var(--rx-v2-accent) !important;
    color: var(--rx-v2-accent) !important;
}
body.rxs-ui-v2 .rxs-chip[data-kind] .rxs-chip-l {
    color: var(--rx-v2-accent);
    opacity: .75;
}

/* 5. Ficha /action: back + titulo en fila, tabs debajo */
body.rxs-ui-v2 .nav-tabs-custom.card.rxs-v2-ficha {
    align-items: center;
    background: transparent !important;
    box-shadow: none !important;
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    gap: 0 10px;
    padding: 0 !important;
}
body.rxs-ui-v2 .nav-tabs-custom.card.rxs-v2-ficha > a[onclick*="stvBackBtn"] {
    flex: 0 0 auto;
    margin: 0;
}
body.rxs-ui-v2 .nav-tabs-custom.card.rxs-v2-ficha > h4.ftidtitle {
    flex: 1 1 0;
    /* mata el mt-2 (Bootstrap !important) que bajaba el titulo ~8px y lo
       desalineaba del "Ir atras" en la fila centrada */
    margin: 0 !important;
    min-width: 0;
}
body.rxs-ui-v2 .nav-tabs-custom.card.rxs-v2-ficha > #tabtabs {
    flex: 0 0 100%;
    margin-top: 8px;
    width: 100%;
}
/* la barra de tabs nivel-1 traia .nav-fill pero quedaba inline-flex (solo el
 * ancho del texto): la estiramos a todo el ancho y repartimos los pills.
 * Aplica a toda ficha con #tabtabs, con o sin boton Ir-atras (ej acciones con
 * html custom que no generan stvBackBtn). El anchor tmb debe llenar el li. */
body.rxs-ui-v2 .nav-tabs-custom.card > #tabtabs > ul.customtab {
    display: flex;
    width: 100%;
}
/* Con muchas pestañas (la ficha de Juventya trae 20) la barra desbordaba a la derecha con
 * overflow-x:auto y la scrollbar escondida: en un escritorio con mouse las ultimas 11 no
 * se veian ni se podian abrir (medido a 1366px: 1078px de barra para 2602px de pills).
 * En pantalla ancha la barra baja de renglon, como cualquier .nav; en el telefono sigue
 * siendo el dock de una fila que se desliza con el dedo (ver el @media de abajo). */
@media (min-width: 768px) {
    body.rxs-ui-v2 .customtab,
    body.rxs-ui-v2 .nav-tabs {
        flex-wrap: wrap;
        row-gap: 2px;
    }
}
body.rxs-ui-v2 .nav-tabs-custom.card > #tabtabs > ul.customtab > li {
    flex: 1 1 auto;
}
body.rxs-ui-v2 .nav-tabs-custom.card > #tabtabs > ul.customtab > li > a {
    width: 100%;
    justify-content: center;
}
/* Lo mismo para la barra de pestañas de un modulo (ppages/table.php y maketab la arman
 * como ul.nav-tabs.nav-fill): fuera de una ficha quedaba inline-flex, del ancho del texto,
 * y el fondo de la barra cortaba a mitad de la columna (Mis Reservas de BSM, 07-10). */
body.rxs-ui-v2 ul.nav-tabs.nav-fill {
    display: flex;
    width: 100%;
}
body.rxs-ui-v2 ul.nav-tabs.nav-fill > li {
    flex: 1 1 auto;
}
body.rxs-ui-v2 ul.nav-tabs.nav-fill > li > a {
    width: 100%;
    justify-content: center;
}

/* nivel 2 de tabs (dentro de .tab-pane de una ficha): mas liviano que el nivel 1.
   NOTA: el .nav-tabs-custom NO es hijo directo de .tab-pane — hay .stvModuleTable
   en el medio, por eso el selector NO lleva > entre .tab-pane y .nav-tabs-custom */
body.rxs-ui-v2 .nav-tabs-custom.card.rxs-v2-ficha .tab-pane .nav-tabs-custom ul.customtab {
    border-bottom: 1px solid var(--rx-v2-border-soft);
    box-shadow: none;
}
body.rxs-ui-v2 .nav-tabs-custom.card.rxs-v2-ficha .tab-pane .nav-tabs-custom ul.customtab > li.active > a,
body.rxs-ui-v2 .nav-tabs-custom.card.rxs-v2-ficha .tab-pane .nav-tabs-custom ul.customtab > li > a.active {
    background: var(--rx-v2-accent-soft) !important;
    box-shadow: none !important;
    color: var(--rx-v2-accent) !important;
}

/* banner QR/zona: tonalidad reducida en v2 (elimina el gradiente naranja fuerte) */
body.rxs-ui-v2 .rxsBarZone {
    background: var(--rx-v2-accent-soft) !important;
    background-image: none !important;
    border: 1px solid var(--rx-v2-accent);
    border-radius: var(--rx-v2-r10);
    color: var(--rx-v2-accent) !important;
}
body.rxs-ui-v2 .rxsBarZone .btn-themecolor {
    background: var(--rx-v2-accent) !important;
    background-image: none !important;
    color: #fff !important;
}

/* =========================================================================
   v2 pass 15: alerts de formulario (stvFormAlert) + boton nativo file input
   ========================================================================= */

/* Alerts contextuales de bootstrap (danger/warning/success/info): los pasteles
   claros legacy chocan sobre el panel oscuro v2. Se tokenizan como los toasts
   (pass 7): fondo panel + borde semantico a la izquierda + heading/icono con el
   hue de estado. Cubre los stvFormAlert (error/exito al enviar un form) y los
   alerts inline de guardado ("... creado correctamente" / "A tener en cuenta").
   El login tiene su propia regla mas especifica (.login-register) que gana. */
body.rxs-ui-v2 .alert.alert-danger,
body.rxs-ui-v2 .alert.alert-warning,
body.rxs-ui-v2 .alert.alert-success,
body.rxs-ui-v2 .alert.alert-info,
body.rxs-ui-v2 .stvFormAlert {
    background: var(--rx-v2-panel) !important;
    background-image: none !important;
    border: 1px solid var(--rx-v2-border) !important;
    border-left: 3px solid var(--rx-v2-accent) !important;
    border-radius: var(--rx-v2-r10) !important;
    box-shadow: var(--rx-v2-shadow);
    color: var(--rx-v2-text) !important;
    font-family: var(--rx-v2-font);
}
body.rxs-ui-v2 .alert.alert-danger,
body.rxs-ui-v2 .stvFormAlert {
    border-left-color: #f4506c !important;
}
body.rxs-ui-v2 .alert.alert-warning {
    border-left-color: #f5b83d !important;
}
body.rxs-ui-v2 .alert.alert-success,
body.rxs-ui-v2 .stvFormAlert.stvSubmitedAlert,
body.rxs-ui-v2 .stvFormAlert.alert-success {
    border-left-color: #2ecf6e !important;
}
body.rxs-ui-v2 .alert.alert-info {
    border-left-color: #4aa3f0 !important;
}
/* heading + icono con el hue de estado; el cuerpo queda en texto normal */
body.rxs-ui-v2 .alert.alert-danger > h4,
body.rxs-ui-v2 .stvFormAlert > h4 {
    color: #f4506c;
}
body.rxs-ui-v2 .alert.alert-warning > h4 {
    color: #f5b83d;
}
body.rxs-ui-v2 .alert.alert-success > h4,
body.rxs-ui-v2 .stvFormAlert.stvSubmitedAlert > h4,
body.rxs-ui-v2 .stvFormAlert.alert-success > h4 {
    color: #2ecf6e;
}
body.rxs-ui-v2 .alert.alert-info > h4 {
    color: #4aa3f0;
}
body.rxs-ui-v2 .alert > h4 {
    font-family: var(--rx-v2-font);
    font-size: 14px;
    font-weight: 600;
    margin: 0 0 4px;
}
/* la X de cerrar: legible sobre el panel, sin el negro solido bootstrap */
body.rxs-ui-v2 .alert .close,
body.rxs-ui-v2 .stvFormAlert .close {
    color: var(--rx-v2-muted);
    opacity: .8;
    text-shadow: none;
}
body.rxs-ui-v2 .alert .close:hover,
body.rxs-ui-v2 .stvFormAlert .close:hover {
    color: var(--rx-v2-text);
    opacity: 1;
}

/* boton nativo de <input type="file"> ("Choose File"): el navegador lo pinta
   blanco y rompe el dark (Mis datos, modo excel, cualquier form con foto). */
body.rxs-ui-v2 input[type="file"]::file-selector-button,
body.rxs-ui-v2 input[type="file"]::-webkit-file-upload-button {
    background: var(--rx-v2-ghost);
    border: 1px solid var(--rx-v2-border);
    border-radius: var(--rx-v2-r8);
    color: var(--rx-v2-text);
    cursor: pointer;
    font-family: var(--rx-v2-font);
    margin-right: 10px;
    padding: 6px 12px;
    transition: background .16s, color .16s;
}
body.rxs-ui-v2 input[type="file"]::file-selector-button:hover,
body.rxs-ui-v2 input[type="file"]::-webkit-file-upload-button:hover {
    background: var(--rx-v2-accent-soft);
    color: var(--rx-v2-accent);
}

/* =========================================================================
   v2 pass 16: pulido de ficha /action
   (1) tabs nivel-1 mismo tamaño  (2) botones edit/ver alineados
   (3) tabs nivel-2 mas visibles
   ========================================================================= */

/* (1) TABS NIVEL-1: igualar el tamaño de todos.
   Los tabs con color (data-clr) traen el icono como badge circular grande
   (regla legacy `[data-clr] a span`); los SIN color quedaban con icono plano
   chico -> el tab se veia mas bajo y desalineado (Data RexShell, y TODOS los
   tabs de fichas que no usan colores como Turnos). Se les da el mismo badge
   (mismas medidas que la regla legacy) en tono accent, asi todos miden igual. */
body.rxs-ui-v2 .nav-tabs-custom.card.rxs-v2-ficha > #tabtabs > ul.customtab > li:not([data-clr]) > a > span[class*="fa"] {
    align-items: center;
    background: var(--rx-v2-accent-soft);
    border-radius: 50%;
    color: var(--rx-v2-accent);
    display: inline-flex;
    font-size: 1.4rem;
    height: 2.3rem;
    justify-content: center;
    line-height: 1.9rem;
    margin-right: .35rem;
    min-width: 20px;
    padding: .2rem .5rem;
    text-align: center;
    vertical-align: middle;
    width: 2.4rem;
}
/* (1b) TABS CON COLOR (data-clr) FUERA DE ESA BARRA: el css legacy les mete SIEMPRE
   el badge circular de 2.4rem, asi que en cualquier otra barra (nivel-2, listados,
   fichas sin "Ir atras") el tab con color quedaba MAS GRANDE que sus hermanos sin
   color (ej sub-tabs de CRM: 3 grandes + 1 chica). Ademas el legacy solo pinta
   colores por NOMBRE de paleta (blue/red/...) -> con un hex el badge quedaba blanco
   y sin color. Aca el icono vuelve a ser plano como el resto, teñido con el color
   real que publica domain.php en --rx-tab-clr. */
body.rxs-ui-v2 ul.customtab > li[data-clr] > a > span[class*="fa"] {
    background: none !important;
    border-radius: 0 !important;
    color: var(--rx-tab-clr, var(--rx-v2-accent)) !important;
    font-size: inherit !important;
    height: auto !important;
    line-height: inherit !important;
    margin-right: .35rem !important;
    min-width: 0 !important;
    padding: 0 !important;
    width: auto !important;
}
/* ...salvo en la barra nivel-1 de la ficha, donde (1) le da badge a TODOS: ahi el
   tab con color mantiene el badge, con su color propio. */
body.rxs-ui-v2 .nav-tabs-custom.card.rxs-v2-ficha > #tabtabs > ul.customtab > li[data-clr] > a > span[class*="fa"] {
    align-items: center;
    background: color-mix(in srgb, var(--rx-tab-clr, var(--rx-v2-accent)) 18%, transparent) !important;
    border-radius: 50% !important;
    display: inline-flex;
    font-size: 1.4rem !important;
    height: 2.3rem !important;
    justify-content: center;
    line-height: 1.9rem !important;
    min-width: 20px !important;
    padding: .2rem .5rem !important;
    width: 2.4rem !important;
}
/* legacy `[data-clr] a.active { color:#FFF !important }` deja el LABEL de la
   pestaña activa en blanco -> invisible sobre el pill activo claro (light mode).
   Se fuerza a color de texto legible (el badge del icono conserva su color). */
body.rxs-ui-v2 ul.customtab > li[data-clr] > a.active {
    color: var(--rx-v2-text) !important;
}

/* (2) TITULO DE FICHA: nombre + botones edit/ver en una fila alineada.
   El h4 era `display:block` con los botones inline -> se pisaban con el nombre
   y quedaban desalineados verticalmente con el "Ir atras". Ahora flex row. */
body.rxs-ui-v2 .nav-tabs-custom.card.rxs-v2-ficha > h4.ftidtitle {
    align-items: center;
    column-gap: 8px;
    display: flex;
    flex-wrap: wrap;
    row-gap: 4px;
}
body.rxs-ui-v2 .nav-tabs-custom.card.rxs-v2-ficha > h4.ftidtitle > .btn,
body.rxs-ui-v2 .nav-tabs-custom.card.rxs-v2-ficha > h4.ftidtitle > a > .btn {
    align-items: center;
    /* mismos tokens ghost que el "Ir atras": sacamos el amarillo/cyan chillon de
       btn-warning/btn-success y quedan neutros, coherentes con la fila */
    background: var(--rx-v2-ghost) !important;
    border: 1px solid var(--rx-v2-border) !important;
    border-radius: var(--rx-v2-r8);
    box-shadow: none !important;
    color: var(--rx-v2-muted) !important;
    display: inline-flex;
    flex: 0 0 auto;
    height: 30px;
    justify-content: center;
    margin: 0;
    padding: 0;
    width: 30px;
}
body.rxs-ui-v2 .nav-tabs-custom.card.rxs-v2-ficha > h4.ftidtitle > .btn:hover,
body.rxs-ui-v2 .nav-tabs-custom.card.rxs-v2-ficha > h4.ftidtitle > a > .btn:hover {
    border-color: var(--rx-v2-accent) !important;
    color: var(--rx-v2-text) !important;
}
body.rxs-ui-v2 .nav-tabs-custom.card.rxs-v2-ficha > h4.ftidtitle > a:not([onclick*="stvBackBtn"]) {
    align-items: center;
    display: inline-flex;
    flex: 0 0 auto;
    height: 30px;
    line-height: 1;
}

/* (3) TABS NIVEL-2 (dentro del .tab-pane de la ficha): pasa de un subrayado
   apenas visible a una barra segmentada liviana (panel-2), mas legible pero
   distinta del nivel-1 (que tiene los badges circulares). Overridea pass 14. */
body.rxs-ui-v2 .nav-tabs-custom.card.rxs-v2-ficha .tab-pane .nav-tabs-custom ul.customtab {
    background: var(--rx-v2-panel-2);
    border: 1px solid var(--rx-v2-border-soft);
    border-radius: var(--rx-v2-r10);
    padding: 3px;
}
body.rxs-ui-v2 .nav-tabs-custom.card.rxs-v2-ficha .tab-pane .nav-tabs-custom ul.customtab > li > a {
    border-radius: var(--rx-v2-r8);
    font-size: 12.5px;
    font-weight: 500;
    padding: 6px 12px;
}
body.rxs-ui-v2 .nav-tabs-custom.card.rxs-v2-ficha .tab-pane .nav-tabs-custom ul.customtab > li > a:not(.active) {
    color: var(--rx-v2-text);
}
body.rxs-ui-v2 .nav-tabs-custom.card.rxs-v2-ficha .tab-pane .nav-tabs-custom ul.customtab > li > a:not(.active):hover {
    background: var(--rx-v2-hover);
    color: var(--rx-v2-accent);
}
body.rxs-ui-v2 .nav-tabs-custom.card.rxs-v2-ficha .tab-pane .nav-tabs-custom ul.customtab > li.active > a,
body.rxs-ui-v2 .nav-tabs-custom.card.rxs-v2-ficha .tab-pane .nav-tabs-custom ul.customtab > li > a.active {
    background: var(--rx-v2-accent-soft) !important;
    color: var(--rx-v2-accent) !important;
    font-weight: 600;
}

/* =========================================================================
   v2 pass 17: transiciones (.loadpage / tabla) + menu + topbar
   (1) preloader de navegacion: velo suave + barra de progreso accent
   (2) entrada animada del contenido de pagina
   (3) barra de progreso en carga/redraw de tabla
   (4) menu: chips de icono, submenu con guia, buscador, switcher de sistema
   (5) topbar: badges, divisores, hover
   ========================================================================= */

/* (1) PRELOADER .loadpage: el legacy es un overlay a pantalla completa con
   --rx-color1 (NARANJA) + blur(2px) inline -> flash naranja en cada navegacion.
   En v2: velo translucido del fondo (se sigue viendo la pagina saliente) +
   barra indeterminada accent arriba, estilo github. El spinner svg se oculta.
   opacity queda inline (0.7) para conservar el fadeIn/fadeOut de jQuery. */
body.rxs-ui-v2 .preloader.stvLoading .circular {
    display: none;
}
body.rxs-ui-v2 .preloader.stvLoading::before {
    animation: rxsV2Sweep 1.1s cubic-bezier(.4, 0, .2, 1) infinite;
    background: linear-gradient(90deg, transparent, var(--rx-v2-accent) 35%, var(--rx-v2-accent) 65%, transparent);
    content: "";
    height: 3px;
    left: 0;
    position: fixed;
    top: 0;
    width: 38%;
    will-change: transform;
    z-index: 100000;
}
@keyframes rxsV2Sweep {
    from { transform: translateX(-110%); }
    to   { transform: translateX(290%); }
}

/* (2) ENTRADA DE PAGINA: el html() de #maincontent inserta nodos nuevos ->
   la animacion corre sola en cada navegacion SPA. Fade en mobile (un transform
   animado en el ancestro descolocaria el dock fijo de tabs un instante). */
@keyframes rxsV2PageIn {
    from { opacity: 0; }
    to   { opacity: 1; }
}
/* El desplazamiento de 6px se saco: era `top` animado, o sea LAYOUT, o sea animacion de
 * hilo principal — y el hilo esta bloqueado ~350ms justo cuando la animacion tendria que
 * correr. Con `backwards` el modulo se queda en el frame `from` (opacity 0) toda esa
 * ventana: el html ya estaba puesto y medido, pero invisible. Eso ERA el "queda vacio".
 * Animando solo `opacity` la animacion es compositable y el fade entra igual aunque el
 * hilo este ocupado: se ve el modulo aparecer mientras DataTables todavia trabaja.
 * (Por transform tampoco: convierte al modulo en containing block y le mueve el ancla a
 * .chat-wrapper (fixed) y .favMeTable (absolute) durante la animacion.)
 * `position:relative` se queda: es lo que ancla al .favMeTable. */
body.rxs-ui-v2 #maincontent > * {
    animation: rxsV2PageIn .22s ease-out backwards;
}
@media (min-width: 768px) {
    body.rxs-ui-v2 #maincontent > * {
        position: relative;
        top: 0;
    }
}

/* (3) TABLA CARGANDO: ademas del pill "Procesando.." y el fade del tbody
   (pass 12), una barra de progreso fina recorre el borde superior del wrapper
   mientras dura el request -> feedback inmediato en filtros/paginado/orden. */
body.rxs-ui-v2 .dataTables_wrapper.rxs-loading {
    overflow-x: clip;
    position: relative;
}
body.rxs-ui-v2 .dataTables_wrapper.rxs-loading::before {
    animation: rxsV2Sweep 1.1s cubic-bezier(.4, 0, .2, 1) infinite;
    background: linear-gradient(90deg, transparent, var(--rx-v2-accent) 35%, var(--rx-v2-accent) 65%, transparent);
    border-radius: 999px;
    content: "";
    height: 2px;
    left: 0;
    position: absolute;
    top: 0;
    width: 38%;
    will-change: transform;
    z-index: 6;
}

/* feedback tactil en tabs (complementa el rxsV2TabIn del pass 5) */
body.rxs-ui-v2 .nav-tabs-custom ul.customtab > li > a:active {
    transform: scale(.97);
}

@media (prefers-reduced-motion: reduce) {
    body.rxs-ui-v2 .preloader.stvLoading::before,
    body.rxs-ui-v2 .dataTables_wrapper.rxs-loading::before {
        animation: none;
    }
    body.rxs-ui-v2 #maincontent > * {
        animation: none !important;
    }
}

/* (4a) MENU: iconos nivel-1 como chips redondeados; accent al hover/activo.
   En rail (mini-sidebar) el chip queda centrado y funciona igual. */
body.rxs-ui-v2 .sidebar-nav > ul > li > a > i {
    align-items: center;
    background: var(--rx-v2-ghost);
    border-radius: var(--rx-v2-r8);
    display: inline-flex;
    flex: 0 0 auto;
    font-size: 12.5px;
    height: 28px;
    justify-content: center;
    margin-right: 10px;
    transition: background .16s ease, color .16s ease;
    width: 28px;
}
body.rxs-ui-v2 .sidebar-nav > ul > li > a {
    align-items: center;
    display: flex;
}
body.rxs-ui-v2 .sidebar-nav > ul > li > a:hover > i,
body.rxs-ui-v2 .sidebar-nav > ul > li.active > a > i,
body.rxs-ui-v2 .sidebar-nav > ul > li > a.active > i {
    background: var(--rx-v2-accent-soft);
    color: var(--rx-v2-accent);
}

/* (4b) submenu expandido: arbol tipo file-tree. Cada nivel indenta y sus items
   cuelgan de un tronco vertical con un conector horizontal (├─ / └─). El tronco
   se dibuja con li::before (NO border-left de la ul) para poder cortarlo en el
   ultimo hijo y cerrar la └; li::after es la rama horizontal. Aplica a cualquier
   profundidad (grupos anidados quedan colgando igual que las hojas).
   Solo modo expandido: en mini-sidebar el flyout usa otra geometria (pass 12). */
body.rxs-ui-v2:not(.mini-sidebar) .sidebar-nav #sidebarnav ul.treeview-menu {
    border-left: 0;
    margin-left: 14px;
    padding-left: 10px;
}
body.rxs-ui-v2:not(.mini-sidebar) .sidebar-nav #sidebarnav ul.treeview-menu > li {
    position: relative;
}
/* tronco vertical: recorre el alto del li (se encadena con los hermanos)... */
body.rxs-ui-v2:not(.mini-sidebar) .sidebar-nav #sidebarnav ul.treeview-menu > li::before {
    border-left: 1px solid var(--rx-v2-border-soft);
    bottom: 0;
    content: "";
    left: -14px;
    position: absolute;
    top: 0;
}
/* ...salvo el ultimo, donde corta a la altura de la rama y forma la └ */
body.rxs-ui-v2:not(.mini-sidebar) .sidebar-nav #sidebarnav ul.treeview-menu > li:last-child::before {
    bottom: auto;
    height: 20px;
}
/* rama horizontal desde el tronco hasta el item */
body.rxs-ui-v2:not(.mini-sidebar) .sidebar-nav #sidebarnav ul.treeview-menu > li::after {
    border-top: 1px solid var(--rx-v2-border-soft);
    content: "";
    left: -14px;
    position: absolute;
    top: 20px;
    width: 11px;
}
body.rxs-ui-v2:not(.mini-sidebar) .sidebar-nav #sidebarnav > li > ul.treeview-menu li a {
    border-radius: var(--rx-v2-r7);
    font-size: 13px;
    min-height: 34px;
    padding: 4px 6px;
}
/* chevron de grupos tokenizado (la rotacion ya la transiciona style.css) */
body.rxs-ui-v2 .sidebar-nav .has-arrow::after {
    border-color: var(--rx-v2-faint);
}

/* (4c) switcher de sistema (#superselect) y selector de settings de dev
   (.devBar): de select suelto a card rotulada. Misma caja para los dos, solo
   cambia el rotulo del ::before. */
body.rxs-ui-v2 .scroll-sidebar > div:has(> #superselect),
body.rxs-ui-v2 .scroll-sidebar > div.devBar {
    background: var(--rx-v2-panel-2);
    border: 1px solid var(--rx-v2-border-soft);
    border-radius: var(--rx-v2-r10);
    margin: 2px 0 10px;
    padding: 8px 10px 9px;
    text-align: left !important;
}
body.rxs-ui-v2 .scroll-sidebar > div:has(> #superselect)::before,
body.rxs-ui-v2 .scroll-sidebar > div.devBar::before {
    color: var(--rx-v2-faint);
    content: "Sistema";
    display: block;
    font-size: 10px;
    font-weight: 600;
    letter-spacing: .08em;
    margin-bottom: 4px;
    text-transform: uppercase;
}
body.rxs-ui-v2 .scroll-sidebar > div.devBar::before {
    content: "Settings (dev)";
}
/* el link de vista publica cuelga de la card de arriba */
body.rxs-ui-v2 .scroll-sidebar > div.devBtnSite {
    text-align: left;
}
body.rxs-ui-v2 .scroll-sidebar > div.devBtnSite a {
    color: var(--rx-v2-muted);
}
body.rxs-ui-v2 .scroll-sidebar > div.devBtnSite a:hover {
    color: var(--rx-v2-text);
}

/* (4d) buscador del menu (lo inserta ui_v2.js) */
body.rxs-ui-v2 .rxs-menu-search {
    margin: 0 0 8px;
    position: relative;
}
body.rxs-ui-v2 .rxs-menu-search::before {
    color: var(--rx-v2-faint);
    content: "\f002";
    font-family: "Font Awesome 5 Free";
    font-size: 11px;
    font-weight: 900;
    left: 11px;
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
}
body.rxs-ui-v2 .rxs-menu-search input {
    background: var(--rx-v2-field);
    border: 1px solid var(--rx-v2-border-soft);
    border-radius: var(--rx-v2-r8);
    color: var(--rx-v2-text);
    font-size: 12.5px;
    height: 32px;
    outline: none;
    padding: 0 10px 0 30px;
    transition: border-color .16s ease, box-shadow .16s ease;
    width: 100%;
}
body.rxs-ui-v2 .rxs-menu-search input::placeholder {
    color: var(--rx-v2-faint);
}
body.rxs-ui-v2 .rxs-menu-search input:focus {
    border-color: var(--rx-v2-accent);
    box-shadow: 0 0 0 3px var(--rx-v2-accent-soft);
}
/* filtrando: los submenus con hits se muestran abiertos aunque esten .collapse */
body.rxs-ui-v2 #sidebarnav.rxs-menu-filtering ul.treeview-menu.rxs-mf-open {
    display: block !important;
    height: auto !important;
}
/* en rail no hay lugar para el buscador */
@media (min-width: 768px) {
    body.rxs-ui-v2.mini-sidebar .rxs-menu-search {
        display: none;
    }
}

/* (5) TOPBAR: pulido fino */
body.rxs-ui-v2 .topbar .navbar-light .navbar-nav .nav-link,
body.rxs-ui-v2 .topbar .top-navbar .navbar-nav > .nav-item > .nav-link {
    transition: background .16s ease, color .16s ease;
}
/* dot de notificaciones/mensajes: accent en vez del cyan legacy.
   style2.css deja el .notify en el flujo (relative, top:-25px) contando con la altura
   del nav-link de v1; con el nav-link chato de v2 (y sobre todo en el layout horizontal)
   el dot se va 25px arriba del icono, fuera de la barra. Lo anclamos al <a>
   (position:relative) para que caiga siempre en la esquina del icono. */
body.rxs-ui-v2 .topbar .nav-link .notify {
    position: absolute;
    top: 9px;
    right: 8px;
    width: 0;
    height: 0;
    pointer-events: none;
}
body.rxs-ui-v2 .topbar .nav-link .notify .point {
    top: 0;
    right: 0;
}
body.rxs-ui-v2 .topbar .nav-link .notify .heartbit {
    top: -10px;
    right: -10px;
}
body.rxs-ui-v2 .topbar .notify .point {
    background-color: var(--rx-v2-accent);
}
body.rxs-ui-v2 .topbar .notify .heartbit {
    border-color: var(--rx-v2-accent);
}
/* en vivid la topbar ES el degrade de marca: el dot accent sobre accent no se ve */
body.rxs-ui-v2.rxs-ui-vivid .topbar .notify .point {
    background-color: #fff;
}
body.rxs-ui-v2.rxs-ui-vivid .topbar .notify .heartbit {
    border-color: rgba(255, 255, 255, .9);
}
/* separador antes del bloque usuario (bandera de idioma + avatar) */
body.rxs-ui-v2 .topbar .navbar-nav.my-lg-0 > li.langdrop {
    border-left: 1px solid var(--rx-v2-border-soft);
    margin-left: 8px;
    padding-left: 8px;
}
/* avatar: anillo accent al hover */
body.rxs-ui-v2 .topbar .profile-pic {
    transition: box-shadow .16s ease, border-color .16s ease;
}
body.rxs-ui-v2 .topbar .nav-link:hover .profile-pic {
    border-color: var(--rx-v2-accent);
    box-shadow: 0 0 0 3px var(--rx-v2-accent-soft);
}
/* dropdowns del mailbox (notificaciones/mensajes) tokenizados */
body.rxs-ui-v2 .topbar .mailbox .drop-title {
    border-bottom: 1px solid var(--rx-v2-border-soft);
    color: var(--rx-v2-text);
    font-weight: 600;
}
body.rxs-ui-v2 .topbar .mailbox .message-center a:hover {
    background: var(--rx-v2-hover);
}
body.rxs-ui-v2 .topbar .mailbox .message-center h5 {
    color: var(--rx-v2-text);
    white-space:nowrap;
    overflow:hidden;
    text-overflow:ellipsis;
}
body.rxs-ui-v2 .topbar .mailbox .message-center .mail-desc,
body.rxs-ui-v2 .topbar .mailbox .message-center .time {
    color: var(--rx-v2-muted);
}

/* item activo del menu (modo expandido): el gradiente naranja legacy
   (.sidebar-menu li.active>a, !important en current48) -> accent-soft.
   En mini-sidebar ya lo tokeniza pass 12. */
body.rxs-ui-v2:not(.mini-sidebar) .sidebar-menu li.active > a,
body.rxs-ui-v2:not(.mini-sidebar) .sidebar-nav > ul > li.active > a,
body.rxs-ui-v2:not(.mini-sidebar) .sidebar-nav > ul > li.active:hover > a {
    background: var(--rx-v2-accent-soft) !important;
    color: var(--rx-v2-text) !important;
}
body.rxs-ui-v2:not(.mini-sidebar) .sidebar-menu li.active > a i {
    color: var(--rx-v2-accent) !important;
}

/* MOBILE: bajo 768px el theme fuerza body.mini-sidebar pero el sidebar se
   muestra EXPANDIDO (overlay). Ahi no aplican ni los overrides de modo
   expandido (:not(.mini-sidebar)) ni los del rail de pass 12 (min-width 768)
   -> se replican aca para matar los gradientes naranjas legacy. */
@media (max-width: 767.98px) {
    body.rxs-ui-v2 .treeview-menu.collapse,
    body.rxs-ui-v2 .sidebar-nav ul.treeview-menu {
        background: none !important;
    }
    body.rxs-ui-v2 .sidebar-menu li.active > a,
    body.rxs-ui-v2 .sidebar-nav #sidebarnav > li:hover > a {
        background: var(--rx-v2-accent-soft) !important;
        color: var(--rx-v2-text) !important;
    }
    body.rxs-ui-v2 .sidebar-menu li.active > a i {
        color: var(--rx-v2-accent) !important;
    }
    /* grupos anidados dentro del submenu (li.treeview) tambien gradiente legacy */
    body.rxs-ui-v2 .sidebar-nav #sidebarnav ul.treeview-menu li.treeview > a {
        background: transparent !important;
        color: var(--rx-v2-text) !important;
    }
    body.rxs-ui-v2 .sidebar-nav #sidebarnav ul.treeview-menu li.treeview > a i {
        color: var(--rx-v2-accent) !important;
    }
    body.rxs-ui-v2 .sidebar-nav #sidebarnav > li > ul.treeview-menu {
        border-left: 1px solid var(--rx-v2-border-soft);
        margin-left: 24px;
        padding-left: 8px;
    }
    body.rxs-ui-v2 .sidebar-nav #sidebarnav > li > ul.treeview-menu li a {
        border-radius: var(--rx-v2-r7);
        font-size: 13px;
        min-height: 34px;
        padding: 7px 10px;
    }
}

/* ============================================================
   UI v2 pass 21 — filtros dinamicos de calendar/listados Vue

   El componente rxs-filters se renderiza como .filterStv.pt-1 con hijos
   .filter-item. Se identifica por estructura para no tocar los filterStv de
   YADCF/DataTables, que usan .input-group.
   ============================================================ */

body.rxs-ui-v2 .filterStv.pt-1.rxs-v2-chips {
    align-items: center;
    background: var(--rx-v2-panel-2);
    border: 1px solid var(--rx-v2-border-soft);
    border-radius: var(--rx-v2-r12);
    display: flex;
    flex-wrap: wrap;
    gap: 7px;
    padding: 10px 12px !important;
}

body.rxs-ui-v2 .filterStv.pt-1.rxs-v2-chips > span.mr-1 {
    align-items: center;
    color: var(--rx-v2-muted);
    display: inline-flex;
    font-size: 10.5px;
    font-weight: 750;
    gap: 7px;
    letter-spacing: .07em;
    margin: 0 3px 0 0 !important;
    text-transform: uppercase;
}

body.rxs-ui-v2 .filterStv.pt-1.rxs-v2-chips > span.mr-1::before {
    color: var(--rx-v2-accent);
    content: "\f0b0";
    font-family: "Font Awesome 5 Free";
    font-size: 11px;
    font-weight: 900;
}

body.rxs-ui-v2 .filterStv.pt-1.rxs-v2-chips .filter-item {
    margin: 0 !important;
    position: relative;
}

body.rxs-ui-v2 .filterStv.pt-1.rxs-v2-chips .filter-item > input[type="checkbox"] {
    height: 1px;
    opacity: 0;
    overflow: hidden;
    pointer-events: none;
    position: absolute;
    width: 1px;
}

body.rxs-ui-v2 .filterStv.pt-1.rxs-v2-chips .filter-item > label {
    align-items: center;
    background: var(--rx-v2-panel);
    border: 1px solid var(--rx-v2-border);
    border-radius: 999px;
    color: var(--rx-v2-muted);
    cursor: pointer;
    display: inline-flex;
    font-size: 12px;
    font-weight: 550;
    gap: 7px;
    line-height: 1;
    margin: 0 !important;
    min-height: 30px;
    padding: 5px 10px 5px 8px;
    transition: background .16s ease, border-color .16s ease, color .16s ease, transform .16s ease;
    white-space: nowrap;
}

body.rxs-ui-v2 .filterStv.pt-1.rxs-v2-chips .filter-item > label::before {
    align-items: center;
    border: 1px solid var(--rx-v2-border);
    border-radius: 50%;
    color: transparent;
    content: "\2713";
    display: inline-flex;
    flex: 0 0 16px;
    font-family: Arial, sans-serif;
    font-size: 10px;
    font-weight: 700;
    height: 16px;
    justify-content: center;
    position: static;
    transition: background .16s ease, border-color .16s ease, color .16s ease;
    width: 16px;
}

body.rxs-ui-v2 .filterStv.pt-1.rxs-v2-chips .filter-item > label:hover {
    background: var(--rx-v2-hover);
    border-color: color-mix(in srgb, var(--rx-v2-accent) 36%, var(--rx-v2-border));
    color: var(--rx-v2-text);
    transform: translateY(-1px);
}

body.rxs-ui-v2 .filterStv.pt-1.rxs-v2-chips .filter-item > input[type="checkbox"]:focus-visible + label {
    border-color: var(--rx-v2-accent);
    box-shadow: 0 0 0 3px var(--rx-v2-accent-soft);
}

body.rxs-ui-v2 .filterStv.pt-1.rxs-v2-chips .filter-item > input[type="checkbox"]:checked + label {
    background: var(--rx-v2-accent-soft);
    border-color: color-mix(in srgb, var(--rx-v2-accent) 58%, var(--rx-v2-border));
    color: var(--rx-v2-accent);
    font-weight: 650;
}

body.rxs-ui-v2 .filterStv.pt-1.rxs-v2-chips .filter-item > input[type="checkbox"]:checked + label::before {
    background: var(--rx-v2-accent);
    border-color: var(--rx-v2-accent);
    color: var(--rx-v2-accent-ink);
}

body.rxs-ui-v2.rxs-ui-vivid .filterStv.pt-1.rxs-v2-chips .filter-item > input[type="checkbox"]:checked + label {
    background: var(--rx-v2-accent);
    border-color: var(--rx-v2-accent);
    color: var(--rx-v2-accent-ink);
}

body.rxs-ui-v2.rxs-ui-vivid .filterStv.pt-1.rxs-v2-chips .filter-item > input[type="checkbox"]:checked + label::before {
    background: color-mix(in srgb, #fff 22%, transparent);
    border-color: color-mix(in srgb, #fff 42%, transparent);
    color: var(--rx-v2-accent-ink);
}

/* Acciones del selector: limpiar y expandir en mobile. */
body.rxs-ui-v2 .filterStv.pt-1.rxs-v2-chips > button.btn-danger {
    align-items: center;
    background: color-mix(in srgb, #ef4444 11%, var(--rx-v2-panel)) !important;
    border: 1px solid color-mix(in srgb, #ef4444 35%, var(--rx-v2-border)) !important;
    border-radius: 999px;
    box-shadow: none;
    color: #d83b3b !important;
    display: inline-flex;
    font-size: 11.5px;
    font-weight: 650;
    gap: 3px;
    margin: 0 !important;
    min-height: 30px;
    padding: 5px 10px;
}

body.rxs-ui-v2.thr-dark .filterStv.pt-1.rxs-v2-chips > button.btn-danger {
    color: #ff8492 !important;
}

body.rxs-ui-v2 .filterStv.pt-1.rxs-v2-chips > .show-more-label {
    background: var(--rx-v2-ghost) !important;
    border: 1px solid var(--rx-v2-border) !important;
    border-radius: var(--rx-v2-r8);
    box-shadow: none;
    color: var(--rx-v2-muted) !important;
    font-size: 11.5px;
    font-weight: 650;
    margin: 3px 0 0 !important;
    padding: 7px 10px;
}

body.rxs-ui-v2 .filterStv.pt-1.rxs-v2-chips > .show-more-label:hover {
    background: var(--rx-v2-hover) !important;
    color: var(--rx-v2-text) !important;
}

/* Selector opcional del campo fecha. */
body.rxs-ui-v2 .filterStv.pt-1.rxs-v2-chips > .date-filter2 {
    align-items: center;
    display: inline-flex;
    gap: 7px;
    margin: 0 0 0 auto !important;
}

body.rxs-ui-v2 .filterStv.pt-1.rxs-v2-chips > .date-filter2 > label {
    color: var(--rx-v2-muted);
    font-size: 11px;
    font-weight: 650;
    margin: 0 !important;
}

body.rxs-ui-v2 .filterStv.pt-1.rxs-v2-chips > .date-filter2 > select {
    background: var(--rx-v2-field);
    border: 1px solid var(--rx-v2-border);
    border-radius: var(--rx-v2-r8);
    color: var(--rx-v2-text);
    font-size: 12px;
    height: 32px;
    padding: 4px 28px 4px 9px;
}

/* Campos que aparecen debajo al activar chips. El form Vue no lleva .rxs-form,
   por eso necesita este scope especifico. */
body.rxs-ui-v2 .filterStv.pt-1.rxs-v2-chips + .col-12 {
    padding: 0;
}

body.rxs-ui-v2 .filterStv.pt-1.rxs-v2-chips + .col-12 > form.rxsAjForm {
    background: var(--rx-v2-panel-2);
    border: 1px solid var(--rx-v2-border-soft);
    border-radius: var(--rx-v2-r12);
    margin: 8px 0 12px;
    padding: 11px 12px 5px;
}

body.rxs-ui-v2 .filterStv.pt-1.rxs-v2-chips + .col-12 > form.rxsAjForm:has(> .row:empty) {
    display: none;
}

body.rxs-ui-v2 .filterStv.pt-1.rxs-v2-chips + .col-12 > form.rxsAjForm > .row {
    margin-left: -6px;
    margin-right: -6px;
}

body.rxs-ui-v2 .filterStv.pt-1.rxs-v2-chips + .col-12 > form.rxsAjForm .form-group {
    margin-bottom: 7px !important;
    padding-left: 6px;
    padding-right: 6px;
}

body.rxs-ui-v2 .filterStv.pt-1.rxs-v2-chips + .col-12 > form.rxsAjForm .form-group > label {
    color: var(--rx-v2-muted);
    display: block;
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: .055em;
    margin: 0 0 5px;
    text-transform: uppercase;
}

body.rxs-ui-v2 .filterStv.pt-1.rxs-v2-chips + .col-12 > form.rxsAjForm .form-control,
body.rxs-ui-v2 .filterStv.pt-1.rxs-v2-chips + .col-12 > form.rxsAjForm input:not(.select2-search__field),
body.rxs-ui-v2 .filterStv.pt-1.rxs-v2-chips + .col-12 > form.rxsAjForm select,
body.rxs-ui-v2 .filterStv.pt-1.rxs-v2-chips + .col-12 > form.rxsAjForm textarea {
    background: var(--rx-v2-field);
    border: 1px solid var(--rx-v2-border);
    border-radius: var(--rx-v2-r8);
    color: var(--rx-v2-text);
    font-size: 12.5px;
    min-height: 36px;
}

body.rxs-ui-v2 .filterStv.pt-1.rxs-v2-chips + .col-12 > form.rxsAjForm .select2-container {
    width: 100% !important;
}

body.rxs-ui-v2 .filterStv.pt-1.rxs-v2-chips + .col-12 > form.rxsAjForm .select2-selection {
    background: var(--rx-v2-field) !important;
    border: 1px solid var(--rx-v2-border) !important;
    border-radius: var(--rx-v2-r8) !important;
    color: var(--rx-v2-text) !important;
    min-height: 36px;
}

body.rxs-ui-v2 .filterStv.pt-1.rxs-v2-chips + .col-12 > form.rxsAjForm .select2-selection__rendered,
body.rxs-ui-v2 .filterStv.pt-1.rxs-v2-chips + .col-12 > form.rxsAjForm .select2-search__field {
    color: var(--rx-v2-text) !important;
}

/* Select2 calcula el buscador multiple segun el placeholder. Dentro del panel
   debe ocupar la seleccion completa, sin generar un segundo box angosto. */
body.rxs-ui-v2 .filterStv.pt-1.rxs-v2-chips + .col-12 > form.rxsAjForm .select2-selection--multiple .select2-selection__rendered {
    box-sizing: border-box;
    display: flex;
    flex-wrap: wrap;
    min-height: 34px;
    padding: 2px 8px !important;
    width: 100%;
}

body.rxs-ui-v2 .filterStv.pt-1.rxs-v2-chips + .col-12 > form.rxsAjForm .select2-search--inline {
    flex: 1 1 100%;
    float: none;
    width: 100%;
}

body.rxs-ui-v2 .filterStv.pt-1.rxs-v2-chips + .col-12 > form.rxsAjForm .select2-search--inline .select2-search__field {
    background: transparent !important;
    border: 0 !important;
    border-radius: 0;
    box-shadow: none !important;
    box-sizing: border-box;
    display: block;
    height: 30px;
    margin: 0;
    min-height: 30px;
    outline: 0;
    padding: 4px 0;
    width: 100% !important;
}

@media (max-width: 767.98px) {
    body.rxs-ui-v2 .filterStv.pt-1.rxs-v2-chips {
        gap: 6px;
        padding: 9px !important;
    }
    /* el chip sigue siendo un target tactil aunque el telefono este apaisado */
    body.rxs-ui-v2 .filterStv.pt-1.rxs-v2-chips .filter-item > label {
        min-height: 32px;
    }
    body.rxs-ui-v2 .filterStv.pt-1.rxs-v2-chips + .col-12 > form.rxsAjForm .form-group {
        flex: 0 0 100%;
        max-width: 100%;
    }
}

/* El "FILTROS:" a renglon propio solo se justifica cuando los chips no entran
 * al lado. Entre 576 y 767 -telefono apaisado- sobra ancho y ese renglon se
 * comia el alto, que es lo que escasea en esa orientacion. */
@media (max-width: 575.98px) {
    body.rxs-ui-v2 .filterStv.pt-1.rxs-v2-chips {
        align-items: stretch;
    }
    body.rxs-ui-v2 .filterStv.pt-1.rxs-v2-chips > span.mr-1 {
        flex: 1 0 100%;
        margin-bottom: 2px !important;
    }
    /* unos pocos px por chip son la diferencia entre que los tres entren en un
     * renglon o que el tercero se vaya solo abajo: 3 chips tipicos median 314
     * de los 310 utiles en un telefono de 390. El alto del target no cambia. */
    body.rxs-ui-v2 .filterStv.pt-1.rxs-v2-chips .filter-item > label {
        gap: 6px;
        padding-left: 7px;
        padding-right: 9px;
    }
    body.rxs-ui-v2 .filterStv.pt-1.rxs-v2-chips > .date-filter2 {
        align-items: stretch;
        flex: 1 0 100%;
        flex-direction: column;
        margin-top: 4px !important;
    }
    body.rxs-ui-v2 .filterStv.pt-1.rxs-v2-chips > .date-filter2 > select {
        width: 100% !important;
    }
}

/* =========================================================================
   v2 pass 18: botones flotantes flat + Ctrl+K palette
   ========================================================================= */

/* botones flotantes (corazon de favorito de tabla, launcher del chat):
   gradiente naranja legacy -> accent flat con sombra y hover */
body.rxs-ui-v2 .favMeTable .btn.btn-themecolor,
body.rxs-ui-v2 button.chat-button {
    background: var(--rx-v2-accent) !important;
    border: 0 !important;
    box-shadow: 0 6px 18px rgba(5, 7, 10, .3);
    transition: transform .16s ease, box-shadow .16s ease, background .16s ease;
}
body.rxs-ui-v2 .favMeTable .btn.btn-themecolor:hover,
body.rxs-ui-v2 button.chat-button:hover {
    box-shadow: 0 10px 24px rgba(5, 7, 10, .38);
    transform: translateY(-2px);
}

/* ---- Columna de flotantes ------------------------------------------------
   Los flotantes se fueron sumando cada uno por su lado y ninguno sabia del
   otro: el chat clavado en bottom:2px/right:2px (rexcal.css), la Ayuda en
   absolute bottom:0/right:0 del <main> (custom.css) — o sea encima del chat,
   del submit del alta y de la barra del scanner — y el corazon de favorito en
   top:2.7rem/right:0 del modulo, tapando el ultimo tab.

   Una sola columna con origen y paso fijos. Cada pieza declara SU indice y la
   posicion sale de la cuenta; sumar una cuarta es una linea. El corazon no
   entra en la columna (es del modulo, no global): se corre al costado del
   strip de tabs y el strip le reserva el hueco. */
body.rxs-ui-v2 {
    --rx-v2-fab-edge: 18px;    /* separacion al borde derecho */
    --rx-v2-fab-bottom: 18px;  /* origen de la columna */
    --rx-v2-fab-size: 50px;    /* alto de referencia (el circulo del chat) */
    --rx-v2-fab-gap: 10px;
    --rx-v2-fab-step: calc(var(--rx-v2-fab-size) + var(--rx-v2-fab-gap));
}
/* indice 0: chat */
body.rxs-ui-v2 .chat-wrapper {
    bottom: var(--rx-v2-fab-bottom);
    right: var(--rx-v2-fab-edge);
}
/* el contador de no leidos del launcher (rxsgpt.js .unread-badge): pastilla en la esquina, sin correr el icono */
body.rxs-ui-v2 button.chat-button {
    position: relative;
}
body.rxs-ui-v2 .chat-button .unread-badge {
    background: #e5484d;
    border-radius: 10px;
    box-shadow: 0 0 0 2px var(--rx-v2-shell);
    color: #fff;
    font-size: 11px;
    font-weight: 700;
    height: 20px;
    line-height: 20px;
    min-width: 20px;
    padding: 0 6px;
    position: absolute;
    right: -4px;
    text-align: center;
    top: -4px;
}
/* indice 1: ayuda. Fixed en todos los anchos: en desktop era absolute dentro
   del main (chocaba con lo que hubiera al fondo) y en mobile una barra naranja
   de ancho completo entre el contenido y la bottom nav. */
body.rxs-ui-v2 .table-helpme {
    border-radius: 999px !important;
    bottom: calc(var(--rx-v2-fab-bottom) + var(--rx-v2-fab-step));
    box-shadow: 0 6px 18px rgba(5, 7, 10, .3);
    float: none;
    padding: 12px 16px;
    position: fixed;
    right: var(--rx-v2-fab-edge);
    width: auto;
    z-index: 9999;
}
body.rxs-ui-v2 .table-helpme:hover {
    box-shadow: 0 10px 24px rgba(5, 7, 10, .38);
    transform: translateY(-2px);
}
/* Ayuda nueva: en reposo es solo el icono; el texto aparece al pasar por
   encima (o con foco de teclado). Se anima el ancho para que el pill crezca en
   vez de saltar.
   Es flex para que los espacios en blanco del markup entre los <span> no
   cuenten como ancho: en linea, ese espacio corria el icono a la izquierda del
   circulo. El padding lateral en reposo iguala al vertical, asi el circulo es
   circulo. */
body.rxs-ui-v2 .table-helpme.newhelp {
    align-items: center;
    display: inline-flex;
    justify-content: center;
    line-height: 1;
    padding: 12px;
    transition: box-shadow .18s ease, transform .18s ease, padding .22s ease;
}
body.rxs-ui-v2 .table-helpme.newhelp > span + span {
    margin-left: 8px;
}
body.rxs-ui-v2 .table-helpme.newhelp > span:not([class*="fa"]) {
    flex: 0 1 auto;
    margin-left: 0;
    max-width: 0;
    min-width: 0;
    opacity: 0;
    overflow: hidden;
    transition: max-width .22s ease, opacity .18s ease, margin-left .22s ease;
    white-space: nowrap;
}
body.rxs-ui-v2 .table-helpme.newhelp:hover,
body.rxs-ui-v2 .table-helpme.newhelp:focus-visible,
body.rxs-ui-v2 a.popupurl:focus-visible > .table-helpme.newhelp {
    padding: 12px 16px;
}
body.rxs-ui-v2 .table-helpme.newhelp:hover > span:not([class*="fa"]),
body.rxs-ui-v2 .table-helpme.newhelp:focus-visible > span:not([class*="fa"]),
body.rxs-ui-v2 a.popupurl:focus-visible > .table-helpme.newhelp > span:not([class*="fa"]) {
    margin-left: 8px;
    max-width: 16rem;
    opacity: 1;
}
/* el <a> que envuelve la Ayuda no debe seguir ocupando lugar en el flujo */
body.rxs-ui-v2 a.popupurl.rxs-v2-help {
    display: contents;
}
/* La columna se reserva su lugar al pie del contenido. Sin esto, lo ultimo de
   la pagina (el submit ancho del alta, el paginado de la lista) queda debajo de
   los flotantes cuando se scrollea hasta el fondo, que es justo cuando se lo
   quiere tocar. Mobile ya lo hacia (padding 112px); desktop no. */
@media (min-width: 768px) {
    body.rxs-ui-v2 #maincontent.container-fluid {
        padding-bottom: calc(var(--rx-v2-fab-bottom) + var(--rx-v2-fab-step) + var(--rx-v2-fab-size));
    }
}

/* La bottom nav de mobile ocupa el borde inferior: la columna arranca arriba
   de ella en vez de encima. */
@media (max-width: 767px) {
    body.rxs-ui-v2 {
        --rx-v2-fab-bottom: calc(18px + env(safe-area-inset-bottom, 0px));
        --rx-v2-fab-size: 44px;
    }
    body.rxs-ui-v2:has(.rxsBottomNav, .stvBottomNav, .mobile-bottom-nav) {
        --rx-v2-fab-bottom: calc(72px + env(safe-area-inset-bottom, 0px));
    }
    /* la barra de pestanas del modulo tambien es dock fijo abajo (custom.css) y en v2 perdio el
       padding-left de 50px que le dejaba lugar a la burbuja: sin esto el chat tapa la ultima pestana.
       En la app con pestanas nativas esa barra se esconde (rxs-shell-tabs-native) y no hace falta. */
    html:not(.rxs-shell-tabs-native) body.rxs-ui-v2:has(#maincontent > .stvModuleTable > .nav-tabs-custom > .nav.customtab, #maincontent > .stvModuleTable > .nav-tabs-custom > #tabtabs > .nav.customtab) {
        --rx-v2-fab-bottom: calc(72px + env(safe-area-inset-bottom, 0px));
    }
    /* custom.css manda el chat a la IZQUIERDA en mobile (la barra ocupaba la derecha); en v2 va arriba de la
       barra, asi que vuelve a la columna de flotantes, a la derecha con la ayuda. Los minis no se tocan. */
    body.rxs-ui-v2 :not(.rxs-chat-mini-host) > .chat-wrapper {
        left: auto !important;
        right: var(--rx-v2-fab-edge) !important;
    }
    /* el dock en oscuro: blacked.css lo pinta con --bg-secondary (#383f48) sobre la pagina v2 */
    body.rxs-ui-v2.blacked #maincontent > .stvModuleTable > .nav-tabs-custom > .nav.customtab,
    body.rxs-ui-v2.blacked #maincontent > .stvModuleTable > .nav-tabs-custom > #tabtabs > .nav.customtab {
        background: var(--rx-v2-shell) !important;
    }
    body.rxs-ui-v2 .table-helpme {
        font-size: 13px;
        padding: 10px 14px;
    }
    body.rxs-ui-v2 .table-helpme.newhelp {
        padding: 10px;
    }
    body.rxs-ui-v2 .table-helpme.newhelp:hover,
    body.rxs-ui-v2 .table-helpme.newhelp:focus-visible,
    body.rxs-ui-v2 a.popupurl:focus-visible > .table-helpme.newhelp {
        padding: 10px 14px;
    }
}

/* Corazon de favorito: pegado al strip de tabs, no encima. El strip le cede el
   ancho (max-width) y el corazon se centra en su altura. */

body.rxs-ui-v2 .stvModuleTable > .favMeTable {
    top: 3rem !important;
}
@keyframes rxsV2CmdkIn {
    from { opacity: 0; transform: translateY(-8px) scale(.985); }
    to   { opacity: 1; transform: none; }
}

/* preloader en mobile real: el legacy usa height:100% (inline) + top:0 sin
   left/inset; en viewport dinamico (barra de URL que colapsa) el 100% queda
   corto y no cubre toda la pantalla. inset completo + unidades de viewport
   dinamicas (dvh con fallback). El inline width/height pide !important. */
body.rxs-ui-v2 .preloader.stvLoading {
    height: 100dvh !important;
    inset: 0;
    width: 100dvw !important;
}

/* preloader mobile, 2do intento: en telefono real el velo seguia cubriendo
   ~50% del alto (la caja del elemento queda corta por algo del browser/inline
   que no reproducimos en emulador). Solucion a prueba de caja: el elemento ya
   no pinta fondo; el velo va en un ::after position:fixed inset:0, que se
   ancla al VIEWPORT sin importar el tamaño del elemento. filter/transform se
   fuerzan a none para que el fixed del pseudo no quede atrapado en un
   containing block. El fade de jQuery sigue andando (la opacity del elemento
   aplica a sus pseudos). */
body.rxs-ui-v2 .preloader.stvLoading {
    background: transparent !important;
    filter: none !important;
    transform: none !important;
}
body.rxs-ui-v2 .preloader.stvLoading::after {
    background: color-mix(in srgb, var(--rx-v2-bg) 72%, transparent);
    content: "";
    inset: 0;
    position: fixed;
    z-index: -1;
}

/* =========================================================================
   v2 pass 19: fixes lote 2026-07
   ========================================================================= */

/* (1) topbar: "Ver todas" en mailbox notif/mensajes → boton ancho completo */
body.rxs-ui-v2 .topbar .mailbox > ul > li > a.nav-link.text-center {
    align-items: center;
    border-top: 1px solid var(--rx-v2-border-soft);
    color: var(--rx-v2-accent) !important;
    display: flex;
    font-size: 13px;
    font-weight: 600;
    gap: 6px;
    justify-content: center;
    padding: 10px 16px;
    width: 100%;
}
body.rxs-ui-v2 .topbar .mailbox > ul > li > a.nav-link.text-center:hover {
    background: var(--rx-v2-hover);
    color: var(--rx-v2-accent) !important;
    text-decoration: none;
}

/* (2) user dropdown: tokenizar colores (style.css aplica gris oscuro sin scope) */
body.rxs-ui-v2 .topbar ul.dropdown-user li a {
    color: var(--rx-v2-text) !important;
}
body.rxs-ui-v2 .topbar ul.dropdown-user li a:hover {
    background: var(--rx-v2-hover) !important;
    color: var(--rx-v2-text) !important;
    text-decoration: none;
}
body.rxs-ui-v2 .topbar ul.dropdown-user li.divider {
    background-color: var(--rx-v2-border-soft) !important;
}
body.rxs-ui-v2 .topbar ul.dropdown-user li .dw-user-box .u-text h4 {
    color: var(--rx-v2-text);
    font-size: 14px;
    font-weight: 600;
    margin: 0 0 2px;
}
body.rxs-ui-v2 .topbar ul.dropdown-user li .dw-user-box .u-text p.text-muted {
    color: var(--rx-v2-muted) !important;
    font-size: 12px;
    margin: 0;
}

/* (3) campo tags huerfano: la div.m-3 queda fuera del card .rxs-form-grid */
body.rxs-ui-v2 form.rxs-form > div.m-3 {
    background: var(--rx-v2-panel);
    border: 1px solid var(--rx-v2-border);
    border-radius: var(--rx-v2-r12);
    box-shadow: var(--rx-v2-shadow);
    margin: 12px 0 !important;
    padding: 12px 16px !important;
}

/* (4) tabla: tabs principales con icon-badge circular igual que ficha */
body.rxs-ui-v2 .nav-tabs-custom.card > ul.customtab {
    display: flex;
    width: 100%;
}
body.rxs-ui-v2 .nav-tabs-custom.card > ul.customtab > li {
    flex: 1 1 auto;
}
body.rxs-ui-v2 .nav-tabs-custom.card > ul.customtab > li > a {
    justify-content: center;
    width: 100%;
}
body.rxs-ui-v2 .nav-tabs-custom.card > ul.customtab > li:not([data-clr]) > a > span[class*="fa"] {
    align-items: center;
    background: var(--rx-v2-accent-soft);
    border-radius: 50%;
    color: var(--rx-v2-accent);
    display: inline-flex;
    font-size: 1.4rem;
    height: 2.3rem;
    justify-content: center;
    line-height: 1.9rem;
    margin-right: .35rem;
    min-width: 20px;
    padding: .2rem .5rem;
    text-align: center;
    vertical-align: middle;
    width: 2.4rem;
}
/* icono activo en tabla: mismo contraste que ficha */
body.rxs-ui-v2 .nav-tabs-custom.card > ul.customtab > li:not([data-clr]) > a.active > span[class*="fa"],
body.rxs-ui-v2 .nav-tabs-custom.card > ul.customtab > li.active:not([data-clr]) > a > span[class*="fa"] {
    background: var(--rx-v2-accent);
    color: #fff;
}

/* ---- v2 pass 14: "colores vivos" (opt-in por usuario: json ui_vivid=1 ->
 * body.rxs-ui-vivid). Rompe el minimalismo: acciones de fila con color pleno,
 * header de tabla tintado, tabs y sidebar con mas acento. ---- */

body.rxs-ui-v2.rxs-ui-vivid .rxs-module table.rxs-table td .btn:not(:where(.rxsBtnsOwn .btn)),
body.rxs-ui-v2.rxs-ui-vivid .rxs-module .rxsBtns .btn:not(:where(.rxsBtnsOwn .btn)),
body.rxs-ui-v2.rxs-ui-vivid .rxs-search-page .rxsBtns .btn:not(:where(.rxsBtnsOwn .btn)) {
    border: 0 !important;
    color: #fff !important;
    opacity: 1;
}

body.rxs-ui-v2.rxs-ui-vivid .rxs-module table.rxs-table td .btn:not(:where(.rxsBtnsOwn .btn)).btn-info,
body.rxs-ui-v2.rxs-ui-vivid .rxs-module table.rxs-table td .btn:not(:where(.rxsBtnsOwn .btn)).btn-primary,
body.rxs-ui-v2.rxs-ui-vivid .rxs-module .rxsBtns .btn:not(:where(.rxsBtnsOwn .btn)).btn-info,
body.rxs-ui-v2.rxs-ui-vivid .rxs-module .rxsBtns .btn:not(:where(.rxsBtnsOwn .btn)).btn-primary,
body.rxs-ui-v2.rxs-ui-vivid .rxs-search-page .rxsBtns .btn:not(:where(.rxsBtnsOwn .btn)).btn-info,
body.rxs-ui-v2.rxs-ui-vivid .rxs-search-page .rxsBtns .btn:not(:where(.rxsBtnsOwn .btn)).btn-primary {
    background: #2e90fa !important;
}

body.rxs-ui-v2.rxs-ui-vivid .rxs-module table.rxs-table td .btn:not(:where(.rxsBtnsOwn .btn)).btn-warning,
body.rxs-ui-v2.rxs-ui-vivid .rxs-module .rxsBtns .btn:not(:where(.rxsBtnsOwn .btn)).btn-warning,
body.rxs-ui-v2.rxs-ui-vivid .rxs-search-page .rxsBtns .btn:not(:where(.rxsBtnsOwn .btn)).btn-warning {
    background: #f59e0b !important;
    color: #201503 !important;
}

body.rxs-ui-v2.rxs-ui-vivid .rxs-module table.rxs-table td .btn:not(:where(.rxsBtnsOwn .btn)).btn-danger,
body.rxs-ui-v2.rxs-ui-vivid .rxs-module .rxsBtns .btn:not(:where(.rxsBtnsOwn .btn)).btn-danger,
body.rxs-ui-v2.rxs-ui-vivid .rxs-search-page .rxsBtns .btn:not(:where(.rxsBtnsOwn .btn)).btn-danger {
    background: #ef4444 !important;
}

body.rxs-ui-v2.rxs-ui-vivid .rxs-module table.rxs-table td .btn:not(:where(.rxsBtnsOwn .btn)).btn-success,
body.rxs-ui-v2.rxs-ui-vivid .rxs-module .rxsBtns .btn:not(:where(.rxsBtnsOwn .btn)).btn-success,
body.rxs-ui-v2.rxs-ui-vivid .rxs-search-page .rxsBtns .btn:not(:where(.rxsBtnsOwn .btn)).btn-success {
    background: #22c55e !important;
    color: #04220f !important;
}

body.rxs-ui-v2.rxs-ui-vivid .rxs-module table.rxs-table td .btn:not(:where(.rxsBtnsOwn .btn)).btn-themecolor,
body.rxs-ui-v2.rxs-ui-vivid .rxs-module .rxsBtns .btn:not(:where(.rxsBtnsOwn .btn)).btn-themecolor,
body.rxs-ui-v2.rxs-ui-vivid .rxs-search-page .rxsBtns .btn:not(:where(.rxsBtnsOwn .btn)).btn-themecolor {
    background: var(--rx-v2-accent) !important;
    color: var(--rx-v2-accent-ink) !important;
}

body.rxs-ui-v2.rxs-ui-vivid .rxs-module table.rxs-table td .btn:not(:where(.rxsBtnsOwn .btn)):hover,
body.rxs-ui-v2.rxs-ui-vivid .rxs-module .rxsBtns .btn:not(:where(.rxsBtnsOwn .btn)):hover,
body.rxs-ui-v2.rxs-ui-vivid .rxs-search-page .rxsBtns .btn:not(:where(.rxsBtnsOwn .btn)):hover {
    filter: brightness(1.12);
}

/* header de tabla con tinte del acento */
body.rxs-ui-v2.rxs-ui-vivid .rxs-module table.rxs-table thead th {
    background: color-mix(in srgb, var(--rx-v2-accent) 9%, var(--rx-v2-head)) !important;
    color: color-mix(in srgb, var(--rx-v2-accent) 38%, var(--rx-v2-muted)) !important;
}

/* icono del modulo y tab activa a color pleno */
body.rxs-ui-v2.rxs-ui-vivid .rxs-module .rxs-module-icon {
    background: linear-gradient(135deg, var(--rx-v2-accent), var(--rx-v2-accent-2));
    color: #fff;
}

body.rxs-ui-v2.rxs-ui-vivid .customtab li a.nav-link.active,
body.rxs-ui-v2.rxs-ui-vivid .nav-tabs .nav-link.active {
    background: var(--rx-v2-accent);
    box-shadow: 0 2px 8px color-mix(in srgb, var(--rx-v2-accent) 40%, transparent);
    color: var(--rx-v2-accent-ink);
}

body.rxs-ui-v2.rxs-ui-vivid .customtab li a.nav-link.active i,
body.rxs-ui-v2.rxs-ui-vivid .nav-tabs .nav-link.active i {
    color: var(--rx-v2-accent-ink);
}

/* pills de columnas enumerables mas saturadas: lo hacen los --rx-tint-* que el bloque
 * vivid del body redefine (arriba), no una regla aparte. El tinte sigue yendo como capa
 * (background-image) sobre el panel opaco, en la regla base. */

/* item activo del menu con mas acento */
body.rxs-ui-v2.rxs-ui-vivid .sidebar-nav ul li.active > a,
body.rxs-ui-v2.rxs-ui-vivid .sidebar-nav > ul > li.active > a {
    background: color-mix(in srgb, var(--rx-v2-accent) 22%, transparent);
}

/* vivid: acciones del header de ficha (los pinta la regla ghost de
 * .row.justify-content-center) y menu "..." de fila (.rxs-row-menu, que cuelga
 * de body y no pasa por .rxs-module) */
body.rxs-ui-v2.rxs-ui-vivid .rxs-module .row.justify-content-center:not(.allFilters):not(.listStvVue):not(.stvVueAction) .btn.btn-info,
body.rxs-ui-v2.rxs-ui-vivid .rxs-module .row.justify-content-center:not(.allFilters):not(.listStvVue):not(.stvVueAction) .btn.btn-primary,
body.rxs-ui-v2.rxs-ui-vivid .rxs-row-menu .btn.btn-info,
body.rxs-ui-v2.rxs-ui-vivid .rxs-row-menu .btn.btn-primary {
    background: #2e90fa !important;
    border: 0 !important;
    color: #fff !important;
}

body.rxs-ui-v2.rxs-ui-vivid .rxs-module .row.justify-content-center:not(.allFilters):not(.listStvVue):not(.stvVueAction) .btn.btn-warning,
body.rxs-ui-v2.rxs-ui-vivid .rxs-row-menu .btn.btn-warning {
    background: #f59e0b !important;
    border: 0 !important;
    color: #201503 !important;
}

body.rxs-ui-v2.rxs-ui-vivid .rxs-module .row.justify-content-center:not(.allFilters):not(.listStvVue):not(.stvVueAction) .btn.btn-danger,
body.rxs-ui-v2.rxs-ui-vivid .rxs-row-menu .btn.btn-danger {
    background: #ef4444 !important;
    border: 0 !important;
    color: #fff !important;
}

body.rxs-ui-v2.rxs-ui-vivid .rxs-module .row.justify-content-center:not(.allFilters):not(.listStvVue):not(.stvVueAction) .btn.btn-success,
body.rxs-ui-v2.rxs-ui-vivid .rxs-row-menu .btn.btn-success {
    background: #22c55e !important;
    border: 0 !important;
    color: #04220f !important;
}

body.rxs-ui-v2.rxs-ui-vivid .rxs-module .row.justify-content-center:not(.allFilters):not(.listStvVue):not(.stvVueAction) .btn.btn-themecolor,
body.rxs-ui-v2.rxs-ui-vivid .rxs-row-menu .btn.btn-themecolor {
    background: var(--rx-v2-accent) !important;
    border: 0 !important;
    color: var(--rx-v2-accent-ink) !important;
}

body.rxs-ui-v2.rxs-ui-vivid .rxs-module .row.justify-content-center:not(.allFilters):not(.listStvVue):not(.stvVueAction) .btn.btn-info:hover,
body.rxs-ui-v2.rxs-ui-vivid .rxs-module .row.justify-content-center:not(.allFilters):not(.listStvVue):not(.stvVueAction) .btn.btn-primary:hover,
body.rxs-ui-v2.rxs-ui-vivid .rxs-module .row.justify-content-center:not(.allFilters):not(.listStvVue):not(.stvVueAction) .btn.btn-warning:hover,
body.rxs-ui-v2.rxs-ui-vivid .rxs-module .row.justify-content-center:not(.allFilters):not(.listStvVue):not(.stvVueAction) .btn.btn-danger:hover,
body.rxs-ui-v2.rxs-ui-vivid .rxs-module .row.justify-content-center:not(.allFilters):not(.listStvVue):not(.stvVueAction) .btn.btn-success:hover,
body.rxs-ui-v2.rxs-ui-vivid .rxs-module .row.justify-content-center:not(.allFilters):not(.listStvVue):not(.stvVueAction) .btn.btn-themecolor:hover,
body.rxs-ui-v2.rxs-ui-vivid .rxs-row-menu .btn:hover {
    filter: brightness(1.12);
}

/* vivid: botones de card de registro (vista Vue: header de ficha y listas en
 * cards), los apaga body.rxs-ui-v2 .stvVueAction .btn */
body.rxs-ui-v2.rxs-ui-vivid .stvVueAction .btn:not(:where(.rxsBtnsOwn .btn)).btn-info,
body.rxs-ui-v2.rxs-ui-vivid .stvVueAction .btn:not(:where(.rxsBtnsOwn .btn)).btn-primary {
    background: #2e90fa !important;
    border: 0 !important;
    color: #fff !important;
}

body.rxs-ui-v2.rxs-ui-vivid .stvVueAction .btn:not(:where(.rxsBtnsOwn .btn)).btn-warning {
    background: #f59e0b !important;
    border: 0 !important;
    color: #201503 !important;
}

body.rxs-ui-v2.rxs-ui-vivid .stvVueAction .btn:not(:where(.rxsBtnsOwn .btn)).btn-danger {
    background: #ef4444 !important;
    border: 0 !important;
    color: #fff !important;
}

body.rxs-ui-v2.rxs-ui-vivid .stvVueAction .btn:not(:where(.rxsBtnsOwn .btn)).btn-success {
    background: #22c55e !important;
    border: 0 !important;
    color: #04220f !important;
}

body.rxs-ui-v2.rxs-ui-vivid .stvVueAction .btn:not(:where(.rxsBtnsOwn .btn)).btn-themecolor {
    background: var(--rx-v2-accent) !important;
    border: 0 !important;
    color: var(--rx-v2-accent-ink) !important;
}

body.rxs-ui-v2.rxs-ui-vivid .stvVueAction .btn:not(:where(.rxsBtnsOwn .btn)):hover {
    filter: brightness(1.12);
}

/* vivid: botones junto al titulo de la ficha (h4.ftidtitle: editar/ver) */
body.rxs-ui-v2.rxs-ui-vivid .nav-tabs-custom.card.rxs-v2-ficha > h4.ftidtitle > .btn.btn-info,
body.rxs-ui-v2.rxs-ui-vivid .nav-tabs-custom.card.rxs-v2-ficha > h4.ftidtitle > a > .btn.btn-info,
body.rxs-ui-v2.rxs-ui-vivid .nav-tabs-custom.card.rxs-v2-ficha > h4.ftidtitle > .btn.btn-primary,
body.rxs-ui-v2.rxs-ui-vivid .nav-tabs-custom.card.rxs-v2-ficha > h4.ftidtitle > a > .btn.btn-primary {
    background: #2e90fa !important;
    border: 0 !important;
    color: #fff !important;
}

body.rxs-ui-v2.rxs-ui-vivid .nav-tabs-custom.card.rxs-v2-ficha > h4.ftidtitle > .btn.btn-warning,
body.rxs-ui-v2.rxs-ui-vivid .nav-tabs-custom.card.rxs-v2-ficha > h4.ftidtitle > a > .btn.btn-warning {
    background: #f59e0b !important;
    border: 0 !important;
    color: #201503 !important;
}

body.rxs-ui-v2.rxs-ui-vivid .nav-tabs-custom.card.rxs-v2-ficha > h4.ftidtitle > .btn.btn-success,
body.rxs-ui-v2.rxs-ui-vivid .nav-tabs-custom.card.rxs-v2-ficha > h4.ftidtitle > a > .btn.btn-success {
    background: #22c55e !important;
    border: 0 !important;
    color: #04220f !important;
}

body.rxs-ui-v2.rxs-ui-vivid .nav-tabs-custom.card.rxs-v2-ficha > h4.ftidtitle > .btn.btn-danger,
body.rxs-ui-v2.rxs-ui-vivid .nav-tabs-custom.card.rxs-v2-ficha > h4.ftidtitle > a > .btn.btn-danger {
    background: #ef4444 !important;
    border: 0 !important;
    color: #fff !important;
}

body.rxs-ui-v2.rxs-ui-vivid .nav-tabs-custom.card.rxs-v2-ficha > h4.ftidtitle > .btn:hover,
body.rxs-ui-v2.rxs-ui-vivid .nav-tabs-custom.card.rxs-v2-ficha > h4.ftidtitle > a > .btn:hover {
    filter: brightness(1.12);
}

/* ============================================================
   UI v2 — overlays de amt: panel #mbhelper y confirmación #fakealert
   Los dos vienen del theme público (negro plano, texto oscuro heredado) y
   quedaban fuera de lugar dentro del admin v2. Todo scopeado a
   body.rxs-ui-v2: el theme público no se toca.
   El panel del calendario (amtCalendarNew) sólo existe con v2 activa, así
   que no necesita variante legacy.
   ============================================================ */
body.rxs-ui-v2 #mbhelper,
body.rxs-ui-v2 #mbhelper2,
body.rxs-ui-v2 #mbhelper3 {
    background: var(--rx-v2-bg);
    color: var(--rx-v2-text);
    font-family: var(--rx-v2-font);
}
/* Blanco fijo heredado de v1: en v1 estos paneles son negros, así que tanto el JS
   (custom/amt) como las descripciones que cada tenant escribió con el editor traen
   `color:#FFF` inline para poder leerse. En v2 el panel es claro y ese texto
   desaparece. El contenido está en la base de cada tenant -no se puede migrar- y es
   inline -no se puede pisar sin !important-, así que acá se neutraliza SOLO el
   blanco y SOLO en v2: v1 sigue viéndose igual. */
body.rxs-ui-v2 :is(.mbhelper, .rxs99-container, #amtcal-rxs99)
    :is([style*="color:#fff" i], [style*="color: #fff" i],
        [style*="color:white" i], [style*="color: white" i]):not([style*="background" i]) {
    color: var(--rx-v2-text) !important;
}
/* ...salvo el resaltador: el editor lo escupe como el `color:#FFF` en el ancestro y
   el `background` en un span hijo, y ese fondo no cambia con el tema, así que ahí el
   blanco es el color correcto y se devuelve (los hijos lo heredan).
   Va acotado a etiquetas de línea a propósito. Los tenants también maquetan la
   descripción con divs con fondo propio (tarjetas claras con su texto oscuro
   adentro): esos NO son resaltadores y forzarles blanco los deja ilegibles.
   Un elemento que trae color y fondo en el mismo style no necesita regla: la de
   arriba ya lo saltea y su inline manda. */
body.rxs-ui-v2 :is(.mbhelper, .rxs99-container, #amtcal-rxs99)
    :is([style*="color:#fff" i], [style*="color: #fff" i],
        [style*="color:white" i], [style*="color: white" i])
    :is(span, u, b, strong, em, i, mark, small, a)[style*="background" i] {
    color: #fff !important;
}
/* el botón lleva .btn-themecolor, que current49.css pinta con gradiente !important */
body.rxs-ui-v2 #mbhelper .mbhelper-btn.backme {
    background: var(--rx-v2-ghost) !important;
    border: 1px solid var(--rx-v2-border) !important;
    color: var(--rx-v2-text) !important;
    border-radius: var(--rx-v2-r9);
    padding: 6px 14px;
    font-size: 13px;
    transition: background .16s, color .16s, border-color .16s;
}
body.rxs-ui-v2 #mbhelper .mbhelper-btn.backme:hover {
    background: var(--rx-v2-accent-soft) !important;
    border-color: var(--rx-v2-accent) !important;
    color: var(--rx-v2-accent) !important;
}

/* --- panel "Nueva reserva" del calendario --- */
body.rxs-ui-v2 .amtCalPanel {
    max-width: 1100px;
    margin: 12px auto 80px;
}
body.rxs-ui-v2 .amtCalCard {
    background: var(--rx-v2-panel);
    border: 1px solid var(--rx-v2-border-soft);
    border-radius: var(--rx-v2-r14);
    box-shadow: var(--rx-v2-shadow);
    padding: 18px;
}
body.rxs-ui-v2 .amtCalTitle {
    font-size: 19px;
    font-weight: 600;
    color: var(--rx-v2-text);
    margin: 0 0 16px;
}
body.rxs-ui-v2 .amtCalTools {
    padding-bottom: 14px;
    margin-bottom: 6px;
    border-bottom: 1px solid var(--rx-v2-border-soft);
}
body.rxs-ui-v2 .amtCalTools label {
    color: var(--rx-v2-muted);
    font-size: 10.5px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .06em;
    margin-bottom: 5px;
}
body.rxs-ui-v2 .amtCalTools .amtCalHint {
    display: block;
    color: var(--rx-v2-faint);
    font-size: 11px;
    margin-top: 4px;
}
body.rxs-ui-v2 .amtCalTools .form-control {
    background: var(--rx-v2-field);
    color: var(--rx-v2-text);
    border: 1px solid var(--rx-v2-border);
    border-radius: var(--rx-v2-r9);
    height: 36px;
    font-size: 13px;
}
body.rxs-ui-v2 .amtCalTools .form-control:focus {
    border-color: var(--rx-v2-accent);
    box-shadow: 0 0 0 3px var(--rx-v2-accent-soft);
}
/* el caret nativo del select sale claro sobre el field oscuro */
body.rxs-ui-v2 #amtCalOrder {
    appearance: none;
    -webkit-appearance: none;
    background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='%238b94a1' d='M4 6l4 4 4-4z'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 10px center;
    background-size: 16px;
    padding-right: 30px;
}
/* el wizard va sin card propia: la card es el panel */
body.rxs-ui-v2 #amtcal-rxs99 .card {
    background: transparent !important;
    box-shadow: none !important;
}
/* la pregunta viene en blanco fijo del theme público (ahí el panel es negro): dentro
   del admin el panel es claro en light, así que va por el token. Scopeado al
   contenedor del wizard y no a #amtcal-rxs99, que sólo cubre el embebido del
   calendario y dejaba el wizard suelto (#mbhelper) en blanco sobre blanco. */
body.rxs-ui-v2 .rxs99-container #code99-question {
    color: var(--rx-v2-text);
}
/* la etiqueta de cada opción es lo único que se lee de la card: sale del acento
   del sitio, que ya viene con la luminancia clampeada para contrastar en los dos temas */
body.rxs-ui-v2 .rxs99-container .rxs99-option-text {
    color: var(--rx-v2-accent);
}
/* las cards traen `background: white` fijo: en oscuro quedaban blancas con el texto
   ya tokenizado (claro) encima, o sea ilegibles. */
body.rxs-ui-v2 .rxs99-container .rxs99-option-card {
    background: var(--rx-v2-panel-2);
    border-color: var(--rx-v2-border);
}
body.rxs-ui-v2 .rxs99-container .rxs99-option-card:hover {
    border-color: var(--rx-v2-accent);
}
/* breadcrumb: es lo único que muestra el contexto con el que se abrió el wizard
   (el profesional / la sede / el día), así que tiene que leerse sobre el panel. */
body.rxs-ui-v2 .rxs99-container #code99-breadcrumb {
    gap: 10px;
    margin-bottom: 12px;
}
body.rxs-ui-v2 .rxs99-container .rxs99-breadcrumb-item {
    color: var(--rx-v2-text);
}
body.rxs-ui-v2 .rxs99-container .rxs99-breadcrumb-item:last-child {
    color: var(--rx-v2-accent);
}
body.rxs-ui-v2 .rxs99-container .rxs99-breadcrumb-label {
    color: var(--rx-v2-faint);
}
body.rxs-ui-v2 .rxs99-container .rxs99-breadcrumb-sep {
    color: var(--rx-v2-border);
}
body.rxs-ui-v2 .rxs99-container .rxs99-breadcrumb-link:hover,
body.rxs-ui-v2 .rxs99-container .rxs99-breadcrumb-link:focus {
    color: var(--rx-v2-accent);
}

/* --- confirmación (#fakealert / goBigMessage) ---
   El scrim queda oscuro en los dos temas a propósito: es un lightbox, no un
   panel. Lo que se tokeniza es la tarjeta de adentro. */
body.rxs-ui-v2 #fakealert {
    background: rgba(5, 7, 10, .62);
    font-family: var(--rx-v2-font);
    /* el base (custom.css) lo deja como bloque con padding-top:10% => la tarjeta
       quedaba pegada arriba. Flex column centrado = centrado vertical real.
       `safe center` para que los overlays altos (helpers con form) no se corten
       arriba al scrollear. */
    flex-direction: column;
    justify-content: safe center;
    padding: 24px 12px !important;
    overflow-y: auto;
}
/* OJO: el display se muestra/oculta SOLO por inline style (markup base
   `style="display:none"`, jQuery fadeIn/fadeOut). Un `display:flex !important`
   suelto pisa también el none y el overlay queda visible SIEMPRE encima de la
   página. Por eso el flex se aplica sólo cuando el inline NO dice none. */
body.rxs-ui-v2 #fakealert:not([style*="display:none"]):not([style*="display: none"]) {
    display: flex !important;
}
body.rxs-ui-v2 #fakealert > * {
    flex: 0 0 auto;
}
/* La animación lottie es el techo de la tarjeta, no un elemento suelto sobre el
   scrim: mismo ancho/fondo que .title y .text. bodymovin le clava width/height
   inline al <svg>, por eso el tamaño del dibujo se acota con !important. */
body.rxs-ui-v2 #fakealert #bmi {
    width: 100%;
    max-width: 540px;
    margin: 0 auto;
    padding: 16px 20px 0;
    background: var(--rx-v2-panel);
    border: 1px solid var(--rx-v2-border-soft);
    border-bottom: 0;
    border-radius: var(--rx-v2-r14) var(--rx-v2-r14) 0 0;
}
body.rxs-ui-v2 #fakealert #bmi svg {
    width: 9rem !important;
    height: auto !important;
    display: block;
    margin: 0 auto;
}
/* con animación arriba, el borde/redondeo superior lo pone #bmi */
body.rxs-ui-v2 #fakealert #bmi + .title {
    border-top: 0;
    border-radius: 0;
    /* el .title trae margin-top propio: con la animación arriba partía la tarjeta */
    margin-top: 0;
    padding-top: 8px;
}
body.rxs-ui-v2 #fakealert .title,
body.rxs-ui-v2 #fakealert .text {
    /* con el contenedor en flex, el margin auto gana sobre align-items:stretch y
       la tarjeta se encogía al ancho del texto: el width:100% la sostiene */
    width: 100%;
    max-width: 540px;
    margin-left: auto;
    margin-right: auto;
    background: var(--rx-v2-panel);
    color: var(--rx-v2-text);
    border-left: 1px solid var(--rx-v2-border-soft);
    border-right: 1px solid var(--rx-v2-border-soft);
    text-align: center;
}
/* Sólo el overlay-formulario (helpers/amt: inputs, labels, selects) vuelve a la
   izquierda; el mensaje simple (goBigMessage(mode,title,text)) va centrado. */
body.rxs-ui-v2 #fakealert .text:has(input, select, textarea, label, table, .input-group, .select2, .form-control) {
    text-align: left;
}
body.rxs-ui-v2 #fakealert .title {
    border-top: 1px solid var(--rx-v2-border-soft);
    border-radius: var(--rx-v2-r14) var(--rx-v2-r14) 0 0;
    padding: 18px 20px 8px;
    font-size: 18px;
    font-weight: 600;
}
body.rxs-ui-v2 #fakealert .text {
    border-bottom: 1px solid var(--rx-v2-border-soft);
    border-radius: 0 0 var(--rx-v2-r14) var(--rx-v2-r14);
    padding: 0 20px 18px;
    box-shadow: 0 18px 50px rgba(5, 7, 10, .45);
}
/* La sombra de la tarjeta la lleva .text, que va última: sin apilar, su difuminado
   sube y se pinta sobre .title y #bmi (una franja gris sobre el título y el arranque
   del texto, en rxsConfirmModal). Con z-index las de arriba quedan por encima. */
body.rxs-ui-v2 #fakealert #bmi,
body.rxs-ui-v2 #fakealert .title {
    position: relative;
    z-index: 1;
}
body.rxs-ui-v2 #fakealert .text .tname {
    color: var(--rx-v2-muted);
    font-size: 13px;
    /* el .text del dialogo de turnos trae el form del paciente, asi que cae en la regla
       :has(input,select,...) de arriba y se va a la izquierda. Estas lineas (turno /
       profesional / sede) son encabezado, no campos: van centradas como el titulo. */
    text-align: center;
}
/* Botones de acción: hijos directos de .text. El .btn-themecolor del prepend
   "+ nuevo usuario" NO entra acá (vive dentro del form).
   !important obligado: current49.css pinta .btn-themecolor con
   `background: linear-gradient(...) !important`, que gana por especificidad
   de origen sin importar el selector. */
/* `--rx-cartel-bg` / `--rx-cartel-ink` los pone el boton mismo cuando el cartel
   declara un color (rxsCartelHtml, njs/custom4.js). Van como fallback de la
   variable y no como una regla aparte porque el !important de aca gana contra
   cualquier estilo inline: la unica forma de que el color declarado llegue es
   que el VALOR sea declarable, no la regla. Sin declarar, el fallback es lo de
   siempre. */
body.rxs-ui-v2 #fakealert .text > .btn {
    background: var(--rx-cartel-bg, var(--rx-v2-accent)) !important;
    border: 1px solid var(--rx-cartel-bg, var(--rx-v2-accent)) !important;
    color: var(--rx-cartel-ink, var(--rx-v2-accent-ink)) !important;
    border-radius: var(--rx-v2-r10);
    font-size: 14px;
    font-weight: 600;
    padding: 10px 16px;
    margin-top: 10px;
    transition: filter .16s;
}
body.rxs-ui-v2 #fakealert .text > .btn:hover {
    filter: brightness(1.08);
}
/* el segundo botón de las variantes de dos acciones queda como secundario */
body.rxs-ui-v2 #fakealert .text > .btn ~ .btn {
    background: var(--rx-cartel-bg, var(--rx-v2-ghost)) !important;
    border-color: var(--rx-cartel-bg, var(--rx-v2-border)) !important;
    color: var(--rx-cartel-ink, var(--rx-v2-text)) !important;
}
body.rxs-ui-v2 #fakealert #turnotext,
body.rxs-ui-v2 #fakealert .text .form-control {
    background: var(--rx-v2-field);
    color: var(--rx-v2-text);
    border: 1px solid var(--rx-v2-border);
    border-radius: var(--rx-v2-r9);
    width: 100%;
}
body.rxs-ui-v2 #fakealert #turnotext:focus,
body.rxs-ui-v2 #fakealert .text .form-control:focus {
    border-color: var(--rx-v2-accent);
    box-shadow: 0 0 0 3px var(--rx-v2-accent-soft);
    outline: none;
}
body.rxs-ui-v2 #fakealert .text .select2-selection {
    background: var(--rx-v2-field) !important;
    border: 1px solid var(--rx-v2-border) !important;
    border-radius: var(--rx-v2-r9) !important;
    height: 36px;
}
body.rxs-ui-v2 #fakealert .text .select2-selection__rendered {
    background: transparent !important;
    color: var(--rx-v2-text) !important;
    line-height: 34px;
}
body.rxs-ui-v2 #fakealert .text .input-group-text.btn-themecolor {
    background: var(--rx-v2-accent-soft) !important;
    border: 1px solid var(--rx-v2-border) !important;
    color: var(--rx-v2-accent) !important;
    border-radius: var(--rx-v2-r9) 0 0 var(--rx-v2-r9);
}
body.rxs-ui-v2 #fakealert .text label {
    color: var(--rx-v2-muted);
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: .05em;
}
/* La X es un control del cartel, no un adorno suelto: el base la deja
   `position:absolute` contra el overlay, o sea arriba a la derecha de la
   VENTANA, y ahi aterriza sobre lo que la pagina tenga en esa esquina (en el
   turnero, el avatar del header). Como una pieza mas de la tarjeta -mismo ancho
   y mismo centrado que #bmi/.title/.text- queda alineada con ella en cualquier
   ancho de pantalla, que es lo que `align-self` no daria: el contenedor ocupa
   todo el ancho y la tarjeta no. */
body.rxs-ui-v2 #fakealert #bmiclose {
    position: static;
    width: 100%;
    max-width: 540px;
    margin: 0 auto 4px;
    padding: 0;
    text-align: right;
    font-size: 2rem;
    line-height: 1;
    color: var(--rx-v2-faint);
    transition: color .16s;
}
body.rxs-ui-v2 #fakealert #bmiclose:hover {
    color: #fff;
}
@media (max-width: 767px) {
    body.rxs-ui-v2 .amtCalPanel { margin: 8px 0 80px; }
    body.rxs-ui-v2 .amtCalCard { padding: 14px; border-radius: var(--rx-v2-r12); }
}

/* ============================================================
   UI v2 pass 20 — shell vivid, menu de servicio y /home adaptable

   ui_vivid ahora cambia tambien las superficies grandes del producto. Sin
   vivid, /home usa el lenguaje graphite/panel de v2; con vivid recupera la
   energia cromatica del shell v1 sin reintroducir sus gradientes en controles.
   ============================================================ */

/* El theme legacy vuelve a pintar .page-wrapper despues de la regla base de
   v2. Aseguramos que todas las rutas usen el fondo tokenizado. */
body.rxs-ui-v2 .page-wrapper,
/* el toggle de tema (rxsSetTheme, g.js) prende blacked + thr-dark: current49 trae
   `body.blacked:not(.no-logged) .page-wrapper{background-color:#383f48!important}`
   (0,3,2), que le gana a la regla de arriba (0,2,1) aunque las dos sean !important.
   Resultado: el page-wrapper quedaba gris pizarra y el body con el token -> la franja
   de 60px de arriba (donde flota la topbar) se veia como una barra de otro color. */
body.rxs-ui-v2.blacked:not(.no-logged) .page-wrapper,
body.rxs-ui-v2.blacked .thr.thr-anim:not(.no-logged) .page-wrapper {
    background: var(--rx-v2-bg) !important;
    background-color: var(--rx-v2-bg) !important;
}

/* Mismo caso para el BODY, y aca se nota mas: .page-wrapper arranca recien en
   y=60 (el padding-top de .thr-fix), asi que la franja de arriba -donde flota la
   topbar- la pinta el body y NADA mas. Si el theme legacy / el css del tenant le
   pisan el fondo, esa franja queda de otro color y se lee como "una barra" en el
   top (se ve clarito poniendole background:red al body: pinta solo esos 60px).
   Se fuerza el token (el de html sale de las reglas `html.rxs-ui-v2` de mas
   arriba: ahi no se puede usar --rx-v2-bg, que vive en body). */
body.rxs-ui-v2 {
    background: var(--rx-v2-bg) !important;
    background-color: var(--rx-v2-bg) !important;
}

/* ---- Colores vivos: topbar + sidebar como una pieza de marca ---- */
body.rxs-ui-v2.rxs-ui-vivid {
    --rx-v2-vivid-a: var(--rx-color1, #3cb1cc);
    --rx-v2-vivid-b: var(--rx-color2, #8a2ac5);
    /* la gama en vivid: mas saturada y mas opaca (pills y home a la vez) */
    --rx-tint-s: 68%;
    --rx-tint-a: .24;
    --rx-tint-ink-s: 50%;
    --rx-tint-ink-l: 30%;
    --rx-v2-vivid-shell: linear-gradient(118deg,
        color-mix(in srgb, var(--rx-v2-vivid-b) 90%, #12151b),
        color-mix(in srgb, var(--rx-v2-vivid-a) 88%, #12151b));
    --rx-v2-vivid-sidebar: linear-gradient(165deg,
        color-mix(in srgb, var(--rx-v2-vivid-b) 92%, #12151b),
        color-mix(in srgb, var(--rx-v2-vivid-a) 86%, #12151b));
}

/* vivid + dark: sin esto el chrome conserva el gradiente de marca claro y la UI
   queda partida en dos mundos (contenido oscuro, sidebar/topbar de dia). Misma
   receta pero la marca tinie en vez de dominar: mayoria de base noche. */
body.rxs-ui-v2.rxs-ui-vivid.thr-dark {
    --rx-tint-s: 62%;
    --rx-tint-l: 54%;
    --rx-tint-a: .28;
    --rx-tint-ink-s: 70%;
    --rx-tint-ink-l: 78%;
    --rx-v2-vivid-shell: linear-gradient(118deg,
        color-mix(in srgb, var(--rx-v2-vivid-b) 32%, #0d1014),
        color-mix(in srgb, var(--rx-v2-vivid-a) 26%, #0d1014));
    --rx-v2-vivid-sidebar: linear-gradient(165deg,
        color-mix(in srgb, var(--rx-v2-vivid-b) 36%, #0c0f13),
        color-mix(in srgb, var(--rx-v2-vivid-a) 24%, #0c0f13));
}

body.rxs-ui-v2.rxs-ui-vivid .topbar {
    background: var(--rx-v2-vivid-shell) !important;
    border-bottom-color: rgba(255, 255, 255, .16);
    box-shadow: 0 5px 22px rgba(12, 16, 24, .16);
}

body.rxs-ui-v2.rxs-ui-vivid .topbar::after {
    background: linear-gradient(90deg,
        rgba(255, 255, 255, .55),
        rgba(255, 255, 255, .08) 45%,
        rgba(255, 255, 255, .35));
    height: 1px;
    opacity: .8;
}

body.rxs-ui-v2.rxs-ui-vivid .topbar .navbar-header,
body.rxs-ui-v2.rxs-ui-vivid .topbar .top-navbar {
    background: transparent !important;
}

body.rxs-ui-v2.rxs-ui-vivid .topbar .navbar-brand.logo span,
body.rxs-ui-v2.rxs-ui-vivid .topbar .navbar-light .navbar-nav .nav-link,
body.rxs-ui-v2.rxs-ui-vivid .topbar .top-navbar .navbar-nav > .nav-item > .nav-link {
    color: rgba(255, 255, 255, .9) !important;
}

body.rxs-ui-v2.rxs-ui-vivid .topbar .navbar-light .navbar-nav .nav-link:hover,
body.rxs-ui-v2.rxs-ui-vivid .topbar .top-navbar .navbar-nav > .nav-item > .nav-link:hover,
body.rxs-ui-v2.rxs-ui-vivid .topbar .top-navbar .navbar-nav > .nav-item.show > .nav-link {
    background: rgba(255, 255, 255, .16);
    color: #fff !important;
}

body.rxs-ui-v2.rxs-ui-vivid .topbar .profile-pic {
    border-color: rgba(255, 255, 255, .45);
}

body.rxs-ui-v2.rxs-ui-vivid .topbar .navbar-nav.my-lg-0 > li.langdrop {
    border-left-color: rgba(255, 255, 255, .22);
}

body.rxs-ui-v2.rxs-ui-vivid .left-sidebar {
    background: var(--rx-v2-vivid-sidebar) !important;
    border-right-color: rgba(255, 255, 255, .14);
    box-shadow: 5px 0 24px rgba(12, 16, 24, .14);
}

body.rxs-ui-v2.rxs-ui-vivid .left-sidebar .sidebar-nav ul li a,
body.rxs-ui-v2.rxs-ui-vivid .left-sidebar .sidebar-nav ul li a:not(:hover),
body.rxs-ui-v2.rxs-ui-vivid .left-sidebar .sidebar-nav > ul > li > a i,
body.rxs-ui-v2.rxs-ui-vivid .left-sidebar .sidebar-nav ul.treeview-menu li a i {
    color: rgba(255, 255, 255, .88) !important;
    text-shadow: none;
}

body.rxs-ui-v2.rxs-ui-vivid .left-sidebar .sidebar-nav > ul > li > a > i {
    background: rgba(255, 255, 255, .12);
}

body.rxs-ui-v2.rxs-ui-vivid .left-sidebar .sidebar-nav ul li a:hover {
    background: rgba(255, 255, 255, .13) !important;
    color: #fff !important;
}

body.rxs-ui-v2.rxs-ui-vivid:not(.mini-sidebar) .left-sidebar .sidebar-nav ul li.active > a,
body.rxs-ui-v2.rxs-ui-vivid:not(.mini-sidebar) .left-sidebar .sidebar-nav > ul > li.active > a,
body.rxs-ui-v2.rxs-ui-vivid:not(.mini-sidebar) .left-sidebar .sidebar-nav > ul > li.active:hover > a {
    background: rgba(255, 255, 255, .2) !important;
    box-shadow: inset 3px 0 0 rgba(255, 255, 255, .9);
    color: #fff !important;
}

body.rxs-ui-v2.rxs-ui-vivid .left-sidebar .sidebar-nav ul li.active > a i {
    background: rgba(255, 255, 255, .18);
    color: #fff !important;
    border-radius: 0.5rem;
}

body.rxs-ui-v2.rxs-ui-vivid .left-sidebar .sidebar-nav .has-arrow::after {
    border-color: rgba(255, 255, 255, .72);
}

body.rxs-ui-v2.rxs-ui-vivid .left-sidebar .scroll-sidebar > div:has(> #superselect),
body.rxs-ui-v2.rxs-ui-vivid .left-sidebar .scroll-sidebar > div.devBar {
    background: rgba(255, 255, 255, .1);
    border-color: rgba(255, 255, 255, .16);
}

body.rxs-ui-v2.rxs-ui-vivid .left-sidebar .scroll-sidebar > div:has(> #superselect)::before,
body.rxs-ui-v2.rxs-ui-vivid .left-sidebar .scroll-sidebar > div.devBar::before,
body.rxs-ui-v2.rxs-ui-vivid .left-sidebar .rxs-menu-search::before {
    color: rgba(255, 255, 255, .68);
}
body.rxs-ui-v2.rxs-ui-vivid .left-sidebar .scroll-sidebar > div.devBtnSite a {
    color: rgba(255, 255, 255, .68);
}
body.rxs-ui-v2.rxs-ui-vivid .left-sidebar .scroll-sidebar > div.devBtnSite a:hover {
    color: #fff;
}

body.rxs-ui-v2.rxs-ui-vivid .left-sidebar .rxs-menu-search input {
    background: rgba(8, 11, 18, .16);
    border-color: rgba(255, 255, 255, .18);
    color: #fff;
}

body.rxs-ui-v2.rxs-ui-vivid .left-sidebar .rxs-menu-search input::placeholder {
    color: rgba(255, 255, 255, .62);
}

body.rxs-ui-v2.rxs-ui-vivid .left-sidebar .rxs-menu-search input:focus {
    border-color: rgba(255, 255, 255, .62);
    box-shadow: 0 0 0 3px rgba(255, 255, 255, .13);
}

/* En rail, los flyouts siguen siendo popovers v2 legibles: no heredan el
   vidrio blanco pensado para links apoyados sobre el gradiente. */
@media (min-width: 768px) {
    body.rxs-ui-v2.rxs-ui-vivid.mini-sidebar .left-sidebar .sidebar-nav #sidebarnav > li:hover > a {
        background: var(--rx-v2-panel-2) !important;
        color: var(--rx-v2-text) !important;
    }
    body.rxs-ui-v2.rxs-ui-vivid.mini-sidebar .left-sidebar .sidebar-nav #sidebarnav > li:hover > a i {
        color: var(--rx-v2-accent) !important;
    }
    body.rxs-ui-v2.rxs-ui-vivid.mini-sidebar .left-sidebar .sidebar-nav #sidebarnav > li > ul a {
        color: var(--rx-v2-text) !important;
    }
}

/* ---- Menu de servicio: off-canvas tokenizado ---- */
body.rxs-ui-v2 .right-sidebar {
    background: var(--rx-v2-panel);
    border-left: 1px solid var(--rx-v2-border);
    box-shadow: -18px 0 48px rgba(8, 12, 18, .24);
    color: var(--rx-v2-text);
    font-family: var(--rx-v2-font);
    height: 100dvh;
    overflow: hidden;
    padding: 0;
    right: -320px;
    transition: right .26s cubic-bezier(.2, .75, .25, 1), box-shadow .26s ease;
    width: 320px;
}

body.rxs-ui-v2 .right-sidebar.shw-rside {
    display: block;
    right: 0;
    width: 320px;
}

body.rxs-ui-v2 .right-sidebar .slimscrollright {
    height: 100%;
    overflow-x: hidden;
    overflow-y: auto;
}

body.rxs-ui-v2 .right-sidebar .rpanel-title {
    align-items: center;
    background: var(--rx-v2-panel-2) !important;
    border: 0;
    border-bottom: 1px solid var(--rx-v2-border-soft);
    color: var(--rx-v2-text);
    display: flex;
    font-size: 12px;
    font-weight: 750;
    gap: 10px;
    height: 64px;
    letter-spacing: .075em;
    padding: 0 16px 0 18px;
    text-transform: uppercase;
}

body.rxs-ui-v2 .right-sidebar .rpanel-title::before {
    align-items: center;
    background: linear-gradient(135deg, var(--rx-v2-accent), var(--rx-color2, #8a2ac5));
    border-radius: var(--rx-v2-r9);
    color: #fff;
    content: "\f14e";
    display: inline-flex;
    flex: 0 0 32px;
    font-family: "Font Awesome 5 Free";
    font-size: 14px;
    font-weight: 900;
    height: 32px;
    justify-content: center;
    letter-spacing: 0;
}

body.rxs-ui-v2 .right-sidebar .rpanel-title span {
    align-items: center;
    background: var(--rx-v2-ghost);
    border: 1px solid var(--rx-v2-border-soft);
    border-radius: var(--rx-v2-r8);
    color: var(--rx-v2-muted);
    display: inline-flex;
    float: none;
    height: 32px;
    justify-content: center;
    margin-left: auto;
    position: relative;
    transition: background .16s ease, color .16s ease;
    width: 32px;
}

body.rxs-ui-v2 .right-sidebar .rpanel-title span > i {
    align-items: center;
    cursor: pointer;
    display: flex;
    inset: 0;
    justify-content: center;
    position: absolute;
}

body.rxs-ui-v2 .right-sidebar .rpanel-title span:hover {
    background: var(--rx-v2-accent-soft);
    color: var(--rx-v2-accent);
}

body.rxs-ui-v2 .right-sidebar .r-panel-body {
    color: var(--rx-v2-text);
    padding: 14px !important;
}

body.rxs-ui-v2 .right-sidebar .cart-slider {
    margin-bottom: 12px !important;
}

body.rxs-ui-v2 .right-sidebar .cart-content {
    background: var(--rx-v2-panel-2);
    border: 1px solid var(--rx-v2-border-soft);
    border-radius: var(--rx-v2-r12);
    color: var(--rx-v2-text);
    padding: 13px;
}

body.rxs-ui-v2 .right-sidebar .click-history-content {
    background: var(--rx-v2-panel-2);
    border: 1px solid var(--rx-v2-border-soft);
    border-radius: var(--rx-v2-r12);
    color: var(--rx-v2-text);
    padding: 13px;
}

body.rxs-ui-v2 .right-sidebar .click-history-content .card {
    background: var(--rx-v2-panel) !important;
    border: 1px solid var(--rx-v2-border-soft);
    border-radius: var(--rx-v2-r8);
    box-shadow: none;
    cursor: pointer;
    position: relative;
    transition: background .16s ease, border-color .16s ease, transform .16s ease;
}

body.rxs-ui-v2 .right-sidebar .click-history-content .card:hover,
body.rxs-ui-v2 .right-sidebar .click-history-content .card:focus-within {
    background: var(--rx-v2-accent-soft) !important;
    border-color: color-mix(in srgb, var(--rx-v2-accent) 45%, var(--rx-v2-border));
    transform: translateY(-1px);
}

/* El template usa .text-primary en los links del historial. Bootstrap los
   dejaba azul pleno dentro de una superficie neutra v2. */
body.rxs-ui-v2 .right-sidebar .click-history-content a.text-primary {
    color: var(--rx-v2-text) !important;
    font-size: 12.5px;
    font-weight: 600;
    text-decoration: none;
}

/* Extiende el enlace real sobre toda la card: no duplica handlers ni cambia
   la navegación .loadpage del template. */
body.rxs-ui-v2 .right-sidebar .click-history-content a.text-primary::after {
    content: "";
    inset: 0;
    position: absolute;
    z-index: 1;
}

body.rxs-ui-v2 .right-sidebar .click-history-content a.text-primary:hover {
    color: var(--rx-v2-accent) !important;
}

body.rxs-ui-v2 .right-sidebar .cart-content h4,
body.rxs-ui-v2 .right-sidebar .click-history-content h4 {
    color: var(--rx-v2-muted);
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: .08em;
    margin: 0 0 12px;
    text-transform: uppercase;
}

body.rxs-ui-v2 .right-sidebar .rxsBcd {
    background: var(--rx-v2-field);
    border: 1px solid var(--rx-v2-border) !important;
    border-radius: var(--rx-v2-r8);
    color: var(--rx-v2-text);
    font-size: 12px;
    height: 34px;
    outline: 0;
    padding: 6px 9px;
}

body.rxs-ui-v2 .right-sidebar .rxsBcd:focus {
    border-color: var(--rx-v2-accent) !important;
    box-shadow: 0 0 0 3px var(--rx-v2-accent-soft);
}

body.rxs-ui-v2 .right-sidebar .cart-content .text-center,
body.rxs-ui-v2 .right-sidebar .rxsBarZone,
body.rxs-ui-v2 .right-sidebar .rxsBarContainer {
    align-items: center;
    display: flex !important;
    flex-wrap: wrap;
    gap: 7px;
    justify-content: center;
}

body.rxs-ui-v2 .right-sidebar .rxsBarZone {
    padding: 10px !important;
}

body.rxs-ui-v2 .right-sidebar .btn,
body.rxs-ui-v2 .right-sidebar .btn.btn-success,
body.rxs-ui-v2 .right-sidebar .btn.btn-info {
    align-items: center;
    background: var(--rx-v2-ghost) !important;
    border: 1px solid var(--rx-v2-border) !important;
    border-radius: var(--rx-v2-r8);
    box-shadow: none !important;
    color: var(--rx-v2-text) !important;
    display: inline-flex;
    font-size: 12px;
    font-weight: 600;
    gap: 6px;
    justify-content: center;
    margin: 0 !important;
    min-height: 34px;
    padding: 6px 10px;
    transition: background .16s ease, border-color .16s ease, color .16s ease, transform .16s ease;
}

body.rxs-ui-v2 .right-sidebar .btn i,
body.rxs-ui-v2 .right-sidebar .btn span[class*="fa"] {
    color: var(--rx-v2-accent);
}

body.rxs-ui-v2 .right-sidebar .btn:hover {
    background: var(--rx-v2-accent-soft) !important;
    border-color: color-mix(in srgb, var(--rx-v2-accent) 45%, var(--rx-v2-border)) !important;
    color: var(--rx-v2-text) !important;
    filter: none;
    transform: translateY(-1px);
}

body.rxs-ui-v2 .right-sidebar .cart-content p,
body.rxs-ui-v2 .right-sidebar .cart-content small,
body.rxs-ui-v2 .right-sidebar .cart-content .text-muted {
    color: var(--rx-v2-muted) !important;
    font-size: 12.5px;
}

/* ---- /home: calmo por defecto, cromatico solo con Colores vivos ---- */
body.rxs-ui-v2:not(.rxs-ui-vivid) .menu-visual-container {
    background:
        radial-gradient(circle at 8% 4%, var(--rx-v2-accent-soft), transparent 34%),
        radial-gradient(circle at 92% 96%, color-mix(in srgb, var(--rx-color2, #8a2ac5) 10%, transparent), transparent 36%),
        var(--rx-v2-panel);
    border: 1px solid var(--rx-v2-border-soft);
    border-radius: var(--rx-v2-r14);
    min-height: calc(100vh - 106px);
}

/* Los tokens del home (--hm-*, adm.css) se mapean al skin: las piezas nuevas del home
   (saludo, tira de recientes, mosaico de favoritos, pestanias y tarjetas de sistemas)
   se pintan solo con esos, asi que con esto ya salen bien en claro, oscuro y vivid. */
body.rxs-ui-v2 .menu-visual-container,
body.rxs-ui-v2 .menu-visual-container.dark-mode {
    --hm-text: var(--rx-v2-text);
    --hm-muted: var(--rx-v2-muted);
    --hm-faint: var(--rx-v2-faint);
    --hm-border: var(--rx-v2-border-soft);
    --hm-ghost: var(--rx-v2-ghost);
    --hm-panel: var(--rx-v2-panel);
    --hm-accent: var(--rx-v2-accent);
    --hm-accent-soft: var(--rx-v2-accent-soft);
}

body.rxs-ui-v2:not(.rxs-ui-vivid) .menu-visual-container {
    --hm-hero-text: var(--rx-v2-text);
    --hm-hero-sub: var(--rx-v2-muted);
    --hm-orb-a: var(--rx-v2-accent-soft);
    --hm-orb-b: color-mix(in srgb, var(--rx-color2, #8a2ac5) 14%, transparent);
}

body.rxs-ui-v2:not(.rxs-ui-vivid) .menu-visual-container .hero-title {
    text-shadow: none;
}

body.rxs-ui-v2:not(.rxs-ui-vivid) .menu-visual-container .menu-search-wrapper,
body.rxs-ui-v2:not(.rxs-ui-vivid) .menu-visual-container.dark-mode .menu-search-wrapper {
    background: var(--rx-v2-field);
    border: 1px solid var(--rx-v2-border);
    box-shadow: 0 4px 16px rgba(12, 16, 24, .07);
}

body.rxs-ui-v2:not(.rxs-ui-vivid) .menu-visual-container .menu-search-input,
body.rxs-ui-v2:not(.rxs-ui-vivid) .menu-visual-container.dark-mode .menu-search-input {
    color: var(--rx-v2-text);
}

body.rxs-ui-v2:not(.rxs-ui-vivid) .menu-visual-container .menu-search-input::placeholder {
    color: var(--rx-v2-faint);
}

/* El /home vivido es la superficie mas grande de la UI: con la marca CRUDA
   (era linear-gradient(135deg, color1, color2, color1) a full) una paleta
   saturada -cyan neon + violeta- deja la pantalla gritando, y ademas no se
   parece a la topbar ni al sidebar, que en vivid van con la marca apagada
   contra #12151b. Misma receta que el chrome pero mas profunda todavia
   (superficie grande = menos brillo): sigue siendo la marca, mantiene el
   texto blanco legible, y las tres piezas se leen como una sola. */
body.rxs-ui-v2.rxs-ui-vivid .menu-visual-container {
    background:
        radial-gradient(circle at 12% 8%, rgba(255, 255, 255, .14), transparent 30%),
        radial-gradient(circle at 88% 92%, rgba(255, 255, 255, .08), transparent 32%),
        linear-gradient(135deg,
            color-mix(in srgb, var(--rx-v2-vivid-a) 58%, #12151b) 0%,
            color-mix(in srgb, var(--rx-v2-vivid-b) 72%, #12151b) 52%,
            color-mix(in srgb, var(--rx-v2-vivid-a) 58%, #12151b) 100%);
    box-shadow: 0 18px 44px rgba(12, 16, 24, .2);
}

/* El titulo del /home lo pinta la regla generica de headings de v2
   (h1..h6 -> --rx-v2-text, puesta para los h6 blancos del tema Oscuro), pero
   sobre la superficie de marca tiene que ir en claro. El panel blanco de abajo
   NO entra: ahi el texto va a tokens. */
body.rxs-ui-v2.rxs-ui-vivid .menu-visual-container .hero-title {
    color: #fff;
}

body.rxs-ui-v2.rxs-ui-vivid .menu-visual-container {
    --hm-hero-sub: rgba(255, 255, 255, .75);
}

/* Home: el panel de resultados (modulos, favoritos y datos) va a tokens del skin, y
   la X del buscador tambien. Vale para vivid y no vivid, claro y oscuro. */
body.rxs-ui-v2 .menu-visual-container .menu-search-clear {
    color: var(--rx-v2-faint);
}

body.rxs-ui-v2 .menu-visual-container .menu-search-clear:hover {
    color: var(--rx-v2-accent);
}

body.rxs-ui-v2 .menu-visual-container .search-panel,
body.rxs-ui-v2 .menu-visual-container.dark-mode .search-panel {
    background: var(--rx-v2-panel);
    border: 1px solid var(--rx-v2-border-soft);
    border-radius: var(--rx-v2-r14);
    box-shadow: var(--rx-v2-shadow);
}

body.rxs-ui-v2 .menu-visual-container .search-block + .search-block,
body.rxs-ui-v2 .menu-visual-container.dark-mode .search-block + .search-block {
    border-color: var(--rx-v2-border-soft);
}

body.rxs-ui-v2 .menu-visual-container .search-block-hd,
body.rxs-ui-v2 .menu-visual-container .search-row-main,
body.rxs-ui-v2 .menu-visual-container a.search-row-main:hover,
body.rxs-ui-v2 .menu-visual-container .menu-search-data-btn,
body.rxs-ui-v2 .menu-visual-container.dark-mode .search-block-hd,
body.rxs-ui-v2 .menu-visual-container.dark-mode .search-row-main,
body.rxs-ui-v2 .menu-visual-container.dark-mode a.search-row-main:hover,
body.rxs-ui-v2 .menu-visual-container.dark-mode .menu-search-data-btn {
    color: var(--rx-v2-text);
}

body.rxs-ui-v2 .menu-visual-container .search-row-path,
body.rxs-ui-v2 .menu-visual-container .search-group-hd,
body.rxs-ui-v2 .menu-visual-container .search-loading,
body.rxs-ui-v2 .menu-visual-container .search-empty,
body.rxs-ui-v2 .menu-visual-container .search-block-hd > i {
    color: var(--rx-v2-muted);
}

body.rxs-ui-v2 .menu-visual-container .search-keys,
body.rxs-ui-v2 .menu-visual-container .search-block-ft,
body.rxs-ui-v2 .menu-visual-container .search-row-date,
body.rxs-ui-v2 .menu-visual-container .search-empty-sub,
body.rxs-ui-v2 .menu-visual-container .search-empty i,
body.rxs-ui-v2 .menu-visual-container .search-row-go,
body.rxs-ui-v2 .menu-visual-container .search-row-fav {
    color: var(--rx-v2-faint);
}

body.rxs-ui-v2 .menu-visual-container .search-count,
body.rxs-ui-v2 .menu-visual-container.dark-mode .search-count {
    background: var(--rx-v2-accent-soft);
    color: var(--rx-v2-accent);
}

body.rxs-ui-v2 .menu-visual-container .search-keys kbd,
body.rxs-ui-v2 .menu-visual-container .search-row-media,
body.rxs-ui-v2 .menu-visual-container .menu-search-data-btn,
body.rxs-ui-v2 .menu-visual-container.dark-mode .search-keys kbd,
body.rxs-ui-v2 .menu-visual-container.dark-mode .search-row-media,
body.rxs-ui-v2 .menu-visual-container.dark-mode .menu-search-data-btn {
    background: var(--rx-v2-ghost);
    border-color: var(--rx-v2-border);
    color: var(--rx-v2-muted);
}

/* El icono de toda fila (reciente, favorito, modulo, categoria) lleva el matiz de su
   categoria de primer nivel (`--ch`), no un arcoiris por indice ni el acento plano:
   el color identifica el sistema y se repite en los tres bloques. Sin `--ch` cae en
   el acento del tenant, que es lo que hace toda fila que no sea del menu. */
body.rxs-ui-v2 .menu-visual-container .search-row-icon {
    background: hsl(var(--ch, 230) var(--rx-tint-s) var(--rx-tint-l) / var(--rx-tint-a));
    color: hsl(var(--ch, 230) var(--rx-tint-ink-s) var(--rx-tint-ink-l));
}

/* La miniatura de un dato no lleva matiz (no es de ninguna categoria) y su regla de
   arriba tiene la misma especificidad que la del chip: se repite aca, al final. */
body.rxs-ui-v2 .menu-visual-container .search-row-icon.search-row-media,
body.rxs-ui-v2 .menu-visual-container.dark-mode .search-row-icon.search-row-media {
    background: var(--rx-v2-ghost);
    color: var(--rx-v2-muted);
}

/* Las pestanias y tarjetas con `--ch` (adm.css) ya leen los --rx-tint-* del body con
   fallback: en oscuro los toman de body.thr-dark, asi que aca no hay regla oscura. */

body.rxs-ui-v2 .menu-visual-container.dark-mode .home-cat {
    background: var(--rx-v2-ghost);
}

body.rxs-ui-v2 .menu-visual-container .search-row:hover,
body.rxs-ui-v2 .menu-visual-container .search-row.is-active,
body.rxs-ui-v2 .menu-visual-container.dark-mode .search-row:hover,
body.rxs-ui-v2 .menu-visual-container.dark-mode .search-row.is-active {
    background: var(--rx-v2-ghost);
}

body.rxs-ui-v2 .menu-visual-container .search-row.is-active {
    box-shadow: inset 0 0 0 2px var(--rx-v2-accent);
}

body.rxs-ui-v2 .menu-visual-container .search-row:hover .search-row-go,
body.rxs-ui-v2 .menu-visual-container .search-row.is-active .search-row-go,
body.rxs-ui-v2 .menu-visual-container .search-block-link,
body.rxs-ui-v2 .menu-visual-container .search-group-more,
body.rxs-ui-v2 .menu-visual-container .menu-search-data-btn:hover,
body.rxs-ui-v2 .menu-visual-container .search-row-data .search-row-fav:hover {
    color: var(--rx-v2-accent);
}

body.rxs-ui-v2 .menu-visual-container .menu-search-data-btn:hover {
    border-color: var(--rx-v2-accent);
}

body.rxs-ui-v2 .menu-visual-container .search-group-hd::after,
body.rxs-ui-v2 .menu-visual-container.dark-mode .search-group-hd::after {
    background: var(--rx-v2-border-soft);
}

body.rxs-ui-v2.rxs-ui-vivid.thr-dark .menu-visual-container {
    background:
        radial-gradient(circle at 12% 8%, rgba(255, 255, 255, .08), transparent 30%),
        radial-gradient(circle at 88% 92%, rgba(255, 255, 255, .05), transparent 32%),
        linear-gradient(135deg,
            color-mix(in srgb, var(--rx-v2-vivid-a) 34%, #0d1014) 0%,
            color-mix(in srgb, var(--rx-v2-vivid-b) 46%, #0d1014) 52%,
            color-mix(in srgb, var(--rx-v2-vivid-a) 34%, #0d1014) 100%);
}

@media (max-width: 767.98px) {
    body.rxs-ui-v2 .right-sidebar,
    body.rxs-ui-v2 .right-sidebar.shw-rside {
        max-width: calc(100vw - 10px);
        width: 320px;
    }
    body.rxs-ui-v2 .right-sidebar {
        right: -320px;
    }
    body.rxs-ui-v2 .right-sidebar.shw-rside {
        right: 0;
    }
    body.rxs-ui-v2:not(.rxs-ui-vivid) .menu-visual-container {
        border-radius: var(--rx-v2-r12);
        min-height: calc(100vh - 145px);
    }
}

/* Cards genericas de la grilla v2 (switch de vista, doc ui-v2-maps-list-reuse §12).
 * Se pintan client-side desde el mismo dict que la tabla, por eso no reusan el
 * markup de .rcol de las cards vue: aca cada linea es label + valor. */
body.rxs-ui-v2 .rxsV2Cards {
    /* current49 le da width:98% + margin:0 auto a .listStvVue; al pisar el margin con
     * el -6px de la grilla se perdia el auto-centrado y el 2% sobrante quedaba todo a
     * la derecha. width:auto = ocupa el ancho completo y los -6px quedan simetricos. */
    width: auto;
    margin: 0 -6px;
}

body.rxs-ui-v2 .rxsV2Cards > .rxsTableGood {
    padding: 6px;
}

/* 5 por fila: bootstrap no tiene quintos (12/5 = 2.4), asi que para ese valor del selector
 * el ancho lo fija el flex-basis y hay que pisar el flex/max-width de la col-* que igual
 * viene en el markup. Los breakpoints chicos siguen como en el resto (1 / 2 / 3). */
@media (min-width: 992px) {
    body.rxs-ui-v2 .rxsV2Cards.rxs-v2-cols-5 > .rxsTableGood {
        flex: 0 0 20%;
        max-width: 20%;
    }
}

body.rxs-ui-v2 .rxs-v2-card {
    background: var(--rx-v2-panel);
    border: 1px solid var(--rx-v2-border-soft);
    border-radius: var(--rx-v2-r12);
    box-shadow: var(--rx-v2-shadow);
    padding: 12px 14px;
    color: var(--rx-v2-text);
    font-size: 13px;
    /* propio, no heredado de .listStvVue .rcol: la card se sostiene sola */
    display: flex;
    flex-direction: column;
}

body.rxs-ui-v2 .rxs-v2-card-line {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    align-items: baseline;
    justify-content: space-between;
    padding: 4px 0;
    border-bottom: 1px solid var(--rx-v2-border-soft);
}

body.rxs-ui-v2 .rxs-v2-card-line:last-of-type {
    border-bottom: 0;
}

body.rxs-ui-v2 .rxs-v2-card-lbl {
    color: var(--rx-v2-muted);
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: .03em;
    flex: 0 0 auto;
    max-width: 55%;
    word-break: normal;
    overflow-wrap: normal;
    hyphens: none;
    white-space:nowrap;
    overflow:hidden;
    text-overflow:ellipsis;
}

body.rxs-ui-v2 .rxs-v2-card-val {
    flex: 1 1 auto;
    text-align: right;
    min-width: 0;
    overflow-wrap: anywhere;
}

/* checkbox de la card: label.rxsCheck viene con `margin: 0 auto` de la celda de tabla
 * (ahi si va centrado). En la card el valor va a la derecha como todo el resto, y el
 * text-align del contenedor no lo alcanza porque el label es display:block. */
body.rxs-ui-v2 .rxs-v2-card-val > label.rxsCheck {
    margin-left: auto !important;
    margin-right: 0 !important;
}

body.rxs-ui-v2 .rxs-v2-card-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    justify-content: flex-end;
    margin-top: auto;
    padding-top: 10px;
    border-top: 1px solid var(--rx-v2-border-soft);
}

/* Botones con clase PROPIA en la columna de acciones (.rxsBtnsOwn, la celda del catalogo de
 * /help: rxsCatalogRowBtns). El skin fantasma de 28px no los alcanza (`:not(:where(...))` en sus
 * reglas, sin sumar especificidad), pero current49.css le saca borde y radio a todo
 * `.rxsBtns .btn`: se los devuelve aca. La linea de estado va arriba, los botones abajo. */
body.rxs-ui-v2 .rxsBtnsOwn {
    display: block;
    width: 100%;
    text-align: right;
    white-space: normal;
}

body.rxs-ui-v2 .rxsBtns.rxsBtnsHasOwn {
    border-radius: 0;
    flex: 1 1 100%;
    overflow: visible;
}

body.rxs-ui-v2 .rxsBtnsOwnBar {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    justify-content: flex-end;
}

body.rxs-ui-v2 .rxsBtnsOwn .btn {
    border: 1px solid transparent;
    border-radius: var(--rx-v2-r7);
    margin: 0;
    white-space: nowrap;
}

body.rxs-ui-v2 .rxsBtnsOwn .btn[class*="btn-outline-"] {
    border-color: currentColor;
}

/* el aviso de requisito es un parrafo, no una pill (table.rxs-table .badge le da radio 999) */
body.rxs-ui-v2 .rxsBtnsOwn .badge,
body.rxs-ui-v2 .rxs-module table.rxs-table .rxsBtnsOwn .badge {
    border-radius: var(--rx-v2-r7);
    line-height: 1.35;
}

/* mismo vacio que la grilla (td.dataTables_empty): el de cards era un texto pelado */
body.rxs-ui-v2 .rxs-v2-card-empty {
    color: var(--rx-v2-muted);
    font-size: 14px;
    font-weight: 500;
    padding: 72px 16px;
    text-align: center;
}

body.rxs-ui-v2 .rxs-v2-card-empty::before {
    background: linear-gradient(135deg, var(--rx-v2-accent-soft), var(--rx-v2-accent-2-soft));
    border-radius: var(--rx-v2-r18);
    color: var(--rx-v2-accent);
    content: "\f002";
    display: block;
    font-family: "Font Awesome 5 Free";
    font-size: 22px;
    font-weight: 900;
    height: 60px;
    line-height: 60px;
    margin: 0 auto 16px;
    width: 60px;
}

/* Switcher de vistas de la grilla v2: tabla / cards / galería / mapa + columnas por fila. */
body.rxs-ui-v2 .rxsV2Views {
    display: inline-flex;
    align-items: center;
    gap: 2px;
    padding: 2px;
    border: 1px solid var(--rx-v2-border-soft);
    border-radius: var(--rx-v2-r10);
    background: var(--rx-v2-panel-2);
}

body.rxs-ui-v2 .rxsV2ViewBtn, body.rxs-ui-v2 .rxsFcBtn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    height: 28px;
    border-radius: var(--rx-v2-r8);
    cursor: pointer;
    color: var(--rx-v2-muted);
    background: transparent;
    font-size: 13px;
    transition: background .15s, color .15s;
}

body.rxs-ui-v2 .rxsV2ViewBtn:hover, body.rxs-ui-v2 .rxsFcBtn:hover {
    background: var(--rx-v2-hover);
    color: var(--rx-v2-text);
}

body.rxs-ui-v2 .rxsV2ViewBtn.active, body.rxs-ui-v2 .rxsFcBtn.active {
    background: var(--rx-v2-accent);
    color: var(--rx-v2-accent-ink);
}

/* Guardar la vista en la URL: misma caja que los botones de vista, pero separado con una
   línea — no es "otra vista", es una acción sobre la que está puesta. */
body.rxs-ui-v2 .rxsViewSave,
body.rxs-ui-v2 .rxsMergeFindBtn {
    align-items: center;
    background: transparent;
    border-left: 1px solid var(--rx-v2-border-soft);
    border-radius: var(--rx-v2-r8);
    color: var(--rx-v2-muted);
    cursor: pointer;
    display: inline-flex;
    font-size: 13px;
    height: 28px;
    justify-content: center;
    margin-left: 4px;
    padding-left: 4px;
    transition: background .15s, color .15s;
    width: 32px;
}

body.rxs-ui-v2 .rxsViewSave:hover,
body.rxs-ui-v2 .rxsMergeFindBtn:hover {
    background: var(--rx-v2-hover);
    color: var(--rx-v2-text);
}

/* Buscar duplicados va pegado a guardar la vista: las dos son acciones, no vistas. */
body.rxs-ui-v2 .rxsViewSave + .rxsMergeFindBtn {
    border-left: 0;
    margin-left: 0;
    padding-left: 0;
}

body.rxs-ui-v2 .rxsV2ColsSel {
    height: 28px;
    margin-left: 2px;
    padding: 0 4px;
    border: 0;
    border-radius: var(--rx-v2-r8);
    background: var(--rx-v2-field);
    color: var(--rx-v2-text);
    font-size: 12px;
}

/* Galería: la imagen manda. */
body.rxs-ui-v2 .rxs-v2-card.rxs-v2-gal {
    padding: 0;
    overflow: hidden;
    display: flex;
    flex-direction: column;
}

body.rxs-ui-v2 .rxs-v2-gal-media {
    position: relative;
    aspect-ratio: 4 / 3;
    background: var(--rx-v2-panel-2);
    overflow: hidden;
}

body.rxs-ui-v2 .rxs-v2-gal-media img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    transition: transform .35s ease;
}

body.rxs-ui-v2 .rxs-v2-card.rxs-v2-gal:hover .rxs-v2-gal-media img {
    transform: scale(1.04);
}

/* la imagen es el acceso a la ficha cuando la tabla la tiene (botón "Más") */
body.rxs-ui-v2 .rxs-v2-gal-link {
    display: block;
    width: 100%;
    height: 100%;
    cursor: pointer;
}

body.rxs-ui-v2 .rxs-v2-gal-media.is-empty .rxs-v2-gal-link {
    display: flex;
    align-items: center;
    justify-content: center;
    color: inherit;
}

body.rxs-ui-v2 .rxs-v2-gal-media.is-empty {
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--rx-v2-faint);
    font-size: 34px;
    background: linear-gradient(135deg, var(--rx-v2-panel-2), var(--rx-v2-hover));
}

/* Un video en la galería y en la thumb de las cards: su miniatura (o un cuadro del propio
 * video si todavía no tiene) con el botón de reproducir encima. El clic lo abre en el
 * reproductor del navegador. */
body.rxs-ui-v2 .rxs-v2-gal-media video {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    pointer-events: none;
    background: var(--rx-v2-panel-2);
}
body.rxs-ui-v2 .rxs-v2-gal-play,
body.rxs-ui-v2 .rxs-v2-card-play {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
    color: var(--rx-v2-faint);
}
body.rxs-ui-v2 .rxs-v2-gal-play > .fa-film {
    font-size: 34px;
}
body.rxs-ui-v2 .rxs-v2-play {
    position: absolute;
    left: 50%;
    top: 50%;
    width: 52px;
    height: 52px;
    margin: -26px 0 0 -26px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    background: color-mix(in srgb, #000 55%, transparent);
    color: #fff;
    font-size: 18px;
    box-shadow: 0 2px 12px color-mix(in srgb, #000 35%, transparent);
    transition: transform .18s ease, background .18s ease;
    pointer-events: none;
}
body.rxs-ui-v2 .rxs-v2-play .fa-play {
    margin-left: 3px; /* el triángulo se ve corrido sin esto */
}
body.rxs-ui-v2 .rxs-v2-card.rxs-v2-gal:hover .rxs-v2-play,
body.rxs-ui-v2 .rxs-v2-gal-play:focus-visible .rxs-v2-play {
    transform: scale(1.08);
    background: var(--rx-v2-accent);
}
body.rxs-ui-v2 .rxs-v2-card-thumb .rxs-v2-play {
    width: 22px;
    height: 22px;
    margin: -11px 0 0 -11px;
    font-size: 9px;
}
body.rxs-ui-v2 .rxs-v2-card-thumb .rxs-v2-play .fa-play {
    margin-left: 1px;
}
/* La duración de un video o un audio (web 42) en la esquina del tile, como en cualquier reproductor. */
body.rxs-ui-v2 .rxs-v2-gal-dur {
    position: absolute;
    right: 6px;
    bottom: 6px;
    padding: 1px 6px;
    border-radius: 4px;
    background: color-mix(in srgb, #000 70%, transparent);
    color: #fff;
    font-size: 11px;
    font-weight: 600;
    line-height: 16px;
    font-variant-numeric: tabular-nums;
    pointer-events: none;
}
body.rxs-ui-v2 .rxs-file-video .fa {
    margin-right: 2px;
}

/* Galería en modo PICKER (#rxsResPickModal): ahi el tile no lleva a la ficha, se
 * ELIGE. Las zonas que intercepta rxsResPickBind (media + titulo) se marcan al hover
 * con velo + etiqueta, para que se entienda que el clic selecciona el recurso. */
body.rxs-ui-v2 #rxsResPickModal .rxs-v2-gal-media,
body.rxs-ui-v2 #rxsResPickModal .rxs-v2-gal-title {
    cursor: pointer;
}
body.rxs-ui-v2 #rxsResPickModal .rxs-v2-gal-media::after {
    content: "\f00c  Seleccionar";
    font-family: "Font Awesome 5 Free", "Font Awesome 5 Pro", FontAwesome, sans-serif;
    font-weight: 900;
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    background: color-mix(in srgb, var(--rx-v2-accent) 62%, transparent);
    color: var(--rx-v2-accent-ink, #fff);
    font-size: 14px;
    letter-spacing: .02em;
    opacity: 0;
    transition: opacity .18s ease;
    pointer-events: none;
}
body.rxs-ui-v2 #rxsResPickModal .rxs-v2-card.rxs-v2-gal:hover .rxs-v2-gal-media::after {
    opacity: 1;
}
body.rxs-ui-v2 #rxsResPickModal .rxs-v2-card.rxs-v2-gal:hover {
    border-color: var(--rx-v2-accent);
    box-shadow: 0 0 0 2px color-mix(in srgb, var(--rx-v2-accent) 45%, transparent);
}
body.rxs-ui-v2 #rxsResPickModal .rxs-v2-card.rxs-v2-gal:hover .rxs-v2-gal-title {
    color: var(--rx-v2-accent);
}

body.rxs-ui-v2 .rxs-v2-gal-body {
    text-align: left;
    display: flex;
    flex-direction: column;
    gap: 6px;
    padding: 12px 14px 14px;
    flex: 1 1 auto;
}

body.rxs-ui-v2 .rxs-v2-gal-title {
    font-weight: 600;
    font-size: 14px;
    line-height: 1.25;
    color: var(--rx-v2-text);
}

body.rxs-ui-v2 .rxs-v2-gal-desc {
    font-size: 12px;
    line-height: 1.4;
    color: var(--rx-v2-muted);
    display: -webkit-box;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

body.rxs-ui-v2 .rxs-v2-gal-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-top: 2px;
}

body.rxs-ui-v2 .rxs-v2-gal-chip {
    font-size: 11px;
    padding: 2px 8px;
    border-radius: 999px;
    background: var(--rx-v2-ghost);
    color: var(--rx-v2-muted);
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

body.rxs-ui-v2 .rxs-v2-gal .rxs-v2-card-actions {
    margin-top: auto;
}

/* ---- Campos largos: recorte con "Ver más" (grilla v2 + cards) ----
   Una celda con HTML rico (textarea/CKEditor) hacia una fila del alto de la pantalla.
   En el <td> el recorte va sobre un wrapper (.rxs-clamp) porque un td ignora max-height;
   en la card va sobre el propio valor. El toggle lo agrega ui_v2.js. */
body.rxs-ui-v2 {
    --rx-v2-clamp: 132px;
}

body.rxs-ui-v2 .rxs-module table.rxs-table tbody td .rxs-clamp,
body.rxs-ui-v2 .rxs-v2-card-val {
    max-height: var(--rx-v2-clamp);
    overflow: hidden;
}

body.rxs-ui-v2 .rxs-module table.rxs-table tbody td[data-rxs-clamp="1"] .rxs-clamp,
body.rxs-ui-v2 .rxs-v2-card-val[data-rxs-clamp="1"] {
    -webkit-mask-image: linear-gradient(180deg, #000 65%, transparent 100%);
    mask-image: linear-gradient(180deg, #000 65%, transparent 100%);
}

body.rxs-ui-v2 .rxs-module table.rxs-table tbody td.is-open .rxs-clamp,
body.rxs-ui-v2 .rxs-v2-card-line.is-open .rxs-v2-card-val {
    max-height: none;
    -webkit-mask-image: none;
    mask-image: none;
}

/* El mismo recorte, declarado a mano desde cualquier html (templates Vue, fichas): basta
   con data-rxs-clamp="1" en el contenedor, un .rxs-clamp adentro y el .rxs-clamp-more al
   lado. El toggle no cambia: el handler de ui_v2.js alterna is-open en el padre y ya es
   generico. Se declara en vez de medirse porque afuera de la grilla el que escribe el
   template sabe de antemano cual es el campo largo. */
body.rxs-ui-v2 [data-rxs-clamp="1"] > .rxs-clamp {
    -webkit-mask-image: linear-gradient(180deg, #000 65%, transparent 100%);
    mask-image: linear-gradient(180deg, #000 65%, transparent 100%);
    max-height: var(--rx-v2-clamp);
    overflow: hidden;
}

/* el declarado por una plantilla de card (data-rxs-clamp="auto"): recorta antes de medir, y
   ui_v2.js lo pasa a "1" con su toggle si desborda o a "0" si entra */
body.rxs-ui-v2 [data-rxs-clamp="auto"] > .rxs-clamp {
    max-height: var(--rx-v2-clamp);
    overflow: hidden;
}

body.rxs-ui-v2 [data-rxs-clamp="1"].is-open > .rxs-clamp {
    -webkit-mask-image: none;
    mask-image: none;
    max-height: none;
}

body.rxs-ui-v2 .rxs-clamp-more {
    background: none;
    border: 0;
    padding: 0;
    margin-top: 2px;
    color: var(--rx-v2-accent);
    font-size: 11px;
    font-weight: 600;
    cursor: pointer;
    display: block;
}

body.rxs-ui-v2 .rxs-clamp-more:hover {
    text-decoration: underline;
}

/* en la card la línea es flex: el toggle baja a su propio renglón, alineado con el valor */
body.rxs-ui-v2 .rxs-v2-card-line .rxs-clamp-more {
    flex: 1 0 100%;
    margin-top: 0;
    text-align: right;
}

/* El HTML del campo trae sus propios font-size/imágenes: dentro de una celda o de una card
   manda la tipografía de la lista, no la del editor de contenido. */
body.rxs-ui-v2 .rxs-module table.rxs-table tbody td [style*="font-size"],
body.rxs-ui-v2 .rxs-v2-card-val [style*="font-size"] {
    font-size: inherit !important;
}

body.rxs-ui-v2 .rxs-module table.rxs-table tbody td img,
body.rxs-ui-v2 .rxs-v2-card-val img {
    max-width: 100%;
    height: auto;
}

body.rxs-ui-v2 .rxs-v2-card-val p:last-child,
body.rxs-ui-v2 .rxs-module table.rxs-table tbody td p:last-child {
    margin-bottom: 0;
}

/* ---- Edición inline en cards/galería (rxsEdGo, mismo editor que el doble click de la grilla) ----
   El campo editable no se anuncia hasta que el mouse pasa: ahí se ilumina como un campo de form
   (mismo lenguaje que el resto de v2) en vez de subrayarse. La pill se pinta sola. */
body.rxs-ui-v2 .rxs-v2-card .rxsEdGo:not(.rxs-pill) {
    padding: 1px 5px;
    margin: -1px -5px;
}

/* en la galería los chips ya son pills con padding propio: el margen negativo del editor
   se comía el gap del flex y los dejaba pegados/superpuestos */
body.rxs-ui-v2 .rxs-v2-card .rxs-v2-gal-chip.rxsEdGo:not(.rxs-pill) {
    margin: 0;
    padding: 2px 8px;
}

/* si el valor ES una pill, la pill ya se ilumina sola: el recuadro del editor sobra */
body.rxs-ui-v2 .rxs-v2-card .rxsEdGo.rxs-v2-edpill:hover {
    background: none;
    box-shadow: none;
}

/* ...y por lo mismo tampoco necesita el padding, que ademas le cortaba el lado derecho.
 * El valor de la card es un item flex con `overflow:hidden` (el recorte de campos largos)
 * y su ancho lo resuelve el navegador contra el ancho del CONTENIDO, sin sumarle este
 * padding: la pill —que es `nowrap` y no se puede encoger— arrancaba 5 px adentro y se
 * quedaba con los ultimos 5 px afuera de la caja, o sea con la curva derecha cortada. Se
 * veia en toda pill que quedara sola en su renglon (cards, galeria, tablero y el globo del
 * mapa). La alineacion no se mueve: el padding venia con un margen negativo que lo anulaba.
 * Emparentado con el `max-width:none` de la pill mas abajo, que arreglo el otro sintoma del
 * mismo padding (el "..." aunque sobrara lugar). */
body.rxs-ui-v2 .rxs-v2-card .rxsEdGo.rxs-v2-edpill:not(.rxs-pill) {
    padding: 0;
    margin: 0;
}

/* la pill ya tiene su propio hover (y su click filtra): no le sumamos el del editor */
body.rxs-ui-v2 .rxs-v2-card .rxsEdGo.rxs-pill:hover {
    box-shadow: 0 0 0 1.5px hsl(var(--rxp) var(--rx-tint-s) var(--rx-tint-l) / .55);
    cursor: pointer;
}

body.rxs-ui-v2 .rxs-v2-card .rxsEdGo .form-control {
    height: 28px;
    padding: 2px 8px;
    font-size: 12px;
    text-align: left;
    background: var(--rx-v2-field);
    color: var(--rx-v2-text);
    border: 1px solid var(--rx-v2-border);
    border-radius: var(--rx-v2-r8);
}

body.rxs-ui-v2 .rxs-v2-card .rxsEdGo .select2-container {
    min-width: 140px;
    text-align: left;
}

/* ==== v2 pass 29: piel del mapa ==========================================
 * El mapa era lo unico de v2 que seguia siendo una caja de Google: tiles
 * claros adentro de un panel oscuro, controles con el chrome de Google y un
 * pin verde fijo. Aca no hay una paleta de mapa elegida a mano: los tiles,
 * los controles, el globo de info y el pin salen de los MISMOS tokens que
 * pinta el resto de v2, asi que el mapa acompana al tema, a los colores del
 * sitio y a ui_accent sin una linea por tenant. El estilo de los tiles y la
 * barra los arma ui_v2.js (rxsV2MapOptions / rxsV2MapSkin), que solo se
 * carga en v2: sin v2 esto no existe y el mapa sale como salia.
 * Los selectores gm-* son de Google y traen estilo inline, de ahi el
 * !important. Doc: docs/frontend/ui-v2-maps-list-reuse-bitacora.md §29. */

body.rxs-ui-v2 .rxsV2MapWrap {
    position: relative;
}

/* Mapa co-residente con la lista. Alto elastico: 520 fijos dejaban el mapa
   cortado por el borde de la ventana en pantallas normales. */
body.rxs-ui-v2 .rxsV2MapCanvas {
    width: 100%;
    height: clamp(360px, calc(100vh - 400px), 760px);
    border-radius: var(--rx-v2-r12);
    overflow: hidden;
    border: 1px solid var(--rx-v2-border-soft);
    background: var(--rx-v2-panel);
}

@media (max-width: 767.98px) {
    body.rxs-ui-v2 .rxsV2MapCanvas {
        height: 340px;
    }
}

/* el mapa del tab de mapas comparte el marco del de la lista */
body.rxs-ui-v2 #map_wrapper > .rxs-v2-map {
    border-radius: var(--rx-v2-r12);
    overflow: hidden;
    border: 1px solid var(--rx-v2-border-soft);
}

/* pantalla completa: el marco del panel sobra */
body.rxs-ui-v2 .rxs-v2-map:fullscreen {
    height: 100% !important;
    border: 0;
    border-radius: 0;
}

/* --- barra de controles (reemplaza a la de Google, apagada en rxsV2MapOptions) --- */
body.rxs-ui-v2 .rxs-v2-mapbar {
    display: flex;
    flex-direction: column;
    margin: 12px;
    border-radius: var(--rx-v2-r10);
    overflow: hidden;
    background: color-mix(in srgb, var(--rx-v2-panel-2) 90%, transparent);
    -webkit-backdrop-filter: blur(8px);
    backdrop-filter: blur(8px);
    border: 1px solid var(--rx-v2-border);
    box-shadow: 0 6px 20px rgba(0, 0, 0, .28);
}

/* el zoom vive en la misma barra, separado del resto por un hueco */
body.rxs-ui-v2 .rxs-v2-mapsep {
    height: 6px;
    background: var(--rx-v2-ghost);
    border-top: 1px solid var(--rx-v2-border-soft);
    border-bottom: 1px solid var(--rx-v2-border-soft);
}

body.rxs-ui-v2 .rxs-v2-mapsep + .rxs-v2-mapbtn {
    border-top: 0;
}

body.rxs-ui-v2 .rxs-v2-mapbtn {
    width: 34px;
    height: 34px;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    border: 0;
    background: transparent;
    color: var(--rx-v2-muted);
    font-size: 13px;
    line-height: 1;
    cursor: pointer;
    transition: background .15s ease, color .15s ease;
}

body.rxs-ui-v2 .rxs-v2-mapbtn + .rxs-v2-mapbtn {
    border-top: 1px solid var(--rx-v2-border-soft);
}

body.rxs-ui-v2 .rxs-v2-mapbtn:hover {
    background: var(--rx-v2-hover);
    color: var(--rx-v2-text);
}

body.rxs-ui-v2 .rxs-v2-mapbtn:focus-visible {
    outline: 2px solid var(--rx-v2-accent);
    outline-offset: -2px;
}

body.rxs-ui-v2 .rxs-v2-mapbtn.is-on {
    background: var(--rx-v2-accent-soft);
    color: var(--rx-v2-accent);
}

body.rxs-ui-v2 .rxs-v2-mapbtn i {
    pointer-events: none;
}

/* --- globo de info: un panel v2, no la tarjeta blanca de Google --- */
body.rxs-ui-v2 .rxs-v2-map .gm-style-iw-c {
    padding: 0 !important;
    background: var(--rx-v2-panel) !important;
    color: var(--rx-v2-text);
    border: 1px solid var(--rx-v2-border);
    border-radius: var(--rx-v2-r14) !important;
    box-shadow: var(--rx-v2-shadow) !important;
}

body.rxs-ui-v2 .rxs-v2-map .gm-style-iw-d {
    padding: 0 14px 14px;
    background: transparent !important;
    overflow: auto !important;
    color: var(--rx-v2-text);
}

/* la colita que apunta al pin */
body.rxs-ui-v2 .rxs-v2-map .gm-style-iw-tc::after {
    background: var(--rx-v2-panel) !important;
}

body.rxs-ui-v2 .rxs-v2-map .gm-style-iw-chr {
    height: 34px;
    min-height: 34px;
}

/* el boton de cerrar es un <span> con mask-image: se tine por background-color */
body.rxs-ui-v2 .rxs-v2-map .gm-ui-hover-effect {
    width: 34px !important;
    height: 34px !important;
    opacity: 1 !important;
}

body.rxs-ui-v2 .rxs-v2-map .gm-ui-hover-effect > span {
    width: 15px !important;
    height: 15px !important;
    margin: 10px !important;
    background-color: var(--rx-v2-faint) !important;
}

body.rxs-ui-v2 .rxs-v2-map .gm-ui-hover-effect:hover > span {
    background-color: var(--rx-v2-text) !important;
}

/* --- la card adentro del globo ---
   El globo NO arma html propio: g.js lo dibuja con rxsV2CardBody(), la misma funcion
   que la vista cards. Aca solo se le saca el marco (el globo ya es el panel) y se le
   pone un ancho y un tope de alto de globo. Doc §30. */
body.rxs-ui-v2 .rxs-v2-map .rxs-v2-mapcard {
    background: none;
    border: 0;
    border-radius: 0;
    box-shadow: none;
    padding: 0;
    width: 320px;
    max-width: 100%;
    display: flex;
    flex-direction: column;
}

/* el tope de alto se lo pasa g.js desde el que calculo Google: scrollea la lista de
   campos, no la card, asi la cabecera y las acciones no se van de pantalla */
body.rxs-ui-v2 .rxs-v2-map .rxs-v2-mapcard .rxs-v2-card-lines {
    overflow-y: auto;
    min-height: 0;
    margin-right: -6px;
    padding-right: 6px;
}

/* la cabecera de la card ya dice el nombre: el titulo del globo no se repite */
body.rxs-ui-v2 .rxs-v2-map .rxs-v2-mapcard .rxs-v2-card-title {
    font-size: 14px;
}

body.rxs-ui-v2 .rxs-v2-map .rxs-v2-mapcard .rxs-v2-card-lines {
    font-size: 12px;
}

/* "Como llegar": lo unico que suma el mapa sobre la card */
body.rxs-ui-v2 .rxs-v2-map .rxs-v2-mapcard-go {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 7px;
    margin-top: 10px;
    padding: 8px 12px;
    border-radius: var(--rx-v2-r9);
    border: 1px solid var(--rx-v2-border);
    background: var(--rx-v2-panel-2);
    color: var(--rx-v2-text) !important;
    font: 600 12px/1.2 var(--rx-v2-font);
}

body.rxs-ui-v2 .rxs-v2-map .rxs-v2-mapcard-go:hover {
    background: var(--rx-v2-hover);
    border-color: var(--rx-v2-accent);
}

/* las acciones de la fila vienen del dict, con los permisos ya resueltos: en el globo
   se apilan a lo ancho en vez de quedar como una tira de iconos */
body.rxs-ui-v2 .rxs-v2-map .rxs-v2-mapcard .rxs-v2-card-actions {
    margin-top: 10px;
    flex-wrap: wrap;
    justify-content: flex-start;
}

body.rxs-ui-v2 .rxs-v2-map .info_content {
    min-width: 180px;
    max-width: 260px;
    font-family: var(--rx-v2-font);
}

body.rxs-ui-v2 .rxs-v2-map .info_content h3 {
    margin: 0 0 10px;
    font-size: 14px;
    font-weight: 650;
    line-height: 1.3;
    color: var(--rx-v2-text);
}

body.rxs-ui-v2 .rxs-v2-map .gm-style-iw a {
    text-decoration: none;
}

/* los botones del globo LEGACY (el html propio de gomaps y los stvMapPopup de tenant,
   que es lo que se usa cuando no hay dict semantico) vienen con los colores de
   bootstrap (success/warning/info): en v2 son todos el mismo boton, y el primario es
   el acento del sitio. El globo v2 no pasa por aca: son las acciones de la fila. */
body.rxs-ui-v2 .rxs-v2-map .gm-style-iw .info_content .btn {
    display: block;
    width: 100%;
    margin: 0 0 6px;
    padding: 8px 12px;
    border: 1px solid var(--rx-v2-border);
    border-radius: var(--rx-v2-r9);
    background: var(--rx-v2-panel-2);
    color: var(--rx-v2-text);
    font: 600 12px/1.2 var(--rx-v2-font);
    box-shadow: none;
    text-shadow: none;
}

body.rxs-ui-v2 .rxs-v2-map .gm-style-iw .info_content .btn:hover {
    background: var(--rx-v2-hover);
    color: var(--rx-v2-text);
}

body.rxs-ui-v2 .rxs-v2-map .gm-style-iw .info_content .btn-success {
    background: var(--rx-v2-accent);
    border-color: transparent;
    color: var(--rx-v2-accent-ink);
}

body.rxs-ui-v2 .rxs-v2-map .gm-style-iw .info_content .btn-success:hover {
    background: var(--rx-v2-accent);
    color: var(--rx-v2-accent-ink);
    filter: brightness(1.07);
}

/* --- "Ver todos (N)": el pie del mapa, en el lenguaje de v2 ---
   Va montado sobre el borde de abajo del mapa, no debajo: el mapa termina justo
   en el borde de la ventana y una fila mas abajo obliga a scrollear para algo
   que es del mapa. Margen negativo y no position:absolute porque el nodo se
   comparte con el tab de mapas, donde el hermano relativo no es el mismo. */
body.rxs-ui-v2 .rxsV2MapAll:not(.d-none) {
    position: relative;
    z-index: 2;
    margin-top: -48px !important;   /* .mt-2 de bootstrap viene con !important */
    pointer-events: none;
}

body.rxs-ui-v2 .rxsV2MapAll .rxsV2MapAllBtn {
    pointer-events: auto;
}

body.rxs-ui-v2 .rxsV2MapAll .rxsV2MapAllBtn {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 6px 14px;
    border-radius: 999px;
    border: 1px solid var(--rx-v2-border);
    background: var(--rx-v2-panel);
    color: var(--rx-v2-muted);
    font: 600 12px/1 var(--rx-v2-font);
    box-shadow: none;
}

body.rxs-ui-v2 .rxsV2MapAll .rxsV2MapAllBtn {
    background: color-mix(in srgb, var(--rx-v2-panel-2) 92%, transparent);
    -webkit-backdrop-filter: blur(8px);
    backdrop-filter: blur(8px);
    box-shadow: 0 6px 20px rgba(0, 0, 0, .28);
    cursor: pointer;
}

body.rxs-ui-v2 .rxsV2MapAll .rxsV2MapAllBtn:hover {
    background: var(--rx-v2-hover);
    color: var(--rx-v2-text);
    border-color: var(--rx-v2-accent);
}

/* ==== v2 pass 22: mini-params de personalizacion (ui_accent / ui_density)
 * + theme-feel: scrollbars y ::selection tokenizados ==== */

/* --- ui_accent: el acento no es un color suelto sino un PAR de los 3 colores del
 * sitio (body.rxs-ui-accAB): A = --rx-v2-accent, B = el que lo acompana en los
 * degrades de marca (--rx-v2-accent-2 para hairlines/washes, --rx-v2-vivid-a/b para
 * el chrome de Colores vivos: topbar, sidebar, CTA, fondo del /home). Las 6
 * combinaciones son elegibles; "1 y 2" es el default y NO emite clase, asi que no
 * tiene regla aca (conserva su accent-2 historico = color3, sin regresion).
 *
 * Todo lo demas (soft, grad, tintes vivid, shell, boton) sale de estas cuatro
 * variables via var(), asi que rota solo: si agregas algo de marca, colgalo de
 * estas y no de --rx-colorN a mano. --- */
body.rxs-ui-v2.rxs-ui-acc13 {
    --rx-v2-accent: var(--rx-color1, #f28c28);
    --rx-v2-accent-2: var(--rx-color3, #FFFFFF);
    --rx-v2-vivid-a: var(--rx-color1, #f28c28);
    --rx-v2-vivid-b: var(--rx-color3, #FFFFFF);
}

body.rxs-ui-v2.rxs-ui-acc21 {
    --rx-v2-accent: var(--rx-color2, #58627a);
    --rx-v2-accent-2: var(--rx-color1, #f28c28);
    --rx-v2-vivid-a: var(--rx-color2, #58627a);
    --rx-v2-vivid-b: var(--rx-color1, #f28c28);
}

body.rxs-ui-v2.rxs-ui-acc23 {
    --rx-v2-accent: var(--rx-color2, #58627a);
    --rx-v2-accent-2: var(--rx-color3, #FFFFFF);
    --rx-v2-vivid-a: var(--rx-color2, #58627a);
    --rx-v2-vivid-b: var(--rx-color3, #FFFFFF);
}

body.rxs-ui-v2.rxs-ui-acc31 {
    --rx-v2-accent: var(--rx-color3, #FFFFFF);
    --rx-v2-accent-2: var(--rx-color1, #f28c28);
    --rx-v2-vivid-a: var(--rx-color3, #FFFFFF);
    --rx-v2-vivid-b: var(--rx-color1, #f28c28);
}

body.rxs-ui-v2.rxs-ui-acc32 {
    --rx-v2-accent: var(--rx-color3, #FFFFFF);
    --rx-v2-accent-2: var(--rx-color2, #58627a);
    --rx-v2-vivid-a: var(--rx-color3, #FFFFFF);
    --rx-v2-vivid-b: var(--rx-color2, #58627a);
}

/* Con acento elegido, el "ink" (texto sobre acento) se resuelve por luminancia:
 * claro sobre acentos oscuros (color2 suele ser navy) y oscuro sobre acentos
 * claros. Solo en los pares explicitos: el default conserva su ink fijo. */
@supports (color: oklch(from red l c h)) {
    body.rxs-ui-v2.rxs-ui-acc13,
    body.rxs-ui-v2.rxs-ui-acc21,
    body.rxs-ui-v2.rxs-ui-acc23,
    body.rxs-ui-v2.rxs-ui-acc31,
    body.rxs-ui-v2.rxs-ui-acc32 {
        --rx-v2-accent-ink: oklch(from var(--rx-v2-accent) clamp(0.14, 0.14 + (0.68 - l) * 999, 0.98) 0 h);
    }
}

/* --- ui_density=1: modo compacto (body.rxs-ui-compact). Menos aire en tabla,
 * modulo y filtros; para operadores con pantallas cargadas de data. --- */
body.rxs-ui-v2.rxs-ui-compact .rxs-module table.rxs-table tbody > tr > td {
    padding: 5px 10px;
    font-size: 12.5px;
}

body.rxs-ui-v2.rxs-ui-compact .rxs-module table.rxs-table thead th {
    padding: 6px 10px;
}

body.rxs-ui-v2.rxs-ui-compact .rxs-module table.rxs-table .badge,
body.rxs-ui-v2.rxs-ui-compact .rxs-module table.rxs-table .rxs-pill {
    font-size: 10px;
    padding: 2px 7px;
}

body.rxs-ui-v2.rxs-ui-compact .rxs-module .rxsBtns .btn:not(:where(.rxsBtnsOwn .btn)),
body.rxs-ui-v2.rxs-ui-compact .rxs-module table.rxs-table td .btn:not(:where(.rxsBtnsOwn .btn)) {
    height: 24px;
    min-width: 24px;
    width: 24px;
}

body.rxs-ui-v2.rxs-ui-compact .rxs-module-head {
    padding: 8px 12px;
}

body.rxs-ui-v2.rxs-ui-compact .rxs-module-head h2 {
    font-size: 15px;
}

body.rxs-ui-v2.rxs-ui-compact .rxs-filterbar .filterStv input,
body.rxs-ui-v2.rxs-ui-compact .rxs-filterbar .filterStv .select2-selection {
    min-height: 30px;
    height: 30px;
}

body.rxs-ui-v2.rxs-ui-compact .rxs-table-footer {
    padding-top: 6px;
}

/* --- ui_density=comodo (body.rxs-ui-comodo). El otro lado del mismo knob: mas
 * aire para pantallas de pocas filas, donde lo compacto no compra nada y se lee
 * apretado. Es el espejo del bloque de arriba, elemento por elemento, para que
 * los tres niveles se comparen leyendo. --- */
body.rxs-ui-v2.rxs-ui-comodo .rxs-module table.rxs-table tbody > tr > td {
    padding: 13px 16px;
    font-size: 14px;
}

body.rxs-ui-v2.rxs-ui-comodo .rxs-module table.rxs-table thead th {
    padding: 14px 16px;
}

body.rxs-ui-v2.rxs-ui-comodo .rxs-module table.rxs-table .badge,
body.rxs-ui-v2.rxs-ui-comodo .rxs-module table.rxs-table .rxs-pill {
    font-size: 12px;
    padding: 4px 11px;
}

body.rxs-ui-v2.rxs-ui-comodo .rxs-module .rxsBtns .btn:not(:where(.rxsBtnsOwn .btn)),
body.rxs-ui-v2.rxs-ui-comodo .rxs-module table.rxs-table td .btn:not(:where(.rxsBtnsOwn .btn)) {
    height: 34px;
    min-width: 34px;
    width: 34px;
}

body.rxs-ui-v2.rxs-ui-comodo .rxs-module-head {
    padding: 18px 22px;
}

body.rxs-ui-v2.rxs-ui-comodo .rxs-module-head h2 {
    font-size: 19px;
}

body.rxs-ui-v2.rxs-ui-comodo .rxs-filterbar .filterStv input,
body.rxs-ui-v2.rxs-ui-comodo .rxs-filterbar .filterStv .select2-selection {
    min-height: 42px;
    height: 42px;
}

body.rxs-ui-v2.rxs-ui-comodo .rxs-table-footer {
    padding-top: 16px;
}

/* --- ui_sidebar: el sidebar como superficie propia --------------------------
 * El sidebar se pinta con --rx-v2-bg y su texto con --rx-v2-muted/--rx-v2-text,
 * o sea que ya lee TOKENS y no colores escritos. Asi que el knob no reescribe
 * ninguna de esas reglas: redefine los tokens PARA ESE SUBARBOL y las reglas
 * que ya existen los leen solas. Es el mismo recurso que usa la tarjeta del
 * login para quedar clara adentro de un admin en oscuro.
 *
 * `neutro` es lo de hoy y no emite clase. Y esto es otro eje que "Colores
 * vivos": aquel tine el shell ENTERO (topbar incluida) y este toca solo el
 * sidebar, asi que los dos se pueden combinar. */
body.rxs-ui-v2.rxs-ui-sb-marca .left-sidebar {
    /* 10% del acento y no el color pelado: el sidebar tiene texto oscuro encima
     * y una marca saturada a fondo completo lo deja ilegible -- eso ya lo
     * resuelve "Colores vivos", que ademas invierte el texto. Aca la marca se
     * insinua y el sidebar sigue siendo una superficie clara. */
    --rx-v2-bg: color-mix(in srgb, var(--rx-v2-accent) 10%, #f6f7f9);
    --rx-v2-hover: color-mix(in srgb, var(--rx-v2-accent) 18%, #f6f7f9);
    --rx-v2-active: color-mix(in srgb, var(--rx-v2-accent) 26%, #f6f7f9);
    --rx-v2-border-soft: color-mix(in srgb, var(--rx-v2-accent) 22%, transparent);
}

body.rxs-ui-v2.thr-dark.rxs-ui-sb-marca .left-sidebar {
    /* en oscuro el mismo 10% sobre una hoja clara daria un sidebar mas claro que
     * el resto del admin: la mezcla va contra la superficie oscura */
    --rx-v2-bg: color-mix(in srgb, var(--rx-v2-accent) 14%, #0b0e11);
    --rx-v2-hover: color-mix(in srgb, var(--rx-v2-accent) 22%, #0b0e11);
    --rx-v2-active: color-mix(in srgb, var(--rx-v2-accent) 30%, #0b0e11);
}

/* `oscuro`: el sidebar en la superficie oscura con el resto del admin en claro.
 * Son los MISMOS valores del bloque `.thr-dark` de arriba, redefinidos para el
 * subarbol: no hay un segundo juego de colores que mantener, y un cambio en la
 * paleta oscura llega aca solo. En un admin que YA esta en oscuro no hace falta
 * -- el sidebar ya es esto -- y por eso la regla excluye .thr-dark. */
body.rxs-ui-v2.rxs-ui-sb-oscuro:not(.thr-dark) .left-sidebar {
    --rx-v2-bg: color-mix(in srgb, var(--rx-color2, #10192e) 10%, #0d1014);
    --rx-v2-shell: #0b0e11;
    --rx-v2-panel: color-mix(in srgb, var(--rx-color2, #10192e) 7%, #171b20);
    --rx-v2-panel-2: color-mix(in srgb, var(--rx-color2, #10192e) 7%, #1b2026);
    --rx-v2-field: #10141a;
    --rx-v2-hover: #1e242b;
    --rx-v2-active: #232a32;
    --rx-v2-ghost: rgba(255, 255, 255, .06);
    --rx-v2-border: rgba(255, 255, 255, .09);
    --rx-v2-border-soft: rgba(255, 255, 255, .055);
    --rx-v2-text: #e8ecf1;
    --rx-v2-muted: #9aa4b1;
    --rx-v2-faint: #6d7784;
}

/* `claro`: la superficie clara de hoy aun con el admin en oscuro --- el espejo
 * exacto de `oscuro`, con los MISMOS literales del tema claro base. Hasta aca
 * se podia declarar la barra oscura pero no la clara. En un admin ya claro la
 * redefinicion no cambia nada, pero la eleccion emite clase, y eso es lo que
 * la hace ganarle al fondo (el guard del §8.5, mas abajo). Bajo vivid queda
 * inerte como `marca`, y por el mismo motivo: el texto blanco de vivid encima
 * de una hoja clara es ilegible. */
body.rxs-ui-v2.thr-dark.rxs-ui-sb-claro .left-sidebar {
    --rx-v2-bg: color-mix(in srgb, var(--rx-color2, #10192e) 5%, #eef0f3);
    --rx-v2-shell: #ffffff;
    --rx-v2-panel: #ffffff;
    --rx-v2-panel-2: #f4f5f7;
    --rx-v2-field: #ffffff;
    --rx-v2-hover: #f3f5f8;
    --rx-v2-active: #e9ecf0;
    --rx-v2-ghost: rgba(18, 25, 33, .05);
    --rx-v2-border: rgba(18, 25, 33, .14);
    --rx-v2-border-soft: rgba(18, 25, 33, .08);
    --rx-v2-text: #1d242c;
    --rx-v2-muted: #5d6773;
    --rx-v2-faint: #8b94a1;
}

/* --- ui_topbar: la topbar como superficie propia ----------------------------
 * La misma receta que el sidebar y por el mismo motivo: la topbar ya se pinta
 * con tokens, asi que el knob no reescribe ninguna regla --- redefine los tokens
 * PARA ESE SUBARBOL y las reglas que existen los leen solas.
 *
 * Pero la topbar tiene DOS fondos, no uno, y la que manda en el admin real no es
 * la obvia. Medido en resumax: srgb(1 1 1 / .82), o sea la barra FLOTANTE del
 * pass 23c (>=768px con fix-header), que pinta --rx-v2-panel al 82% con blur. La
 * regla base --- `background: var(--rx-v2-bg)` --- solo manda en mobile y sin
 * fix-header. Por eso el knob mueve LOS DOS tokens: si moviera solo --rx-v2-bg
 * no haria nada en desktop, que es exactamente como empezo `ui_sidebar` bajo
 * vivid.
 *
 * Los menues del avatar y de avisos cuelgan del .topbar, asi que heredan estos
 * tokens y quedan como paneles del mismo juego. Es lo mismo que ya pasa con los
 * flyouts del sidebar en `oscuro`, y es lo que se quiere: una cabecera oscura
 * con sus desplegables claros se lee como dos temas peleando. */
/* El `:not(.rxs-ui-vivid)` no es simetria con el sidebar: alla `marca` bajo
 * vivid es inerte de verdad (vivid pinta el degrade y sus hover/active con
 * !important, y los flyouts leen --rx-v2-panel, que sb-marca no toca). Aca SI
 * toca --rx-v2-panel --- es la superficie de la barra flotante --- y los
 * desplegables del avatar y de avisos cuelgan del .topbar, asi que sin el guard
 * la barra quedaba vivid y sus menues tenidos: medido, #f6e7e1 contra el
 * degrade. Media aplicacion es peor que ninguna. */
body.rxs-ui-v2.rxs-ui-tb-marca:not(.rxs-ui-vivid) .topbar {
    /* 10% del acento, no el color pelado: la topbar tiene texto oscuro encima
     * (ver el bloque de `ui_sidebar`, es el mismo argumento) */
    --rx-v2-panel: color-mix(in srgb, var(--rx-v2-accent) 10%, #f6f7f9);
    --rx-v2-bg: color-mix(in srgb, var(--rx-v2-accent) 10%, #f6f7f9);
    --rx-v2-hover: color-mix(in srgb, var(--rx-v2-accent) 18%, #f6f7f9);
    --rx-v2-active: color-mix(in srgb, var(--rx-v2-accent) 26%, #f6f7f9);
    --rx-v2-border-soft: color-mix(in srgb, var(--rx-v2-accent) 22%, transparent);
}

body.rxs-ui-v2.thr-dark.rxs-ui-tb-marca:not(.rxs-ui-vivid) .topbar {
    --rx-v2-panel: color-mix(in srgb, var(--rx-v2-accent) 14%, #0b0e11);
    --rx-v2-bg: color-mix(in srgb, var(--rx-v2-accent) 14%, #0b0e11);
    --rx-v2-hover: color-mix(in srgb, var(--rx-v2-accent) 22%, #0b0e11);
    --rx-v2-active: color-mix(in srgb, var(--rx-v2-accent) 30%, #0b0e11);
}

/* `oscuro`: los MISMOS valores del bloque .thr-dark, redefinidos para el
 * subarbol --- no hay un segundo juego de colores que mantener. En un admin que
 * ya esta en oscuro no hace falta, y por eso la regla excluye .thr-dark. */
body.rxs-ui-v2.rxs-ui-tb-oscuro:not(.thr-dark) .topbar {
    --rx-v2-bg: color-mix(in srgb, var(--rx-color2, #10192e) 10%, #0d1014);
    --rx-v2-shell: #0b0e11;
    --rx-v2-panel: color-mix(in srgb, var(--rx-color2, #10192e) 7%, #171b20);
    --rx-v2-panel-2: color-mix(in srgb, var(--rx-color2, #10192e) 7%, #1b2026);
    --rx-v2-field: #10141a;
    --rx-v2-hover: #1e242b;
    --rx-v2-active: #232a32;
    --rx-v2-ghost: rgba(255, 255, 255, .06);
    --rx-v2-border: rgba(255, 255, 255, .09);
    --rx-v2-border-soft: rgba(255, 255, 255, .055);
    --rx-v2-text: #e8ecf1;
    --rx-v2-muted: #9aa4b1;
    --rx-v2-faint: #6d7784;
}

/* `claro`: el espejo de `oscuro`, como en el sidebar --- la barra clara de hoy
 * aun con el admin en oscuro, y por emitir clase le gana al fondo. El
 * `:not(.rxs-ui-vivid)` es el mismo del bloque `marca`: aca el knob toca
 * --rx-v2-panel y sin el guard la barra queda a mitad de camino entre vivid y
 * la hoja clara, con los menues tenidos. */
body.rxs-ui-v2.thr-dark.rxs-ui-tb-claro:not(.rxs-ui-vivid) .topbar {
    --rx-v2-bg: color-mix(in srgb, var(--rx-color2, #10192e) 5%, #eef0f3);
    --rx-v2-shell: #ffffff;
    --rx-v2-panel: #ffffff;
    --rx-v2-panel-2: #f4f5f7;
    --rx-v2-field: #ffffff;
    --rx-v2-hover: #f3f5f8;
    --rx-v2-active: #e9ecf0;
    --rx-v2-ghost: rgba(18, 25, 33, .05);
    --rx-v2-border: rgba(18, 25, 33, .14);
    --rx-v2-border-soft: rgba(18, 25, 33, .08);
    --rx-v2-text: #1d242c;
    --rx-v2-muted: #5d6773;
    --rx-v2-faint: #8b94a1;
}

/* Y bajo vivid, lo mismo que el sidebar: no se le pelea al !important, se le
 * cambia lo que lee. `marca` bajo vivid se queda como esta --- vivid ya es la
 * marca --- y solo `oscuro` pide su superficie. */
body.rxs-ui-v2.rxs-ui-vivid.rxs-ui-tb-oscuro .topbar {
    --rx-v2-vivid-shell: color-mix(in srgb, var(--rx-color2, #10192e) 10%, #0d1014);
}

/* Y el otro que se peleaba con este knob: "Colores vivos".
 *
 * El §4 del doc decia que son otro eje y que se combinan, y no era cierto:
 * `.rxs-ui-vivid .left-sidebar` pinta `var(--rx-v2-vivid-sidebar) !important`
 * --- un degrade --- asi que el token que redefine el knob no lo lee nadie.
 * Medido: con vivid prendido, `marca` y `oscuro` daban el mismo degrade de vivid.
 *
 * No se pelea con esa regla: se le cambia LO QUE LEE. Vivid sigue pintando su
 * propia declaracion y las ~20 reglas de texto blanco que la acompanan --- que
 * es lo que hace legible un sidebar oscuro --- siguen valiendo tal cual.
 *
 * Solo `oscuro`: una superficie oscura con texto blanco encima es exactamente
 * lo que vivid ya dibuja. `marca` bajo vivid se queda como esta a proposito y no
 * es un olvido --- vivid YA es la marca, y un tinte plano del acento con el
 * texto blanco de vivid encima es ilegible. Lo dice el helper del campo. */
body.rxs-ui-v2.rxs-ui-vivid.rxs-ui-sb-oscuro .left-sidebar {
    --rx-v2-vivid-sidebar: color-mix(in srgb, var(--rx-color2, #10192e) 10%, #0d1014);
}

/* --- ui_bg / ui_pt: el fondo del admin --------------------------------------
 * La capa la emite el PHP (rxsUiBgLayer, functions/ui.php) y trae las clases del
 * catalogo de njs/custom.css, las mismas que las pantallas publicas: el degrade
 * y la trama entran por --rxs-gr / --rxs-pt sin una linea de CSS por opcion.
 *
 * Se lee la variable directo y no se depende de la regla `.rxsPt-N.rxsPt-N` que
 * pinta en custom.css. Es a proposito: esa regla ENUMERA las nueve clases de
 * fabrica, asi que una trama de marca de pdf-gen (`rxsPt-<marca>-<variacion>`,
 * el logo del cliente tileado) declara su textura y no se veria. Leyendola aca,
 * la trama de marca funciona igual que las de fabrica. */
body.rxs-ui-v2 > .rxsUiBg {
    background-image:
        var(--rxs-pt, none),
        var(--rxs-gr, none);
    background-repeat: repeat, no-repeat;
    background-size: auto, cover;
    inset: 0;
    pointer-events: none;
    /* fixed y no absolute: el fondo del admin no scrollea con el contenido, y
     * asi la capa no depende del alto del documento (que en un listado largo
     * son varias pantallas y en el dashboard, una) */
    position: fixed;
    z-index: -1;
}

/* Con fondo elegido, las superficies del shell dejan de pintar su color plano:
 * si no, el degrade queda debajo de un gris que lo tapa entero y lo unico que
 * se ve es la franja de los bordes. Los PANELES no se tocan -- una tarjeta
 * translucida sobre un degrade es lo que hace ilegible una tabla.
 *
 * PERO solo si nadie eligio el lienzo (el mismo guard del §8.5 que ya tienen el
 * sidebar y la topbar): un `ui_surface` elegido A MANO pinta aunque haya fondo
 * --- hasta el 03-09 el knob entero era un no-op con fondo, medido: transparent
 * gane quien gane. Y `translucido` es la eleccion explicita del medio: el
 * lienzo pinta su color como VELO (45%) sobre el fondo --- se hereda el fondo,
 * atenuado, y el contenido lee mejor que sobre el crudo. Sin fondo, el velo
 * cae sobre el mismo color que pintan el html y el body: igual a `normal`. */
body.rxs-ui-v2.rxs-ui-bg:not(.rxs-ui-surface-neutro):not(.rxs-ui-surface-marca):not(.rxs-ui-surface-contraste):not(.rxs-ui-surface-translucido) .page-wrapper {
    background: transparent !important;
}

body.rxs-ui-v2.rxs-ui-bg.rxs-ui-surface-translucido .page-wrapper {
    background: color-mix(in srgb, var(--rx-v2-bg) 45%, transparent) !important;
}

/* La topbar sobre el fondo ya NO se apaga: es VIDRIO. La barra flotante del
 * pass 23c ya pinta panel al `--rx-v2-glass-a` con blur; con fondo el alfa
 * baja a 55% para que el fondo se vea a traves del esmerilado y los iconos
 * sigan leyendo --- hasta el 03-09 la barra quedaba `transparent` a secas, o
 * sea ni vidrio ni solida, y el knob `ui_glass` era un no-op con fondo (con
 * `solida` la barra directamente desaparecia). El guard del `:not`: si el
 * tenant pidio `solida`, solida es, tambien sobre el fondo. */
body.rxs-ui-v2.rxs-ui-bg:not(.rxs-ui-glass-solida) {
    --rx-v2-glass-a: 55%;
}

/* `claro` elegido con fondo: la barra clara DE HOY, no el vidrio al 55% ---
 * que en un admin claro es identico a no elegir nada (el pase 8 del arnes lo
 * cazo: 127 px contra 66k/71k de marca/oscuro). El alfa vuelve al 82% de
 * siempre, y solo en la barra: el sidebar sigue leyendo el del body. */
body.rxs-ui-v2.rxs-ui-bg.rxs-ui-tb-claro:not(.rxs-ui-glass-solida) .topbar {
    --rx-v2-glass-a: 82%;
}

/* El sidebar tambien, PERO solo si nadie lo eligio.
 *
 * Esta regla y el bloque de `ui_sidebar` de mas arriba se peleaban y ganaba
 * esta: el knob redefine --rx-v2-bg para el subarbol y aca el `transparent
 * !important` se lo lleva puesto, asi que el token quedaba bien puesto y no lo
 * pintaba nadie. Con un fondo elegido el knob del sidebar no hacia NADA --- era
 * el §8.5 de docs/frontend/ui-v2-config-del-tenant.md, medido: sin fondo,
 * `marca` computa srgb(.963 .908 .881); con fondo, rgba(0,0,0,0).
 *
 * La regla para desempatar: gana el que se eligio A MANO. `ui_bg` apaga las
 * superficies que NADIE pidio de otro color --- el degrade se sigue viendo en el
 * page-wrapper y en la topbar, que es la mayor parte de la pantalla --- y el
 * sidebar que el tenant eligio se pinta. Se nombran los valores en vez de un
 * [class*=] para que un grep de la clase encuentre esta regla.
 *
 * Y ya no es `transparent` a secas: es la MISMA receta del vidrio de la topbar
 * (§11.1) --- crudo, con un fondo fuerte el menu era ilegible (medido con
 * `gradiente-repetido`). El lienzo del sidebar pasa al `--rx-v2-glass-a` (55%
 * con fondo) con el blur de `--rx-v2-glass` detras, asi las dos barras del
 * shell responden IGUAL sobre el fondo; `ui_glass: solida` lo tapa opaco,
 * tambien aca, por los mismos tokens y sin saber una del otro. */
body.rxs-ui-v2.rxs-ui-bg:not(.rxs-ui-sb-claro):not(.rxs-ui-sb-marca):not(.rxs-ui-sb-oscuro) .left-sidebar {
    background: color-mix(in srgb, var(--rx-v2-bg) var(--rx-v2-glass-a), transparent) !important;
    -webkit-backdrop-filter: var(--rx-v2-glass);
    backdrop-filter: var(--rx-v2-glass);
}

/* y el <html> tambien: es el que pinta la franja que asoma arriba del shell */
html.rxs-ui-v2.rxs-ui-bg {
    background: transparent;
}

/* --- theme-feel: scrollbars con tokens. scrollbar-color pinta el scroll nativo
 * (viewport via body + todos los contenedores con overflow). --- */
body.rxs-ui-v2,
body.rxs-ui-v2 * {
    scrollbar-color: color-mix(in srgb, var(--rx-v2-faint) 55%, transparent) transparent;
}

/* --- theme-feel: seleccion de texto en acento --- */
body.rxs-ui-v2 ::selection {
    background: var(--rx-v2-accent);
    color: var(--rx-v2-accent-ink);
}

/* ================= pass 23: dropdown de usuario del topbar =================
 * El menu del avatar seguia siendo la lista v1 plana. Ahora: panel con padding,
 * header de usuario como card accent-soft, items con chip de icono, hover ghost,
 * "Modo Oscuro" como switch y "Salir" con hover danger. */
body.rxs-ui-v2 .topbar .dropdown-menu:has(> ul.dropdown-user) {
    border-radius: var(--rx-v2-r14);
    min-width: 268px;
    padding: 8px;
}
body.rxs-ui-v2 .topbar ul.dropdown-user {
    padding: 0;
}
/* header de usuario */
body.rxs-ui-v2 .topbar ul.dropdown-user li .dw-user-box {
    align-items: center;
    background: var(--rx-v2-accent-soft);
    border: 1px solid var(--rx-v2-border-soft);
    border-bottom: 1px solid var(--rx-v2-border-soft);
    border-radius: var(--rx-v2-r10);
    display: flex;
    gap: 10px;
    margin-bottom: 6px;
    padding: 12px;
}
body.rxs-ui-v2 .topbar ul.dropdown-user li .dw-user-box .u-img {
    flex: 0 0 auto;
    width: auto;
}
body.rxs-ui-v2 .topbar ul.dropdown-user li .dw-user-box .u-img img {
    border-radius: 50%;
    height: 40px;
    object-fit: cover;
    width: 40px;
}
body.rxs-ui-v2 .topbar ul.dropdown-user li .dw-user-box .u-text {
    min-width: 0;
}
body.rxs-ui-v2 .topbar ul.dropdown-user li .dw-user-box .u-text h4,
body.rxs-ui-v2 .topbar ul.dropdown-user li .dw-user-box .u-text p.text-muted {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
/* items: fila flex con chip de icono */
body.rxs-ui-v2 .topbar ul.dropdown-user > li > a {
    align-items: center;
    border-radius: var(--rx-v2-r8);
    display: flex !important;
    font-size: 13px;
    gap: 10px;
    padding: 7px 8px !important;
}
body.rxs-ui-v2 .topbar ul.dropdown-user > li > a > i.fa,
body.rxs-ui-v2 .topbar ul.dropdown-user li .rxsCheck2 #themeIcon > .fa {
    align-items: center;
    background: var(--rx-v2-ghost);
    border-radius: var(--rx-v2-r7);
    color: var(--rx-v2-muted);
    display: inline-flex;
    flex: 0 0 auto;
    font-size: 12px;
    height: 26px;
    justify-content: center;
    margin: 0;
    transition: background .14s ease, color .14s ease;
    width: 26px;
}
body.rxs-ui-v2 .topbar ul.dropdown-user > li > a:hover > i.fa {
    background: var(--rx-v2-accent-soft);
    color: var(--rx-v2-accent);
}
/* divisores con aire */
body.rxs-ui-v2 .topbar ul.dropdown-user li.divider {
    margin: 6px 4px;
}
/* fila "Modo Oscuro": misma fila que un item + switch a la derecha */
body.rxs-ui-v2 .topbar ul.dropdown-user > li.pl-2 {
    align-items: center;
    border-radius: var(--rx-v2-r8);
    display: flex;
    flex-direction: row-reverse;
    gap: 10px;
    justify-content: space-between;
    padding: 7px 8px !important;
}
body.rxs-ui-v2 .topbar ul.dropdown-user > li.pl-2:hover {
    background: var(--rx-v2-hover);
}
body.rxs-ui-v2 .topbar ul.dropdown-user li .rxsCheck2 {
    align-items: center;
    color: var(--rx-v2-text);
    cursor: pointer;
    display: flex;
    flex: 1 1 auto;
    font-size: 13px;
    margin: 0;
}
body.rxs-ui-v2 .topbar ul.dropdown-user li .rxsCheck2 #themeIcon {
    align-items: center;
    display: flex;
    gap: 10px;
}
/* materialize esconde el input (opacity 0, left -9999) y dibuja el cuadrado en
 * los pseudos del label: se anulan y el switch vive en el input real */
body.rxs-ui-v2 .topbar ul.dropdown-user li [type="checkbox"]#themeToggle + label.rxsCheck2 {
    padding-left: 0 !important;
}
body.rxs-ui-v2 .topbar ul.dropdown-user li [type="checkbox"]#themeToggle + label.rxsCheck2::before,
body.rxs-ui-v2 .topbar ul.dropdown-user li [type="checkbox"]#themeToggle + label.rxsCheck2::after {
    content: none !important;
    display: none !important;
}
body.rxs-ui-v2 .topbar ul.dropdown-user input#themeToggle {
    -webkit-appearance: none;
    appearance: none;
    left: auto !important;
    opacity: 1 !important;
    pointer-events: auto !important;
    visibility: visible !important;
    background: var(--rx-v2-faint);
    border: 0;
    border-radius: 999px;
    cursor: pointer;
    flex: 0 0 auto;
    height: 20px;
    margin: 0;
    position: relative;
    transition: background .15s ease;
    width: 36px;
}
body.rxs-ui-v2 .topbar ul.dropdown-user input#themeToggle::after {
    background: var(--rx-v2-panel, #fff);
    border-radius: 50%;
    box-shadow: 0 1px 3px rgba(0, 0, 0, .3);
    content: "";
    height: 16px;
    left: 2px;
    position: absolute;
    top: 2px;
    transition: left .15s ease;
    width: 16px;
}
body.rxs-ui-v2 .topbar ul.dropdown-user input#themeToggle:checked {
    background: var(--rx-v2-accent);
}
body.rxs-ui-v2 .topbar ul.dropdown-user input#themeToggle:checked::after {
    left: 18px;
}
/* salir: hover danger */
body.rxs-ui-v2 .topbar ul.dropdown-user > li > a[onclick*="logmeOut"]:hover {
    background: color-mix(in srgb, #f4506c 14%, transparent) !important;
    color: #f4506c !important;
}
body.rxs-ui-v2 .topbar ul.dropdown-user > li > a[onclick*="logmeOut"]:hover > i.fa {
    background: color-mix(in srgb, #f4506c 18%, transparent);
    color: #f4506c;
}

/* chip de iniciales cuando la foto de usuario esta rota (ui_v2.js fixAvatars) */
body.rxs-ui-v2 .rxs-avatar-ini {
    align-items: center;
    background: var(--rx-v2-accent-soft);
    border-radius: 50%;
    color: var(--rx-v2-accent);
    display: inline-flex;
    flex: 0 0 auto;
    font-size: 14px;
    font-weight: 700;
    height: 40px;
    justify-content: center;
    letter-spacing: .02em;
    width: 40px;
}
body.rxs-ui-v2 .rxs-avatar-ini-sm {
    font-size: 11.5px;
    height: 30px;
    width: 30px;
}
/* iniciales con un tono de la gama en --rxp (una persona, un autor): el mismo tinte de la
 * pill pero mas cargado, sobre el panel opaco, asi tambien se adapta al modo oscuro */
body.rxs-ui-v2 .rxs-avatar-ini.rxs-avatar-hue {
    background-color: var(--rx-v2-panel);
    background-image: linear-gradient(hsl(var(--rxp) var(--rx-tint-s) var(--rx-tint-l) / calc(var(--rx-tint-a) * 2.2)), hsl(var(--rxp) var(--rx-tint-s) var(--rx-tint-l) / calc(var(--rx-tint-a) * 2.2)));
    color: hsl(var(--rxp) var(--rx-tint-ink-s) var(--rx-tint-ink-l));
}
/* en vivid la topbar es gradiente de marca: chip en vidrio blanco */
body.rxs-ui-v2.rxs-ui-vivid .topbar .rxs-avatar-ini {
    background: rgba(255, 255, 255, .24);
    color: #fff;
}

/* ============ pass 23b: login / register / recpw — salto v2 real ============
 * El pass 8c tokenizaba, pero los sitios con css propio (csst.css) cargan DESPUES
 * de adm.css y lo pisaban (CTA btn-info cyan, inputs con otro radio). Este bloque
 * asegura las pantallas publicas con !important y moderniza la estructura:
 * icono ADENTRO del campo (prepend absoluto) en vez de cajita pegada, card con
 * hairline de marca, CTA accent y secundarios ghost. */
body.rxs-ui-v2 .login-register .login-box.card {
    border-radius: var(--rx-v2-r18) !important;
    overflow: hidden;
    position: relative;
}
body.rxs-ui-v2 .login-register .login-box.card::before {
    background: var(--rx-v2-grad, linear-gradient(90deg, var(--rx-v2-accent), var(--rx-v2-accent-2, var(--rx-v2-accent))));
    content: "";
    height: 3px;
    left: 0;
    position: absolute;
    right: 0;
    top: 0;
}
body.rxs-ui-v2 .login-register .box-title {
    font-size: 21px !important;
    font-weight: 700 !important;
    letter-spacing: -.02em;
}
/* icon-inside: el input-group entero es el campo; prepend/append flotan adentro */
body.rxs-ui-v2 .login-register .input-group {
    position: relative;
}
body.rxs-ui-v2 .login-register .input-group .input-group-prepend,
body.rxs-ui-v2 .login-register .input-group .input-group-append {
    align-items: center;
    background: none !important;
    border: 0 !important;
    bottom: 0;
    display: flex;
    margin: 0;
    position: absolute;
    top: 0;
    z-index: 5;
}
body.rxs-ui-v2 .login-register .input-group .input-group-prepend { left: 0; pointer-events: none; }
body.rxs-ui-v2 .login-register .input-group .input-group-append { right: 0; }
body.rxs-ui-v2 .login-register .input-group .input-group-text {
    background: none !important;
    border: 0 !important;
    color: var(--rx-v2-faint) !important;
    font-size: 13px;
    padding: 0 13px;
}
/* en light --rx-v2-field es blanco = invisible sobre la card blanca: tinte suave.
 * (la variante #maincontent gana a la regla generica de inputs de #maincontent) */
body.rxs-ui-v2 #maincontent .login-register input.form-control,
body.rxs-ui-v2 #maincontent .login-register select.form-control,
body.rxs-ui-v2 .login-register .form-control,
body.rxs-ui-v2 .login-register .input-group .form-control,
body.rxs-ui-v2 .login-register form.rxs-form .rxs-field .input-group .form-control {
    background: color-mix(in srgb, var(--rx-v2-text) 4%, var(--rx-v2-field)) !important;
    border: 1px solid var(--rx-v2-border) !important;
    border-radius: var(--rx-v2-r12) !important;
    color: var(--rx-v2-text) !important;
    height: 44px !important;
    width: 100% !important;
}
/* current49 le pone al .input-group border-radius:1rem + overflow:hidden (pensado para
 * inputs cuadrados): con el radio 12px del campo v2 ese clip de 16px se come el borde en
 * las esquinas. Mismo radio y sin recorte. */
body.rxs-ui-v2 .login-register .input-group {
    border-radius: var(--rx-v2-r12) !important;
    overflow: visible !important;
}
/* goform embebido (register): el pass 19 pinta el prepend como cajita con fondo
 * y parte el radio del input; aca el icono va adentro del campo */
body.rxs-ui-v2 .login-register form.rxs-form .rxs-field .input-group .input-group-prepend .input-group-text,
body.rxs-ui-v2 .login-register form.rxs-form .rxs-field .input-group .input-group-text {
    background: transparent !important;
    border: 0 !important;
    color: var(--rx-v2-faint) !important;
}
body.rxs-ui-v2 .login-register form.rxs-form .rxs-field .input-group .form-control {
    padding-left: 40px !important;
}
body.rxs-ui-v2 .login-register .input-group .form-control {
    padding-left: 40px !important;
}
body.rxs-ui-v2 .login-register .input-group .input-group-append ~ .form-control,
body.rxs-ui-v2 .login-register .input-group:has(.input-group-append) .form-control {
    padding-right: 40px !important;
}
body.rxs-ui-v2 .login-register .form-control:focus {
    border-color: var(--rx-v2-accent) !important;
    box-shadow: 0 0 0 3px var(--rx-v2-accent-soft) !important;
}
/* select nativo del goform embebido (registro): mismo campo */
body.rxs-ui-v2 .login-register select.form-control {
    -webkit-appearance: none;
    appearance: none;
}
/* CTA primario: login (stvLoginBtn), recpw (recpw-btn), submits de goform */
body.rxs-ui-v2 .login-register .stvLoginBtn,
body.rxs-ui-v2 .login-register .recpw-btn,
body.rxs-ui-v2 .login-register .rxsFormSb,
body.rxs-ui-v2 .login-register .rxsAuth-cta,
body.rxs-ui-v2 .login-register form button[type="submit"].btn-info,
body.rxs-ui-v2 .login-register form button[type="submit"].btn-success {
    background: var(--rx-v2-accent) !important;
    background-image: none !important;
    border: 0 !important;
    border-radius: var(--rx-v2-r12) !important;
    box-shadow: none !important;
    color: var(--rx-v2-accent-ink, #fff) !important;
    font-size: 13px !important;
    font-weight: 650 !important;
    height: 44px;
    letter-spacing: .04em;
    transition: filter .15s ease;
}
body.rxs-ui-v2 .login-register .stvLoginBtn:hover,
body.rxs-ui-v2 .login-register .recpw-btn:hover,
body.rxs-ui-v2 .login-register .rxsFormSb:hover,
body.rxs-ui-v2 .login-register .rxsAuth-cta:hover {
    filter: brightness(1.08);
}
/* secundarios (como usuario/admin, QR, registro, sin contraseña, biometria): ghost */
body.rxs-ui-v2 .login-register .btn-block:not(.stvLoginBtn):not(.recpw-btn):not(.rxsFormSb):not(.rxsAuth-cta),
body.rxs-ui-v2 .login-register .btnMailLogin {
    background: var(--rx-v2-ghost) !important;
    background-image: none !important;
    border: 1px solid var(--rx-v2-border) !important;
    border-radius: var(--rx-v2-r12) !important;
    color: var(--rx-v2-muted) !important;
    font-size: 12.5px;
    font-weight: 600;
    text-shadow: none !important;
    transition: border-color .15s ease, color .15s ease;
}
body.rxs-ui-v2 .login-register .btn-block:not(.stvLoginBtn):not(.recpw-btn):not(.rxsFormSb):not(.rxsAuth-cta):hover,
body.rxs-ui-v2 .login-register .btnMailLogin:hover {
    border-color: var(--rx-v2-accent) !important;
    color: var(--rx-v2-text) !important;
}
/* sociales tipo banda (register: CONECTAR CON FACEBOOK/APPLE/GOOGLE) */
body.rxs-ui-v2 .login-register .btn-social {
    align-items: center;
    display: flex !important;
    gap: 8px;
    justify-content: center;
    text-transform: none;
}
/* links (recpw, ya tengo usuario, registro) */
body.rxs-ui-v2 .login-register a.recpw,
body.rxs-ui-v2 .login-register a.already-login,
body.rxs-ui-v2 .login-register a.text-center {
    color: var(--rx-v2-accent) !important;
    display: block;
    font-size: 13px !important;
    font-weight: 600;
    margin: 10px 0 12px;
}
/* alerts del form (goform mete pasteles bootstrap) */
body.rxs-ui-v2 .login-register .alert {
    background: var(--rx-v2-panel-2, var(--rx-v2-ghost)) !important;
    border: 1px solid var(--rx-v2-border-soft) !important;
    border-left: 3px solid #f5b83d !important;
    border-radius: var(--rx-v2-r10) !important;
    color: var(--rx-v2-text) !important;
}
body.rxs-ui-v2 .login-register .alert-danger { border-left-color: #f4506c !important; }
body.rxs-ui-v2 .login-register .alert-success { border-left-color: #2ecf6e !important; }
/* captcha: que no desborde la card */
body.rxs-ui-v2 .login-register .g-recaptcha,
body.rxs-ui-v2 .login-register iframe[src*="recaptcha"] {
    border-radius: var(--rx-v2-r10);
    max-width: 100%;
}

/* ============ pantallas de ingreso por contrato ============
 * Salio a njs/g_auth.css el 2026-10-06: el render del contrato se monta tambien sin UI v2. Las
 * reglas de arriba (pass 23b: campos, CTA, aviso) siguen siendo de v2 y le dan los campos. */

/* ============ pass 23c: shell flotante (desktop) ============
 * Salto estructural del chrome: la topbar deja de ser una banda full-width v1
 * y pasa a ser una barra flotante redondeada sobre el area de contenido; el
 * sidebar queda como rail a altura completa con su contenido arrancando arriba
 * (ya no reserva los 70px de la topbar); el footer pasa de banda blanca a
 * hairline mudo. Solo >=768px: en mobile el shell legacy (dock + overlay) queda. */
@media (min-width: 768px) {
    body.rxs-ui-v2.fix-header .topbar {
        border: 1px solid var(--rx-v2-border-soft);
        border-radius: var(--rx-v2-r14);
        left: 252px;
        right: 12px;
        top: 10px !important; /* .thr-fix header.topbar clava top:0 !important */
        width: auto;
    }
    /* el blur/translucido solo sin vivid (vivid pinta su gradiente de marca).
     * Los dos numeros salen de tokens: son el knob `ui_glass`, y con `solida`
     * quedan `none` / `100%`, o sea la misma barra sin vidrio. Y la superficie
     * es --rx-v2-panel, que es lo que redefine `ui_topbar` para este subarbol:
     * los dos knobs se combinan sin que ninguno sepa del otro. */
    /* El vidrio NO va en la topbar sino en su ::before. Un backdrop-filter
     * distinto de `none` vuelve al elemento el containing block de sus hijos
     * `position:fixed`, y la nav adentro lleva #helperContainer (el panel del
     * tour, fixed bottom:0): su `bottom:0` se resolvia contra el borde de abajo
     * de la barra (62px) y el panel se dibujaba arriba, cortado. Vive ahi porque
     * lo tiene que compilar Vue (index.php, $rxsHelperCont), y con Vue 2 no hay
     * <teleport>. El fondo va con el blur al ::before porque el backdrop de un
     * hijo incluye el fondo del padre: dejarlo en la barra blureaba su propio
     * panel. `isolation` deja el z-index:-1 adentro de la barra sin volverla
     * containing block. */
    body.rxs-ui-v2.fix-header:not(.rxs-ui-vivid) .topbar {
        background: transparent !important;
        box-shadow: var(--rx-v2-shadow);
        isolation: isolate;
    }
    body.rxs-ui-v2.fix-header:not(.rxs-ui-vivid) .topbar::before {
        -webkit-backdrop-filter: var(--rx-v2-glass);
        backdrop-filter: var(--rx-v2-glass);
        background: color-mix(in srgb, var(--rx-v2-panel) var(--rx-v2-glass-a), transparent);
        border-radius: inherit;
        content: "";
        inset: 0;
        pointer-events: none;
        position: absolute;
        z-index: -1;
    }
    /* hairline de marca adentro del radio */
    body.rxs-ui-v2.fix-header .topbar::after {
        border-radius: var(--rx-v2-r2);
        bottom: 0;
        left: 14px;
        right: 14px;
    }
    body.rxs-ui-v2.mini-sidebar.fix-header .topbar { left: 72px; }
    body.rxs-ui-v2.single-column.fix-header .topbar { left: 12px; }
    /* compensar el corrimiento: el theme deja body{padding-top:60px} y la topbar
     * flotante termina en 72 (10 de top + 62 de alto), o sea 12 de deuda. El aire
     * hasta el contenido NO va aca: lo pone el padding-top del #maincontent (18),
     * que es el mismo ritmo que los 20 de los costados. Con 24 se sumaban los dos
     * y quedaban 30px muertos entre la topbar y la primera card/tab. */
    body.rxs-ui-v2.fix-header .page-wrapper {
        padding-top: 12px;
    }
    /* OJO: el left/right/top de arriba asume topbar FIJA, y eso NO lo da
     * .fix-header (index.php la pone siempre) sino .thr-fix, que solo se agrega
     * si el sitio tiene menu json (prs.home > 0). Sin .thr-fix la topbar es
     * position:relative: `right` se ignora, `width:auto` = 100% del padre y el
     * `left:252px` la corre entera -> la barra se pasa 252px de la pantalla por
     * la derecha. Para ese caso la misma geometria va por margin (queda en
     * flujo, sin desbordar). */
    body.rxs-ui-v2.fix-header:not(.thr-fix) .topbar {
        left: auto;
        margin: 10px 12px 0 252px;
        right: auto;
        top: auto !important;
    }
    body.rxs-ui-v2.mini-sidebar.fix-header:not(.thr-fix) .topbar { margin-left: 72px; }
    body.rxs-ui-v2.single-column.fix-header:not(.thr-fix) .topbar { margin-left: 12px; }
    /* en flujo no hay corrimiento que compensar */
    body.rxs-ui-v2.fix-header:not(.thr-fix) .page-wrapper {
        padding-top: 0;
    }
    /* el rail ya no vive debajo de la topbar: su contenido arranca arriba.
     * En horizontal no hay rail y esta regla le gana por especificidad al
     * padding de la barra (pass 23e), asi que el menu quedaba con 14px arriba
     * y 4 abajo: descentrado dentro de su propia caja. */
    body.rxs-ui-v2.fix-sidebar:not(.mini-sidebar):not(.horizontal) .left-sidebar {
        padding-top: 14px;
    }
    /* la marca dentro de la barra flotante respira menos alto, pero sigue
     * centrada (index.php pone SIEMPRE body.logo-center y asi se ve el sitio).
     * OJO: el theme (style2.css) la centra con position:absolute + left:0 +
     * right:0 contando con el width:240px fijo de .navbar-header; al pisar ese
     * width con auto, un absolute con left Y right se estira a TODO el ancho de
     * la topbar y el bloque tapa/come los clicks de los nav-link. Por eso el
     * centrado se rehace con left:50% + translateX y right:auto. */
    body.rxs-ui-v2 .topbar .top-navbar .navbar-header {
        width: auto;
        min-width: 0;
        padding-left: 0;
        left: 50%;
        right: auto;
        margin: 0;
        transform: translateX(-50%);
    }
}

/* logo del sitio: el chip oscuro que iba detras del img en claro (para que un
 * asset blanco no desapareciera sobre la barra clara) se saco a pedido --- el
 * logo va suelto sobre la topbar en los cuatro modos. Si un tenant sube un logo
 * blanco sobre transparente, el que tiene que cambiar es el asset. */

/* footer: de banda blanca v1 a hairline mudo */
body.rxs-ui-v2 .footer {
    background: transparent !important;
    border-top: 1px solid var(--rx-v2-border-soft) !important;
    color: var(--rx-v2-faint) !important;
    font-size: 11.5px;
    padding: 12px 20px;
    text-align: center;
}

/* ============ pass 23d: "Ingresar" del topbar + centrado de publicas ============ */

/* deslogueado: el link "Ingresar" era un nav-link muted a 19px pegado al borde.
 * Ahora es el CTA del topbar: pill accent con gap y aire a la derecha */
body.rxs-ui-v2 .topbar .nav-link.stvGoLogin {
    background: var(--rx-v2-accent) !important;
    border-radius: 999px;
    color: var(--rx-v2-accent-ink, #fff) !important;
    font-size: 13px !important;
    font-weight: 650;
    gap: 7px;
    height: 36px;
    margin: 0 6px 0 4px;
    padding: 0 16px !important;
    transition: filter .15s ease;
}
body.rxs-ui-v2 .topbar .nav-link.stvGoLogin:hover {
    background: var(--rx-v2-accent) !important;
    color: var(--rx-v2-accent-ink, #fff) !important;
    filter: brightness(1.08);
}
body.rxs-ui-v2 .topbar .nav-link.stvGoLogin i.fa {
    font-size: 12px;
}
/* el color del texto lo pisaba la regla del tema para los nav-link de la topbar
 * (mismo !important, mas especificidad) -> el CTA quedaba gris muted sobre el
 * pill accent, ilegible. Igualamos especificidad con la cadena completa. */
body.rxs-ui-v2 .topbar .navbar-nav > .nav-item > a.nav-link.stvGoLogin,
body.rxs-ui-v2 .topbar .navbar-nav > .nav-item > a.nav-link.stvGoLogin:hover,
body.rxs-ui-v2 .topbar .navbar-nav > .nav-item > a.nav-link.stvGoLogin:focus,
body.rxs-ui-v2 .topbar .navbar-nav > .nav-item > a.nav-link.stvGoLogin i.fa {
    color: var(--rx-v2-accent-ink, #fff) !important;
}
body.rxs-ui-v2.rxs-ui-vivid .topbar .navbar-nav > .nav-item > a.nav-link.stvGoLogin,
body.rxs-ui-v2.rxs-ui-vivid .topbar .navbar-nav > .nav-item > a.nav-link.stvGoLogin i.fa {
    color: #1d242c !important;
}
/* en vivid la topbar ya es accent: el CTA va en vidrio blanco */
body.rxs-ui-v2.rxs-ui-vivid .topbar .nav-link.stvGoLogin {
    background: rgba(255, 255, 255, .92) !important;
    color: #1d242c !important;
}

/* login/register/recpw: centrado vertical real. login.php trae d-flex vh-100
 * pero recpw/register son display:block arriba a la izquierda; y el vh-100 ya
 * no cierra con la topbar flotante (desborda y scrollea). Unificamos: flex
 * centrado con min-height segun viewport menos el chrome.
 *
 * Ese "menos el chrome" era un 190px a ojo y no cerraba: la pantalla scrolleaba
 * igual, sin nada abajo para ver. Medido a 1280x860 lo que hay arriba y abajo
 * de la tarjeta es
 *
 *     60  body padding-top   (`thr-fix` reserva la topbar fija)
 *   + 12  .page-wrapper padding-top
 *   + 18  #maincontent padding-top
 *   + 128 #maincontent padding-bottom  <- la reserva de la columna de FABs
 *   + 60  .page-wrapper padding-bottom (solo con sesion)
 *   ----
 *     278 con sesion / 218 sin sesion
 *
 * o sea 88px de scroll fantasma en la vista publica de un admin y 28px en el
 * login publico. Los dos que sobran son reservas para cosas que en estas tres
 * pantallas no existen: contados en el DOM de /login y /register, no hay ni un
 * FAB ni bottom nav que esquivar, y el colchon del page-wrapper es
 * para que el ultimo renglon de una tabla no quede pegado al borde. Se anulan
 * con :has() —que este archivo ya usa para la bottom nav— y entonces el chrome
 * deja de ser una estimacion: son los cuatro paddings que quedan. */
body.rxs-ui-v2 {
    --rx-v2-login-chrome: 72px;
}
body.rxs-ui-v2 #maincontent > .login-register {
    align-items: center;
    display: flex;
    flex-direction: column;
    height: auto !important; /* pisa el vh-100 de la variante login */
    justify-content: center;
    min-height: calc(100dvh - var(--rx-v2-login-chrome));
    padding: 24px 12px;
    position: relative;
}
/* El footer del sitio publico es position:absolute pegado al fondo del
 * page-wrapper: no reserva alto (por eso no hace scroll) pero queda flotando
 * ENCIMA del area de contenido. Contra el gris de antes no se notaba; contra el
 * degrade el texto gris no se lee. Se le da su propia banda. En `.no-logged` no
 * aplica: ahi current49 lo esconde. */
body.rxs-ui-v2.rxs-v2-login .footer {
    /* !important porque mas arriba v2 pone `.footer{background:transparent
     * !important}`: ahi el fondo de la pagina es plano y el footer sin caja se
     * ve mejor. Sobre un degrade deja de ser cierto, y esta es la excepcion. */
    background: var(--rx-v2-shell) !important;
    border-top: 1px solid var(--rx-v2-border-soft);
}

body.rxs-ui-v2.rxs-v2-login .page-wrapper {
    /* el min-height lo escribe el theme por JS y sale de `100vh - 71`: no mira
     * el padding del body (60 arriba y, en mobile, 50 abajo reservando la
     * bottom nav), asi que en telefono se pasaba 39px el solo. Aca no hace
     * falta: la altura ya la pone .login-register, que si los cuenta. Va con
     * !important porque el otro es un estilo inline. */
    min-height: 0 !important;
    padding-bottom: 0;
}
body.rxs-ui-v2.rxs-v2-login #maincontent.container-fluid {
    /* el min-height inline es del theme y sobrevive a la navegacion SPA: el
     * boton "Ingresar" reemplaza el interior de #maincontent (njs/g.js) pero
     * deja el alto que se habia calculado para la pagina ANTERIOR. Entrando por
     * el boton desde la home eso son 1272px contra los 788 que necesita el
     * login: 484px de scroll sin nada abajo, y en mobile 2415. Va con
     * !important porque el otro es inline. */
    min-height: 0 !important;
    padding: 0;
}
@media (max-width: 767px) {
    /* en mobile el body suma 50px abajo reservando la bottom nav: 60 + 50 */
    body.rxs-ui-v2 {
        --rx-v2-login-chrome: 110px;
    }
    body.rxs-ui-v2.rxs-v2-login #maincontent.container-fluid {
        padding: 0;
    }
}
/* En `.no-logged` (public=0) el chrome no esta escondido a medias: NO ESTA. La
 * topbar, el footer y la bottom nav salen los tres en display:none --contado en
 * el DOM de resumax, desktop y mobile-- y sin embargo el documento sigue
 * reservandoles el lugar: 60px arriba (`thr-fix`), 12 mas del page-wrapper y en
 * mobile 50 abajo por la bottom nav.
 *
 * Eso deja el area de contenido empezando en y=72 en vez de 0, y ahi se ve la
 * costura que se nota en la pantalla: el velo (`.login-register::before`) es
 * inset:0 de un elemento que arranca en 72, mientras que la capa del fondo en
 * esta pantalla es `fixed` y ocupa la ventana entera. La banda de arriba --y en
 * mobile la de abajo-- queda con el degrade SIN velar, y el borde entre las dos
 * es una linea recta cruzando la pantalla. De paso la tarjeta quedaba centrada
 * 36px mas abajo del centro real.
 *
 * Se corrige la reserva y no el velo: el velo esta bien atado a la caja de
 * contenido (es lo que hace falta en `.not-logged`, donde arriba hay una topbar
 * de verdad). Lo que estaba mal es que esta pantalla creyera tener chrome. */
body.rxs-ui-v2.no-logged.rxs-v2-login {
    /* le gana por especificidad al `body.rxs-ui-v2.thr-fix{padding-top:60px}` de
     * mas arriba y al `body{padding-bottom:50px}` de custom.css en mobile */
    padding-bottom: 0;
    padding-top: 0;
    /* y entonces no queda chrome que descontarle al alto de la tarjeta: los
     * 72/110 de `--rx-v2-login-chrome` eran justamente esas reservas */
    --rx-v2-login-chrome: 0px;
}
body.rxs-ui-v2.no-logged.rxs-v2-login .page-wrapper {
    padding-top: 0;
}
/* Adentro de la app (`rxsAppShell`) tampoco hay chrome, y aca el body es `.not-logged` si el
 * tenant es publico: el server no manda topbar ni footer y las barras las dibuja la app afuera
 * del WebView. Con los 110px de mobile el login quedaba 110px mas corto que la ventana y abajo
 * una franja sin velo (medido en el moto g54, nuevosistema: 584 de 694). */
body.rxs-ui-v2.rxsAppShell.rxs-v2-login {
    --rx-v2-login-chrome: 0px;
}
/* En un telefono la tarjeta del login/registro eran seis capas de aire por lado: 12 del
 * contenedor, 32 de la tarjeta, la caja blanca del formulario (borde + 14) y 15 de cada columna
 * de bootstrap. 75px por lado: de 360 quedaban 210 para los campos, y el reCAPTCHA (304 fijos)
 * se salia de la tarjeta. Una tarjeta adentro de otra no aporta en ese ancho: el formulario va
 * directo sobre la tarjeta y los campos ocupan su ancho. */
@media (max-width: 575px) {
    body.rxs-ui-v2 #maincontent > .login-register {
        padding-left: 8px;
        padding-right: 8px;
    }
    body.rxs-ui-v2 #maincontent > .login-register .card-body {
        padding-left: 14px;
        padding-right: 14px;
    }
    body.rxs-ui-v2 .login-register form.rxs-form .rxs-form-grid {
        background: transparent;
        border: 0;
        box-shadow: none;
        margin-left: 0;
        margin-right: 0;
        padding-left: 0;
        padding-right: 0;
    }
    body.rxs-ui-v2 .login-register form.rxs-form .rxs-form-grid > [class*="col"] {
        padding-left: 0;
        padding-right: 0;
    }
}
/* fondo decorativo: dos glows con los colores del sitio (dark y light) */
/* El velo. Los degrades de marca van de un color claro a otro claro -naranja a
 * amarillo, violeta a celeste- y sobre eso no hay texto que sirva, ni blanco ni
 * negro; un radial oscuro hacia los bordes le da a la tarjeta contra que
 * recortarse sin apagar el color en el centro. Antes esta capa era un wash de
 * accent al 14% que sobre el gris se leia como "gris con una sombra": eso era
 * el "no veo ni efectos ni tramas".
 *
 * Va en el ::before y no adentro de `.rxsLoginBg` para que el velo quede SIEMPRE
 * arriba del fondo, elija el tenant el degrade que elija. Es absolute igual que
 * la capa, asi que en las pantallas con chrome no se le sube a la topbar ni al
 * footer; en `.no-logged` la capa pasa a fixed y el velo la acompana porque el
 * .login-register ya ocupa todo lo que hay. */
body.rxs-ui-v2 #maincontent > .login-register::before {
    background-image: radial-gradient(130% 100% at 50% 41%,
        rgba(0, 0, 0, 0), rgba(0, 0, 0, .34));
    background-size: cover;
    content: "";
    inset: 0;
    pointer-events: none;
    position: absolute;
}

/* La tarjeta. Sobre un fondo de color el panel opaco de la app se lee como un
 * parche pegado encima, asi que en la publica pasa a vidrio: el mismo panel,
 * translucido y con blur, para que el color de la marca se intuya detras.
 *
 * Vidrio CLARO y no oscuro, aunque el launcher use oscuro: alla el logo es el
 * de RexShell y esta hecho para fondo oscuro; aca el logo lo sube el cliente y
 * un buen numero de ellos son negros sobre transparente. Probado en resumax:
 * sobre vidrio oscuro la mitad del logo desaparece. Por lo mismo el texto, los
 * campos y los botones NO se invierten: siguen siendo los de la tarjeta clara
 * que ya estaba, que es lo que un logo de cliente puede acompanar.
 *
 * El color es fijo y no sale de --rx-v2-panel: el fondo de marca es el mismo en
 * claro y en oscuro —la marca no cambia con la preferencia del que mira—, asi
 * que en dark un token de tema daria una tarjeta oscura con el mismo problema
 * del logo. Va todo scopeado a .no-logged: la MISMA pantalla abierta por un
 * admin con sesion sigue adentro del chrome de la app, sobre --rx-v2-bg, y ahi
 * el panel opaco es lo correcto. */
/* En dark la tarjeta seguiria siendo clara (arriba es un color fijo) pero el
 * texto, los campos y los bordes salen de --rx-v2-*, que en `.thr-dark` son
 * claros: texto claro sobre vidrio claro. En vez de repetir las ~20 reglas de
 * la tarjeta con colores a mano, se redefinen los tokens para ESTE subarbol y
 * las reglas que ya existen los leen solas. El acento no se toca: es la marca,
 * y en dark ya viene aclarado a proposito. */
body.rxs-ui-v2.thr-dark #maincontent > .login-register {
    --rx-v2-panel: #ffffff;
    --rx-v2-panel-2: #f4f5f7;
    --rx-v2-field: #ffffff;
    --rx-v2-head: #f1f3f5;
    --rx-v2-hover: #f3f5f8;
    --rx-v2-active: #e9ecf0;
    --rx-v2-ghost: rgba(18, 25, 33, .05);
    --rx-v2-border: rgba(18, 25, 33, .14);
    --rx-v2-border-soft: rgba(18, 25, 33, .08);
    --rx-v2-text: #1d242c;
    --rx-v2-muted: #5d6773;
    --rx-v2-faint: #8b94a1;
}
body.rxs-ui-v2 #maincontent > .login-register .login-box.card,
body.rxs-ui-v2 #maincontent > .login-register .card {
    -webkit-backdrop-filter: blur(16px) saturate(1.2);
    backdrop-filter: blur(16px) saturate(1.2);
    background: rgba(255, 255, 255, .84) !important;
    border: 1px solid rgba(255, 255, 255, .65) !important;
    border-radius: var(--rx-v2-r18);
    box-shadow: 0 22px 60px rgba(0, 0, 0, .28);
}
body.rxs-ui-v2 #maincontent > .login-register .login-box.card {
    margin: 0 auto;
    max-width: 432px;
    position: relative; /* sobre el ::before */
    width: 100%;
}
body.rxs-ui-v2 .login-register .card-body {
    padding: 32px 32px 26px;
}
body.rxs-ui-v2 .login-register .box-title,
body.rxs-ui-v2 .login-register .card-body > h3 {
    color: var(--rx-v2-text);
    display: block;
    font-size: 21px;
    font-weight: 700;
    letter-spacing: -.02em;
    margin-bottom: 14px;
    text-align: center;
}
/* huecos muertos del markup legacy (mb-5 alrededor del CTA del login) */
body.rxs-ui-v2 .login-register .mb-5 {
    margin-bottom: 12px !important;
}

/* ---- KPI strip (barra fina arriba del listado) en v2 ----
 * El markup base es el mismo del dashboard grande: cards col-xl-2 con sombra fuerte, badge
 * solido y dropdown outline, sobre el degrade de adm.css (#f8f9fa->#e9ecef en claro y el azul
 * acero #2c3e50 en oscuro) que v2 nunca habia pisado. En v2 la tira es UN panel segmentado
 * (el mismo lenguaje que las cajas de KPIs de /dash): fondo del tema, las metricas como
 * celdas separadas por hairlines y los bordes alineados con el modulo de abajo. */
body.rxs-ui-v2 .dashboard-full-container.kpi-compact {
    background: transparent !important;
    padding: 0 !important;
    margin-bottom: 14px;
}

body.rxs-ui-v2 .kpi-compact .dashboard-content > .animate-fade-in > .row,
body.rxs-ui-v2 .kpi-compact .dashboard-content .row.align-items-start {
    margin-left: 0;
    margin-right: 0;
}

/* el panel: una sola caja; las celdas reparten el ancho y siguen wrapeando en angosto.
 * Los divisores son box-shadow hacia arriba/izquierda: los de la primera fila y la primera
 * columna caen afuera y el overflow los recorta, asi no hay que saber donde corta la fila. */
body.rxs-ui-v2 .kpi-compact .dashboard-content .row.align-items-start {
    background: var(--rx-v2-panel);
    border: 1px solid var(--rx-v2-border-soft);
    border-radius: var(--rx-v2-r16);
    box-shadow: 0 1px 2px rgba(16, 24, 40, .04);
    overflow: hidden;
}

body.rxs-ui-v2 .kpi-compact .dashboard-content .row.align-items-start > [class*="col-"] {
    /* 150 y no 170: con el favorito del catalogo + kpi-limit 6 llegan 7 celdas, y en 1440 la
       septima caia sola a un segundo renglon a todo el ancho */
    flex: 1 1 150px;
    max-width: none;
    margin: 0 !important;
    padding: 0;
    box-shadow: -1px 0 0 var(--rx-v2-border-soft), 0 -1px 0 var(--rx-v2-border-soft);
}

/* el panel arranca y termina donde el modulo de abajo (su .box-body pone 5px, el col-12 15) */
body.rxs-ui-v2 .kpi-compact .dashboard-content [class*="col-"]:has(> .row.align-items-start) {
    padding: 0 5px;
}

/* margin-bottom:30px es el .card del tema: con el h-100 dejaba 30px muertos al pie de cada celda */
body.rxs-ui-v2 .kpi-compact .metric-card {
    background: transparent;
    border: 0 !important;
    border-radius: 0;
    box-shadow: none !important;
    margin: 0;
    transition: background-color .15s ease;
}

/* el translateY del hover del dashboard grande hace saltar la barra: solo un tinte */
body.rxs-ui-v2 .kpi-compact .metric-card:hover {
    transform: none;
    box-shadow: none !important;
    background: color-mix(in srgb, var(--rx-v2-accent) 4%, transparent);
}

/* header de la celda: el titulo usa todo el ancho; el "..." y el boton del informe flotan
 * arriba a la derecha (antes reservaban su lugar aun invisibles y el titulo se cortaba) */
body.rxs-ui-v2 .kpi-compact .metric-card .card-header {
    padding: .7rem .95rem .15rem !important;
}

body.rxs-ui-v2 .kpi-compact .metric-card .card-header > .d-flex > .d-flex:last-child {
    position: absolute;
    right: .45rem;
    top: .45rem;
    z-index: 2;
}

body.rxs-ui-v2 .kpi-compact .metric-card .card-header h6 {
    color: var(--rx-v2-muted);
    font-size: .66rem;
    font-weight: 700;
    letter-spacing: .06em;
    margin: 0 !important;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    text-transform: uppercase;
    white-space: nowrap;
}

body.rxs-ui-v2 .kpi-compact .metric-card .card-header .flex-wrap,
body.rxs-ui-v2 .kpi-compact .metric-card .card-header .flex-column {
    min-width: 0;
    max-width: 100%;
}

/* el "..." solo aparece al pasar por la celda (en reposo es ruido en una barra fina) */
body.rxs-ui-v2 .kpi-compact .metric-card .dropdown-toggle {
    border: 0 !important;
    background: transparent !important;
    color: var(--rx-v2-faint) !important;
    opacity: 0;
    transition: opacity .15s ease, color .15s ease;
}

body.rxs-ui-v2 .kpi-compact .metric-card:hover .dropdown-toggle,
body.rxs-ui-v2 .kpi-compact .metric-card .dropdown-toggle:focus,
body.rxs-ui-v2 .kpi-compact .metric-card .show > .dropdown-toggle {
    opacity: 1;
    color: var(--rx-v2-text) !important;
}

body.rxs-ui-v2 .kpi-compact .metric-card .dropdown-toggle::after {
    display: none;
}

/* El botón del informe sigue al "..." : en reposo no existe, aparece al pasar por la cajita.
   Una barra fina con un botón fijo en cada caja es ruido; con el hover, el que lo busca lo
   encuentra donde ya esta mirando. */
body.rxs-ui-v2 .kpi-compact .metric-card .rxs-kpi-golist {
    color: var(--rx-v2-faint) !important;
    opacity: 0;
    transition: opacity .15s ease, color .15s ease;
}

body.rxs-ui-v2 .kpi-compact .metric-card:hover .rxs-kpi-golist,
body.rxs-ui-v2 .kpi-compact .metric-card .rxs-kpi-golist:focus-visible {
    opacity: 1;
    color: var(--rx-v2-accent) !important;
}

body.rxs-ui-v2 .kpi-compact .card-body {
    padding: 0 .95rem .75rem !important;
    min-height: 0;
    justify-content: flex-start !important;
}

body.rxs-ui-v2 .kpi-strip-value {
    color: var(--rx-v2-text);
    font-size: 1.5rem;
    font-variant-numeric: tabular-nums;
    font-weight: 700;
    letter-spacing: -.02em;
    line-height: 1.15;
}

body.rxs-ui-v2 .kpi-strip-sub {
    color: var(--rx-v2-faint) !important;
    font-size: .7rem;
    margin-top: 2px;
}

/* badges de tendencia: pill suave en vez del verde/gris pleno de bootstrap */
body.rxs-ui-v2 .kpi-compact .kpi-strip-metric .trend-badge {
    align-self: center;
    border-radius: 999px;
    font-size: .64rem;
    font-variant-numeric: tabular-nums;
    font-weight: 700;
    padding: .2em .55em;
}

body.rxs-ui-v2 .kpi-compact .kpi-strip-metric .trend-badge.badge-success {
    background: color-mix(in srgb, #2fa36b 14%, transparent) !important;
    color: #23915c !important;
}

body.rxs-ui-v2 .kpi-compact .kpi-strip-metric .trend-badge.badge-danger {
    background: color-mix(in srgb, #d9534f 13%, transparent) !important;
    color: #cf4b46 !important;
}

body.rxs-ui-v2.thr-dark .kpi-compact .kpi-strip-metric .trend-badge.badge-success {
    color: #4cc38a !important;
}

body.rxs-ui-v2.thr-dark .kpi-compact .kpi-strip-metric .trend-badge.badge-danger {
    color: #f07a75 !important;
}

body.rxs-ui-v2 .kpi-compact .kpi-strip-metric .trend-badge.badge-secondary {
    background: var(--rx-v2-ghost) !important;
    color: var(--rx-v2-faint) !important;
}

/* La minilinea es la misma de /dash. Regla de la tira: NADA le suma alto. Va a la DERECHA del
 * numero y del subtitulo (ocupando sus dos renglones) solo cuando la celda tiene ancho para
 * eso; en una celda angosta al lado se encimaba con el badge de tendencia y abajo hacia crecer
 * toda la tira, asi que ahi no se dibuja. La tinta es el acento v2 (rota con ui_accent). */
body.rxs-ui-v2 .kpi-compact .kpi-spark {
    display: none !important;
}

@container rxs-kpi-cell (min-width: 250px) {
    body.rxs-ui-v2 .kpi-compact .kpi-strip-metric:has(> .kpi-spark) {
        align-items: center;
        column-gap: 14px;
        display: grid;
        /* el numero (con su badge) nunca mas angosto que su contenido: la minilinea se queda
           con lo que sobre, hasta 140px, y con numeros enormes se achica en vez de encimarse
           (1/89: "1.303.378.329 +453,9%"). El subtitulo no empuja: contain:inline-size. */
        grid-template-columns: minmax(max-content, 1fr) minmax(0, 140px);
    }

    body.rxs-ui-v2 .kpi-compact .kpi-strip-metric:has(> .kpi-spark) > .kpi-strip-sub {
        contain: inline-size;
    }

    body.rxs-ui-v2 .kpi-compact .kpi-strip-metric:has(> .kpi-spark) > :not(.kpi-spark) {
        grid-column: 1;
        min-width: 0;
    }

    body.rxs-ui-v2 .kpi-compact .kpi-spark {
        color: var(--rx-v2-accent) !important;
        display: block !important;
        grid-column: 2;
        grid-row: 1 / span 2;
        margin: 0 !important;
        position: relative;
        width: 100% !important;
    }

    body.rxs-ui-v2 .kpi-compact .kpi-spark svg {
        display: block;
        height: 30px;
        width: 100%;
    }
}

/* Numero + badge en UN renglon, sin sumar alto: el renglon envuelve pero su alto es el de una
 * linea y recorta, asi que un badge que no entra cae entero al segundo renglon (que no se ve)
 * en vez de salirse de la celda, verse a medias o empujar el subtitulo para abajo. */
body.rxs-ui-v2 .kpi-compact .kpi-strip-metric > .d-flex {
    flex-wrap: wrap !important;
    max-height: 1.75rem;
    min-width: 0;
    overflow: hidden;
}

/* el numero no cede ante el badge, pero tampoco pasa el ancho de la celda: un valor de catalogo
   con unidad ("248 consultas") sin badge se metia en la celda de al lado */
body.rxs-ui-v2 .kpi-compact .kpi-strip-metric > .d-flex > .kpi-strip-value,
body.rxs-ui-v2 .kpi-compact .rxs-kpi-strip-multi .kpi-strip-value {
    flex-shrink: 0;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Una celda de catalogo con VARIOS KPIs (el funnel, "Dev · El periodo": hasta 8) los apilaba y
 * la tira llegaba a 448px. En la tira van en fila, a la izquierda, y solo los que entran en UN
 * renglon: el resto envuelve a un segundo renglon que el max-height deja afuera. Todos estan
 * en "Ver todos"; el title de cada uno dice su nombre completo. */
body.rxs-ui-v2 .kpi-compact .rxs-kpi-strip-multi {
    align-content: flex-start;
    gap: 0 16px;
    justify-content: flex-start;
    max-height: 2.6rem;
    overflow: hidden;
}

body.rxs-ui-v2 .kpi-compact .rxs-kpi-strip-multi > div {
    min-width: 0;
    text-align: left !important;
}

body.rxs-ui-v2 .kpi-compact .rxs-kpi-strip-multi .kpi-strip-value {
    font-size: 1.15rem !important;
    line-height: 1.2;
}

body.rxs-ui-v2 .kpi-compact .rxs-kpi-strip-multi .kpi-strip-sub {
    margin-top: 0;
}

/* El overflow:hidden del panel (redondea las esquinas y recorta los divisores de afuera)
 * cortaba el menu del "...": mientras hay uno abierto, el panel no recorta. */
body.rxs-ui-v2 .kpi-compact .dashboard-content .row.align-items-start:has(.dropdown-menu.show) {
    overflow: visible;
}

/* ...y la tira sube de capa: si no, el modulo de abajo (con su filete de marca) tapa el menu */
body.rxs-ui-v2 .dashboard-full-container.kpi-compact:has(.dropdown-menu.show) {
    position: relative;
    z-index: 30;
}

/* Celda ANCHA (pantallas grandes, o pocos KPIs): una distribucion muestra al lado del numero
 * su top 2 con barra (dos, porque es lo que entra en el alto de numero + subtitulo), que es la MISMA lista "TOP 5 VALORES" que la card de /dash y que ya viene
 * en el DOM de la celda (.data-section, que adm.css esconde en la tira). Solo si tiene mas de
 * una categoria: con una sola, la barra al 100% repite el "todas: X" del subtitulo. */
body.rxs-ui-v2 .kpi-compact .dashboard-content .row.align-items-start > [class*="col-"] {
    container: rxs-kpi-cell / inline-size;
}

@container rxs-kpi-cell (min-width: 330px) {
    body.rxs-ui-v2 .kpi-compact .card-body:has(> .data-section .data-item + .data-item) {
        align-items: start;
        column-gap: 18px;
        display: grid !important;
        grid-template-columns: minmax(0, 1fr) minmax(0, 1.2fr);
    }

    body.rxs-ui-v2 .kpi-compact .card-body > .data-section:has(.data-item + .data-item) {
        display: block !important;
        grid-column: 2;
        grid-row: 1;
        margin: 0 !important;
        min-width: 0;
    }

    body.rxs-ui-v2 .kpi-compact .card-body > .data-section .main-metric,
    body.rxs-ui-v2 .kpi-compact .card-body > .data-section .list-header,
    body.rxs-ui-v2 .kpi-compact .card-body > .data-section .data-item:nth-child(n+4),
    body.rxs-ui-v2 .kpi-compact .card-body > .data-section .data-list > :last-child:not(.data-item) {
        display: none !important;
    }

    body.rxs-ui-v2 .kpi-compact .data-section .data-item {
        color: var(--rx-v2-muted);
        font-size: .7rem;
        line-height: 1.2;
        margin: 0 0 7px !important;
        padding: 0 !important;
    }

    body.rxs-ui-v2 .kpi-compact .data-section .data-item:nth-child(3) {
        margin-bottom: 0 !important;
    }

    body.rxs-ui-v2 .kpi-compact .data-section .data-item .badge {
        background: transparent !important;
        color: var(--rx-v2-text) !important;
        font-size: .7rem;
        font-variant-numeric: tabular-nums;
        font-weight: 600;
        padding: 0;
    }

    body.rxs-ui-v2 .kpi-compact .data-section .data-item .progress {
        background: var(--rx-v2-ghost);
        border-radius: 999px;
        height: 3px !important;
        margin-top: 2px !important;
    }

    body.rxs-ui-v2 .kpi-compact .data-section .data-item .progress-bar {
        background: var(--rx-v2-accent) !important;
        border-radius: 999px;
    }

    body.rxs-ui-v2 .kpi-compact .data-section .data-item + .data-item .progress-bar {
        opacity: .55;
    }
}

/* header de la barra: una linea de rotulo sobre el panel, sin hairline propio */
body.rxs-ui-v2 .kpi-strip-header {
    opacity: 1;
    padding: 0 6px 7px !important;
    margin-bottom: 0 !important;
    border-bottom: 0;
    font-size: .8rem;
}

body.rxs-ui-v2 .kpi-strip-header > div:first-child > .fa-chart-line {
    color: var(--rx-v2-accent) !important;
    font-size: .8rem;
}

body.rxs-ui-v2 .kpi-strip-header > div:first-child > .font-weight-bold {
    color: var(--rx-v2-text);
    font-size: .82rem;
    letter-spacing: -.005em;
}

body.rxs-ui-v2 .kpi-strip-header > div > .badge-light {
    background: var(--rx-v2-ghost);
    border-radius: 999px;
    color: var(--rx-v2-muted);
    font-size: .66rem;
    font-variant-numeric: tabular-nums;
    font-weight: 700;
    padding: .25em .6em;
}

body.rxs-ui-v2 .kpi-strip-header .text-muted.small {
    color: var(--rx-v2-faint) !important;
    font-size: .74rem;
}

body.rxs-ui-v2 .kpi-strip-header .btn-link {
    border-radius: 8px;
    color: var(--rx-v2-muted);
    font-size: .74rem;
    font-weight: 600;
    padding: 2px 8px;
    text-decoration: none;
}

body.rxs-ui-v2 .kpi-strip-header .btn-link:hover {
    background: var(--rx-v2-ghost);
    color: var(--rx-v2-accent);
}

/* "· N sin info para estas fechas  Mostrarlas": el link va como texto del renglon, no como boton */
body.rxs-ui-v2 .kpi-strip-header .kpi-strip-empty .btn-link {
    border-radius: 4px;
    color: var(--rx-v2-accent);
    font-size: inherit;
    font-weight: 600;
    line-height: inherit;
    padding: 0 2px !important;
    vertical-align: baseline;
}

body.rxs-ui-v2 .kpi-strip-header .kpi-strip-empty .btn-link:hover {
    background: transparent;
    text-decoration: underline;
}

/* El corazon de favoritos (.favMeTable, absolute top:48px right:0 del modulo) cae justo sobre
 * "Ver todos" y el chevron: se comia el click y, colapsada, no habia como volver a abrirla. */
body.rxs-ui-v2 .stvModuleTable:has(> .favMeTable) .kpi-strip-header {
    padding-right: 50px !important;
}

/* Colapsada queda solo el renglon del titulo: sin el aire que separa el titulo del panel ni el
 * margen de abajo, y subida contra las pestanas. Pasaba de 64px entre pestanas y tabla. */
body.rxs-ui-v2 .dashboard-full-container.kpi-compact:has(> .dashboard-content:not(.show)) {
    margin-bottom: 2px;
    margin-top: -6px;
}

body.rxs-ui-v2 .kpi-compact:has(> .dashboard-content:not(.show)) > .kpi-strip-header {
    padding-bottom: 0 !important;
}

body.rxs-ui-v2 .kpi-compact:has(> .dashboard-content:not(.show)) > .kpi-strip-header .btn-link {
    padding-bottom: 1px;
    padding-top: 1px;
}

/* con las celdas anchas el valor centrado queda flotando lejos del titulo: alineado a la izq */
body.rxs-ui-v2 .kpi-compact .kpi-strip-metric,
body.rxs-ui-v2 .kpi-compact .kpi-strip-metric > .d-flex,
body.rxs-ui-v2 .kpi-compact .kpi-strip-sub {
    text-align: left !important;
    justify-content: flex-start !important;
}

/* ---- color de fila por estado (clases rowCol-*) ---------------------------------
 * El color lo declara cada tenant en su css como variable, junto al fondo que ya usaba
 * para el admin viejo (ej. custom/amt/csst.css):
 *     .rowCol-ausente { --rx-rowcol: #b93a2f; --rx-rowcol-fg: #FFF;
 *                       background-color: var(--rx-rowcol) !important; color: #FFF !important; }
 * La clase la pone el formattable de la tabla sobre el <tr> a partir del VALOR de la
 * columna de estado, asi que hay filas cuya clase no tiene color declarado: ahi la
 * variable no existe, el fallback del color-mix devuelve el fondo de v2 tal cual y la
 * fila queda como cualquier otra. Por eso v2 mezcla en vez de cederle el fondo al
 * tenant: asi no depende de ganarle en especificidad al zebra del tema (que en varios
 * es !important y mas especifico que .rowCol-x, y le comia el color a las impares).
 * Lo unico que cambia entre modos es cuanto color entra en la mezcla. */

body.rxs-ui-v2 {
    --rx-v2-zebra: var(--rx-v2-panel-2);
    /* v2 normal: apenas un tinte, se lee el estado sin romper el minimalismo. El -2 es el
     * de las filas pares: sin el, dos filas seguidas del mismo estado se leen como una
     * sola mancha y se pierde el renglon. */
    --rx-v2-rowcol-mix: 20%;
    --rx-v2-rowcol-mix-2: 32%;
    --rx-v2-rowcol-mix-hover: 46%;
}

/* "colores vivos": el estado manda, color pleno y el texto que eligio el tenant */
body.rxs-ui-v2.rxs-ui-vivid {
    --rx-v2-rowcol-mix: 100%;
    --rx-v2-rowcol-mix-2: 86%;
    --rx-v2-rowcol-mix-hover: 74%;
}

/* franja del color pleno a la izquierda: es lo que se lee de un golpe cuando el fondo va
 * apenas tinteado. Sin color declarado el gradiente es transparente y no se ve nada.
 * Va en la primera celda y no en el <tr> porque las celdas heredan un fondo opaco que
 * taparia el gradiente de la fila. */
body.rxs-ui-v2 .rxs-module table.rxs-table tbody tr > td:first-child,
body.rxs-ui-v2 .rxs-v2-card {
    background-image: linear-gradient(to right, var(--rx-rowcol, transparent) 0, var(--rx-rowcol, transparent) 3px, transparent 3px) !important;
}

/* la card no tiene zebra: mezcla sobre su propio panel */
body.rxs-ui-v2 .rxs-v2-card {
    background-color: color-mix(in srgb, var(--rx-rowcol, var(--rx-v2-panel)) var(--rx-v2-rowcol-mix), var(--rx-v2-panel)) !important;
}

/* Con color pleno el texto del tema no se lee: pasa a ser el que declaro el tenant
 * (--rx-rowcol-fg), y sin color declarado el fallback deja todo como estaba. */
body.rxs-ui-v2.rxs-ui-vivid .rxs-module table.rxs-table tbody td,
body.rxs-ui-v2.rxs-ui-vivid .rxs-v2-card,
body.rxs-ui-v2.rxs-ui-vivid .rxs-v2-card .rxs-v2-gal-title {
    color: var(--rx-rowcol-fg, var(--rx-v2-text));
}

body.rxs-ui-v2.rxs-ui-vivid .rxs-v2-card .rxs-v2-card-lbl,
body.rxs-ui-v2.rxs-ui-vivid .rxs-v2-card .rxs-v2-gal-desc {
    color: color-mix(in srgb, var(--rx-rowcol-fg, var(--rx-v2-muted)) 72%, transparent);
}

/* separadores internos de la card sobre color pleno */
body.rxs-ui-v2.rxs-ui-vivid .rxs-v2-card[class*="rowCol-"] .rxs-v2-card-line,
body.rxs-ui-v2.rxs-ui-vivid .rxs-v2-card[class*="rowCol-"] .rxs-v2-card-actions {
    border-color: color-mix(in srgb, var(--rx-rowcol-fg, var(--rx-v2-border-soft)) 28%, transparent);
}

/* la caja de acciones de la card trae su propio panel (.stvVueAction): sobre una card
 * con color quedaba un rectangulo blanco flotando */
body.rxs-ui-v2 .rxs-v2-card[class*="rowCol-"] .rxs-v2-card-actions {
    background: transparent !important;
}

/* la card hereda overflow:hidden de .listStvVue .rcol (las cards vue lo necesitan por el
 * redondeo). La v2 no tiene contenido a sangre -- el recorte de los valores largos lo hace
 * .rxs-v2-card-val con su propio overflow -- y ese hidden cortaba el menu de los botones de
 * accion, que se abre fuera de la card. La galeria se queda con el suyo (imagen a sangre).
 * Y el CALENDARIO tambien: ahi la misma card no mide lo que mide su contenido, mide lo que
 * dura el turno, y este `visible` le dejaba a un turno de una hora los ~500px de su ficha
 * dibujados encima de todo lo que tiene debajo. Medido en 1600 (BSM Pilates), 2026-09-02:
 * cajas de 87x72 con 568px adentro, y con 12 reservas a la misma hora la pantalla es una
 * sopa. Se queda con el `overflow: hidden` que ya declara `.rxscal-ev`. */
body.rxs-ui-v2 .rxs-v2-card:not(.rxs-v2-gal):not(.rxscal-ev) {
    overflow: visible;
}

/* El menu de acciones es mas ancho que una card y se abre hacia la izquierda desde su
 * boton: en la primera columna se iba fuera del modulo (que si recorta) y se veia
 * cortado. En la card se ancla a la caja de acciones, que mide lo mismo que la card, asi
 * que no puede pasarse de su borde: en vez de desbordar, envuelve en varias filas. */
body.rxs-ui-v2 .rxs-v2-card .rxs-v2-card-actions {
    position: relative;
}

body.rxs-ui-v2 .rxs-v2-card .rxs-v2-card-actions .btn-group {
    position: static;
}

body.rxs-ui-v2 .rxs-v2-card .rxs-v2-card-actions .dropdown-menu {
    flex-wrap: wrap;
    justify-content: flex-end;
    left: auto;
    max-width: 100%;
    right: 0;
}

/* =========================================================================
   v2 pass 26: .btn-themecolor como BOTON (el gradiente crudo de marca)
   =========================================================================
   custom.css pinta .btn-themecolor con el degrade var(--rx-color1) ->
   var(--rx-color2) con !important (y el hover al reves), sin pasar nunca por
   los tokens v2. Con una marca saturada (ej cyan #00e8cd -> violeta #8a2ac5)
   los botones quedan gritando y, sobre todo, NO se parecen a la topbar ni al
   menu, que en v2 si estan tokenizados. Hasta ahora se venia arreglando caso
   por caso (chat, barra QR, favoritos flotantes, acciones de fila): esto lo
   generaliza.

   Se keyea en .btn.btn-themecolor a proposito: la clase tambien se usa como
   SUPERFICIE (card-header, .rpanel-title del menu de servicio, .nof-icon, la
   barra de progreso del helper) y esos markups NO llevan .btn -- si se pisara
   la clase pelada se aplanarian todos.

   Excepciones:
   - .allFiltersBtn ("Busqueda"): no es un CTA, es chrome de la barra de
     herramientas y v2 ya lo dibuja ghost (~L4772) con el icono y el estado
     abierto en accent. Como esta regla va despues y con la misma
     especificidad, le ganaba el fondo -> icono accent sobre fondo accent
     (invisible) y, con la barra abierta, texto accent sobre accent.
   - .badge.btn-themecolor (chips tipo .rxsTagFilter): no llevan .btn y se
     quedaban con el degrade crudo de v1; entran por su propio selector. */
body.rxs-ui-v2 .btn.btn-themecolor:not(.allFiltersBtn),
body.rxs-ui-v2 .badge.btn-themecolor,
body.rxs-ui-v2 .btn.btn-themecolor.disabled:not(.allFiltersBtn) {
    background: var(--rx-v2-accent) !important;
    background-image: none !important;
    border: 0 !important;
    color: var(--rx-v2-accent-ink) !important;
    transition: filter .16s ease, box-shadow .16s ease, transform .16s ease;
}

body.rxs-ui-v2 .btn.btn-themecolor:not(.allFiltersBtn):hover,
body.rxs-ui-v2 .badge.btn-themecolor:hover,
body.rxs-ui-v2 .btn.btn-themecolor:not(.allFiltersBtn):focus {
    background: var(--rx-v2-accent) !important;
    background-image: none !important;
    color: var(--rx-v2-accent-ink) !important;
    filter: brightness(1.08);
}

/* ---- Colores vivos: el CTA lleva la marca, igual que topbar y sidebar ----
   En vivid el chrome es el degrade de marca (--rx-v2-vivid-shell); un boton
   flat accent al lado se lee como de otra UI, asi que el boton tambien va con
   degrade de marca.

   Pero un degrade crudo color1 -> color2 no se puede escribir encima: los dos
   extremos pueden tener luminancias opuestas (el caso que disparo esto: cyan
   #00e8cd l=.84 y violeta #8a2ac5 l=.42 -> no hay tinta que sirva para los
   dos). Se conserva el TONO y el croma de la marca y se le fija la luminancia
   a los dos extremos en una banda donde el blanco siempre lee (~4:1 y 5:1).
   Asi el boton es de marca, es legible con cualquier marca, y no hace falta
   calcular la tinta. La mezcla con #12151b del shell no se usa: apagaria el
   color justo en la pieza que tiene que resaltar. */
body.rxs-ui-v2.rxs-ui-vivid {
    --rx-v2-vivid-btn: linear-gradient(118deg, var(--rx-v2-vivid-b), var(--rx-v2-vivid-a));
}
@supports (color: oklch(from red l c h)) {
    body.rxs-ui-v2.rxs-ui-vivid {
        --rx-v2-vivid-btn: linear-gradient(118deg,
            oklch(from var(--rx-v2-vivid-b) .44 c h),
            oklch(from var(--rx-v2-vivid-a) .54 c h));
    }
}

body.rxs-ui-v2.rxs-ui-vivid .btn.btn-themecolor:not(.allFiltersBtn),
body.rxs-ui-v2.rxs-ui-vivid .btn.btn-themecolor.disabled:not(.allFiltersBtn),
body.rxs-ui-v2.rxs-ui-vivid .btn.btn-themecolor:not(.allFiltersBtn):hover,
body.rxs-ui-v2.rxs-ui-vivid .btn.btn-themecolor:not(.allFiltersBtn):focus,
body.rxs-ui-v2.rxs-ui-vivid .badge.btn-themecolor,
body.rxs-ui-v2.rxs-ui-vivid .badge.btn-themecolor:hover {
    background: var(--rx-v2-vivid-btn) !important;
    background-image: var(--rx-v2-vivid-btn) !important;
    color: #fff !important;
}

/* ============ pass 23e: layout horizontal (menu en cabecera) ============
 * En body.horizontal (preferencia "Menu Cabezera") no hay rail: el .left-sidebar
 * es una barra FIJA full-width arriba y el menu vive ahi, en una o dos filas.
 * El shell flotante de pass 23c asume rail y ahi rompia dos cosas: la topbar
 * arrancaba en left:252px (franja muerta del ancho del rail a la izquierda) y
 * el sidebar, que dejo de reservar los 70px de la topbar, quedaba DEBAJO de
 * ella con la primera fila de items tapada.
 * La barra de menu pasa a estar EN FLUJO (position:static, dentro de
 * .stvVueAdapter, que es hermano anterior de .rxs-wrp): asi el contenido
 * arranca siempre despues del menu ocupe las filas que ocupe. El legacy lo
 * compensaba con un padding fijo y con dos filas se comia el contenido. */
/* index.php (~L594) le da al <main> la clase `container` pelada en horizontal (en el
 * resto es `container-fluid`), asi que bootstrap le clava max-width 1140px en >=1200 y
 * el contenido queda angosto contra una barra de menu que si es full width. En v2 el
 * shell ya pone sus propios margenes: el ancho lo maneja el, no el container. */
body.rxs-ui-v2.horizontal #maincontent.container {
    max-width: none;
}
@media (min-width: 768px) {
    body.rxs-ui-v2.horizontal.fix-header .topbar {
        left: 12px;
        right: 12px;
    }
    body.rxs-ui-v2.horizontal.fix-header:not(.thr-fix) .topbar {
        margin-left: 12px;
    }
    /* margin-top 24: el theme ya pone body{padding-top:60px} por la topbar
     * fija, y la barra flotante termina en 72px (10 de top + 62 de alto), asi
     * que 60+24 deja los mismos 12px que los costados */
    body.rxs-ui-v2.horizontal .left-sidebar {
        background: var(--rx-v2-panel);
        border: 1px solid var(--rx-v2-border-soft);
        border-radius: var(--rx-v2-r14);
        box-shadow: var(--rx-v2-shadow);
        height: auto;
        /* el scroller es el BODY (overflow-y:auto), asi que su barra de scroll
         * le come ~8px al ancho en flujo pero NO a la topbar, que es fixed y
         * mide contra el viewport: la barra de menu terminaba 8px antes que la
         * topbar justo abajo suyo. (100vw - 100%) = ese ancho, 0 si no hay. */
        margin: 24px calc(12px - (100vw - 100%)) 0 12px;
        padding: 4px 8px;
        position: static;
        width: auto;
    }
    /* debajo de 1024 el theme agrega .mini-sidebar (pensado para el rail) y ahi
     * el scroll-sidebar pasa a absolute: la barra se quedaba sin alto (10px) y
     * el menu se montaba sobre el contenido. En horizontal no hay rail que
     * colapsar, asi que vuelve al flujo */
    body.rxs-ui-v2.horizontal .scroll-sidebar {
        padding: 0;
        position: static;
    }
    /* y el resto del rail colapsado tampoco aplica: ancho fijo de 60px, item de
     * 50px que se estira a 380 en hover, label escondido y chevron apagado. En
     * la barra los items miden lo que su texto, siempre */
    body.rxs-ui-v2.horizontal.mini-sidebar .left-sidebar {
        width: auto;
    }
    body.rxs-ui-v2.horizontal.mini-sidebar .sidebar-nav #sidebarnav > li > a,
    body.rxs-ui-v2.horizontal.mini-sidebar .sidebar-nav #sidebarnav > li:hover > a {
        width: auto;
    }
    body.rxs-ui-v2.horizontal.mini-sidebar .sidebar-nav #sidebarnav > li > a .hide-menu {
        display: inline;
    }
    body.rxs-ui-v2.horizontal.mini-sidebar .sidebar-nav #sidebarnav > li > a.has-arrow::after {
        display: block;
    }
    body.rxs-ui-v2.horizontal.mini-sidebar .sidebar-nav #sidebarnav > li > ul {
        left: auto;
        top: auto;
        width: 260px;
    }
    body.rxs-ui-v2.horizontal .page-wrapper {
        padding-top: 14px;
    }
    /* items de la barra: la mitad del aire vertical que en el rail. El
     * position:relative ancla el submenu flotante al ITEM: hasta ahora el unico
     * positioned de la cadena era el aside, y al sacarlo del fixed el absolute
     * se hubiera ido al bloque inicial */
    body.rxs-ui-v2.horizontal .sidebar-nav #sidebarnav > li {
        padding: 2px 0;
        position: relative;
    }
    body.rxs-ui-v2.horizontal .sidebar-nav #sidebarnav > li > a {
        margin: 0;
        min-height: 34px;
        padding: 6px 10px;
    }
    /* el chevron de los grupos es absolute a right:13.5px, pensado para un link
     * que ocupa todo el rail; en la barra el link mide lo que el texto y le
     * caia encima de la ultima letra. Ademas apunta hacia abajo, que es lo que
     * se espera de un menu de cabecera (en el rail apunta a la derecha) */
    body.rxs-ui-v2.horizontal .sidebar-nav #sidebarnav > li > a.has-arrow {
        padding-right: 26px;
    }
    body.rxs-ui-v2.horizontal .sidebar-nav #sidebarnav > li > a.has-arrow::after {
        right: 10px;
        transform: rotate(45deg) translate(0, 0);
    }
    /* el dropdown flota sobre el contenido (panel claro): el texto va en color
     * de panel, no el blanco que vivid usa para los links apoyados sobre el
     * gradiente de la barra -- quedaba blanco sobre blanco, invisible */
    body.rxs-ui-v2.horizontal .sidebar-nav #sidebarnav > li > ul a,
    body.rxs-ui-v2.horizontal .sidebar-nav #sidebarnav > li > ul a i,
    body.rxs-ui-v2.rxs-ui-vivid.horizontal .left-sidebar .sidebar-nav #sidebarnav > li > ul a,
    body.rxs-ui-v2.rxs-ui-vivid.horizontal .left-sidebar .sidebar-nav #sidebarnav > li > ul a i {
        color: var(--rx-v2-text) !important;
    }
    body.rxs-ui-v2.horizontal .sidebar-nav #sidebarnav > li > ul a:hover {
        background: var(--rx-v2-ghost);
    }
    body.rxs-ui-v2.horizontal .sidebar-nav #sidebarnav > li > ul li.active > a {
        background: var(--rx-v2-accent-soft) !important;
    }
}

/* El flyout del rail (mini-sidebar) es una superficie clara independiente.
   current48 le aplica el gradiente de marca a la ul completa y vivid fuerza
   iconos blancos; ambos quedan sin contraste en este panel. */
@media (min-width: 768px) {
    body.rxs-ui-v2.mini-sidebar .left-sidebar .sidebar-nav #sidebarnav > li > ul,
    body.rxs-ui-v2.mini-sidebar .left-sidebar .sidebar-nav #sidebarnav > li > ul.treeview-menu,
    body.rxs-ui-v2.mini-sidebar .left-sidebar .sidebar-nav #sidebarnav > li > ul.treeview-menu.collapse {
        background: var(--rx-v2-panel) !important;
        background-image: none !important;
    }

    body.rxs-ui-v2.mini-sidebar .left-sidebar .sidebar-nav #sidebarnav > li > ul li a,
    body.rxs-ui-v2.mini-sidebar .left-sidebar .sidebar-nav #sidebarnav > li > ul li a:not(:hover),
    body.rxs-ui-v2.mini-sidebar .left-sidebar .sidebar-nav #sidebarnav > li > ul li a i,
    body.rxs-ui-v2.rxs-ui-vivid.mini-sidebar .left-sidebar .sidebar-nav #sidebarnav > li > ul li a,
    body.rxs-ui-v2.rxs-ui-vivid.mini-sidebar .left-sidebar .sidebar-nav #sidebarnav > li > ul li a i {
        color: var(--rx-v2-muted) !important;
        text-shadow: none;
    }

    body.rxs-ui-v2.mini-sidebar .left-sidebar .sidebar-nav #sidebarnav > li > ul li a:hover,
    body.rxs-ui-v2.mini-sidebar .left-sidebar .sidebar-nav #sidebarnav > li > ul li.active > a {
        background: var(--rx-v2-accent-soft) !important;
        color: var(--rx-v2-text) !important;
    }

    body.rxs-ui-v2.mini-sidebar .left-sidebar .sidebar-nav #sidebarnav > li > ul li a:hover i,
    body.rxs-ui-v2.mini-sidebar .left-sidebar .sidebar-nav #sidebarnav > li > ul li.active > a i {
        color: var(--rx-v2-accent) !important;
    }

    /* custom.css tambien colorea cada li del treeview en el rail; no alcanza
       con quitar el fondo de la ul contenedora. */
    body.rxs-ui-v2.mini-sidebar .left-sidebar .sidebar-nav #sidebarnav ul.treeview-menu > li,
    body.rxs-ui-v2.mini-sidebar .left-sidebar .sidebar-nav #sidebarnav ul.treeview-menu > li > a {
        background: transparent !important;
        background-image: none !important;
    }

    /* El menu de cada categoria (Stock, Assets, etc.) es un treeview anidado
       dentro del flyout ERP; el selector del primer nivel no lo alcanza. */
    body.rxs-ui-v2.mini-sidebar .left-sidebar .sidebar-nav #sidebarnav ul.treeview-menu,
    body.rxs-ui-v2.mini-sidebar .left-sidebar .sidebar-nav #sidebarnav ul.treeview-menu.collapse {
        background: var(--rx-v2-panel) !important;
        background-image: none !important;
    }

    /* Los grupos anidados del flyout (Assets, Stock, etc.) conservan un
       indicador visible aunque el shell general vivid use chevrons blancos. */
    body.rxs-ui-v2.mini-sidebar .left-sidebar .sidebar-nav #sidebarnav ul.treeview-menu .has-arrow::after {
        border-color: var(--rx-v2-faint) !important;
        opacity: .9;
    }
}

/* ============ pass 27: filtro de fecha del dashboard ============
 * El grupo del dash (.filterStv > .input-group con input.dateFilter) no vive dentro de
 * .rxs-module, asi que no lo alcanzaba el tratamiento de .rxs-filter-field: el chip del
 * icono queda absolute con 36px (current49) mientras el input es un input PELADO de 29px
 * -> chip mas alto que el campo, y la "Periodicidad" cae abajo sin alinear con nada. */
/* la columna que lo contiene es un col de bootstrap y su padding metia la tarjeta 15px
 * adentro: arrancaba a la derecha del panel del dashboard que va justo abajo (que empieza
 * en el borde del .container-fluid). Sin padding, los dos bordes quedan a plomo. */
body.rxs-ui-v2 .filterStv.rxs-v2-fdate {
    padding-left: 0;
    padding-right: 0;
}

/* ademas va en una tarjeta propia: suelto sobre el fondo de la pagina (el pane del dash
 * ya trae su propio card y no lo alcanza el panel de los tab-pane) quedaba flotando */
body.rxs-ui-v2 .input-group.rxs-v2-igdate {
    align-items: center;
    background: var(--rx-v2-panel);
    border: 1px solid var(--rx-v2-border);
    border-radius: var(--rx-v2-r12);
    box-shadow: var(--rx-v2-shadow);
    column-gap: 10px;
    flex-wrap: wrap;
    max-width: 100%;
    padding: 10px 12px;
    row-gap: 8px;
}

/* el chip es absolute (current49) y sin top/left cae en su posicion estatica, que con el
 * grupo en dos lineas queda centrado entre ambas: lo clavamos a la linea del campo */
body.rxs-ui-v2 .input-group.rxs-v2-igdate > .input-group-prepend {
    height: 38px;
    left: 12px;
    top: 10px;
    width: 38px;
}

body.rxs-ui-v2 .input-group.rxs-v2-igdate > .input-group-prepend > .input-group-text {
    border: 0;
    border-radius: var(--rx-v2-r10);
    font-size: 15px;
    height: 100%;
    justify-content: center;
    padding: 0;
    width: 100%;
}

/* el margin-left lo pone el JS inline (deja lugar al chip absolute): lo igualamos al
 * ancho del chip + el gap para que el campo arranque justo despues */
body.rxs-ui-v2 .input-group > input.dateFilter {
    background: var(--rx-v2-field);
    border: 1px solid var(--rx-v2-border);
    border-radius: var(--rx-v2-r10);
    color: var(--rx-v2-text);
    font-size: 13px;
    height: 38px;
    margin-left: 48px !important;
    padding: 0 12px;
}

body.rxs-ui-v2 .input-group > input.dateFilter:focus {
    border-color: var(--rx-v2-accent);
    outline: 0;
}

body.rxs-ui-v2 .input-group.rxs-v2-igdate > .text-right,
body.rxs-ui-v2 .input-group.rxs-v2-igdate > .text-end {
    align-items: center;
    color: var(--rx-v2-muted);
    display: flex;
    font-size: 12px;
    gap: 8px;
    margin-left: 48px;
    padding: 0 !important;
}

body.rxs-ui-v2 .input-group.rxs-v2-igdate select.timedg {
    background: var(--rx-v2-field);
    border: 1px solid var(--rx-v2-border);
    border-radius: var(--rx-v2-r10);
    color: var(--rx-v2-text);
    font-size: 13px;
    height: 34px;
    padding: 0 8px;
    width: auto;
}

/* ============ pass 28: scroll horizontal de la grilla ancha ============
 * Con noresp=1 el JS deja la tabla como bloque scrolleable (rxsTableLarge). El scroll
 * existe pero la barra es la del sistema y pasa desapercibida: al desplegar las columnas
 * vacias parece que las de la derecha "no estan". Barra fina y tokenizada. */
body.rxs-ui-v2 .rxsTableLarge table {
    scrollbar-color: var(--rx-v2-border) transparent;
    scrollbar-width: thin;
}

body.rxs-ui-v2 .rxsTableLarge table::-webkit-scrollbar {
    height: 10px;
}

body.rxs-ui-v2 .rxsTableLarge table::-webkit-scrollbar-thumb {
    background: var(--rx-v2-border);
    border: 2px solid transparent;
    background-clip: padding-box;
    border-radius: var(--rx-v2-r10);
}

body.rxs-ui-v2 .rxsTableLarge table::-webkit-scrollbar-thumb:hover {
    background: var(--rx-v2-faint);
    background-clip: padding-box;
}

/* ============ pass 29: footer de la grilla, una fila mas ============
 * El footer era un grid de 3 columnas (info | mostrar | paginador) y los botones de
 * exportacion, que son el 4to hijo, caian SIEMPRE a una fila propia aunque al lado del
 * "Mostrando de..." sobrara lugar. Con flex + wrap se acomodan solos: entran al lado del
 * info cuando entran, y recien wrapean cuando de verdad no hay ancho. */
body.rxs-ui-v2 .rxs-module .rxs-table-footer {
    align-items: center;
    display: flex;
    flex-wrap: wrap;
    gap: 10px 18px;
}

body.rxs-ui-v2 .rxs-module .rxs-table-footer .dataTables_info {
    flex: 0 1 auto;
    order: 1;
}

body.rxs-ui-v2 .rxs-module .rxs-table-footer .dt-buttons {
    order: 2;
}

/* mostrar + paginador vuelven a ser un bloque (venian con display:contents, que los
 * dejaba wrapear por separado y el paginador terminaba solo en una fila): asi el par
 * viaja junto y el margin-left:auto lo pega al borde derecho, este donde este */
body.rxs-ui-v2 .rxs-module .rxs-table-footer .rxs-table-footer-right {
    align-items: center;
    display: flex;
    flex-wrap: wrap;
    gap: 6px 14px;
    margin-left: auto;
    order: 3;
}

/* el <label> del "Mostrar N registros" heredaba la tipografia de label de los forms v2
 * (14px/500) y quedaba mas grande y mas negra que el "Mostrando de ..." de al lado */
body.rxs-ui-v2 .rxs-module .rxs-table-footer .dataTables_length label {
    font-size: inherit;
    font-weight: inherit;
    letter-spacing: normal;
    text-transform: none;
}

@media (max-width: 767px) {
    body.rxs-ui-v2 .rxs-module .rxs-table-footer {
        justify-content: center;
    }

    body.rxs-ui-v2 .rxs-module .rxs-table-footer .rxs-table-footer-right {
        justify-content: center;
        margin-left: 0;
    }
}

/* ============================================================================
   Vista tablero (kanban) de la grilla v2
   Las mismas cards de la vista cards, repartidas en carriles por un campo. El
   carril scrollea solo; la fila de carriles scrollea en horizontal.
   ========================================================================= */

body.rxs-ui-v2 .rxsV2Board {
    margin-top: 6px;
}

body.rxs-ui-v2 .rxs-v2-board-bar {
    align-items: center;
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    margin-bottom: 10px;
}

body.rxs-ui-v2 .rxs-v2-board-lbl {
    color: var(--rx-v2-muted);
    font-size: 12px;
    font-weight: 600;
    margin: 0;
    text-transform: uppercase;
    letter-spacing: .02em;
}

body.rxs-ui-v2 .rxs-v2-board-bar .rxsV2BoardSel,
body.rxs-ui-v2 .rxs-v2-board-bar .rxsV2BoardSwimSel {
    background: var(--rx-v2-field);
    border: 1px solid var(--rx-v2-border);
    border-radius: var(--rx-v2-r8);
    color: var(--rx-v2-text);
    font-size: 13px;
    height: 32px;
    max-width: 220px;
    width: auto;
}

body.rxs-ui-v2 .rxs-v2-board-chk {
    align-items: center;
    color: var(--rx-v2-muted);
    display: flex;
    font-size: 12px;
    gap: 6px;
    margin: 0;
}

body.rxs-ui-v2 .rxs-v2-board-note {
    color: var(--rx-v2-faint);
    font-size: 12px;
    margin-left: auto;
}

body.rxs-ui-v2 .rxs-v2-board-load {
    color: var(--rx-v2-muted);
    padding: 40px;
    text-align: center;
}

/* Repintado en curso (cambio de campo, de vacios o "Ver todos"): el tablero que ya esta
   dibujado se atenua y no se puede tocar, con el mismo spinner que la carga inicial. */
body.rxs-ui-v2 .rxsV2Board.rxs-v2-board-busy {
    position: relative;
}

body.rxs-ui-v2 .rxsV2Board.rxs-v2-board-busy > *:not(.rxs-v2-board-load) {
    opacity: .35;
    pointer-events: none;
}

body.rxs-ui-v2 .rxsV2Board.rxs-v2-board-busy > .rxs-v2-board-load {
    font-size: 22px;
    left: 0;
    padding: 70px 0 0;
    position: absolute;
    right: 0;
    top: 0;
    z-index: 3;
}

body.rxs-ui-v2 .rxs-v2-board-lanes {
    align-items: flex-start;
    display: flex;
    gap: 12px;
    overflow-x: auto;
    padding-bottom: 10px;
}

/* Segundo eje (swimlanes): una banda por valor del campo de filas, y adentro los MISMOS
   carriles. El scroll horizontal es uno solo, el de la banda exterior: si scrolleara cada fila
   por su cuenta, las columnas de una fila y otra dejarian de estar alineadas, que es lo unico
   que hace legible un tablero de dos ejes. */
body.rxs-ui-v2 .rxs-v2-board-swims {
    overflow-x: auto;
    padding-bottom: 10px;
}

body.rxs-ui-v2 .rxs-v2-board-swims .rxs-v2-board-lanes {
    overflow: visible;
    padding-bottom: 0;
    width: max-content;
}

body.rxs-ui-v2 .rxs-v2-swim {
    border-top: 1px solid var(--rx-v2-border-soft);
    padding: 8px 0 14px;
}

body.rxs-ui-v2 .rxs-v2-swim:first-child {
    border-top: 0;
    padding-top: 0;
}

/* La cabecera de la fila queda pegada a la izquierda mientras se scrollea en horizontal: sin
   esto, al llegar a la ultima columna ya no se sabe de quien es la fila. */
body.rxs-ui-v2 .rxs-v2-swim-head {
    align-items: center;
    background: var(--rx-v2-bg);
    display: flex;
    gap: 8px;
    left: 0;
    margin-bottom: 6px;
    max-width: 100%;
    padding: 4px 2px;
    position: sticky;
    width: max-content;
}

body.rxs-ui-v2 .rxs-v2-swim-name {
    border-left: 3px solid hsl(var(--rxp, 220) 60% 48% / .75);
    color: var(--rx-v2-text);
    font-size: 13px;
    font-weight: 700;
    max-width: 40vw;
    overflow: hidden;
    padding-left: 8px;
    text-overflow: ellipsis;
    white-space: nowrap;
}

body.rxs-ui-v2 .rxs-v2-swim-n {
    background: hsl(var(--rxp, 220) 45% 45% / .16);
    border-radius: 999px;
    color: var(--rx-v2-text);
    flex: 0 0 auto;
    font-size: 11px;
    font-weight: 600;
    padding: 1px 8px;
}

/* En un tablero de dos ejes cada carril es una celda de la grilla, no una columna de pantalla
   completa: si conservaran el alto de siempre, entrarian una fila y media. */
body.rxs-ui-v2 .rxs-v2-board-swims .rxs-v2-lane {
    max-height: 42vh;
}

/* Cada carril lleva el tono de su valor (--rxp lo pone g.js con el mismo pillHue que las
   pills, ver rxsV2LaneHue), para que se distingan de un vistazo sin pintarlos de colores
   fuertes: el color va en el fondo, el borde y la cabecera, siempre muy diluido. */
body.rxs-ui-v2 .rxs-v2-lane {
    background: hsl(var(--rxp, 220) 45% 50% / .05);
    border: 1px solid hsl(var(--rxp, 220) 45% 45% / .18);
    border-radius: var(--rx-v2-r14);
    display: flex;
    flex: 0 0 280px;
    flex-direction: column;
    max-height: 72vh;
    width: 280px;
}

body.rxs-ui-v2 .rxs-v2-lane::before {
    background: hsl(var(--rxp, 220) 60% 48% / .75);
    border-radius: var(--rx-v2-r14) var(--rx-v2-r14) 0 0;
    content: "";
    display: block;
    height: 3px;
}

body.rxs-ui-v2.thr-dark .rxs-v2-lane {
    background: hsl(var(--rxp, 220) 40% 50% / .08);
    border-color: hsl(var(--rxp, 220) 40% 55% / .2);
}

body.rxs-ui-v2 .rxs-v2-lane-head {
    align-items: center;
    background: hsl(var(--rxp, 220) 45% 50% / .10);
    border-bottom: 1px solid var(--rx-v2-border-soft);
    display: flex;
    gap: 8px;
    justify-content: space-between;
    padding: 10px 12px;
    position: sticky;
    top: 0;
}

body.rxs-ui-v2 .rxs-v2-lane-name {
    color: var(--rx-v2-text);
    font-size: 12.5px;
    font-weight: 600;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

body.rxs-ui-v2 .rxs-v2-lane-n {
    background: hsl(var(--rxp, 220) 45% 45% / .16);
    border-radius: 999px;
    color: var(--rx-v2-text);
    flex: 0 0 auto;
    font-size: 11px;
    font-weight: 600;
    padding: 1px 8px;
}

/* Contador + totales de las columnas que suman (options.sum=1, las mismas del pie de la
   grilla): un tablero de oportunidades quiere ver la plata por etapa, no solo cuantas cards. */
body.rxs-ui-v2 .rxs-v2-lane-tot {
    align-items: center;
    display: flex;
    flex: 0 0 auto;
    gap: 5px;
}

body.rxs-ui-v2 .rxs-v2-lane-sum {
    color: var(--rx-v2-text-soft, inherit);
    font-size: 11.5px;
    font-weight: 600;
    opacity: .85;
    white-space: nowrap;
}

/* Carril pasado de tope (WIP limit, json kanban_wip): el contador dice "n/tope" y el carril se
   marca en rojo. Pisa el tono del valor solo en el borde y la cabecera: el fondo del carril
   sigue siendo el del valor, si no un tablero con tres carriles pasados se lee todo rojo. */
body.rxs-ui-v2 .rxs-v2-lane.rxs-v2-lane-over {
    border-color: hsl(0 70% 50% / .45);
}

body.rxs-ui-v2 .rxs-v2-lane.rxs-v2-lane-over::before {
    background: hsl(0 72% 50% / .85);
}

body.rxs-ui-v2 .rxs-v2-lane.rxs-v2-lane-over .rxs-v2-lane-head {
    background: hsl(0 70% 50% / .12);
}

/* El contador va en rojo SOLIDO, no teñido: hay valores cuyo propio tono ya es rojizo (un
   carril "No"), y un fondo diluido no distinguiria "pasado de tope" de "asi es su color". */
body.rxs-ui-v2 .rxs-v2-lane.rxs-v2-lane-over .rxs-v2-lane-n {
    background: hsl(0 72% 46%);
    color: #fff;
}

/* Carril plegado: queda una columna angosta con el nombre de canto y el contador. */
body.rxs-ui-v2 .rxs-v2-lane-head {
    cursor: pointer;
}

body.rxs-ui-v2 .rxs-v2-lane.rxs-v2-lane-fold {
    flex: 0 0 44px;
    width: 44px;
}

body.rxs-ui-v2 .rxs-v2-lane.rxs-v2-lane-fold .rxs-v2-lane-head {
    flex-direction: column;
    gap: 10px;
    justify-content: flex-start;
    padding: 10px 4px;
}

body.rxs-ui-v2 .rxs-v2-lane.rxs-v2-lane-fold .rxs-v2-lane-name {
    max-height: 220px;
    writing-mode: vertical-rl;
}

body.rxs-ui-v2 .rxs-v2-lane.rxs-v2-lane-fold .rxs-v2-lane-body,
body.rxs-ui-v2 .rxs-v2-lane.rxs-v2-lane-fold .rxs-v2-lane-sum {
    display: none;
}

body.rxs-ui-v2 .rxs-v2-lane-body {
    display: flex;
    flex-direction: column;
    gap: 8px;
    min-height: 60px;
    overflow-y: auto;
    padding: 10px;
}

body.rxs-ui-v2 .rxs-v2-board-card {
    font-size: 12.5px;
    padding: 10px 12px;
    /* Un carril puede tener cientos de cards y cada card son ~20 nodos. Con esto el motor no
       maqueta ni pinta las que estan fuera de la pantalla (siguen midiendo con el tamano
       estimado, que es lo que necesita el arrastre para ubicar el hueco). */
    content-visibility: auto;
    contain-intrinsic-size: auto 220px;
}

body.rxs-ui-v2 .rxs-v2-board-card.rxs-v2-board-drag {
    cursor: grab;
}

body.rxs-ui-v2 .rxs-v2-board-card.rxs-v2-board-drag:active {
    cursor: grabbing;
}

/* mientras el update viaja, la card queda apagada: si falla, vuelve a su carril */
body.rxs-ui-v2 .rxs-v2-board-card.rxs-v2-board-saving {
    opacity: .5;
    pointer-events: none;
}

/* hueco donde va a caer la card */
body.rxs-ui-v2 .rxs-v2-board-ph {
    background: hsl(var(--rxp, 220) 50% 50% / .10);
    border: 1px dashed hsl(var(--rxp, 220) 55% 50% / .55);
    border-radius: var(--rx-v2-r12);
    flex: 0 0 auto;
}

/* la card original queda en su lugar pero invisible: sacarla del DOM al empezar obligaria a
   re-medir todo el carril */
body.rxs-ui-v2 .rxs-v2-board-ghost {
    display: none !important;
}
body.rxs-ui-v2 .rxs-v2-board-helper {
    left: 0;
    opacity: .95;
    pointer-events: none;
    position: fixed;
    top: 0;
    transform: translate3d(-9999px, -9999px, 0);
    transition: none;
    will-change: transform;
    z-index: 4000;
}

body.rxs-ui-v2 .rxs-v2-board-helper {
    box-shadow: 0 18px 38px rgba(18, 25, 33, .28);
    cursor: grabbing;
    rotate: 1.5deg;
}

@media (max-width: 576px) {
    body.rxs-ui-v2 .rxs-v2-lane {
        flex: 0 0 82vw;
        width: 82vw;
    }
}

/* ============ v2 pass 31: consistencia de controles + jerarquia de cards (2026-08-22) ============
 * P3 de docs/frontend/ui-v2.md. Lo que se veia: selects nativos con chevron del browser al
 * lado de select2 tokenizados (form, "Mostrar N", barra del tablero); el boton naranja v1
 * "Modificacion masiva" junto al CTA "Crear filtro"; 10 iconos de export/colvis en fila
 * plana; el kebab de fila con cuadraditos sin verbo; las cards como lista "ETIQUETA valor"
 * sin titulo. */

/* --- select nativo: mismo cuerpo que el select2 (fondo/borde/radio ya venian de pass 9c),
 *     sin el chevron del sistema y con uno propio. `multiple`/`size` quedan como listas. --- */
body.rxs-ui-v2 #maincontent select:not(.select2-hidden-accessible):not([class*="yadcf"]):not([multiple]):not([size]),
body.rxs-ui-v2 .modal select:not(.select2-hidden-accessible):not([class*="yadcf"]):not([multiple]):not([size]),
body.rxs-ui-v2 .rxs-module .dataTables_length select,
body.rxs-ui-v2 .rxs-v2-board-bar select {
    -webkit-appearance: none !important;
    appearance: none !important;
    background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath d='M2.5 4.5 6 8l3.5-3.5' fill='none' stroke='%236b7280' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") !important;
    background-position: right 10px center !important;
    background-repeat: no-repeat !important;
    background-size: 12px 12px !important;
    padding-right: 30px !important;
}
body.rxs-ui-v2.thr-dark #maincontent select:not(.select2-hidden-accessible):not([class*="yadcf"]):not([multiple]):not([size]),
body.rxs-ui-v2.thr-dark .modal select:not(.select2-hidden-accessible):not([class*="yadcf"]):not([multiple]):not([size]),
body.rxs-ui-v2.thr-dark .rxs-module .dataTables_length select,
body.rxs-ui-v2.thr-dark .rxs-v2-board-bar select {
    background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath d='M2.5 4.5 6 8l3.5-3.5' fill='none' stroke='%239aa4b2' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") !important;
}
/* el select del form: misma altura/tipografia que el input de al lado y el mismo foco */
body.rxs-ui-v2 form.rxs-form .rxs-field select.form-control:not(.select2-hidden-accessible) {
    font-size: 14px;
    height: 38px;
    line-height: 1.3;
    padding-top: 6px;
    padding-bottom: 6px;
}
body.rxs-ui-v2 #maincontent select:not(.select2-hidden-accessible):focus,
body.rxs-ui-v2 .modal select:not(.select2-hidden-accessible):focus,
body.rxs-ui-v2 .rxs-v2-board-bar select:focus,
body.rxs-ui-v2 .rxs-module .dataTables_length select:focus {
    border-color: var(--rx-v2-accent) !important;
    box-shadow: 0 0 0 3px var(--rx-v2-accent-soft) !important;
    outline: 0;
}
body.rxs-ui-v2 .rxs-v2-board-bar select {
    padding-right: 26px !important;
}

/* --- footer: "Modificacion masiva" (btn-warning v1) y "Crear filtro" (btn-themecolor) eran
 *     dos botones de dos epocas. Las dos son acciones secundarias del pie: accent-soft, y
 *     el unico CTA lleno sigue siendo el "+ Nuevo" de la cabecera. --- */
body.rxs-ui-v2 .rxs-module .rxs-table-tools .btn.btn-warning,
body.rxs-ui-v2 .rxs-module .rxs-table-tools .btn.btn-themecolor,
/* vivid: la regla de pass 14 pinta los .btn-warning/.btn-themecolor de .row.justify-content-center
 * con (0,8,1) + !important; el mismo selector con .rxs-table-tools adelante le gana */
body.rxs-ui-v2.rxs-ui-vivid .rxs-module .rxs-table-tools.row.justify-content-center:not(.allFilters):not(.listStvVue):not(.stvVueAction) .btn.btn-warning,
body.rxs-ui-v2.rxs-ui-vivid .rxs-module .rxs-table-tools.row.justify-content-center:not(.allFilters):not(.listStvVue):not(.stvVueAction) .btn.btn-themecolor {
    background: var(--rx-v2-accent-soft) !important;
    background-image: none !important;
    border: 1px solid color-mix(in srgb, var(--rx-v2-accent) 35%, transparent) !important;
    border-radius: var(--rx-v2-r9);
    box-shadow: none !important;
    color: var(--rx-v2-accent) !important;
    font-size: 13px;
    font-weight: 600;
    text-shadow: none;
}
body.rxs-ui-v2 .rxs-module .rxs-table-tools .btn.btn-warning:hover,
body.rxs-ui-v2 .rxs-module .rxs-table-tools .btn.btn-themecolor:hover,
body.rxs-ui-v2.rxs-ui-vivid .rxs-module .rxs-table-tools.row.justify-content-center:not(.allFilters):not(.listStvVue):not(.stvVueAction) .btn.btn-warning:hover,
body.rxs-ui-v2.rxs-ui-vivid .rxs-module .rxs-table-tools.row.justify-content-center:not(.allFilters):not(.listStvVue):not(.stvVueAction) .btn.btn-themecolor:hover {
    background: var(--rx-v2-accent) !important;
    border-color: var(--rx-v2-accent) !important;
    color: var(--rx-v2-accent-ink) !important;
}

/* --- dt-buttons del footer agrupados por intencion: tabla | exportar | seleccion | columnas.
 *     El separador es un hairline antes del primero de cada grupo; y en desktop los dos
 *     que mas se usan (Excel, Imprimir) muestran su nombre (sale del title que ya traen). --- */
body.rxs-ui-v2 .rxs-module .rxs-table-footer .dt-buttons .dt-button.buttons-copy,
body.rxs-ui-v2 .rxs-module .rxs-table-footer .dt-buttons .dt-button.buttons-select-all,
body.rxs-ui-v2 .rxs-module .rxs-table-footer .dt-buttons .dt-button.buttons-colvisGroup:first-of-type {
    margin-left: 10px !important;
    position: relative;
}
body.rxs-ui-v2 .rxs-module .rxs-table-footer .dt-buttons .dt-button.buttons-copy::before,
body.rxs-ui-v2 .rxs-module .rxs-table-footer .dt-buttons .dt-button.buttons-select-all::before,
body.rxs-ui-v2 .rxs-module .rxs-table-footer .dt-buttons .dt-button.buttons-colvisGroup:first-of-type::before {
    background: var(--rx-v2-border);
    content: "";
    height: 18px;
    left: -8px;
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    width: 1px;
}
@media (min-width: 1200px) {
    body.rxs-ui-v2 .rxs-module .rxs-table-footer .dt-buttons .dt-button.buttons-excel::after,
    body.rxs-ui-v2 .rxs-module .rxs-table-footer .dt-buttons .dt-button.buttons-print::after {
        content: attr(title);
        font-size: 12px;
        font-weight: 500;
        margin-left: 6px;
    }
}

/* --- kebab de fila: lista vertical "icono + verbo", borrar al final y separado. El popover
 *     #rxsRowMenu recibe los mismos nodos de la celda (a > button.btn / button.btn), ui_v2.js
 *     les cuelga el .rxs-row-menu-lbl y la clase .rxs-row-menu-danger mientras estan abiertos.
 *     Se keyea por #id a proposito: el boton "robot" es .btn.btn-themecolor y pass 26 lo pinta
 *     con `:not(.allFiltersBtn)` + !important, que le gana a cualquier cadena de clases. --- */
body.rxs-ui-v2 #rxsRowMenu:not(.rxs-fav-menu) {
    flex-direction: column;
    gap: 2px;
    min-width: 190px;
    padding: 6px;
}
body.rxs-ui-v2 #rxsRowMenu:not(.rxs-fav-menu) > a,
body.rxs-ui-v2 #rxsRowMenu:not(.rxs-fav-menu) > button.btn {
    align-items: center;
    background: transparent !important;
    border: 0 !important;
    border-radius: var(--rx-v2-r8);
    box-shadow: none !important;
    color: var(--rx-v2-text) !important;
    cursor: pointer;
    display: flex;
    font-size: 13px;
    font-weight: 500;
    gap: 10px;
    height: auto !important;
    justify-content: flex-start !important;
    line-height: 1.2;
    margin: 0;
    min-height: 34px;
    min-width: 0;
    padding: 3px 10px 3px 3px !important;
    text-align: left;
    text-decoration: none;
    width: 100% !important;
}
body.rxs-ui-v2 #rxsRowMenu:not(.rxs-fav-menu) > a:hover,
body.rxs-ui-v2 #rxsRowMenu:not(.rxs-fav-menu) > button.btn:hover {
    background: var(--rx-v2-accent-soft) !important;
    color: var(--rx-v2-text) !important;
}
/* el chip del icono: el button de adentro del <a>, o el .fa del button suelto */
body.rxs-ui-v2 #rxsRowMenu:not(.rxs-fav-menu) > a > .btn,
body.rxs-ui-v2 #rxsRowMenu:not(.rxs-fav-menu) > button.btn > .fa,
body.rxs-ui-v2 #rxsRowMenu:not(.rxs-fav-menu) > button.btn > .fas {
    align-items: center;
    background: var(--rx-v2-ghost) !important;
    border: 1px solid var(--rx-v2-border-soft) !important;
    border-radius: var(--rx-v2-r7);
    color: var(--rx-v2-muted) !important;
    display: inline-flex;
    flex: 0 0 28px;
    font-size: 12px;
    height: 28px !important;
    justify-content: center;
    margin: 0;
    min-width: 28px;
    padding: 0;
    pointer-events: none;
    width: 28px !important;
}
body.rxs-ui-v2 #rxsRowMenu:not(.rxs-fav-menu) > a:hover > .btn,
body.rxs-ui-v2 #rxsRowMenu:not(.rxs-fav-menu) > button.btn:hover > .fa,
body.rxs-ui-v2 #rxsRowMenu:not(.rxs-fav-menu) > button.btn:hover > .fas {
    background: var(--rx-v2-accent) !important;
    border-color: var(--rx-v2-accent) !important;
    color: var(--rx-v2-accent-ink) !important;
}
/* un boton con texto visible (.rxs-row-menu-txt, ui_v2.js): el texto ya es el label del
 * renglon, en el chip queda solo el icono. `font-size:0` y no esconder nodos: el texto es un
 * nodo suelto al lado del <span class="fa">, sin elemento propio que ocultar. */
body.rxs-ui-v2 #rxsRowMenu:not(.rxs-fav-menu) > a.rxs-row-menu-txt > .btn,
body.rxs-ui-v2 #rxsRowMenu:not(.rxs-fav-menu) > button.btn.rxs-row-menu-txt {
    font-size: 0 !important;
}
body.rxs-ui-v2 #rxsRowMenu:not(.rxs-fav-menu) > a.rxs-row-menu-txt > .btn > .fa,
body.rxs-ui-v2 #rxsRowMenu:not(.rxs-fav-menu) > a.rxs-row-menu-txt > .btn > .fas,
body.rxs-ui-v2 #rxsRowMenu:not(.rxs-fav-menu) > a.rxs-row-menu-txt > .btn > .fab {
    font-size: 12px;
}
body.rxs-ui-v2 #rxsRowMenu:not(.rxs-fav-menu) > button.btn.rxs-row-menu-txt > .rxs-row-menu-lbl {
    font-size: 13px;
}
body.rxs-ui-v2 .rxs-row-menu .rxs-row-menu-lbl {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
body.rxs-ui-v2 #rxsRowMenu:not(.rxs-fav-menu) > .rxs-row-menu-danger {
    margin-top: 4px;
    position: relative;
}
body.rxs-ui-v2 #rxsRowMenu:not(.rxs-fav-menu) > .rxs-row-menu-danger::before {
    background: var(--rx-v2-border-soft);
    content: "";
    height: 1px;
    left: 4px;
    position: absolute;
    right: 4px;
    top: -3px;
}
body.rxs-ui-v2 #rxsRowMenu:not(.rxs-fav-menu) > .rxs-row-menu-danger > .btn,
body.rxs-ui-v2 #rxsRowMenu:not(.rxs-fav-menu) > .rxs-row-menu-danger > .fa {
    background: color-mix(in srgb, #e5484d 12%, transparent) !important;
    border-color: color-mix(in srgb, #e5484d 30%, transparent) !important;
    color: #e5484d !important;
}
body.rxs-ui-v2 #rxsRowMenu:not(.rxs-fav-menu) > .rxs-row-menu-danger:hover {
    background: color-mix(in srgb, #e5484d 10%, transparent) !important;
    color: #e5484d !important;
}
body.rxs-ui-v2 #rxsRowMenu:not(.rxs-fav-menu) > .rxs-row-menu-danger:hover > .btn,
body.rxs-ui-v2 #rxsRowMenu:not(.rxs-fav-menu) > .rxs-row-menu-danger:hover > .fa {
    background: #e5484d !important;
    border-color: #e5484d !important;
    color: #fff !important;
}

/* --- cards (vista cards y tablero): cabecera + grilla de campos + acciones --- */
body.rxs-ui-v2 .rxs-v2-card-head {
    align-items: flex-start;
    display: flex;
    gap: 10px;
    margin-bottom: 6px;
    min-width: 0;
    text-align: left; /* el .rcol de la lista centra todo */
}
body.rxs-ui-v2 .rxs-v2-card-thumb {
    background: var(--rx-v2-ghost);
    border: 1px solid var(--rx-v2-border-soft);
    border-radius: var(--rx-v2-r9);
    flex: 0 0 44px;
    height: 44px;
    overflow: hidden;
    width: 44px;
}
body.rxs-ui-v2 .rxs-v2-card-thumb img {
    display: block;
    height: 100%;
    object-fit: cover;
    width: 100%;
}
body.rxs-ui-v2 .rxs-v2-card-hd {
    flex: 1 1 auto;
    min-width: 0;
}
body.rxs-ui-v2 .rxs-v2-card-title {
    color: var(--rx-v2-text);
    font-size: 14.5px;
    font-weight: 650;
    letter-spacing: -.01em;
    line-height: 1.25;
    overflow-wrap: anywhere;
}
body.rxs-ui-v2 .rxs-v2-card-title a {
    color: inherit;
}
body.rxs-ui-v2 .rxs-v2-card-desc {
    color: var(--rx-v2-muted);
    display: -webkit-box;
    font-size: 12px;
    line-height: 1.35;
    margin-top: 2px;
    overflow: hidden;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
}
/* los campos: etiqueta sobre valor, fluyendo en fila (los cortos comparten renglon, los
 * que no entran bajan); los largos (texto, parrafos, tablas) toman todo el ancho */
body.rxs-ui-v2 .rxs-v2-card-lines {
    display: flex;
    flex-wrap: wrap;
    gap: 0 18px;
    text-align: left;
}
body.rxs-ui-v2 .rxs-v2-card-line {
    align-items: flex-start;
    border-bottom: 0;
    /* ancho natural y sin encoger: dos pills que no entran juntas bajan de renglon en vez
     * de recortarse con puntos suspensivos (se veia en las cards angostas del tablero) */
    flex: 0 0 auto;
    flex-direction: column;
    gap: 2px;
    justify-content: flex-start;
    max-width: 100%;
    min-width: 0;
    padding: 5px 0;
}
body.rxs-ui-v2 .rxs-v2-card-line-wide {
    flex-basis: 100%;
}
/* con la línea en columna, el `flex: 1 0 100%` del toggle es ALTO y no ancho: con flex-wrap
 * el "Ver más" se iba a una segunda columna a la derecha, cortado contra el borde de la card */
body.rxs-ui-v2 .rxs-v2-card-line .rxs-clamp-more {
    align-self: flex-end;
    flex: 0 0 auto;
}
/* barra rápida de una columna (json.dt_quick, quickBar en ui_v2.js): arriba de la lista */
body.rxs-ui-v2 .rxs-quick {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    padding: 10px 16px 2px;
}
body.rxs-ui-v2 .rxs-quick-chip {
    align-items: center;
    background: var(--rx-v2-panel-2);
    border: 1px solid var(--rx-v2-border-soft);
    border-radius: 999px;
    color: var(--rx-v2-text);
    cursor: pointer;
    display: inline-flex;
    font-size: 13px;
    font-weight: 500;
    gap: 7px;
    line-height: 1.2;
    padding: 6px 13px;
}
body.rxs-ui-v2 .rxs-quick-chip:hover {
    border-color: var(--rx-v2-accent);
}
body.rxs-ui-v2 .rxs-quick-chip.is-active {
    background: var(--rx-v2-accent);
    border-color: var(--rx-v2-accent);
    color: var(--rx-v2-accent-ink);
}
body.rxs-ui-v2 .rxs-quick-n {
    background: var(--rx-v2-ghost);
    border-radius: 999px;
    font-size: 11.5px;
    font-weight: 600;
    min-width: 22px;
    padding: 1px 7px;
    text-align: center;
}
body.rxs-ui-v2 .rxs-quick-chip.is-active .rxs-quick-n {
    background: color-mix(in srgb, var(--rx-v2-accent-ink) 18%, transparent);
}
/* "Ayuda sobre Módulos" (su card es json.v2card de la pestaña 117) */
body.rxs-ui-v2 .rxsHlpModDesc {
    color: var(--rx-v2-muted);
    text-align: left;
    font-size: 12.5px;
    line-height: 1.4;
    margin-top: 8px;
}
body.rxs-ui-v2 .rxsHlpModCampos {
    margin-top: 10px;
}
body.rxs-ui-v2 .rxsHlpModCampos > .rxs-clamp-more {
    margin-left: auto;
    margin-top: 4px;
}
/* un chip por campo (ícono + nombre) y la ayuda al abrirlo, a todo el ancho */
body.rxs-ui-v2 .rxsHlpCampos {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    text-align: left;
}
body.rxs-ui-v2 .rxsHlpCampos > details {
    background: var(--rx-v2-panel-2);
    border: 1px solid var(--rx-v2-border-soft);
    border-radius: var(--rx-v2-r8);
    max-width: 100%;
}
body.rxs-ui-v2 .rxsHlpCampos > details[open] {
    background: var(--rx-v2-panel);
    flex-basis: 100%;
}
body.rxs-ui-v2 .rxsHlpCampos > details > summary {
    color: var(--rx-v2-text);
    cursor: pointer;
    font-size: 12.5px;
    list-style: none;
    padding: 3px 9px;
}
body.rxs-ui-v2 .rxsHlpCampos > details > summary::-webkit-details-marker {
    display: none;
}
body.rxs-ui-v2 .rxsHlpCampos > details > summary > .fa {
    color: var(--rx-v2-accent);
    margin-right: 6px;
}
body.rxs-ui-v2 .rxsHlpCampos > details > div {
    color: var(--rx-v2-muted);
    font-size: 12.5px;
    padding: 0 9px 7px;
}
body.rxs-ui-v2 .rxs-v2-card-lbl {
    font-size: 10.5px;
    letter-spacing: .04em;
    line-height: 1.2;
    max-width: 100%;
}
body.rxs-ui-v2 .rxs-v2-card-val {
    font-size: 13px;
    line-height: 1.35;
    max-width: 100%;
    /* break-word, no anywhere: "8000.00" no se parte en "8000." / "00"; una palabra solo
     * se corta si no entra entera en el ancho de la card */
    overflow-wrap: break-word;
    text-align: left;
}
body.rxs-ui-v2 .rxs-v2-card-val > label.rxsCheck {
    margin-left: 0 !important;
}
/* la pill dentro de la card ya no compite con una etiqueta a la izquierda: ancho natural.
 * Con max-width:100% heredado de la grilla, el .rxsEdGo (padding para el lapiz) le comia
 * ~10px al valor y la pill se recortaba con "..." aunque estuviera sola en el renglon. */
body.rxs-ui-v2 .rxs-v2-card-lines .rxs-v2-card-val .rxs-pill {
    max-width: none;
}
body.rxs-ui-v2 .rxs-v2-card-lines .rxs-v2-card-val {
    overflow: hidden;
}
/* acciones de la card: chips neutros, el color aparece al hover (antes: cuatro botones
 * llenos de cuatro colores abajo de cada card). Borrar se mantiene rojo suave. */
body.rxs-ui-v2 .rxs-module .rxs-v2-card .rxs-v2-card-actions .rxsBtns .btn:not(:where(.rxsBtnsOwn .btn)),
body.rxs-ui-v2 .rxs-module .rxs-v2-card .rxs-v2-card-actions .btn:not(:where(.rxsBtnsOwn .btn)) {
    background: var(--rx-v2-ghost) !important;
    background-image: none !important;
    border: 1px solid var(--rx-v2-border-soft) !important;
    border-radius: var(--rx-v2-r7);
    box-shadow: none !important;
    color: var(--rx-v2-muted) !important;
    height: 28px;
    min-width: 28px;
    opacity: 1 !important;
    padding: 0 7px;
}
body.rxs-ui-v2 .rxs-module .rxs-v2-card .rxs-v2-card-actions .rxsBtns .btn:not(:where(.rxsBtnsOwn .btn)):hover,
body.rxs-ui-v2 .rxs-module .rxs-v2-card .rxs-v2-card-actions .btn:not(:where(.rxsBtnsOwn .btn)):hover {
    background: var(--rx-v2-accent) !important;
    border-color: var(--rx-v2-accent) !important;
    color: var(--rx-v2-accent-ink) !important;
}
body.rxs-ui-v2 .rxs-module .rxs-v2-card .rxs-v2-card-actions .rxsBtns .btn:not(:where(.rxsBtnsOwn .btn)).btn-danger,
body.rxs-ui-v2 .rxs-module .rxs-v2-card .rxs-v2-card-actions .btn:not(:where(.rxsBtnsOwn .btn)).btn-danger {
    color: #e5484d !important;
}
body.rxs-ui-v2 .rxs-module .rxs-v2-card .rxs-v2-card-actions .rxsBtns .btn:not(:where(.rxsBtnsOwn .btn)).btn-danger:hover,
body.rxs-ui-v2 .rxs-module .rxs-v2-card .rxs-v2-card-actions .btn:not(:where(.rxsBtnsOwn .btn)).btn-danger:hover {
    background: #e5484d !important;
    border-color: #e5484d !important;
    color: #fff !important;
}
/* tablero: la card es angosta, una sola columna de campos y cabecera mas chica */
body.rxs-ui-v2 .rxs-v2-board-card .rxs-v2-card-title {
    font-size: 13.5px;
}
body.rxs-ui-v2 .rxs-v2-board-card .rxs-v2-card-thumb {
    flex-basis: 36px;
    height: 36px;
    width: 36px;
}
/* barra del tablero: los controles a la altura y al radio del resto de la cabecera */
body.rxs-ui-v2 .rxs-v2-board-bar .rxsV2BoardSel,
body.rxs-ui-v2 .rxs-v2-board-bar .rxsV2BoardSwimSel {
    font-weight: 500;
    padding-left: 10px;
}

/* --- ficha: el lapiz "Modificar" junto al titulo. Sin vivid ya era neutro; en vivid la
 *     familia de pass 16 lo pinta ambar solido (#f59e0b), que al lado del acento se lee
 *     como el btn-warning de v1 (el mismo sintoma que "Modificacion masiva" del footer).
 *     Es una accion secundaria de la cabecera: accent-soft, como el resto. El success /
 *     danger / info de esa misma barra quedan como estan: ahi el color ES el significado. --- */
body.rxs-ui-v2.rxs-ui-vivid .nav-tabs-custom.card.rxs-v2-ficha > h4.ftidtitle > .btn.btn-warning.popupurlForm,
body.rxs-ui-v2.rxs-ui-vivid .nav-tabs-custom.card.rxs-v2-ficha > h4.ftidtitle > a > .btn.btn-warning.popupurlForm {
    background: var(--rx-v2-accent-soft) !important;
    border: 1px solid color-mix(in srgb, var(--rx-v2-accent) 35%, transparent) !important;
    color: var(--rx-v2-accent) !important;
}
body.rxs-ui-v2.rxs-ui-vivid .nav-tabs-custom.card.rxs-v2-ficha > h4.ftidtitle > .btn.btn-warning.popupurlForm:hover,
body.rxs-ui-v2.rxs-ui-vivid .nav-tabs-custom.card.rxs-v2-ficha > h4.ftidtitle > a > .btn.btn-warning.popupurlForm:hover {
    background: var(--rx-v2-accent) !important;
    border-color: var(--rx-v2-accent) !important;
    color: var(--rx-v2-accent-ink) !important;
    filter: none;
}

/* ---- notas del sitio (rxsNote): la INTENSIDAD ----
   Los tokens --rx-tone-* se definen en adm.css, que baja siempre; aca solo se
   REdefinen. Es a proposito: la nota se dibuja en la pagina publica y este
   archivo solo lo baja el sitio con ui_v=2 (page.php:377), asi que un token que
   naciera aca dejaria la nota sin pintar en los demas tenants.

   Con "colores vivos" (json de usuario ui_vivid=1) el tinte del 12-14% se queda
   corto y la nota no se impone. Sube el tinte y se marca el borde, PERO no se
   pinta el fondo lleno como hacen los botones de fila (pass 14): ahi el texto
   es un label corto en negrita, aca es el cuerpo de una nota. Blanco sobre el
   #2e90fa de `btn-info` vivid da 3,2:1 — alcanza para un boton y no para leer
   tres renglones. Las tintas de adm.css estan elegidas para pasar 4:1 sobre su
   PROPIO tinte, asi que subiendo el tinte y dejando la tinta se gana presencia
   sin perder legibilidad. El color pleno se lo queda la barra de la izquierda,
   que es donde de verdad se ve el tono de un vistazo. */
body.rxs-ui-v2.rxs-ui-vivid {
    --rx-tone-0-bg: rgba(46, 144, 250, .22);
    --rx-tone-0-bd: #2e90fa;
    --rx-tone-1-bg: rgba(245, 158, 11, .24);
    --rx-tone-1-bd: #f59e0b;
    --rx-tone-2-bg: color-mix(in srgb, var(--rx-v2-accent) 24%, transparent);
    --rx-tone-2-bd: var(--rx-v2-accent);
    --rx-tone-3-bg: rgba(239, 68, 68, .20);
    --rx-tone-3-bd: #ef4444;
    --rx-tone-4-bg: rgba(34, 197, 94, .22);
    --rx-tone-4-bd: #22c55e;
    --rx-tone-5-bg: var(--rx-v2-ghost);
    --rx-tone-5-bd: var(--rx-v2-border);
}

/* la barra del tono, mas ancha y a color pleno: es la senal que se lee de lejos */
body.rxs-ui-v2.rxs-ui-vivid .rxsNote {
    border-left-color: var(--rx-tone-bd, var(--rx-tone-5-bd));
    border-left-width: 6px;
}
body.rxs-ui-v2.rxs-ui-vivid .rxsNote .rxsNote-b { opacity: 1; }

/* ============ pass 32: el tablero grande (/dash y tab_ds) ============
 * El <kpi-dashboard> sin :compact era la unica pantalla de v2 que seguia con su cromo de
 * origen: cabecera con degrade y un icono de 15rem de marca de agua, cards con sombra fuerte
 * y hover que las levanta, cajitas de KPI con borde punteado e icono generico, dos tarjetas de
 * metadatos al pie, un FAB de refresco suelto, y una tira de periodos que no envuelve (en un
 * telefono se salia 200px por la derecha). Aca se lleva todo a los tokens del panel v2 con el
 * criterio de un tablero de monitoreo: paneles planos con borde fino sobre el fondo de la
 * pagina, una sola barra arriba (etiquetas + fecha + periodos + acciones), titulo chico y
 * mudo en cada panel, el numero grande como protagonista, y los controles secundarios que
 * aparecen al pasar por el panel. Todo scopeado a .dashboard-full-container:not(.kpi-compact):
 * la tira de KPIs del listado (pass anterior) no cambia. */

/* -- la pagina /dash: sin el card envolvente ni el padding del contenedor -- */
body.rxs-ui-v2 .dashfavspage > .nav-tabs-custom.card {
    padding: 0 !important;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) {
    background: transparent;
    color: var(--rx-v2-text);
    padding: 0;
}

/* -- barra de arriba: chips de etiqueta + filtro de fecha en una fila -- */
body.rxs-ui-v2 .dash-toolbar {
    align-items: center;
    display: flex;
    flex-wrap: wrap;
    gap: 6px 12px;
    margin-bottom: 10px;
}

body.rxs-ui-v2 .dash-toolbar > .dash-tags {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin: 0 !important;
}

body.rxs-ui-v2 .dash-toolbar > .dash-tags > .btn {
    background: var(--rx-v2-panel);
    border: 1px solid var(--rx-v2-border);
    border-radius: 999px;
    color: var(--rx-v2-muted);
    font-size: 12px;
    font-weight: 600;
    line-height: 1.2;
    margin: 0 !important;
    padding: 5px 11px;
}

/* Las dos lineas de la cabecera (Periodo y Actualizado) con el icono en la misma columna: una
 * era un <p> con mr-2 y la otra un <small> con mr-1, y el reloj quedaba 10px corrido. */
body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .rxs-dash-meta i.fas {
    margin: 0 6px 0 0 !important;
    text-align: center;
    width: 14px;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .rxs-dash-meta,
body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .rxs-dash-meta small {
    font-size: 12px;
}

/* En un telefono las etiquetas eran tres renglones de chips arriba de todo: una tira que se
 * desliza, como la de periodos de abajo. */
@media (max-width: 767px) {
    body.rxs-ui-v2 .dash-toolbar > .dash-tags {
        flex: 1 1 100%;
        flex-wrap: nowrap;
        -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 24px), transparent);
        mask-image: linear-gradient(to right, #000 calc(100% - 24px), transparent);
        max-width: 100%;
        overflow-x: auto;
        padding-right: 24px;
        scrollbar-width: none;
    }

    body.rxs-ui-v2 .dash-toolbar > .dash-tags::-webkit-scrollbar {
        display: none;
    }

    body.rxs-ui-v2 .dash-toolbar > .dash-tags > .btn {
        flex: none;
        white-space: nowrap;
    }
}

body.rxs-ui-v2 .dash-toolbar > .dash-tags > .btn:hover {
    border-color: var(--rx-v2-accent);
    color: var(--rx-v2-text);
}

body.rxs-ui-v2 .dash-toolbar > .dash-tags > .btn.btn-themecolor {
    background: var(--rx-v2-accent-soft);
    border-color: transparent;
    color: var(--rx-v2-accent);
}

body.rxs-ui-v2 .dash-toolbar > .dash-tags > .btn .badge {
    background: var(--rx-v2-ghost);
    color: inherit;
    font-size: 10px;
    margin-left: 4px;
    padding: 2px 6px;
}

/* el filtro de fecha deja de ser col-md-6: toma lo que queda de la fila */
body.rxs-ui-v2 .dash-toolbar > .filterStv.rxs-v2-fdate {
    flex: 1 1 320px;
    margin: 0 !important;
    max-width: 100%;
    width: auto;
}

body.rxs-ui-v2 .dash-toolbar > .filterStv.rxs-v2-fdate > .input-group.rxs-v2-igdate {
    box-shadow: none;
    padding: 6px 10px;
}

body.rxs-ui-v2 .dash-toolbar > .filterStv.rxs-v2-fdate > .input-group.rxs-v2-igdate > .input-group-prepend {
    height: 34px;
    left: 10px;
    top: 6px;
    width: 34px;
}

/* -- cabecera del dashboard: un panel, no un cartel -- */
body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .dashboard-header {
    background: var(--rx-v2-panel) !important;
    border: 1px solid var(--rx-v2-border-soft);
    border-radius: var(--rx-v2-r12) !important;
    box-shadow: none !important;
    color: var(--rx-v2-text) !important;
    margin-bottom: 12px !important;
    padding: 10px 14px !important;
}

/* la marca de agua (chart-line de 15rem) y el tacometro de 3rem */
body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .dashboard-header > .position-absolute,
body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .dashboard-header .fa-tachometer-alt {
    display: none;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .dashboard-header h1 {
    color: var(--rx-v2-text);
    font-size: 17px;
    font-weight: 600;
    letter-spacing: -.01em;
    line-height: 1.3;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .dashboard-header h1 .badge-light {
    background: var(--rx-v2-ghost);
    border-radius: 999px;
    color: var(--rx-v2-muted);
    font-size: 11px !important;
    font-weight: 600;
    margin-left: 8px !important;
    padding: 3px 8px;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .dashboard-header h1 .badge-light small {
    color: var(--rx-v2-faint) !important;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .dashboard-header p,
body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .dashboard-header small {
    color: var(--rx-v2-muted);
    font-size: 12px;
    opacity: 1 !important;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .dashboard-header .d-flex.align-items-center.mb-2 {
    margin-bottom: 2px !important;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .dashboard-header .mt-1 {
    display: inline-block;
    margin-left: 10px;
    margin-top: 0 !important;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .dashboard-header .rxs-dash-qt {
    color: var(--rx-v2-faint);
}

/* botones de la cabecera: fantasma, el activo con el acento suave. Cubre colapsar,
 * refrescar, Top N, funciones SQL, Favoritos/Editar/Comparar/Ocultar y los periodos
 * de comparacion, que llegan con btn-outline-light / btn-light / btn-themecolor(2) /
 * btn-warning / btn-info segun su estado. */
body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .dashboard-header .btn.btn-sm {
    background: transparent;
    border: 1px solid var(--rx-v2-border) !important;
    border-radius: var(--rx-v2-r8);
    box-shadow: none !important;
    color: var(--rx-v2-muted);
    font-size: 12px;
    font-weight: 500;
    line-height: 1.2;
    margin-bottom: 0 !important;
    padding: 5px 9px;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .dashboard-header .btn.btn-sm:hover {
    border-color: var(--rx-v2-accent) !important;
    color: var(--rx-v2-text);
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .dashboard-header .btn.btn-sm.btn-light,
body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .dashboard-header .btn.btn-sm.btn-themecolor,
body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .dashboard-header .btn.btn-sm.btn-themecolor2,
body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .dashboard-header .btn.btn-sm.btn-warning,
body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .dashboard-header .btn.btn-sm.btn-info {
    /* btn-themecolor(2) traen fondo con !important desde adm.css (el rojo del tenant) */
    background: var(--rx-v2-accent-soft) !important;
    border-color: transparent !important;
    color: var(--rx-v2-accent) !important;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .dashboard-header h1 .btn.btn-sm {
    height: 26px;
    margin-left: 6px !important;
    padding: 0 7px;
}

body.rxs-ui-v2 .rxs-dash-refresh {
    display: inline-flex;
    align-items: center;
}

/* la columna derecha: una sola fila de controles que envuelve, alineada a la derecha */
body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .dashboard-header .col-lg-6.text-lg-right {
    align-items: center;
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    justify-content: flex-end;
    margin-top: 0 !important;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .dashboard-header .sql-functions-selector,
body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .dashboard-header .comparison-periods-selector,
body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .dashboard-header .comparison-periods-selector > .mb-2 {
    display: inline-flex;
    flex-wrap: wrap;
    gap: 6px;
    margin: 0 !important;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .dashboard-header .btn-group {
    margin: 0 !important;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .dashboard-header .btn-group > .btn.btn-sm {
    margin-left: -1px;
    border-radius: 0;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .dashboard-header .btn-group > .btn.btn-sm:first-child {
    border-radius: var(--rx-v2-r8) 0 0 var(--rx-v2-r8);
    margin-left: 0;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .dashboard-header .btn-group > .btn.btn-sm:last-child {
    border-radius: 0 var(--rx-v2-r8) var(--rx-v2-r8) 0;
}

/* los periodos: un control segmentado. En vez de la pildora blanca translucida que no
 * envolvia (624px de ancho en un viewport de 412), una tira que si no entra se desplaza
 * de costado sin sacar la pagina de su ancho. */
body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .dashboard-header .period-selector {
    background: var(--rx-v2-panel-2) !important;
    border: 1px solid var(--rx-v2-border-soft);
    border-radius: var(--rx-v2-r10) !important;
    display: flex !important;
    flex-wrap: nowrap;
    gap: 2px;
    margin: 0 !important;
    max-width: 100%;
    overflow-x: auto;
    padding: 3px !important;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .dashboard-header .period-selector::-webkit-scrollbar {
    display: none;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .dashboard-header .period-btn {
    background: transparent;
    border: 0;
    border-radius: var(--rx-v2-r7);
    color: var(--rx-v2-muted);
    flex: 0 0 auto;
    font-size: 12px;
    font-weight: 500;
    margin: 0 !important;
    padding: 4px 9px;
    white-space: nowrap;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .dashboard-header .period-btn:hover:not(.active) {
    background: var(--rx-v2-hover);
    color: var(--rx-v2-text);
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .dashboard-header .period-btn.active {
    background: var(--rx-v2-panel);
    box-shadow: 0 1px 3px rgba(18, 25, 33, .12);
    color: var(--rx-v2-text);
    font-weight: 600;
}

body.rxs-ui-v2.thr-dark .dashboard-full-container:not(.kpi-compact) .dashboard-header .period-btn.active {
    background: var(--rx-v2-active);
    box-shadow: none;
}

/* -- pass 32c: la cabecera en UNA fila. La tira de periodos lleva solo el pasado, las
 * ventanas futuras, Top N, la funcion de agregado, comparar y ocultar vacios van en un menu
 * (.rxs-dash-more), y Favoritos/Editar quedan como botones. Antes eran tres filas y la tira
 * se salia del panel a 1440 (el +15D terminaba 5px despues del borde). -- */
body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .dashboard-header .rxs-dash-periods {
    flex: 0 1 auto;
    min-width: 0;
}

/* las dos columnas ya no son mitad y mitad: el titulo toma lo suyo y los controles el resto.
   El que ABSORBE es el titulo (flex-grow) y los controles miden lo suyo anclados a la derecha
   (margin-left:auto): al reves, cuando llegaba el meta y el titulo sumaba "Periodo ... ·
   Actualizado", la caja de los controles se corria 98px a la derecha aunque sus botones no se
   movieran un pixel (estan alineados a la derecha) — y layout-shift cuenta cajas, no pixeles:
   0,045 de CLS por una caja invisible (docs/repro/dash-cls.mjs). */
@media (min-width: 992px) {
    body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .dashboard-header .row.align-items-center {
        flex-wrap: nowrap;
    }

    body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .dashboard-header .row.align-items-center > .col-lg-6:first-child {
        flex: 1 1 auto;
        min-width: 0;
        max-width: 45%;
        width: auto;
    }

    body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .dashboard-header .row.align-items-center > .col-lg-6.text-lg-right {
        flex: 0 1 auto;
        margin-left: auto;
        max-width: none;
        width: auto;
    }
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .dashboard-header .rxs-dash-more {
    position: relative;
}

/* el header trae overflow-hidden (era para la marca de agua): el menu tiene que salir */
body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .dashboard-header.overflow-hidden {
    overflow: visible !important;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .dashboard-header .rxs-dash-more > .btn.btn-sm {
    height: 28px;
    padding: 0 8px;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .dashboard-header .rxs-dash-more > .btn.btn-sm::after {
    display: none;
}

body.rxs-ui-v2 .rxs-dash-menu {
    min-width: 250px;
    padding: 6px;
    text-align: left;
}

body.rxs-ui-v2 .rxs-dash-menu .dropdown-header {
    color: var(--rx-v2-faint);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .04em;
    padding: 8px 8px 4px;
    text-transform: uppercase;
}

body.rxs-ui-v2 .rxs-dash-menu .dropdown-item {
    border-radius: var(--rx-v2-r7);
    font-size: 13px;
    padding: 6px 8px;
}

body.rxs-ui-v2 .rxs-dash-menu .rxs-dash-menu-chk {
    align-items: center;
    display: flex;
    gap: 8px;
}

body.rxs-ui-v2 .rxs-dash-menu .rxs-dash-menu-chk > i {
    color: var(--rx-v2-faint);
    font-size: 13px;
    width: 14px;
}

/* el .active de bootstrap es un bloque azul solido: aca el activo se dice con el check */
body.rxs-ui-v2 .rxs-dash-menu .dropdown-item.active,
body.rxs-ui-v2 .rxs-dash-menu .dropdown-item:active {
    background: transparent;
    color: var(--rx-v2-text);
}

body.rxs-ui-v2 .rxs-dash-menu .dropdown-item.active:hover,
body.rxs-ui-v2 .rxs-dash-menu .dropdown-item:hover {
    background: var(--rx-v2-ghost);
}

body.rxs-ui-v2 .rxs-dash-menu .rxs-dash-menu-chk.active > i {
    color: var(--rx-v2-accent);
}

body.rxs-ui-v2 .rxs-dash-menu .rxs-dash-menu-sym {
    color: var(--rx-v2-faint);
    font-size: 12px;
    margin-left: auto;
}

/* control segmentado adentro del menu (Top N, periodos de comparacion) */
body.rxs-ui-v2 .rxs-dash-menu .rxs-dash-menu-seg {
    background: var(--rx-v2-panel-2);
    border: 1px solid var(--rx-v2-border-soft);
    border-radius: var(--rx-v2-r8);
    display: flex;
    flex-wrap: wrap;
    gap: 2px;
    margin: 2px 8px 6px;
    padding: 3px;
}

body.rxs-ui-v2 .rxs-dash-menu .rxs-dash-menu-seg > button {
    background: transparent;
    border: 0;
    border-radius: var(--rx-v2-r7);
    color: var(--rx-v2-muted);
    flex: 1 1 auto;
    font-size: 12px;
    font-weight: 500;
    padding: 4px 8px;
}

body.rxs-ui-v2 .rxs-dash-menu .rxs-dash-menu-seg > button:hover:not(.active) {
    background: var(--rx-v2-hover);
    color: var(--rx-v2-text);
}

body.rxs-ui-v2 .rxs-dash-menu .rxs-dash-menu-seg > button.active {
    background: var(--rx-v2-panel);
    box-shadow: 0 1px 3px rgba(18, 25, 33, .12);
    color: var(--rx-v2-text);
    font-weight: 600;
}

body.rxs-ui-v2.thr-dark .rxs-dash-menu .rxs-dash-menu-seg > button.active {
    background: var(--rx-v2-active);
    box-shadow: none;
}

body.rxs-ui-v2 .rxs-dash-menu .rxs-dash-menu-sub {
    margin-left: 30px;
}

/* -- pass 32f: variables del tablero, refresco automatico y el foco de cada panel -- */

/* Un selector por clave @p_<clave> que declaren los widgets: etiqueta chica y un select con
 * el mismo cuerpo que los botones de la cabecera (28px, panel-2, borde suave). En mobile
 * envuelven como el resto de la fila. */
body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .dashboard-header .rxs-dash-vars {
    display: inline-flex;
    flex: 0 1 auto;
    flex-wrap: wrap;
    gap: 6px;
    min-width: 0;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .dashboard-header .rxs-dash-var {
    align-items: center;
    background: var(--rx-v2-panel-2);
    border: 1px solid var(--rx-v2-border-soft);
    border-radius: var(--rx-v2-r8);
    display: inline-flex;
    gap: 6px;
    height: 28px;
    margin: 0;
    max-width: 260px;
    padding: 0 0 0 8px;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .dashboard-header .rxs-dash-var-l {
    color: var(--rx-v2-muted);
    font-size: 11px;
    font-weight: 500;
    text-transform: uppercase;
    white-space: nowrap;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .dashboard-header .rxs-dash-var-s {
    appearance: auto;
    background: transparent;
    border: 0;
    border-radius: 0 var(--rx-v2-r8) var(--rx-v2-r8) 0;
    color: var(--rx-v2-text);
    font-size: 12px;
    font-weight: 600;
    height: 26px;
    max-width: 190px;
    min-width: 0;
    outline: none;
    padding: 0 6px;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .dashboard-header .rxs-dash-var-s:focus {
    background: var(--rx-v2-hover);
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .dashboard-header .rxs-dash-var-s option {
    background: var(--rx-v2-panel);
    color: var(--rx-v2-text);
}

/* "↻ 1 min" al lado de Actualizado: la pill de que el tablero se refresca solo */
body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .rxs-dash-auto {
    background: var(--rx-v2-accent-soft);
    border-radius: 999px;
    color: var(--rx-v2-accent);
    font-size: 11px;
    font-weight: 600;
    padding: 1px 7px;
    white-space: nowrap;
}

/* el foco aplicado a un panel ("Empresa: Acme"), con el acento suave para que se distinga de
 * la ventana propia (gris) */
body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .rxs-card-win.rxs-card-focus {
    background: var(--rx-v2-accent-soft);
    color: var(--rx-v2-accent);
    display: inline-block;
    max-width: min(320px, 70%);
    overflow: hidden;
    text-overflow: ellipsis;
    vertical-align: middle;
}

/* la ventana propia de un panel ("Últimos 30 días"), al lado del titulo */
body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .rxs-card-win {
    background: var(--rx-v2-ghost);
    border-radius: 999px;
    color: var(--rx-v2-faint);
    font-size: 11px;
    font-weight: 500;
    margin-left: 6px;
    padding: 1px 7px;
    vertical-align: 1px;
    white-space: nowrap;
}

/* el panel vino del cache (o acaba de guardarse): mismo pill, con el reloj. Ver
 * rxsFilterGraphCacheStore (functions/extra.php) y cacheLabel() en g_charts.js. */
body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .rxs-card-win.rxs-card-cache {
    background: color-mix(in srgb, var(--rx-v2-accent) 10%, transparent);
    color: var(--rx-v2-faint);
}

/* la ventana que declara el INFORME y el panel no puede cambiar: mismo pill, con borde punteado.
 * Es la diferencia entre "este panel mira 30 dias porque yo se los puse" y "este numero es del
 * anio y el selector de fechas de arriba no lo mueve" */
body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .rxs-card-win.rxs-card-win-own {
    background: transparent;
    border: 1px dashed var(--rx-v2-border);
    padding: 0 6px;
}

/* -- la grilla de paneles: gutter de 12px en vez de 30 + mb-4 -- */
body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .dashboard-content > .animate-fade-in > .row.mb-5 {
    margin-bottom: 0 !important;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .row.align-items-start {
    margin-left: -6px;
    margin-right: -6px;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .row.align-items-start > [class*="col-"] {
    margin-bottom: 12px !important;
    padding-left: 6px;
    padding-right: 6px;
}

/* -- cada panel: plano, borde fino, sin sombra ni salto al pasar -- */
body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .metric-card {
    background: var(--rx-v2-panel);
    border: 1px solid var(--rx-v2-border-soft) !important;
    border-radius: var(--rx-v2-r12) !important;
    box-shadow: none !important;
    transition: border-color .15s ease;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .metric-card:hover {
    border-color: var(--rx-v2-border) !important;
    box-shadow: none !important;
    transform: none;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .metric-card > .card-header {
    background: transparent !important;
    padding: 9px 10px 4px 12px !important;
}

/* titulo del panel: chico, medio, en tinta; el icono generico (pie) no dice nada y se va;
 * uno elegido a proposito para el favorito queda, chiquito y con el acento suave */
body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .metric-card .card-header h6 {
    color: var(--rx-v2-text);
    font-size: 13px;
    font-weight: 600;
    letter-spacing: 0;
    line-height: 1.3;
    margin-bottom: 0 !important;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .metric-card .card-header h6 > i.btn-rxsm {
    background: var(--rx-v2-accent-soft) !important;
    color: var(--rx-v2-accent) !important;
    font-size: 10px;
    height: 20px;
    line-height: 20px;
    margin-right: 6px !important;
    padding: 0 !important;
    text-align: center;
    width: 20px;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .metric-card .card-header h6 > i.btn-rxsm.fa-chart-pie {
    display: none;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .metric-card .card-header h6 .fa-info-circle {
    color: var(--rx-v2-faint) !important;
    opacity: 1 !important;
    transition: opacity .15s ease;
}

/* pass 32e: el "i" en trece titulos era ruido. Con puntero aparece al pasar por el panel,
 * como la estrella y el kebab; el popover sigue ahi. En touch queda siempre: con `pointer:
 * fine` y no solo `hover`, porque una pantalla tactil que tambien reporta hover (tablets,
 * notebooks con touch) los escondia igual (tarea 43837). */
@media (hover: hover) and (pointer: fine) {
    body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .metric-card .card-header h6 .fa-info-circle {
        opacity: 0 !important;
    }
    body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .metric-card:hover .card-header h6 .fa-info-circle,
    body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .metric-card .card-header h6 .fa-info-circle:focus {
        opacity: 1 !important;
    }
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .metric-card .card-header h6 .badge-light {
    background: var(--rx-v2-ghost);
    color: var(--rx-v2-muted);
    font-weight: 500;
}

/* la estrella y el kebab: fantasma; con puntero se ven al pasar por el panel (en touch
 * quedan siempre, que ahi no hay hover) */
body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .metric-card .card-header .btn.btn-sm {
    background: transparent !important;
    border: 0 !important;
    border-radius: var(--rx-v2-r8);
    box-shadow: none !important;
    color: var(--rx-v2-faint) !important;
    font-size: 12px;
    height: 26px;
    line-height: 26px;
    margin: 0 0 0 2px !important;
    padding: 0 7px;
    transition: opacity .15s ease, color .15s ease, background .15s ease;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .metric-card .card-header .btn.btn-sm:hover,
body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .metric-card .card-header .show > .btn.btn-sm {
    background: var(--rx-v2-hover) !important;
    color: var(--rx-v2-text) !important;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .metric-card .card-header .btn.btn-sm.btn-warning {
    color: var(--rx-v2-accent) !important;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .metric-card .card-header .dropdown-toggle::after {
    display: none;
}

@media (hover: hover) and (pointer: fine) {
    body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .metric-card .card-header .btn.btn-sm {
        opacity: 0;
    }
    body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .metric-card:hover .card-header .btn.btn-sm,
    body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .metric-card .card-header .btn.btn-sm:focus,
    body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .metric-card .card-header .btn.btn-sm.btn-warning,
    body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .metric-card .card-header .show > .btn.btn-sm {
        opacity: 1;
    }
}

/* tendencia: pill suave, no el badge solido de bootstrap */
body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .metric-card .card-header .trend-badge,
body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .metric-card .rxs-cmp .trend-badge {
    border-radius: 999px;
    font-size: 11px;
    font-weight: 600;
    padding: 2px 8px;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .metric-card .card-header .trend-badge.badge-success,
body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .metric-card .rxs-cmp .trend-badge.badge-success {
    background: color-mix(in srgb, #2fa36b 16%, transparent) !important;
    color: #2fa36b !important;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .metric-card .card-header .trend-badge.badge-danger,
body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .metric-card .rxs-cmp .trend-badge.badge-danger {
    background: color-mix(in srgb, #d9534f 16%, transparent) !important;
    color: #e2726e !important;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .metric-card .card-header .trend-badge.badge-secondary,
body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .metric-card .rxs-cmp .trend-badge.badge-secondary {
    background: var(--rx-v2-ghost) !important;
    color: var(--rx-v2-faint) !important;
}

/* pass 33 (bloque L): las comparaciones son UNA linea de chips al pie del grafico —
 * "Anterior +20,3% · Año pasado +60,3% · Prom. 6M +10,1%"—, no tres barras de color a
 * ancho completo que pesaban mas que el grafico. El titulo queda como etiqueta muda. */
body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .metric-card .rxs-cmp-line {
    align-items: center;
    display: flex;
    flex-wrap: wrap;
    gap: 6px 14px;
    margin: 6px 0 0 !important;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .metric-card .rxs-cmp-line .rxs-cmp-title {
    color: var(--rx-v2-faint) !important;
    font-size: 10.5px !important;
    font-weight: 600 !important;
    letter-spacing: .06em;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .metric-card .rxs-cmp {
    align-items: center;
    display: inline-flex;
    gap: 6px;
    white-space: nowrap;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .metric-card .rxs-cmp .rxs-cmp-l {
    color: var(--rx-v2-muted) !important;
    font-size: 12px;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .metric-card > .card-body {
    padding: 4px 12px 12px !important;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .metric-card .data-section {
    margin-bottom: 0 !important;
}

/* .analysis-section se dibuja con solo item.comparison (el % ya va en la cabecera) y
 * queda un <hr> suelto al pie de cada grafico */
body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .metric-card .analysis-section > hr {
    display: none;
}

/* -- cajitas de KPI: el numero es el panel (tipo "stat") -- */
/* Grilla, no flex: con flex: 1 1 120px la ultima fila se repartia el ancho (dos cajitas de
 * 559px debajo de dieciseis de 134px, medido en "Grandes indicadores" de meli). Con la
 * grilla todas las cajitas miden lo mismo y las que sobran quedan a la izquierda. */
/* 2026-09-28: y las cajitas LLENAN el panel. Con auto-fill de 156px un KPI de cinco numeros en
 * un panel de 12 columnas ocupaba el 60% y dejaba el resto vacio, y ocho numeros donde entran
 * siete eran siete y una huerfana. El ancho minimo de cada cajita es (--rxs-kn = cuantas son):
 *   - todas en UNA fila, si a cada una le tocan 156px o mas;
 *   - si no, en DOS filas parejas (--rxs-kh, la mitad redondeada para arriba, la pone el
 *     template: round() de CSS no esta en todos los navegadores y un var() invalido no cae
 *     al fallback, deja la grilla sin columnas);
 *   - y si tampoco, 156px y las que entren.
 * Es max(156px, 1/n, min(1/mitad, (156px - 1/n) * 1000)): el ultimo termino es negativo cuando
 * entran todas (y no pesa) y enorme cuando no (y deja pasar el 1/mitad). */
body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .kpi-container .row {
    --rxs-kn: 4;
    --rxs-kh: 2;
    --rxs-k1: calc((100% - (var(--rxs-kn) - 1) * 8px) / var(--rxs-kn) - 0.5px);
    --rxs-k2: calc((100% - (var(--rxs-kh) - 1) * 8px) / var(--rxs-kh) - 0.5px);
    display: grid;
    gap: 8px;
    grid-template-columns: repeat(auto-fill, minmax(156px, 1fr));
    grid-template-columns: repeat(auto-fit, minmax(max(156px, var(--rxs-k1), min(var(--rxs-k2), (156px - var(--rxs-k1)) * 1000)), 1fr));
    justify-content: flex-start !important;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .kpi-container .row > .col {
    flex: none;
    margin: 0 !important;
    max-width: none;
    min-width: 0;
    padding: 0;
    width: auto;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .kpi-card {
    /* el h2 lleva color: var(--rx-color1) inline (o el color del semaforo). Pass 32c: el
     * numero sin estado va en TINTA, no en el acento del tenant: con el acento verde de
     * ResuMax "14 firing sin analizar" salia del mismo verde que "0 colgados" y el color
     * no decia nada. Ahora el color lo pone solo el semaforo (o un color elegido). */
    --rx-color1: var(--rx-v2-text);
    background: var(--rx-v2-panel-2) !important;
    border: 1px solid var(--rx-v2-border-soft) !important;
    border-radius: var(--rx-v2-r10) !important;
    box-shadow: none !important;
    /* el numero se mide contra el ancho de SU cajita (cqw), no contra la pantalla */
    container-type: inline-size;
    margin-bottom: 0 !important;
    padding: 12px 10px 10px !important;
    text-align: left !important;
    transition: border-color .15s ease, background .15s ease;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .kpi-card.kpi-drill:hover {
    background: var(--rx-v2-hover) !important;
    border-color: var(--rx-v2-accent) !important;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .kpi-card .kpi-icon {
    display: none;
}

/* El numero en UNA linea: "3.084.019,75" a 28px en una cajita de 134px se partia en dos
 * ("3.084.01 / 9,75"). El tamanio sale del ancho de la cajita (12cqw: 19px a 156px, 28px
 * de 234px para arriba) y si aun asi no entra se recorta con puntos, con el valor entero
 * en el title. */
body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .kpi-card .kpi-value h2 {
    font-size: clamp(16px, 12cqw, 26px);
    font-variant-numeric: tabular-nums;
    font-weight: 700;
    letter-spacing: -.02em;
    line-height: 1.15;
    overflow: hidden;
    padding-left: 2px;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* La etiqueta heredaba el line-height del body (24px) para un texto de 10.5px: dos
 * lineas quedaban con 13px de aire entre medio. El interlineado es el del texto. */
body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .kpi-card .kpi-label {
    line-height: 1.25;
    margin-bottom: 0 !important;
    margin-top: 3px;
    padding-left: 2px;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .kpi-card .kpi-label small {
    color: var(--rx-v2-faint) !important;
    display: block;
    font-size: 10.5px !important;
    font-weight: 600 !important;
    letter-spacing: .06em;
    line-height: 1.25;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .kpi-card .kpi-signal,
body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .kpi-card .kpi-comparison {
    justify-content: flex-start !important;
    line-height: 1;
    margin-top: 8px !important;
    padding-left: 2px;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .kpi-card .kpi-signal .badge,
body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .kpi-card .kpi-comparison .badge {
    border-radius: 999px;
    font-size: 10.5px;
    font-weight: 600;
    padding: 2px 7px;
}

/* el semaforo: pill suave del color del estado (el inline trae fondo pleno + blanco; el
 * color viaja tambien en --kpi-sig para poder mezclarlo). El numero ya lleva el color. */
body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .kpi-card .kpi-signal .badge {
    background: color-mix(in srgb, var(--kpi-sig, #1cc88a) 16%, transparent) !important;
    color: var(--kpi-sig, #1cc88a) !important;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .kpi-card .kpi-signal small {
    color: var(--rx-v2-faint) !important;
}

/* el delta contra el periodo anterior: la misma pill suave que el trend badge del panel */
body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .kpi-card .kpi-comparison .badge.badge-success {
    background: color-mix(in srgb, #2fa36b 16%, transparent) !important;
    color: #2fa36b !important;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .kpi-card .kpi-comparison .badge.badge-danger {
    background: color-mix(in srgb, #d9534f 16%, transparent) !important;
    color: #e2726e !important;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .kpi-card .kpi-comparison .badge.badge-secondary {
    background: var(--rx-v2-ghost) !important;
    color: var(--rx-v2-faint) !important;
}

/* -- graficos: mas bajos (los 400px de antes eran la mitad de un telefono) -- */
body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) {
    --rxs-graph-h: 300px;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .chart-mini {
    background: var(--rx-v2-panel-2) !important;
    border-color: var(--rx-v2-border-soft);
}

/* -- feed: llena el panel -- */
body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .rxs-feed {
    max-height: 380px;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .rxs-feed-item {
    background: var(--rx-v2-panel-2);
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .rxs-feed-click:hover {
    background: var(--rx-v2-hover);
}

/* -- lo que se va: los metadatos del pie (lo util paso a la cabecera: "Actualizado ... · 0.6s")
 * y el FAB de refresco (esta en la cabecera) -- */
body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .dashboard-metadata,
body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .floating-actions {
    display: none;
}

/* aviso de "N tarjetas sin info" */
body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .kpi-empty-note {
    color: var(--rx-v2-faint) !important;
}

/* -- mobile -- */
@media (max-width: 767px) {
    body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) {
        --rxs-graph-h: 240px;
    }

    body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .dashboard-header {
        padding: 8px 10px !important;
    }

    body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .dashboard-header .col-lg-6.text-lg-right {
        justify-content: flex-start;
        margin-top: 6px !important;
    }

    /* las funciones SQL (sum/avg/...) y el Top N son de escritorio: en un telefono son dos
     * filas de simbolos entre el titulo y los paneles */
    body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .dashboard-header .sql-functions-selector {
        display: none;
    }

    body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .metric-card > .card-body {
        padding: 2px 10px 10px !important;
    }

    body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .kpi-card .kpi-value h2 {
        font-size: clamp(15px, 12cqw, 24px);
    }

    body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .kpi-container .row {
        grid-template-columns: repeat(auto-fit, minmax(max(124px, var(--rxs-k1), min(var(--rxs-k2), (124px - var(--rxs-k1)) * 1000)), 1fr));
    }
}

/* -- pass 32b: la grilla empaquetada (>= 992px) --
 * (2026-09-28: ya no es densa. La arma en FILAS rxsDashRows() — njs/g_charts.js — que le
 * pasa a cada columna su ancho y su fila por --rxs-cx/--rxs-ox (>= 1200) y --rxs-cl/--rxs-ol
 * (992-1199). Cada fila suma 12 y sus paneles miden lo mismo: se estiran al mas alto. Lo de
 * abajo queda como historia del flujo denso.) */
/* --
 * Filas de bootstrap: un panel bajo al lado de uno alto dejaba el hueco debajo. Ahora es CSS
 * grid de 12 columnas con filas de 4px y flujo denso: el ancho lo sigue diciendo col-xl-N
 * (--rxs-cs), el alto lo media el chunk (rxsDashPack -> --rxs-rs en la columna) y el siguiente
 * panel que entra ocupa el hueco. En edicion (drag & drop) el flujo no es denso: el orden es
 * el que arrastra el usuario. Por debajo de 992 sigue la pila de bootstrap. */
@media (min-width: 992px) {
    body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .dashboard-content .row.align-items-start {
        /* el .align-items-start de bootstrap es !important: sin esto las celdas no se estiran y
         * los paneles de una fila quedan de distinto alto */
        align-items: stretch !important;
        column-gap: 12px;
        display: grid;
        grid-auto-flow: row;
        grid-auto-rows: auto;
        grid-template-columns: repeat(12, minmax(0, 1fr));
        margin: 0;
        row-gap: 0;
    }

    body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact).rxs-dash-edit .dashboard-content .row.align-items-start {
        grid-auto-flow: row;
    }

    body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .dashboard-content .row.align-items-start > [class*="col-"] {
        --rxs-cs: 6;
        flex: none;
        grid-column: span var(--rxs-cl, var(--rxs-cs));
        grid-row: auto;
        margin: 0 !important;
        order: var(--rxs-ol, 0);
        max-width: none;
        min-width: 0;
        padding: 0 0 12px;
        width: auto;
    }

    /* la card mide su contenido (el h-100 la estiraba a la celda y el alto no se podia leer);
     * un height inline de Editar no lleva h-100 y sigue ganando */
    body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .dashboard-content .row.align-items-start > [class*="col-"] > .metric-card.h-100 {
        height: 100% !important;
    }

    /* el .card del tema trae margin-bottom 30px: el gutter aca es el padding de la columna,
     * y con el margen la celda media 42px mas que la card */
    body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .dashboard-content .row.align-items-start > [class*="col-"] > .metric-card {
        margin: 0 !important;
    }

    body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .dashboard-content .row.align-items-start > .col-12 {
        --rxs-cs: 12;
        --rxs-rs: auto;
    }
}

@media (min-width: 1200px) {
    body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .dashboard-content .row.align-items-start > .col-xl-1 { --rxs-cs: 1; }
    body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .dashboard-content .row.align-items-start > .col-xl-2 { --rxs-cs: 2; }
    body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .dashboard-content .row.align-items-start > .col-xl-3 { --rxs-cs: 3; }
    body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .dashboard-content .row.align-items-start > .col-xl-4 { --rxs-cs: 4; }
    body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .dashboard-content .row.align-items-start > .col-xl-5 { --rxs-cs: 5; }
    body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .dashboard-content .row.align-items-start > .col-xl-6 { --rxs-cs: 6; }
    body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .dashboard-content .row.align-items-start > .col-xl-7 { --rxs-cs: 7; }
    body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .dashboard-content .row.align-items-start > .col-xl-8 { --rxs-cs: 8; }
    body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .dashboard-content .row.align-items-start > .col-xl-9 { --rxs-cs: 9; }
    body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .dashboard-content .row.align-items-start > .col-xl-10 { --rxs-cs: 10; }
    body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .dashboard-content .row.align-items-start > .col-xl-11 { --rxs-cs: 11; }
    body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .dashboard-content .row.align-items-start > .col-xl-12 { --rxs-cs: 12; }

    body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .dashboard-content .row.align-items-start > [class*="col-"] {
        grid-column: span var(--rxs-cx, var(--rxs-cs));
        order: var(--rxs-ox, 0);
    }
}

/* el subtitulo "Panel de Control Inteligente" es el default del prop: relleno */
body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .dashboard-header .rxs-dash-sub[data-default="1"] {
    display: none;
}

/* -- esqueleto de carga: seis paneles con brillo en vez del icono girando -- */
body.rxs-ui-v2 .rxs-dash-skel {
    column-gap: 12px;
    display: grid;
    grid-template-columns: repeat(12, minmax(0, 1fr));
    row-gap: 12px;
}

body.rxs-ui-v2 .rxs-dash-skel-p {
    background: var(--rx-v2-panel);
    border: 1px solid var(--rx-v2-border-soft);
    border-radius: var(--rx-v2-r12);
    grid-column: span var(--rxs-cs, 4);
    min-height: 230px;
    padding: 12px;
}

body.rxs-ui-v2 .rxs-dash-skel-t,
body.rxs-ui-v2 .rxs-dash-skel-b {
    animation: rxsDashShimmer 1.4s ease-in-out infinite;
    background: linear-gradient(90deg, var(--rx-v2-ghost) 25%, var(--rx-v2-active) 50%, var(--rx-v2-ghost) 75%);
    background-size: 200% 100%;
    border-radius: var(--rx-v2-r6);
}

body.rxs-ui-v2 .rxs-dash-skel-t {
    height: 12px;
    margin-bottom: 14px;
    width: 45%;
}

body.rxs-ui-v2 .rxs-dash-skel-b {
    height: 160px;
}

@keyframes rxsDashShimmer {
    0% { background-position: 200% 0; }
    100% { background-position: -200% 0; }
}

/* -- pass 33d: el panel que todavia no llego (meta.plan). La card ya esta en su lugar con su
 * titulo; el cuerpo es el brillo del esqueleto al alto estimado del tipo, y lo que no tiene
 * sentido sin dato (acciones, favorito, info) no se dibuja. -- */
body.rxs-ui-v2 .rxs-card-skel {
    display: flex;
    flex-direction: column;
}

body.rxs-ui-v2 .rxs-card-skel .rxs-dash-skel-b {
    flex: 1 1 auto;
    height: auto;
    min-height: 0;
}

body.rxs-ui-v2 .metric-card.rxs-card-loading .card-header .dropdown,
body.rxs-ui-v2 .metric-card.rxs-card-loading .card-header .btn,
body.rxs-ui-v2 .metric-card.rxs-card-loading .card-header .fa-info-circle,
body.rxs-ui-v2 .metric-card.rxs-card-loading .card-header .trend-badge {
    visibility: hidden;
}

body.rxs-ui-v2 .metric-card.rxs-card-loading .card-header h6 {
    color: var(--rx-v2-muted);
}

/* dos alturas que se reservan para que la carga no baje el tablero: el filtro de fecha suma
 * la fila "Periodicidad" cuando dateFilterData lo arma (52 -> 94), y la cabecera suma
 * Periodo y Actualizado con el primer frame (28 -> 70). */
@media (min-width: 768px) {
    body.rxs-ui-v2 .dash-toolbar .filterStv.rxs-v2-fdate {
        min-height: 94px;
    }
}

@media (min-width: 992px) {
    body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .dashboard-header .col-lg-6:not(.text-lg-right) {
        min-height: 70px;
    }
}

@media (max-width: 991px) {
    body.rxs-ui-v2 .rxs-dash-skel-p {
        grid-column: span 12;
        min-height: 150px;
    }

    /* En la pila de un telefono el aire entre paneles era el mb-4 de la columna (24px) mas el
     * margin-bottom de 30px del .card del tema: 54px entre panel y panel, mas que el panel de
     * una cajita. El mismo gutter de 12px que la grilla de escritorio. */
    body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .dashboard-content .row.align-items-start > [class*="col-"] {
        margin-bottom: 12px !important;
    }

    body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .dashboard-content .row.align-items-start > [class*="col-"] > .metric-card {
        margin-bottom: 0 !important;
    }
    body.rxs-ui-v2 .rxs-dash-skel-b {
        height: 90px;
    }
}

@media (prefers-reduced-motion: reduce) {
    body.rxs-ui-v2 .rxs-dash-skel-t,
    body.rxs-ui-v2 .rxs-dash-skel-b {
        animation: none;
    }
}

/* El chip del informe en la barra del drill lleva cruz (volver al listado completo), asi que
   recupera el padding derecho chico. La clase la pone el server: un `:has()` aca costaria un
   recalculo de documento entero por cada insercion de DOM del listado. */
body.rxs-ui-v2 .rxs-module .rxs-drill-chips .rxs-chip.rxs-chip-hasx {
    padding-right: 4px;
}

body.rxs-ui-v2 .rxs-module .rxs-drill-chips a.rxs-chip-x {
    text-decoration: none;
}

/* ---- El select de INFORMES del dropdown de busqueda ----
   Es una celda de filtro mas (misma grilla de anchos que una columna), pero no filtra en el
   cliente: elegir un informe navega al listado acotado por el. El acento lo distingue de un
   filtro de columna, que solo recorta lo que ya esta en pantalla. */
body.rxs-ui-v2 .rxs-filterbar .rxs-filter-reports .input-group-text {
    background: var(--rx-v2-accent-soft);
    border-color: var(--rx-v2-accent-soft);
    color: var(--rx-v2-accent);
}

body.rxs-ui-v2 .select2-dropdown.rxs-reports-drop {
    min-width: 320px;
}

/* ============ pass 33: la tabla adentro de una card del tablero (bloque I) ============
 * Un `column2` era el DataTable del listado metido en la card: header navy de adm.css
 * (`body:not(.blacked) table.table thead th { background:#2c3e50 !important }`, que es
 * global), bordes y cebra de bootstrap, margin-top 20px, y con fixedColumns el scrollX le
 * clonaba el thead y la dejaba al ancho de su contenido: 273px en una card de 570, con el
 * total en un pie clonado aparte (medido en /dash de 1693, 2026-09-18). Ahora la tabla ocupa
 * la card y habla el idioma de la grilla v2: cabecera muda en panel-2, filas sin bordes
 * laterales, hover, y el total como pie de la misma tabla. Scopeado al tablero grande: la
 * tira compacta no dibuja tablas. */
body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .column2-table-container {
    overflow-x: auto;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .column2-table-container table.rxs-card-table {
    background: transparent !important;
    border: 0 !important;
    border-collapse: separate !important;
    border-spacing: 0;
    margin: 0 !important;
    width: 100% !important;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .column2-table-container table.rxs-card-table thead th {
    background: var(--rx-v2-head) !important;
    border: 0 !important;
    border-bottom: 1px solid var(--rx-v2-border) !important;
    box-shadow: none !important;
    color: var(--rx-v2-muted) !important;
    font-size: 10.5px !important;
    font-weight: 600 !important;
    letter-spacing: .07em;
    line-height: 1.3;
    padding: 8px 10px !important;
    text-transform: uppercase;
    vertical-align: bottom;
    /* en una card de 4 columnas "TOTAL CONVERSACIONES" no entra en una linea: envuelve, no
     * se corta (el nowrap de la grilla del listado es para una tabla que scrollea) */
    white-space: normal;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .column2-table-container table.rxs-card-table thead th:first-child {
    border-top-left-radius: var(--rx-v2-r8);
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .column2-table-container table.rxs-card-table thead th:last-child {
    border-top-right-radius: var(--rx-v2-r8);
}

/* la cebra y el hover de bootstrap pintan el <tr>: se apagan ahi y la celda pone el suyo */
body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .column2-table-container table.rxs-card-table tbody tr {
    background: transparent !important;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .column2-table-container table.rxs-card-table tbody td {
    background: transparent !important;
    border: 0 !important;
    border-bottom: 1px solid var(--rx-v2-border-soft) !important;
    color: var(--rx-v2-text) !important;
    font-size: 13px;
    font-variant-numeric: tabular-nums;
    line-height: 1.35;
    padding: 7px 10px !important;
    vertical-align: middle;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .column2-table-container table.rxs-card-table tbody tr:hover > td {
    background: var(--rx-v2-hover) !important;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .column2-table-container table.rxs-card-table tbody tr:last-child > td {
    border-bottom: 0 !important;
}

/* el total del informe: pie de la MISMA tabla, no una caja gris suelta */
body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .column2-table-container table.rxs-card-table tfoot th,
body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .column2-table-container table.rxs-card-table tfoot td {
    background: var(--rx-v2-panel-2) !important;
    border: 0 !important;
    border-top: 1px solid var(--rx-v2-border) !important;
    color: var(--rx-v2-text) !important;
    font-size: 13px !important;
    font-variant-numeric: tabular-nums;
    font-weight: 600 !important;
    padding: 8px 10px !important;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .column2-table-container table.rxs-card-table tfoot th:first-child,
body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .column2-table-container table.rxs-card-table tfoot td:first-child {
    border-bottom-left-radius: var(--rx-v2-r8);
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .column2-table-container table.rxs-card-table tfoot th:last-child,
body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .column2-table-container table.rxs-card-table tfoot td:last-child {
    border-bottom-right-radius: var(--rx-v2-r8);
}

/* "5 de 312 · Ver todo": la linea de abajo, en el gris de la cabecera */
body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .column2-table-container > .small {
    color: var(--rx-v2-faint) !important;
    font-size: 11.5px;
    padding: 6px 2px 0;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .column2-table-container a.rxs-col2-all {
    color: var(--rx-v2-accent);
    font-weight: 600;
    text-decoration: none;
}

/* ============ pass 33 (bloque M): "Todos" por secciones de etiqueta ============
 * El tablero sin etiqueta elegida agrupa los paneles por la primera etiqueta de cada
 * favorito (dashSections, g_charts.js); cada seccion es su propia grilla densa y arriba va
 * el titulo mudo con la cuenta y el link al tablero de esa etiqueta. */
body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .rxs-dash-sec {
    gap: 8px;
    margin: 6px 0 10px !important;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .rxs-dash-sec + .row.align-items-start {
    margin-bottom: 8px;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .rxs-dash-sec-t {
    color: var(--rx-v2-muted) !important;
    font-size: 12px !important;
    font-weight: 700 !important;
    letter-spacing: .06em;
    text-transform: uppercase;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .rxs-dash-sec-n {
    background: var(--rx-v2-ghost) !important;
    border-radius: 999px;
    color: var(--rx-v2-faint) !important;
    font-size: 10.5px;
    font-weight: 600;
    margin: 0 !important;
    padding: 2px 7px;
}

/* la raya que cierra la fila, entre la cuenta y el link */
body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .rxs-dash-sec::after {
    background: var(--rx-v2-border-soft);
    content: '';
    flex: 1 1 auto;
    height: 1px;
    order: 2;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .rxs-dash-sec-go {
    color: var(--rx-v2-accent);
    font-size: 11.5px;
    font-weight: 600;
    margin: 0 !important;
    order: 3;
    text-decoration: none;
    white-space: nowrap;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .rxs-dash-sec-go:hover {
    text-decoration: underline;
}

/* ============ pass 35 (tarea 43837): lo que esta en orden, como chip ============
 * Una cajita con todos sus numeros en verde no ocupa un panel: va en esta linea arriba de la
 * grilla de su seccion (cardOkChip, g_charts.js). El chip de un favorito que todavia no llego
 * (la carga pasada vino en orden) se ve tenue hasta que trae los numeros. */
body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .rxs-dash-ok {
    gap: 6px;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .rxs-dash-ok-chip {
    align-items: center;
    background: var(--rx-v2-panel);
    border: 1px solid var(--rx-v2-border-soft);
    border-radius: 999px;
    color: var(--rx-v2-text);
    display: inline-flex;
    font-size: 12px;
    gap: 6px;
    line-height: 1.4;
    max-width: 100%;
    padding: 4px 10px;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .rxs-dash-ok-chip > .fa-check-circle {
    color: #1cc88a;
    margin: 0 !important;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .rxs-dash-ok-t {
    font-weight: 600;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .rxs-dash-ok-v {
    color: var(--rx-v2-muted);
    white-space: nowrap;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .rxs-dash-ok-chip.is-pending {
    opacity: .55;
}

/* -- la franja "Hoy" (dashToday): una linea de alto FIJO desde el primer frame, que se desliza
 * de costado si no entra. Si creciera al llegar el stream empujaria la grilla entera (CLS). -- */
body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .rxs-dash-today {
    -webkit-overflow-scrolling: touch;
    background: var(--rx-v2-panel);
    border: 1px solid var(--rx-v2-border-soft);
    border-radius: var(--rx-v2-r10);
    gap: 6px;
    height: 44px;
    overflow-x: auto;
    overflow-y: hidden;
    padding: 0 10px;
    scrollbar-width: thin;
    white-space: nowrap;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .rxs-dash-today-t {
    color: var(--rx-v2-muted);
    flex: none;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .06em;
    margin-right: 4px;
    text-transform: uppercase;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .rxs-dash-today-chip {
    align-items: center;
    background: var(--rx-v2-ghost);
    border: 1px solid transparent;
    border-radius: 999px;
    color: var(--rx-v2-text) !important;
    display: inline-flex;
    flex: none;
    font-size: 12px;
    gap: 6px;
    padding: 3px 10px;
    text-decoration: none !important;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .rxs-dash-today-chip:hover {
    border-color: var(--rx-v2-border);
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .rxs-dash-today-chip > i { font-size: 11px; }
body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .rxs-dash-today-chip.is-red > i { color: #e74a3b; }
body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .rxs-dash-today-chip.is-amber > i { color: #f6c23e; }
body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .rxs-dash-today-chip.is-good > i { color: #1cc88a; }
body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .rxs-dash-today-chip.is-bad > i { color: #e74a3b; }
body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .rxs-dash-today-chip.is-flat > i { color: var(--rx-v2-muted); }

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .rxs-dash-today-l {
    color: var(--rx-v2-muted);
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .rxs-dash-today-none {
    color: var(--rx-v2-muted);
    font-size: 12px;
}

/* -- el indice de secciones: fijo debajo de la barra de arriba al bajar -- */
body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .rxs-dash-index {
    -webkit-overflow-scrolling: touch;
    background: var(--rx-v2-bg, var(--rx-v2-panel));
    gap: 4px;
    overflow-x: auto;
    padding: 6px 0;
    position: sticky;
    scrollbar-width: none;
    top: 72px;
    white-space: nowrap;
    z-index: 20;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .rxs-dash-index-a {
    align-items: center;
    border-radius: 999px;
    color: var(--rx-v2-text) !important;
    display: inline-flex;
    flex: none;
    font-size: 12px;
    font-weight: 600;
    gap: 6px;
    padding: 3px 10px;
    text-decoration: none !important;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .rxs-dash-index-a:hover {
    background: var(--rx-v2-hover);
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .rxs-dash-index-a small {
    color: var(--rx-v2-faint);
    font-weight: 500;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .rxs-dash-dot {
    background: var(--rx-v2-border);
    border-radius: 50%;
    display: inline-block;
    flex: none;
    height: 8px;
    width: 8px;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .rxs-dash-dot.is-red { background: #e74a3b; }
body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .rxs-dash-dot.is-amber { background: #f6c23e; }
body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .rxs-dash-dot.is-green { background: #1cc88a; }

/* -- la seccion se pliega desde su titulo -- */
body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .rxs-dash-sec-tg {
    background: transparent;
    border: 0;
    border-radius: var(--rx-v2-r8);
    color: var(--rx-v2-faint);
    font-size: 11px;
    line-height: 1;
    padding: 4px 5px;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .rxs-dash-sec-tg:hover {
    background: var(--rx-v2-hover);
    color: var(--rx-v2-text);
}

/* -- el panel al que lleva un chip de la franja, un momento resaltado -- */
body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .rxs-dash-flash {
    box-shadow: 0 0 0 2px var(--rx-v2-accent) !important;
    transition: box-shadow .3s ease;
}

/* ============ pass 34: lavada de cara del tablero ============
 * Cuatro cosas medidas en /dash de resumax (2026-09-19). (1) La fila de chips de etiqueta
 * flotaba a la izquierda del filtro de fecha, ARRIBA de la cabecera, y visualmente cortaba
 * el borde superior del panel: ahora la barra (chips + fecha) es la tira de arriba del MISMO
 * panel que la cabecera —una sola tarjeta con dos filas—, sin tocar el DOM ni los altos
 * reservados para el CLS (la tira sigue midiendo lo mismo). (2) La minilinea de las cajitas
 * era una polilinea negra de 1,6px estirada a 120px debajo del numero: ahora es una curva con
 * relleno degradado (rxsSparkSvg, en el modulo compartido) a la DERECHA del numero, en el
 * acento del tenant o en el color del semaforo, y la cajita es una grilla —etiqueta arriba,
 * numero + minilinea, semaforo, delta— en vez de una pila centrada. (3) El menu de cada card
 * salia con el body de bootstrap (16px, items de 8px 16px, 584px de alto): toma el mismo
 * cuerpo que el menu del tablero (.rxs-dash-menu). (4) El cromo de ECharts (eje de valor sin
 * linea, grilla punteada, leyenda de puntos, tooltip con sombra, area degradada bajo una
 * linea sola, donas con borde del panel) vive en applyV2Chrome, no aca. */

/* -- (1) la barra de arriba es la tira superior del panel de la cabecera -- */
body.rxs-ui-v2 .dashfavspage .dash-toolbar {
    align-items: center;
    background: var(--rx-v2-panel);
    border: 1px solid var(--rx-v2-border-soft);
    border-bottom: 0;
    border-radius: var(--rx-v2-r12) var(--rx-v2-r12) 0 0;
    gap: 8px 12px;
    margin-bottom: 0;
    padding: 10px 14px 8px;
    position: relative;
}

/* el hilo que separa la tira de la cabecera: adentro del panel, con margen */
body.rxs-ui-v2 .dashfavspage .dash-toolbar::after {
    background: var(--rx-v2-border-soft);
    bottom: 0;
    content: '';
    height: 1px;
    left: 14px;
    position: absolute;
    right: 14px;
}

body.rxs-ui-v2 .dashfavspage .dash-toolbar + .dashboard-full-container:not(.kpi-compact) .dashboard-header {
    border-top: 0;
    border-top-left-radius: 0 !important;
    border-top-right-radius: 0 !important;
}

/* la tarjeta del filtro de fecha deja de ser una tarjeta: es una fila de la tira */
body.rxs-ui-v2 .dashfavspage .dash-toolbar > .filterStv.rxs-v2-fdate {
    flex: 0 1 auto;
    margin-left: auto !important;
}

body.rxs-ui-v2 .dashfavspage .dash-toolbar > .filterStv.rxs-v2-fdate > .input-group.rxs-v2-igdate {
    background: transparent;
    border: 0;
    box-shadow: none;
    justify-content: flex-end;
    padding: 0;
}

body.rxs-ui-v2 .dashfavspage .dash-toolbar > .filterStv.rxs-v2-fdate > .input-group.rxs-v2-igdate > .input-group-prepend {
    height: 34px;
    left: 0;
    top: 0;
    width: 34px;
}

body.rxs-ui-v2 .dashfavspage .dash-toolbar > .filterStv.rxs-v2-fdate > .input-group.rxs-v2-igdate > input.dateFilter {
    height: 34px;
    margin-left: 42px !important;
}

body.rxs-ui-v2 .dashfavspage .dash-toolbar > .filterStv.rxs-v2-fdate > .input-group.rxs-v2-igdate > .text-right,
body.rxs-ui-v2 .dashfavspage .dash-toolbar > .filterStv.rxs-v2-fdate > .input-group.rxs-v2-igdate > .text-end {
    margin-left: 0;
}

body.rxs-ui-v2 .dashfavspage .dash-toolbar > .filterStv.rxs-v2-fdate > .input-group.rxs-v2-igdate select.timedg {
    height: 30px;
}

/* la fila "Periodicidad" ya no suma una linea entera: va al lado de la fecha. Y su ANCHO se
 * reserva: el filtro nace con la fecha sola (345px) al lado de las etiquetas, dateFilterData
 * le suma Periodicidad (580px) medio segundo despues, ya no entra y baja de renglon con todo
 * el tablero atras. Era el 0,108 de CLS que quedaba con memoria en /dash de resumax
 * (docs/repro/dash-cls.mjs, 28-09). Desde el primer frame mide lo que va a medir. */
@media (min-width: 768px) {
    body.rxs-ui-v2 .dashfavspage .dash-toolbar .filterStv.rxs-v2-fdate {
        min-height: 0;
        min-width: min(580px, 100%);
    }
}

/* los chips: pastillas mudas, la activa con el acento suave y el contador como un punto */
body.rxs-ui-v2 .dashfavspage .dash-toolbar > .dash-tags > .btn {
    background: transparent;
    border-color: transparent;
    padding: 5px 10px;
    transition: background .15s ease, color .15s ease;
}

body.rxs-ui-v2 .dashfavspage .dash-toolbar > .dash-tags > .btn:hover {
    background: var(--rx-v2-ghost);
    border-color: transparent;
}

body.rxs-ui-v2 .dashfavspage .dash-toolbar > .dash-tags > .btn.btn-themecolor {
    background: var(--rx-v2-accent-soft);
}

body.rxs-ui-v2 .dashfavspage .dash-toolbar > .dash-tags > .btn .badge {
    background: transparent;
    color: var(--rx-v2-faint);
    font-weight: 500;
    margin-left: 5px;
    padding: 0;
}

body.rxs-ui-v2 .dashfavspage .dash-toolbar > .dash-tags > .btn.btn-themecolor .badge {
    color: inherit;
    opacity: .75;
}

/* -- (2) la cajita de KPI como grilla: etiqueta / numero + minilinea / semaforo / delta -- */
body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .kpi-card {
    --rxs-spark-ink: var(--rx-v2-accent);
    align-items: end;
    column-gap: 10px;
    display: grid;
    grid-template-areas:
        "label label"
        "value spark"
        "signal signal"
        "cmp cmp";
    grid-template-columns: minmax(0, 1fr) auto;
    padding: 11px 12px 11px !important;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .kpi-card .kpi-label {
    grid-area: label;
    margin-top: 0;
    padding-left: 0;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .kpi-card .kpi-value {
    grid-area: value;
    min-width: 0;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .kpi-card .kpi-value h2 {
    padding-left: 0;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .kpi-card .kpi-spark {
    align-self: end;
    color: var(--rxs-spark-ink);
    grid-area: spark;
    margin: 0 0 3px !important;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .kpi-card .kpi-spark svg {
    display: block;
    height: 26px;
    width: clamp(52px, 32cqw, 88px);
}

/* Con la minilinea al lado, una cajita de 163px le dejaba 75px al numero: "2.714 episodios" y
 * "US$ 12.345,67" salian cortados con puntos (/dash/tag_dev, 26-09). Cuando la columna es
 * angosta la minilinea baja debajo del numero y el numero se queda con el ancho entero. La
 * consulta mira la COLUMNA y no la cajita: una container query no puede cambiar la grilla
 * del mismo elemento que es el contenedor. */
body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .kpi-container .row > .col {
    container: rxs-kpi-col / inline-size;
}

/* 2026-09-28: la minilinea va SIEMPRE debajo del numero. Al lado, con las cajitas llenando el
 * panel, el numero quedaba con lo que dejaba la linea: en una misma tira "N/A" sin serie salia
 * a 28px y "N/A" con serie a 16, y "28.709 llamadas" cortado con puntos en una cajita de 300px.
 * Abajo el numero tiene el ancho entero y la linea tambien. (Antes era solo con la columna de
 * menos de 220px.) */
body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .kpi-card {
    /* arriba: una cajita sin serie al lado de una con serie tenia el numero mas abajo */
    align-content: start;
    align-items: start;
    grid-template-areas:
        "label"
        "value"
        "spark"
        "signal"
        "cmp";
    grid-template-columns: minmax(0, 1fr);
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .kpi-card .kpi-spark {
    margin: 4px 0 0 !important;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .kpi-card .kpi-spark svg {
    height: 24px;
    width: 100%;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .kpi-card .kpi-signal {
    grid-area: signal;
    padding-left: 0;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .kpi-card .kpi-comparison {
    grid-area: cmp;
    padding-left: 0;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .kpi-card .kpi-signal + .kpi-comparison {
    margin-top: 5px !important;
}

/* -- (2b) las cajitas de un mismo widget como UN panel segmentado, igual que la tira del
 * listado: antes eran cajas con borde propio y m-1/mb-3 dentro de la card (caja dentro de
 * caja, con canaletas desparejas). Divisores por box-shadow hacia arriba/izquierda: los de la
 * primera fila/columna caen afuera y el overflow los recorta, asi el wrap no deja rayas. -- */
body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .kpi-container .row:has(> .col > .kpi-card) {
    border: 1px solid var(--rx-v2-border-soft);
    border-radius: var(--rx-v2-r12);
    margin: 0 !important;
    overflow: hidden;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .kpi-container .row > .col:has(> .kpi-card) {
    box-shadow: -1px 0 0 var(--rx-v2-border-soft), 0 -1px 0 var(--rx-v2-border-soft);
    margin: 0 !important;
    padding: 0 !important;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .kpi-container .row > .col > .kpi-card {
    background: transparent !important;
    border: 0 !important;
    border-radius: 0 !important;
    box-shadow: none !important;
    margin: 0 !important;
    padding: 12px 14px !important;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .kpi-container .row > .col > .kpi-card.kpi-drill:hover {
    background: color-mix(in srgb, var(--rx-v2-accent) 5%, transparent) !important;
    transform: none;
}

body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .kpi-card .kpi-value h2 {
    font-variant-numeric: tabular-nums;
    letter-spacing: -.02em;
}

/* -- (3) el menu de cada card, con el cuerpo del menu del tablero -- */
body.rxs-ui-v2 .rxs-dash-menu,
body.rxs-ui-v2 .rxs-card-menu {
    border: 1px solid var(--rx-v2-border-soft);
    border-radius: var(--rx-v2-r10);
    box-shadow: var(--rx-v2-shadow);
    font-size: 13px;
    max-height: min(72vh, 560px);
    min-width: 232px;
    overflow-y: auto;
    padding: 6px;
    text-align: left;
}

body.rxs-ui-v2 .rxs-card-menu .dropdown-item {
    align-items: center;
    border-radius: var(--rx-v2-r7);
    color: var(--rx-v2-text);
    display: flex;
    font-size: 13px;
    gap: 8px;
    padding: 6px 8px;
}

body.rxs-ui-v2 .rxs-card-menu .dropdown-item > i {
    color: var(--rx-v2-faint);
    font-size: 12px;
    margin: 0 !important;
    text-align: center;
    width: 16px;
}

body.rxs-ui-v2 .rxs-card-menu .dropdown-item:hover,
body.rxs-ui-v2 .rxs-card-menu .dropdown-item:focus {
    background: var(--rx-v2-ghost);
    color: var(--rx-v2-text);
}

body.rxs-ui-v2 .rxs-card-menu .dropdown-item.active,
body.rxs-ui-v2 .rxs-card-menu .dropdown-item:active {
    background: transparent;
    color: var(--rx-v2-text);
}

body.rxs-ui-v2 .rxs-card-menu .dropdown-item.rxs-dash-menu-chk.active > i {
    color: var(--rx-v2-accent);
}

body.rxs-ui-v2 .rxs-card-menu .dropdown-item.text-danger,
body.rxs-ui-v2 .rxs-card-menu .dropdown-item.text-danger > i {
    color: #e2726e !important;
}

body.rxs-ui-v2 .rxs-card-menu .dropdown-item.text-success,
body.rxs-ui-v2 .rxs-card-menu .dropdown-item.text-success > i,
body.rxs-ui-v2 .rxs-card-menu .dropdown-item.text-primary,
body.rxs-ui-v2 .rxs-card-menu .dropdown-item.text-primary > i {
    color: var(--rx-v2-accent) !important;
}

body.rxs-ui-v2 .rxs-card-menu .dropdown-header {
    color: var(--rx-v2-faint);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .04em;
    padding: 8px 8px 4px;
    text-transform: uppercase;
}

body.rxs-ui-v2 .rxs-card-menu .dropdown-item-text {
    color: var(--rx-v2-muted) !important;
    font-size: 12px !important;
    line-height: 1.4;
    padding: 2px 8px 6px;
}

body.rxs-ui-v2 .rxs-card-menu .dropdown-divider,
body.rxs-ui-v2 .rxs-dash-menu .dropdown-divider {
    border-top-color: var(--rx-v2-border-soft);
    margin: 4px 2px;
}

/* dos divisores seguidos (el bloque "Ventana del panel" abre y cierra con uno) son uno */
body.rxs-ui-v2 .rxs-card-menu .dropdown-divider + .dropdown-divider,
body.rxs-ui-v2 .rxs-card-menu .dropdown-divider:first-child {
    display: none;
}

/* en un telefono la tira de periodos no entra (se cortaba en "Este me..."): se desliza a lo
 * ancho en vez de cortarse, sin barra visible */
@media (max-width: 767px) {
    body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .dashboard-header .rxs-dash-periods {
        -ms-overflow-style: none;
        flex-wrap: nowrap;
        max-width: 100%;
        overflow-x: auto;
        scrollbar-width: none;
    }

    body.rxs-ui-v2 .dashboard-full-container:not(.kpi-compact) .dashboard-header .rxs-dash-periods::-webkit-scrollbar {
        display: none;
    }
}

/* Unificar duplicados (modal de la seleccion de la grilla). Reusa la card de la grilla v2
 * (.rxs-v2-card / -line / -lbl / -val): cada registro es una card, el que queda va marcado y
 * en cada linea se elige de que card sale el valor. Una linea por campo y el valor recortado a
 * un renglon, asi las cards quedan alineadas campo contra campo. */
.rxs-merge[v-cloak] {
    display: none;
}

body.rxs-ui-v2 .rxs-merge-head {
    margin-bottom: 14px;
    color: var(--rx-v2-muted);
    font-size: 13px;
}

body.rxs-ui-v2 .rxs-merge-head b {
    color: var(--rx-v2-text);
}

/* La card de la grilla reparte las lineas en fila (etiqueta sobre valor). Para comparar hace
 * falta lo contrario: una linea por campo, etiqueta a la izquierda y valor a la derecha, asi
 * el mismo campo cae a la misma altura en todas las cards. */
body.rxs-ui-v2 .rxs-merge-card {
    text-align: left;
}

body.rxs-ui-v2 .rxs-merge-card .rxs-v2-card-lines {
    display: block;
}

body.rxs-ui-v2 .rxs-merge-card {
    cursor: default;
    transition: border-color .15s ease, box-shadow .15s ease;
}

body.rxs-ui-v2 .rxs-merge-card.is-master {
    border-color: var(--rx-v2-accent);
    box-shadow: 0 0 0 1px var(--rx-v2-accent), var(--rx-v2-shadow);
}

body.rxs-ui-v2 .rxs-merge-card-head {
    display: flex;
    align-items: center;
    gap: 10px;
    padding-bottom: 10px;
    margin-bottom: 4px;
    border-bottom: 1px solid var(--rx-v2-border-soft);
    cursor: pointer;
}

body.rxs-ui-v2 .rxs-merge-card-title {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
}

body.rxs-ui-v2 .rxs-merge-card-title b {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

body.rxs-ui-v2 .rxs-merge-card-title small {
    color: var(--rx-v2-muted);
}

body.rxs-ui-v2 .rxs-merge-radio {
    flex: 0 0 18px;
    height: 18px;
    border-radius: 50%;
    border: 2px solid var(--rx-v2-border);
}

body.rxs-ui-v2 .rxs-merge-radio.is-on {
    border-color: var(--rx-v2-accent);
    box-shadow: inset 0 0 0 3px var(--rx-v2-panel);
    background: var(--rx-v2-accent);
}

body.rxs-ui-v2 .rxs-merge-state {
    flex: 0 0 auto;
    white-space: nowrap;
}

body.rxs-ui-v2 .rxs-merge-state.is-keep {
    background: var(--rx-v2-accent-soft);
    color: var(--rx-v2-accent);
}

body.rxs-ui-v2 .rxs-merge-state.is-out {
    color: var(--rx-v2-muted);
}

body.rxs-ui-v2 .rxs-merge-card .rxs-merge-line {
    display: flex;
    flex-direction: row;
    flex-wrap: nowrap;
    align-items: baseline;
    justify-content: space-between;
    gap: 10px;
    margin: 0 -6px;
    padding: 6px;
    border-radius: var(--rx-v2-r7);
    cursor: pointer;
}

body.rxs-ui-v2 .rxs-merge-card .rxs-merge-line .rxs-v2-card-lbl {
    flex: 0 0 40%;
}

body.rxs-ui-v2 .rxs-merge-line .rxs-v2-card-val {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

body.rxs-ui-v2 .rxs-merge-line:hover {
    background: var(--rx-v2-hover);
}

body.rxs-ui-v2 .rxs-merge-line.is-pick {
    background: var(--rx-v2-accent-soft);
}

body.rxs-ui-v2 .rxs-merge-line.is-pick .rxs-v2-card-val {
    color: var(--rx-v2-accent);
    font-weight: 600;
}

body.rxs-ui-v2 .rxs-merge-line.is-empty,
body.rxs-ui-v2 .rxs-merge-line.is-same {
    cursor: default;
}

body.rxs-ui-v2 .rxs-merge-line.is-empty .rxs-v2-card-val,
body.rxs-ui-v2 .rxs-merge-line.is-same .rxs-v2-card-val {
    color: var(--rx-v2-muted);
}

body.rxs-ui-v2 .rxs-merge-line.is-empty:hover,
body.rxs-ui-v2 .rxs-merge-line.is-same:hover {
    background: transparent;
}

body.rxs-ui-v2 .rxs-merge-foot {
    display: flex;
    flex-direction: column;
    gap: 12px;
    margin-top: 14px;
}

body.rxs-ui-v2 .rxs-merge-toggle {
    align-self: flex-start;
    padding: 0;
    color: var(--rx-v2-accent);
    font-size: 13px;
}

body.rxs-ui-v2 .rxs-merge-impact {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
    padding: 10px 12px;
    border-radius: var(--rx-v2-r12);
    background: var(--rx-v2-accent-soft);
}

body.rxs-ui-v2 .rxs-merge-impact-title {
    flex: 1 1 100%;
    font-size: 13px;
}

body.rxs-ui-v2 .rxs-merge-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 3px 10px;
    border-radius: 999px;
    background: var(--rx-v2-panel);
    border: 1px solid var(--rx-v2-border-soft);
    font-size: 12px;
}

body.rxs-ui-v2 .rxs-merge-chip b {
    color: var(--rx-v2-accent);
}

body.rxs-ui-v2 .rxs-merge-btns {
    display: flex;
    justify-content: flex-end;
    gap: 8px;
}

/* Buscar duplicados: la barra de campos (chips + un select para sumar otro) y el criterio de
 * cual queda; abajo una card por grupo, con sus registros de muestra y el boton que lo abre en
 * el modal de unificar. */
body.rxs-ui-v2 .rxs-merge-find-bar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    margin-bottom: 14px;
}

body.rxs-ui-v2 .rxs-merge-find-on {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
    min-width: 0;
}

body.rxs-ui-v2 .rxs-merge-chip.is-on {
    background: var(--rx-v2-accent-soft);
    border-color: transparent;
    color: var(--rx-v2-accent);
    font-weight: 600;
}

body.rxs-ui-v2 .rxs-merge-chip-x {
    padding: 0 2px;
    border: 0;
    background: transparent;
    color: inherit;
    font-size: 15px;
    line-height: 1;
    cursor: pointer;
}

body.rxs-ui-v2 .rxs-merge-chip-num {
    padding: 0 5px;
    border: 1px solid currentColor;
    border-radius: 6px;
    background: transparent;
    color: inherit;
    font-size: 10px;
    font-weight: 600;
    line-height: 15px;
    opacity: .45;
    cursor: pointer;
}

body.rxs-ui-v2 .rxs-merge-chip-num.is-on {
    opacity: 1;
}

body.rxs-ui-v2 .rxs-merge-find-add {
    width: auto;
    max-width: 220px;
}

body.rxs-ui-v2 .rxs-merge-find-crit {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 0;
    color: var(--rx-v2-muted);
    font-size: 13px;
}

body.rxs-ui-v2 .rxs-merge-find-crit select {
    width: auto;
}

body.rxs-ui-v2 .rxs-merge-find-sum {
    margin-bottom: 10px;
    color: var(--rx-v2-muted);
    font-size: 13px;
}

body.rxs-ui-v2 .rxs-merge-find-sum b {
    color: var(--rx-v2-text);
}

body.rxs-ui-v2 .rxs-merge-groups > div {
    margin-bottom: 14px;
}

body.rxs-ui-v2 .rxs-merge-group {
    display: flex;
    flex-direction: column;
    text-align: left;
    cursor: default;
}

body.rxs-ui-v2 .rxs-merge-group .rxs-v2-card-lines {
    display: block;
    flex: 1 1 auto;
}

body.rxs-ui-v2 .rxs-merge-group .rxs-merge-line,
body.rxs-ui-v2 .rxs-merge-group .rxs-merge-line:hover {
    cursor: default;
    background: transparent;
}

body.rxs-ui-v2 .rxs-merge-group .rxs-merge-line .rxs-v2-card-lbl {
    flex: 0 0 auto;
}

body.rxs-ui-v2 .rxs-merge-more {
    padding: 4px 0;
    color: var(--rx-v2-muted);
    font-size: 12px;
}

body.rxs-ui-v2 .rxs-merge-group-btn {
    align-self: flex-end;
    margin-top: 10px;
}

/* Deshacer: un renglon por registro que vuelve, y el impacto con los campos en conflicto. */
body.rxs-ui-v2 .rxs-merge-undo-list {
    display: flex;
    flex-direction: column;
    gap: 8px;
    margin-bottom: 12px;
}

body.rxs-ui-v2 .rxs-merge-undo-rec {
    display: flex;
    flex-direction: row;
    justify-content: flex-start;
    align-items: center;
    gap: 12px;
    text-align: left;
}

body.rxs-ui-v2 .rxs-merge-undo-rec > .fa {
    color: var(--rx-v2-accent);
}

body.rxs-ui-v2 .rxs-merge-undo .rxs-merge-btns {
    margin-top: 14px;
}

/* un campo que no vuelve: punteado y apagado, sin inventar un color de alerta que el tema no tiene */
body.rxs-ui-v2 .rxs-merge-chip.is-warn {
    border-style: dashed;
    color: var(--rx-v2-muted);
}
