/* Base visual del sitio: la tipografia, el reset de caja y el fondo animado
 * de estrellas con sus animaciones.
 *
 * Estas nueve reglas estaban copiadas palabra por palabra en styles.css y en
 * home.css, las dos hojas de pagina, que nunca se cargan juntas. Son ~140
 * lineas y las mueve el mismo background_motion.js en las dieciseis paginas,
 * asi que tener dos copias solo servia para que se desviaran.
 *
 * ORDEN: esta hoja tiene que cargarse ANTES que la de cada pagina. No es
 * cosmetico: `body::after` de las hojas de pagina redefine `inset`, que la
 * regla compartida `body::before, body::after` tambien fija. Si esta fuera la
 * ultima ganaria ella y la capa de estrellas se descolocaria en todo el sitio.
 * Por eso se enlaza desde head_base.html, al principio del <head>, y no desde
 * pwa_head.html, que va al final.
 */

/* Nunito Sans, desde septiembre de 2026. Antes el sitio iba en Ubuntu.
 *
 * Los nombres de fichero llevan el peso REAL (300 y 600) porque los anteriores
 * mentian: `ubuntu.woff2` se declaraba `normal` y era la Light, y
 * `ubuntu-medium.woff2` se declaraba `700` y era la Medium. Aqui el fichero
 * dice lo que es y la declaracion dice el hueco que ocupa.
 *
 * Se declara el 300 como `normal` y el 600 como `700` para no tener que tocar
 * los 33 sitios del CSS que piden peso. El reparto que hace el navegador:
 *   400, 500   -> la de 300
 *   600 a 800  -> la de 600
 *
 * Sin hinting a proposito: son mas de la mitad del peso del fichero, Android
 * no los usa, y en Windows el texto de las tarjetas se pinta en escala de
 * grises (el giro 3D de la tarjeta impide el ClearType), donde tampoco ayudan.
 * Las dos caras juntas son 29 KB; las dos de Ubuntu eran 84 KB.
 *
 * OJO con las metricas, que NO son las de Ubuntu:
 *   caja de linea   Ubuntu 1,149 em   Nunito 1,364 em   (+19%)
 *   altura de x     Ubuntu 517        Nunito 485        (-6%)
 * Donde el CSS fija `line-height` no cambia nada, pero donde no lo fija
 * —los titulos de la portada— la linea crece. Si se toca el tamano de algun
 * titulo, comprobar la portada en un movil de 375x812, que va justa de alto.
 *
 * `optional` y no `swap`: con `swap` el navegador pinta en la del sistema y
 * RECOMPONE al llegar la nuestra, y eso es el salto que se veia. Con
 * `optional` o llega a tiempo para el primer pintado o esa carga se queda en
 * la del sistema, pero no recompone nunca. Con el preload de head_base.html y
 * las dos caras en el precache del service worker, llega a tiempo salvo en la
 * primera visita con la cache vacia. Si algun dia se prefiere garantizar
 * siempre esta tipografia, la alternativa es `block`, que deja el texto
 * invisible hasta que llegue en vez de usar la del sistema. */
@font-face {
    font-family: 'Nunito Sans';
    src: url("../fonts/nunito-sans-300.17d4dc28b36f.woff2") format('woff2');
    font-weight: normal;
    font-style: normal;
    font-display: optional;
}

@font-face {
    font-family: 'Nunito Sans';
    src: url("../fonts/nunito-sans-600.a186d5b3db67.woff2") format('woff2');
    font-weight: 700;
    font-style: normal;
    font-display: optional;
}

*, *::before, *::after {
    box-sizing: inherit;
}

/* El destello azul que pintan los navegadores de Android al tocar cualquier
 * cosa pulsable. Se apagaba caso por caso en news.css —la tarjeta y el modo
 * lectura— y seguia saliendo en todo lo demas: botones, enlaces, pestanas,
 * el menu de la cabecera. Se declara aqui, en la hoja comun, porque la
 * propiedad se HEREDA: basta con ponerla en la raiz para todo el documento.
 *
 * No toca la seleccion de texto (eso es ::selection) ni el foco de teclado
 * (:focus-visible se sigue pintando): solo quita el rectangulo del toque. */
