/* ============================================================================
   redy-app.css — CSS funcional propio (escrito a mano)
   ----------------------------------------------------------------------------
   OJO: el Tailwind de css/rediseno.css viene COMPILADO Y PURGADO contra la
   maqueta original, y este proyecto no tiene paso de build. Eso significa que
   una clase de Tailwind que no estuviera ya en la maqueta simplemente NO existe
   en ese archivo. Por eso todo lo que agregamos nosotros (modales, estados de
   validacion, botones flotantes, spinner) vive aqui como CSS normal, en vez de
   depender de utilidades que no se pueden regenerar.
   ============================================================================ */

/* ── Tipografia: NO se toca ───────────────────────────────────────────────────
   La maqueta declara `font-family: 'Sofia Pro', sans-serif` con
   `src: local('Sofia Pro')`, asi que quien no tenga la fuente instalada ve la
   sans del sistema. Aqui hubo una vez un respaldo con DM Sans / Sora, pensando
   que se parecia mas a la marca, pero cambiaba el aspecto aprobado: con otra
   fuente el <h1> del hero pasaba de tres lineas a cuatro. El diseno aprobado
   manda, asi que no se define ninguna font-family en este archivo.

   Pendiente para el cliente: si existe licencia web de Sofia Pro, cargarla con
   @font-face y archivos woff2 es la unica forma de que el sitio se vea con la
   tipografia de la marca en los equipos de los visitantes. Ver docs/PENDIENTES.md.
   ---------------------------------------------------------------------------- */

/* ── Modales ──────────────────────────────────────────────────────────────── */
.redy-modal {
    position: fixed;
    inset: 0;
    z-index: 60;
    display: none;
    align-items: center;
    justify-content: center;
    padding: 16px;
}

.redy-modal.abierto {
    display: flex;
}

.redy-modal__fondo {
    position: absolute;
    inset: 0;
    background: rgba(10, 8, 40, .65);
}

.redy-modal__caja {
    position: relative;
    z-index: 1;
    width: 100%;
    max-width: 470px;
    background: #fff;
    color: #2218a3;
    border-radius: 1.5rem;
    padding: 28px 24px 20px;
    text-align: center;
    box-shadow: 0 25px 50px -12px rgba(0, 0, 0, .45);
    max-height: calc(100vh - 32px);
    overflow-y: auto;
}

.redy-modal__titulo {
    font-weight: 700;
    font-size: 1.05rem;
    color: #e74c3c;
    margin-bottom: 12px;
}

.redy-modal__texto {
    font-size: .9rem;
    line-height: 1.55;
    margin-bottom: 10px;
    color: #4b5563;
}

.redy-modal__texto:last-of-type {
    margin-bottom: 0;
}

.redy-modal__cerrar {
    margin-top: 18px;
    background: #2218a3;
    color: #fff;
    font-weight: 700;
    border: 0;
    border-radius: 9999px;
    padding: 10px 28px;
    cursor: pointer;
    transition: background .15s ease;
}

.redy-modal__cerrar:hover {
    background: #150e70;
}

/* Modal de exito: contiene el iframe de gracias.php, sin padding ni scroll */
.redy-modal--iframe .redy-modal__caja {
    max-width: 800px;
    padding: 0;
    overflow: hidden;
}

.redy-modal--iframe iframe {
    width: 100%;
    height: 500px;
    border: 0;
    display: block;
}

@media (min-width: 768px) {
    .redy-modal--iframe iframe {
        height: 635px;
    }
}

/* Bloquea el scroll del fondo mientras hay un modal abierto */
body.redy-sin-scroll {
    overflow: hidden;
}

/* ── Estados de validacion del formulario ─────────────────────────────────── */
.campo-wrap {
    position: relative;
}

.campo-wrap input {
    padding-right: 38px;
}

.field-icon {
    position: absolute;
    right: 14px;
    top: 50%;
    transform: translateY(-50%);
    font-size: .95rem;
    font-weight: 700;
    line-height: 1;
    pointer-events: none;
    opacity: 0;
    transition: opacity .2s;
}

