/* ==========================================================================
   ANIMATION.CSS — Keyframes & kelas animasi
   KKN Tematik Universitas Nurtanio Bandung 2026 · Kelompok 07 · Desa Cipada
   --------------------------------------------------------------------------
   Berkas ini menampung SELURUH @keyframes dan kelas bantu animasi.
   GSAP menangani animasi berbasis scroll (lihat js/animation.js);
   CSS di sini menangani gerak ambien yang terus berjalan (kabut, awan,
   burung, daun) serta animasi masuk sebagai fallback tanpa JavaScript.
   --------------------------------------------------------------------------
   DAFTAR ISI
   01. Fallback tanpa JS
   02. Reveal & Fade (GSAP + CSS)
   03. Text Split
   04. Atmosfer: kabut, awan, sinar, matahari
   05. Burung terbang
   06. Daun melayang
   07. Loader & indikator
   08. Mikro-interaksi (ripple, pulse, magnetic, eq)
   09. Ikon cuaca
   10. Peta & penanda
   11. Reduce Motion (prefers-reduced-motion)
   ========================================================================== */

/* ==========================================================================
   01. FALLBACK TANPA JS
   Elemen ber-[data-anim] disembunyikan oleh GSAP saat JS aktif.
   Bila JS mati, .no-js membuat semuanya langsung tampil.
   ========================================================================== */
.no-js [data-anim] {
  opacity: 1 !important;
  transform: none !important;
  clip-path: none !important;
}

/* Saat JS aktif, GSAP mengatur visibilitas. Kelas ini dipasang oleh
   main.js pada <html> segera setelah skrip berjalan. */
.js [data-anim]:not(.is-revealed) {
  will-change: transform, opacity;
}

/* ==========================================================================
   02. REVEAL & FADE
   Dipakai sebagai animasi CSS mandiri (mis. hasil kuis, feedback).
   ========================================================================== */
@keyframes fade-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}

@keyframes fade-up {
  from { opacity: 0; transform: translateY(22px); }
  to   { opacity: 1; transform: translateY(0); }
}

@keyframes fade-down {
  from { opacity: 0; transform: translateY(-18px); }
  to   { opacity: 1; transform: translateY(0); }
}

@keyframes fade-left {
  from { opacity: 0; transform: translateX(28px); }
  to   { opacity: 1; transform: translateX(0); }
}

@keyframes fade-right {
  from { opacity: 0; transform: translateX(-28px); }
  to   { opacity: 1; transform: translateX(0); }
}

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

@keyframes zoom-out {
  from { opacity: 0; transform: scale(1.07); }
  to   { opacity: 1; transform: scale(1); }
}

/* Reveal ala Apple: masker naik dari bawah */
@keyframes reveal-up {
  from { clip-path: inset(100% 0 0 0); transform: translateY(28px); }
  to   { clip-path: inset(0 0 0 0);    transform: translateY(0); }
}

/* Kelas siap pakai */
.a-fade-in   { animation: fade-in   620ms var(--ease-soft) both; }
.a-fade-up   { animation: fade-up   720ms var(--ease-out)  both; }
.a-fade-down { animation: fade-down 640ms var(--ease-out)  both; }
.a-zoom-in   { animation: zoom-in   680ms var(--ease-out)  both; }
.a-reveal    { animation: reveal-up 900ms var(--ease-out)  both; }

/* Penundaan bertingkat untuk daftar/kisi */
.a-d1 { animation-delay: 80ms; }
.a-d2 { animation-delay: 160ms; }
.a-d3 { animation-delay: 240ms; }
.a-d4 { animation-delay: 320ms; }
.a-d5 { animation-delay: 400ms; }
.a-d6 { animation-delay: 480ms; }

/* ==========================================================================
   03. TEXT SPLIT
   js/animation.js memecah judul menjadi <span class="word"><span class="ch">
   Kelas di bawah menyiapkan kondisi awal & transisi.
   ========================================================================== */
.split-line { display: block; overflow: hidden; }
/* Masker per kata. padding/margin negatif memberi ruang bagi ekor huruf
   (g, y, j) sehingga tidak terpotong oleh overflow: hidden. */
.split-word {
  display: inline-block;
  overflow: hidden;
  vertical-align: top;
  padding-bottom: 0.14em;
  margin-bottom: -0.14em;
}
.split-char {
  display: inline-block;
  will-change: transform, opacity;
}
/* Fallback CSS bila GSAP gagal dimuat */
.split-fallback .split-char {
  animation: char-rise 760ms var(--ease-out) both;
}
@keyframes char-rise {
  from { opacity: 0; transform: translateY(100%) rotateX(-40deg); }
  to   { opacity: 1; transform: translateY(0) rotateX(0); }
}

/* ==========================================================================
   04. ATMOSFER: KABUT, AWAN, SINAR, MATAHARI
   ========================================================================== */
/* Kabut bergulir horizontal tanpa jeda (lebar latar 2× agar mulus) */
@keyframes mist-roll {
  from { background-position: 0 bottom; }
  to   { background-position: -1600px bottom; }
}
@keyframes mist-roll-rev {
  from { background-position: -1200px bottom; }
  to   { background-position: 0 bottom; }
}

/* Awan dua kecepatan */
@keyframes cloud-drift-a {
  from { background-position: 0 0; }
  to   { background-position: 1400px 0; }
}
@keyframes cloud-drift-b {
  from { background-position: 0 0; }
  to   { background-position: -1000px 0; }
}

/* Sinar matahari berputar sangat lambat */
@keyframes rays-turn {
  from { transform: translate(-50%, -50%) rotate(0deg); }
  to   { transform: translate(-50%, -50%) rotate(360deg); }
}

/* Matahari "bernapas" — sedikit membesar & menguat */
@keyframes sun-breathe {
  0%, 100% { transform: translate(-50%, -50%) scale(1);    opacity: 0.9; }
  50%      { transform: translate(-50%, -50%) scale(1.06); opacity: 1; }
}

/* Zoom kamera sangat lambat pada seluruh panggung hero — kesan sinematik */
@keyframes hero-kenburns {
  0%   { transform: scale(1); }
  100% { transform: scale(1.045); }
}

/* Bayangan awan yang melintas di badan gunung */
@keyframes cloud-shadow-drift {
  0%   { transform: translateX(-12%); opacity: 0.35; }
  50%  { opacity: 0.55; }
  100% { transform: translateX(112%); opacity: 0.35; }
}

/* Berkas cahaya lembut menyapu perlahan dari balik gunung */
@keyframes shaft-sweep {
  0%, 100% { opacity: 0.5; transform: translate(-50%, -50%) rotate(-3deg); }
  50%      { opacity: 0.85; transform: translate(-50%, -50%) rotate(3deg); }
}

/* Bintang berkelip acak (durasi/delay diatur per elemen) */
@keyframes star-twinkle {
  0%, 100% { opacity: var(--star-min, 0.2); }
  50%      { opacity: var(--star-max, 1); }
}

/* Kunang-kunang berdenyut lembut (posisi & jalur diatur GSAP via JS) */
@keyframes firefly-glow {
  0%, 100% { opacity: 0.25; transform: scale(0.8); }
  50%      { opacity: 1;    transform: scale(1.15); }
}

/* Kabut naik lembut (dipakai .mist-band saat masuk viewport) */
@keyframes mist-rise {
  from { opacity: 0; transform: translateY(30px); }
  to   { opacity: 0.4; transform: translateY(0); }
}

/* ==========================================================================
   05. BURUNG TERBANG
   Dua jalur berbeda + kepakan sayap.
   ========================================================================== */
@keyframes bird-fly-1 {
  0%   { left: -8%;  transform: translateY(0) scale(1); opacity: 0; }
  8%   { opacity: 0.7; }
  35%  { transform: translateY(-38px) scale(1); }
  60%  { transform: translateY(14px) scale(0.96); }
  88%  { opacity: 0.6; }
  100% { left: 106%; transform: translateY(-26px) scale(0.9); opacity: 0; }
}
@keyframes bird-fly-2 {
  0%   { left: 104%; transform: translateY(0) scaleX(-1); opacity: 0; }
  10%  { opacity: 0.62; }
  40%  { transform: translateY(26px) scaleX(-1); }
  70%  { transform: translateY(-20px) scaleX(-1); }
  90%  { opacity: 0.5; }
  100% { left: -8%;  transform: translateY(10px) scaleX(-1); opacity: 0; }
}
/* Kepakan: jalur SVG diskalakan vertikal */
@keyframes wing-flap {
  0%, 100% { transform: scaleY(1); }
  50%      { transform: scaleY(0.35); }
}

/* ==========================================================================
   06. DAUN MELAYANG
   Enam varian jalur agar tidak terasa berulang.
   ========================================================================== */
@keyframes leaf-fall-1 {
  0%   { transform: translate3d(0, -8vh, 0) rotate(0deg);      opacity: 0; }
  10%  { opacity: 0.75; }
  35%  { transform: translate3d(46px, 32vh, 0) rotate(120deg); }
  65%  { transform: translate3d(-32px, 62vh, 0) rotate(230deg); }
  90%  { opacity: 0.5; }
  100% { transform: translate3d(38px, 108vh, 0) rotate(400deg); opacity: 0; }
}
@keyframes leaf-fall-2 {
  0%   { transform: translate3d(0, -8vh, 0) rotate(20deg);       opacity: 0; }
  12%  { opacity: 0.65; }
  40%  { transform: translate3d(-58px, 38vh, 0) rotate(-90deg); }
  72%  { transform: translate3d(30px, 70vh, 0) rotate(-210deg); }
  100% { transform: translate3d(-24px, 108vh, 0) rotate(-360deg); opacity: 0; }
}
@keyframes leaf-fall-3 {
  0%   { transform: translate3d(0, -8vh, 0) rotate(-15deg) scale(0.8); opacity: 0; }
  15%  { opacity: 0.55; }
  50%  { transform: translate3d(72px, 48vh, 0) rotate(160deg) scale(0.9); }
  100% { transform: translate3d(-16px, 108vh, 0) rotate(430deg) scale(0.8); opacity: 0; }
}

/* Melayang di tempat (untuk daun dekoratif statis) */
@keyframes float-y {
  0%, 100% { transform: translateY(0) rotate(0deg); }
  50%      { transform: translateY(-13px) rotate(5deg); }
}
@keyframes float-x {
  0%, 100% { transform: translateX(0); }
  50%      { transform: translateX(7px); }
}

/* ==========================================================================
   07. LOADER & INDIKATOR
   ========================================================================== */
/* Garis punggungan menggambar dirinya sendiri */
@keyframes draw-ridge {
  0%   { stroke-dashoffset: 400; opacity: 0.2; }
  45%  { stroke-dashoffset: 0;   opacity: 1; }
  75%  { stroke-dashoffset: 0;   opacity: 1; }
  100% { stroke-dashoffset: -400; opacity: 0.2; }
}

/* Indikator gulir turun */
@keyframes cue-slide {
  0%   { top: -50%; }
  100% { top: 100%; }
}

/* Titik berdenyut */
@keyframes pulse-dot {
  0%, 100% { opacity: 1;   transform: scale(1); }
  50%      { opacity: 0.35; transform: scale(1.55); }
}
@keyframes pulse-soft {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.55; }
}

/* Putaran lambat (cincin lencana, ikon matahari) */
@keyframes spin-slow {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}

/* ==========================================================================
   08. MIKRO-INTERAKSI
   ========================================================================== */
/* Riak tombol */
@keyframes ripple-out {
  to { transform: scale(2.6); opacity: 0; }
}

/* Bar visualiser audio */
@keyframes eq-bounce {
  0%, 100% { height: 4px; }
  50%      { height: 15px; }
}

/* Getaran halus untuk validasi form gagal */
@keyframes shake-x {
  0%, 100% { transform: translateX(0); }
  20%      { transform: translateX(-6px); }
  40%      { transform: translateX(5px); }
  60%      { transform: translateX(-3px); }
  80%      { transform: translateX(2px); }
}
.a-shake { animation: shake-x 420ms var(--ease-soft) both; }

/* Kilau melintas pada kartu saat hover (mikro-interaksi hover image) */
.shine { position: relative; overflow: hidden; }
.shine::after {
  content: "";
  position: absolute;
  top: 0; left: -120%;
  width: 55%; height: 100%;
  background: linear-gradient(100deg, transparent, rgba(255, 255, 255, 0.30), transparent);
  transform: skewX(-18deg);
  transition: left 780ms var(--ease-out);
  pointer-events: none;
  z-index: 3;
}
.shine:hover::after { left: 130%; }

