/* ==========================================================================
   TEMA NUEVO — reglas que USAN los tokens de app.tokens.css
   ==========================================================================

   ESTA HOJA SÓLO CARGA EN LOCAL, a propósito (ver `layouts/app.blade.php`).
   Es el borrador del rediseño: acá se prueba cómo queda la plataforma con la
   paleta nueva sin que producción se entere. Cuando esté aprobado se saca el
   `@if` del layout y pasa a cargar en los dos lados.

   POR QUÉ DOS HOJAS Y NO UNA. `app.tokens.css` sólo declara variables y carga
   SIEMPRE, también en producción. Si los tokens estuvieran gateados y una
   regla de `app.custom.css` usara `var(--cb-marca)`, en producción esa
   variable no existiría, **la declaración entera se volvería inválida** y el
   color se perdería. Declarar siempre y pintar sólo en local es lo que hace
   que esto no pueda romper nada.

   CÓMO SE AGREGA UNA REGLA ACÁ. Se copia el selector de `app.custom.css` o del
   tema, y se reemplaza el hex por el token. Nada más — como esta hoja carga
   última, gana sin necesidad de `!important`.
   ========================================================================== */

/* Todavía vacía: los tokens están definidos y esta hoja es donde se van a
   escribir las reglas que los usen, de a una y comparando contra la actual.
   La pantalla de referencia es /config/system/paleta. */

/* --------------------------------------------------------------------------
   1) EL ACENTO: de azul a verde
   --------------------------------------------------------------------------
   El tema comprado pinta `.btn-primary` y los links con `#2949ef`. Acá se
   reemplaza por el token, sin tocar el tema — esta hoja carga última, así que
   gana sin `!important`.

   Los links usan `--cb-marca-oscuro` y no `--cb-marca`: el verde claro sobre
   blanco da 3,65:1 y para texto chico hace falta 4,5. El oscuro da 8,42:1 y se
   lee como el mismo verde.
   -------------------------------------------------------------------------- */
a {
    color: var(--cb-marca-oscuro);
}

a:hover,
a:focus {
    color: var(--cb-marca-hover);
}

.btn-primary,
.btn-primary:disabled,
.btn-primary.disabled {
    color: var(--cb-marca-contraste);
    background-color: var(--cb-marca);
    border-color: var(--cb-marca);
}

.btn-primary:hover,
.btn-primary:focus,
.btn-primary.focus,
.btn-primary:not(:disabled):not(.disabled):active,
.btn-primary:not(:disabled):not(.disabled).active {
    color: var(--cb-marca-contraste);
    background-color: var(--cb-marca-hover);
    border-color: var(--cb-marca-hover);
}

/* El foco del tema deja un halo azul que delata el color viejo. */
.btn-primary:focus,
.btn-primary.focus {
    box-shadow: 0 0 0 .2rem rgba(0, 153, 102, .35);
}

/* Pedido por Miguel el 2026-08-22: los outline en verde por default hacían que
   el mismo botón —"Suscribirme", "Cambiar plan"— se viera azul en Cursos (que
   ya tenía una regla puntual) y verde en cualquier otra pantalla que no la
   tuviera, por ejemplo `subscriptionPlans.blade.php` incluido en `/research` o
   el dashboard. `.btn-outline-primary` se usa en unas 80 vistas del panel, así
   que en vez de seguir agregando una regla por ruta, el default pasa a azul
   —el mismo `--cb-secundario` de `.btn-outline-secondary`— y con eso se
   resuelve para todo el panel de una vez. Las reglas puntuales que ya
   convertían pantallas sueltas (Cursos, Grupos, Suscripciones) quedan
   redundantes pero no rompen nada: dicen lo mismo. */
.btn-outline-primary {
    color: var(--cb-secundario);
    border-color: var(--cb-secundario);
    background-color: transparent;
}

.btn-outline-primary:hover,
.btn-outline-primary:focus,
.btn-outline-primary:not(:disabled):not(.disabled):active {
    color: var(--cb-secundario-contraste);
    background-color: var(--cb-secundario);
    border-color: var(--cb-secundario);
}

.text-primary { color: var(--cb-marca-oscuro) !important; }
.bg-primary   { background-color: var(--cb-marca) !important; }
.border-primary { border-color: var(--cb-marca) !important; }

/* --------------------------------------------------------------------------
   2) LOS ESTADOS, unificados
   --------------------------------------------------------------------------
   Acá está la mitad del problema que se midió: el tema pinta `.badge-success`
   de TURQUESA (`#06b5b6`) mientras las vistas usan `#28a745` y `#4caf50` a
   mano para lo mismo. Tres verdes para un solo significado.
   -------------------------------------------------------------------------- */
/* LOS BADGES LLEVAN TEXTO BLANCO, no `-contraste`. Esos tokens están pensados
   para el fondo SUAVE, no para el sólido, y acá quedaban ilegibles: el de info
   daba **2,35:1** (`#0d47a1` sobre el azul) — literalmente no se leía.

   El blanco da 3,68:1 en info, 3,13:1 en ok y 4,53:1 en danger. El de alerta es
   el caso incómodo —blanco 1,97:1 contra 3,17:1 del oscuro— pero se decidió el
   texto blanco en los alerts por consistencia, así que los badges siguen el
   mismo criterio.

   El nombre del token es lo que confunde: `-contraste` debería significar
   "texto sobre el color sólido" y en alerta e info significa "sobre el suave".
   Vale renombrarlo cuando se limpie esto. */
