/* Promoción Juan Valdez — herramienta de registro.
   Una sola pantalla, pensada para el celular: la mayoría llega desde un
   empaque o un anuncio, con el teléfono en la mano y la factura al lado. */

/* Paleta de Juan Valdez, tomada del CSS del sitio oficial (juanvaldez.com),
   no de memoria: café profundo con rojo de marca sobre crema cálido.
   La identidad NO es verde — ese es el logo antiguo de Café de Colombia, que
   es otra cosa. Las cuatro combinaciones que se usan pasan el mínimo de
   contraste de 4,5:1. */
:root {
    --promo: #3F1017;        /* café profundo — 15,1:1 sobre el crema */
    --promo-acento: #D50121; /* rojo de marca — 5,1:1 sobre el crema */
    --tinta: #231F20;
    --crema: #FFF5F2;
    --gris: #6B6B72;
    --borde: #E8DCD8;
    --carbon: #1A1616;       /* el fondo mientras carga la foto, para que no haya destello blanco */
    --ok: #1B7A47;           /* verde de "vas bien" — 5,0:1 sobre blanco */
    --error: #B2212D;        /* rojo de error, distinto del rojo de marca para no confundir con el botón */
}
* { box-sizing: border-box; }
body {
    margin: 0;
    background: var(--carbon);
    color: var(--tinta);
    font-family: 'Fira Sans', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
    -webkit-font-smoothing: antialiased;
}

.promo-shell {
    min-height: 100vh;
    display: grid;
    align-content: start;
    justify-items: center;
    padding: clamp(1.5rem, 6vw, 3.5rem) 1rem clamp(2rem, 6vw, 4rem);
}

/* El fondo va en un ::before fijo al viewport y no en el shell: en celular el
   formulario mide tres pantallas de alto y un `cover` sobre esa altura estira
   la foto hasta que no se reconoce. Fijo al viewport la composición se ve
   siempre igual. `background-attachment: fixed` haría lo mismo en una línea
   pero en iOS se dibuja con el tamaño equivocado. */
body::before {
    content: '';
    position: fixed;
    inset: 0;
    z-index: -1;
    /* El velo es café oscuro y no negro: sobre el verde del cafetal un negro
       neutro lo apaga a gris, el café lo lleva hacia el tostado de la marca. */
    background-image:
        linear-gradient(180deg, rgba(34, 17, 12, .74) 0%, rgba(26, 14, 11, .84) 100%),
        var(--promo-fondo);
    background-size: cover;
    background-position: center;
}
.promo-aside,
.promo-main { width: 100%; max-width: 560px; }
/* En celular las dos columnas se apilan: la de marca va centrada y separada de
   la tarjeta, que arranca justo debajo. */
.promo-aside { text-align: center; margin-bottom: clamp(1.4rem, 5vw, 2rem); }
.promo-card {
    width: 100%;
    background: #fff;
    border: 1px solid var(--borde);
    border-top: 4px solid var(--promo-acento);
    border-radius: 4px;
    padding: clamp(1.5rem, 5vw, 2.75rem);
    box-shadow: 0 24px 70px rgba(0, 0, 0, .38);
}
/* El logotipo se pinta en blanco sobre el fondo oscuro: es la versión que la
   marca usa sobre fondo oscuro, y el filtro da el mismo resultado ya sea que
   el archivo cargado venga en rojo o ya en blanco. */
.promo-logo {
    display: block;
    max-width: clamp(150px, 40vw, 210px);
    height: auto;
    margin: 0 auto;
    filter: brightness(0) invert(1) drop-shadow(0 2px 10px rgba(0, 0, 0, .45));
}
/* El titular de la pieza es el premio, arriba y sobre la foto. Esto de acá es
   solo el rótulo de la tarjeta: si compite en tamaño, vuelven a ser dos
   titulares peleando y el premio pierde. */
