/* Tokens semánticos compartidos home + PDP.
   data-theme se setea en <html> via inline script (pre-paint) y App useEffect.
   Para Next.js: este archivo se traslada tal cual a app/globals.css. */

:root {
  /* Full dark mode (2026-07: la web es dark-only; se retiró el light mode).
     color-scheme:dark evita el flash blanco del canvas inicial del browser
     en sistemas configurados en claro. */
  color-scheme: dark;
  --bg-base:     #0A0A0C; /* superficie raíz home */
  --bg-elevated: #070709; /* superficie elevada PDP */
  --fg-toggle:   #F5F0E6;
}

/* Tipografía oficial Epicodes Venezuela: Switzer (display + body) + IBM Plex Mono (mono). */
:root {
  --font-display: 'Switzer', -apple-system, system-ui, sans-serif;
  --font-body:    'Switzer', -apple-system, system-ui, sans-serif;
  --font-mono:    'IBM Plex Mono', ui-monospace, 'SF Mono', Menlo, monospace;
}

/* Transición suave del bg/color cuando cambia data-theme (fallback si no hay
   View Transitions API). React JSX inline backgrounds no transicionan, pero el
   bg base + scrollbars + chrome del nav sí, lo cual ayuda a que no flashee. */
html, body {
  transition: background-color .35s cubic-bezier(0.22, 1, 0.36, 1),
              color .35s cubic-bezier(0.22, 1, 0.36, 1);
}

/* View Transitions API — Chromium: morph entre temas con crossfade global.
   Override del default 250ms para que sea más rápido y elegante. */
::view-transition-old(root),
::view-transition-new(root) {
  animation-duration: 320ms;
  animation-timing-function: cubic-bezier(0.22, 1, 0.36, 1);
}

/* Skeleton shimmer */
@keyframes evz-shimmer {
  0%   { background-position: -200% center; }
  100% { background-position:  200% center; }
}
.evz-skeleton {
  background-image: linear-gradient(
    90deg,
    rgba(255,255,255,0.00) 0%,
    rgba(255,255,255,0.06) 50%,
    rgba(255,255,255,0.00) 100%
  );
  background-size: 200% 100%;
  animation: evz-shimmer 1.4s ease-in-out infinite;
}

/* PS Plus en el paso 2 del checkout: la fila aparece un instante después de
   cargar, y el botón hace UN barrido. Ninguna de las dos loopea a propósito —
   al lado del CTA de "Confirmar pedido", algo que se mueve para siempre le
   compite, y a los pocos segundos el ojo lo lee como publicidad.

   ⚠ evz-plus-in se usa con `backwards` y NO con `both`. Se ven igual cuando
   todo sale bien, pero fallan distinto: con `both` el estado final lo fija la
   animación, así que si no llega a terminar la fila queda en opacity:0 —
   invisible y encima ocupando lugar. Con `backwards`, si no corre, la fila
   aparece sin animar. En un checkout, "sale sin efecto" es aceptable; "no
   sale" es una venta perdida.
   Anima solo opacity y transform: no dispara layout, así que nada se corre. */
@keyframes evz-plus-in {
  from { opacity: 0; transform: translateY(-10px); }
  to   { opacity: 1; transform: none; }
}
@keyframes evz-plus-sweep {
  0%        { transform: translateX(-130%); }
  48%, 100% { transform: translateX(130%); }
}

/* Feedback al agregar el PS Plus al pedido. Tres piezas que corren juntas y se
   apagan: la fila destella en verde, el botón hace un pop, y el TOTAL late.
   El total es la que importa — lo que el cliente quiere confirmar al tocar
   "agregar" es cuánto va a pagar ahora, no que el botón se movió. */
/* Termina en 0 y no en un verde tenue: la fila no tiene fondo propio, así que
   cualquier resto queda pegado para siempre. Arranca fuerte para que el
   destello se vea sobre el fondo oscuro de la card. */
@keyframes evz-plus-added {
  0%   { background: rgba(34,197,94,.45); }
  55%  { background: rgba(34,197,94,.20); }
  100% { background: rgba(34,197,94,0);   }
}
@keyframes evz-plus-pop {
  0%   { transform: scale(1); }
  38%  { transform: scale(.93); }
  100% { transform: scale(1); }
}
@keyframes evz-total-bump {
  0%   { transform: scale(1);    }
  35%  { transform: scale(1.13); }
  100% { transform: scale(1);    }
}

/* Pop-in para popovers (AccountSoonButton, etc.) */
@keyframes evz-pop-in {
  from { opacity: 0; transform: translateY(-4px) scale(0.97); }
  to   { opacity: 1; transform: translateY(0)    scale(1); }
}