.field-icon.show {
    opacity: 1;
}

/* Iconos por contenido: evita depender de una fuente de iconos externa */
.field-icon.ok::before {
    content: "\2713";
    color: #16a34a;
}

.field-icon.err::before {
    content: "\2715";
    color: #e74c3c;
}

input.is-invalid {
    border-color: #e74c3c !important;
    box-shadow: 0 0 0 1px #e74c3c inset;
}

input.is-valid {
    border-color: #16a34a !important;
}

.field-error {
    display: block;
    font-size: .72rem;
    color: #e74c3c;
    font-weight: 600;
    margin-top: 4px;
    min-height: 6px;
}

/* Grupo de radios (tarjetas) marcado como invalido */
.radio-group-invalid .card-inner {
    border-color: #e74c3c;
}

/* Radios en tarjeta: la maqueta deja el input en position:absolute SIN un padre
   posicionado, asi que los 4 radios invisibles se apilaban en la esquina del
   contenedor .relative de la tarjeta del formulario -> se podian marcar solos al
   hacer clic ahi. Anclamos el input a su propia etiqueta y lo estiramos para que
   toda la tarjeta sea el area clickeable. */
.radio-card {
    position: relative;
    display: block;
}

.radio-card input {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    margin: 0;
    opacity: 0;
    cursor: pointer;
}

/* ── Boton de envio ───────────────────────────────────────────────────────── */
.btn-enviar {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
}

.btn-enviar:disabled {
    cursor: not-allowed;
    /* Un boton deshabilitado no dispara click ni lo propaga, asi que el handler
       de .contact-button-wrap (el que explica POR QUE esta bloqueado) nunca se
       ejecutaba al pulsar el boton. Dejando pasar el puntero, el clic llega al
       wrapper y si se abre el modal correspondiente. */
    pointer-events: none;
}

/* Deshabilitado por lead descalificado (factura=no / monto menor a 10k) */
.btn-enviar.bloqueado {
    background: #b0b0b0 !important;
    color: #fff !important;
}

.btn-spinner {
    width: 15px;
    height: 15px;
    border: 2px solid currentColor;
    border-right-color: transparent;
    border-radius: 50%;
    display: none;
    animation: redy-giro .7s linear infinite;
}

.btn-spinner.show {
    display: inline-block;
}

@keyframes redy-giro {
    to {
        transform: rotate(360deg);
    }
}

/* Mensaje de error general del formulario */
.form-msg {
    display: none;
    font-size: .78rem;
    font-weight: 600;
    color: #e74c3c;
    margin-bottom: 10px;
}

.form-msg.show {
    display: block;
}

/* ── Scroll to top (apilado sobre el boton de WhatsApp) ───────────────────── */
#scrollTop {
    position: fixed;
    bottom: 96px;
    right: 30px;
    z-index: 50;
    width: 44px;
    height: 44px;
    background: #00ff26;
    color: #2218a3;
    border: 0;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    opacity: 0;
    pointer-events: none;
    transition: opacity .25s, transform .2s;
    box-shadow: 0 8px 20px rgba(0, 0, 0, .25);
}

#scrollTop.show {
    opacity: 1;
    pointer-events: auto;
}

#scrollTop:hover {
    transform: scale(1.1);
}

/* ── Ajustes de accesibilidad / detalle ───────────────────────────────────── */
.radio-card:focus-within .card-inner {
    box-shadow: 0 0 0 2px #3d3dff;
}

/* ============================================================================
   ACCESIBILIDAD (informe de Lighthouse del 2026-08-20: 91 movil / 89 escritorio)
   ============================================================================ */