html {
    -webkit-tap-highlight-color: transparent;
}

html::before {
    content: '';
    position: fixed;
    inset: 0;
    pointer-events: none;
    z-index: -2;
    background:
        radial-gradient(circle at 12% 18%, rgba(255, 255, 255, 0.78) 0 1px, transparent 2px),
        radial-gradient(circle at 26% 64%, rgba(207, 229, 255, 0.64) 0 1px, transparent 2px),
        radial-gradient(circle at 44% 36%, rgba(255, 255, 255, 0.72) 0 1px, transparent 2px),
        radial-gradient(circle at 58% 82%, rgba(210, 181, 255, 0.62) 0 1px, transparent 2px),
        radial-gradient(circle at 76% 28%, rgba(255, 255, 255, 0.7) 0 1px, transparent 2px),
        radial-gradient(circle at 88% 72%, rgba(194, 222, 255, 0.58) 0 1px, transparent 2px);
    background-size: 340px 340px, 460px 460px, 620px 620px, 760px 760px, 980px 980px, 1240px 1240px;
    opacity: 0.46;
    will-change: transform, opacity;
    /* starDrift va y vuelve (alternate): con `linear infinite` el campo de
       estrellas saltaba de golpe del final al principio en cada ciclo. */
    animation: starDrift 80s ease-in-out infinite alternate, starTwinkleSlow 18s ease-in-out infinite alternate;
}

html::after {
    content: '';
    position: fixed;
    top: 12%;
    left: 78%;
    width: 180px;
    height: 2px;
    pointer-events: none;
    z-index: -1;
    opacity: 0;
    transform: rotate(-24deg) translate3d(0, 0, 0);
    transform-origin: right center;
    background: linear-gradient(90deg, rgba(255, 255, 255, 0), rgba(210, 232, 255, 0.98) 55%, rgba(255, 255, 255, 0.1));
    filter: drop-shadow(0 0 8px rgba(181, 214, 255, 0.86));
    animation: shootingStar 19s linear infinite;
}

body::before,
body::after {
    content: '';
    position: fixed;
    inset: 0;
    pointer-events: none;
    z-index: -1;
}

html.background-motion-paused::before,
html.background-motion-paused::after,
html.background-motion-paused body::before,
html.background-motion-paused body::after {
    animation-play-state: paused !important;
}

@keyframes starTwinkleSlow {
    from {
        opacity: 0.34;
    }
    to {
        opacity: 0.58;
    }
}

@keyframes starDrift {
    from {
        transform: translate3d(-2%, -1%, 0) scale(1.02);
    }
    to {
        transform: translate3d(2%, 1%, 0) scale(1.02);
    }
}

@keyframes shootingStar {
    0% {
        opacity: 0;
        transform: rotate(-24deg) translate3d(0, 0, 0) scaleX(0.35);
    }
    78% {
        opacity: 0;
        transform: rotate(-24deg) translate3d(0, 0, 0) scaleX(0.35);
    }
    80% {
        opacity: 0.95;
        transform: rotate(-24deg) translate3d(-8px, 6px, 0) scaleX(1);
    }
    84% {
        opacity: 0.9;
        transform: rotate(-24deg) translate3d(-300px, 190px, 0) scaleX(1);
    }
    88% {
        opacity: 0;
        transform: rotate(-24deg) translate3d(-520px, 330px, 0) scaleX(0.75);
    }
    100% {
        opacity: 0;
        transform: rotate(-24deg) translate3d(-520px, 330px, 0) scaleX(0.75);
    }
}

/* Modo rendimiento: en pantallas pequenas o con reduced-motion se apagan las
 * cuatro capas del fondo. Estaba repetido igual en las dos hojas de pagina, que
 * conservan lo suyo dentro de la misma media query (el fondo plano de cada una).
 * Aqui el orden no importa porque va todo con !important. */