.promo-title { font-size: 1.05rem; font-weight: 700; line-height: 1.3; margin: 0 0 .25rem; text-align: center; color: var(--promo); }
.promo-intro { color: var(--gris); line-height: 1.55; margin: 0 0 1.6rem; text-align: center; font-size: .9rem; }
.promo-empty { color: #B23; text-align: center; }

/* El formulario lo arma el módulo Forms con clases de Bootstrap; el tema no
   toca ese markup, solo lo reviste desde acá. */
.promo-form .form-label { font-size: .82rem; font-weight: 600; color: var(--tinta); margin-bottom: .35rem; }
.promo-form .form-control,
.promo-form .form-select {
    border-radius: 3px;
    border: 1px solid var(--borde);
    background: #FDFAF9;
    /* 16px evita que iOS haga zoom al enfocar el campo, que en un formulario
       de celular desplaza toda la pantalla y se siente roto. */
    font-size: 16px;
    padding: .7rem .85rem;
    transition: border-color .2s ease, box-shadow .2s ease, background-color .2s ease;
}
.promo-form .form-control:focus,
.promo-form .form-select:focus {
    background: #fff;
    border-color: var(--promo);
    box-shadow: 0 0 0 3px rgba(63, 16, 23, .14);
}
.promo-form input[type="file"] { padding: .55rem .6rem; }
.promo-form .form-check-label { font-size: .9rem; line-height: 1.45; color: var(--gris); }
.promo-form .text-danger { color: var(--promo) !important; }

.promo-form .btn-primary {
    --bs-btn-bg: var(--promo-acento);
    --bs-btn-border-color: var(--promo-acento);
    --bs-btn-hover-bg: #A80119;
    --bs-btn-hover-border-color: #A80119;
    --bs-btn-active-bg: #A80119;
    --bs-btn-focus-shadow-rgb: 213, 1, 33;
    --bs-btn-border-radius: 3px;
    --bs-btn-padding-y: .8rem;
    --bs-btn-font-weight: 700;
    width: 100%;
}
.promo-form .alert { border-radius: 3px; }
.promo-form .form-errors:empty { display: none; }

/* Términos y condiciones. Van arriba del formulario y con peso de enlace de
   verdad, no de nota al pie: es lo que el checkbox de abajo le pide aceptar, así
   que tiene que poder leerlos antes de llegar ahí. */
.promo-terms {
    margin: 0 0 1.5rem;
    padding: .7rem .9rem;
    background: var(--crema);
    border: 1px solid var(--borde);
    border-radius: 3px;
    font-size: .9rem;
    text-align: center;
}
.promo-terms a {
    color: var(--promo);
    font-weight: 600;
    text-decoration: none;
    display: inline-flex;
    align-items: center;
    gap: .4rem;
}
.promo-terms a:hover { color: var(--promo-acento); text-decoration: underline; }
/* El icono de "abre en otra pestaña" avisa que no se pierde lo ya escrito. */
.promo-terms__ext { font-size: .75em; opacity: .7; }
.promo-terms--missing { color: #B23; background: #FDF1F1; border-color: #F3C9C9; font-weight: 600; }

/* ---- Bloque de campaña: premio, sorteo y pasos ----
   Todo esto vive sobre el fondo oscuro, fuera de la tarjeta. La tarjeta queda
   solo para el formulario: mezclar promesa y captura en la misma caja es lo que
   hace que una promo se lea como planilla. */
.promo-premio {
    margin: clamp(1rem, 3vw, 1.4rem) 0 0;
    font-size: clamp(1.5rem, 6.5vw, 2.4rem);
    font-weight: 700;
    line-height: 1.12;
    letter-spacing: -.015em;
    color: #fff;
    text-shadow: 0 2px 14px rgba(0, 0, 0, .5);
}
.promo-sorteo {
    margin: .7rem 0 0;
    display: inline-block;
    padding: .38rem .9rem;
    border-radius: 999px;
    background: var(--promo-acento);
    color: #fff;
    font-size: .84rem;
    font-weight: 600;
    letter-spacing: .01em;
}
.promo-premio__foto {
    display: block;
    width: 100%;
    max-width: 380px;
    height: auto;
    margin: clamp(1rem, 3vw, 1.5rem) auto 0;
    border-radius: 6px;
}

.promo-pasos {
    /* `max-content` + `margin auto` centra la lista como bloque sin tocar la
       alineación de cada paso: los números tienen que seguir formando una
       columna recta, y con `text-align: center` cada uno quedaría en su
       propio sitio. */
    width: max-content;
    max-width: 100%;
    margin: clamp(1.4rem, 4vw, 2rem) auto clamp(1rem, 3vw, 1.5rem);
    padding: 0;
    list-style: none;
    display: grid;
    gap: .55rem;
}
.promo-paso {
    display: flex;
    align-items: center;
    gap: .75rem;
    color: rgba(255, 255, 255, .92);
    font-size: .93rem;
    line-height: 1.35;
    text-align: left;
}
.promo-paso__num {
    flex: 0 0 auto;
    width: 1.8rem;
    height: 1.8rem;
    display: grid;
    place-items: center;
    border-radius: 50%;
    border: 1.5px solid rgba(255, 255, 255, .45);
    font-size: .8rem;
    font-weight: 700;
}
/* El último paso es el resultado ("Listo, ya estás participando"), no una
   instrucción: se marca en rojo de marca para cerrar la secuencia. */
.promo-paso:last-child .promo-paso__num {
    background: var(--promo-acento);
    border-color: var(--promo-acento);
}

.promo-aviso {
    width: 100%;
    margin: 1.1rem auto 0;
    max-width: max-content;
    display: flex;
    align-items: flex-start;
    gap: .55rem;
    font-size: .84rem;
    line-height: 1.45;
    color: rgba(255, 255, 255, .8);
    text-align: left;
}
.promo-aviso .bi { color: var(--promo-acento); font-size: 1rem; line-height: 1.3; }

/* El módulo Forms pone un avioncito de papel en el submit, que es el ícono de
   "enviar un mensaje". Acá no se manda un mensaje, se entra a un sorteo: el
   ícono contradice al texto del botón. Se oculta desde el tema en vez de
   forkear el partial completo del formulario. */
.promo-form .btn-primary .bi-send { display: none; }

/* ---- Validación en vivo ----
   Bootstrap ya trae .is-valid / .is-invalid con el borde y el ícono; acá solo
   se ajustan al verde y rojo del tema y se estiliza el mensaje propio. */
.promo-form .form-control.is-valid,
.promo-form .form-select.is-valid { border-color: var(--ok); }
.promo-form .form-control.is-valid:focus,
.promo-form .form-select.is-valid:focus { box-shadow: 0 0 0 3px rgba(27, 122, 71, .16); }
.promo-form .form-control.is-invalid,
.promo-form .form-select.is-invalid { border-color: var(--error); }
.promo-form .form-control.is-invalid:focus,
.promo-form .form-select.is-invalid:focus { box-shadow: 0 0 0 3px rgba(178, 33, 45, .16); }
.promo-form .form-check-input.is-valid { background-color: var(--ok); border-color: var(--ok); }
.promo-form .form-check-input.is-valid ~ .form-check-label { color: var(--gris); }
.promo-form .form-check-input.is-invalid { border-color: var(--error); }
.promo-form .form-check-input.is-invalid ~ .form-check-label { color: var(--error); }

.promo-msg {
    margin: .35rem 0 0;
    font-size: .82rem;
    line-height: 1.4;
    color: var(--error);
}
.promo-msg[hidden] { display: none; }

.promo-pendiente {
    margin: .6rem 0 0;
    font-size: .84rem;
    text-align: center;
    color: var(--gris);
}
.promo-pendiente[hidden] { display: none; }

/* El botón deshabilitado se ve apagado pero no invisible: tiene que seguir
   leyéndose como el destino del formulario, no como un elemento roto. */
.promo-form .btn-primary:disabled {
    --bs-btn-disabled-bg: #C9BDB9;
    --bs-btn-disabled-border-color: #C9BDB9;
    --bs-btn-disabled-color: #fff;
    --bs-btn-disabled-opacity: 1;
    cursor: not-allowed;
}


/* El CTA de la columna de marca. Es un enlace y no un botón: en celular lleva
   al formulario que quedó más abajo, y sin JS esa es toda la función. */
.promo-cta {
    display: inline-block;
    padding: .8rem 1.6rem;
    border-radius: 3px;
    background: var(--promo-acento);
    color: #fff;
    font-weight: 700;
    text-decoration: none;
    margin-top: .5rem;
    transition: background-color .2s ease, transform .2s ease;
}
.promo-cta:hover,
.promo-cta:focus-visible { background: #A80119; color: #fff; transform: translateY(-1px); }

/* ---- Escritorio: dos columnas ----
   El formulario a la izquierda porque es la tarea; la marca a la derecha,
   fija, porque acompaña y no compite. Recién a 992px: por debajo las dos
   columnas dejarían el formulario en una tira demasiado angosta. */
@media (min-width: 992px) {
    .promo-shell {
        max-width: 1240px;
        margin-inline: auto;
        /* El formulario se lleva algo más de ancho que la columna de marca:
           son campos de texto y una laptop de 1280 con las dos columnas
           iguales los deja innecesariamente apretados. */
        grid-template-columns: minmax(0, 1.08fr) minmax(0, .92fr);
        column-gap: clamp(2.5rem, 4.5vw, 4rem);
        align-items: start;
        justify-items: stretch;
    }
    .promo-main  { order: 1; max-width: none; }
    .promo-aside {
        order: 2;
        max-width: none;
        /* El formulario es más alto que la columna de marca: sin `sticky` el
           premio y los pasos desaparecen apenas empieza a llenar. */
        position: sticky;
        top: clamp(1.5rem, 4vw, 3rem);
        margin-bottom: 0;
    }
    .promo-logo { max-width: 210px; }
    .promo-premio { font-size: clamp(1.8rem, 2.6vw, 2.4rem); }
    .promo-cta { margin-top: 1.5rem; }
}

/* Estado de promoción cerrada. Ocupa el lugar del formulario dentro de la
   misma tarjeta: la marca y el premio siguen arriba, que es lo que explica qué
   fue lo que cerró. */
.promo-cerrada {
    text-align: center;
    padding: clamp(1.5rem, 5vw, 2.5rem) 0 clamp(.5rem, 2vw, 1rem);
}
.promo-cerrada .bi {
    font-size: 2.4rem;
    color: var(--promo-acento);
    opacity: .85;
}
.promo-cerrada__txt {
    margin: 1rem 0 0;
    font-size: 1.05rem;
    line-height: 1.5;
    color: var(--tinta);
}

/* Página 404. Reusa la tarjeta del formulario porque es la misma pieza: no hay
   otra pantalla a la que volver, así que el 404 es un desvío corto de regreso. */
.promo-card--404 { text-align: center; padding-top: clamp(2rem, 6vw, 3rem); padding-bottom: clamp(2rem, 6vw, 3rem); }
.promo-404__codigo {
    margin: 0;
    font-size: clamp(3rem, 9vw, 4.5rem);
    font-weight: 800;
    line-height: 1;
    letter-spacing: -.04em;
    color: var(--borde);
}
.promo-404__titulo { margin: .5rem 0 .75rem; font-size: clamp(1.25rem, 4vw, 1.6rem); font-weight: 700; color: var(--promo); }
.promo-404__txt { margin: 0 0 1.5rem; color: var(--gris); line-height: 1.6; font-size: .97rem; }