.badge-success, .bg-success { background-color: var(--cb-ok) !important;     color: #fff !important; }
.badge-warning, .bg-warning { background-color: var(--cb-alerta) !important; color: #fff !important; }
.badge-danger,  .bg-danger  { background-color: var(--cb-error) !important;  color: #fff !important; }
.badge-info,    .bg-info    { background-color: var(--cb-info) !important;   color: #fff !important; }

.text-success { color: var(--cb-ok) !important; }
.text-warning { color: var(--cb-alerta) !important; }
.text-danger  { color: var(--cb-error) !important; }
.text-info    { color: var(--cb-info) !important; }

.btn-success { background-color: var(--cb-ok); border-color: var(--cb-ok); color: var(--cb-ok-contraste); }
.btn-danger  { background-color: var(--cb-error); border-color: var(--cb-error); color: var(--cb-error-contraste); }
.btn-warning { background-color: var(--cb-alerta); border-color: var(--cb-alerta); color: var(--cb-alerta-contraste); }

/* --------------------------------------------------------------------------
   LOS ALERTS: fondo sólido, texto BLANCO — oscureciendo el fondo
   --------------------------------------------------------------------------
   Decidido por Miguel: **el texto va en blanco y el fondo queda como estaba**,
   el sólido del tema. Se probó oscurecer los fondos para alcanzar 4,5:1 y se
   volvió atrás — se veían apagados.

   Queda anotado el dato, medido: sobre el naranja del tema el blanco da
   **1,97:1**, sobre el verde 3,13:1 y sobre el azul 3,68:1. El rojo es el único
   que pasa (4,53:1). Es el estado que ya tenía la app desde antes de todo esto;
   lo que sí se arregla acá es que **las 24 vistas queden parejas**, traigan o no
   `text-white` en el markup.
   -------------------------------------------------------------------------- */
.alert-warning, .alert-warning .text-white, .alert-warning.text-white,
.alert-success, .alert-success .text-white, .alert-success.text-white,
.alert-info,    .alert-info .text-white,    .alert-info.text-white,
.alert-danger,  .alert-danger .text-white,  .alert-danger.text-white {
    color: #ffffff !important;
}

/* Los enlaces dentro de un alert siguen al texto: si no se van al verde de
   marca, que sobre estos fondos no se lee. */
.alert-warning a, .alert-success a, .alert-info a, .alert-danger a {
    color: inherit;
    text-decoration: underline;
}

/* NOTA: el fondo lo maneja el tema tokenizado, con fondo SÓLIDO.
   Se probó pasarlos a fondo suave con texto oscuro y quedó ilegible: el tema los
   pinta llenos —naranja, rojo, verde— y por eso **5 vistas les agregan
   `text-white`** (`home_user`, `allPost`, `cards-video`, los dos `faq` de
   Balanz). Ese `text-white` le gana al `color` de la regla, así que el fondo
   claro dejaba texto blanco sobre casi-blanco.

   Cambiarlos de verdad significa sacar el `text-white` de esas vistas primero.
   Mientras tanto, el color sale igual de los tokens: el tema ya dice
   `background-color: var(--cb-alerta)`. */

/* --------------------------------------------------------------------------
   3) SUPERFICIES
   --------------------------------------------------------------------------
   El fondo de la página y el de las cards salen de los tokens, así el modo
   oscuro no necesita una regla propia: se redefine la variable y listo.
   -------------------------------------------------------------------------- */
body {
    background-color: var(--cb-fondo);
    color: var(--cb-texto);
    border-top-color: var(--cb-marca);
}

.card {
    background-color: var(--cb-superficie);
    border-color: var(--cb-borde);
}

.table th,
.table td { border-color: var(--cb-borde); }
/* EL ENCABEZADO DE TABLA va en el azul de marca con letra blanca. Antes era
   `--cb-gris-200` con texto gris —el del tema—, que sobre el fondo claro del
   área casi no se separaba de las filas. El azul le da un techo claro a la
   tabla, y es coherente con la barra lateral: el azul es la estructura.

   Se cubren las tres variantes porque en las vistas sólo se usa `thead-light`
   (24 tablas), pero el día que alguien copie un `thead-dark` de la documentación
   del tema va a quedar igual. Blanco sobre el azul da 15,97:1. */
.thead-light th,
.thead-dark th,
.thead-primary th,
.table .thead-light th,
.table .thead-dark th,
.table .thead-primary th {
    background-color: var(--cb-secundario);
    color: var(--cb-secundario-contraste);
    border-color: var(--cb-secundario-hover);
}

.text-muted { color: var(--cb-texto-suave) !important; }

/* --------------------------------------------------------------------------
   4) LOS ICONOS DECORATIVOS NO SON ADVERTENCIAS
   --------------------------------------------------------------------------
   El tema usa `.text-warning` como color de adorno, no por su significado: de
   los 144 `data-widget-icon` de las vistas, **142 llevan `text-warning`** y
   ninguno advierte nada — son el ícono del widget (un carrito, un signo peso,
   una gente). Con el naranja del token quedaban gritando en cada dashboard.

   Pasan al color de marca, que es lo que son: un adorno con la identidad de la
   app.

   `.text-warning` NO se toca en general, porque sí hay advertencias de verdad
   usándolo — son dos: `ft-alert-triangle` y `fa-exclamation-triangle`. Ésas
   tienen que seguir naranjas. De ahí que el selector sea la combinación y no
   la clase sola.
   -------------------------------------------------------------------------- */
.data-widget-icon.text-warning,
i.font-40.text-warning {
    color: var(--cb-marca) !important;
}

/* --------------------------------------------------------------------------
   5) EL ÁREA DE CONTENIDO
   --------------------------------------------------------------------------
   Pedido por Miguel el 2026-08-21: **`#eaedfd`** en modo claro — un lavanda muy
   claro, que tiene su propio token (`--cb-area`) porque no pertenece a la
   familia del verde.

   Y es el mejor ejemplo de para qué sirve todo esto. Hoy ese mismo fondo está
   escrito DOS veces en DOS archivos:

       app.custom.css:9      →  #ebebeb   (claro)
       app.dark-mode.css:196 →  #0f172b   (oscuro)

   Acá es UNA regla. El modo oscuro sale gratis porque `--cb-area` ya vale
   `#0f172b` bajo `body.dark` — el mismo que usa hoy. Cuando esto se apruebe,
   las dos reglas viejas se borran.

   La transición se conserva: viene del dark mode y suaviza el cambio de tema.
   -------------------------------------------------------------------------- */
.content-area {
    background-color: var(--cb-area);
    -webkit-transition: 0.3s ease all;
    transition: 0.3s ease all;
}

/* --------------------------------------------------------------------------
   6) UNA SOLA FORMA DE BOTÓN
   --------------------------------------------------------------------------
   Medido el 2026-08-21: de los 1.105 botones de las vistas, **939 son cuadrados
   (radio 0, el del tema) y 166 son píldora** (`.btn-rounded`, radio 50px) — en
   94 archivos. No son dos estilos parecidos que chocan: son los dos extremos.

   Se unifica desde acá y no borrando la clase de los 94 archivos, por dos
   razones: es reversible de una línea, y `.btn-rounded` sigue existiendo por si
   algún día se quiere la píldora a propósito en algún lugar puntual.

   DECIDIDO: **`.6rem` para todo** (9,6px), el radio que el tema ya le daba a las
   cards y los modales. Antes convivían cuatro: cards y modales a `.6rem`,
   controles a `.25rem`, botones a 0 y los 166 `.btn-rounded` a 50px.

   Con los botones en 0 y los inputs en 4px, un botón al lado de un input en el
   mismo formulario se veía desparejo — que es lo que motivó unificarlos.

   ES UN SOLO NÚMERO. `.25rem` lo lleva al radio de los controles del tema y `0`
   vuelve todo cuadrado. Se prueba y se decide mirando.
   -------------------------------------------------------------------------- */
:root {
    --cb-radio-boton: .6rem;
}

.btn,
.btn-rounded,
.btn-group > .btn,
.input-group .btn {
    border-radius: var(--cb-radio-boton) !important;
}

/* Los grupos de botones pegados no llevan radio en los lados que se tocan, o se
   ve una muesca entre uno y otro. */
.btn-group > .btn:not(:last-child),
.btn-group > .btn:not(:last-child) .dropdown-toggle {
    border-top-right-radius: 0 !important;
    border-bottom-right-radius: 0 !important;
}

.btn-group > .btn:not(:first-child) {
    border-top-left-radius: 0 !important;
    border-bottom-left-radius: 0 !important;
}

/* Los CONTENEDORES y los CONTROLES comparten el radio, que es lo que pedía el
   ojo: una card a `.6rem` con inputs a `.25rem` adentro se lee como dos
   sistemas. Se toma el de las cards, que es el más redondeado de los dos. */
.card,
.modal-content,
.form-control,
.custom-select,
.input-group-text,
.badge,
.alert {
    border-radius: var(--cb-radio-boton);
}

/* --------------------------------------------------------------------------
   7) LA BARRA DE "ESTÁS EN LOCAL"
   --------------------------------------------------------------------------
   El aviso de entorno era rojo (`#fe4d2e`), que es el mismo tono que la app usa
   para errores — leía como "algo se rompió" cuando sólo dice "estás en local".
   Pasa al verde de marca.

   El color vive INLINE en `partials/navbar.blade.php`, dentro de un
   `@env('local')`, así que ese atributo ni se imprime en producción. Acá sólo
   se acompaña el modo oscuro, que sí tenía su propia regla (`#741909`, el rojo
   apagado) en `app.dark-mode.css:245`.
   -------------------------------------------------------------------------- */
body.dark .header.local-env-header {
    background-color: var(--cb-marca-suave) !important;
}

/* --------------------------------------------------------------------------
   8) EL ÍTEM ACTIVO DEL MENÚ
   --------------------------------------------------------------------------
   Era `#043263` —un azul marino— tanto en `.mm-active` como en el `:hover` del
   menú, así que "dónde estoy" y "dónde tengo el mouse" se veían **igual**.
   Ahora el activo lleva el verde de marca y el hover una versión más tenue, que
   es lo que hace que se distingan.

   El color venía de `app.custom.css:44`, y en `app.dark-mode.css` la misma regla
   está escrita DOS veces, idéntica (líneas 257 y 269) — otro caso de lo que los
   tokens vienen a evitar.
   -------------------------------------------------------------------------- */
/* SE PINTA EL RENGLÓN DEL LINK, NO EL `li`.
   Un ítem con submenú es `<li class="mm-active"><a>…</a><ul>…</ul></li>`: al
   pintar el `li`, se pintaba **el bloque entero con el submenú adentro** y el
   menú de Cursos quedaba todo verde al abrirlo. */
.sidebar-menu li.mm-active {
    background-color: transparent;
}

.sidebar-menu li.mm-active > a {
    background-color: var(--cb-marca);
    color: var(--cb-marca-contraste);
}

/* EL PADRE DE UN SUBMENÚ ABIERTO no es "dónde estoy", es "por dónde llegué":
   lleva el mismo realce que el hover, no el verde. `metisMenu` le pone
   `mm-active` igual que al hijo, y la única forma de distinguirlos es que el
   padre contiene un `<ul>`. */
.sidebar-menu li.mm-active:has(> ul) > a {
    background-color: var(--cb-sidebar-hover);
    /* Blanco explícito y no `inherit`: heredaba el color de link de la app —el
       verde oscuro que se puso para el texto sobre fondo claro— y sobre el azul
       de la barra no se leía. Da 11,2:1. */
    color: #ffffff;
}

/* El submenú abierto se separa apenas del resto, sin llegar al realce del
   hover: es un fondo, no un elemento sobre el que se está. */
.sidebar-menu li.mm-active > ul {
    background-color: rgba(0, 0, 0, .15);
}

/* EL HOVER NO ES VERDE. El verde queda reservado para el ítem ACTIVO —"dónde
   estoy"—; el hover es sólo un realce de la barra —"dónde tengo el mouse"—. Si
   los dos fueran del color de marca, el menú parecería cambiar de sección al
   pasar el mouse.

   Antes los dos eran `#043263` y no se distinguían en absoluto.

   VA SÓLO SOBRE EL `<a>`, Y SÓLO SI NO ES EL ACTIVO. Estaba escrito
   `.page-sidebar ul :hover`, un descendiente suelto: pinta **cualquier**
   elemento bajo el puntero, y en un ítem del menú hay cuatro —el `li`, el `a`,
   el `<i>` del ícono y el `<span class="nav-label">`—. El `a` se salvaba por
   especificidad (`li.mm-active > a` es 0,2,2), pero el `span` y el `i` no tienen
   nada que los defienda y quedaban azules **encima** del renglón verde: se veía
   el activo con un recuadro azul pegado al texto. El `li` de atrás, igual —
   `.sidebar-menu li.mm-active { transparent }` tiene la misma especificidad
   (0,2,1) y está más arriba, así que perdía por orden.

   El único elemento que se toca en el menú es el link; el `li`, el ícono y el
   texto son pasajeros. */
.page-sidebar ul li:not(.mm-active) > a:hover {
    background-color: var(--cb-sidebar-hover);
}

/* Y HAY QUE NEUTRALIZAR LAS OTRAS DOS COPIAS. La regla suelta está escrita tres
   veces: acá arriba, en `app.custom.css:48` (`#043263`) y en
   `app.dark-mode.css:275` (`body.dark`, `#1e293b`). Las dos últimas son de
   producción y no se tocan, así que se las apaga desde acá: todo lo que esté
   bajo el puntero y **no sea el link** vuelve a transparente y toma el color de
   su contenedor —verde si el ítem está activo, el azul de la barra si no—.

   Se excluye el `<ul>` para no apagar el fondo del submenú abierto
   (`li.mm-active > ul`, más arriba), que también quedaría bajo el puntero.

   La variante `body.dark` va aparte porque la de `app.dark-mode.css` suma una
   clase más y le ganaría a la clara. */
.page-sidebar ul :hover:not(a):not(ul),
body.dark .page-sidebar ul :hover:not(a):not(ul) {
    background-color: transparent;
}

/* EN OSCURO, LO MISMO: EL RENGLÓN DEL LINK, NO EL `li`. Esta regla pintaba el
   `li` entero de verde —el arreglo de arriba no le llegaba, porque `body.dark`
   suma una clase y gana—, así que al abrir un submenú en modo oscuro el bloque
   completo con los hijos adentro quedaba verde. Es el mismo síntoma que tenía el
   modo claro antes de la sección 8, sobrevivido en la variante oscura.

   Va a transparente y no se borra: si se borra, gana
   `app.dark-mode.css:257` (`#1e293b`), que tiene la misma especificidad y carga
   antes. El verde del ítem activo lo pone `.sidebar-menu li.mm-active > a`, que
   vale para los dos modos porque `--cb-marca` se invierte solo. */
body.dark .sidebar-menu li.mm-active {
    background-color: transparent;
}

/* --------------------------------------------------------------------------
   9) LA BARRA LATERAL
   --------------------------------------------------------------------------
   Es el **azul de marca** (`#082146`), no un gris oscuro cualquiera. Se llegó
   acá por pasos el 2026-08-21: estaba en `#2c2f48` (el del tema), se probó
   `#0b1324`, se volvió atrás porque "ese azul es parte de la identidad" — y ahí
   apareció el dato que ordenó todo: **la marca tiene dos colores**, el verde y
   el azul `#082146`. La barra es el lugar natural del segundo.

   No hay riesgo de contraste: el texto del menú ya era claro porque el fondo ya
   era oscuro.
   -------------------------------------------------------------------------- */
.page-sidebar {
    background-color: var(--cb-sidebar);
}

body.dark .page-sidebar {
    background-color: var(--cb-sidebar);
}

/* --------------------------------------------------------------------------
   10) LA CARD DEL USUARIO EN LA BARRA
   --------------------------------------------------------------------------
   Ya era el azul de marca — pero escrito `#072146` en `app.custom.css:19`,
   **un dígito distinto** del `#082146` real. Nadie lo iba a notar mirando, y es
   justo la deriva que los tokens vienen a evitar: el mismo color de identidad
   con dos valores conviviendo.

   En oscuro tenía otro azul más (`#0b1324`, en `app.dark-mode.css:234`). Ahora
   los dos salen del token del sidebar, que es la superficie de la que forma
   parte.
   -------------------------------------------------------------------------- */
.user-navbar-bg {
    background-color: var(--cb-secundario);
}

body.dark .user-navbar-bg {
    background-color: var(--cb-sidebar);
}

/* --------------------------------------------------------------------------
   11) EL FOOTER, SIEMPRE AL FONDO
   --------------------------------------------------------------------------
   La estructura del tema ya era la correcta para lograrlo —`.page-wrapper` es
   flex column, `.content-area` también, y `.page-content` lleva `flex: 1 1 0%`,
   que es el que empuja—. Lo que fallaba estaba más abajo: **`html` tiene
   `height: 100%` y `body` no**, así que el `height: 100%` del wrapper se
   resolvía contra un padre de altura automática y colapsaba a la altura del
   contenido.

   Se arregla con `min-height: 100vh` en el wrapper, que no depende de la cadena
   de padres. Y `min-height` y no `height`, para que en las pantallas largas
   —los listados de 40 filas— siga creciendo en vez de recortar.

   NO es `position: fixed`: un footer fijo taparía contenido en pantallas
   largas. Éste se apoya en el fondo cuando la página es corta y baja con el
   scroll cuando es larga, que es lo que se espera.
   -------------------------------------------------------------------------- */
.page-wrapper {
    min-height: 100vh;
}

/* La `main` es la que se estira para ocupar lo que sobra. El tema ya se lo
   pone; se repite acá porque sin `.page-content` —las vistas que usan
   `$omit_page_content`— no habría nada empujando y el footer volvería a subir. */
.content-area > main {
    flex: 1 1 auto;
}

/* --------------------------------------------------------------------------
   12) LOS TOGGLES, TODOS DEL COLOR DE MARCA
   --------------------------------------------------------------------------
   El tema trae nueve variantes de switch —success, info, warning, danger,
   secondary, dark, purple…— y en las vistas se usan tres: **72 `switch-success`,
   4 `switch-primary` y 1 `switch-warning`**, sobre 78 en total.

   Que el 92% sean "success" no es una decisión de diseño: es lo que quedó del
   ejemplo del tema. Un toggle no dice "esto salió bien", dice **prendido o
   apagado** — y prendido es el color de la app.

   Se pisa la variante entera en vez de cambiar las clases en las vistas: son 78
   lugares y el día que aparezca un `switch-info` nuevo ya va a estar cubierto.
   -------------------------------------------------------------------------- */
.ui-switch input:checked ~ span:after,
.switch-primary input:checked ~ span:after,
.switch-success input:checked ~ span:after,
.switch-info input:checked ~ span:after,
.switch-warning input:checked ~ span:after,
.switch-danger input:checked ~ span:after,
.switch-secondary input:checked ~ span:after,
.switch-dark input:checked ~ span:after,
.switch-purple input:checked ~ span:after {
    background-color: var(--cb-marca);
}

/* En la variante `solid` se pinta la pista y la perilla queda blanca. */
.ui-switch.switch-solid input:checked ~ span,
.switch-solid.switch-primary input:checked ~ span,
.switch-solid.switch-success input:checked ~ span,
.switch-solid.switch-info input:checked ~ span,
.switch-solid.switch-warning input:checked ~ span,
.switch-solid.switch-danger input:checked ~ span,
.switch-solid.switch-secondary input:checked ~ span,
.switch-solid.switch-dark input:checked ~ span,
.switch-solid.switch-purple input:checked ~ span {
    background-color: var(--cb-marca);
    border-color: var(--cb-marca);
}

/* --------------------------------------------------------------------------
   13) UN SOLO ESTILO DE INPUT
   --------------------------------------------------------------------------
   Conviven DOS sistemas de formulario:

       .form-control      181 usos en 164 archivos   caja con borde (Bootstrap)
       .md-form-control   367 usos en  74 archivos   línea inferior (Material)

   El segundo es el "tipo Google": etiqueta que flota al escribir. No se
   diferencian sólo por CSS —el Material necesita un `<div class="md-form">` y el
   `<label>` DESPUÉS del input, que es lo que hace flotar la etiqueta—, así que
   convertir el markup serían 74 archivos como mínimo.

   ACÁ SE UNIFICA EL ASPECTO, NO EL MARKUP: el Material pasa a verse como la caja
   estándar y la etiqueta sigue flotando igual. Cero archivos tocados.

   PENDIENTE PARA CUANDO SE APRUEBE EL REDISEÑO (hablado el 2026-08-21 y
   pospuesto): convertir a Bootstrap los **11 campos de las pantallas de
   autenticación** —9 en `register` y 2 en `login`—, que es donde el Material no
   aporta nada y quedó de copiar el ejemplo del tema. La conversión es mecánica:

       <div class="md-form mb-0">              <div class="form-group mb-0">
         <input class="md-form-control" …>  →    <label for="x">Nombre</label>
         <label>Nombre</label>                   <input class="form-control" …>
       </div>                                  </div>

   No se hizo ahora porque **es markup y llegaría a producción**: allá la etiqueta
   dejaría de flotar y el campo pasaría de línea a caja. Hecho eso, estas reglas
   se pueden borrar.

   El `padding-top` del contenedor es lo que le deja lugar a la etiqueta cuando
   sube: sin eso queda pisando el borde de arriba de la caja.
   -------------------------------------------------------------------------- */
.md-form-control {
    border: 1px solid var(--cb-gris-300);
    border-radius: var(--cb-radio-boton);
    background-color: var(--cb-superficie);

    /* EL ALTO LO DA EL PADDING, no un `height` fijo. El tema le pone
       `height: 36px; padding: 0` —pensado para el estilo de línea, donde el
       texto se apoya abajo—, y al meterle la caja el texto quedaba pegado
       arriba: el alto estaba fijo y el padding no tenía dónde empujar.
       Con `height: auto` el padding y el `line-height` centran el texto solos,
       y da los mismos ~44px que `.form-control`. */
    height: auto;
    line-height: 1.5;
    padding: .55rem 1.1rem;
}

.md-form-control:focus:not([readonly]) {
    border: 1px solid var(--cb-marca);
    box-shadow: 0 0 0 .2rem rgba(0, 153, 102, .25);
}

/* La etiqueta flotante, corrida para que no se monte sobre el borde. */
.md-form {
    padding-top: .35rem;
}

.md-form > label {
    left: 1.1rem;
}

.md-form > label.active {
    left: .9rem;
}

/* --------------------------------------------------------------------------
   14) LOS BOTONES DE LAS PANTALLAS DE AUTENTICACIÓN
   --------------------------------------------------------------------------
   "Crear una cuenta" y el de recuperar contraseña son `.btn-danger` — rojo, el
   color de "algo salió mal", para acciones perfectamente normales. Pasan al azul
   de marca, que además arma la jerarquía correcta: **verde el ingreso** (la
   acción principal) y **azul lo secundario**.

   Se hace por CSS y acotado a `.auth-wrapper`, NO cambiando la clase en el
   Blade: `class="btn btn-danger"` está en el HTML y tocarlo llegaría a
   producción, mientras que todo el rediseño sigue siendo local. El día que se
   apruebe, ahí sí conviene arreglar la clase en el markup y borrar esta regla.

   Alcanza a las 10 vistas de autenticación de una: login, registro, recuperar y
   confirmar contraseña, verificación.
   -------------------------------------------------------------------------- */
.auth-wrapper .btn-danger {
    background-color: var(--cb-secundario);
    border-color: var(--cb-secundario);
    color: var(--cb-secundario-contraste);
}

.auth-wrapper .btn-danger:hover,
.auth-wrapper .btn-danger:focus,
.auth-wrapper .btn-danger:not(:disabled):not(.disabled):active {
    background-color: var(--cb-secundario-hover);
    border-color: var(--cb-secundario-hover);
    color: var(--cb-secundario-contraste);
}

.auth-wrapper .btn-danger:focus {
    box-shadow: 0 0 0 .2rem rgba(8, 33, 70, .3);
}

/* El nombre del sitio en login y registro: `<h1 class="text-primary">`, que con
   el token queda verde. Va en el azul de marca — es identidad, no una acción, y
   el verde está reservado para lo que se toca. Acotado a `.auth-wrapper` para no
   pisar los `.text-primary` del resto de la app. */
.auth-wrapper h1.text-primary {
    color: var(--cb-secundario) !important;
}

/* --------------------------------------------------------------------------
   15) EL FONDO DE LAS PANTALLAS DE AUTENTICACIÓN
   --------------------------------------------------------------------------
   Era un degradé radial blanco→gris escrito INLINE en `layouts/master.blade.php`
   (`style="background: radial-gradient(#ffffff, #f5f5f5)"`). Pasa al mismo fondo
   que el resto de la app, para que entrar a la plataforma no sea un salto visual.

   Dos cosas del cómo:

   - Va con `!important` porque un `style` inline le gana a cualquier hoja. La
     alternativa era editar el Blade, pero eso **llegaría a producción** — y todo
     el rediseño sigue siendo local.
   - Se selecciona con `body:has(.auth-wrapper)` porque ese layout no le pone
     ninguna clase al `<body>`, así que no hay otro gancho. Alcanza a las 10
     vistas de autenticación y no toca el `<body>` del resto de la app.

   Cuando el rediseño se apruebe, lo correcto es sacar el `style` inline del
   Blade y borrar esta regla.
   -------------------------------------------------------------------------- */
body:has(.auth-wrapper) {
    background: var(--cb-area) !important;
}

/* --------------------------------------------------------------------------
   16) LA VALIDACIÓN DE LOS INPUTS MATERIAL
   --------------------------------------------------------------------------
   El tema ya pinta `.invalid` y `.valid` con los tokens correctos, pero la regla
   de foco que se agregó más arriba —`.md-form-control:focus:not([readonly])`—
   tiene la MISMA especificidad que `.md-form-control:focus.invalid` y va después,
   así que le ganaba: un campo con error, al enfocarlo, se veía verde.

   Se resuelve con selectores más específicos, no con `!important`: agregando
   `:not([readonly])` a los estados de validación quedan por encima de la regla
   de foco sin necesidad de forzar nada.
   -------------------------------------------------------------------------- */
.md-form-control.invalid:not([readonly]),
.md-form-control.invalid:focus:not([readonly]) {
    border: 1px solid var(--cb-error);
    box-shadow: 0 0 0 .2rem rgba(220, 53, 69, .25);
}

.md-form-control.valid:not([readonly]),
.md-form-control.valid:focus:not([readonly]) {
    border: 1px solid var(--cb-ok);
    box-shadow: 0 0 0 .2rem rgba(40, 167, 69, .25);
}

/* La etiqueta y el texto de ayuda acompañan al borde. */
.md-form-control.invalid ~ label,
.md-form-control.invalid:focus ~ label,
.md-form-control.invalid ~ .helper-text:after {
    color: var(--cb-error);
}

.md-form-control.valid ~ label,
.md-form-control.valid:focus ~ label {
    color: var(--cb-ok);
}

/* --------------------------------------------------------------------------
   17) LOS ESTADOS HOVER Y ACTIVE DE LOS BOTONES
   --------------------------------------------------------------------------
   El script que tokenizó el tema mapea los **13 colores de identidad**, y los
   estados `:hover`/`:active` de cada botón usan **un hex propio, más oscuro,
   distinto de la base** — uno o dos usos cada uno, así que ninguno entró en el
   mapeo y todos sobrevivieron.

   El peor era `.btn-primary:hover`: **`#1132e1`, el azul viejo**. O sea que los
   botones verdes se ponían AZULES al pasar el mouse. El de `danger` iba a
   `#fe2d08`, un naranja rojizo, que es lo que se veía raro.

   Los de las redes sociales (`btn-facebook`, `btn-twitter`…) NO se tocan: su
   hover es el color de esa marca y ahí sí corresponde.
   -------------------------------------------------------------------------- */
.btn-primary:hover,
.btn-primary:not(:disabled):not(.disabled):active,
.btn-primary:not(:disabled):not(.disabled).active,
.btn-outline-primary:not(:disabled):not(.disabled):active,
.btn-outline-primary:not(:disabled):not(.disabled).active {
    background-color: var(--cb-marca-hover);
    border-color: var(--cb-marca-hover);
    color: var(--cb-marca-contraste);
}

.btn-success:hover,
.btn-success:not(:disabled):not(.disabled):active,
.btn-outline-success:not(:disabled):not(.disabled):active {
    background-color: var(--cb-ok-hover);
    border-color: var(--cb-ok-hover);
    color: var(--cb-ok-contraste);
}

.btn-danger:hover,
.btn-danger:not(:disabled):not(.disabled):active,
.btn-outline-danger:not(:disabled):not(.disabled):active {
    background-color: var(--cb-error-hover);
    border-color: var(--cb-error-hover);
    color: var(--cb-error-contraste);
}

.btn-warning:hover,
.btn-warning:not(:disabled):not(.disabled):active,
.btn-outline-warning:not(:disabled):not(.disabled):active {
    background-color: var(--cb-alerta-hover);
    border-color: var(--cb-alerta-hover);
    color: var(--cb-alerta-contraste);
}

.btn-info:hover,
.btn-info:not(:disabled):not(.disabled):active,
.btn-outline-info:not(:disabled):not(.disabled):active {
    background-color: var(--cb-info-hover);
    border-color: var(--cb-info-hover);
    color: #ffffff;
}

/* El link con estilo de botón también apuntaba al azul viejo (`#0e2abd`). */
.btn-link,
.btn-link:hover {
    color: var(--cb-marca-oscuro);
}

/* --------------------------------------------------------------------------
   18) `.btn-secondary` ES EL AZUL DE MARCA, NO UN GRIS
   --------------------------------------------------------------------------
   Hasta acá "secundario" significaba dos cosas distintas: en login y registro se
   usó `--cb-secundario` (el azul `#082146`) y en el resto de la app el
   `.btn-secondary` de Bootstrap, que es un gris (`#6c757d`, mapeado a
   `--cb-texto-suave`).

   Se unifican al azul de marca. La marca tiene dos colores y el botón secundario
   es el lugar natural del segundo: **verde la acción principal, azul la
   alternativa**. Un gris ahí no dice nada — parece deshabilitado.

   Con esto la regla de `.auth-wrapper .btn-danger` de más arriba queda diciendo
   lo mismo que el resto de la app, que era el sentido.
   -------------------------------------------------------------------------- */
.btn-secondary,
.btn-secondary:disabled,
.btn-secondary.disabled {
    background-color: var(--cb-secundario);
    border-color: var(--cb-secundario);
    color: var(--cb-secundario-contraste);
}

.btn-secondary:hover,
.btn-secondary:not(:disabled):not(.disabled):active,
.btn-secondary:not(:disabled):not(.disabled).active {
    background-color: var(--cb-secundario-hover);
    border-color: var(--cb-secundario-hover);
    color: var(--cb-secundario-contraste);
}

.btn-secondary:focus,
.btn-secondary.focus {
    box-shadow: 0 0 0 .2rem rgba(8, 33, 70, .3);
}

.btn-outline-secondary {
    color: var(--cb-secundario);
    border-color: var(--cb-secundario);
    background-color: transparent;
}

.btn-outline-secondary:hover,
.btn-outline-secondary:not(:disabled):not(.disabled):active {
    background-color: var(--cb-secundario);
    border-color: var(--cb-secundario);
    color: var(--cb-secundario-contraste);
}

/* --------------------------------------------------------------------------
   19) EL FILTRO DE CONTACTOS
   --------------------------------------------------------------------------
   Pedido por Miguel con los valores `#c8cfda` y `#092146`. Los dos ya estaban en
   la paleta: el primero **es** `--cb-gris-300` y el segundo es el azul de marca
   con un dígito de diferencia (`#082146`).

   Es la TERCERA variante que aparece del mismo azul —ya estaban `#072146` en
   `app.custom.css` y `#082146` en las hojas públicas—, que es exactamente lo que
   los tokens vienen a cortar: escribirlo con el nombre y no con el número.

   La pestaña activa es un ESTADO, no una acción, por eso va el gris y no el
   verde: el verde queda para lo que se toca.
   -------------------------------------------------------------------------- */
.contacts-filter-nav .nav-link.active {
    background-color: var(--cb-gris-300);
    color: var(--cb-secundario);
}

/* --------------------------------------------------------------------------
   20) LOS BOTONES DE EXPORTAR, TODOS IGUALES
   --------------------------------------------------------------------------
   Estaban con cinco clases distintas según quién hizo cada pantalla: **16
   `btn-primary`, 5 `btn-success`, 5 `btn-outline-secondary`, 1 `btn-dark`** y
   dos con clase propia. La misma acción, cinco colores.

   NO SE PUEDEN SELECCIONAR POR CLASE, justamente porque no comparten ninguna. El
   gancho es el ÍCONO: un botón con un ícono de descarga o exportación es un
   botón de exportar, y eso sí lo comparten todos —`ft-download`, `ti-download`,
   `ti-export`, `fa-download`, `fa-file-excel`—.

   Van en azul y no en verde a propósito: exportar es una **acción secundaria**.
   El verde queda para la acción principal de cada pantalla —guardar, crear,
   confirmar— y si todo es verde, nada lo es.
   -------------------------------------------------------------------------- */
.btn:has(.ft-download),
.btn:has(.ti-download),
.btn:has(.ti-export),
.btn:has(.fa-download),
.btn:has(.fa-file-excel),
.btn:has(.fa-file-export),
#btn-exportar {
    background-color: var(--cb-secundario);
    border-color: var(--cb-secundario);
    color: var(--cb-secundario-contraste);
}

.btn:has(.ft-download):hover,
.btn:has(.ti-download):hover,
.btn:has(.ti-export):hover,
.btn:has(.fa-download):hover,
.btn:has(.fa-file-excel):hover,
.btn:has(.fa-file-export):hover,
#btn-exportar:hover {
    background-color: var(--cb-secundario-hover);
    border-color: var(--cb-secundario-hover);
    color: var(--cb-secundario-contraste);
}

/* --------------------------------------------------------------------------
   21) LA PAGINACIÓN
   --------------------------------------------------------------------------
   El `:hover` del tema traía `color: #0e2abd` escrito a mano —**el azul viejo**,
   otro que se escapó del mapeo por tener un solo uso—, así que al pasar el mouse
   sobre un número el texto saltaba de verde a azul.

   Se le pone el mismo par que `.contacts-filter-nav .nav-link.active`: gris
   claro de fondo y azul de marca en el texto. Es un realce, no una acción — el
   número donde ESTÁS parado ya lleva el verde, y si el hover también fuera
   fuerte no se distinguirían.

   Y EL NÚMERO EN REPOSO TAMBIÉN ERA VERDE: `app.themed.min.css` trae
   `.page-link { color: var(--cb-marca) }`, así que el paginador mezclaba las dos
   escalas —verde en reposo, azul al pasar el mouse, azul en el activo—. Pedido
   por Miguel el 2026-08-22: que sea homogéneo. Va todo al azul, que es lo que
   corresponde por el criterio de la sección: un paginador es ESTRUCTURA.

   Alcanza con repetir el selector `.page-link` sin `!important`: tiene la misma
   especificidad que el del tema, y esta hoja carga después.
   -------------------------------------------------------------------------- */
.page-link {
    color: var(--cb-secundario);
}

.page-link:hover,
.page-link:focus {
    background-color: var(--cb-gris-300);
    color: var(--cb-secundario);
    border-color: var(--cb-borde);
}

/* DataTables genera su paginado con estas clases cuando no usa las de
   Bootstrap; se cubren las dos para que se vea igual en todos los listados. */
.dataTables_paginate .paginate_button:hover,
.dataTables_paginate .paginate_button:focus {
    background: var(--cb-gris-300) !important;
    color: var(--cb-secundario) !important;
    border-color: var(--cb-borde) !important;
}

.dataTables_paginate .paginate_button.current {
    background: var(--cb-secundario) !important;
    color: var(--cb-secundario-contraste) !important;
    border-color: var(--cb-secundario) !important;
}

/* LA PÁGINA ACTUAL VA EN AZUL, NO EN VERDE. Pedido por Miguel el 2026-08-22, y
   cierra el criterio de toda la tanda: el verde es la ACCIÓN y el azul la
   ESTRUCTURA. Un paginador no ejecuta nada, dice dónde estás parado dentro de
   una lista — es estructura pura. El tema la traía en `var(--cb-marca)`.

   Contraste: `#082146` con blanco da 15,95:1, contra los 3,65:1 del verde. Un
   número de paginación es texto chico, así que además arregla el punto flojo. */
.page-item.active .page-link {
    background-color: var(--cb-secundario);
    border-color: var(--cb-secundario);
    color: var(--cb-secundario-contraste);
}

/* --------------------------------------------------------------------------
   22) EL BOTÓN "CONFIGURACIÓN", EN EL AZUL DE MARCA
   --------------------------------------------------------------------------
   Son **10 botones idénticos**, uno arriba de cada pantalla de broker
   (`brokers/balanz`, `eco`, `servente`, `simplestate`, `decrypto`, `sbs`,
   `ppi`, `iol`) más `community-group/index` y `lottery/index`. Todos escritos
   igual: `btn btn-primary btn-rounded` con
   `<span class="btn-icon"><i class="ti-settings"></i>Configuración</span>`.

   Estaban en verde por ser `btn-primary`, y el verde es la ACCIÓN de la
   pantalla. Configurar no es la acción de la pantalla: es la puerta a otra
   cosa, igual que exportar (sección 20). Pasan al azul de marca.

   EL GANCHO ES EL ÍCONO, como en los botones de exportar: la clase no
   distingue —`btn-primary` la comparten con los botones de acción real de esas
   mismas pantallas—, así que hay que mirar qué contienen. `:has()` ya se usa
   más arriba para el menú.

   NO se toca el markup a propósito: las vistas llegan a producción y esta hoja
   no. Cambiar la clase a `btn-secondary` en el blade dejaría 10 botones grises
   en producción, que es justo lo que el rediseño todavía no decidió.

   Los otros dos `ti-settings` de la app (`livewire/subscription-index`) son
   `btn-outline-danger`, así que el selector no los alcanza.

   Contraste: `#082146` con blanco da **15,95:1**.
   -------------------------------------------------------------------------- */
.btn-primary:has(.ti-settings) {
    background-color: var(--cb-secundario);
    border-color: var(--cb-secundario);
    color: var(--cb-secundario-contraste);
}

.btn-primary:has(.ti-settings):hover,
.btn-primary:has(.ti-settings):focus,
.btn-primary:has(.ti-settings):not(:disabled):not(.disabled):active,
.btn-primary:has(.ti-settings):not(:disabled):not(.disabled).active {
    background-color: var(--cb-secundario-hover);
    border-color: var(--cb-secundario-hover);
    color: var(--cb-secundario-contraste);
}

/* El halo del foco también, si no delata el verde. */
.btn-primary:has(.ti-settings):focus,
.btn-primary:has(.ti-settings).focus {
    box-shadow: 0 0 0 .2rem rgba(8, 33, 70, .35);
}

/* --------------------------------------------------------------------------
   23) LAS REFERENCIAS DE LOS GRÁFICOS
   --------------------------------------------------------------------------
   El color del gráfico y el del cuadradito de la referencia **no se copian: se
   deducen del mismo nombre en dos lugares distintos**, y por eso se pueden
   despegar.

   Cómo funciona. Cada canvas trae en el blade una lista fija de doce
   `theme_color('primary'), theme_color('info'), …`; `theme_color()` (en
   `assets/js/app.min.js`) es un lookup sobre `APP.COLORS`. La referencia de al
   lado recorre los mismos ítems con `array_colors()[0][$loop->index]`
   (`app/Helpers/helpers.php:220`), que devuelve **la misma lista de nombres en
   el mismo orden**, y arma la clase `.color-primary`, `.color-info`… definidas
   en `app.custom.css:177`.

   QUÉ SE ROMPIÓ. `js/app.theme.js` pisó `APP.COLORS` con la rampa nueva y nadie
   tocó las clases `.color-*`, que seguían en la paleta vieja del tema: la torta
   quedó verde y la referencia al lado, azul y violeta. Visto en el gráfico de
   "Condición Laboral" de los brokers.

   Se replican acá los doce valores, **en el mismo orden y con los mismos
   colores** que `js/app.theme.js`. Esta hoja carga después de `app.custom.css`,
   así que gana sin `!important` y esa hoja —que sí llega a producción— no se
   toca.

   SI SE CAMBIA UN COLOR, SE CAMBIA EN LOS DOS ARCHIVOS. No hay forma de que uno
   lea al otro: el canvas resuelve en JS y el cuadradito en CSS.
   -------------------------------------------------------------------------- */
.color-primary   { background-color: #009966; }  /*  0 verde base       */
.color-info      { background-color: #2c67ba; }  /*  1 azul vivo        */
.color-danger    { background-color: #005438; }  /*  2 verde más oscuro */
.color-yellow    { background-color: #8cacd9; }  /*  3 azul más claro   */
.color-purple    { background-color: #40b28c; }  /*  4 verde claro      */
.color-pink      { background-color: #12386e; }  /*  5 azul oscuro      */
.color-success   { background-color: #a6dbc9; }  /*  6 verde suave      */
.color-light     { background-color: #1d4f96; }  /*  7 azul medio       */
.color-secondary { background-color: #00734c; }  /*  8 verde oscuro     */
.color-indigo    { background-color: #5587ce; }  /*  9 azul claro       */
.color-dark      { background-color: #73c7ab; }  /* 10 verde más claro  */
.color-warning   { background-color: #082146; }  /* 11 azul de marca    */

/* Fuera de la secuencia de 12, para que la tabla quede completa. */
.color-teal      { background-color: #d1ede3; }

/* --------------------------------------------------------------------------
   24) LAS DOS TORTAS DE "RECAUDACIÓN POR CUENTA Y PLAN", DEL MISMO TAMAÑO
   --------------------------------------------------------------------------
   Pantalla de Suscripciones, card "Recaudación por Cuenta y Plan": la torta de
   la pestaña MES ACTUAL se veía bastante más grande que la de MES ANTERIOR.

   Las dos están escritas IGUAL —`col-lg-4` con un `<canvas style="height:
   300px">`, y los dos Chart con `responsive: true` y `maintainAspectRatio:
   false`—, así que la diferencia no estaba en el markup: la ponía el dato.

   Por qué. Con `maintainAspectRatio: false` el gráfico toma **la altura de su
   contenedor**, y Chart.js pisa el `height` del canvas en cada resize — o sea
   que ese `300px` del blade nunca mandó. El contenedor es una columna de un
   `row`, y un flex row estira todas sus columnas a la altura de la más alta
   (`align-items: stretch`). Al lado hay un `col-lg-8` con dos tablas que salen
   de `@foreach` sobre cuentas y planes: el mes con más filas estira la fila
   entera, y la torta crece con ella. Cuál de las dos pestañas se ve más grande
   depende de cuántas filas trajo cada mes.

   `align-self: flex-start` corta el estirado y `height` fija la caja, así que
   las dos miden lo mismo siempre. Se eligió 300px —el valor que el markup
   siempre quiso— y no el tamaño grande.

   No se toca el blade a propósito: esa vista llega a producción y esta hoja no.
   Para sumar otra torta, se agrega su id a la lista.
   -------------------------------------------------------------------------- */
.tab-content .row > div:has(> #pie_chart_6),
.tab-content .row > div:has(> #pie_chart_8) {
    height: 300px;
    align-self: flex-start;
}

/* --------------------------------------------------------------------------
   25) EL HOVER DE LOS MENÚS DESPLEGABLES
   --------------------------------------------------------------------------
   Los ítems de un `.dropdown-menu` no se pintaban al pasar el mouse. No es algo
   que el rediseño haya roto: el tema trae `#f8f9fa` para el `:hover` y es el
   MISMO valor en el original y en el tokenizado. Lo que pasa es que ese gris es
   casi blanco, y sobre el fondo claro nuevo directamente no se distingue.

   Pasa a `--cb-gris-200`, que es el primer paso de la escala que realmente se
   ve. UNA sola declaración cubre los dos modos: la escala de grises se invierte
   en `body.dark` (`#dfe4ec` en claro, `#2b3a50` en oscuro), así que el token
   sigue significando "el fondo apenas separado" en los dos.

   HAY QUE REPETIR EL SELECTOR CON `body.dark`, y no es por el color. En
   `app.dark-mode.css:229` está `body.dark .dropdown-item { background-color:
   #0f172b }` — sin `:hover`, pero con MÁS especificidad (0,2,1) que
   `.dropdown-item:hover` (0,2,0). O sea que en modo oscuro el hover del tema
   nunca se llegaba a ver: no es que se viera poco, no se veía nada.

   Alcanza a todos los desplegables porque todos usan la misma clase: el menú de
   usuario de la barra superior (`partials/navbar.blade.php:36`), el de
   notificaciones y los de acciones de las tablas.
   -------------------------------------------------------------------------- */
.dropdown-item:focus,
.dropdown-item:hover {
    background-color: var(--cb-gris-200);
    color: var(--cb-texto);
}

/* En oscuro va un paso MÁS ARRIBA, no el mismo token: el desplegable es la capa
   elevada (`--cb-elevada`, `#324052`) y `--cb-gris-200` vale `#2b3a50` ahí, o
   sea más oscuro que el propio menú — el hover se habría visto hundido. */
body.dark .dropdown-item:focus,
body.dark .dropdown-item:hover {
    background-color: var(--cb-gris-300);
    color: var(--cb-texto);
}

/* --------------------------------------------------------------------------
   26) EL BOTÓN DE UN COMBO ABIERTO
   --------------------------------------------------------------------------
   Encontrado mirando pantallas: al abrir un combo, el botón quedaba en el
   naranja viejo (`#fe2d08` en `btn-outline-danger`).

   Es el MISMO problema de la sección 17, en otro estado. El script que tokenizó
   el tema mapea los 13 colores de identidad, y `.show > .btn-*.dropdown-toggle`
   tiene **un hex propio por variante** —16 reglas, un uso cada una—, así que
   ninguna entró en el mapeo y las 16 sobrevivieron con el color viejo.

   El peor no es el naranja: `.show > .btn-primary.dropdown-toggle` era
   **`#1030d5`** y el de `outline-primary` **`#1132e1`** —los dos, el azul
   anterior—. O sea que un combo primario abierto se ponía azul, igual que
   pasaba con el `:hover` antes de la sección 17.

   Se usan los mismos tokens que ahí, para que "abierto" y "presionado" se vean
   igual: son el mismo estado para quien mira.

   `light` y `dark` quedan afuera a propósito: sus hexes (`#c1c9d0`, `#1d2124`,
   `#c8cfd6`, `#23272b`) ya son grises neutros, no colores de la identidad vieja,
   así que no delatan nada. Y los grises se invierten en modo oscuro, con lo cual
   tokenizarlos a ciegas rompería más de lo que arregla.
   -------------------------------------------------------------------------- */
.show > .btn-primary.dropdown-toggle,
.show > .btn-outline-primary.dropdown-toggle {
    background-color: var(--cb-marca-hover);
    border-color: var(--cb-marca-hover);
    color: var(--cb-marca-contraste);
}

.show > .btn-secondary.dropdown-toggle,
.show > .btn-outline-secondary.dropdown-toggle {
    background-color: var(--cb-secundario-hover);
    border-color: var(--cb-secundario-hover);
    color: var(--cb-secundario-contraste);
}

.show > .btn-success.dropdown-toggle,
.show > .btn-outline-success.dropdown-toggle {
    background-color: var(--cb-ok-hover);
    border-color: var(--cb-ok-hover);
    color: var(--cb-ok-contraste);
}

.show > .btn-info.dropdown-toggle,
.show > .btn-outline-info.dropdown-toggle {
    background-color: var(--cb-info-hover);
    border-color: var(--cb-info-hover);
    color: #ffffff;
}

.show > .btn-warning.dropdown-toggle,
.show > .btn-outline-warning.dropdown-toggle {
    background-color: var(--cb-alerta-hover);
    border-color: var(--cb-alerta-hover);
    color: var(--cb-alerta-contraste);
}

.show > .btn-danger.dropdown-toggle,
.show > .btn-outline-danger.dropdown-toggle {
    background-color: var(--cb-error-hover);
    border-color: var(--cb-error-hover);
    color: var(--cb-error-contraste);
}

/* --------------------------------------------------------------------------
   27) LOS TÍTULOS VAN AL VERDE CLARO, NO AL OSCURO
   --------------------------------------------------------------------------
   Pedido por Miguel el 2026-08-21 mirando Informes: los títulos de los PDF, y
   los títulos de los cards de videos.

   `.text-primary` usa `--cb-marca-oscuro` a propósito —está en la sección 1—:
   son 193 usos en la app y la mayoría es **texto chico** (valores de 9pt en los
   detalles de pago, en planes, en grupos). Ahí el verde claro da 3,65:1, por
   debajo del 4,5 que pide texto chico; el oscuro da 5,75:1.

   Un TÍTULO es otra cosa, así que se acota a los títulos en vez de cambiar la
   utilidad entera. Los 193 usos siguen en el oscuro.

   DOS GANCHOS, porque hay dos maquetados distintos:

   - `.card-title.text-primary` — 15 lugares, todos `<h5>`: los cards de videos
     (`web/news/partials/cards-video`), los de novedades, cursos, grupos, los de
     informes en la vista de socio y los de `reports`.

   - El título de la fila de un documento descargable, que es un `<div>` con el
     tamaño puesto inline y sin clase propia. Son exactamente DOS —Informes
     (`research/index:73`) y Reportes (`reports/index:85`)—, así que se lo toma
     por el atributo `style`. No es elegante, pero es preciso: dentro de `.liste`
     el resto de los `.text-primary` son valores de 9pt y no hay que tocarlos.

   Contraste: `#009966` con blanco da 3,65:1. Alcanza para texto grande (WCAG
   pide 3,0) y es una decisión tomada sabiendo eso — son títulos, no texto de
   lectura.
   -------------------------------------------------------------------------- */
/* LOS TÍTULOS DE CARD VAN AL AZUL DE MARCA, no al verde. Pedido por Miguel el
   2026-08-21 después de verlos en verde. Tiene sentido con el reparto que ya
   usa el resto del tema: **el verde es la acción —lo que se toca— y el azul es
   la estructura**. Un título de card no se toca: nombra. El verde queda para el
   botón que hay dentro de esa misma card, que es lo que sí se clickea.

   Contraste: `#082146` sobre blanco da **15,95:1**, contra los 3,65:1 del verde
   claro, así que además deja de ser el punto flojo que era.

   El título de la fila de un documento descargable (Informes y Reportes) va
   igual. Primero se lo dejó en verde con el argumento de que ahí el título ES
   el link de descarga, pero Miguel pidió unificarlo — y es lo correcto: el
   título nombra el documento, y lo que se toca es el ícono de PDF y el botón
   "VER INFORME" que están al lado. Que un texto sea clickeable no lo convierte
   en la acción de la pantalla.

   EL GANCHO CAMBIÓ. Antes era `[style*="13pt"]`, leyendo el tamaño del atributo
   `style` inline porque el `<div>` no tenía clase propia. Ahora es `.mb-2`, que
   es la clase que esos dos títulos ya traían: son las ÚNICAS dos apariciones de
   `mb-2` junto a `text-primary` en toda la app, así que no alcanza a nada más y
   se lee mucho mejor que un selector de atributo. */
.card-title.text-primary,
.mb-2.text-primary {
    color: var(--cb-secundario) !important;
}

/* --------------------------------------------------------------------------
   28) MODO OSCURO: QUE LA PALETA TAMBIÉN SE VEA AHÍ
   --------------------------------------------------------------------------
   Hasta acá el rediseño no llegaba al modo oscuro, y no por olvido: **hay una
   paleta paralela entera** en `app.dark-mode.css` —96 reglas `body.dark`— y le
   gana a todo lo del tema. Escritas como `body.dark .card .btn-primary` tienen
   tres clases; cualquier regla de acá sin `body.dark` tiene una o dos y pierde.

   Lo que se veía en oscuro, medido el 2026-08-21:

     .text-primary          #f1f1f1   los títulos verdes salían GRIS CLARO
     .btn-primary           #0d6efd   un TERCER azul, ni el viejo ni el nuevo
     .btn-outline-primary   #9e9e9e   gris — parecía deshabilitado
     .btn-outline-danger    #fe4d2e   el naranja viejo otra vez
     .page-link activo      #0d6efd   la paginación volvía al azul

   NO HACE FALTA ELEGIR COLORES NUEVOS. La escala de grises y los tokens de marca
   ya se invierten solos en `body.dark` (`--cb-marca` vale `#34d399` ahí, que da
   8,9:1 sobre el fondo). Así que esto es casi todo repetir el selector y apuntar
   al mismo token: el trabajo de decidir ya está hecho en `app.tokens.css`.

   TAMPOCO HACE FALTA `!important`. `app.theme.css` carga DESPUÉS de
   `app.dark-mode.css` (ver `layouts/app.blade.php`), así que con la misma
   especificidad gana por orden. Se copian los selectores tal cual están allá —
   incluidas las variantes con `.card` y `.row`, que existen para subir la
   especificidad—. La única excepción es `.text-primary`, que allá va con
   `!important` y por eso acá también.

   LO QUE SE DEJA COMO ESTÁ, a propósito:
   - `body.dark .card a` (`#a1a8ad`) y `body.dark a:hover` (`#c8c8c8`): links
     apagados dentro de cards. Se puede discutir, pero es una decisión de
     legibilidad del modo oscuro, no un color viejo que se escapó.
   - `body.dark .table-hover .table-info:hover` (`#f44336`): un rojo al pasar el
     mouse por una fila de info. Es raro, pero es otro tema.
   -------------------------------------------------------------------------- */

/* BOTONES PRIMARIOS */
body.dark .btn-primary,
body.dark .card .btn-primary {
    background-color: var(--cb-marca);
    border-color: var(--cb-marca);
    color: var(--cb-marca-contraste);
}

body.dark .btn-primary:hover,
body.dark .card .btn-primary:hover {
    background-color: var(--cb-marca-hover);
    border-color: var(--cb-marca-hover);
    color: var(--cb-marca-contraste);
}

body.dark .btn-outline-primary,
body.dark .row .btn-outline-primary {
    color: var(--cb-marca);
    border-color: var(--cb-marca);
    background-color: transparent;
}

body.dark .btn-outline-primary:hover,
body.dark .row .btn-outline-primary:hover {
    background-color: var(--cb-marca);
    border-color: var(--cb-marca);
    color: var(--cb-marca-contraste);
}

/* BOTONES DE PELIGRO. El `#fe4d2e` de allá es el naranja rojizo viejo, el mismo
   que ya se corrigió en la sección 17 para el modo claro. */
body.dark .btn-danger,
body.dark .card .btn-danger,
body.dark .row .btn-danger {
    background-color: var(--cb-error);
    border-color: var(--cb-error);
    color: var(--cb-error-contraste);
}

body.dark .btn-danger:hover,
body.dark .card .btn-danger:hover,
body.dark .row .btn-danger:hover {
    background-color: var(--cb-error-hover);
    border-color: var(--cb-error-hover);
    color: var(--cb-error-contraste);
}

body.dark .btn-outline-danger,
body.dark .card .btn-outline-danger,
body.dark .row .btn-outline-danger {
    color: var(--cb-error);
    border-color: var(--cb-error);
    background-color: transparent;
}

body.dark .btn-outline-danger:hover,
body.dark .card .btn-outline-danger:hover,
body.dark .row .btn-outline-danger:hover {
    background-color: var(--cb-error);
    border-color: var(--cb-error);
    color: var(--cb-error-contraste);
}

/* TEXTO Y LINKS. En oscuro `--cb-marca` es el verde claro (`#34d399`), así que
   acá sí sirve para texto chico: 8,9:1. Por eso `.text-primary` va al token de
   marca y no al `-oscuro` como en el modo claro. */
body.dark .text-primary {
    color: var(--cb-marca) !important;
}

body.dark a:hover,
body.dark .btn-link:hover {
    color: var(--cb-marca-hover);
}

body.dark .text-muted-link:hover {
    color: var(--cb-marca) !important;
}

body.dark td a {
    color: var(--cb-marca);
}

body.dark .row a:hover,
body.dark .nav-link a:hover {
    color: var(--cb-marca-hover);
}

body.dark .primary {
    color: var(--cb-marca);
}

/* PAGINACIÓN. Misma decisión que la sección 21: la página actual lleva el verde
   y el hover es sólo un realce. */
body.dark .page-item.active .page-link {
    background-color: var(--cb-secundario);
    border-color: var(--cb-secundario);
    color: var(--cb-secundario-contraste);
}

/* LAS PESTAÑAS. El subrayado del tab activo era `#0d6efd`. */
body.dark .line-tabs .nav-link.active,
body.dark .line-tabs .nav-link:hover {
    border-color: var(--cb-marca);
}

/* LA FILA DESTACADA DE UNA TABLA es información, no acción: va al token de info,
   no al de marca. */
body.dark .table-info,
body.dark .table-info > td,
body.dark .table-info > th {
    background-color: var(--cb-info);
}

/* EL AVISO DE ENTORNO ya estaba cubierto en la sección 7; el `#741909` de
   `app.dark-mode.css:245` pierde por orden aunque los dos usen `!important`. */

/* TRES QUE SE ESCAPARON EN LA PRIMERA PASADA, encontradas comparando selector
   por selector contra `app.dark-mode.css`:

   - `.btn-link` estaba cubierto sólo en `:hover`, así que el link con estilo de
     botón se veía gris claro en reposo y verde al pasar el mouse.
   - `td a:hover` iba a `#ebf1f3` (casi blanco) mientras el link en reposo ya es
     verde: el par quedaba raro.
   - `.row .btn-outline-secondary:hover` fuerza `color: #fff`, y en oscuro
     `--cb-secundario` es un gris CLARO (`#bac1cb`): blanco sobre gris claro no
     se lee. Va el contraste del token, que ahí es el azul oscuro. */
body.dark .btn-link {
    color: var(--cb-marca);
}

body.dark td a:hover {
    color: var(--cb-marca-hover);
}

body.dark .row .btn-outline-secondary:hover {
    color: var(--cb-secundario-contraste);
}

/* --------------------------------------------------------------------------
   29) MODO OSCURO: LAS SUPERFICIES, A LA ESCALERA
   --------------------------------------------------------------------------
   Redefinir los tokens no alcanza: `app.dark-mode.css` tiene los colores de
   superficie **escritos a mano** en unas veinte reglas, así que no ven el
   cambio. Acá se los manda a los tokens nuevos.

   Las capas, de abajo hacia arriba:

     --cb-sidebar     #0a1524   la barra: ancla el layout, es la más oscura
     --cb-fondo       #162131   la página, y todo lo HUNDIDO (inputs, thead,
                                paginación) — se ve recortado contra la card
     --cb-superficie  #243042   las cards
     --cb-elevada     #324052   lo que FLOTA: desplegables, modales, select2

   ANTES ESTABA AL REVÉS EN LA PUNTA: los desplegables usaban `#0f172b`, más
   oscuro que la card (`#1e293b`). Un menú que flota por encima tiene que ser más
   claro, no más hundido — es la señal de que está arriba.

   LOS INPUTS VAN A `--cb-fondo` A PROPÓSITO, aunque hoy conviven dos valores
   (`.form-control` en `#0f172b` y `.md-form-control` en `#1e293b`, o sea uno
   hundido y el otro al ras de la card). Se unifican al hundido: un campo de
   texto se lee mejor cuando parece un hueco en la tarjeta.

   `banner-circulos` y `jumbotron` (`#001d2c`) quedan afuera: son de las páginas
   públicas, no del panel, y tienen su propia identidad.
   -------------------------------------------------------------------------- */

/* LA PÁGINA */
body.dark .page-wrapper,
body.dark .content-area,
body.dark .video-content,
body.dark .preloader-backdrop {
    background-color: var(--cb-fondo);
}

/* LAS CARDS */
body.dark .card,
body.dark .card.card-fullheight,
body.dark .page-footer,
body.dark .ui-switch span {
    background-color: var(--cb-superficie);
}

body.dark .bg-white {
    background-color: var(--cb-superficie) !important;
}

/* LO QUE FLOTA */
body.dark .dropdown-menu.show,
body.dark .dropdown-item,
body.dark .modal-content,
body.dark .select2-dropdown,
body.dark .select2-container--default .select2-results__option--highlighted[aria-selected] {
    background-color: var(--cb-elevada);
}

/* LO QUE SE HUNDE: campos, encabezados de tabla, paginación, pestañas sólidas */
body.dark .form-control,
body.dark .md-form-control,
body.dark .input-group-text,
body.dark .custom-select,
body.dark .page-link,
body.dark .line-tabs.line-tabs-solid .nav-link.active,
body.dark .line-tabs.line-tabs-solid .nav-link:hover {
    background-color: var(--cb-fondo);
}

body.dark .table .thead-light th {
    background-color: var(--cb-fondo);
    border-color: var(--cb-borde);
}

body.dark .alert-light {
    background-color: var(--cb-fondo);
    border-color: var(--cb-borde);
}

/* LOS BORDES, todos al mismo token */
body.dark .table-bordered,
body.dark .table td,
body.dark .table th {
    border-color: var(--cb-borde);
}

/* LAS TRES QUE FALTABAN, encontradas cruzando regla por regla contra
   `app.dark-mode.css`:

   - `body.dark { background: #0f172b }` — el fondo del propio `body`, debajo de
     todo. Si no se cambia, asoma en los bordes y al hacer scroll de más.
   - `body.dark nav` (`#1e293b`) — la barra superior, que es una superficie como
     las cards.
   - `.row .btn-delete` (`#dc3545` / `#b02a37`) — el rojo de borrar, escrito a
     mano en vez de salir del token de error. */
body.dark {
    background-color: var(--cb-fondo);
}

body.dark nav {
    background-color: var(--cb-superficie);
}

body.dark .row .btn-delete {
    background-color: var(--cb-error);
    border-color: var(--cb-error);
    color: var(--cb-error-contraste);
}

body.dark .row .btn-delete:hover {
    background-color: var(--cb-error-hover);
    border-color: var(--cb-error-hover);
    color: var(--cb-error-contraste);
}

/* --------------------------------------------------------------------------
   30) LA FAMILIA "DARK": TEXTO FIJO SOBRE UN FONDO QUE SE INVIERTE
   --------------------------------------------------------------------------
   Encontrado por Miguel el 2026-08-21: en modo oscuro el `btn-dark` era "gris
   con texto gris". No se veía.

   La causa es un error de mezcla que el script de tokenización dejó a la vista:

       .btn-dark { color: #fff; background-color: var(--cb-gris-800); }

   El fondo es un token que **se invierte** con el modo —`#2b3a50` en claro,
   `#dfe4ec` en oscuro— pero el texto es un `#fff` **fijo**. En claro da 11,5:1
   de casualidad; en oscuro, blanco sobre gris claro: **1,28:1**.

   No es un caso aislado: son SEIS reglas con exactamente la misma forma
   (`.btn-dark`, `.btn-dark:disabled`, `.btn-outline-dark:hover`, `.badge-dark`,
   `.alert-dark` y el `:active` del combo). El script mapeó el fondo porque
   `#343a40` era uno de los 13 colores de identidad, y dejó el `#fff` como
   estaba: no tenía forma de saber que los dos van juntos.

   LA REGLA GENERAL, que vale para todo lo que venga: **si el fondo es un token
   que se invierte, el texto también tiene que serlo**. Acá el par es
   `--cb-gris-800` de fondo y `--cb-gris-100` de texto: se mueven juntos, así que
   una sola declaración sirve para los dos modos —10,4:1 en claro, 12,4:1 en
   oscuro— sin escribir ninguna variante `body.dark`.

   Los `:hover` y `:active` iban a `#23272b` y `#1d2124`, hexes fijos que en
   oscuro saltaban a casi negro sobre un botón claro. Van a `--cb-gris-900`, que
   es "un paso más lejos del texto" en los dos modos: más oscuro en claro, más
   claro en oscuro. 14,2:1 de las dos maneras.
   -------------------------------------------------------------------------- */
.btn-dark,
.btn-dark:disabled,
.btn-dark.disabled,
.badge-dark,
.alert-dark {
    background-color: var(--cb-gris-800);
    border-color: var(--cb-gris-800);
    color: var(--cb-gris-100);
}

.btn-dark:hover,
.btn-dark:not(:disabled):not(.disabled):active,
.btn-dark:not(:disabled):not(.disabled).active,
.show > .btn-dark.dropdown-toggle {
    background-color: var(--cb-gris-900);
    border-color: var(--cb-gris-900);
    color: var(--cb-gris-100);
}

.btn-outline-dark {
    color: var(--cb-gris-800);
    border-color: var(--cb-gris-800);
    background-color: transparent;
}

.btn-outline-dark:hover,
.btn-outline-dark:not(:disabled):not(.disabled):active {
    background-color: var(--cb-gris-800);
    border-color: var(--cb-gris-800);
    color: var(--cb-gris-100);
}

/* En oscuro `app.dark-mode.css:290` pinta `.btn-outline-dark` con `#f1f1f1` y
   `#767879` — dos grises sueltos, fuera de la escala. Se los manda al token, que
   ahí vale el gris claro y da lo mismo pero dentro de la familia. */
body.dark .btn-outline-dark {
    color: var(--cb-gris-800);
    border-color: var(--cb-gris-800);
}

/* --------------------------------------------------------------------------
   31) EN OSCURO, UN BOTÓN QUE ES `<a>` PERDÍA SU COLOR DE TEXTO
   --------------------------------------------------------------------------
   Visto por Miguel el 2026-08-21 en `/user/{id}/profile/edit`: "Validar
   Preapproval" y "Sincronizar" tienen **exactamente las mismas clases**
   (`btn btn-sm btn-outline-dark`) y se veían de distinto color.

   La diferencia es la etiqueta, y viene del método HTTP: la acción que va por
   POST es un `<form>` con `<button>`, y la que va por GET es un `<a href>`.

   Y ahí pega esto, de `app.dark-mode.css`:

       body.dark .card a { color: #a1a8ad; }
       body.dark .row  a { color: #aab1b5; }

   Son (0,2,2) —dos clases y dos elementos— contra los (0,1,0) de
   `.btn-outline-dark`. O sea que **cualquier `<a class="btn">` dentro de una
   card o de un row pierde el color de su variante** y se vuelve gris. El
   `<button>` de al lado, no. Son **415 `<a class="btn">`** en la app, así que
   afectaba a buena parte del panel.

   ARREGLO: repetir el color con el prefijo `.card`/`.row`, que sube a (0,3,1) y
   gana. Sólo hace falta el `color`: esas dos reglas no tocan fondo ni borde, así
   que el resto del botón ya estaba bien — por eso el síntoma era sólo el texto.

   Los `:hover` de los outline van aparte porque `body.dark .card a:hover`
   también existe (`#ebf1f3`) y hay que ganarle igual.

   No se toca `app.dark-mode.css`: llega a producción. Lo correcto de fondo sería
   escribir allá `a:not(.btn)`, y queda anotado para cuando se limpie esa hoja.
   -------------------------------------------------------------------------- */

body.dark .card .btn-primary,
body.dark .row .btn-primary {
    color: var(--cb-marca-contraste);
}

body.dark .card .btn-outline-primary,
body.dark .row .btn-outline-primary {
    color: var(--cb-marca);
}

body.dark .card .btn-outline-primary:hover,
body.dark .row .btn-outline-primary:hover {
    color: var(--cb-marca-contraste);
}

body.dark .card .btn-secondary,
body.dark .row .btn-secondary {
    color: var(--cb-secundario-contraste);
}

body.dark .card .btn-outline-secondary,
body.dark .row .btn-outline-secondary {
    color: var(--cb-secundario);
}

body.dark .card .btn-outline-secondary:hover,
body.dark .row .btn-outline-secondary:hover {
    color: var(--cb-secundario-contraste);
}

body.dark .card .btn-success,
body.dark .row .btn-success {
    color: var(--cb-ok-contraste);
}

body.dark .card .btn-outline-success,
body.dark .row .btn-outline-success {
    color: var(--cb-ok);
}

body.dark .card .btn-outline-success:hover,
body.dark .row .btn-outline-success:hover {
    color: var(--cb-ok-contraste);
}

body.dark .card .btn-info,
body.dark .row .btn-info {
    color: var(--cb-info-contraste);
}

body.dark .card .btn-outline-info,
body.dark .row .btn-outline-info {
    color: var(--cb-info);
}

body.dark .card .btn-outline-info:hover,
body.dark .row .btn-outline-info:hover {
    color: var(--cb-info-contraste);
}

body.dark .card .btn-warning,
body.dark .row .btn-warning {
    color: var(--cb-alerta-contraste);
}

body.dark .card .btn-outline-warning,
body.dark .row .btn-outline-warning {
    color: var(--cb-alerta);
}

body.dark .card .btn-outline-warning:hover,
body.dark .row .btn-outline-warning:hover {
    color: var(--cb-alerta-contraste);
}

body.dark .card .btn-danger,
body.dark .row .btn-danger {
    color: var(--cb-error-contraste);
}

body.dark .card .btn-outline-danger,
body.dark .row .btn-outline-danger {
    color: var(--cb-error);
}

body.dark .card .btn-outline-danger:hover,
body.dark .row .btn-outline-danger:hover {
    color: var(--cb-error-contraste);
}

body.dark .card .btn-dark,
body.dark .row .btn-dark {
    color: var(--cb-gris-100);
}

body.dark .card .btn-outline-dark,
body.dark .row .btn-outline-dark {
    color: var(--cb-gris-800);
}

body.dark .card .btn-outline-dark:hover,
body.dark .row .btn-outline-dark:hover {
    color: var(--cb-gris-100);
}

/* --------------------------------------------------------------------------
   32) EL TOGGLE DE MODO OSCURO SE QUEDA COMO ESTÁ — NO ES UNA OMISIÓN
   --------------------------------------------------------------------------
   Este es el único control de la app que NO sigue la convención de la sección 11
   ("prendido = el color de la app"). Tiene su pista `#343d5b`, su perilla blanca
   `#f1f1f1` y el naranja `#ff9800` al activarse, todo en `app.dark-mode.css:405`
   y siguientes. Y así queda.

   El 2026-08-21 se lo pasó al verde por consistencia y Miguel pidió volver atrás.
   Tenía razón, y el motivo es de fondo: **los otros 78 switches dicen prendido o
   apagado; éste dice sol o luna**. No es un estado booleano de un formulario, es
   un selector de modo, y lo dice con dos íconos (`partials/navbar.blade.php:91`).
   El naranja no es un color suelto que se escapó del mapeo: es el sol. Pintarlo
   de verde le saca el significado y lo deja pareciendo un toggle más.

   ESTO NO ES DEUDA. Si en una revisión futura aparece como "el único switch sin
   tokenizar", la respuesta es ésta: el naranja se queda.

   PERO EL HEX SÍ SE TOKENIZA, y no cambia nada de lo anterior. Medido: el
   `#ff9800` del toggle y el `--cb-alerta` de la paleta están a **1° de matiz**
   (36° contra 37°) y difieren un 7,7% en total — puestos al lado no se
   distinguen. O sea que el naranja del sol **ya estaba en la paleta**; nadie lo
   había notado porque estaba escrito como hex suelto.

   Así que se conserva exactamente el color que Miguel quiere Y deja de ser un
   valor fuera de la paleta: si mañana se ajusta el ámbar, el sol lo acompaña.
   La perilla blanca y la pista quedan como estaban.
   -------------------------------------------------------------------------- */
.switch-mode.active {
    background: var(--cb-alerta);
}

/* --------------------------------------------------------------------------
   33) `<code>`, AL VERDE DE MARCA
   --------------------------------------------------------------------------
   Estaba en `#e83e8c` —el rosa de Bootstrap—, otro color de fuera de la paleta.
   No entró en el mapeo del script porque no es uno de los 13 de identidad: es
   un default del framework que nadie eligió.

   En la app `<code>` no marca código: marca un VALOR del sistema —`Activo`,
   `Automático`, el nombre de una variable— dentro de una frase. O sea que es un
   dato destacado, y el color de lo destacado es el de la marca.

   VA `--cb-marca`, el verde CLARO. Pedido por Miguel el 2026-08-21 después de
   verlo con el oscuro.

   Queda dicho el número, porque es la única regla de la hoja que no llega a AA:
   el `<code>` es texto chico (87,5% del tamaño base) y el verde claro da
   **3,65:1** contra el 4,5 que pide texto chico. Alcanza para texto grande
   (3,0), no para éste. El `--cb-marca-oscuro` daría 8,42:1.

   Es una decisión tomada sabiendo eso, y acotada: `<code>` marca un VALOR
   —`Activo`, `Automático`, el nombre de una variable— que casi siempre va
   acompañado de su etiqueta en texto normal al lado, así que no es la única
   forma de leer el dato. Si algún día molesta, es cambiar este token por
   `--cb-marca-oscuro` y listo.

   En modo oscuro no hay tal problema: ahí `--cb-marca` es el verde claro sobre
   fondo oscuro y da 7,7:1.
   -------------------------------------------------------------------------- */
code {
    color: var(--cb-marca);
}

/* --------------------------------------------------------------------------
   34) EL TERCER VERDE: `#4caf50` CON `!important`
   --------------------------------------------------------------------------
   Visto por Miguel el 2026-08-21 en `/config/system/mp-abandonadas`: los botones
   de exportar se veían de un verde que no es ninguno de los dos de la paleta.

   Y no lo era. En la app conviven TRES verdes:

       #009966   `--cb-marca`   el de la marca, la acción
       #28a745   `--cb-ok`      el semántico, "esto salió bien"
       #4caf50   ninguno        el de Material, escrito en `app.custom.css:655`

   El tercero es el que se ve, porque va con `!important`:

       .btn-success { background-color: #4caf50 !important; }

   Son 11 reglas así (9 de `.btn-success` y 2 de `.btn-outline-success`), y le
   ganan a todo el tema. Ése es el "verde inventado".

   EFECTO COLATERAL QUE EXPLICA EL SÍNTOMA: la sección 20 manda los botones de
   exportar al azul enganchándolos por el ícono, y `.btn:has(.ft-download)` tiene
   MÁS especificidad que `.btn-success`… pero no lleva `!important`, así que
   perdía. Por eso en esa pantalla exportar seguía verde mientras en las demás ya
   era azul: las otras no usaban `btn-success`.

   Se corrigen las dos cosas, y las dos necesitan `!important` — no por gusto,
   sino porque es la única forma de ganarle a otro `!important`. Cuando se limpie
   `app.custom.css` (que llega a producción) estas 11 reglas se borran y acá se
   puede sacar el `!important`.
   -------------------------------------------------------------------------- */

/* EXPORTAR ES AZUL, también cuando alguien lo escribió como `btn-success`. */
.btn:has(.ft-download),
.btn:has(.ti-download),
.btn:has(.ti-export),
.btn:has(.fa-download),
.btn:has(.fa-file-excel),
.btn:has(.fa-file-export),
#btn-exportar {
    background-color: var(--cb-secundario) !important;
    border-color: var(--cb-secundario) !important;
    color: var(--cb-secundario-contraste) !important;
}

.btn:has(.ft-download):hover,
.btn:has(.ti-download):hover,
.btn:has(.ti-export):hover,
.btn:has(.fa-download):hover,
.btn:has(.fa-file-excel):hover,
.btn:has(.fa-file-export):hover,
#btn-exportar:hover {
    background-color: var(--cb-secundario-hover) !important;
    border-color: var(--cb-secundario-hover) !important;
    color: var(--cb-secundario-contraste) !important;
}

/* Y CUANDO `btn-success` SÍ CORRESPONDE, que sea el verde semántico de la
   paleta y no el de Material. */
.btn-success,
.btn-success.disabled,
.btn-success:disabled {
    background-color: var(--cb-ok) !important;
    border-color: var(--cb-ok) !important;
    color: var(--cb-ok-contraste) !important;
}

.btn-success:hover,
.btn-success:not(:disabled):not(.disabled):active,
.btn-success:not(:disabled):not(.disabled).active,
.show > .btn-success.dropdown-toggle {
    background-color: var(--cb-ok-hover) !important;
    border-color: var(--cb-ok-hover) !important;
    color: var(--cb-ok-contraste) !important;
}

.btn-success:focus,
.btn-success.focus {
    box-shadow: 0 0 0 .2rem rgba(40, 167, 69, .35) !important;
}

.btn-outline-success {
    color: var(--cb-ok) !important;
    border-color: var(--cb-ok) !important;
    background-color: transparent !important;
}

.btn-outline-success:hover,
.btn-outline-success:not(:disabled):not(.disabled):active {
    background-color: var(--cb-ok) !important;
    border-color: var(--cb-ok) !important;
    color: var(--cb-ok-contraste) !important;
}

/* --------------------------------------------------------------------------
   35) TEMPORAL: EL AVISO DE "ESTÁS EN LOCAL", APAGADO
   --------------------------------------------------------------------------
   Pedido por Miguel el 2026-08-21: quiere ver el header como se va a ver en
   producción mientras se construye la paleta.

   La barra de entorno vive INLINE en `partials/navbar.blade.php:54`, dentro de
   un `@env('local')`. Producción nunca la imprime, así que no es un color del
   rediseño — pero en local tapa el header real con el verde de marca y no deja
   juzgar cómo queda.

   Se apaga desde acá y NO tocando el blade, por dos motivos: el blade llega a
   producción y esta hoja no, y para volver a prenderlo alcanza con borrar esta
   sección. El `!important` es necesario porque hay que ganarle a un atributo
   `style` inline.

   `#fff` es el fondo real de `.header` en el tema, así que queda idéntico a
   producción. La variante oscura apaga la regla de la sección 7.

   PARA VOLVER A PRENDERLO: borrar la sección entera. El aviso vuelve solo.
   -------------------------------------------------------------------------- */
.header.local-env-header {
    background-color: #fff !important;
}

body.dark .header.local-env-header {
    background-color: var(--cb-superficie) !important;
}

/* --------------------------------------------------------------------------
   36) EL ENCABEZADO DE VIDEOS, BLANCO PLANO — ARREGLADO EN EL ORIGEN
   --------------------------------------------------------------------------
   Pedido por Miguel el 2026-08-21: sin degradé, blanco liso. Tenía
   `#ffffff → #f8f9fa → #ffffff`, que casi no se percibe pero ensucia el borde.

   ACÁ NO HAY REGLA, Y ES A PROPÓSITO. El primer intento fue taparlo desde esta
   hoja con `!important`, pero la regla no vive en un CSS: está **inline en
   cuatro vistas**, cada una con su propio `<style>` —`web/news/index`,
   `web/news/posts`, `web/news/allWebinars` y `reports/index`—, las mismas diez
   declaraciones copiadas cuatro veces. Taparlo desde afuera dejaba el degradé
   escrito en el código y una regla `!important` acá para anularlo: dos cosas
   que decían lo contrario.

   Se cambió en las cuatro vistas. **Eso llega a producción**, y es un cambio
   mínimo —de un degradé casi blanco a blanco— pero es un cambio real.

   La variante oscura también: era otro degradé (`#0f172b → #1e293b → #0f172b`)
   y quedó en `#1e293b` plano. Esos hexes siguen sin tokenizar porque están en
   el blade, que llega a producción; entran en la limpieza final junto con la
   unificación de los cuatro bloques repetidos.
   -------------------------------------------------------------------------- */

/* --------------------------------------------------------------------------
   37) LOS ACCESOS DEL DASHBOARD, EN EL AZUL DE MARCA
   --------------------------------------------------------------------------
   Pedido por Miguel el 2026-08-21. Son los **37 botones** de ancho completo de
   `/home`, repartidos en las cinco vistas según el rol: `home_admin` (13),
   `home_coordinador` (9), `home_broker` (6), `home_partner` (5) y
   `home_instructor` (4).

   Sigue el mismo criterio que los títulos de la sección 27 y que los botones de
   exportar: **el verde es la acción, el azul es la estructura**. Estos botones
   no hacen nada — llevan a otra pantalla. Son el índice del panel, no una
   acción, y si todo el dashboard es verde el verde deja de significar algo.

   EL GANCHO ES LA COMBINACIÓN DE LAS TRES CLASES. `btn-outline-primary` sola
   aparece 102 veces en la app y la mayoría sí son acciones; lo que identifica a
   estos es que además sean `btn-block` (ancho completo) y `btn-rounded`. Esa
   terna existe únicamente en las cinco vistas de home — verificado, 37 de 37.

   No se toca el markup: son cinco vistas que llegan a producción y esta hoja no.

   Contraste: `#082146` con blanco da 15,95:1 al pasar el mouse, y el borde y el
   texto en reposo, 15,95:1 sobre el fondo de la card.
   -------------------------------------------------------------------------- */
.btn-rounded.btn-block.btn-outline-primary {
    color: var(--cb-secundario);
    border-color: var(--cb-secundario);
    background-color: transparent;
}

.btn-rounded.btn-block.btn-outline-primary:hover,
.btn-rounded.btn-block.btn-outline-primary:focus,
.btn-rounded.btn-block.btn-outline-primary:not(:disabled):not(.disabled):active {
    background-color: var(--cb-secundario);
    border-color: var(--cb-secundario);
    color: var(--cb-secundario-contraste);
}

/* En oscuro hay que repetirlo con `.card`/`.row` por lo de la sección 31: estos
   botones son `<a>` y viven dentro de cards. */
body.dark .card .btn-rounded.btn-block.btn-outline-primary,
body.dark .row .btn-rounded.btn-block.btn-outline-primary {
    color: var(--cb-secundario);
    border-color: var(--cb-secundario);
}

body.dark .card .btn-rounded.btn-block.btn-outline-primary:hover,
body.dark .row .btn-rounded.btn-block.btn-outline-primary:hover {
    color: var(--cb-secundario-contraste);
}

/* --------------------------------------------------------------------------
   38) LOS FILTROS POR CATEGORÍA DE NOVEDADES, AL AZUL DE MARCA
   --------------------------------------------------------------------------
   Pedido por Miguel el 2026-08-21. Son los botones con la foto del autor que
   filtran por categoría, en `web/news/allWebinars` y `web/news/posts`.

   EL GANCHO ES `d-inline-flex`, y no es arbitrario: `btn-outline-dark` aparece
   32 veces en la app y la mayoría son acciones de tabla —"Ver", "Descargar"—
   que no tienen nada que ver con esto. Lo que distingue a estos dos es que son
   `flex`, porque llevan una imagen redonda al lado del texto. Verificado: la
   combinación `btn-outline-dark` + `btn-rounded` + `d-inline-flex` existe
   únicamente en esos dos lugares.

   Mismo criterio que las secciones 27 y 37: filtrar es navegar, no actuar. Van
   en azul; el verde queda para lo que ejecuta algo.
   -------------------------------------------------------------------------- */
.btn-outline-dark.btn-rounded.d-inline-flex {
    color: var(--cb-secundario);
    border-color: var(--cb-secundario);
    background-color: transparent;
}

.btn-outline-dark.btn-rounded.d-inline-flex:hover,
.btn-outline-dark.btn-rounded.d-inline-flex:focus,
.btn-outline-dark.btn-rounded.d-inline-flex:not(:disabled):not(.disabled):active {
    background-color: var(--cb-secundario);
    border-color: var(--cb-secundario);
    color: var(--cb-secundario-contraste);
}

/* Son `<a>` dentro de un row: en oscuro hay que repetirlo (sección 31). */
body.dark .card .btn-outline-dark.btn-rounded.d-inline-flex,
body.dark .row .btn-outline-dark.btn-rounded.d-inline-flex {
    color: var(--cb-secundario);
    border-color: var(--cb-secundario);
}

body.dark .card .btn-outline-dark.btn-rounded.d-inline-flex:hover,
body.dark .row .btn-outline-dark.btn-rounded.d-inline-flex:hover {
    color: var(--cb-secundario-contraste);
}

/* --------------------------------------------------------------------------
   39) LOS `btn-outline-dark` DENTRO DE UNA CARD, AL AZUL DE MARCA
   --------------------------------------------------------------------------
   Pedido por Miguel el 2026-08-21. `btn-outline-dark` es la variante NEUTRA del
   tema —ni acción ni peligro— y hasta acá tomaba `--cb-gris-800` (sección 30).
   Un gris neutro no dice nada; el azul de marca dice lo mismo pero pertenece a
   la identidad.

   Esto NO le saca protagonismo al verde, que es lo que cuidan las secciones 27,
   37 y 38: no se está pasando una acción a azul, se está cambiando un gris por
   el azul de la marca. Los botones que ejecutan algo siguen en verde.

   ALCANZA A 32 MENOS LOS DE AFUERA DE UNA CARD. Están repartidos en: los cuatro
   de MercadoPago en la ficha de usuario (`users/edit`), los detalles de los seis
   brokers, `users/show`, las páginas de novedades, "VER INFORME" de Informes y
   Reportes, y los cards de video.

   QUEDA AFUERA `vendor/laravel-log-viewer/log.blade.php`, y a propósito: es una
   vista publicada de un paquete, no tiene el layout del panel y es el visor que
   usa sólo el super-admin. Está anotado en `EST_PENDING.md` como excluido desde
   la migración de los `confirm()`.

   Los dos filtros de categoría de la sección 38 ya estaban cubiertos por su
   propia regla, que es más específica y sigue ganando.
   -------------------------------------------------------------------------- */
.card .btn-outline-dark {
    color: var(--cb-secundario);
    border-color: var(--cb-secundario);
    background-color: transparent;
}

.card .btn-outline-dark:hover,
.card .btn-outline-dark:focus,
.card .btn-outline-dark:not(:disabled):not(.disabled):active {
    background-color: var(--cb-secundario);
    border-color: var(--cb-secundario);
    color: var(--cb-secundario-contraste);
}

/* En oscuro `body.dark .card a` sigue pegándole a los que son `<a>` (sección
   31), así que hace falta la variante. */
body.dark .card .btn-outline-dark {
    color: var(--cb-secundario);
    border-color: var(--cb-secundario);
}

body.dark .card .btn-outline-dark:hover {
    color: var(--cb-secundario-contraste);
}

/* --------------------------------------------------------------------------
   40) EXPORTAR EN AZUL, PERO SIN ROMPER EL `outline`
   --------------------------------------------------------------------------
   Visto por Miguel el 2026-08-21 en `/informes`: ahí hay una fila de tres
   botones chicos —ver (`ti-eye`), descargar (`ti-download`) y borrar
   (`ti-trash`)—, los tres `btn-sm btn-outline-primary`, y **el del medio salía
   sólido**. La fila quedaba despareja.

   Es un defecto de la sección 20: engancha los botones de exportar por el ícono
   y les pone fondo sólido, dando por sentado que exportar siempre se dibuja como
   un botón sólido. En `/informes` no: ahí es un ícono más de una fila de
   acciones, y el autor eligió `outline` a propósito.

   Se corrige el criterio, no el gancho: **exportar define el COLOR, no la
   forma**. Si el botón es `outline`, se queda outline —color y borde azules,
   fondo transparente— y sólo se llena al pasar el mouse, como cualquier
   `btn-outline-*`. Si es sólido, sigue sólido.

   `[class*="btn-outline-"]` cubre las nueve variantes de una, sin listarlas. Con
   `.btn` adelante suma tres clases y le gana al `!important` de la sección 34,
   que tiene dos.
   -------------------------------------------------------------------------- */
.btn[class*="btn-outline-"]:has(.ft-download),
.btn[class*="btn-outline-"]:has(.ti-download),
.btn[class*="btn-outline-"]:has(.ti-export),
.btn[class*="btn-outline-"]:has(.fa-download),
.btn[class*="btn-outline-"]:has(.fa-file-excel),
.btn[class*="btn-outline-"]:has(.fa-file-export) {
    background-color: transparent !important;
    border-color: var(--cb-secundario) !important;
    color: var(--cb-secundario) !important;
}

.btn[class*="btn-outline-"]:has(.ft-download):hover,
.btn[class*="btn-outline-"]:has(.ti-download):hover,
.btn[class*="btn-outline-"]:has(.ti-export):hover,
.btn[class*="btn-outline-"]:has(.fa-download):hover,
.btn[class*="btn-outline-"]:has(.fa-file-excel):hover,
.btn[class*="btn-outline-"]:has(.fa-file-export):hover,
.btn[class*="btn-outline-"]:has(.ft-download):focus,
.btn[class*="btn-outline-"]:has(.ti-download):focus,
.btn[class*="btn-outline-"]:has(.ti-export):focus,
.btn[class*="btn-outline-"]:has(.fa-download):focus,
.btn[class*="btn-outline-"]:has(.fa-file-excel):focus,
.btn[class*="btn-outline-"]:has(.fa-file-export):focus {
    background-color: var(--cb-secundario) !important;
    border-color: var(--cb-secundario) !important;
    color: var(--cb-secundario-contraste) !important;
}

/* --------------------------------------------------------------------------
   41) LAS SECCIONES DE BROKER, EN EL AZUL DE MARCA — MENOS LOS MODALES
   --------------------------------------------------------------------------
   Pedido por Miguel el 2026-08-21 para ir más rápido: en vez de ir botón por
   botón, toda la sección.

   HIZO FALTA UN GANCHO NUEVO, porque el CSS no tiene forma de saber en qué
   pantalla está. Se agregó en `layouts/app.blade.php` una clase al `<body>`
   derivada del **prefijo del nombre de ruta** (`balanz.index` → `ruta-balanz`).
   Es aditiva: si nadie la usa no cambia un pixel, y en producción no la usa
   nadie porque esta hoja no carga ahí. Sirve para cualquier sección futura.

   Se usa `[class*="ruta-balanz"]` y no `.ruta-balanz` a propósito: las
   subsecciones tienen su propio prefijo —`balanz-conditions`,
   `balanz-occupations`, `balanz-reasons`— y así entran todas sin listarlas.

   POR QUÉ. Los menús de broker usan `btn-danger` y `btn-outline-danger` para
   NAVEGAR —"Ver Resumen", "Editar Opciones de Listas"—. Rojo de peligro para
   moverse entre pantallas.

   LOS MODALES QUEDAN AFUERA, y ésta es la corrección importante. El primer
   intento pintó **todos** los `.btn` de la sección y se llevó puestos los
   botones de los modales, que estaban bien: ahí "Guardar" es una acción real y
   le corresponde el verde. Un menú de navegación y un formulario no son lo
   mismo aunque estén en la misma pantalla.

   El `:not(.modal .btn)` es la forma corta de decir "salvo dentro de un modal".
   Sube la especificidad —cuenta como `.modal .btn`, su argumento más
   específico— pero eso no molesta: sigue sin alcanzar a lo que excluye.

   SE RESPETA LA FORMA: sólido sigue sólido, `outline` sigue outline (sección 40).

   Y BORRAR SIGUE ROJO: se excluye por clase (`btn-delete`, `btn-outline-delete`)
   y por ícono (`fa-trash`, `ti-trash`). Ahí el rojo no decora, avisa.
   -------------------------------------------------------------------------- */
body[class*="ruta-balanz"] .btn:not(.modal .btn),
body[class*="ruta-sbs"] .btn:not(.modal .btn),
body[class*="ruta-servente"] .btn:not(.modal .btn),
body[class*="ruta-ppi"] .btn:not(.modal .btn),
body[class*="ruta-iol"] .btn:not(.modal .btn),
body[class*="ruta-eco"] .btn:not(.modal .btn),
body[class*="ruta-decrypto"] .btn:not(.modal .btn),
body[class*="ruta-simplestate"] .btn:not(.modal .btn) {
    background-color: var(--cb-secundario);
    border-color: var(--cb-secundario);
    color: var(--cb-secundario-contraste);
}

body[class*="ruta-balanz"] .btn[class*="btn-outline-"]:not(.modal .btn),
body[class*="ruta-sbs"] .btn[class*="btn-outline-"]:not(.modal .btn),
body[class*="ruta-servente"] .btn[class*="btn-outline-"]:not(.modal .btn),
body[class*="ruta-ppi"] .btn[class*="btn-outline-"]:not(.modal .btn),
body[class*="ruta-iol"] .btn[class*="btn-outline-"]:not(.modal .btn),
body[class*="ruta-eco"] .btn[class*="btn-outline-"]:not(.modal .btn),
body[class*="ruta-decrypto"] .btn[class*="btn-outline-"]:not(.modal .btn),
body[class*="ruta-simplestate"] .btn[class*="btn-outline-"]:not(.modal .btn) {
    background-color: transparent;
    border-color: var(--cb-secundario);
    color: var(--cb-secundario);
}

body[class*="ruta-balanz"] .btn[class*="btn-outline-"]:not(.modal .btn):hover,
body[class*="ruta-sbs"] .btn[class*="btn-outline-"]:not(.modal .btn):hover,
body[class*="ruta-servente"] .btn[class*="btn-outline-"]:not(.modal .btn):hover,
body[class*="ruta-ppi"] .btn[class*="btn-outline-"]:not(.modal .btn):hover,
body[class*="ruta-iol"] .btn[class*="btn-outline-"]:not(.modal .btn):hover,
body[class*="ruta-eco"] .btn[class*="btn-outline-"]:not(.modal .btn):hover,
body[class*="ruta-decrypto"] .btn[class*="btn-outline-"]:not(.modal .btn):hover,
body[class*="ruta-simplestate"] .btn[class*="btn-outline-"]:not(.modal .btn):hover,
body[class*="ruta-balanz"] .btn[class*="btn-outline-"]:not(.modal .btn):focus,
body[class*="ruta-sbs"] .btn[class*="btn-outline-"]:not(.modal .btn):focus,
body[class*="ruta-servente"] .btn[class*="btn-outline-"]:not(.modal .btn):focus,
body[class*="ruta-ppi"] .btn[class*="btn-outline-"]:not(.modal .btn):focus,
body[class*="ruta-iol"] .btn[class*="btn-outline-"]:not(.modal .btn):focus,
body[class*="ruta-eco"] .btn[class*="btn-outline-"]:not(.modal .btn):focus,
body[class*="ruta-decrypto"] .btn[class*="btn-outline-"]:not(.modal .btn):focus,
body[class*="ruta-simplestate"] .btn[class*="btn-outline-"]:not(.modal .btn):focus {
    background-color: var(--cb-secundario);
    border-color: var(--cb-secundario);
    color: var(--cb-secundario-contraste);
}

/* BORRAR SIGUE SIENDO ROJO. */
body[class*="ruta-balanz"] .btn:not(.modal .btn).btn-delete,
body[class*="ruta-sbs"] .btn:not(.modal .btn).btn-delete,
body[class*="ruta-servente"] .btn:not(.modal .btn).btn-delete,
body[class*="ruta-ppi"] .btn:not(.modal .btn).btn-delete,
body[class*="ruta-iol"] .btn:not(.modal .btn).btn-delete,
body[class*="ruta-eco"] .btn:not(.modal .btn).btn-delete,
body[class*="ruta-decrypto"] .btn:not(.modal .btn).btn-delete,
body[class*="ruta-simplestate"] .btn:not(.modal .btn).btn-delete,
body[class*="ruta-balanz"] .btn:not(.modal .btn).btn-outline-delete,
body[class*="ruta-sbs"] .btn:not(.modal .btn).btn-outline-delete,
body[class*="ruta-servente"] .btn:not(.modal .btn).btn-outline-delete,
body[class*="ruta-ppi"] .btn:not(.modal .btn).btn-outline-delete,
body[class*="ruta-iol"] .btn:not(.modal .btn).btn-outline-delete,
body[class*="ruta-eco"] .btn:not(.modal .btn).btn-outline-delete,
body[class*="ruta-decrypto"] .btn:not(.modal .btn).btn-outline-delete,
body[class*="ruta-simplestate"] .btn:not(.modal .btn).btn-outline-delete,
body[class*="ruta-balanz"] .btn:not(.modal .btn):has(.fa-trash),
body[class*="ruta-sbs"] .btn:not(.modal .btn):has(.fa-trash),
body[class*="ruta-servente"] .btn:not(.modal .btn):has(.fa-trash),
body[class*="ruta-ppi"] .btn:not(.modal .btn):has(.fa-trash),
body[class*="ruta-iol"] .btn:not(.modal .btn):has(.fa-trash),
body[class*="ruta-eco"] .btn:not(.modal .btn):has(.fa-trash),
body[class*="ruta-decrypto"] .btn:not(.modal .btn):has(.fa-trash),
body[class*="ruta-simplestate"] .btn:not(.modal .btn):has(.fa-trash),
body[class*="ruta-balanz"] .btn:not(.modal .btn):has(.ti-trash),
body[class*="ruta-sbs"] .btn:not(.modal .btn):has(.ti-trash),
body[class*="ruta-servente"] .btn:not(.modal .btn):has(.ti-trash),
body[class*="ruta-ppi"] .btn:not(.modal .btn):has(.ti-trash),
body[class*="ruta-iol"] .btn:not(.modal .btn):has(.ti-trash),
body[class*="ruta-eco"] .btn:not(.modal .btn):has(.ti-trash),
body[class*="ruta-decrypto"] .btn:not(.modal .btn):has(.ti-trash),
body[class*="ruta-simplestate"] .btn:not(.modal .btn):has(.ti-trash) {
    background-color: var(--cb-error);
    border-color: var(--cb-error);
    color: var(--cb-error-contraste);
}

/* --------------------------------------------------------------------------
   42) COMUNIDAD: TODO EN AZUL MENOS CREAR
   --------------------------------------------------------------------------
   Pedido por Miguel el 2026-08-21 para `/community-groups`. Mismo criterio que
   la sección 41 y el mismo gancho de ruta, pero con una excepción explícita.

   La pantalla tiene cinco botones arriba —Crear Nuevo Grupo, Ver Formulario,
   Administrar Usuarios, Procesar Pendientes, Buscar usuario— y de esos **sólo
   Crear ejecuta algo en esta pantalla**; los otros cuatro llevan a otro lado o
   abren una búsqueda. Tres de ellos, además, son `btn-danger`: rojo de peligro
   para navegar.

   CREAR SE ENGANCHA POR EL ÍCONO (`ti-plus`), no por la clase: comparte
   `btn-primary` con otros de la misma pantalla. Es el mismo recurso que la
   sección 20 usa para exportar — cuando la clase no distingue, distingue el
   ícono. Y así queda cubierto cualquier "crear" que se agregue después.

   COMO EN LA 41, quedan afuera los modales —ahí "Buscar" y "Guardar" son
   acciones— y los botones de borrar, que siguen en rojo.

   `[class*="ruta-community"]` cubre `community-groups` y `community-users` de
   una: son la misma sección para quien la usa.
   -------------------------------------------------------------------------- */
body[class*="ruta-community"] .btn:not(.modal .btn):not(:has(.ti-plus)) {
    background-color: var(--cb-secundario);
    border-color: var(--cb-secundario);
    color: var(--cb-secundario-contraste);
}

body[class*="ruta-community"] .btn[class*="btn-outline-"]:not(.modal .btn):not(:has(.ti-plus)) {
    background-color: transparent;
    border-color: var(--cb-secundario);
    color: var(--cb-secundario);
}

body[class*="ruta-community"] .btn[class*="btn-outline-"]:not(.modal .btn):not(:has(.ti-plus)):hover,
body[class*="ruta-community"] .btn[class*="btn-outline-"]:not(.modal .btn):not(:has(.ti-plus)):focus {
    background-color: var(--cb-secundario);
    border-color: var(--cb-secundario);
    color: var(--cb-secundario-contraste);
}

/* CREAR SE QUEDA EN VERDE: es la acción de la pantalla. */
body[class*="ruta-community"] .btn:has(.ti-plus) {
    background-color: var(--cb-marca);
    border-color: var(--cb-marca);
    color: var(--cb-marca-contraste);
}

body[class*="ruta-community"] .btn:has(.ti-plus):hover {
    background-color: var(--cb-marca-hover);
    border-color: var(--cb-marca-hover);
    color: var(--cb-marca-contraste);
}

/* BORRAR SIGUE SIENDO ROJO. */
body[class*="ruta-community"] .btn.btn-delete:not(.modal .btn),
body[class*="ruta-community"] .btn.btn-outline-delete:not(.modal .btn),
body[class*="ruta-community"] .btn:has(.fa-trash):not(.modal .btn),
body[class*="ruta-community"] .btn:has(.ti-trash):not(.modal .btn) {
    background-color: var(--cb-error);
    border-color: var(--cb-error);
    color: var(--cb-error-contraste);
}

/* PROCESAR PENDIENTES SE QUEDA EN ROJO. Pedido por Miguel el 2026-08-21, y tiene
   sentido: de los cinco de arriba es el único que **cambia datos de clientes** —
   asigna a los pendientes a un grupo de WhatsApp— y no se puede deshacer solo.
   El rojo ahí no es "peligro" de borrar, es "esto tiene consecuencias".

   Se engancha por el `data-target` del modal, que es lo único que lo identifica:
   comparte clase con "Administrar Usuarios" y "Buscar usuario". */
body[class*="ruta-community"] .btn[data-target="#modalProcessPending"] {
    background-color: var(--cb-error);
    border-color: var(--cb-error);
    color: var(--cb-error-contraste);
}

body[class*="ruta-community"] .btn[data-target="#modalProcessPending"]:hover {
    background-color: var(--cb-error-hover);
    border-color: var(--cb-error-hover);
    color: var(--cb-error-contraste);
}

/* --------------------------------------------------------------------------
   43) CURSOS Y GRUPOS: SÓLO LA FILA DE BOTONES DEL MENÚ
   --------------------------------------------------------------------------
   Pedido por Miguel el 2026-08-22 para `/course` y `/group`, y con una
   aclaración que corrige el alcance: **sólo los botones del menú**, no todos los
   de la pantalla.

   Es el ajuste que faltaba después de lo de los modales (sección 41). "Toda la
   sección" se pasa de largo: se lleva puestos el "Nuevo curso", el "Buscar" del
   filtro y el "Editar" de cada card, que son acciones. Lo que hay que pintar es
   la **barra de navegación de la pantalla**, que es otra cosa.

   EL GANCHO ES EL MAQUETADO DE ESA BARRA, no la ruta sola:

       .row.col-12 > [class*="mb-4"] .btn

   Es el patrón con el que están escritas todas las filas de menú del panel —un
   `row col-12` con un `<div class="mb-4 mr-2">` por botón—, el mismo que se
   unificó a 7px más temprano. Selecciona exactamente la barra y nada más: ni el
   encabezado, ni las cards, ni los modales, ni el buscador.

   En Cursos son los cinco filtros (Mostrar Todo, Cursos, Talleres, OnDemand,
   Combos) y en Grupos el "Filtrar por Curso" y sus vecinos. Todos eran
   `btn-danger` o `btn-outline-danger`: rojo de peligro para filtrar una lista.

   LO QUE YA NO SE TOCA, y antes sí: "Nuevo curso", "Buscar", "Limpiar" y el
   "Editar" de cada card se quedan como estaban.
   -------------------------------------------------------------------------- */
body[class*="ruta-course"] .row.col-12 > [class*="mb-4"] .btn,
body[class*="ruta-group"] .row.col-12 > [class*="mb-4"] .btn {
    background-color: var(--cb-secundario);
    border-color: var(--cb-secundario);
    color: var(--cb-secundario-contraste);
}

body[class*="ruta-course"] .row.col-12 > [class*="mb-4"] .btn[class*="btn-outline-"],
body[class*="ruta-group"] .row.col-12 > [class*="mb-4"] .btn[class*="btn-outline-"] {
    background-color: transparent;
    border-color: var(--cb-secundario);
    color: var(--cb-secundario);
}

body[class*="ruta-course"] .row.col-12 > [class*="mb-4"] .btn[class*="btn-outline-"]:hover,
body[class*="ruta-group"] .row.col-12 > [class*="mb-4"] .btn[class*="btn-outline-"]:hover,
body[class*="ruta-course"] .row.col-12 > [class*="mb-4"] .btn[class*="btn-outline-"]:focus,
body[class*="ruta-group"] .row.col-12 > [class*="mb-4"] .btn[class*="btn-outline-"]:focus {
    background-color: var(--cb-secundario);
    border-color: var(--cb-secundario);
    color: var(--cb-secundario-contraste);
}

/* --------------------------------------------------------------------------
   44) EL HOVER QUE FALTABA EN LAS REGLAS DE SECCIÓN
   --------------------------------------------------------------------------
   Notado por Miguel el 2026-08-22: algunos botones de `/group` y `/course` no
   reaccionaban al pasar el mouse.

   Es un descuido de las secciones 41, 42 y 43. En las tres se escribió el color
   base para TODOS los botones pero el `:hover` **sólo para los `outline`**. Los
   sólidos quedaban con la regla base, que tiene cinco clases de especificidad y
   le gana a cualquier `:hover` de más abajo —el de la sección 17, el del tema—:
   el fondo no cambiaba nunca y el botón se sentía muerto.

   No se ve como "falta un color", se ve como que el botón no anda. Por eso vale
   la pena la nota: **cuando una regla de sección pisa el color base, tiene que
   pisar también el `:hover`**, o lo apaga.

   Los outline ya tienen el suyo en cada sección. Acá van sólo los sólidos, y se
   excluyen los que tienen hover propio: "Crear" y "Procesar Pendientes" de
   Comunidad.
   -------------------------------------------------------------------------- */
body[class*="ruta-balanz"] .btn:not(.modal .btn):hover,
body[class*="ruta-sbs"] .btn:not(.modal .btn):hover,
body[class*="ruta-servente"] .btn:not(.modal .btn):hover,
body[class*="ruta-ppi"] .btn:not(.modal .btn):hover,
body[class*="ruta-iol"] .btn:not(.modal .btn):hover,
body[class*="ruta-eco"] .btn:not(.modal .btn):hover,
body[class*="ruta-decrypto"] .btn:not(.modal .btn):hover,
body[class*="ruta-simplestate"] .btn:not(.modal .btn):hover,
body[class*="ruta-community"] .btn:not(.modal .btn):not(:has(.ti-plus)):not([data-target="#modalProcessPending"]):hover,
body[class*="ruta-course"] .row.col-12 > [class*="mb-4"] .btn:hover,
body[class*="ruta-group"] .row.col-12 > [class*="mb-4"] .btn:hover {
    background-color: var(--cb-secundario-hover);
    border-color: var(--cb-secundario-hover);
    color: var(--cb-secundario-contraste);
}

/* --------------------------------------------------------------------------
   45) EL "EDITAR" DE LAS LISTAS DE CURSOS Y GRUPOS
   --------------------------------------------------------------------------
   Pedido por Miguel el 2026-08-22. El "Editar" de cada card era
   `btn-outline-danger`: rojo de peligro para abrir un formulario.

   SE CUBREN TODOS LOS `danger` DE ESAS DOS PANTALLAS, no sólo el Editar, y se
   puede porque **ahí no hay ni un botón de borrar**: verificado, los únicos
   `danger` de `courses/index` y `groups/index` son los cinco filtros, los cuatro
   desplegables de filtro y el Editar. Con esto queda cubierto también lo que se
   agregue después, sin volver a tocar la hoja.

   La regla de la sección 43 ya pintaba los del menú; ésta agrega los que están
   fuera de esa barra. Se superponen sin conflicto porque dicen lo mismo.

   Va con su `:hover`, que es la lección de la sección 44: si se pisa el color
   base y no el hover, el botón deja de reaccionar.
   -------------------------------------------------------------------------- */
body[class*="ruta-course"] .btn.btn-danger:not(.modal .btn),
body[class*="ruta-group"] .btn.btn-danger:not(.modal .btn) {
    background-color: var(--cb-secundario);
    border-color: var(--cb-secundario);
    color: var(--cb-secundario-contraste);
}

body[class*="ruta-course"] .btn.btn-outline-danger:not(.modal .btn),
body[class*="ruta-group"] .btn.btn-outline-danger:not(.modal .btn) {
    background-color: transparent;
    border-color: var(--cb-secundario);
    color: var(--cb-secundario);
}

body[class*="ruta-course"] .btn.btn-danger:hover:not(.modal .btn),
body[class*="ruta-group"] .btn.btn-danger:hover:not(.modal .btn),
body[class*="ruta-course"] .btn.btn-outline-danger:hover:not(.modal .btn),
body[class*="ruta-group"] .btn.btn-outline-danger:hover:not(.modal .btn),
body[class*="ruta-course"] .btn.btn-outline-danger:focus:not(.modal .btn),
body[class*="ruta-group"] .btn.btn-outline-danger:focus:not(.modal .btn) {
    background-color: var(--cb-secundario-hover);
    border-color: var(--cb-secundario-hover);
    color: var(--cb-secundario-contraste);
}

/* --------------------------------------------------------------------------
   46) TODOS LOS "EDITAR", DEL MISMO COLOR
   --------------------------------------------------------------------------
   Medido el 2026-08-22: hay **27 botones que llevan a una ruta `.edit`** y están
   escritos en **siete variantes distintas** —8 `btn-outline-primary`, 7
   `btn-outline-dark`, 6 `btn-outline-secondary`, 2 `btn-primary`, 2
   `btn-outline-danger`, 1 `btn-success` y 1 `btn-secondary`—. La misma acción,
   siete colores, según quién hizo cada pantalla.

   Es exactamente el caso de exportar (sección 20, cinco colores) y del botón
   Configuración (sección 22).

   EL GANCHO ES EL DESTINO, NO LA CLASE NI EL TEXTO. Las clases no distinguen
   —las comparten con botones que hacen otra cosa— y el CSS no puede leer el
   texto de un elemento. Lo que sí distingue es a dónde va: `href*="/edit"`, que
   es lo que genera `route('x.edit', …)` en los 27 casos. Además cubre solo, sin
   tocar nada, cualquier "Editar" que se escriba después.

   VA EN AZUL porque editar **abre un formulario**, no ejecuta nada. El verde
   queda para el "Guardar" de ese formulario, que es donde el cambio ocurre de
   verdad. Es el mismo reparto de las secciones 27, 37 y 41.

   Se respeta la forma (sección 40) y va con su `:hover` (sección 44).
   -------------------------------------------------------------------------- */
a.btn[href*="/edit"] {
    background-color: var(--cb-secundario);
    border-color: var(--cb-secundario);
    color: var(--cb-secundario-contraste);
}

a.btn[href*="/edit"][class*="btn-outline-"] {
    background-color: transparent;
    border-color: var(--cb-secundario);
    color: var(--cb-secundario);
}

a.btn[href*="/edit"]:hover,
a.btn[href*="/edit"]:focus,
a.btn[href*="/edit"][class*="btn-outline-"]:hover,
a.btn[href*="/edit"][class*="btn-outline-"]:focus {
    background-color: var(--cb-secundario-hover);
    border-color: var(--cb-secundario-hover);
    color: var(--cb-secundario-contraste);
}

/* En oscuro, los que están dentro de una card necesitan la variante por lo de la
   sección 31: son `<a>` y `body.dark .card a` les gana. */
body.dark .card a.btn[href*="/edit"],
body.dark .row a.btn[href*="/edit"] {
    color: var(--cb-secundario-contraste);
}

body.dark .card a.btn[href*="/edit"][class*="btn-outline-"],
body.dark .row a.btn[href*="/edit"][class*="btn-outline-"] {
    color: var(--cb-secundario);
}

/* --------------------------------------------------------------------------
   47) EL FILTRO POR CURSO DE RESEÑAS
   --------------------------------------------------------------------------
   Pedido por Miguel el 2026-08-22 para `/reviews/0`. Era `btn-outline-danger`:
   rojo de peligro para filtrar una lista, como los de Cursos y Grupos.

   NO LO ALCANZABA LA SECCIÓN 43 aunque haga exactamente lo mismo, y la razón es
   de maquetado: allá los filtros están en el patrón `.row.col-12 >
   [class*="mb-4"]` y acá el botón cuelga de un `<div class="mb-3">` suelto. El
   gancho de la 43 es la barra de menú, no el rol del botón, así que este queda
   afuera.

   Se engancha por sus clases —`btn-outline-danger` + `dropdown-toggle`—, que en
   la sección de reseñas identifican sólo a este botón. Los otros dos `.btn` de
   la sección están en `addReview` y `create`, y ninguno es un borrar.

   ANOTADO PARA MÁS ADELANTE: hay al menos dos maquetados distintos para la misma
   barra de filtros. Unificarlos a uno solo haría que una regla los cubriera a
   todos, en vez de ir sección por sección. Es markup, así que llega a
   producción — va con la limpieza final.
   -------------------------------------------------------------------------- */
body[class*="ruta-reviews"] .btn-outline-danger.dropdown-toggle {
    background-color: transparent;
    border-color: var(--cb-secundario);
    color: var(--cb-secundario);
}

body[class*="ruta-reviews"] .btn-outline-danger.dropdown-toggle:hover,
body[class*="ruta-reviews"] .btn-outline-danger.dropdown-toggle:focus,
body[class*="ruta-reviews"] .show > .btn-outline-danger.dropdown-toggle {
    background-color: var(--cb-secundario);
    border-color: var(--cb-secundario);
    color: var(--cb-secundario-contraste);
}

/* --------------------------------------------------------------------------
   48) SUSCRIPCIONES, LA SECCIÓN ENTERA
   --------------------------------------------------------------------------
   Pedido por Miguel el 2026-08-22. Es la sección más grande del panel: **cuatro
   prefijos de ruta** —`subscription`, `subscriptions`, `subscription_classes` y
   `subscription_types`— y unos **112 botones en 12 variantes**: 35
   `btn-primary`, 17 `btn-outline-secondary`, 14 `btn-outline-primary`, 14
   `btn-outline-danger`, 8 `btn-secondary`, 8 `btn-light`, 5 `btn-dark`…

   `[class*="ruta-subscription"]` cubre los cuatro prefijos de una.

   SE REVISARON LOS ROJOS ANTES DE PINTAR, que en esta sección podían ser bajas
   de clientes. No lo son: los cuatro `btn-danger` resultaron ser "Upload file",
   "Buscar aumentos por Usuario", el modal de importar y un "Ya tengo cuenta" del
   formulario público. El único destructivo de verdad es **"Eliminar Lote"**, y
   está escrito como `btn-delete` con ícono `ti-trash`, así que ya cae en las
   exclusiones de siempre.

   EXCLUSIONES, las mismas que en las secciones 41 a 45: los modales —ahí
   "Guardar" es una acción y le toca el verde—, los botones de borrar por clase y
   por ícono, y se respeta la forma sólido/outline (sección 40). Con su `:hover`,
   que es lo que faltó en la 44.
   -------------------------------------------------------------------------- */
body[class*="ruta-subscription"] .btn:not(.modal .btn):not(.btn-delete):not(.btn-outline-delete):not(:has(.fa-trash)):not(:has(.ti-trash)):not(:has(.ti-plus)):not(:has(.ft-search)) {
    background-color: var(--cb-secundario);
    border-color: var(--cb-secundario);
    color: var(--cb-secundario-contraste);
}

body[class*="ruta-subscription"] .btn[class*="btn-outline-"]:not(.modal .btn):not(.btn-delete):not(.btn-outline-delete):not(:has(.fa-trash)):not(:has(.ti-trash)):not(:has(.ti-plus)):not(:has(.ft-search)) {
    background-color: transparent;
    border-color: var(--cb-secundario);
    color: var(--cb-secundario);
}

body[class*="ruta-subscription"] .btn:not(.modal .btn):not(.btn-delete):not(.btn-outline-delete):not(:has(.fa-trash)):not(:has(.ti-trash)):not(:has(.ti-plus)):not(:has(.ft-search)):hover,
body[class*="ruta-subscription"] .btn:not(.modal .btn):not(.btn-delete):not(.btn-outline-delete):not(:has(.fa-trash)):not(:has(.ti-trash)):not(:has(.ti-plus)):not(:has(.ft-search)):focus {
    background-color: var(--cb-secundario-hover);
    border-color: var(--cb-secundario-hover);
    color: var(--cb-secundario-contraste);
}

/* EL OUTLINE SE LLENA CON EL AZUL PLENO, no con el aclarado. Ver la nota de la
   sección 50. */
body[class*="ruta-subscription"] .btn[class*="btn-outline-"]:not(.modal .btn):not(.btn-delete):not(.btn-outline-delete):not(:has(.fa-trash)):not(:has(.ti-trash)):not(:has(.ti-plus)):not(:has(.ft-search)):hover,
body[class*="ruta-subscription"] .btn[class*="btn-outline-"]:not(.modal .btn):not(.btn-delete):not(.btn-outline-delete):not(:has(.fa-trash)):not(:has(.ti-trash)):not(:has(.ti-plus)):not(:has(.ft-search)):focus {
    background-color: var(--cb-secundario);
    border-color: var(--cb-secundario);
    color: var(--cb-secundario-contraste);
}

/* BORRAR SIGUE SIENDO ROJO — "Eliminar Lote" y los `btn-delete` de las tablas. */
body[class*="ruta-subscription"] .btn.btn-delete:not(.modal .btn),
body[class*="ruta-subscription"] .btn.btn-outline-delete:not(.modal .btn),
body[class*="ruta-subscription"] .btn:has(.ti-trash):not(.modal .btn),
body[class*="ruta-subscription"] .btn:has(.fa-trash):not(.modal .btn) {
    background-color: var(--cb-error);
    border-color: var(--cb-error);
    color: var(--cb-error-contraste);
}

/* --------------------------------------------------------------------------
   49) EL "SUBIR ARCHIVO" DEL MODAL DE IMPORTACIÓN, EN VERDE
   --------------------------------------------------------------------------
   Pedido por Miguel el 2026-08-22. Es el submit del modal `#modalImportFile` en
   `subscriptions/import`, y estaba en `btn-danger`: rojo de peligro para la
   acción principal de un formulario.

   Va al verde de marca, que es lo que corresponde y lo que hace el resto del
   panel: **el verde es lo que ejecuta**. Es la contracara de todo lo que se pasó
   a azul en las secciones 41 a 48 — ahí se sacó el verde de lo que sólo navega;
   acá se lo devuelve a lo que sí actúa.

   ES UN `<input>`, NO UN `<button>`: lo genera `Form::submit()` en
   `import/uploadForm.blade.php`, así que se engancha por `[type="submit"]`.

   Se acota al modal por su id y no a la sección entera a propósito: la 48
   excluye los modales justamente para no tocar los formularios, y esto es una
   excepción puntual dentro de uno.
   -------------------------------------------------------------------------- */
#modalImportFile .btn[type="submit"] {
    background-color: var(--cb-marca);
    border-color: var(--cb-marca);
    color: var(--cb-marca-contraste);
}

#modalImportFile .btn[type="submit"]:hover,
#modalImportFile .btn[type="submit"]:focus {
    background-color: var(--cb-marca-hover);
    border-color: var(--cb-marca-hover);
    color: var(--cb-marca-contraste);
}

/* LO QUE CREA Y LO QUE BUSCA, EN VERDE. Pedido por Miguel el 2026-08-22 para
   `subscriptions/subscribers`: "Crear Suscriptor" y "Filtrar".

   Es la misma excepción que en Comunidad (sección 42) y por el mismo motivo: la
   regla de sección pinta de azul lo que navega, pero estos dos **ejecutan** —uno
   da de alta un suscriptor, el otro corre la búsqueda—. El verde es de ellos.

   POR ÍCONO, no por clase: los dos son `btn-primary`, que en esta sección lo
   comparten con decenas de botones. `ti-plus` es "crear" y `ft-search` es
   "buscar". Medido: `ft-search` existe una sola vez en toda la sección, y
   `ti-plus` siete —el de Suscriptores más seis en las vistas de cuentas y
   planes, que son todos "agregar" y les corresponde el mismo verde—.

   Cubre solo cualquier "crear" que se agregue después, sin volver a tocar nada.
   -------------------------------------------------------------------------- */
body[class*="ruta-subscription"] .btn:has(.ti-plus),
body[class*="ruta-subscription"] .btn:has(.ft-search) {
    background-color: var(--cb-marca);
    border-color: var(--cb-marca);
    color: var(--cb-marca-contraste);
}

body[class*="ruta-subscription"] .btn:has(.ti-plus):hover,
body[class*="ruta-subscription"] .btn:has(.ft-search):hover {
    background-color: var(--cb-marca-hover);
    border-color: var(--cb-marca-hover);
    color: var(--cb-marca-contraste);
}

/* --------------------------------------------------------------------------
   50) EL HOVER DE LOS OUTLINE DE SUSCRIPCIONES
   --------------------------------------------------------------------------
   Notado por Miguel el 2026-08-22: el hover de los outline de Suscripciones se
   veía lavado al lado del de Cursos. No era una impresión — eran dos colores
   distintos.

   Hay dos tokens de azul y cada uno tiene su trabajo:

     --cb-secundario        #082146   el azul pleno
     --cb-secundario-hover  #344967   el mismo, aclarado

   - SÓLIDO: el fondo ya es `#082146`, así que el hover ACLARA a `#344967`. Si
     usara el pleno, el botón no reaccionaría.
   - OUTLINE: el fondo es transparente, así que el hover LLENA con el pleno
     `#082146`. Si usara el aclarado, el relleno sale lavado.

   La sección 48 escribió el `:hover` en un solo selector agrupado para sólidos y
   outline juntos. Como el valor correcto para el sólido es el aclarado, los
   outline se lo comieron. Es la contracara del descuido de la sección 44: allá
   faltó el hover de los sólidos, acá sobró el de los sólidos aplicado a los
   outline.

   ALCANCE: SÓLO SUSCRIPCIONES. Cursos y Grupos se dejan como están por pedido
   de Miguel, aunque el "Editar" de sus cards (sección 45) y todos los "Editar"
   del panel (sección 46) tengan el mismo aclarado en sus outline. Queda anotado
   por si más adelante se quiere unificar.

   Las secciones que ya lo tenían bien —41 (brokers), 42 (comunidad), 43 (barra
   de filtros de Cursos y Grupos), 47 (reseñas)— no se tocaron: ahí el outline
   siempre tuvo su propia regla.

   PARA LA PRÓXIMA: cuando una sección pise el color de un botón, tiene que
   escribir TRES reglas, no una — base sólido, base outline y hover de cada uno.
   Con dos alcanza sólo si la sección no tiene outline.
   -------------------------------------------------------------------------- */
