/* =============================================================================
   te.publico.css — LA MARCA de las páginas que se ven SIN ENTRAR (Pages/Shared/_LayoutPublico.cshtml)
   =============================================================================

   José, 24/10/2026, viendo la página de la factura por QR hecha aparte: «Y LA IMAGEN CORPORATIVA, Y TODO LO
   NUESTRO? Y NUESTROS LOGOS?» y, al proponerle copiar el login en ella, «que si mañana tenemos otra haces otra
   nueva? [...] que no aprovechas?». Las seis páginas públicas se montaban de CUATRO maneras: el login con su marca
   en styleLoginNuevo.css, tres sueltas con su <style> (confirmar el correo, la baja de los informes programados y la
   factura) y dos con el _LayoutLogin de la v19. Ahora la marca vive AQUÍ y la pone el layout:

       .pbFondo     las dos columnas: la marca a la izquierda, lo de la página a la derecha
       .pbMarca     el panel de marca: el logo de la M, la malla que respira y el pie «Servicio operativo»
       .pbPanel     el lado de la página: el sol/luna arriba y la caja (.pbCaja) con lo suyo

   Y las piezas que repite cualquier página pública, las del login: el título y su subtítulo, el campo con su icono,
   el botón principal, el aviso de error o de bien y el mensaje grande del panel de marca (.pbClaim).

   Todo el color sale de te.tokens.css, así que el claro y el oscuro salen solos. Lo que sólo es de una página va
   en la suya (styleLoginNuevo.css, te.factura.css...).
   ============================================================================= */

/* Sin el margen del navegador: con él, los 100dvh de abajo se pasaban 16 px y salía la barra de desplazamiento. */
.pbCuerpo { margin: 0; }

.pbFondo {
    position: relative;
    min-height: 100dvh;
    display: grid;
    grid-template-columns: 1.15fr 1fr;
    background: var(--te-fondo);
    color: var(--te-texto);
    font-family: var(--te-tipo);
    overflow: hidden;
}

/* ---------------------------------------------------------------- la marca */

.pbMarca {
    position: relative;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    padding: 3.5rem;
    overflow: hidden;
    background: var(--pb-degradado);
}

/* El degradado de la marca, UNA vez: en el ordenador lo lleva el panel de marca; en el móvil, el fondo entero. */
.pbFondo {
    --pb-degradado:
        radial-gradient(1200px 800px at 15% 20%, var(--te-acento-suave), transparent 60%),
        radial-gradient(900px 700px at 80% 90%, var(--te-acento-foco), transparent 55%),
        var(--te-superficie);
}

/* La malla de fondo: puro CSS, sin imagen ni libreria. Dos gradientes repetidos
   que dibujan una cuadricula y se desvanecen hacia el centro. */
