/* 소리와 연출 모듈 스타일
 * html.fx-on     : 설정의 애니메이션이 켜져 있음 (완성 표시 등 정적 연출 허용)
 * html.fx-motion : fx-on 이면서 prefers-reduced-motion이 아님 (움직이는 연출 허용) */
:root { --fx-wait: .65s; }

/* ---------- 화면 전환 · 모달 ---------- */
.fx-motion #app.fx-enter > :not(.tabbar) { animation: fx-screen .3s ease-out both; }
@keyframes fx-screen { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: none; } }
.fx-motion .modal:not([hidden]) { animation: fx-fade .2s ease-out both; }
.fx-motion .modal .sheet { animation: fx-sheet .32s cubic-bezier(.2, .85, .3, 1.2) both; }
@keyframes fx-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes fx-sheet { from { opacity: 0; transform: translateY(26px) scale(.94); } to { opacity: 1; transform: none; } }
/* 클리어 모달은 보드 위 고양이들이 뛰는 동안 잠깐 기다렸다가 나온다 */
.fx-motion .modal.fx-clear:not([hidden]), .fx-motion .modal.fx-clear .sheet, .fx-motion .modal.fx-clear .sheet.clear .party { animation-delay: var(--fx-wait); animation-fill-mode: both; }

/* ---------- 보드: 완성 표시 ---------- */
.frame { position: relative; }
.fx-layer { position: absolute; inset: 0; pointer-events: none; z-index: 3; }
.fx-tick { position: absolute; border-radius: 3px; background: var(--good); opacity: 0; }
.fx-tick.r { left: 1.5px; width: 5px; }
.fx-tick.c { top: 1.5px; height: 5px; }
.fx-on .fx-tick.on { opacity: .85; }
.fx-motion .fx-tick { transform: scale(.2); transition: opacity .25s, transform .3s cubic-bezier(.3, 1.7, .5, 1); }
.fx-motion .fx-tick.on { transform: none; }
/* 완성된 색 영역은 한 톤 밝아진다 (칸 배경색은 그대로 두고 흰 막을 얹는다) */
.fx-on .cell[data-fxg] { background-image: linear-gradient(rgba(255, 255, 255, .42), rgba(255, 255, 255, .42)) !important; }
.fx-flash { position: absolute; background: rgba(255, 255, 255, .85); border-radius: 6px; opacity: 0; animation: fx-flash .55s ease-out both; }
@keyframes fx-flash { 0% { opacity: 0; transform: scale(.7); } 30% { opacity: .9; transform: scale(1); } 100% { opacity: 0; transform: scale(1); } }

/* ---------- 보드: 충돌 떨림 · 클리어 점프 ---------- */
.fx-motion .cell .cat.fx-shake { animation: fx-shake .45s ease-in-out; }
@keyframes fx-shake {
  0%, 100% { transform: none; }
  18% { transform: translateX(-10%) rotate(-7deg); }
  38% { transform: translateX(9%) rotate(6deg); }
  58% { transform: translateX(-6%) rotate(-4deg); }
  78% { transform: translateX(4%) rotate(2deg); }
}
.fx-motion .cell .cat.fx-hop { animation: fx-hop .62s cubic-bezier(.3, .6, .4, 1) both; }
@keyframes fx-hop {
  0% { transform: none; }
  15% { transform: translateY(4%) scale(1.1, .88); }
  42% { transform: translateY(-36%) scale(.95, 1.1); }
  68% { transform: translateY(0) scale(1.1, .9); }
  84% { transform: translateY(-9%) scale(1); }
  100% { transform: none; }
}

/* ---------- 반짝이 · 색종이 (화면 전체 위 레이어) ---------- */
#fx-top { position: fixed; inset: 0; z-index: 30; pointer-events: none; overflow: hidden; }
.fx-spark { position: absolute; margin: -6px 0 0 -6px; opacity: 0;
  clip-path: polygon(50% 0, 62% 38%, 100% 50%, 62% 62%, 50% 100%, 38% 62%, 0 50%, 38% 38%);
  animation: fx-spark .6s cubic-bezier(.2, .7, .3, 1) both; }
@keyframes fx-spark {
  0% { opacity: 0; transform: translate(0, 0) scale(.3) rotate(0); }
  20% { opacity: 1; }
  100% { opacity: 0; transform: translate(var(--dx), var(--dy)) scale(1.15) rotate(90deg); }
}
.fx-confetti { position: absolute; top: -24px; opacity: 0; animation: fx-fall 2.6s cubic-bezier(.3, .25, .7, 1) both; }
@keyframes fx-fall {
  0% { opacity: 1; transform: translate3d(0, 0, 0) rotate(0); }
  85% { opacity: 1; }
  100% { opacity: 0; transform: translate3d(var(--dx), 105vh, 0) rotate(var(--rot)); }
}

/* ---------- 클리어 모달: 별이 하나씩 찍힌다 ---------- */
.fx-motion .modal.fx-clear .bigstars > :not(.off) { animation: fx-stamp .45s cubic-bezier(.3, 1.5, .5, 1) both; }
.fx-motion .modal.fx-clear .bigstars > :nth-child(1) { animation-delay: calc(var(--fx-wait) + .38s); }
.fx-motion .modal.fx-clear .bigstars > :nth-child(2) { animation-delay: calc(var(--fx-wait) + .68s); }
.fx-motion .modal.fx-clear .bigstars > :nth-child(3) { animation-delay: calc(var(--fx-wait) + .98s); }
@keyframes fx-stamp { 0% { opacity: 0; scale: 2.6; rotate: -30deg; } 55% { opacity: 1; scale: .82; rotate: 6deg; } 100% { opacity: 1; scale: 1; rotate: 0deg; } }
.fx-motion .modal.fx-clear .sheet > .card { animation: fx-sheet .4s cubic-bezier(.2, .85, .3, 1.3) calc(var(--fx-wait) + 1.35s) both; }

/* ---------- 스테이지 맵: 다음 지점이 살짝 숨 쉰다 ---------- */
.fx-motion .node.next { animation: fx-bob 1.8s ease-in-out infinite; }
@keyframes fx-bob { 50% { scale: 1.07; } }

/* ---------- 움직임 줄이기: game.js가 넣는 기본 애니메이션도 멈춘다 ---------- */
@media (prefers-reduced-motion: reduce) {
  .anim .cell.catc .cat, .anim .cell.tg::after, .anim-on .sheet.clear .party { animation: none !important; }
  .switch::after { transition: none; }
}
