/* ============================================================
   HYPERTALE — Atmosphere & motion (background FX, reveals)
   ============================================================ */

/* ---- Fixed background stage that sits behind everything ---- */
.fx-stage {
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  overflow: hidden;
}

/* Aurora blobs — slow drifting color fields */
.fx-aurora {
  position: absolute;
  border-radius: 50%;
  filter: blur(70px);
  opacity: 0.5;
  mix-blend-mode: screen;
  will-change: transform;
}
.fx-aurora.a1 { width: 46vw; height: 46vw; left: -8vw; top: -10vw; background: radial-gradient(circle, rgba(var(--purple-rgb), 0.5), transparent 65%); animation: drift1 26s ease-in-out infinite; }
.fx-aurora.a2 { width: 40vw; height: 40vw; right: -6vw; top: 4vw; background: radial-gradient(circle, rgba(var(--green-rgb), 0.32), transparent 65%); animation: drift2 32s ease-in-out infinite; }
.fx-aurora.a3 { width: 52vw; height: 52vw; left: 20vw; bottom: -22vw; background: radial-gradient(circle, rgba(var(--cyan-rgb), 0.22), transparent 65%); animation: drift3 38s ease-in-out infinite; }

@keyframes drift1 { 0%,100% { transform: translate(0,0) scale(1); } 50% { transform: translate(6vw, 5vw) scale(1.12); } }
@keyframes drift2 { 0%,100% { transform: translate(0,0) scale(1); } 50% { transform: translate(-5vw, 7vw) scale(1.08); } }
@keyframes drift3 { 0%,100% { transform: translate(0,0) scale(1); } 50% { transform: translate(4vw, -6vw) scale(1.15); } }

/* Fog sheets */
.fx-fog {
  position: absolute; inset: -20% -20% auto -20%; height: 60%;
  background: radial-gradient(120% 80% at 50% 0%, rgba(255, 255, 255, 0.04), transparent 70%);
  animation: fog 40s linear infinite;
}
@keyframes fog { 0% { transform: translateX(-4%); } 50% { transform: translateX(4%); } 100% { transform: translateX(-4%); } }

