/* Kirava · efecto holográfico
   ------------------------------------------------------------------------
   Las cartas holo tienen que parecer holo. Es el detalle que hace que la gente
   comparta capturas, y eso es publicidad gratis.

   Técnica: --mx/--my son la posición normalizada del puntero (0..1) y las pone
   el JS dentro de requestAnimationFrame, nunca en el propio evento de ratón.
   Aquí solo se componen capas con mix-blend-mode y gradientes cuya posición
   depende de esas dos variables.

   El acabado depende de printings.holo_style: no es lo mismo un holo cósmico de
   1999 que un full art moderno. */

@layer components {

/* Espectro base compartido por todos los acabados. */
:root {
  --spectrum: repeating-linear-gradient(
    var(--holo-angle, 108deg),
    hsl(  2 100% 73%)  0%,
    hsl( 53 100% 69%)  8%,
    hsl( 93 100% 69%) 16%,
    hsl(176 100% 76%) 24%,
    hsl(228 100% 74%) 32%,
    hsl(283 100% 73%) 40%,
    hsl(  2 100% 73%) 48%
  );
}

.holo,
.glare {
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  opacity: 0;
  transition: opacity var(--dur) var(--ease-out);
  will-change: opacity, background-position;
}

/* El brillo direccional: un foco que sigue al puntero. Es lo que da la
   sensación de que hay una fuente de luz real sobre la carta.

   Contenido a propósito: la ilustración se tiene que seguir leyendo. Un holo
   que tapa la carta no parece una carta holográfica, parece un filtro. */
.glare {
  background: radial-gradient(
    circle at calc(var(--mx, .5) * 100%) calc(var(--my, .5) * 100%),
    rgb(255 255 255 / .26) 0%,
    rgb(255 255 255 / .07) 24%,
    rgb(0 0 0 / .20) 64%,
    rgb(0 0 0 / .32) 100%
  );
  mix-blend-mode: overlay;
}

/* UNA HOLO TIENE QUE VERSE HOLO SIN TOCAR NADA.
   ------------------------------------------------------------------------
   Hasta ahora el foil solo aparecía al pasar el ratón por encima, y en reposo
   una holo y una normal de la misma carta eran EXACTAMENTE la misma imagen.
   Dos fichas idénticas, una etiquetada «Holo» y otra «1.ª edición»: la
   diferencia estaba escrita pero no se veía, y distinguirlas de un vistazo es
   justo para lo que sirve esta web.

   Así que en reposo se enciende un foil. Contenido: con doscientas cartas en
   pantalla, un arcoíris a plena potencia en cada una convierte la rejilla en un
   puesto de feria y deja de leerse ninguna. El que hace el trabajo de verdad a
   tamaño de miniatura es el halo de aquí abajo; esto es el relleno. */
[data-holo]:not([data-holo="none"]) .holo { opacity: var(--holo-rest, .30); }

/* EL HALO: lo único que se distingue a 146 PÍXELES.
   ------------------------------------------------------------------------
   El foil de arriba y el canto de abajo van DENTRO de la carta, y dentro de la
   carta ya hay un borde amarillo enorme impreso en cada Pokémon desde 1996.
   A tamaño de rejilla el efecto se mete debajo de ese amarillo y desaparece:
   una holo y una normal salían idénticas en la cuadrícula aunque de cerca se
   distinguieran perfectamente.

   La solución es salirse de la carta. Fuera está el papel crema de la página,
   donde no compite con nada, y ahí un resplandor irisado se ve a la primera
   ojeada y a cualquier tamaño. Ninguna carta normal tiene color alrededor: es
   una señal que no admite confusión.

   Son cuatro focos de colores tirados en cuatro direcciones distintas, no un
   resplandor de un solo color. Un aro naranja parecería «seleccionada» o
   «destacada»; lo que hace legible una holo es que el color CAMBIA según por
   dónde la mires, y cuatro tonos repartidos dan esa lectura estando quietos.

   Cuesta cero por fotograma: una sombra se pinta una vez y se queda. */
.hit[data-holo]:not([data-holo="none"]) .card,
.sc-item[data-holo]:not([data-holo="none"]) .card,
.slot[data-holo]:not([data-holo="none"]) .sleeve {
  --aura:
    0 0 0 1px            hsl(190 100% 62% / .50),
    -5px -4px 13px -4px  hsl(322 100% 62% / .75),
     5px -4px 13px -4px  hsl(186 100% 55% / .72),
     0    6px 15px -4px  hsl( 48 100% 56% / .68),
     0    0   24px -7px  hsl(268 100% 66% / .60);
}

/* EL CANTO IRISADO: lo que delata una holo de lejos.
   ------------------------------------------------------------------------
   El foil por sí solo tiñe la ilustración y a tamaño de miniatura se confunde
   con que la carta sea de color. Lo que de verdad distingue una holo en la
   mano es el BORDE: el laminado coge la luz por el canto y devuelve un arco
   iris fino que ninguna carta normal tiene.

   Es una sombra interior de dos colores y cuesta lo mismo que cualquier borde:
   nada. Y funciona a cualquier tamaño, que es la gracia — a 146 píxeles el
   foil apenas se aprecia y este canto sí. */
[data-holo]:not([data-holo="none"]) .card-face,
[data-holo]:not([data-holo="none"]) .holo {
  --canto: inset 0 0 0 1px rgb(255 255 255 / .62),
           inset 0 2px 6px -1px hsl(190 100% 78% / .45),
           inset 0 -2px 6px -1px hsl(330 100% 78% / .38),
           inset 0 0 14px 2px hsl( 45 100% 70% / .18);
}
[data-holo]:not([data-holo="none"]) .card::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  z-index: 3;
  box-shadow: var(--canto);
  pointer-events: none;
}