.pbMalla {
    position: absolute;
    inset: -2px;
    background-image:
        linear-gradient(var(--te-borde) 1px, transparent 1px),
        linear-gradient(90deg, var(--te-borde) 1px, transparent 1px);
    background-size: 44px 44px;
    -webkit-mask-image: radial-gradient(circle at 30% 40%, #000 0%, transparent 70%);
    mask-image: radial-gradient(circle at 30% 40%, #000 0%, transparent 70%);
    opacity: .55;
    pointer-events: none;
}

.pbMarcaTop { position: relative; z-index: 1; }

.pbLogo { width: min(320px, 60%); height: auto; display: block; }

/* El mensaje grande del panel de marca: las noticias del login, o lo que diga cada página. El contenido de las
   noticias es HTML del editor de SoporteGTE, ya saneado (h1 p br strong em mark a ul ol li). `mark` es «el trozo
   resaltado»: en el título va en su propia línea y en el acento; en el texto, en su sitio. */
.pbClaim {
    position: relative;
    z-index: 1;
    /* ⚠️ EN REM, NO EN CH. El `ch` se mide con la letra de ESTE contenedor -1rem-,
       no con la del titular, que es tres veces mayor: 15ch daban 120 px y el titular
       se partia en cuatro lineas en vez de dos. Aqui hace falta ancho de verdad. */
    max-width: 27rem;
}
.pbClaim h1 {
    margin: 0 0 .6rem;
    font-size: clamp(1.9rem, 2.7vw, 2.8rem);
    line-height: 1.08;
    text-wrap: balance;
    letter-spacing: -.02em;
    font-weight: 650;
}
.pbClaim mark { background: none; color: var(--te-acento-vivo); }
.pbClaim h1 mark { display: block; }
.pbClaim strong { font-weight: 650; color: var(--te-texto); }
.pbClaim p {
    margin: 0;
    max-width: 30ch;
    color: var(--te-texto-suave);
    font-size: 1.02rem;
    line-height: 1.5;
}
.pbClaim p + p, .pbClaim ul, .pbClaim ol { margin-top: .6rem; }
.pbClaim ul, .pbClaim ol { margin-bottom: 0; padding-left: 1.2rem; max-width: 34ch; color: var(--te-texto-suave); line-height: 1.5; }
.pbClaim a { color: var(--te-acento-vivo); }

.pbPie {
    position: relative;
    z-index: 1;
    display: flex;
    gap: 1.5rem;
    align-items: center;
    color: var(--te-texto-legal);
    font-size: .82rem;
}
.pbPie a { color: inherit; text-decoration: none; }
.pbPie a:hover { color: var(--te-acento-vivo); }

/* El punto de estado del servicio. Nada de dato de negocio aqui: solo si
   responde o no, que es lo unico que se puede ensenar antes de entrar. */
.pbEstado { display: inline-flex; align-items: center; gap: .45rem; }

.pbPunto {
    width: 8px; height: 8px; border-radius: 50%;
    background: var(--te-ok);
    box-shadow: 0 0 0 0 var(--te-ok);
    animation: pbLatido 2.4s ease-out .8s infinite;   /* retrasado para no competir con la entrada */
}

@keyframes pbLatido {
    0%   { box-shadow: 0 0 0 0 rgba(111,191,139,.45); }
    70%  { box-shadow: 0 0 0 7px rgba(111,191,139,0); }
    100% { box-shadow: 0 0 0 0 rgba(111,191,139,0); }
}

/* ---------------------------------------------------------- lo de la página */

.pbPanel {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    padding: 2rem;
    position: relative;
}

.pbBarra {
    position: absolute;
    top: 1.2rem; right: 1.4rem;
    display: flex; gap: .4rem;
}

.pbCaja { width: min(380px, 100%); }

.pbTitulo { margin: 0 0 .35rem; font-size: 1.6rem; font-weight: 600; letter-spacing: -.01em; }
.pbSubtitulo { margin: 0 0 2rem; color: var(--te-texto-suave); font-size: .95rem; }

/* El texto de la página y su nota al pie, más pequeña. Lo que se resalta dentro (el nombre de un informe), en fuerte. */
.pbTexto { margin: 0 0 1rem; color: var(--te-texto-suave); font-size: .95rem; line-height: 1.5; }
.pbTexto strong { color: var(--te-texto); font-weight: 600; }
.pbNota { margin: 1.2rem 0 0; color: var(--te-texto-legal); font-size: .82rem; line-height: 1.5; }
.pbTitulo + :is(.pbError, .pbBien, .pbTexto) { margin-top: 1.2rem; }
:is(.pbTexto, .pbNota)[hidden] { display: none; }

/* El campo: con su icono dentro, a la izquierda; sin icono, el texto empieza en el borde. */
.pbCampo { position: relative; margin-bottom: .8rem; }

.pbCampo :is(input, select) {
    width: 100%;
    padding: .95rem 1rem .95rem 2.8rem;
    border: 1px solid var(--te-borde);
    border-radius: 11px;
    background: var(--te-superficie);
    color: var(--te-texto);
    font: inherit;
    transition: border-color .15s ease, box-shadow .15s ease;
}
.pbCampo:not(:has(.pbIcoCampo)) :is(input, select) { padding-left: 1rem; }
.pbCampo input::placeholder { color: var(--te-texto-legal); }
.pbCampo :is(input, select):focus {
    outline: none;
    border-color: var(--te-acento);
    box-shadow: 0 0 0 4px var(--te-acento-foco);
}
.pbCampo input[readonly] { color: var(--te-texto-suave); }

.pbCampo .pbIcoCampo {
    position: absolute; left: .95rem; top: 50%; transform: translateY(-50%);
    width: var(--te-tam-icono); height: var(--te-tam-icono); color: var(--te-texto-legal); pointer-events: none;
}

/* El botón principal: la acción de la página. */
.pbBoton {
    width: 100%;
    display: inline-flex; align-items: center; justify-content: center; gap: .5rem;
    padding: .95rem;
    border: 0; border-radius: 11px;
    background: var(--te-acento);
    color: var(--te-sobre-acento);
    font: inherit; font-weight: 600;
    text-decoration: none;
    cursor: pointer;
    transition: background .15s ease, transform .12s ease;
}
.pbBoton:hover:not(:disabled) { background: var(--te-acento-vivo); transform: translateY(-1px); }
.pbBoton:disabled { opacity: .55; cursor: default; }

/* El aviso: de error, o de que salió bien. Vacío no ocupa. */
.pbError, .pbBien {
    border-radius: 10px;
    padding: .7rem .9rem;
    font-size: .88rem;
    margin-bottom: 1rem;
}
.pbError { background: var(--te-error-fondo); border: 1px solid var(--te-error); color: var(--te-error); }
.pbBien { background: var(--te-ok-fondo); border: 1px solid var(--te-ok); color: var(--te-ok); }
:is(.pbError, .pbBien):empty { display: none; }

/* --------------------------------------------------------------- el móvil */

/* En el móvil la marca no desaparece: el logo y el sol/luna van arriba, y el degradado y la malla BAJAN por toda la
   página, por detrás de lo suyo (José, 24/10/2026: «que el degradado de la izquierda bajara sobre los elementos»). El
   mensaje grande y el pie se van, y manda lo de la página.
   Cómo: el panel de marca y el de la página se quedan sin posición propia, así que la malla (absoluta) y el sol/luna se
   colocan sobre el fondo entero; la caja va encima de la malla. */
@media (max-width: 900px) {
    .pbFondo { grid-template-columns: 1fr; grid-template-rows: auto 1fr; background: var(--pb-degradado); }
    .pbMarca { position: static; padding: 1.1rem 1.5rem 0; background: none; }
    .pbMarca > :not(.pbMalla):not(.pbMarcaTop) { display: none; }
    .pbLogo { width: 150px; }
    .pbPanel { position: static; padding: 1.5rem; justify-content: flex-start; }
    .pbBarra { top: 1.4rem; right: 1.2rem; z-index: 2; }
    .pbCaja { position: relative; z-index: 1; width: min(400px, 100%); margin-top: .5rem; }
}

/* =============================================================================
   MOVIMIENTO

   Tres cosas y ni una mas, con un criterio: una pantalla publica se ve varias
   veces al dia, asi que lo que se mueva tiene que pasar DESAPERCIBIDO a la tercera.
   Todo entra una sola vez, salvo el latido del fondo -que es lentisimo a proposito-.
   Y todo se apaga con prefers-reduced-motion.
   ============================================================================= */

/* La entrada escalonada: cada pieza sube 10 px y aparece, con 70 ms de diferencia. No es decoracion:
   ordena la mirada -logo, mensaje, y por ultimo donde hay que actuar-. */
@keyframes pbEntra {
    from { opacity: 0; transform: translateY(10px); }
    to   { opacity: 1; transform: none; }
}

.pbMarcaTop, .pbClaim, .pbPie, .pbTitulo, .pbSubtitulo, .pbCampo, .pbBoton {
    animation: pbEntra .5s cubic-bezier(.22, .61, .36, 1) backwards;
}

.pbMarcaTop  { animation-delay: .05s; }
.pbClaim     { animation-delay: .14s; }
.pbPie       { animation-delay: .30s; }
.pbTitulo    { animation-delay: .10s; }
.pbSubtitulo { animation-delay: .15s; }
.pbCampo:nth-of-type(1) { animation-delay: .34s; }
.pbCampo:nth-of-type(2) { animation-delay: .38s; }
.pbCampo:nth-of-type(3) { animation-delay: .42s; }
.pbBoton     { animation-delay: .50s; }

/* El fondo respira: 28 segundos por ciclo, a esa velocidad no se ve moverse, solo se nota que la pantalla no esta
   muerta. Se mueve la MASCARA de la malla, no la malla: mover un fondo repetido obliga a repintar todo el panel. */
.pbMalla {
    animation: pbRespira 28s ease-in-out infinite alternate;
    will-change: mask-position;
}
@keyframes pbRespira {
    from { -webkit-mask-position: 0 0;   mask-position: 0 0; }
    to   { -webkit-mask-position: 4% 3%; mask-position: 4% 3%; }
}

@media (prefers-reduced-motion: reduce) {
    .pbMarcaTop, .pbClaim, .pbPie, .pbTitulo, .pbSubtitulo, .pbCampo, .pbBoton, .pbMalla, .pbPunto { animation: none; }
    .pbBoton:hover:not(:disabled) { transform: none; }
}
