/* =========================================================================
   EL CAPTCHA DEL JUEGO: «tocá las tres sillas»
   =========================================================================

   La grilla es UNA sola imagen armada en el servidor, con nueve casillas de
   verdad (`input type="checkbox"`) puestas encima, cada una sobre el pedazo de
   imagen que le toca.

   Que sean casillas de verdad y no `div` manejados con JavaScript importa por
   tres motivos, y ninguno es de purista:

     - se resuelve con el teclado (tabulador y barra espaciadora);
     - el lector de pantalla las anuncia como «Dibujo 1», «Dibujo 2»…;
     - SI EL JAVASCRIPT NO CARGA, el formulario anda igual: se ven nueve
       casillas numeradas y se marcan a mano. Un CAPTCHA que rompe el registro
       cuando falla un script es peor que no tener CAPTCHA.
   ========================================================================= */

/*
 * (17/10) LA CAJA SE TIENE QUE VER COMO UN PASO, NO COMO UN ADORNO.
 *
 * Con el borde finito y el mismo fondo que la ficha, la grilla se leía como
 * una ilustración más de la página: la gente completaba usuario y contraseña
 * y se quedaba esperando. Ahora va con el borde grueso y un tinte del color
 * del juego; cuando está completa, el borde pasa a verde.
 */
.captcha {
    border: 2px solid var(--acento, #6a45d8);
    border-radius: var(--r-3, 14px);
    padding: var(--e-4, 16px);
    background: var(--acento-tinte, var(--sup-1, #fff));
    transition: border-color .2s, box-shadow .2s;
}

.captcha--completo { border-color: var(--verde, #1f8a4c); }

.captcha-cabeza {
    display: flex;
    gap: var(--e-3, 12px);
    align-items: baseline;
    justify-content: space-between;
    flex-wrap: wrap;
    margin-bottom: var(--e-3, 12px);
}

.captcha-consigna {
    margin: 0;
    font: 600 var(--t-4-size, 1.05rem)/1.3 var(--f-juego, inherit);
}

.captcha-otro,
.captcha-enlace {
    border: 0;
    background: none;
    padding: 0;
    color: var(--acento, #6a45d8);
    font: inherit;
    font-size: var(--t-2-size, .9rem);
    text-decoration: underline;
    text-underline-offset: 2px;
    cursor: pointer;
}

.captcha-otro:hover,
.captcha-enlace:hover { color: var(--carbon, #222); }

/* --- la grilla: la imagen de fondo y las casillas encima ----------------- */

/*
 * LA GRILLA SE MIDE POR EL ANCHO **Y POR EL ALTO** QUE HAYA.
 *
 * Eran 324 px fijos. En un celular acostado, con 390 px de pantalla, la grilla
 * sola se llevaba el 83 % del alto: quedaba la grilla y nada más, ni los
 * campos ni el botón de entrar.
 *
 * Con `aspect-ratio: 1`, limitar el ancho limita el alto, así que alcanza con
 * una sola cuenta: el menor entre los 324 de siempre, lo que haya de ancho, y
 * una parte de la pantalla.
 *
 * ==========================================================================
 *  POR QUÉ 46dvh NO ALCANZABA, Y AHORA SON 34
 * ==========================================================================
 *
 * Medido en el login de 1366 × 768: el 46 % de 768 son 353, o sea que el tope
 * no mordía y la grilla se quedaba con sus 324 px. Con eso el bloque del
 * captcha medía 425 y el formulario no entraba: el botón de entrar quedaba
 * abajo del borde de la pantalla y había que desplazarse para encontrarlo.
 *
 * Con 34dvh la grilla mide 261 en esa notebook y el formulario entero entra.
 * En una pantalla alta no cambia nada: el 34 % de 1080 son 367, así que sigue
 * mandando el tope de 324.
 *
 * `max(140px, …)` es el piso y no se toca: 140 divididos en tres casillas dan
 * 46 px por dibujo, apenas por encima de los 44 que pide un dedo. Antes que
 * achicar más, se prefiere que la página se desplace: un captcha que no se
 * puede tocar no es un captcha más chico, es una puerta cerrada.
 */
.captcha-grilla {
    position: relative;
    display: block;
    width: max(140px, min(324px, 100%, 34vh));
    width: max(140px, min(324px, 100%, 34dvh));
    max-width: 100%;
    aspect-ratio: 1;
    border-radius: var(--r-2, 10px);
    overflow: hidden;
}

.captcha-img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: contain;

    /* Los dibujos del juego son de píxeles: sin esto el navegador los suaviza
       y se ven borrosos, que es justo lo que hace dudar a una persona. */
    image-rendering: pixelated;

    /* Que no se pueda arrastrar ni seleccionar. No le impide nada a un
       programa; evita que alguien la arrastre sin querer al tocarla. */
    user-select: none;
    -webkit-user-drag: none;
}

/*
 * CADA CASILLA SOBRE SU PEDAZO DE LA IMAGEN.
 *
 * La posición sale del índice que le puso PHP (`--i`) y del lado de la grilla
 * (`--captcha-lado`). Se calcula con `mod()` y `round()` de CSS, que son
 * recientes; para los navegadores que no las tengan está la regla de más abajo
 * con `:nth-child()`, que hace lo mismo a mano para una grilla de 3 × 3.
 */
.captcha-casillero {
    position: absolute;
    margin: 0;
    cursor: pointer;
    width: calc(100% / var(--captcha-lado, 3));
    height: calc(100% / var(--captcha-lado, 3));
}

/* La cuenta a mano para 3 × 3. Va PRIMERO para que, donde `mod()` funcione,
   la regla de abajo la pise con el cálculo general. */
.captcha-grilla .captcha-casillero:nth-of-type(3n + 1) { left: 0; }
.captcha-grilla .captcha-casillero:nth-of-type(3n + 2) { left: 33.3333%; }
.captcha-grilla .captcha-casillero:nth-of-type(3n + 3) { left: 66.6666%; }

.captcha-grilla .captcha-casillero:nth-of-type(-n + 3) { top: 0; }
.captcha-grilla .captcha-casillero:nth-of-type(n + 4):nth-of-type(-n + 6) { top: 33.3333%; }
.captcha-grilla .captcha-casillero:nth-of-type(n + 7) { top: 66.6666%; }

@supports (left: calc(mod(2, 3) * 1%)) {
    .captcha-grilla .captcha-casillero {
        --paso: calc(100% / var(--captcha-lado, 3));
        left: calc(mod(var(--i), var(--captcha-lado, 3)) * var(--paso));
        top: calc(round(down, calc(var(--i) / var(--captcha-lado, 3)), 1) * var(--paso));
    }
}

.captcha-casillero input {
    position: absolute;
    opacity: 0;
    width: 100%;
    height: 100%;
    margin: 0;
    cursor: pointer;
}

.captcha-marca {
    position: absolute;
    inset: 3px;
    border-radius: var(--r-1, 6px);
    border: 3px solid transparent;
    transition: border-color .12s, background-color .12s;
    pointer-events: none;
}

.captcha-casillero input:hover + .captcha-marca {
    border-color: rgb(255 255 255 / .35);
}

/* Elegido: el color del juego y un tilde en la esquina. */
.captcha-casillero input:checked + .captcha-marca {
    border-color: var(--acento, #6a45d8);
    background: rgb(106 69 216 / .22);
}

.captcha-casillero input:checked + .captcha-marca::after {
    content: '';
    position: absolute;
    right: 5px;
    top: 5px;
    width: 20px;
    height: 20px;
    border-radius: 50%;
    background: var(--acento, #6a45d8)
        url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E")
        center / 13px no-repeat;
}

/* El foco del teclado TIENE que verse: es la única forma de resolverlo sin
   mouse, y sin esto no se sabe en qué casilla se está parado. */
.captcha-casillero input:focus-visible + .captcha-marca {
    border-color: #fff;
    box-shadow: 0 0 0 3px var(--acento, #6a45d8);
}

.captcha-ayuda {
    margin: var(--e-3, 12px) 0 0;
    font-size: var(--t-2-size, .85rem);
    color: var(--carbon-3, #777);
}

/* --- qué hay que hacer, y cuánto falta ---------------------------------- */

/*
 * LA EXPLICACIÓN VA ANTES DE LA GRILLA Y EL CONTADOR DESPUÉS.
 *
 * La gente pasaba la grilla de largo y apretaba «Entrar»: volvía con el
 * formulario vacío y un cartel arriba que no sabía a qué se refería. Ahora la
 * grilla se presenta como un paso («antes de entrar, marcá…»), el contador
 * dice cuántos faltan y el botón de enviar queda apagado hasta completarla.
 */
.captcha-explica {
    display: flex;
    align-items: center;
    gap: var(--e-2, 8px);
    margin: 0 0 var(--e-3, 12px);
    font-size: var(--t-2-size, .9rem);
    line-height: 1.3;
    color: var(--carbon-2, #444);
}

.captcha-explica strong { color: var(--carbon, #222); }

/* El número del paso: un círculo lleno, para que se lea antes que el texto. */
.captcha-paso {
    flex: 0 0 auto;
    display: grid;
    place-items: center;
    width: 26px;
    height: 26px;
    border-radius: 50%;
    background: var(--acento, #6a45d8);
    color: var(--sobre-acento, #fff);
    font: 700 .95rem/1 var(--f-juego, inherit);
}

.captcha--completo .captcha-paso { background: var(--verde, #1f8a4c); color: #fff; }

/*
 * EL LLAMADO: se completaron usuario y contraseña y la grilla sigue vacía.
 * Un halo que late despacio hasta que se marquen los dibujos. Es lo que hace
 * mirar a quien no lee: algo que se mueve justo donde tiene que tocar.
 */
.captcha--llama:not(.captcha--completo) {
    animation: captcha-llama 1.4s ease-in-out infinite;
}

@keyframes captcha-llama {
    0%, 100% { box-shadow: 0 0 0 0 rgb(255 138 61 / .0); }
    50%      { box-shadow: 0 0 0 6px rgb(255 138 61 / .45); }
}

.captcha-cuenta {
    margin: var(--e-2, 8px) 0 0;
    font-size: var(--t-2-size, .9rem);
    font-weight: 600;
    color: var(--carbon-2, #444);
}

/* `--verde` y no un verde fijo: el de siempre (#1f8a4c) casi no se leía sobre
   el fondo oscuro del tema de noche; `--verde` cambia con el tema. */
.captcha--completo .captcha-cuenta { color: var(--verde, #1f8a4c); }

/* Cuando se intenta mandar con la grilla a medias: un sacudón corto y el
   contador en rojo, para que se vea qué es lo que falta. */
.captcha--avisa {
    animation: captcha-sacudon .45s ease-in-out;
    border-color: var(--mal, #c62828);
}

.captcha--avisa .captcha-cuenta { color: var(--mal, #c62828); }

@keyframes captcha-sacudon {
    0%, 100% { transform: translateX(0); }
    20%, 60% { transform: translateX(-6px); }
    40%, 80% { transform: translateX(6px); }
}

@media (prefers-reduced-motion: reduce) {
    .captcha--avisa,
    .captcha--llama:not(.captcha--completo) { animation: none; box-shadow: 0 0 0 4px rgb(255 138 61 / .45); }
}

/*
 * El botón de enviar mientras la grilla está a medias: se ve a media luz y
 * DICE lo que falta («Falta tocar 3 dibujos»). Ya no es `disabled`: un botón
 * apagado no contesta cuando lo tocan, y eso era justo lo que dejaba a la
 * gente pensando. Ahora se puede tocar y lleva a la grilla (ver `captcha.js`).
 */
form button[type="submit"].btn-esperando-captcha,
form input[type="submit"].btn-esperando-captcha {
    opacity: .72;
    filter: saturate(.7);
}

/*
 * SIN JAVASCRIPT las casillas siguen andando —son casillas de verdad— pero se
 * las muestra debajo, numeradas y a la vista, porque superpuestas sin ayuda
 * visual cuesta saber cuál es cuál. Se resuelve igual: se mira la imagen y se
 * marcan los números.
 */
.no-js .captcha-casillero {
    position: static;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    width: auto;
    height: auto;
    margin: 4px 8px 0 0;
    padding: 6px 10px;
    border: 1px solid var(--filo, #ddd);
    border-radius: var(--r-1, 6px);
}

.no-js .captcha-grilla { aspect-ratio: auto; height: auto; overflow: visible; }
.no-js .captcha-casillero input { position: static; opacity: 1; width: auto; height: auto; }
.no-js .captcha-marca { display: none; }

.no-js .captcha-casillero .visualmente-oculto {
    position: static;
    width: auto;
    height: auto;
    clip: auto;
    margin: 0;
    overflow: visible;
}

@media (max-width: 400px) {
    .captcha-grilla { width: 100%; }
}

/*
 * «OTROS DIBUJOS» Y «PEDÍ OTROS DIBUJOS» TIENEN QUE PODER TOCARSE.
 *
 * Son enlaces de texto de 14 px de alto: con el mouse se aciertan, con el dedo
 * no. Y son la salida de emergencia de quien no distingue los dibujos, así que
 * errarles es quedarse encerrado en una grilla que no se entiende.
 *
 * Se agranda el área, no el dibujo: el subrayado se sigue viendo igual.
 */
@media (pointer: coarse) {
    .captcha-otro,
    .captcha-enlace {
        position: relative;
        display: inline-flex;
        align-items: center;
        min-height: var(--tocable, 44px);
        padding-inline: 2px;
    }
}