/* ╔══════════════════════════════════════════════════════════════════════════╗
   ║  VERDE PARA FONDOS CLAROS — UNICO LUGAR DONDE SE DEFINE                  ║
   ╚══════════════════════════════════════════════════════════════════════════╝

   ESTADO ACTUAL: el verde de la marca (#00ff26), por decision del cliente del
   2026-08-20. Se habia oscurecido a #008014 para pasar el audit de contraste y
   se revirtio porque no se veia bien.

   CONSECUENCIA ASUMIDA: sobre blanco este verde da 1,37:1 y sobre #f3f4f6 da
   1,24:1, asi que Lighthouse vuelve a marcar "contraste insuficiente" y la
   accesibilidad no llega a 100. Es una decision de marca, no un descuido: no
   "arreglarlo" por cuenta propia.

   Los tres textos afectados son «que te deja seguir usandolo», «tu carro nunca
   deja de ser tuyo» y «¡Empieza ya con redy!».

   SI ALGUN DIA SE QUIERE QUE PASE: cambiar solo la variable de abajo. Los tres
   titulos no hay que tocarlos.

   Dato util para esa conversacion: los tres son TEXTO GRANDE (48 px, 48 px y
   24 px en negrita), y el texto grande solo necesita 3:1, no 4,5:1. O sea que no
   hace falta irse tan oscuro como #008014 para pasar:

     #00ff26  1,37 sobre blanco  ·  1,24 sobre #f3f4f6   <- el actual, no pasa
     #00a31a  3,36              ·  3,05                  pasa, muy justo
     #008f16  4,25              ·  3,86                  pasa con margen
     #008014  5,12              ·  4,66                  el que se habia puesto
     #006b11  6,75              ·  6,13
   ---------------------------------------------------------------------------- */
:root {
    --redy-verde-claro: #00ff26;
}

.text-redy-green-dark {
    color: var(--redy-verde-claro);
}

.hover\:text-redy-green-dark:hover {
    color: var(--redy-verde-claro);
}

/* ── Areas tactiles de 24x24 (WCAG 2.2 SC 2.5.8) ─────────────────────────────
   Los puntos del carrusel median 10x10. El boton crece a 24x24 transparente y
   el punto visible pasa a ser el <span> de dentro, asi que el punto se ve igual
   de chico pero se puede pulsar. Va como clase propia porque las utilidades que
   harian esto en Tailwind (p-0, bg-transparent) no existen en el CSS purgado. */
.punto-carrusel {
    width: 24px;
    height: 24px;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    border: 0;
    background: transparent;
    cursor: pointer;
}

/* Los enlaces legales del pie median 14 px de alto y estaban a 4 px uno del
   otro. Con esto llegan a 26 px sin moverse de sitio: el relleno reemplaza al
   margen inferior que tenian. */
.enlace-legal {
    display: inline-block;
    padding-top: 6px;
    padding-bottom: 6px;
}

/* Enlace dentro de una frase corrida (el "aviso de privacidad" del formulario,
   12 px de alto). El relleno agranda el area pulsable a 24 px y el margen
   negativo lo cancela para el layout, asi que el parrafo no se separa ni se
   mueve: crece la caja que se puede tocar, no el espacio que ocupa. */
.enlace-inline-tactil {
    display: inline-block;
    padding-top: 6px;
    padding-bottom: 6px;
    margin-top: -6px;
    margin-bottom: -6px;
}

/* ============================================================================
   BOTON PRINCIPAL DEL HERO — "Quiero mi prestamo"
   ----------------------------------------------------------------------------
   Propuesta 17 del demo, elegida por el cliente el 2026-08-20. Son cuatro cosas
   trabajando juntas, y cada una cubre un momento distinto:

     1. EN REPOSO  el chip azul con la flecha. Es la pieza que mas trabaja:
        funciona incluso en una captura quieta, porque la persona ve un boton que
        lleva a algun lado. La afordancia es lo que hace que la gente pulse; el
        movimiento solo llama la atencion la primera vez.
     2. AL ACERCAR  el blanco entra barriendo desde la izquierda y el chip se
        corre 6 px. Es el mismo cambio de color que ya tenia, pero con direccion.
     3. AL PULSAR   el boton se hunde 3 px y se encoge apenas. No es adorno: es
        la respuesta que convierte un dibujo en un boton.
     4. CADA 7 s    un aro sale del boton y despues silencio. Un pulso aislado se
        lee intencional; el mismo pulso cada 2 s se lee como anuncio, y para una
        financiera regulada eso importa.

   Todo lo que se mueve son transform y opacity, o sea que lo compone la GPU sin
   recalcular layout por fotograma. Es la razon de que el sitio este en 100 de
   rendimiento y conviene no perderla.

   ESTRUCTURA DEL MARKUP (hace falta tal cual):

     <span class="btn-hero-aviso">          <- lleva el aro de cada 7 s
       <a class="btn-hero">                 <- recorta el barrido (overflow)
         <span>texto <span class="btn-hero__chip">flecha</span></span>
       </a>
     </span>

   El aro va en el envoltorio y no en el boton porque el boton necesita
   overflow:hidden para recortar el barrido blanco, y eso recortaria el aro.
   ============================================================================ */
.btn-hero {
    position: relative;
    isolation: isolate;
    overflow: hidden;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 18px;
    min-height: 68px;
    padding: 22px 20px 22px 52px;
    border-radius: 9999px;
    background: #00ff26;
    color: #2218a3;
    font-weight: 700;
    font-size: 1.25rem;
    line-height: 1.2;
    letter-spacing: -.01em;
    box-shadow: 0 14px 32px -8px rgba(0, 255, 38, .45);
    transition: transform .12s ease, box-shadow .18s ease;
}

/* El barrido blanco. Se mueve con scaleX, no cambiando el ancho, para que sea
   la GPU la que lo componga. */
.btn-hero::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 0;
    background: #fff;
    transform: scaleX(0);
    transform-origin: left center;
    transition: transform .42s cubic-bezier(.4, 0, .2, 1);
}

.btn-hero > span {
    position: relative;
    z-index: 1;
    display: inline-flex;
    align-items: center;
    gap: 18px;
    white-space: nowrap;
}

.btn-hero__chip {
    flex-shrink: 0;
    width: 40px;
    height: 40px;
    border-radius: 50%;
    background: #2218a3;
    color: #00ff26;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    transition: transform .3s cubic-bezier(.3, 0, .2, 1);
}

.btn-hero__chip svg {
    width: 18px;
    height: 18px;
}

.btn-hero:hover {
    box-shadow: 0 20px 38px -10px rgba(0, 255, 38, .55);
}

.btn-hero:hover::before {
    transform: scaleX(1);
}

.btn-hero:hover .btn-hero__chip {
    transform: translateX(6px);
}

.btn-hero:active {
    transform: translateY(3px) scale(.985);
    box-shadow: 0 5px 12px -6px rgba(0, 255, 38, .5);
}

/* El aviso cada 7 segundos, en el envoltorio */
.btn-hero-aviso {
    position: relative;
    isolation: isolate;
    display: inline-flex;
}

.btn-hero-aviso::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    border-radius: 9999px;
    border: 2px solid #00ff26;
    animation: redy-aviso 7s cubic-bezier(.2, .6, .3, 1) infinite;
    pointer-events: none;
}

@keyframes redy-aviso {
    0% {
        transform: scale(1);
        opacity: .85;
    }

    14% {
        transform: scale(1.42);
        opacity: 0;
    }

    100% {
        transform: scale(1.42);
        opacity: 0;
    }
}

/* Quien pidio menos movimiento no ve el aviso periodico. El barrido, el chip y
   la prensa SE QUEDAN: son reaccion a algo que hizo la persona, no movimiento
   no solicitado, y sin ellos el boton deja de sentirse boton. */
@media (prefers-reduced-motion: reduce) {
    .btn-hero-aviso::after {
        animation: none;
        opacity: 0;
    }
}

/* En pantallas angostas se recorta el relleno para que entre completo */
@media (max-width: 420px) {
    .btn-hero {
        gap: 14px;
        padding: 20px 16px 20px 34px;
        font-size: 1.14rem;
    }

    .btn-hero > span {
        gap: 14px;
    }

    .btn-hero__chip {
        width: 36px;
        height: 36px;
    }
}

/* Titulo de la seccion de ubicacion.
   Va en mayusculas por CSS y NO escrito en mayusculas en el HTML: algunos
   lectores de pantalla deletrean letra por letra el texto que viene todo en
   mayusculas, y ademas asi se puede copiar el texto en su forma normal. Se ve
   exactamente igual. */
