/* ============================================================
   La Bola 8 de Eze — styles
   Secciones: tokens · base · fondo · masthead · bola · ventana
   · reveal · hint · CTA · footer · reduced-motion · responsive
   ============================================================ */

/* ---------- tokens ---------- */
:root {
  --bg: #0a0711;
  --bg-glow: #695fbe;
  --text: #f4f4f5;
  --text-muted: #9d9da8;
  --text-faint: #8b8b97; /* AA sobre el fondo (antes #5c5c66 ≈ 3:1) */
  --accent: #ff7a1a;
  --accent-soft: #ffb37a;
  --window-navy: #141824;
  --die-blue-1: #2f3aa8;
  --die-blue-2: #1b2260;

  /* geometría de la ventana sobre el arte (medida con grilla sobre assets/ball.png) */
  --window-x: 51%;
  --window-y: 49%;
  --window-size: 46%;

  --ball-size: clamp(290px, 64vmin, 500px);

  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-exit: cubic-bezier(0.4, 0, 1, 1);
  /* display con carácter para los momentos de la bola; body de sistema, neutro */
  --font-display: "Bricolage Grotesque", system-ui, sans-serif;
  --font-body: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
}

/* ---------- base ---------- */
* { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  overflow-x: clip;
}

body {
  margin: 0;
  min-height: 100vh;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  align-items: center;
  font-family: var(--font-body);
  background: var(--bg);
  color: var(--text);
  overflow-x: clip;
}

.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap; border: 0;
}

/* ---------- fondo (atmósfera en código: glow + humo, separado de la bola) ---------- */
.bg {
  position: fixed;
  inset: 0;
  z-index: -1;
  overflow: hidden;
  background:
    /* viñeta oscura hacia los bordes */
    radial-gradient(ellipse 130% 100% at 50% 42%, transparent 46%, rgba(3 1 7 / 0.78) 100%),
    /* luz radial violeta detrás de la bola (como frente.png) */
    radial-gradient(ellipse 30% 22% at 50% 36%, rgba(126 112 214 / 0.42), transparent 100%),
    radial-gradient(ellipse 56% 44% at 50% 38%, rgba(89 74 168 / 0.30), transparent 74%),
    var(--bg);
}

/* aurora violeta re suave (stripes animadas, adaptación oscura del snippet) */
.aurora {
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  --stripes: repeating-linear-gradient(
    100deg,
    var(--bg) 0%, var(--bg) 7%,
    transparent 10%, transparent 12%,
    var(--bg) 16%
  );
  --aurora: repeating-linear-gradient(
    100deg,
    #5b4ba8 10%, #8a76e8 15%, #3b2f7e 20%, #7a5fd0 25%, #5b4ba8 30%
  );
  background-image: var(--stripes), var(--aurora);
  background-size: 300% 100%, 200% 100%;
  background-position: 50% 50%, 50% 50%;
  filter: blur(16px) saturate(180%);
  opacity: 0.55;
  mask-image: radial-gradient(ellipse 120% 85% at 50% 0%, black 45%, transparent 88%);
  -webkit-mask-image: radial-gradient(ellipse 120% 85% at 50% 0%, black 45%, transparent 88%);
}

.aurora::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: 320%;
  background-image: var(--stripes), var(--aurora);
  /* períodos: 200vw y 100vw → el shift de -62.5% (= 200vw) es
     exactamente 1 y 2 períodos: el loop calza perfecto, sin salto */
  background-size: 62.5% 100%, 31.25% 100%;
  mix-blend-mode: screen;
  opacity: 0.5;
  /* transform puro: la capa se rasteriza una vez y solo se compone */
  will-change: transform;
  animation: aurora-scroll 70s linear infinite;
}

@keyframes aurora-scroll {
  from { transform: translateX(0); }
  to   { transform: translateX(-62.5%); }
}

/* noche estrellada sutil: estrellas de 4 puntas titilando desfasadas */
.stars {
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
}

.star {
  position: absolute;
  background: center / contain no-repeat url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 0C13.2 7.8 16.2 10.8 24 12 16.2 13.2 13.2 16.2 12 24 10.8 16.2 7.8 13.2 0 12 7.8 10.8 10.8 7.8 12 0Z" fill="white"/></svg>');
  filter: drop-shadow(0 0 4px rgba(190 185 255 / 0.55));
  opacity: 0;
  animation: star-twinkle var(--tw, 5s) ease-in-out var(--delay, 0s) infinite;
}

@keyframes star-twinkle {
  0%, 100% { opacity: 0.05; transform: scale(0.7); }
  50%      { opacity: var(--peak, 0.55); transform: scale(1.05); }
}