/* Star / dust grain */
.fx-grid {
  position: absolute; inset: 0;
  background-image: radial-gradient(rgba(255, 255, 255, 0.05) 1px, transparent 1px);
  background-size: 42px 42px;
  mask-image: radial-gradient(circle at 50% 30%, #000 0%, transparent 75%);
  -webkit-mask-image: radial-gradient(circle at 50% 30%, #000 0%, transparent 75%);
  opacity: 0.6;
}

/* Canvas particle field lives here */
#fx-canvas { position: absolute; inset: 0; width: 100%; height: 100%; }

@media (prefers-reduced-motion: reduce) {
  .fx-aurora, .fx-fog { animation: none; }
  #fx-canvas { display: none; }
}

/* Custom site-wide background image (admin: Appearance > Theme) — sits behind
   both body::before's gradient wash and .fx-stage's aurora/particle layer. */
.site-bg-layer {
  position: fixed; inset: 0; z-index: -3;
  background-size: cover; background-position: center; background-attachment: fixed;
}

/* Site-wide accent effect (admin: Appearance > Theme) — same visual language
   as the rank/badge/admin effect classes, applied to primary buttons and the
   active top-nav link so the choice is obviously visible across the site. */
@keyframes siteAccentGlow {
  0%, 100% { box-shadow: 0 0 0 1px rgba(255,255,255,0.12), 0 0 10px rgba(var(--accent-rgb), 0.45); }
  50% { box-shadow: 0 0 0 1px rgba(255,255,255,0.22), 0 0 26px rgba(var(--accent-rgb), 0.7); }
}
body.site-fx-glow .btn-primary, body.site-fx-glow .nav-links a.active { animation: siteAccentGlow 2.6s ease-in-out infinite; }
body.site-fx-pulse .btn-primary, body.site-fx-pulse .nav-links a.active { animation: rankPulse 2.2s ease-in-out infinite; }
body.site-fx-shimmer .btn-primary, body.site-fx-shimmer .nav-links a.active { position: relative; overflow: hidden; }
body.site-fx-shimmer .btn-primary::after, body.site-fx-shimmer .nav-links a.active::after {
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(120deg, transparent 30%, rgba(255,255,255,0.3) 50%, transparent 70%);
  transform: translateX(-120%); animation: rankShimmer 2.8s linear infinite;
}

/* Site-wide heading font (admin: Appearance > Theme). */
body.site-font-display h1, body.site-font-display h2, body.site-font-display h3 { font-family: var(--font-display); }
body.site-font-pixel h1, body.site-font-pixel h2, body.site-font-pixel h3 { font-family: var(--font-pixel); }
body.site-font-mono h1, body.site-font-mono h2, body.site-font-mono h3 { font-family: var(--font-mono); }

/* ============================================================
   STARFIELD — the magical night sky under the hero.
   Three parallax layers of star dots + a few twinkling sparkles.
   ============================================================ */
.starfield {
  position: absolute; inset: 0; pointer-events: none; overflow: hidden;
  -webkit-mask-image: linear-gradient(to bottom, #000 45%, transparent 100%);
  mask-image: linear-gradient(to bottom, #000 45%, transparent 100%);
}
.starfield .star-layer {
  position: absolute; inset: -50% 0 0 0; height: 200%;
  background-repeat: repeat;
  will-change: transform;
}
/* Each layer is a repeating field of dots at a different size + speed, which
   reads as depth without a single image request. */
.starfield .sl1 {
  background-image:
    radial-gradient(1px 1px at 12% 18%, rgba(255,255,255,0.9), transparent),
    radial-gradient(1px 1px at 47% 62%, rgba(255,255,255,0.75), transparent),
    radial-gradient(1px 1px at 78% 31%, rgba(255,255,255,0.85), transparent),
    radial-gradient(1px 1px at 63% 88%, rgba(255,255,255,0.6), transparent),
    radial-gradient(1px 1px at 27% 74%, rgba(255,255,255,0.7), transparent);
  background-size: 240px 240px;
  opacity: 0.7;
  animation: starDrift 150s linear infinite;
}
.starfield .sl2 {
  background-image:
    radial-gradient(1.6px 1.6px at 22% 42%, rgba(var(--cyan-rgb),0.85), transparent),
    radial-gradient(1.6px 1.6px at 68% 15%, rgba(255,255,255,0.9), transparent),
    radial-gradient(1.6px 1.6px at 88% 71%, rgba(var(--purple-rgb),0.8), transparent),
    radial-gradient(1.4px 1.4px at 41% 84%, rgba(255,255,255,0.7), transparent);
  background-size: 380px 380px;
  opacity: 0.8;
  animation: starDrift 95s linear infinite reverse;
}
.starfield .sl3 {
  background-image:
    radial-gradient(2.4px 2.4px at 33% 28%, rgba(var(--gold-rgb),0.9), transparent),
    radial-gradient(2.2px 2.2px at 72% 58%, rgba(var(--cyan-rgb),0.9), transparent),
    radial-gradient(2px 2px at 15% 78%, rgba(255,255,255,0.95), transparent);
  background-size: 560px 560px;
  opacity: 0.9;
  animation: starDrift 60s linear infinite;
}
@keyframes starDrift {
  from { transform: translate3d(0, 0, 0); }
  to { transform: translate3d(-240px, 60px, 0); }
}

/* Individually placed sparkles that pulse — the "magic dust" accent. */
.starfield .twinkle {
  position: absolute; width: 3px; height: 3px; border-radius: 50%;
  background: #fff;
  box-shadow: 0 0 8px 2px rgba(var(--cyan-rgb), 0.8);
  opacity: 0;
  animation: twinkle var(--tw-dur, 4s) ease-in-out var(--tw-delay, 0s) infinite;
}
.starfield .twinkle::before,
.starfield .twinkle::after {
  content: ''; position: absolute; left: 50%; top: 50%;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,0.9), transparent);
  transform: translate(-50%, -50%);
}
.starfield .twinkle::before { width: 16px; height: 1px; }
.starfield .twinkle::after { width: 1px; height: 16px; background: linear-gradient(180deg, transparent, rgba(255,255,255,0.9), transparent); }
@keyframes twinkle {
  0%, 100% { opacity: 0; transform: scale(0.4); }
  50% { opacity: 1; transform: scale(1); }
}

/* Slow-turning constellation glow behind the hero copy. */
.starfield .nebula {
  position: absolute; border-radius: 50%; filter: blur(50px); mix-blend-mode: screen;
  animation: nebulaPulse 18s ease-in-out infinite;
}
@keyframes nebulaPulse {
  0%, 100% { opacity: 0.35; transform: scale(1); }
  50% { opacity: 0.6; transform: scale(1.15); }
}

@media (prefers-reduced-motion: reduce) {
  .starfield .star-layer,
  .starfield .twinkle,
  .starfield .nebula { animation: none; }
  .starfield .twinkle { opacity: 0.85; }
}

/* ---- Floating orbs used inside the hero ---- */
.orb { position: absolute; border-radius: 50%; filter: blur(1px); pointer-events: none; will-change: transform; }
.orb::after { content: ''; position: absolute; inset: 0; border-radius: 50%; box-shadow: 0 0 20px 6px currentColor; opacity: 0.5; }
@keyframes floaty { 0%,100% { transform: translateY(0); } 50% { transform: translateY(-22px); } }

/* ============================================================
   VOXEL / MINECRAFT blocks
   ============================================================ */
.voxel { display: inline-block; pointer-events: none; filter: drop-shadow(0 10px 16px rgba(0,0,0,0.5)); }
.voxel svg { width: 100%; height: 100%; overflow: visible; image-rendering: auto; }

/* Floating decorative blocks (in hero + backgrounds) */
.float-block {
  position: absolute; pointer-events: none; will-change: transform;
  animation: blockFloat var(--dur, 7s) ease-in-out infinite;
}
.float-block .voxel svg { filter: drop-shadow(0 0 14px var(--ore-glow, rgba(var(--green-rgb),0.35))); }
@keyframes blockFloat {
  0%, 100% { transform: translateY(0) rotate(var(--rot, 0deg)); }
  50% { transform: translateY(-26px) rotate(calc(var(--rot, 0deg) + 4deg)); }
}

/* Background drifting voxel field */
.fx-voxels { position: absolute; inset: 0; pointer-events: none; opacity: 0.5; }
.fx-voxels .float-block { opacity: 0.35; }

/* Pixel-edged glow for wordmark blocks */
.pixel-mark { image-rendering: pixelated; }

@media (prefers-reduced-motion: reduce) {
  .float-block { animation: none; }
}

/* ---- Hover lift utility ---- */
.lift { transition: transform var(--t) var(--ease), box-shadow var(--t) var(--ease), border-color var(--t) var(--ease); }
.lift:hover { transform: translateY(-6px); box-shadow: var(--sh-lg); }

/* ---- Animated gradient border (wrap an element) ---- */
.glow-border { position: relative; }
.glow-border::before {
  content: ''; position: absolute; inset: -1px; border-radius: inherit; padding: 1px;
  pointer-events: none; /* critical: must not intercept clicks/focus on inner inputs */
  background: linear-gradient(120deg, rgba(var(--green-rgb), 0.6), rgba(var(--purple-rgb), 0.6), rgba(var(--cyan-rgb), 0.5), rgba(var(--green-rgb), 0.6));
  background-size: 300% 300%;
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor; mask-composite: exclude;
  opacity: 0; transition: opacity var(--t) var(--ease);
  animation: borderFlow 6s linear infinite;
}
.glow-border:hover::before, .glow-border.always::before { opacity: 1; }
@keyframes borderFlow { from { background-position: 0% 50%; } to { background-position: 300% 50%; } }

/* ---- Scroll reveal ---- */
.reveal { opacity: 0; transform: translateY(26px); transition: opacity 0.7s var(--ease), transform 0.7s var(--ease); }
.reveal.in { opacity: 1; transform: none; }
.reveal.d1 { transition-delay: 0.08s; } .reveal.d2 { transition-delay: 0.16s; }
.reveal.d3 { transition-delay: 0.24s; } .reveal.d4 { transition-delay: 0.32s; }
@media (prefers-reduced-motion: reduce) { .reveal { opacity: 1; transform: none; } }

/* ---- Shimmering text (logo / headings) ---- */
.shimmer {
  background: linear-gradient(100deg, var(--text) 30%, var(--green-bright) 45%, var(--purple-bright) 55%, var(--text) 70%);
  background-size: 200% auto;
  -webkit-background-clip: text; background-clip: text;
  color: transparent;
  animation: shimmer 6s linear infinite;
}
@keyframes shimmer { to { background-position: 200% center; } }

/* ---- Pulsing live dot ---- */
.live-dot { position: relative; width: 9px; height: 9px; border-radius: 50%; background: var(--green); }
.live-dot::before {
  content: ''; position: absolute; inset: 0; border-radius: 50%;
  background: var(--green); animation: livePulse 1.8s ease-out infinite;
}
@keyframes livePulse { 0% { transform: scale(1); opacity: 0.7; } 100% { transform: scale(3.4); opacity: 0; } }

/* ---- Spinner ---- */
.spinner { width: 18px; height: 18px; border-radius: 50%; border: 2px solid rgba(255, 255, 255, 0.2); border-top-color: var(--green); animation: spin 0.7s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }
