/* assets/css/06_animations.css
   이징 기반 모션 시스템
   ─────────────────────────────────────────────────────────────
   EASE-IN-OUT  cubic-bezier(0.4, 0, 0.2, 1)   진입+퇴장 공존, 루프
   EASE-OUT     cubic-bezier(0, 0, 0.2, 1)     도착·등장 (빠르게 시작 → 정착)
   EASE-IN      cubic-bezier(0.4, 0, 1, 1)     퇴장·사라짐 (천천히 → 빠르게)
   OVERSHOOT    cubic-bezier(0.22, 1, 0.36, 1) 스크롤 등장 오버슈트
*/


/* =========================
   @keyframes — EASE-IN-OUT
========================= */

/* 스크롤 등장: 아래서 위로 올라오며 나타남 */
@keyframes fadeSlideUp {
  from { opacity: 0; transform: translateY(32px); }
  to   { opacity: 1; transform: translateY(0);    }
}

/* 페이지 로드 히어로 진입 */
@keyframes heroReveal {
  from { opacity: 0; transform: translateY(32px); }
  to   { opacity: 1; transform: translateY(0);    }
}

/* 테마 버튼 회전 */
@keyframes spinOnce {
  from { transform: rotate(0deg);   }
  to   { transform: rotate(360deg); }
}

/* 모바일 nav 아이템 순차 진입 */
@keyframes navItemReveal {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: translateY(0);   }
}

/* 히어로 h1 플로팅 — CSS 변수로 모바일 진폭 조절 */
@keyframes heroFloat {
  0%, 100% { transform: translateY(0); }
  50%       { transform: translateY(var(--float-y, -8px)); }
}


/* =========================
   @keyframes — EASE-OUT
========================= */

/* 토스트 등장 */
@keyframes toastSlideUp {
  from { opacity: 0; transform: translateX(-50%) translateY(10px); }
  to   { opacity: 1; transform: translateX(-50%) translateY(0);    }
}

/* 모달 다이얼로그 등장 */
@keyframes modalIn {
  from { opacity: 0; transform: translateY(-14px) scale(0.98); }
  to   { opacity: 1; transform: translateY(0)     scale(1);    }
}

/* 모달 백드롭 등장 */
@keyframes backdropIn {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* 버튼 Ripple */
@keyframes ripple {
  0%   { transform: translate(-50%, -50%) scale(0); opacity: 0.4; }
  100% { transform: translate(-50%, -50%) scale(3); opacity: 0;   }
}


/* =========================
   @keyframes — EASE-IN
========================= */

/* 토스트 퇴장 */
@keyframes toastFadeOut {
  from { opacity: 1; transform: translateX(-50%) translateY(0);    }
  to   { opacity: 0; transform: translateX(-50%) translateY(6px);  }
}

/* 모달 다이얼로그 닫힘 */
@keyframes modalOut {
  from { opacity: 1; transform: translateY(0)    scale(1);    }
  to   { opacity: 0; transform: translateY(6px)  scale(0.98); }
}

/* 모달 백드롭 닫힘 */
@keyframes backdropOut {
  from { opacity: 1; }
  to   { opacity: 0; }
}


/* =========================
   히어로 / 페이지 헤더  (overshoot)
========================= */

.hero,
.page-header {
  animation: heroReveal 0.55s cubic-bezier(0.22, 1, 0.36, 1) both;
}


/* =========================
   히어로 h1 플로팅  (ease-in-out 루프)
========================= */

.hero h1 {
  display     : inline-block; /* transform이 block 요소에도 적용되도록 */
  animation   : heroFloat 4s ease-in-out infinite;
  will-change : transform;
}

/* 모바일: 진폭 절반 */
@media (max-width: 768px) {
  .hero h1 {
    --float-y: -4px;
  }
}


/* =========================
   페이지 진입 Fade In  (ease-out)
   .js 클래스 전제 — JS 없는 환경에서는 숨겨지지 않음
========================= */

.js main {
  opacity   : 0;
  transform : translateY(12px);
  transition: opacity   0.4s cubic-bezier(0, 0, 0.2, 1),
              transform 0.4s cubic-bezier(0, 0, 0.2, 1);
}

.js main.is-page-ready {
  opacity  : 1;
  transform: translateY(0);
}


/* =========================
   스크롤 등장 — scroll-reveal  (overshoot)
   .js 클래스 전제로만 숨김 처리하여 JS 비활성 환경 보호
========================= */

.js .scroll-reveal {
  opacity   : 0;
  transform : translateY(32px);
  transition: opacity   0.55s cubic-bezier(0.22, 1, 0.36, 1),
              transform 0.55s cubic-bezier(0.22, 1, 0.36, 1);
}

.js .scroll-reveal.is-visible {
  opacity  : 1;
  transform: translateY(0);
}


/* =========================
   카드 호버 lift  (ease-out)
========================= */

.card {
  transition: border-color 0.2s,
              transform    0.25s cubic-bezier(0, 0, 0.2, 1),
              box-shadow   0.25s cubic-bezier(0, 0, 0.2, 1);
}

.card:hover {
  transform : translateY(-6px);
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
}

/* 모바일(터치): hover 눌러붙음 방지, :active로 대체 */
@media (hover: none) {
  .card:hover {
    transform : none;
    box-shadow: none;
  }

  .card:active {
    transform : translateY(-6px);
    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
  }
}


/* =========================
   버튼 Ripple 효과
========================= */

.btn {
  position: relative;
  overflow: hidden;
}

.ripple-effect {
  position      : absolute;
  width         : 100px;
  height        : 100px;
  border-radius : 50%;
  background    : rgba(255, 255, 255, 0.35);
  pointer-events: none;
  transform     : translate(-50%, -50%) scale(0);
  animation     : ripple 0.55s cubic-bezier(0, 0, 0.2, 1) forwards;
}


/* =========================
   nav-link 언더라인  (ease-in-out)
========================= */

.nav-link::after {
  transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1);
}


/* =========================
   모바일 nav 아이템 순차 진입  (ease-in-out)
========================= */

@media (max-width: 640px) {
  .nav.is-open .nav-link {
    animation: navItemReveal 0.28s cubic-bezier(0.4, 0, 0.2, 1) both;
  }

  .nav.is-open .nav-link:nth-child(1) { animation-delay: 0.04s; }
  .nav.is-open .nav-link:nth-child(2) { animation-delay: 0.08s; }
  .nav.is-open .nav-link:nth-child(3) { animation-delay: 0.12s; }
  .nav.is-open .nav-link:nth-child(4) { animation-delay: 0.16s; }
  .nav.is-open .nav-link:nth-child(5) { animation-delay: 0.20s; }
  .nav.is-open .nav-link:nth-child(6) { animation-delay: 0.24s; }
  .nav.is-open .nav-link:nth-child(7) { animation-delay: 0.28s; }
  .nav.is-open .nav-link:nth-child(8) { animation-delay: 0.32s; }
}


/* =========================
   테마 토글 버튼 스핀  (ease-in-out)
========================= */

.is-spinning {
  animation: spinOnce 0.38s cubic-bezier(0.4, 0, 0.2, 1);
}


/* =========================
   토스트  (ease-out 등장 / ease-in 퇴장)
========================= */

.toast.is-show {
  display  : block;
  animation: toastSlideUp 0.28s cubic-bezier(0, 0, 0.2, 1) both;
}

.toast.is-show.is-hiding {
  animation: toastFadeOut 0.22s cubic-bezier(0.4, 0, 1, 1) both;
}


/* =========================
   모달  (ease-out 등장 / ease-in 퇴장)
========================= */

.modal.is-open .modal-backdrop {
  animation: backdropIn 0.25s cubic-bezier(0, 0, 0.2, 1) both;
}

.modal.is-open .modal-dialog {
  animation: modalIn 0.3s cubic-bezier(0, 0, 0.2, 1) both;
}

.modal.is-open.is-closing .modal-backdrop {
  animation: backdropOut 0.2s cubic-bezier(0.4, 0, 1, 1) both;
}

.modal.is-open.is-closing .modal-dialog {
  animation: modalOut 0.2s cubic-bezier(0.4, 0, 1, 1) both;
}


/* =========================
   prefers-reduced-motion — 모든 모션 비활성
========================= */

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration        : 0.01ms !important;
    animation-iteration-count : 1      !important;
    transition-duration       : 0.01ms !important;
  }

  /* 페이지 진입 즉시 표시 */
  .js main,
  .js main.is-page-ready {
    opacity  : 1;
    transform: none;
    transition: none;
  }

  /* 스크롤 등장 즉시 표시 */
  .js .scroll-reveal {
    opacity  : 1;
    transform: none;
  }

  /* 카드 hover/active 효과 제거 */
  .card:hover,
  .card:active {
    transform : none;
    box-shadow: none;
  }

  /* 플로팅 제거 */
  .hero h1 {
    animation  : none;
    will-change: auto;
  }
}