/* UNA BANDA DE ARCO IRIS, NO UN BRILLO BLANCO.
   ------------------------------------------------------------------------
   El primer intento fue una banda de luz blanca y no servía: el foil de abajo
   usa `color-dodge`, que sobre una carta clara —y las de la era Wizards son
   casi todas amarillas— no irisa, BLANQUEA. Salía una carta con niebla, no una
   carta holográfica.

   El segundo intento sí llevaba colores pero colgaba de `.holo`, que en reposo
   está al 38 % de opacidad: las dos opacidades se multiplican y la banda se
   quedaba en un 15 % — invisible. Por eso cuelga de `.card`, que va a opacidad
   plena, y así el color que se escribe es el color que se ve.

   Se funde con `overlay`: oscurece lo claro y aclara lo oscuro, o sea que se
   ve tanto sobre el marco amarillo como sobre la ilustración morada. Es el
   mismo efecto que hace reconocible a una holo al girarla bajo una lámpara.

   Y no está quieta: la pasea el barrido de aquí abajo. */
[data-holo]:not([data-holo="none"]) .card::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  z-index: 2;
  background: linear-gradient(
    104deg,
    rgb(255 255 255 / 0)      30%,
    hsl(320 100% 70% / .34)   38%,
    hsl( 45 100% 66% / .46)   44%,
    hsl(150 100% 66% / .40)   50%,
    hsl(200 100% 70% / .38)   56%,
    hsl(275 100% 72% / .30)   62%,
    rgb(255 255 255 / 0)      70%
  );
  /* La banda es más ancha que la carta para que le quede recorrido: así el
     barrido de abajo la puede pasear de lado a lado en vez de estirarla. */
  background-size: 260% 100%;
  background-position: 60% 0;
  background-repeat: no-repeat;
  mix-blend-mode: overlay;
  pointer-events: none;
  transition: opacity var(--dur) var(--ease-out);
}

/* EL BARRIDO.
   ------------------------------------------------------------------------
   Lo que delata una holo en la vida real no es que tenga colores: es que los
   colores SE MUEVEN al girarla. Quieta, hasta una holo de verdad fotografiada
   parece una carta normal impresa en papel brillante. Por eso la banda pasea.

   Muy lenta (nueve segundos) y desfasada por posición: si las doscientas
   barrieran a la vez la rejilla parpadearía como un cartel de neón. Con seis
   desfases distintos lo que se ve es un brillo que recorre la cuadrícula, que
   es exactamente lo que hace una caja de cartas bajo un fluorescente.

   El coste: solo cambia `background-position` de UNA capa, y el navegador solo
   repinta lo que hay en pantalla, no las doscientas. Aun así se apaga entero
   con el interruptor de efectos de la cabecera y con reduced-motion, que están
   más abajo. */
@media (prefers-reduced-motion: no-preference) {
  [data-holo]:not([data-holo="none"]) .card::after {
    animation: holo-barrido 9s linear infinite;
  }
  .hit:nth-child(6n + 2) .card::after { animation-delay: -1.5s; }
  .hit:nth-child(6n + 3) .card::after { animation-delay: -3s;   }
  .hit:nth-child(6n + 4) .card::after { animation-delay: -4.5s; }
  .hit:nth-child(6n + 5) .card::after { animation-delay: -6s;   }
  .hit:nth-child(6n)     .card::after { animation-delay: -7.5s; }
}

@keyframes holo-barrido {
  0%   { background-position: 100% 0; }
  100% { background-position:   0% 0; }
}

/* Al pasar el puntero la banda estorba: ahí manda el foil que sigue al ratón. */
/* En la rejilla, al pasar el puntero la banda fija estorba: ahí manda el foil
   que sigue al ratón. */
