/* kovil.mu coming soon - scene choreography.
   Animations only run on live scenes (.scene.is-live), restart each time a
   scene comes back, and freeze together when playback is paused. Everything
   animates transform / opacity only, so it stays on the compositor. */

/* -------------------------------------------------- shared atmosphere */

.is-live .fx-sun {
  animation: sun-breathe 6s ease-in-out infinite alternate;
}

[data-scene='awakening'].is-live .fx-sun {
  animation: sun-rise 6.5s cubic-bezier(.3, 0, .3, 1) both, sun-breathe 5s ease-in-out 6.5s infinite alternate;
}

@keyframes sun-rise {
  0% { opacity: 0; transform: translateY(6%) scale(0.55); }
  45% { opacity: 0.85; }
  100% { opacity: 1; transform: translateY(0) scale(1); }
}

@keyframes sun-breathe {
  from { opacity: 0.85; transform: scale(0.96); }
  to { opacity: 1; transform: scale(1.04); }
}

.is-live .fx-rays {
  animation: rays-in 4.5s ease-out 0.8s both;
}

.is-live .fx-rays-spin {
  animation: spin 90s linear infinite;
}

@keyframes rays-in {
  from { opacity: 0; transform: scale(0.7); }
  to { opacity: var(--o); transform: scale(1); }
}

@keyframes spin {
  to { transform: rotate(360deg); }
}

.is-live .fx-shafts {
  animation: shafts 7s ease-in-out infinite alternate;
}

@keyframes shafts {
  from { opacity: calc(var(--o) * 0.55); transform: rotate(var(--angle)) translateX(-2%); }
  to { opacity: var(--o); transform: rotate(var(--angle)) translateX(2%); }
}

.is-live .fx-mist {
  animation: mist-drift var(--dur) linear infinite alternate;
}

@keyframes mist-drift {
  from { transform: translate3d(calc(-6% * var(--dir)), 0, 0); }
  to { transform: translate3d(calc(6% * var(--dir)), -4%, 0); }
}

.is-live .fx-flame {
  animation: flicker var(--dur) ease-in-out var(--delay) infinite;
}

@keyframes flicker {
  0%, 100% { opacity: 0.85; transform: scale(1); }
  18% { opacity: 1; transform: scale(1.08, 1.14); }
  37% { opacity: 0.72; transform: scale(0.94, 0.9); }
  56% { opacity: 0.95; transform: scale(1.04, 1.1); }
  78% { opacity: 0.8; transform: scale(0.97); }
}

.is-live .fx-puff {
  animation: smoke-rise var(--dur) ease-out var(--delay) infinite;
}

@keyframes smoke-rise {
  0% { opacity: 0; transform: translate3d(0, 20%, 0) scale(0.5, 0.6); }
  20% { opacity: 0.85; }
  60% { opacity: 0.55; transform: translate3d(calc(var(--sway) * 0.6), -60%, 0) scale(1.2, 1.4) rotate(8deg); }
  100% { opacity: 0; transform: translate3d(var(--sway), -140%, 0) scale(1.9, 2.2) rotate(-6deg); }
}

/* --------------------------------------------------- 1. awakening */

.is-live .fx-veil {
  animation: veil-lift var(--dur) cubic-bezier(.45, 0, .3, 1) both;
}

@keyframes veil-lift {
  0% { opacity: 0.94; }
  100% { opacity: 0; }
}

/* ------------------------------------------------------ 2. the bell */

/* A damped pendulum around the chain's pivot - the cut-out bell moves over a
   painted-out background, so this is real object motion, not a frame tilt. */
.is-live .fx-bell {
  animation: bell-swing 7.2s linear 0.4s both;
}

@keyframes bell-swing {
  0% { transform: rotate(0deg); animation-timing-function: cubic-bezier(.33, 0, .67, 1); }
  9% { transform: rotate(3.3deg); animation-timing-function: cubic-bezier(.45, 0, .55, 1); }
  22% { transform: rotate(-2.9deg); animation-timing-function: cubic-bezier(.45, 0, .55, 1); }
  35% { transform: rotate(2.4deg); animation-timing-function: cubic-bezier(.45, 0, .55, 1); }
  48% { transform: rotate(-1.9deg); animation-timing-function: cubic-bezier(.45, 0, .55, 1); }
  61% { transform: rotate(1.45deg); animation-timing-function: cubic-bezier(.45, 0, .55, 1); }
  74% { transform: rotate(-1deg); animation-timing-function: cubic-bezier(.45, 0, .55, 1); }
  87% { transform: rotate(0.6deg); animation-timing-function: cubic-bezier(.45, 0, .55, 1); }
  100% { transform: rotate(-0.3deg); }
}

.is-live .fx-bell-glint {
  animation: glint 3.4s ease-in-out 0.9s infinite;
}

@keyframes glint {
  0% { background-position: 100% 0; opacity: 0; }
  20% { opacity: 1; }
  70% { opacity: 1; }
  100% { background-position: 0% 0; opacity: 0; }
}

/* ---------------------------------------------------- 3. the doors */

/* 0-1.4s closed with light at the seam; 1.4-6s the doors swing inward (away
   from the viewer) on their outer hinges in 3D; the light then floods the frame.
   In CSS a negative rotateY on a left-hinged leaf turns its free edge away. */
.is-live .door--left {
  animation: door-left var(--scene-dur, 8s) cubic-bezier(.5, 0, .3, 1) both;
}

.is-live .door--right {
  animation: door-right var(--scene-dur, 8s) cubic-bezier(.5, 0, .3, 1) both;
}

@keyframes door-left {
  0%, 17% { transform: rotateY(0deg) scaleX(var(--closed)); }
  32% { transform: rotateY(-14deg) scaleX(1.02); }
  75% { transform: rotateY(-72deg) scaleX(1); }
  100% { transform: rotateY(-78deg) scaleX(1); }
}

@keyframes door-right {
  0%, 17% { transform: rotateY(0deg) scaleX(var(--closed)); }
  32% { transform: rotateY(14deg) scaleX(1.02); }
  75% { transform: rotateY(72deg) scaleX(1); }
  100% { transform: rotateY(78deg) scaleX(1); }
}

.is-live .door-shade {
  animation: door-shade var(--scene-dur, 8s) ease-in-out both;
}

@keyframes door-shade {
  0%, 17% { opacity: 0; }
  75%, 100% { opacity: 1; }
}

.is-live .door-seam {
  animation: seam var(--scene-dur, 8s) ease-in-out both;
}

@keyframes seam {
  0% { opacity: 0.25; transform: scaleX(0.6); }
  8% { opacity: 0.75; transform: scaleX(1); }
  12% { opacity: 0.55; }
  17% { opacity: 1; transform: scaleX(1.3); }
  30% { opacity: 0; transform: scaleX(3); }
  100% { opacity: 0; }
}

.is-live .door-light-core {
  animation: door-light var(--scene-dur, 8s) ease-in both;
}

@keyframes door-light {
  0%, 17% { opacity: 0.45; transform: scale(0.55, 0.8); }
  70% { opacity: 0.95; transform: scale(1.1, 1); }
  100% { opacity: 1; transform: scale(1.6, 1.15); }
}

.is-live .door-rays {
  animation: door-rays var(--scene-dur, 8s) ease-in-out both;
}

@keyframes door-rays {
  0%, 12% { opacity: 0.25; transform: scaleX(0.08); }
  20% { opacity: 0.55; transform: scaleX(0.12); }
  60% { opacity: 0.85; transform: scaleX(0.7); }
  100% { opacity: 1; transform: scaleX(1.2); }
}

.is-live .door-floor {
  animation: door-floor var(--scene-dur, 8s) ease-in-out both;
}

@keyframes door-floor {
  0%, 15% { opacity: 0.3; transform: scaleX(0.12); }
  70% { opacity: 0.9; transform: scaleX(0.8); }
  100% { opacity: 1; transform: scaleX(1.1); }
}

/* ---------------------------------------------------------- loader */

.loader-flame {
  transform-origin: 50% 90%;
  animation: lamp-flicker 1.8s ease-in-out infinite;
}

@keyframes lamp-flicker {
  0%, 100% { transform: scale(1, 1); opacity: 0.95; }
  30% { transform: scale(0.94, 1.06); opacity: 1; }
  60% { transform: scale(1.04, 0.96); opacity: 0.88; }
}

/* Waiting for the tap that enables sound: a gentle beckoning pulse. */
[data-load='waiting'] .loader-ring {
  animation: beckon 1.6s ease-in-out infinite;
}

@keyframes beckon {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.06); }
}

/* ---------------------------------------------------------- finale */

/* Staged reveal: light, logo, words, date, countdown. */
[data-stage='finale'] .finale-logo::before {
  animation: halo-in 2.4s cubic-bezier(.2, .7, .2, 1) both, halo-breathe 5s ease-in-out 2.4s infinite alternate;
}

[data-stage='finale'] .finale-logo::after {
  animation: halo-in 3s ease-out 0.3s both, halo-spin 80s linear infinite;
}

[data-stage='finale'] .finale-logo img {
  animation: logo-in 1.8s cubic-bezier(.2, .8, .2, 1) 0.3s both;
}

