/* ==========================================================================
   [Sacado de freefrontend]
   dot_background.css — fondo de puntos de colores que parpadean, detrás del
   recuadro de contenido. Solo en Aims, Coordination y Who we are: son las
   únicas páginas que cargan este fichero.

   Cómo funciona: dos capas fijas, una encima de otra.
   1. body::before: los puntos, QUIETOS. Un degradado de colores con una máscara
      de rejilla de puntos redondos (radial-gradient): solo se ve el degradado en los puntos.
   2. body::after: una "tapa" del color del fondo, con agujeros en forma de manchas
      de ruido (un SVG generado aquí mismo, sin ficheros externos). Tapa unos puntos y deja ver otros.
   - La animación desliza la tapa: van encendiéndose y apagándose puntos distintos.

   Por qué dos capas (y no una con la máscara animada, como el original):
   - Animar mask-position obliga a repintar toda la pantalla en cada fotograma (medido: varios núcleos de CPU).
   - La tapa se mueve con transform, que el navegador hace en la tarjeta gráfica sin repintar nada.

   Colores: los de la imagen de la cabecera (page-header-bg.webp).
   - Oscuro: fondo negro, puntos en los tonos de la imagen.
   - Claro: fondo claro, los mismos tonos más oscuros (si no, apenas se ven).
   ========================================================================== */

/* --------------------------------------------------------------------------
   Variables por tema
   -------------------------------------------------------------------------- */
:root,
:root[data-theme="light"] {
  --dots-bg: var(--bg-primary);   /* el mismo fondo claro de siempre */
  /* Saturados, para que "brillen" en azul y verde como en la cabecera (con tonos apagados se veían grises) */
  --dots-blue: #1a7fd6;
  --dots-cyan: #00a3e0;
  --dots-orange: #e8891c;
  --dots-green: #4caf2a;
  --dots-opacity: 1;
}

:root[data-theme="dark"] {
  --dots-bg: #000000;
  --dots-blue: #2f6fc4;
  --dots-cyan: #4a9be0;
  --dots-orange: #d9893a;
  --dots-green: #8cc63f;
  --dots-sky: #8ccaf7;   /* azul cielo pálido: el de los puntos más brillantes de la cabecera (solo en oscuro) */
  --dots-opacity: 0.6;   /* mismos colores, pero más apagados: al 100 % brillaban demasiado sobre el negro */
}

/* --------------------------------------------------------------------------
   Fondo de la página: sustituye al --bg-primary de style.css
   -------------------------------------------------------------------------- */
body {
  background-color: var(--dots-bg);
}

/* --------------------------------------------------------------------------
   Recuadro de contenido (main.content) algo transparente: deja asomar los puntos
   - Solo el fondo, no "opacity": opacity volvería transparente también el texto.
   - color-mix: el mismo --bg-secondary de style.css (blanco / azul pizarra según el tema),
     al 85 % y el resto transparente.
   -------------------------------------------------------------------------- */
main.content {
  background-color: color-mix(in srgb, var(--bg-secondary) 85%, transparent);
}

/* --------------------------------------------------------------------------
   Capa 1: los puntos (quietos)
   -------------------------------------------------------------------------- */
body::before {
  --dot-size: 20px;   /* separación entre puntos */

  content: "";
  position: fixed;     /* cubre la ventana y se queda quieta al hacer scroll */
  inset: 0;
  z-index: -1;         /* detrás de todo el contenido */
  pointer-events: none;   /* no "tapa" clics */
  opacity: var(--dots-opacity);

  /* Los colores: un degradado en círculo con los tonos de la imagen.
     - Sobre todo azul, cian y verde, como en la cabecera.
     - El naranja, solo en una franja estrecha (290-330deg): un toque, como los pocos puntos naranjas de la imagen.
     - Empieza y acaba en el mismo color para que no haya corte. */
  background: conic-gradient(
    from 180deg at 50% 70%,
    var(--dots-cyan) 0deg,
    var(--dots-green) 90deg,
    var(--dots-blue) 180deg,
    var(--dots-cyan) 290deg,
    var(--dots-orange) 310deg,
    var(--dots-cyan) 330deg,
    var(--dots-cyan) 1turn
  );

  /* Máscara: rejilla de puntos, un círculo de 2px en cada casilla de --dot-size */
  mask: radial-gradient(circle at 50% 50%, white 2px, transparent 2.5px) 50% 50% / var(--dot-size) var(--dot-size);
}

/* Modo oscuro: otro reparto de colores (el claro no cambia).
   - Verde: solo una franja (250-290deg), en vez de ocupar medio círculo.
   - Azul cielo (--dots-sky): nuevo, ocupa lo que deja el verde.
   - Orden de los colores invertido respecto al claro (cada ángulo X pasa a 360-X): el verde queda a la derecha y el naranja a la izquierda.
   - Gana a la regla de arriba porque el selector es más específico (:root[data-theme="dark"] delante). */
:root[data-theme="dark"] body::before {
  background: conic-gradient(
    from 180deg at 50% 70%,
    var(--dots-cyan) 0deg,
    var(--dots-cyan) 30deg,
    var(--dots-orange) 50deg,
    var(--dots-cyan) 70deg,
    var(--dots-blue) 180deg,
    var(--dots-sky) 230deg,
    var(--dots-green) 270deg,
    var(--dots-sky) 310deg,
    var(--dots-cyan) 1turn
  );
}

/* --------------------------------------------------------------------------
   Capa 2: la tapa con agujeros de ruido (la que se mueve)
   -------------------------------------------------------------------------- */
body::after {
  content: "";
  position: fixed;
  top: 0;
  bottom: 0;
  left: -256px;                 /* empieza un mosaico (256px) a la izquierda de la ventana... */
  width: calc(100% + 256px);    /* ...y es un mosaico más ancha: al deslizarse 256px nunca deja un hueco */
  z-index: -1;                  /* = body::before, pero va después en la página: queda encima de los puntos */
  pointer-events: none;
  background-color: var(--dots-bg);   /* mismo color que el fondo: donde tapa, no se nota */

  /* Máscara de ruido (mosaico de 256px):
     - feTurbulence genera manchas.
       baseFrequency regula su tamaño: 0.06 = manchas de ~1 punto (los puntos se encienden sueltos, al azar).
       Con 0.02 eran manchas grandes: se encendían grupos de puntos juntos y se veía el bloque deslizarse.
     - feColorMatrix las invierte y las contrasta (alfa = 3.6 - 6·ruido): la tapa es opaca donde
       el ruido es bajo (tapa los puntos) y transparente donde es alto (deja verlos).
     - El 3.6 regula cuántos puntos se ven: donde el ruido pasa de ~0.6.
       Más alto = menos puntos visibles (probado 4.2, de ~0.7: demasiado tapados).
     - stitchTiles: el mosaico encaja consigo mismo sin costuras. */
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='256' height='256'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.06' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -6 3.6'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E") 0 0 / 256px 256px;

  will-change: transform;       /* avisa al navegador: la pone en su propia capa de la tarjeta gráfica */
  /* 256px en 30s: más rápido = parpadeo más vivo; más lento = más tranquilo.
     - Con manchas pequeñas (baseFrequency 0.06) cada punto se enciende y apaga más a menudo:
       hace falta ir más lento que con manchas grandes para que no parezca acelerado.
     steps(900): 900 saltos en 30s = 30 por segundo (en vez de 60). En los fotogramas en que la tapa
     no se ha movido, el navegador no redibuja: menos gasto.
     - Si se cambia la duración, cambiar también los saltos (segundos × 30) para seguir a 30 fps. */
  animation: dots-flicker 30s infinite steps(900);
}

/* Desliza la tapa 256px (un mosaico entero) a la derecha: al volver a empezar, el ruido
   está en la misma posición que al principio y no se nota el salto */
@keyframes dots-flicker {
  to {
    transform: translateX(256px);
  }
}

/* Quien tiene pedido en su sistema "reducir movimiento": tapa quieta (puntos quietos) */
@media (prefers-reduced-motion: reduce) {
  body::after {
    animation: none;
  }
}