[data-holo]:hover .card::after,
[data-holo]:focus-visible .card::after { opacity: 0; }

/* EN LA CARTA AMPLIADA, EL FOIL SIGUE AL RATÓN.
   ------------------------------------------------------------------------
   Aquí no hay banda fija: hay un halo dorado pegado al puntero, como la luz de
   una lámpara sobre el laminado, y un arco iris debajo que se desplaza con él.
   Es el momento en que alguien está mirando UNA carta de cerca, así que se
   puede gastar en efecto lo que en una rejilla de doscientas sería ruido.

   Va con `overlay` y no con `color-dodge` por lo mismo que la banda de la
   rejilla: sobre una carta clara el dodge blanquea en vez de irisar, y media
   colección son cartas claras.

   Y la carta NORMAL no entra aquí: se inclina igual, coge luz igual, pero sin
   una gota de color. Esa es toda la gracia — que la diferencia se note en el
   gesto y no solo en la etiqueta. */
.card-big[data-holo]:not([data-holo="none"]) .card::after {
  opacity: 1;
  background:
    radial-gradient(
      circle at calc(var(--mx, .5) * 100%) calc(var(--my, .5) * 100%),
      hsl(48 100% 72% / .70)  0%,
      hsl(38 100% 66% / .34) 18%,
      hsl(48 100% 72% / 0)   42%
    ),
    linear-gradient(
      calc(100deg + (var(--mx, .5) - .5) * 44deg),
      rgb(255 255 255 / 0)      18%,
      hsl(320 100% 70% / .34)   30%,
      hsl( 45 100% 66% / .42)   40%,
      hsl(150 100% 66% / .36)   50%,
      hsl(200 100% 70% / .36)   60%,
      hsl(275 100% 72% / .28)   70%,
      rgb(255 255 255 / 0)      82%
    );
  background-size: 100% 100%, 220% 220%;
  background-position:
    0 0,
    calc(var(--mx, .5) * 100%) calc(var(--my, .5) * 100%);
  mix-blend-mode: overlay;
  transition: none;   /* sigue al puntero: una transición lo dejaría a rastras */
}

/* Y aquí no barre nada: en la ampliada el foil lo mueve el ratón, y un barrido
   automático por encima iría a su aire, contra el gesto de quien la mira. */
.card-big .card::after { animation: none; }

/* La normal: sin foil y sin banda. Solo la luz y el movimiento. */
.card-big[data-holo="none"] .card::after { opacity: 0; }

/* Al pasar el puntero, el halo sube: la carta se levanta seis píxeles y el
   color de alrededor se abre con ella. */
.hit[data-holo]:not([data-holo="none"]):hover .card {
  --aura:
    0 0 0 1.5px           hsl(190 100% 66% / .70),
    -8px -6px 20px -5px   hsl(322 100% 62% / .95),
     8px -6px 20px -5px   hsl(186 100% 55% / .92),
     0   10px 24px -5px   hsl( 48 100% 56% / .88),
     0    0   36px -8px   hsl(268 100% 66% / .78);
}

/* Y al pasar por encima, a plena potencia. */
[data-holo]:hover .holo,
[data-holo]:focus-visible .holo,
.card-big .holo   { opacity: var(--holo-op, .55); }

[data-holo]:hover .glare,
[data-holo]:focus-visible .glare,
.card-big .glare  { opacity: 1; }

/* Sin acabado holográfico, NADA de foil.
   ------------------------------------------------------------------------
   Aquí está la otra mitad de la idea: la carta normal también se mueve y
   también coge luz —es una carta, refleja— pero no lleva ni un destello de
   color. La diferencia con la holo tiene que notarse en el gesto, no solo en
   la etiqueta. */
[data-holo="none"] .holo { display: none; }
[data-holo="none"] .glare { opacity: 0; }
[data-holo="none"]:hover .glare { opacity: .28; }
/* En la ampliada, un reflejo de luz limpio: se mueve, brilla y no tiñe. */
.card-big[data-holo="none"] .glare {
  opacity: .5;
  background: radial-gradient(
    circle at calc(var(--mx, .5) * 100%) calc(var(--my, .5) * 100%),
    rgb(255 255 255 / .34) 0%,
    rgb(255 255 255 / .06) 30%,
    rgb(0 0 0 / .16) 70%,
    rgb(0 0 0 / .26) 100%
  );
}

/* En la carta ampliada el foil sube: es UNA carta, ocupa media pantalla y es
   el momento en que alguien está mirándola de verdad. Aquí sí conviene que se
   note tanto como en la mano. */