.titulo-ubicacion {
    text-transform: uppercase;
}

/* En una sola linea a partir de 900 px.
   El titulo no cabia porque su contenedor mide 896 px (max-w-4xl) menos el
   relleno, o sea 848, y el texto en mayusculas a 48 px pide unos 1090. En vez
   de ensanchar el contenedor —que arrastraria tambien al parrafo y al mapa— el
   titulo se sale de el: left:50% lo lleva al centro del contenedor y
   translateX(-50%) lo centra sobre su propio ancho, que se define aparte.
   La seccion recorta con overflow-hidden, por eso el ancho se topa en 94vw.
   El tamano va con clamp para que siempre sobre margen: en el caso mas ancho el
   texto ocupa ~1020 px dentro de 1180, un 13% de holgura por si la tipografia
   real resulta mas ancha que la del sistema.
   Debajo de 900 px no entra en una linea a un tamano legible, asi que ahi se
   deja envolver como estaba. */
@media (min-width: 900px) {
    .titulo-ubicacion {
        position: relative;
        left: 50%;
        transform: translateX(-50%);
        width: min(1180px, 94vw);
        white-space: nowrap;
        font-size: clamp(1.9rem, 3.6vw, 2.8rem);
    }
}

/* ── Menu del header ─────────────────────────────────────────────────────────
   En movil "Cómo funciona" se partia en dos lineas y se leia "Cómo / funciona".
   Poner solo white-space:nowrap no alcanza: las cuatro etiquetas enteras miden
   ~357px y en una pantalla de 360 quedan ~312 utiles, asi que apareceria scroll
   horizontal. La regla es: la ETIQUETA no se parte nunca, y si no caben todas en
   una linea es el MENU el que envuelve. En escritorio caben de sobra, asi que
   ahi no cambia nada. */
header nav {
    flex-wrap: wrap;
    justify-content: center;
}

header nav a {
    white-space: nowrap;
}

/* Los cuatro enlaces en una fila necesitan ~336px; con el relleno del contenedor
   eso pide una pantalla de 384px o mas. Por debajo, en vez de dejar "Preguntas"
   sola en un segundo renglon, se acomodan en 2x2 centrado. El limite se pone en
   420px para no quedar a seis pixeles de romperse. */
/* El selector lleva [class] a proposito: la utilidad .flex de Tailwind que trae
   el <nav> tiene mas especificidad que "header nav", asi que sin ese detalle el
   display:grid pierde y el menu se queda en 3+1. */
@media (max-width: 420px) {
    header nav[class] {
        display: grid;
        grid-template-columns: repeat(2, auto);
        justify-content: center;
        column-gap: 22px;
        row-gap: 8px;
        text-align: center;
    }
}

/* Salto al contenido: fuera de la pantalla hasta que recibe el foco con el
   teclado, asi que NO altera el aspecto aprobado del diseno. */
.skip-link {
    position: absolute;
    left: 12px;
    top: -60px;
    z-index: 100;
    background: #00ff26;
    color: #2218a3;
    font-weight: 700;
    padding: 10px 18px;
    border-radius: 0 0 12px 12px;
    transition: top .18s ease;
}

.skip-link:focus {
    top: 0;
}

/* El widget de Turnstile mide 300px fijos. En la tarjeta del formulario entra,
   pero conviene que nunca pueda empujar el ancho de su contenedor.
   Se cubren las dos formas: la clase (por si vuelve el render implicito) y el
   hueco del render explicito, que es como se dibuja hoy.
   El min-height reserva el alto del widget para que al aparecer no empuje el
   boton de envio hacia abajo: eso seria un salto de layout (CLS). */
.cf-turnstile,
#turnstile-slot {
    max-width: 100%;
    min-height: 65px;
}