/* Toast minimal — fade in/out (AccountSoonButton "Próximamente") */
@keyframes evz-toast-in {
  from { opacity: 0; transform: translateY(-3px); }
  to   { opacity: 1; transform: translateY(0); }
}
@keyframes evz-toast-out {
  to { opacity: 0; transform: translateY(-3px); }
}

/* ── Tile destacada (GTA VI): backlight tipo "aurora" — 4 manchas de color
   (violeta / rosa / amarillo / naranja del gradiente del juego) alrededor de
   la tile AL MISMO TIEMPO, orbitando de forma irregular (no un aro uniforme).
   box-shadow no lo clipa el overflow de la propia tile; z-index la levanta
   sobre las vecinas. */
@keyframes evz-featured-glow {
  0% {
    box-shadow:
      -2px -8px 14px 0 #B14BF4cc,
      8px -1px 13px 0 #FF2D88cc,
      3px 8px 15px 0 #FFC92Eaa,
      -7px 3px 13px 0 #FF7A2Eaa;
  }
  20% {
    box-shadow:
      5px -6px 13px 0 #B14BF4cc,
      7px 5px 15px 0 #FF2D88cc,
      -5px 7px 12px 0 #FFC92Eaa,
      -6px -4px 14px 0 #FF7A2Eaa;
  }
  45% {
    box-shadow:
      7px 3px 15px 0 #B14BF4cc,
      -2px 7px 12px 0 #FF2D88cc,
      -8px -2px 14px 0 #FFC92Eaa,
      4px -7px 13px 0 #FF7A2Eaa;
  }
  70% {
    box-shadow:
      1px 8px 13px 0 #B14BF4cc,
      -7px 2px 15px 0 #FF2D88cc,
      -3px -7px 12px 0 #FFC92Eaa,
      7px -2px 14px 0 #FF7A2Eaa;
  }
  100% {
    box-shadow:
      -2px -8px 14px 0 #B14BF4cc,
      8px -1px 13px 0 #FF2D88cc,
      3px 8px 15px 0 #FFC92Eaa,
      -7px 3px 13px 0 #FF7A2Eaa;
  }
}
.evz-featured-tile {
  position: relative;
  z-index: 1;
  animation: evz-featured-glow 8s ease-in-out infinite;
}

/* ── Títulos con piel propia (PDP personalizado por juego) ────────────────
   Gradiente vertical + resplandor (shimmer) que barre las letras
   periódicamente (estilo "Ver todas →" pero clipeado al texto). Dos capas de
   background sobre el mismo texto: la de arriba es una banda blanca diagonal
   que se anima en x; la de abajo es el color, que aporta cada juego vía
   --evz-title-grad. Para sumar un juego: una regla de 1 línea acá + poner la
   clase en su config `titleClass` (pdp-refined.jsx). */