.card-big[data-holo]:not([data-holo="none"]) { --holo-rest: .42; }
.card-big[data-holo]:not([data-holo="none"]) .holo { opacity: var(--holo-op, .55); }

/* --- cosmos: el foil de estrellas de la era WOTC (1999-2003) ------------ */

[data-holo="cosmos"] .holo {
  --holo-op: .30;
  background-image:
    radial-gradient(circle at 30% 30%, rgb(255 255 255 / .95) 0, rgb(255 255 255 / 0) 1.4px),
    radial-gradient(circle at 72% 64%, rgb(190 225 255 / .85) 0, rgb(255 255 255 / 0) 1.1px),
    radial-gradient(circle at 48% 86%, rgb(255 240 200 / .8) 0, rgb(255 255 255 / 0) 1.7px),
    var(--spectrum);
  background-size: 34px 34px, 47px 47px, 63px 63px, 220% 220%;
  background-position:
    calc(var(--mx, .5) * -26px) calc(var(--my, .5) * -26px),
    calc(var(--mx, .5) * -44px) calc(var(--my, .5) * -44px),
    calc(var(--mx, .5) * -62px) calc(var(--my, .5) * -62px),
    calc(var(--mx, .5) * 100%)  calc(var(--my, .5) * 100%);
  background-blend-mode: screen, screen, screen, normal;
  mix-blend-mode: color-dodge;
  filter: saturate(.85) contrast(1.1);
}

/* --- linear: bandas rectas. Reverse holo y holos de los 2000 ------------ */

[data-holo="linear"] .holo {
  --holo-op: .26;
  /* En reposo un pelo más que las demás: la reverse lleva el foil en TODA la
     superficie menos la ilustración, así que en la vida real es la que más
     brilla de lejos. */
  --holo-rest: .24;
  background-image:
    repeating-linear-gradient(
      100deg,
      rgb(255 255 255 / 0)    0px,
      rgb(255 255 255 / .30)  2px,
      rgb(255 255 255 / 0)    5px,
      rgb(255 255 255 / 0)   11px
    ),
    var(--spectrum);
  background-size: 100% 100%, 240% 240%;
  background-position:
    calc(var(--mx, .5) * 40px) 0,
    calc(var(--mx, .5) * 100%) calc(var(--my, .5) * 100%);
  mix-blend-mode: color-dodge;
  filter: saturate(.8);
}

/* --- textured: tramado fino de los holos modernos ---------------------- */

[data-holo="textured"] .holo {
  --holo-op: .28;
  --holo-angle: 125deg;
  background-image:
    repeating-linear-gradient( 45deg, rgb(255 255 255 / .14) 0 1px, rgb(255 255 255 / 0) 1px 4px),
    repeating-linear-gradient(-45deg, rgb(255 255 255 / .10) 0 1px, rgb(255 255 255 / 0) 1px 5px),
    var(--spectrum);
  background-size: 100% 100%, 100% 100%, 190% 190%;
  background-position:
    0 0, 0 0,
    calc(var(--mx, .5) * 100%) calc(var(--my, .5) * 100%);
  mix-blend-mode: color-dodge;
  filter: saturate(.9) contrast(1.05);
}

/* --- fullart: barrido amplio y saturado de las raras modernas ---------- */

[data-holo="fullart"] .holo {
  --holo-op: .40;
  --holo-angle: 118deg;
  background-image:
    linear-gradient(
      calc(var(--holo-angle) + 40deg),
      rgb(255 255 255 / 0)   30%,
      rgb(255 255 255 / .34) 48%,
      rgb(255 255 255 / 0)   66%
    ),
    var(--spectrum);
  background-size: 260% 260%, 170% 170%;
  background-position:
    calc(var(--mx, .5) * 100%) calc(var(--my, .5) * 100%),
    calc((1 - var(--mx, .5)) * 100%) calc(var(--my, .5) * 100%);
  mix-blend-mode: color-dodge;
  filter: saturate(1.05) contrast(1.08);
}

/* --- Apagado -----------------------------------------------------------
   Dos vías: prefers-reduced-motion (obligatorio) y el interruptor manual de
   la cabecera, para equipos lentos. */

@media (prefers-reduced-motion: reduce) {
  .holo, .glare { display: none !important; }
  .flip { transform: none !important; }
  .sleeve { transform: none !important; }
}

:root[data-fx="off"] .holo,
:root[data-fx="off"] .glare { display: none; }
:root[data-fx="off"] .flip { --rx: 0deg; --ry: 0deg; }

/* Con los efectos apagados se para el barrido, pero el halo se queda: no
   cuesta un fotograma y es lo que distingue una holo de una normal. Apagarlo
   no sería ahorrar, sería perder el dato. */
:root[data-fx="off"] .card::after { animation: none; }

}