[data-stage='finale'] .finale-ta { animation: rise-in 1.2s ease-out 1.4s both; }
[data-stage='finale'] .finale-en { animation: rise-in 1.2s ease-out 1.7s both; }
[data-stage='finale'] .finale-soon { animation: rise-in 1.2s ease-out 2.3s both; }
[data-stage='finale'] .finale-date { animation: date-in 1.4s cubic-bezier(.2, .8, .2, 1) 2.7s both; }
[data-stage='finale'] .countdown { animation: rise-in 1.2s ease-out 3.4s both; }
[data-stage='finale'] .finale-replay { animation: rise-in 1s ease-out 4.2s both; }

@keyframes halo-in {
  from { opacity: 0; transform: translate(-50%, -50%) scale(0.3); }
  to { transform: translate(-50%, -50%) scale(1); }
}

@keyframes halo-breathe {
  from { transform: translate(-50%, -50%) scale(0.97); }
  to { transform: translate(-50%, -50%) scale(1.04); }
}

@keyframes halo-spin {
  to { transform: translate(-50%, -50%) rotate(360deg); }
}

@keyframes logo-in {
  from { opacity: 0; transform: scale(0.82); filter: blur(10px) drop-shadow(0 6px 22px rgba(120, 60, 0, 0.35)); }
  to { opacity: 1; transform: scale(1); filter: blur(0) drop-shadow(0 6px 22px rgba(120, 60, 0, 0.35)); }
}

@keyframes rise-in {
  from { opacity: 0; transform: translateY(14px); }
  to { opacity: 1; transform: translateY(0); }
}

@keyframes date-in {
  from { opacity: 0; transform: scale(1.25); }
  to { opacity: 1; transform: scale(1); }
}

.cd-num.tick {
  animation: tick 0.5s ease-out;
}

@keyframes tick {
  from { transform: translateY(-6px); opacity: 0.4; }
  to { transform: translateY(0); opacity: 1; }
}

/* ------------------------------------------------------- particles */

.is-live .ember {
  animation: ember-float var(--dur) linear var(--delay) infinite;
}

@keyframes ember-float {
  0% { opacity: 0; transform: translate3d(0, 0, 0) scale(0.6); }
  15% { opacity: 0.9; }
  50% { transform: translate3d(calc(var(--dx) * 0.5 + 12px), -14vh, 0) scale(1); }
  80% { opacity: 0.6; }
  100% { opacity: 0; transform: translate3d(var(--dx), -30vh, 0) scale(0.7); }
}

.is-live .petal {
  animation: petal-fall var(--dur) linear var(--delay) infinite;
}

@keyframes petal-fall {
  0% { opacity: 0; transform: translate3d(0, 0, 0) rotate3d(1, 0.6, 0.2, 0deg); }
  8% { opacity: 0.95; }
  35% { transform: translate3d(calc(var(--dx) * 0.4 + 30px), 38vh, 0) rotate3d(1, 0.6, 0.2, calc(var(--spin) * 0.4)); }
  70% { transform: translate3d(calc(var(--dx) * 0.7 - 20px), 76vh, 0) rotate3d(1, 0.6, 0.2, calc(var(--spin) * 0.7)); }
  90% { opacity: 0.9; }
  100% { opacity: 0; transform: translate3d(var(--dx), 110vh, 0) rotate3d(1, 0.6, 0.2, var(--spin)); }
}

/* ------------------------------------------------------ pause / tab */

[data-playback='paused'] .scene * {
  animation-play-state: paused !important;
}

/* --------------------------------------------------- lighter mobile */

@media (max-width: 700px), (max-height: 500px) {
  .fx-rays-spin,
  .is-live .fx-rays-spin {
    animation: none;
  }

  .fx-mist:nth-of-type(n + 2) {
    display: none;
  }

  .ember {
    box-shadow: none;
  }
}

/* -------------------------------------------------- reduced motion */

/* A still, composed frame per scene: no camera, swing, doors or particles.
   The original artwork is shown as painted (doors ajar, bell at rest). */
@media (prefers-reduced-motion: reduce) {
  .scene *,
  .scene *::before,
  .scene *::after,
  .loader-flame,
  .loader-ring,
  .finale *,
  .finale *::before,
  .finale *::after {
    animation: none !important;
  }

  .particles,
  .fx-doors,
  .fx-veil,
  .fx-puff,
  .fx-rays {
    display: none;
  }

  .scene,
  .scene.is-live {
    transition-duration: 0.5s;
  }

  .caption-ta,
  .caption-en,
  .saying {
    transform: none !important;
    filter: none !important;
  }
}
