/* ============================================
   CAVE SCENE v2 -- Level 2's living Crystal Cave
   Used by game/js/cave-scene.js on top of css/scene-kit.css (stage,
   layers, props, generic reactions, particles, HUD). This file holds the
   cave look: the cool haze, crystal glow, the pokable reactions, Jasper's
   crystal (cracks, shatter, the freed golem), the balance-scale cue, the
   moths and the warm "light restored" finale.
   ============================================ */

.fs-root.fs-cave { background: #060812; }

/* Cool haze between the far clusters and the floor (far layer) */
.cs-haze {
  position: absolute;
  left: 0; right: 0;
  top: 240px;
  height: 160px;
  background: linear-gradient(to bottom,
    rgba(40, 90, 130, 0) 0%,
    rgba(40, 90, 130, 0.36) 55%,
    rgba(30, 60, 100, 0.5) 85%,
    rgba(30, 60, 100, 0) 100%);
  pointer-events: none;
}

/* Far clusters pushed back by tone; near pieces darker (crystals are the only light) */
.fs-cave .fs-layer-far .fs-prop img {
  filter: brightness(0.5) saturate(0.7) blur(0.4px);
  opacity: 0.85;
}
.fs-cave .fs-layer-fore .fs-prop img {
  filter: brightness(0.55) saturate(0.9);
}

/* ---- Crystals: a resting glow, and a flash when tapped ---- */
.fs-cave .cs-crystal .fs-body > img {
  filter: drop-shadow(0 0 6px rgba(150, 240, 255, 0.35));
}
@keyframes cs-glow-pulse {
  0%   { filter: brightness(1) drop-shadow(0 0 6px rgba(200, 255, 255, 0.4)); }
  30%  { filter: brightness(1.7) drop-shadow(0 0 24px rgba(230, 255, 255, 0.95)); }
  100% { filter: brightness(1) drop-shadow(0 0 6px rgba(200, 255, 255, 0.4)); }
}
.fs-body.glow-pulse > img { animation: cs-glow-pulse 0.9s ease-out; }
.fs-body.glow-run > img   { animation: cs-glow-pulse 1.5s ease-out; }

/* Phosphorescent moss brightens */
@keyframes cs-moss-bright {
  0%, 100% { filter: brightness(1); }
  25%      { filter: brightness(1.9) saturate(1.4) drop-shadow(0 0 18px rgba(120, 255, 220, 0.9)); }
  70%      { filter: brightness(1.4) drop-shadow(0 0 10px rgba(120, 255, 220, 0.6)); }
}
.fs-body.moss-bright > img { animation: cs-moss-bright 1.6s ease-out; }

/* The snail peeks out */
@keyframes cs-peek {
  0%, 100% { transform: translateX(0) scale(1); }
  25%      { transform: translateX(4px) scale(1.06, 0.94); }
  55%      { transform: translateX(7px) scale(0.96, 1.08) rotate(-4deg); }
  80%      { transform: translateX(2px) scale(1.02, 0.98); }
}
.fs-body.peek { animation: cs-peek 0.9s ease-out; }

/* Geodes: shake, split, and the gem inside keeps glowing once found */
@keyframes cs-crack-shake {
  0%, 100% { transform: translate(0, 0); }
  20%      { transform: translate(-3px, 1px) rotate(-2deg); }
  40%      { transform: translate(3px, -1px) rotate(2deg); }
  60%      { transform: translate(-2px, 0) rotate(-1deg); }
  80%      { transform: translate(2px, 0) rotate(1deg); }
}
.fs-body.crack-shake { animation: cs-crack-shake 0.45s ease-in-out; }
.fs-prop.open .fs-body > img { filter: drop-shadow(0 0 10px rgba(255, 255, 255, 0.5)); }
.fs-prop.found .fs-body > img { animation: cs-gem-glow 2.4s ease-in-out infinite; }
@keyframes cs-gem-glow {
  0%, 100% { filter: brightness(1) drop-shadow(0 0 8px rgba(255, 255, 255, 0.45)); }
  50%      { filter: brightness(1.2) drop-shadow(0 0 16px rgba(255, 255, 255, 0.85)); }
}
.cs-gem-rise {
  position: absolute;
  height: 44px;
  width: auto;
  image-rendering: pixelated;
  pointer-events: none;
  filter: drop-shadow(0 0 10px rgba(255, 255, 255, 0.8));
}

/* A water drop from a stalactite */
.cs-drop {
  position: absolute;
  width: 6px;
  height: 10px;
  border-radius: 50% 50% 50% 50% / 40% 40% 60% 60%;
  background: linear-gradient(to bottom, #e8fbff, #8fd8ff);
  box-shadow: 0 0 4px rgba(180, 240, 255, 0.8);
  pointer-events: none;
}

/* The second pool is magenta-lit */
.fs-prop.tint-magenta .fs-body > img { filter: hue-rotate(120deg) saturate(1.1); }

/* Moths */
.cs-moth img { filter: drop-shadow(0 0 6px rgba(220, 255, 255, 0.6)); }

/* ---- The balance scale on its plinth ---- */
.cs-scale .fs-body > img { filter: drop-shadow(0 0 8px rgba(120, 220, 255, 0.35)); }
.cs-scale.cs-scale-pulse .fs-body > img { animation: cs-scale-pulse 2s ease-in-out infinite; }
@keyframes cs-scale-pulse {
  0%, 100% { filter: drop-shadow(0 0 12px rgba(100, 200, 255, 0.5)); transform: scale(1); }
  50%      { filter: drop-shadow(0 0 30px rgba(150, 220, 255, 0.95)) brightness(1.25); transform: scale(1.06); }
}

/* ---- Jasper: the great crystal, its cracks, the shatter, the freed golem ---- */
.cs-jasper .fs-body { display: flex; align-items: flex-end; justify-content: center; }
/* The kit sizes every prop image from --h and forces display:block; Jasper's
   two images are sized here and honour `hidden` (only one shows at a time) */
.cs-jasper .fs-body > img.cs-jasper-free { height: 230px; }
.cs-jasper .fs-body > img[hidden], .cs-jasper .cs-crystal-wrap[hidden] { display: none !important; }
.cs-crystal-wrap { position: relative; }
.cs-jasper-crystal {
  display: block;
  height: 300px;
  width: auto;
  image-rendering: pixelated;
  filter: drop-shadow(0 0 16px rgba(120, 220, 255, 0.45));
  animation: cs-crystal-breathe 4s ease-in-out infinite;
}
@keyframes cs-crystal-breathe {
  0%, 100% { filter: drop-shadow(0 0 14px rgba(120, 220, 255, 0.4)); }
  50%      { filter: drop-shadow(0 0 22px rgba(150, 230, 255, 0.6)); }
}
.cs-jasper-free {
  display: block;
  height: 230px;
  width: auto;
  image-rendering: pixelated;
  transform-origin: 50% 100%;
  filter: drop-shadow(0 6px 8px rgba(0, 0, 0, 0.4));
  animation: cs-breathe 3.6s ease-in-out infinite;
}
@keyframes cs-breathe {
  0%, 100% { transform: scaleY(1); }
  50%      { transform: scaleX(1.008) scaleY(1.016) translateY(-0.4%); }
}
/* Crack lines drawn over the crystal; `on` lines light up as slots are solved */
.cs-crack-lines { position: absolute; inset: 0; pointer-events: none; }
.cs-crack-line {
  position: absolute;
  height: 3px;
  background: linear-gradient(90deg, rgba(255, 255, 255, 0), #fff 30%, #d8fbff 70%, rgba(255, 255, 255, 0));
  box-shadow: 0 0 8px 2px rgba(200, 250, 255, 0.95);
  transform-origin: 0 50%;
  opacity: 0;
  transition: opacity 0.5s ease;
}
.cs-crack-line.on { opacity: 0.85; animation: cs-crack-flicker 2.2s ease-in-out infinite; }
@keyframes cs-crack-flicker { 0%, 100% { opacity: 0.55; } 50% { opacity: 1; } }
/* Light leaking through the loosening crystal, escalating with each slot */
.cs-jasper.cs-crack-1 .cs-jasper-crystal { animation: cs-flicker-1 4.2s ease-in-out infinite; }
.cs-jasper.cs-crack-2 .cs-jasper-crystal { animation: cs-flicker-2 3.2s ease-in-out infinite; }
.cs-jasper.cs-crack-3 .cs-jasper-crystal { animation: cs-flicker-3 2.4s ease-in-out infinite; }
.cs-jasper.cs-crack-4 .cs-jasper-crystal { animation: cs-flicker-4 1.7s ease-in-out infinite; }
@keyframes cs-flicker-1 { 0%, 86%, 100% { filter: brightness(1) drop-shadow(0 0 14px rgba(120, 220, 255, 0.4)); } 93% { filter: brightness(1.12) drop-shadow(0 0 22px rgba(154, 210, 255, 0.6)); } }
@keyframes cs-flicker-2 { 0%, 84%, 100% { filter: brightness(1) drop-shadow(0 0 14px rgba(120, 220, 255, 0.4)); } 92% { filter: brightness(1.18) drop-shadow(0 0 26px rgba(154, 210, 255, 0.7)); } }
@keyframes cs-flicker-3 { 0%, 82%, 100% { filter: brightness(1.02) drop-shadow(0 0 16px rgba(120, 220, 255, 0.45)); } 91% { filter: brightness(1.25) drop-shadow(0 0 30px rgba(180, 230, 255, 0.8)); } }
@keyframes cs-flicker-4 { 0%, 80%, 100% { filter: brightness(1.05) drop-shadow(0 0 18px rgba(154, 210, 255, 0.5)); } 90% { filter: brightness(1.35) drop-shadow(0 0 36px rgba(205, 243, 255, 0.9)); } }
/* One-shot flash the moment a new crack lands, and when the crystal is poked */
.cs-jasper-body.cs-crack-pulse { animation: cs-crack-pulse 0.7s ease-out; }
@keyframes cs-crack-pulse {
  0%   { filter: brightness(1); }
  25%  { filter: brightness(1.5) drop-shadow(0 0 24px rgba(205, 243, 255, 0.8)); }
  100% { filter: brightness(1); }
}
.cs-jasper-body.cs-pulse .cs-jasper-crystal { animation: cs-glow-pulse 1s ease-out; }
/* Shatter: flash of light, the crystal burns out, shards fly, Jasper glitches in */
.cs-flash {
  position: absolute;
  inset: 0;
  background: radial-gradient(ellipse at 56% 60%, rgba(255, 255, 255, 0.95) 0%, rgba(200, 250, 255, 0.6) 30%, rgba(255, 200, 255, 0) 70%);
  mix-blend-mode: screen;
  animation: cs-flash 1.3s ease-out forwards;
  pointer-events: none;
}
@keyframes cs-flash { 0% { opacity: 0; } 12% { opacity: 1; } 100% { opacity: 0; } }
.cs-shard {
  position: absolute;
  pointer-events: none;
  clip-path: polygon(50% 0, 100% 40%, 70% 100%, 20% 85%, 0 35%);
  box-shadow: 0 0 8px rgba(200, 250, 255, 0.9);
}
.cs-jasper.cs-shattering .cs-jasper-crystal { animation: cs-shatter-out 0.5s ease-in forwards; }
@keyframes cs-shatter-out {
  0%   { opacity: 1; transform: scale(1); filter: brightness(1.2); }
  60%  { opacity: 1; transform: scale(1.08); filter: brightness(3); }
  100% { opacity: 0; transform: scale(1.15); filter: brightness(4); }
}
.cs-jasper.cs-freed .cs-jasper-free { animation: cs-jasper-in 1.3s ease-out, cs-breathe 3.6s ease-in-out 1.3s infinite; }
@keyframes cs-jasper-in {
  0%   { clip-path: inset(100% 0 0 0); filter: drop-shadow(0 0 10px rgba(120, 220, 255, 0.9)) brightness(2.2) saturate(0); }
  60%  { clip-path: inset(0 0 0 0); filter: drop-shadow(0 0 12px rgba(120, 220, 255, 0.8)) brightness(1.6) saturate(0.4); }
  100% { clip-path: inset(0 0 0 0); filter: drop-shadow(0 6px 8px rgba(0, 0, 0, 0.4)) brightness(1) saturate(1); }
}

/* ---- Atmosphere: breathing pools of crystal light, cool motes and sparks ---- */
.cs-glow {
  position: absolute;
  top: 110px;
  width: 260px;
  height: 420px;
  border-radius: 50%;
  transform: translateX(-50%);
  filter: blur(30px);
  mix-blend-mode: screen;
  opacity: 0.35;
  animation: cs-glow-breathe var(--dur, 7s) ease-in-out infinite;
  animation-delay: var(--delay, 0s);
  transition: opacity 3s ease, background 3s ease;
}
.cs-glow.cyan    { background: radial-gradient(circle, rgba(90, 230, 255, 0.55), rgba(90, 230, 255, 0) 70%); }
.cs-glow.magenta { background: radial-gradient(circle, rgba(255, 110, 230, 0.5), rgba(255, 110, 230, 0) 70%); }
.cs-glow.white   { background: radial-gradient(circle, rgba(230, 245, 255, 0.45), rgba(230, 245, 255, 0) 70%); }
@keyframes cs-glow-breathe { 0%, 100% { opacity: 0.22; } 50% { opacity: 0.5; } }
.fs-mote.cs-mote { background: rgba(200, 245, 255, 0.9); box-shadow: 0 0 4px rgba(160, 230, 255, 0.8); }
.fs-firefly.cs-spark {
  background: radial-gradient(circle, #ffffff 0%, #9af0ff 40%, rgba(150, 240, 255, 0.4) 65%, transparent 100%);
  box-shadow: 0 0 10px 3px rgba(150, 240, 255, 0.7);
}
.fs-cave .fs-vignette {
  background:
    linear-gradient(to bottom, rgba(2, 4, 10, 0.6) 0%, rgba(2, 4, 10, 0) 26%),
    radial-gradient(ellipse at 50% 55%, rgba(0, 0, 0, 0) 50%, rgba(2, 4, 12, 0.6) 100%);
}

/* "This way": the arrow that leads on glows */
.fs-arrow.glow {
  border-color: var(--gold-bright, #ffe888);
  box-shadow: 0 0 18px rgba(255, 232, 136, 0.75);
  animation: cs-arrow-glow 0.9s ease-in-out infinite;
}
@keyframes cs-arrow-glow { 0%, 100% { opacity: 0.75; transform: translateY(-50%) scale(1); } 50% { opacity: 1; transform: translateY(-50%) scale(1.12); } }

/* ---- Light restored (correct code): warm golden light floods the cave ---- */
.cs-warm {
  position: absolute;
  inset: 0;
  background: radial-gradient(ellipse at 50% 42%, rgba(255, 200, 90, 0.5) 0%, rgba(255, 170, 60, 0.32) 45%, rgba(255, 140, 40, 0.12) 100%);
  mix-blend-mode: screen;
  opacity: 0;
  transition: opacity 3s ease;
  pointer-events: none;
}
.fs-cave .fs-backdrop img, .fs-cave .fs-ground img, .fs-cave .fs-layer-far .fs-prop img,
.fs-cave .fs-layer-fore .fs-prop img, .fs-cave .cs-haze, .fs-cave .fs-vignette { transition: filter 3s ease, opacity 3s ease; }
.fs-cave.light-restored .cs-warm { opacity: 1; }
.fs-cave.light-restored .fs-backdrop img { filter: brightness(1.05) sepia(0.55) saturate(1.3); }
.fs-cave.light-restored .fs-ground img { filter: brightness(1.1) sepia(0.45) saturate(1.2); }
.fs-cave.light-restored .fs-layer-far .fs-prop img { filter: brightness(0.85) sepia(0.4); opacity: 1; }
.fs-cave.light-restored .fs-layer-fore .fs-prop img { filter: brightness(0.85) sepia(0.3); }
.fs-cave.light-restored .cs-haze { opacity: 0; }
.fs-cave.light-restored .fs-vignette { opacity: 0.6; }
.fs-cave.light-restored .cs-glow { opacity: 0.55; background: radial-gradient(circle, rgba(255, 190, 90, 0.6), rgba(255, 190, 90, 0) 70%); }

@media (prefers-reduced-motion: reduce) {
  .cs-glow, .cs-jasper-crystal, .cs-jasper-free, .cs-crack-line, .cs-scale-pulse .fs-body > img, .fs-arrow.glow { animation: none !important; }
}