/* Tombol magnetik — transform diatur JS, transisi diatur di sini */
.magnetic {
  transition: transform 260ms var(--ease-out);
  will-change: transform;
}

/* Angka counter: sedikit "pop" saat selesai menghitung */
@keyframes count-pop {
  0%   { transform: scale(1); }
  55%  { transform: scale(1.07); }
  100% { transform: scale(1); }
}
.is-counted { animation: count-pop 460ms var(--ease-back) both; }

/* ==========================================================================
   09. IKON CUACA
   ========================================================================== */
@keyframes drop-fall {
  0%   { transform: translateY(0);    opacity: 0; }
  25%  { opacity: 0.9; }
  100% { transform: translateY(16px); opacity: 0; }
}

/* Angin: garis meluncur */
@keyframes wind-slide {
  0%   { transform: translateX(-6px); opacity: 0.3; }
  50%  { transform: translateX(6px);  opacity: 1; }
  100% { transform: translateX(-6px); opacity: 0.3; }
}
.wx-wind-line { animation: wind-slide 2.6s ease-in-out infinite; }
.wx-wind-line:nth-of-type(2) { animation-delay: 0.4s; }
.wx-wind-line:nth-of-type(3) { animation-delay: 0.8s; }

/* ==========================================================================
   10. PETA & PENANDA
   ========================================================================== */
/* Cincin denyut pada marker aktif */
@keyframes pin-ring {
  0%   { transform: scale(0.7); opacity: 0.8; }
  70%  { transform: scale(1.7); opacity: 0; }
  100% { transform: scale(1.7); opacity: 0; }
}

/* Marker menjatuhkan diri saat peta selesai dimuat */
@keyframes pin-drop {
  0%   { transform: translateY(-34px) rotate(-45deg) scale(0.6); opacity: 0; }
  60%  { transform: translateY(0) rotate(-45deg) scale(1.08); opacity: 1; }
  100% { transform: translateY(0) rotate(-45deg) scale(1); opacity: 1; }
}
.pin { animation: pin-drop 620ms var(--ease-back) both; }

/* Garis jalur trekking menggambar sendiri di peta */
.trek-path {
  stroke-dasharray: 6 8;
  animation: dash-march 1.6s linear infinite;
}
@keyframes dash-march {
  to { stroke-dashoffset: -28; }
}

/* ==========================================================================
   11. REDUCE MOTION
   Menghormati preferensi sistem "kurangi gerakan".
   Semua animasi ambien dimatikan; transisi dipersingkat agar antarmuka
   tetap responsif namun tenang. Konten tetap terlihat penuh.
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }

  html { scroll-behavior: auto; }

  /* Elemen dekoratif yang bergerak dihilangkan sepenuhnya */
  .hero-clouds,
  .hero-clouds--far,
  .hero-mist,
  .hero-mist--low,
  .hero-rays,
  .hero-shafts,
  .hero-cloud-shadow,
  .hero-fireflies,
  .hero-birds,
  .leaves,
  .mist-band,
  .story-embers,
  .cursor-glow { display: none !important; }

  /* Panggung hero tidak boleh ikut "zoom" ambien */
  .hero-scene { animation: none !important; transform: none !important; }

  /* Pastikan konten beranimasi tetap tampil */
  [data-anim] {
    opacity: 1 !important;
    transform: none !important;
    clip-path: none !important;
  }

  .hero-sun { animation: none !important; }

  /* Pesawat loader diparkir di puncak lintasan, tidak berputar */
  .loader-plane { offset-distance: 25% !important; }
  .loader-orbit ellipse { animation: none !important; }
}

/* Kelas manual bila pengguna menekan tombol "kurangi gerak" di navbar */
html.reduce-motion .hero-clouds,
html.reduce-motion .hero-clouds--far,
html.reduce-motion .hero-mist,
html.reduce-motion .hero-mist--low,
html.reduce-motion .hero-rays,
html.reduce-motion .hero-birds,
html.reduce-motion .leaves,
html.reduce-motion .mist-band,
html.reduce-motion .cursor-glow { display: none !important; }
html.reduce-motion * {
  animation-duration: 0.001ms !important;
  transition-duration: 120ms !important;
}
html.reduce-motion .loader-plane { offset-distance: 25% !important; }
html.reduce-motion .loader-orbit ellipse { animation: none !important; }