/* polvo estelar del cursor — mismo sistema visual que los sparks del reveal */
.trail-star {
  position: fixed;
  z-index: 4;
  pointer-events: none;
  border-radius: 50%;
  background: radial-gradient(circle, #fff 0%, currentColor 55%, transparent 78%);
  box-shadow: 0 0 8px currentColor;
  opacity: 0;
}

.trail-star--star {
  border-radius: 0;
  background: center / contain no-repeat url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 0C13.2 7.8 16.2 10.8 24 12 16.2 13.2 13.2 16.2 12 24 10.8 16.2 7.8 13.2 0 12 7.8 10.8 10.8 7.8 12 0Z" fill="white"/></svg>');
  box-shadow: none;
  filter: drop-shadow(0 0 6px currentColor);
}

/* partículas del reveal: emergen desde atrás de la esfera */
.spark {
  position: absolute;
  left: 50%;
  top: 50%;
  z-index: 0; /* detrás del cuerpo de la bola, delante del halo */
  pointer-events: none;
  border-radius: 50%;
  background: radial-gradient(circle, #fff 0%, currentColor 55%, transparent 78%);
  box-shadow: 0 0 10px currentColor;
  opacity: 0;
}

.spark--star {
  border-radius: 0;
  background: center / contain no-repeat url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 0C13.2 7.8 16.2 10.8 24 12 16.2 13.2 13.2 16.2 12 24 10.8 16.2 7.8 13.2 0 12 7.8 10.8 10.8 7.8 12 0Z" fill="white"/></svg>');
  box-shadow: none;
  filter: drop-shadow(0 0 7px currentColor);
}

/* humo: dos capas blureadas con derivas lentas y desfasadas */
.bg::before,
.bg::after {
  content: "";
  position: absolute;
  inset: -25%;
  pointer-events: none;
  will-change: transform;
  background:
    /* humo violeta, denso abajo a la izquierda (frente.png) */
    radial-gradient(ellipse 44% 30% at 24% 76%, rgba(156 136 216 / 0.5), transparent 70%),
    radial-gradient(ellipse 38% 24% at 44% 90%, rgba(120 104 190 / 0.42), transparent 70%),
    radial-gradient(ellipse 30% 38% at 6% 58%, rgba(110 95 180 / 0.32), transparent 70%);
  filter: blur(24px);
  animation: smoke-a 22s ease-in-out infinite alternate;
}

.bg::after {
  background:
    /* humo cálido abajo a la derecha, eco del rim light naranja */
    radial-gradient(ellipse 40% 26% at 78% 82%, rgba(196 116 56 / 0.4), transparent 70%),
    radial-gradient(ellipse 30% 34% at 96% 64%, rgba(170 96 46 / 0.28), transparent 70%),
    radial-gradient(ellipse 34% 20% at 60% 94%, rgba(150 120 190 / 0.3), transparent 70%);
  filter: blur(30px);
  animation: smoke-b 30s ease-in-out infinite alternate;
}

@keyframes smoke-a {
  from { transform: translate3d(-3%, 2%, 0) scale(1); }
  to   { transform: translate3d(3%, -2.5%, 0) scale(1.1); }
}

@keyframes smoke-b {
  from { transform: translate3d(2.5%, -1.5%, 0) scale(1.08); }
  to   { transform: translate3d(-3%, 2%, 0) scale(1); }
}

/* ---------- masthead ---------- */
/* masthead compacto: la bola es la protagonista (ref: Fey) */
.masthead {
  text-align: center;
  padding: clamp(18px, 3vh, 34px) 24px 0;
  max-width: 640px;
}

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  margin: 0 0 18px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: #a89dde;
}

.eyebrow__emoji {
  font-size: 16px;
  line-height: 1;
  letter-spacing: 0;
}

.title__word {
  display: inline-block;
  white-space: nowrap;
}

.title__ch {
  display: inline-block;
  animation: ch-in 640ms var(--ease-out) both;
}

@keyframes ch-in {
  from { opacity: 0; transform: translateY(0.35em) rotate(3deg); filter: blur(6px); }
  to   { opacity: 1; transform: none; filter: blur(0); }
}

.title {
  margin: 0;
  font-family: var(--font-display);
  font-size: clamp(40px, 8.5vw, 72px);
  font-weight: 800;
  letter-spacing: -0.02em;
  line-height: 1.02;
  /* blanco con cast violeta + glow: la luz de la escena baña el título */
  color: #f1edfd;
  text-shadow: 0 0 28px rgba(126 112 214 / 0.35);
}

.tagline {
  margin: 12px auto 0;
  max-width: 52ch;
  font-size: clamp(15px, 2.3vw, 18px);
  line-height: 1.55;
  color: var(--text-muted);
  text-wrap: balance;
}

/* ---------- bola ---------- */
.stage {
  position: relative;
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 100%;
  padding: clamp(8px, 2vh, 24px) 24px 32px;
}

.stage > * { position: relative; z-index: 1; }

/* niebla local pegada a la mitad baja de la bola */
.stage::before {
  content: "";
  position: absolute;
  z-index: 0;
  top: calc(clamp(16px, 4vh, 40px) + var(--ball-size) * 0.52);
  left: 50%;
  transform: translateX(-50%);
  width: calc(var(--ball-size) * 1.6);
  height: calc(var(--ball-size) * 0.62);
  background:
    radial-gradient(ellipse 42% 46% at 38% 52%, rgba(150 132 214 / 0.32), transparent 70%),
    radial-gradient(ellipse 38% 40% at 66% 60%, rgba(122 100 190 / 0.26), transparent 70%);
  filter: blur(24px);
  will-change: transform, opacity;
  animation: fog-drift 16s ease-in-out infinite alternate;
  pointer-events: none;
}

@keyframes fog-drift {
  from { transform: translateX(-53%) translateY(0.5%); opacity: 0.75; }
  to   { transform: translateX(-47%) translateY(-2%); opacity: 1; }
}

.ball {
  position: relative;
  width: var(--ball-size);
  height: var(--ball-size);
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: none;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
  /* --mx/--my: atracción magnética al cursor (lerp por rAF, sin transition) */
  transform: translate(var(--mx, 0px), var(--my, 0px));
}

.ball:active { transform: translate(var(--mx, 0px), var(--my, 0px)) scale(0.98); }

/* anillo de foco sutil en violeta: el naranja de marca alrededor de la
   bola se leía como glitch, no como affordance */
.ball:focus-visible {
  outline: 2px solid rgba(190 160 255 / 0.55);
  outline-offset: 6px;
}

.ball__float,
.ball__body,
.ball__art {
  position: absolute;
  inset: 0;
  display: block;
  border-radius: 50%;
}

.ball__float { z-index: 1; }

/* humo real (recorte de frente.png) envolviendo la esfera */
.smoke {
  position: absolute;
  left: 50%;
  pointer-events: none;
  mix-blend-mode: screen;
  user-select: none;
  will-change: transform;
  /* fundido radial: sin ningún borde recto del recorte */
  mask-image: radial-gradient(ellipse 60% 44% at 50% 52%, #000 48%, transparent 90%);
  -webkit-mask-image: radial-gradient(ellipse 60% 44% at 50% 52%, #000 48%, transparent 90%);
}

.smoke--back {
  z-index: 0;
  width: calc(var(--ball-size) * 2.75);
  top: calc(clamp(16px, 4vh, 40px) + var(--ball-size) * 0.54);
  transform: translateX(-50%);
  opacity: 1;
  animation: smoke-back-drift 16s ease-in-out infinite alternate;
}

.smoke--front {
  z-index: 2;
  width: calc(var(--ball-size) * 2.15);
  top: calc(clamp(16px, 4vh, 40px) + var(--ball-size) * 0.85);
  transform: translateX(-50%) scaleX(-1);
  opacity: 0.58;
  animation: smoke-front-drift 22s ease-in-out infinite alternate;
}

@keyframes smoke-back-drift {
  from { transform: translateX(-53.5%) translateY(1.8%) scale(1); }
  to   { transform: translateX(-46.5%) translateY(-2.6%) scale(1.05); }
}

@keyframes smoke-front-drift {
  from { transform: translateX(-46.5%) scaleX(-1) translateY(-1.8%) scale(1.04); }
  to   { transform: translateX(-53.5%) scaleX(-1) translateY(2.4%) scale(1); }
}

.ball__float {
  will-change: transform;
  animation: float 5.4s ease-in-out infinite alternate;
}

/* geometría de ventana propia del modo CSS (la de :root está medida
   sobre el arte generado) */
.ball[data-art="css"] {
  --window-x: 50%;
  --window-y: 56%;
  --window-size: 42%;
}

/* esfera glossy en CSS puro (fallback hasta que llegue el arte generado) */
[data-art="css"] .ball__art {
  background:
    /* brillo especular superior */
    radial-gradient(ellipse 34% 22% at 33% 22%, rgba(255 255 255 / 0.55), rgba(255 255 255 / 0.08) 55%, transparent 70%),
    /* rebote de luz cálida inferior-derecha */
    radial-gradient(ellipse 45% 32% at 72% 92%, rgba(255 122 26 / 0.16), transparent 65%),
    /* rim light frío a la izquierda */
    radial-gradient(ellipse 22% 40% at 6% 55%, rgba(140 160 255 / 0.10), transparent 70%),
    /* cuerpo */
    radial-gradient(circle at 36% 30%, #43434c 0%, #232329 38%, #0f0f14 72%, #050508 100%);
  box-shadow:
    inset 0 -18px 42px rgba(0 0 0 / 0.55),
    inset 0 10px 30px rgba(255 255 255 / 0.05);
}

.ball__art img,
.ball__art video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* micro-parallax: sprite sheet 5x5 de la esfera rotada ±PARALLAX_DEG sobre el
   eje vertical (tools/make-sprite.py). La celda del medio es ball.png tal cual.
   El recorte va por máscara y no por alpha del webp: 25 discos con alpha real
   triplican el peso del archivo. */
.ball__sprite {
  position: absolute;
  inset: 0;
  background-repeat: no-repeat;
  background-size: 700% 500%;   /* grilla del sheet: COLS x ROWS */
  mask-image: radial-gradient(ellipse 48.04% 48.67% at 50% 50%, #000 99.4%, transparent 100%);
  -webkit-mask-image: radial-gradient(ellipse 48.04% 48.67% at 50% 50%, #000 99.4%, transparent 100%);
  opacity: 0;
  transition: opacity 260ms var(--ease-out);
}

.ball__sprite.is-ready { opacity: 1; }

/* el arte generado trae su propia ventana: sin fondo CSS, pero el
   vidrio (glint/flash/barrido) y una sombra de asiento quedan encima */
[data-art="image"] .ball__window,
[data-art="video"] .ball__window {
  background: none;
  box-shadow:
    inset 0 12px 28px rgba(0 0 0 / 0.5),
    inset 0 -6px 18px rgba(60 70 140 / 0.16);
}

.ball-shadow {
  width: calc(var(--ball-size) * 0.82);
  height: calc(var(--ball-size) * 0.13);
  margin-top: calc(var(--ball-size) * 0.015);
  border-radius: 50%;
  background: radial-gradient(ellipse at center, rgba(0 0 0 / 0.6), transparent 68%);
  filter: blur(8px);
  will-change: transform, opacity;
  animation: shadow-breathe 5.4s ease-in-out infinite alternate;
}

/* ---------- ventana ---------- */
.ball__window {
  position: absolute;
  /* --tilt-x lo setea el parallax: la ventana está sobre la superficie de la
     esfera, así que acompaña la rotación del arte (js/parallax.js) */
  left: calc(var(--window-x) + var(--tilt-x, 0%));
  top: var(--window-y);
  width: var(--window-size);
  height: var(--window-size);
  transform: translate(-50%, -50%);
  border-radius: 50%;
  display: grid;
  place-items: center;
  perspective: 300px;
  overflow: hidden;
  /* border-radius+overflow NO recorta layers compuestos (blur/will-change):
     sin esta máscara, el vapor del dado pinta un recuadro sobre el vidrio */
  -webkit-mask-image: radial-gradient(circle closest-side, #000 98.5%, transparent 100%);
  mask-image: radial-gradient(circle closest-side, #000 98.5%, transparent 100%);
  background:
    radial-gradient(circle at 50% 42%, #1d2333 0%, var(--window-navy) 55%, #05060b 100%);
  box-shadow:
    inset 0 6px 18px rgba(0 0 0 / 0.85),
    inset 0 -3px 10px rgba(80 100 180 / 0.12),
    0 1px 0 rgba(255 255 255 / 0.06);
}

/* vidrio: glint curvo, reflejo inferior, anillo de lente y sheen convexo */
.ball__window::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 2;
  border-radius: 50%;
  background:
    radial-gradient(ellipse 58% 22% at 50% 5%, rgba(255 255 255 / 0.16), transparent 65%),
    radial-gradient(ellipse 44% 15% at 36% 97%, rgba(150 170 255 / 0.1), transparent 70%),
    radial-gradient(circle at 50% 46%, rgba(255 255 255 / 0.035), transparent 58%);
  box-shadow:
    inset 0 0 34px rgba(0 0 0 / 0.55),
    inset 0 0 0 1.5px rgba(165 180 255 / 0.07),
    inset 0 2px 2px rgba(255 255 255 / 0.06);
  pointer-events: none;
}

/* flash violeta que se expande al revelar la respuesta */
.ball__window::before {
  content: "";
  position: absolute;
  inset: 8%;
  z-index: 2;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(140 130 255 / 0.5), rgba(110 95 220 / 0.18) 55%, transparent 75%);
  opacity: 0;
  pointer-events: none;
}

[data-state="revealed"] .ball__window::before {
  animation: reveal-flash 850ms var(--ease-out) both;
}

@keyframes reveal-flash {
  0%   { opacity: 0.6; transform: scale(0.55); }
  100% { opacity: 0; transform: scale(1.3); }
}

/* barrido de luz lento sobre el vidrio */
.ball__glass {
  position: absolute;
  inset: 0;
  z-index: 2;
  border-radius: 50%;
  overflow: hidden;
  -webkit-mask-image: radial-gradient(circle, #000 98%, transparent 100%);
  mask-image: radial-gradient(circle, #000 98%, transparent 100%);
  pointer-events: none;
}

/* banda de luz direccional con bordes fundidos: ni dura ni nube */
.ball__glass::before {
  content: "";
  position: absolute;
  top: -22%;
  left: 0;
  width: 40%;
  height: 144%;
  background: linear-gradient(100deg, transparent 8%, rgba(255 255 255 / 0.09) 42%, rgba(190 200 255 / 0.13) 55%, transparent 92%);
  filter: blur(3px);
  transform: translateX(-160%) rotate(12deg);
  animation: glass-sweep 8s ease-in-out infinite;
}

/* segundo destello menor que persigue al principal */
.ball__glass::after {
  content: "";
  position: absolute;
  top: -22%;
  left: 0;
  width: 14%;
  height: 144%;
  background: linear-gradient(100deg, transparent 12%, rgba(255 255 255 / 0.08) 50%, transparent 88%);
  filter: blur(4px);
  transform: translateX(-380%) rotate(12deg);
  animation: glass-sweep-b 8s ease-in-out 0.35s infinite;
}

@keyframes glass-sweep {
  0%   { transform: translateX(-160%) rotate(10deg); }
  46%  { transform: translateX(420%) rotate(10deg); }
  100% { transform: translateX(420%) rotate(10deg); }
}

@keyframes glass-sweep-b {
  0%   { transform: translateX(-380%) rotate(10deg); }
  46%  { transform: translateX(1150%) rotate(10deg); }
  100% { transform: translateX(1150%) rotate(10deg); }
}

/* líquido índigo: profundidad permanente, se agita en el shake */
.ball__liquid {
  position: absolute;
  inset: -20%;
  border-radius: 50%;
  background:
    radial-gradient(circle at 50% 38%, rgba(45 56 105 / 0.55), transparent 62%),
    radial-gradient(ellipse 70% 55% at 50% 100%, rgba(8 10 22 / 0.8), transparent 70%);
  opacity: 0.5;
  transition: opacity 500ms var(--ease-out);
}

[data-state="shaking"] .ball__liquid {
  opacity: 1;
  transition-duration: 180ms;
  background:
    radial-gradient(ellipse 60% 45% at 42% 60%, rgba(24 30 58 / 0.95), transparent 70%),
    radial-gradient(ellipse 50% 40% at 62% 38%, rgba(10 12 24 / 0.95), transparent 70%);
}

/* al revelar, la luz del dado tiñe el líquido y sangra sobre el anillo */
[data-state="revealed"] .ball__liquid {
  opacity: 0.85;
  background:
    radial-gradient(circle at 50% 46%, rgba(120 80 230 / 0.36), rgba(70 48 160 / 0.15) 55%, transparent 75%),
    radial-gradient(ellipse 70% 55% at 50% 100%, rgba(8 10 22 / 0.7), transparent 70%);
}

/* dado clásico: triángulo INVERTIDO azul eléctrico brillando desde
   adentro, con el texto SOBRE la cara (ref Magic8Ball.webp) —
   dado y texto emergen y se mecen juntos */
.ball__die-group {
  position: absolute;
  z-index: 1;
  width: 74%;
  aspect-ratio: 100 / 90;
  display: grid;
  justify-items: center;
  align-items: start;
  /* sin will-change: el layer promovido recortaba el glow del dado en
     recto (el "recuadro"); Chrome decide solo durante la transición */
  /* pose oculta = vapor: al revelarse el dado CONDENSA desde el humo
     (blur alto + apenas expandido), no emerge del líquido */
  opacity: 0;
  transform: translateY(-3%) scale(1.08);
  filter: blur(9px);
  transition:
    opacity 550ms var(--ease-out),
    transform 620ms var(--ease-out),
    filter 620ms var(--ease-out);
}

[data-state="revealed"] .ball__die-group {
  opacity: 1;
  transform: translateY(0) scale(1);
  filter: blur(0);
  transition-delay: 90ms; /* deja que el tumble entregue la posta */
  animation: die-sway 8s ease-in-out 1.2s infinite alternate;
}

/* ---------- modo picante: el dado (y su luz) viran al ember ----------
   Un solo SVG (el violeta) recoloreado por filtro: los drop-shadows van
   ANTES del hue-rotate, así el glow también vira a naranja. */
body[data-picante="true"] .ball__die {
  filter:
    drop-shadow(0 8px 18px rgba(0 0 0 / 0.5))
    drop-shadow(0 0 26px rgba(140 80 255 / 0.5))
    drop-shadow(0 0 55px rgba(120 70 230 / 0.3))
    hue-rotate(127deg) saturate(1.35) brightness(1.05);
}

body[data-picante="true"] .ball__tumble {
  filter: blur(0.7px) drop-shadow(0 0 18px rgba(140 85 255 / 0.4)) hue-rotate(127deg) saturate(1.35);
}

body[data-picante="true"] [data-state="revealed"] .ball__liquid {
  background:
    radial-gradient(circle at 50% 46%, rgba(235 125 45 / 0.34), rgba(160 75 25 / 0.14) 55%, transparent 75%),
    radial-gradient(ellipse 70% 55% at 50% 100%, rgba(8 10 22 / 0.7), transparent 70%);
}

body[data-picante="true"] [data-state="revealed"] .ball__window::before {
  background: radial-gradient(circle, rgba(255 150 70 / 0.5), rgba(230 115 40 / 0.18) 55%, transparent 75%);
}

body[data-picante="true"] .ball__answer {
  text-shadow:
    0 0 2px rgba(255 255 255 / 0.65),
    0 0 14px rgba(255 185 120 / 0.85),
    0 1px 3px rgba(70 25 5 / 0.5);
}

[data-state="shaking"] .ball__die-group {
  opacity: 0;
  transform: translateY(-5%) scale(1.05);
  filter: blur(10px);
  transition-duration: 260ms;
  transition-delay: 0ms;
}

@keyframes die-sway {
  from { transform: translateY(0) rotate(0deg); }
  to   { transform: translateY(1.8%) rotate(1deg); }
}

/* dado dando tumbos durante el shake (ref GIF: se ve la geometría 3D) */
.ball__tumble {
  position: absolute;
  z-index: 1;
  width: 52%;
  aspect-ratio: 100 / 90;
  opacity: 0;
  transition: opacity 380ms var(--ease-out);
  pointer-events: none;
  filter: blur(0.7px) drop-shadow(0 0 18px rgba(140 85 255 / 0.4));
}

.ball__tumble-face {
  position: absolute;
  inset: 0;
  background: center / contain no-repeat url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 90"><defs><linearGradient id="tf" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="%238a52f5"/><stop offset="1" stop-color="%235327b8"/></linearGradient></defs><path d="M50 5.5 Q53.5 5.5 55.5 9.5 L93 74.5 Q96 81 89 83 L11 83 Q4 81 7 74.5 L44.5 9.5 Q46.5 5.5 50 5.5 Z" fill="url(%23tf)"/></svg>');
}

[data-state="shaking"] .ball__tumble {
  /* física del GIF: el dado se hunde en la tinta (oscuridad un beat)
     y vuelve con tumbos amortiguados — cada tramo con easing sinusoidal
     para que fluya como líquido, no como animatic */
  animation: die-tumble 1120ms cubic-bezier(0.37, 0, 0.63, 1) forwards;
}

@keyframes die-tumble {
  0% {
    opacity: 0;
    transform: rotateX(42deg) rotateY(-28deg) rotate(-16deg) translateY(30%) scale(0.52);
    animation-timing-function: cubic-bezier(0.37, 0, 0.63, 1);
  }
  18% {
    opacity: 0.25;
    transform: rotateX(30deg) rotateY(36deg) rotate(18deg) translateY(24%) scale(0.56);
    animation-timing-function: cubic-bezier(0.37, 0, 0.63, 1);
  }
  34% {
    opacity: 0.1;
    transform: rotateX(-24deg) rotateY(-40deg) rotate(-26deg) translateY(17%) scale(0.52);
    animation-timing-function: cubic-bezier(0.37, 0, 0.63, 1);
  }
  54% {
    opacity: 0.6;
    transform: rotateX(-30deg) rotateY(24deg) rotate(20deg) translateY(8%) scale(0.7);
    animation-timing-function: cubic-bezier(0.37, 0, 0.63, 1);
  }
  72% {
    opacity: 0.88;
    transform: rotateX(16deg) rotateY(-16deg) rotate(-10deg) translateY(2.5%) scale(0.84);
    animation-timing-function: cubic-bezier(0.33, 0, 0.4, 1);
  }
  86% {
    opacity: 0.96;
    transform: rotateX(-6deg) rotateY(7deg) rotate(4deg) translateY(-0.8%) scale(0.92);
    animation-timing-function: cubic-bezier(0.3, 0, 0.35, 1);
  }
  100% {
    opacity: 1;
    transform: rotateX(0deg) rotateY(0deg) rotate(0deg) translateY(0) scale(0.96);
  }
}

.ball__die {
  position: absolute;
  inset: 0;
  /* capa propia siempre: evita el flash cuadrado al rasterizar filtros */
  will-change: filter;
  transform: translateZ(0);
  /* el hue-rotate de picante MORPHEA al ember en vez de saltar */
  transition: opacity 200ms var(--ease-out), filter 450ms var(--ease-out);
  background: center / contain no-repeat url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 90"><defs><linearGradient id="f" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="%239a63ff"/><stop offset=".5" stop-color="%237b3df2"/><stop offset="1" stop-color="%235e2ecc"/></linearGradient></defs><path d="M50 5.5 Q53.5 5.5 55.5 9.5 L93 74.5 Q96 81 89 83 L11 83 Q4 81 7 74.5 L44.5 9.5 Q46.5 5.5 50 5.5 Z" fill="url(%23f)"/></svg>');
  filter:
    drop-shadow(0 8px 18px rgba(0 0 0 / 0.5))
    drop-shadow(0 0 26px rgba(140 80 255 / 0.5))
    drop-shadow(0 0 55px rgba(120 70 230 / 0.3));
}

/* ---------- la respuesta, sobre la cara del dado ----------
   El texto fluye en forma TRIANGULAR: dos cuñas flotadas con
   shape-outside replican los lados del dado, así cada línea se
   angosta con la cara y nunca se sale (como impreso en el juguete). */
.ball__answer {
  position: absolute;
  z-index: 1;
  left: 4%;
  right: 4%;
  top: 15%;
  bottom: 4%;
  display: block;
  text-align: center;
  font-family: var(--font-display);
  font-size: clamp(9px, calc(var(--ball-size) * 0.024), 12px);
  font-weight: 700;
  line-height: 1.38;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: #f6f2ff;
  text-shadow:
    0 0 2px rgba(255 255 255 / 0.65),
    0 0 14px rgba(200 165 255 / 0.85),
    0 1px 3px rgba(30 12 60 / 0.5);
}

/* El quiebre de líneas lo arma fitAnswer() en JS: mide cada palabra
   con la fuente real y respeta el ancho del triángulo línea por línea.
   Acá solo va la tipografía; font-size lo setea el JS inline. */

/* la frase se esfuma en humo, letra por letra, antes del shake
   (aplica a la respuesta y al hint de bienvenida por igual) */
.smoke-ch {
  display: inline-block;
  white-space: pre;
}

.is-smoking .smoke-ch {
  animation: letter-smoke 300ms var(--ease-out) forwards;
}

@keyframes letter-smoke {
  to {
    transform: translateY(-14px) rotate(22deg);
    opacity: 0;
    filter: blur(6px);
  }
}

/* micro-estado "smoking": el dado queda quieto y visible mientras
   las letras se van; recién después arranca el tumble */
[data-state="smoking"] .ball__die-group {
  opacity: 1;
  transform: translateY(0) scale(1);
  filter: blur(0);
}

/* ---------- hint de bienvenida: texto en el vidrio vacío ----------
   Mismo estilo que la respuesta pero sin triángulo. Se esfuma en humo
   con el primer click y no vuelve. El wrapper flex centra un span
   interno: las letras del smoke-out viven ahí adentro, no como hijos
   directos del flex. */
.ball__hint {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 0 16%;
  font-family: var(--font-display);
  font-size: clamp(10px, calc(var(--ball-size) * 0.028), 14px);
  font-weight: 700;
  line-height: 1.6;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: #f6f2ff;
  text-shadow:
    0 0 2px rgba(255 255 255 / 0.65),
    0 0 14px rgba(200 165 255 / 0.85),
    0 1px 3px rgba(30 12 60 / 0.5);
  opacity: 0;
  animation:
    hint-in 900ms var(--ease-out) 1200ms forwards,
    hint-breathe 4.5s ease-in-out 2600ms infinite alternate;
  pointer-events: none;
}

@keyframes hint-in {
  from { opacity: 0; filter: blur(7px); }
  to { opacity: 1; filter: blur(0); }
}

@keyframes hint-breathe {
  from { opacity: 1; }
  to { opacity: 0.62; }
}

/* si un atajo de QA saltea el flujo normal, el hint no pisa al dado
   (en shaking NO se oculta: la cola del humo sigue sobre el arranque) */
[data-state="revealed"] .ball__hint { display: none; }

body[data-picante="true"] .ball__hint {
  text-shadow:
    0 0 2px rgba(255 255 255 / 0.65),
    0 0 14px rgba(255 185 120 / 0.85),
    0 1px 3px rgba(70 25 5 / 0.5);
}

[data-state="shaking"] .ball__die {
  opacity: 0;
}


.hint.is-swapping { opacity: 0; }

/* ---------- modo picante ---------- */
.spice-toggle {
  margin-top: 26px;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 14px;
  border-radius: 999px;
  border: 1px solid rgba(255 255 255 / 0.12);
  background: rgba(255 255 255 / 0.04);
  color: var(--text-faint);
  font: inherit;
  font-size: 12.5px;
  font-weight: 600;
  letter-spacing: 0.04em;
  cursor: pointer;
  transition:
    color 150ms ease, border-color 150ms ease, background 150ms ease,
    box-shadow 150ms ease, transform 140ms var(--ease-out);
}

.spice-toggle:active { transform: scale(0.96); }
.spice-toggle svg { flex-shrink: 0; }
.spice-toggle .spice-toggle__on { display: none; }

.spice-toggle[aria-checked="true"] {
  color: #ff8a5c;
  border-color: rgba(255 100 40 / 0.5);
  background: rgba(255 90 30 / 0.1);
  box-shadow: 0 0 20px rgba(255 90 30 / 0.16);
}

.spice-toggle[aria-checked="true"] .spice-toggle__on { display: block; }
.spice-toggle[aria-checked="true"] .spice-toggle__off { display: none; }

@media (hover: hover) and (pointer: fine) {
  .spice-toggle:hover { color: var(--text-muted); }
  .spice-toggle[aria-checked="true"]:hover { color: #ffa47e; }
}

/* ---------- CTA ---------- */
/* borde luminoso girando lento (OriginKit "Crystal/Electric glow") */
@property --cta-a {
  syntax: "<angle>";
  initial-value: 0deg;
  inherits: false;
}

.cta::before {
  content: "";
  position: absolute;
  inset: -1px;
  border-radius: inherit;
  padding: 1px;
  background: conic-gradient(from var(--cta-a),
    rgba(140 120 230 / 0.55), rgba(255 122 26 / 0.4),
    rgba(140 120 230 / 0.1), rgba(140 120 230 / 0.55));
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask-composite: exclude;
  animation: cta-spin 9s linear infinite;
  pointer-events: none;
}

@keyframes cta-spin {
  to { --cta-a: 360deg; }
}

/* card glassy sobre la atmósfera + pill con botón embebido (ref: v0/AcMem) */
.cta {
  position: relative;
  margin-top: clamp(28px, 5vh, 48px);
  width: min(420px, calc(100vw - 48px));
  padding: 26px 24px 20px;
  border-radius: 24px;
  text-align: center;
  background: rgba(16 12 28 / 0.55);
  -webkit-backdrop-filter: blur(18px) saturate(140%);
  backdrop-filter: blur(18px) saturate(140%);
  border: 1px solid rgba(255 255 255 / 0.08);
  box-shadow:
    inset 0 1px 0 rgba(255 255 255 / 0.06),
    0 24px 60px rgba(0 0 0 / 0.5);
  opacity: 1;
  transform: translateY(0);
  transition: opacity 600ms var(--ease-out), transform 600ms var(--ease-out);

  @starting-style {
    opacity: 0;
    transform: translateY(22px);
  }
}

.cta[hidden] { display: none; }

.cta__title {
  margin: 0;
  font-family: var(--font-display);
  font-size: 21px;
  font-weight: 700;
  letter-spacing: -0.01em;
}

.cta__body {
  margin: 10px auto 18px;
  max-width: 38ch;
  font-size: 14px;
  line-height: 1.55;
  color: var(--text-muted);
}

.hp { position: absolute; left: -9999px; opacity: 0; }

.cta__pill {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 6px 6px 18px;
  border-radius: 999px;
  background: rgba(255 255 255 / 0.06);
  border: 1px solid rgba(255 255 255 / 0.12);
  transition: border-color 150ms ease, box-shadow 150ms ease;
}

.cta__pill:focus-within {
  border-color: rgba(255 122 26 / 0.7);
  box-shadow: 0 0 0 3px rgba(255 122 26 / 0.14);
}

.cta__input {
  flex: 1;
  min-width: 0;
  padding: 10px 0;
  border: 0;
  background: none;
  color: var(--text);
  font: inherit;
  font-size: 14px;
}

.cta__input::placeholder { color: var(--text-faint); }
.cta__input:focus { outline: none; }

.cta__submit {
  position: relative;
  overflow: hidden;
  padding: 10px 18px;
  border: 0;
  border-radius: 999px;
  background: var(--accent);
  color: #17110b;
  font: inherit;
  font-size: 13.5px;
  font-weight: 700;
  cursor: pointer;
  white-space: nowrap;
  /* magnético (--mx/--my via rAF) */
  transform: translate(var(--mx, 0px), var(--my, 0px));
  transition: filter 140ms ease;
}

/* shine líquido al hover (OriginKit "Water Button") */
.cta__submit::before {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: -45%;
  width: 36%;
  background: linear-gradient(100deg, transparent, rgba(255 255 255 / 0.55), transparent);
  transform: skewX(-14deg);
  transition: left 500ms ease;
  pointer-events: none;
}

@media (hover: hover) and (pointer: fine) {
  .cta__submit:hover::before { left: 112%; }
}

.cta__submit:hover { filter: brightness(1.08); }
.cta__submit:active { transform: translate(var(--mx, 0px), var(--my, 0px)) scale(0.96); }
.cta__submit:disabled { opacity: 0.6; cursor: default; }

.cta__note {
  margin: 12px 0 0;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--text-faint);
}

.cta__status {
  margin: 12px 0 0;
  min-height: 1.3em;
  font-size: 13px;
  color: var(--text-muted);
  opacity: 0;
  transform: translateY(4px);
  transition: opacity 400ms var(--ease-out), transform 400ms var(--ease-out);
}

.cta__status.is-visible { opacity: 1; transform: translateY(0); }
.cta__status.is-ok { color: #6ee7a0; }
.cta__status a { color: var(--accent-soft); }

/* form colapsado tras éxito */
.cta.is-done .cta__form { display: none; }

/* ---------- sound toggle ---------- */
.sound-toggle {
  position: fixed;
  top: 18px;
  right: 18px;
  z-index: 5;
  display: grid;
  place-items: center;
  width: 44px; height: 44px;
  border-radius: 50%;
  border: 1px solid rgba(255 255 255 / 0.12);
  background: rgba(255 255 255 / 0.04);
  color: var(--text-muted);
  cursor: pointer;
  transition: transform 140ms var(--ease-out), color 140ms ease;
}

.sound-toggle:active { transform: scale(0.94); }
.sound-toggle .sound-toggle__off { display: none; }
.sound-toggle[aria-pressed="true"] .sound-toggle__on { display: none; }
.sound-toggle[aria-pressed="true"] .sound-toggle__off { display: block; }

@media (hover: hover) and (pointer: fine) {
  .sound-toggle:hover { color: var(--text); }
}

/* Modo picante ON: brasa pulsante (OriginKit "Electric Border", versión ember) */
.spice-toggle[aria-checked="true"] {
  color: #ffc79a;
  border-color: rgba(255 122 26 / 0.55);
  animation: ember-pulse 2.4s ease-in-out infinite alternate;
}

@keyframes ember-pulse {
  from { box-shadow: 0 0 10px rgba(255 100 30 / 0.18), inset 0 0 8px rgba(255 122 26 / 0.1); }
  to   { box-shadow: 0 0 22px rgba(255 100 30 / 0.4), inset 0 0 12px rgba(255 122 26 / 0.2); }
}

/* ---------- footer ---------- */
.footer {
  padding: 26px 24px calc(30px + env(safe-area-inset-bottom));
  text-align: center;
}

.footer__eze {
  margin: 0 0 14px;
  font-size: 13px;
  color: var(--text-faint);
}

.footer__eze a {
  color: var(--text-muted);
  text-decoration-color: rgba(255 255 255 / 0.25);
  text-underline-offset: 3px;
  transition: color 150ms ease;
}

.footer__eze a:hover { color: var(--text); }

.footer__credit {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
  color: var(--text-faint);
  text-decoration: none;
  opacity: 0.85;
  transition: opacity 150ms ease;
}

.footer__credit:hover { opacity: 1; }
.footer__credit img { display: block; opacity: 0.9; }


.noscript {
  margin: 20px;
  text-align: center;
  color: var(--text-muted);
}

/* ---------- animaciones ---------- */
@keyframes float {
  from { transform: translateY(-11px) rotate(-0.7deg); }
  to   { transform: translateY(12px) rotate(0.8deg); }
}

@keyframes shadow-breathe {
  from { transform: scaleX(0.88); opacity: 0.7; }
  to   { transform: scaleX(1.08); opacity: 1; }
}

/* ---------- reduced motion ---------- */
@media (prefers-reduced-motion: reduce) {
  .ball__float, .ball-shadow { animation: none; }
  .bg::before, .bg::after { animation: none; }
  .aurora::after, .stage::before { animation: none; }
  .smoke { animation: none; }
  .ball__glass::before { animation: none; }
  [data-state="revealed"] .ball__die-group { animation: none; }
  [data-state="revealed"] .ball__window::before { animation: none; }
  [data-state="shaking"] .ball__tumble { animation: none; opacity: 0; }
  .star { animation: none; opacity: 0.3; }
  .cta::before { animation: none; }
  .title__ch { animation: none; }
  .spice-toggle[aria-checked="true"] { animation: none; }
  .ball__hint { animation: none; opacity: 1; }

  .ball__die-group {
    transition: opacity 200ms ease;
    transform: none;
    filter: none;
  }

  [data-state="shaking"] .ball__die-group { transform: none; }

  .cta { transition: opacity 200ms ease; }
}

/* ---------- responsive fino ---------- */
@media (max-width: 420px) {
  .cta { padding: 22px 16px 18px; }
  .cta__pill { padding-left: 14px; }
  .cta__submit { padding: 10px 14px; }
}

/* mobile: blur más liviano (GPU) sin cambiar la composición */
@media (max-width: 520px) {
  .aurora { filter: blur(15px) saturate(160%); }
  .bg::before { filter: blur(18px); }
  .bg::after { filter: blur(22px); }
  .stage::before { filter: blur(18px); }
}

/* mobile: la bola AL CORTE (sangra los costados) y todo más grande.
   El cap por svh garantiza el pill de Modo picante arriba del fold. */
@media (max-width: 640px) {
  :root {
    --ball-size: 128vw;
    --ball-size: min(128vw, 62svh);
  }

  .masthead { padding-top: 12px; }
  .eyebrow { margin-bottom: 10px; }
  .title { font-size: clamp(44px, 12vw, 58px); }

  /* EN: "Eze's Magic 8 Ball" es más largo que "La Bola 8 de Eze" y a
     44px quiebra en dos líneas, empujando el pill de picante abajo del
     fold. Escala por vw para que entre SIEMPRE en una línea. */
  html[lang="en"] .title { font-size: clamp(28px, 9.4vw, 46px); white-space: nowrap; }
  .tagline { font-size: 17px; margin-top: 8px; }
  .tagline__extra { display: none; }
  .stage { padding-top: 4px; }

  /* el volumen baja al ángulo inferior: no pisa el título */
  .sound-toggle { top: auto; bottom: calc(16px + env(safe-area-inset-bottom)); right: 16px; }

  /* el pill se centra solo en el espacio libre entre la bola y el corte;
     padding para hit-area >=44px (WCAG touch target) */
  .spice-toggle { margin-top: auto; margin-bottom: auto; font-size: 16px; padding: 13px 18px; }
  .cta__title { font-size: 23px; }
  .cta__body { font-size: 15.5px; }
  .cta__input, .cta__submit { font-size: 15px; }
  .cta__note { font-size: 11px; }
  .footer__eze { font-size: 14px; }
  .footer__credit { font-size: 13px; }
}