/* ============================================================================
   PAGINAS LEGALES (aviso-de-privacidad.html, terminos-y-condiciones.html)
   ----------------------------------------------------------------------------
   Usan el mismo header y footer que la landing, asi que cargan rediseno.css y
   este archivo. Antes traian Bootstrap, Google Fonts, redy.css y un bloque
   <style> propio; todo eso salio.

   El contenido legal es prosa, y el preflight de Tailwind deja los <p> sin
   margen y las listas sin viñetas. Por eso aqui se le devuelve el estilo de
   forma explicita: sin estas reglas el texto legal se ve como un solo bloque.
   ============================================================================ */

/* Encabezado con el titulo de la pagina */
.encabezado-pagina {
    background: #2218a3;
    color: #fff;
    padding: 56px 24px 48px;
    text-align: center;
}

.encabezado-pagina h1 {
    max-width: 820px;
    margin: 0 auto;
    font-weight: 800;
    font-size: clamp(1.8rem, 4vw, 2.8rem);
    line-height: 1.15;
    letter-spacing: -.01em;
}

.encabezado-pagina .barra {
    width: 56px;
    height: 5px;
    background: #00ff26;
    border-radius: 99px;
    margin: 18px auto 0;
}

/* La seccion blanca a todo lo ancho con la esquina superior redondeada es el
   mismo motivo que usan las secciones claras de la landing (rounded-t-[3rem]). */
.seccion-legal {
    display: block;
    background: #fff;
    border-radius: 3rem 3rem 0 0;
    margin-top: 40px;
}

/* Prosa del documento legal */
.contenido-legal {
    max-width: 820px;
    margin: 0 auto;
    padding: 56px 24px 72px;
    color: #333;
}

.contenido-legal p {
    line-height: 1.8;
    margin-bottom: 1.1rem;
}

.contenido-legal h2 {
    font-weight: 700;
    font-size: 1.15rem;
    line-height: 1.35;
    color: #2218a3;
    margin: 2.2rem 0 .9rem;
}

.contenido-legal h3 {
    font-weight: 700;
    font-size: 1rem;
    color: #2218a3;
    margin: 1.6rem 0 .7rem;
}

.contenido-legal ul,
.contenido-legal ol {
    margin: 0 0 1.1rem 1.5rem;
    padding-left: .5rem;
    line-height: 1.8;
}

.contenido-legal ul {
    list-style: disc;
}

.contenido-legal ol {
    list-style: decimal;
}

.contenido-legal li {
    margin-bottom: .5rem;
}

.contenido-legal strong {
    color: #2218a3;
}

.contenido-legal a {
    color: #2218a3;
    text-decoration: underline;
    overflow-wrap: anywhere;
}

.contenido-legal a:hover {
    color: #150e70;
}

/* ── Mapa (Leaflet) ───────────────────────────────────────────────────────── */
/* Leaflet necesita que su contenedor tenga alto propio: la caja de la maqueta lo
   da con h-96, y el mapa la llena. */
#map {
    width: 100%;
    height: 100%;
    background: #e3e5ea;
}

/* Si el CDN de Leaflet no responde, el hueco no queda vacio y sin explicacion:
   la direccion y el boton "Como llegar" siguen arriba, en la misma seccion. */
#map.mapa-sin-cargar::after {
    content: "No se pudo cargar el mapa. Usa el botón «Cómo llegar» de arriba.";
    display: flex;
    align-items: center;
    justify-content: center;
    height: 100%;
    padding: 24px;
    text-align: center;
    color: #4b5563;
    font-size: .95rem;
}

/* El globo del marcador hereda la tipografia de la pagina */
.leaflet-popup-content {
    font-size: .9rem;
    line-height: 1.5;
}

.leaflet-popup-content a {
    color: #2218a3;
    font-weight: 600;
}

/* Utilidades que el Tailwind purgado NO trae porque la maqueta no las usaba,
   o que nunca pudo generar: text-redy-green es una clase propia de la maqueta,
   asi que Tailwind jamas creo su variante hover (en la maqueta ese hover era
   letra muerta). */
.w-auto {
    width: auto;
}

.hover\:text-redy-green:hover {
    color: #00ff26;
}

/* El honeypot nunca se muestra ni se enfoca */
input[name="website"] {
    display: none !important;
}