@media (max-width: 900px), (prefers-reduced-motion: reduce) {
    html::before,
    html::after,
    body::before,
    body::after {
        content: none !important;
        animation: none !important;
        filter: none !important;
    }
}

/* Tooltips. Uno solo para todo el sitio, el mismo que tenían los botones de la
 * cabecera. Antes el resto de botones usaba el `title` nativo, que tarda un
 * segundo en salir, no se ve con el teclado y lo pinta cada sistema a su
 * manera. js/tooltips.js pasa cada `title` a `data-tip` (también los que se
 * ponen después desde JS) y esto lo dibuja.
 *
 * Sale por ENCIMA por defecto; la cabecera lo baja (header.css) y los botones
 * flotantes, que van pegados al borde derecho, lo sacan a su izquierda.
 * `:where` deja el `position: relative` sin especificidad: cualquier regla que
 * fije la posición del elemento (los botones flotantes son `fixed`) le gana. */
:where([data-tip]) {
    position: relative;
}

[data-tip]::after {
    content: attr(data-tip);
    position: absolute;
    bottom: calc(100% + 8px);
    left: 50%;
    transform: translate(-50%, 4px);
    padding: 5px 9px;
    border-radius: var(--radius-xs, 6px);
    background: rgba(11, 20, 44, 0.94);
    border: 1px solid rgba(198, 214, 242, 0.2);
    box-shadow: var(--shadow-sm);
    color: #f2f5fb;
    font-size: 12.5px;
    font-weight: 500;
    font-style: normal;
    letter-spacing: normal;
    text-transform: none;
    line-height: 1.2;
    white-space: nowrap;
    text-shadow: none;
    pointer-events: none;
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.15s ease, transform 0.15s ease, visibility 0.15s;
    z-index: 1100;
}

/* Solo con puntero fino: en táctil el primer toque ya activa el botón y la
 * etiqueta se quedaría colgada encima. Con teclado sale siempre. */
@media (hover: hover) and (pointer: fine) {
    [data-tip]:hover::after {
        opacity: 1;
        visibility: visible;
        transform: translate(-50%, 0);
    }
}

[data-tip]:focus-visible::after {
    opacity: 1;
    visibility: visible;
    transform: translate(-50%, 0);
}

/* Botones flotantes: pegados al borde derecho, la etiqueta va a su izquierda. */
:is(.fab-stack, .news-actions-menu) [data-tip]::after,
:is(.update-feed-btn, .undo-btn, .order-btn, .reader-btn, .book-scroll-top-btn)[data-tip]::after {
    bottom: auto;
    left: auto;
    top: 50%;
    right: calc(100% + 10px);
    transform: translate(4px, -50%);
}

@media (hover: hover) and (pointer: fine) {
    :is(.fab-stack, .news-actions-menu) [data-tip]:hover::after,
    :is(.update-feed-btn, .undo-btn, .order-btn, .reader-btn, .book-scroll-top-btn)[data-tip]:hover::after {
        transform: translate(0, -50%);
    }
}

:is(.fab-stack, .news-actions-menu) [data-tip]:focus-visible::after,
:is(.update-feed-btn, .undo-btn, .order-btn, .reader-btn, .book-scroll-top-btn)[data-tip]:focus-visible::after {
    transform: translate(0, -50%);
}


/* Mínimos de tamaño de letra (ver --text-* en tokens.css). `<small>` sin regla
 * propia hereda `smaller` de su padre y en las fichas de Música bajaba a 10,7 px. */
small {
    font-size: max(var(--text-xs, 0.75rem), 0.8em);
}

/* En móvil, los campos a 16 px como mínimo: con menos, iOS amplía la página al
 * enfocarlos y hay que deshacer el zoom a mano. Las casillas no llevan texto. */
@media (max-width: 767px) {
    input:not([type="checkbox"]):not([type="radio"]):not([type="range"]),
    select,
    textarea {
        font-size: max(var(--text-base, 1rem), 1em);
    }
}