@keyframes evz-title-shimmer {
  /* barrido lento (0→83% ≈ 3.9s, misma velocidad) + pausa corta (17% ≈ 0.8s)
     → el resplandor aparece más seguido sin acelerar el glide */
  0%   { background-position: 230% 0, 0 0; }
  83%  { background-position: -140% 0, 0 0; }
  100% { background-position: -140% 0, 0 0; }
}
.evz-gta-title,
.evz-fc27-title {
  background-image:
    linear-gradient(100deg, transparent 43%, rgba(255,255,255,0.92) 50%, transparent 57%),
    var(--evz-title-grad);
  background-size: 230% 100%, 100% 100%;
  background-position: 230% 0, 0 0;
  background-repeat: no-repeat;
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
  animation: evz-title-shimmer 4.7s ease-in-out infinite;
}
/* GTA VI — violeta → rosa → amarillo (como el logo oficial). */
.evz-gta-title {
  --evz-title-grad: linear-gradient(178deg, #B14BF4 0%, #DA2BA0 34%, #FF2D88 52%, #FF7A33 76%, #FFC92E 100%);
}
/* FC 27 — volt → menta → cian (paleta EA SPORTS de la portada). */
.evz-fc27-title {
  --evz-title-grad: linear-gradient(178deg, #E4FF6B 0%, #B6F23C 32%, #4EE3A8 66%, #17D6E8 100%);
}

/* ── Hover de los trailers de la ficha de GTA VI (A/B de diseño) ────────
   Al pasar el mouse por una miniatura o por el reproductor aparece encima un
   velo MUY tenue con los colores de GTA VI (violeta → rosa → naranja, los de
   GTA6_CTA_GRADIENT), la imagen se suaviza apenas y crece un 2%. Tiene que
   seguir viéndose el trailer: con el velo opaco la miniatura quedaba tapada.
   El velo es un <span class="evz-gta-wash"> puesto ENTRE la imagen y el ▶ /
   la etiqueta, así esos quedan arriba. Con html[data-perf="lite"] (sin GPU,
   ver perf-mode.js) no hay blur ni escala: solo el velo. */
.evz-gta-hover img {
  transition: filter .5s ease, transform .6s ease;
}
.evz-gta-hover .evz-gta-wash {
  position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(135deg, rgba(177,75,244,0.24) 0%, rgba(255,45,126,0.16) 52%, rgba(255,122,46,0.20) 100%);
  opacity: 0;
  transition: opacity .5s ease;
}
.evz-gta-hover:hover .evz-gta-wash,
.evz-gta-hover:focus-visible .evz-gta-wash {
  opacity: 1;
}
.evz-gta-hover:hover img,
.evz-gta-hover:focus-visible img {
  filter: blur(0.6px) saturate(1.1);
  transform: scale(1.02);
}
html[data-perf="lite"] .evz-gta-hover:hover img,
html[data-perf="lite"] .evz-gta-hover:focus-visible img {
  filter: none;
  transform: none;
}

/* ── Custom scrollbar PC ─────────────────────────────────────────────────
   Mobile (<1024) sigue oculta — cada *.html setea html/body scrollbar-width:
   none + ::-webkit-scrollbar display:none. En PC (>=1024) la revelamos con
   estilo propio: track sutil casi invisible + thumb violeta tenue (light:
   violeta más oscuro). Hover/active suben el contraste sin exagerar.
   Aplica a TODOS los HTMLs porque overridea las reglas globales del block
   <style> embebido cuando coincide media query.
   Override scope: html (no body — Chrome ahora pinta scrollbar en root). */
@media (min-width: 1024px) {
  html {
    scrollbar-width: thin !important;
    scrollbar-color: rgba(139, 92, 246, 0.45) transparent !important;
  }
  html::-webkit-scrollbar {
    display: block !important;
    width: 12px;
    height: 12px;
  }
  html::-webkit-scrollbar-track {
    background: transparent;
    border: 0;
  }
  html::-webkit-scrollbar-thumb {
    background: linear-gradient(180deg, rgba(139,92,246,0.40), rgba(124,58,237,0.55));
    border: 3px solid var(--bg-base);
    border-radius: 999px;
    background-clip: padding-box;
    min-height: 40px;
    transition: background .15s ease;
  }
  html::-webkit-scrollbar-thumb:hover {
    background: linear-gradient(180deg, rgba(139,92,246,0.65), rgba(124,58,237,0.85));
    background-clip: padding-box;
  }
  html::-webkit-scrollbar-thumb:active {
    background: linear-gradient(180deg, rgba(139,92,246,0.85), rgba(124,58,237,1));
    background-clip: padding-box;
  }
  html::-webkit-scrollbar-corner { background: transparent; }
}

/* ── 10% off al sumar el PS Plus (2026-08-30) ─────────────────────────────
   Dos piezas, y las dos son deliberadamente cortas: esto pasa mientras el
   cliente esta decidiendo, no es una celebracion.

   El chip -10% entra con rebote sobre la caratula del plan. Va con `backwards`
   por el mismo motivo que evz-plus-in: con el delay, sin backwards el chip
   estaria visible y sin animar durante los primeros 780ms, que es justo cuando
   se lo esta mirando. */
@keyframes evz-plus-chip {
  0%   { transform: scale(.4); opacity: 0; }
  60%  { transform: scale(1.12); opacity: 1; }
  100% { transform: scale(1); opacity: 1; }
}

/* La linea "Descuento PS Plus" del bloque de totales entra ABRIENDO espacio, no
   apareciendo: el empujon hacia abajo del total es lo que hace notar que
   aparecio plata de vuelta. Se anima max-height y no height porque la linea no
   tiene altura fija; 26px alcanza para una linea de 13px con su interlineado y
   nunca la recorta. */
@keyframes evz-plus-off-in {
  from { max-height: 0; opacity: 0; transform: translateY(-6px); }
  to   { max-height: 26px; opacity: 1; transform: none; }
}

/* ─── Barra del navegador in-app (ver inapp-guard.js) ──────────────────────────

   Cuando un anuncio de Meta tiene el CTA "Llamar", el navegador in-app de
   Instagram pega una barra fija abajo, POR ENCIMA de la pagina. Esta fuera de
   nuestro documento: no hay z-index que le gane ni forma de medirla desde JS
   (el viewport no se encoge). Lo unico que se puede hacer es reservarle el alto
   para que los controles anclados al borde inferior queden arriba de ella.

   COMO SE CONSUME: cada control suma `+ var(--evz-inapp-pad, 0px)` a su
   padding-bottom (los sticky) o a su bottom (los FAB, que son fixed). Sin el
   atributo que pone inapp-guard.js la variable no existe, el fallback es 0px y
   el valor computado queda IDENTICO al de antes. Ahi vive la garantia de que
   esto no puede cambiarle nada al ~90% de los visitantes.

   EL NUMERO es una estimacion: de la captura del reporte sale ~44px y 72 deja
   margen. Reservar de mas es aire, reservar de menos es el boton tapado, asi
   que el error barato es para arriba. Se calibra ACA, es el unico lugar donde
   vive.

   Solo `meta`: es el unico in-app donde vimos la barra. El resto (`otro`:
   TikTok, WhatsApp, WebView de Android) se detecta para medir y para habilitar
   el CTA inline, que no le cuesta nada a nadie.

   El @media es la segunda red: aun con un falso positivo en un WebView de
   escritorio, desktop no se entera. */
@media (max-width: 1023px) {
  html[data-inapp="meta"] { --evz-inapp-pad: 72px; }
}

/* ── Cartel de ENVÍO INMEDIATO (StockPill de la PDP) ────────────────────────
   Entrada una sola vez + el sobre flotando + las estelas corriendo en cascada.
   Elegido por Iker el 2026-09-15 contra siete alternativas; acá quedó solo lo
   elegido. La clase `evz-envio-base` la pone el componente sobre la raíz del
   cartel y las tres reglas de abajo reparten el movimiento por parte.

   Viven acá y no inline porque son @keyframes, que un style inline no puede
   expresar.

   Los tiempos están en relación 2:1 a propósito (flota 2.4s / estelas 1.2s): con
   períodos que no son múltiplos, las dos animaciones se desfasan sin repetirse
   nunca y el conjunto se lee nervioso en vez de rítmico.

   No hay ningún color acá: todo lo que se anima es `transform` y `opacity`, o
   sea que corre en el compositor y no dispara layout ni repaint. El verde vive
   en un solo lugar, `STOCK_VERDE` de pdp-refined.jsx.

   🚨 NADA DE `prefers-reduced-motion`: es decisión de Iker (2026-05-24) y está
   argumentada en vendor/perf/perf-mode.js — esa preferencia del SO es sobre
   parallax y UI bouncy, no sobre esto. El mecanismo correcto de degradado en
   este sitio es `html[data-perf="lite"]`, que perf-mode.js ya setea cuando el
   browser no tiene aceleración por GPU. Está al final del bloque. */
@keyframes evz-envio-entra {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: none; }
}
@keyframes evz-envio-flota {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-1.8px); }
}
@keyframes evz-envio-estela {
  0%, 100% { opacity: 0.2; transform: translateX(2.5px); }
  40%      { opacity: 1;   transform: translateX(0); }
}
.evz-envio-base { animation: evz-envio-entra 0.32s ease-out both; }
.evz-envio-base svg { animation: evz-envio-flota 2.4s ease-in-out infinite; }
.evz-envio-base .evz-envio-estela1 { animation: evz-envio-estela 1.2s ease-in-out infinite; }
.evz-envio-base .evz-envio-estela2 { animation: evz-envio-estela 1.2s ease-in-out 0.1s infinite; }
.evz-envio-base .evz-envio-estela3 { animation: evz-envio-estela 1.2s ease-in-out 0.2s infinite; }

/* Degradado en máquinas sin GPU (perf-mode.js pone data-perf="lite").
   Se apagan SOLO los loops infinitos; la entrada de una vez se conserva porque
   cuesta nada y es la que evita el salto de layout.
   ⚠ HOY ESTO NO ACTÚA EN LA PDP: perf-mode.js solo se carga en index.html, así que
   `data-perf` nunca se setea acá. Las reglas están escritas y verificadas para
   cuando se cargue. */
html[data-perf="lite"] .evz-envio-base svg,
html[data-perf="lite"] .evz-envio-base .evz-envio-estela1,
html[data-perf="lite"] .evz-envio-base .evz-envio-estela2,
html[data-perf="lite"] .evz-envio-base .evz-envio-estela3 { animation: none; }

/* Botón flotante de WhatsApp: se esconde mientras se baja (la clase la pone shared.jsx).
   El !important gana al transform inline del hover. */
.evz-wa-fab { transition: transform .22s ease, opacity .22s ease, box-shadow .15s !important; }
html.evz-wa-fab-oculto .evz-wa-fab { transform: translateY(160%) !important; opacity: 0; pointer-events: none; }
