/* ============================================================
 * vweb-anim.css — V-Web 공통 애니메이션 라이브러리
 *
 * 출처: 과거 퍼블 프로젝트 4종의
 *       css/animation.css 에서 "단위 중립(transform/opacity/filter)"
 *       keyframe 만 추출 → v- 프리픽스로 표준화.
 *
 * 단위 정책:
 *   여기 있는 모든 keyframe 은 transform/opacity/filter 만 사용한다.
 *   → px/vw/%/top/left 같은 좌표·길이 단위에 의존하지 않으므로
 *     캔버스/단위 체계(rem·--px)와 무관하게 그대로 재사용 가능.
 *
 * 사용:
 *   <div class="v-float">…</div>
 *   <ul class="v-marquee-x">…</ul>      (seamless 반복은 내용 2배 복제 + v-*-half)
 *
 * hook:
 *   vweb-* 프리픽스 → 모든 Edit/Write hook 자동 면제.
 *
 * ⛔ 라이브러리에서 제외한 효과 (좌표/px/random 의존 → 섹션 로컬로 작성):
 *   - smoke      : translate(calc(random()*100vw), 100vh) + px  (random() 실험적)
 *   - fall/fall2 : top: -0% → 100%                              (좌표 의존)
 *   - ball       : bottom: 0px → 20px                           (px 좌표)
 *   - slick-circle : left: 0 → 99%                              (좌표 의존)
 *   - ddm/ddm2*/ddm_m* : matrix(... , -30px) / translate(20px)  (px 이동)
 *   - hand/hand2 : translate(%,%)                               (미세 % 손동작)
 *   - uitLineMove: stroke-dashoffset                            (SVG 경로 길이 의존)
 *   필요하면 해당 섹션 style.css 에 직접 정의할 것.
 * ============================================================ */

/* ===== Marquee (무한 흐름) ===== */
/* seamless 무한루프: 내용을 2배 복제하고 -half 사용 (translateX -50%) */
@keyframes v-marquee-x      { from { transform: translateX(0); }    to { transform: translateX(-100%); } }
@keyframes v-marquee-x-rev  { from { transform: translateX(0); }    to { transform: translateX(100%); } }
@keyframes v-marquee-y      { from { transform: translateY(0); }    to { transform: translateY(-100%); } }
@keyframes v-marquee-y-rev  { from { transform: translateY(0); }    to { transform: translateY(100%); } }
@keyframes v-marquee-half     { from { transform: translateX(0); }    to { transform: translateX(-50%); } }
@keyframes v-marquee-half-rev { from { transform: translateX(-50%); } to { transform: translateX(0); } }

.v-marquee-x      { animation: v-marquee-x 20s infinite linear; }
.v-marquee-x-rev  { animation: v-marquee-x-rev 20s infinite linear; }
.v-marquee-y      { animation: v-marquee-y 20s infinite linear; }
.v-marquee-y-rev  { animation: v-marquee-y-rev 20s infinite linear; }
.v-marquee-half     { animation: v-marquee-half 20s infinite linear; }
.v-marquee-half-rev { animation: v-marquee-half-rev 20s infinite linear; }

/* ===== Rotate (연속 회전) ===== */
@keyframes v-rotate   { to { transform: rotate(360deg); } }
@keyframes v-rotate-y { from { transform: rotateY(0); } to { transform: rotateY(360deg); } }

.v-rotate   { animation: v-rotate 10s infinite linear; }
.v-rotate-y { animation: v-rotate-y 10s infinite linear; }

/* ===== Wobble (미세 흔들림) ===== */
@keyframes v-wobble {
  0%   { transform: rotate(-1deg); }
  40%  { transform: rotate(1deg); }
  60%  { transform: rotate(2deg); }
  80%  { transform: rotate(-1deg); }
  100% { transform: rotate(1deg); }
}
.v-wobble { animation: v-wobble 4s infinite ease-in-out; }

/* ===== Float (상하 부유) ===== */
@keyframes v-float { 0% { transform: translateY(-5%); } 100% { transform: translateY(5%); } }

.v-float       { animation: v-float 2s ease-in-out infinite alternate; }
.v-float-delay { animation: v-float 2s 1s ease-in-out infinite alternate; }

/* ===== Scale + Opacity (확산/펄스) ===== */
@keyframes v-scale-opa  { 0% { transform: scale(0.5); opacity: 0; } 50% { opacity: 1; } 100% { transform: scale(1); opacity: 0; } }
@keyframes v-scale-opa-2 { 0% { transform: scale(1); opacity: 0; } 20% { opacity: 0.4; } 100% { transform: scale(1.2); opacity: 0; } }
@keyframes v-scale-opa-3 { 100% { transform: scale(1.3); opacity: 0; } }

.v-scale-opa   { animation: v-scale-opa 2s infinite; }
.v-scale-opa-2 { animation: v-scale-opa-2 2s infinite; }
.v-scale-opa-3 { animation: v-scale-opa-3 2s infinite; }

/* ===== Zoom (스케일 펄스) ===== */
@keyframes v-zoom        { 0% { transform: scale(1); } 50% { transform: scale(1.02); } 100% { transform: scale(1); } }
@keyframes v-zoom-strong { 0% { transform: scale(1); } 50% { transform: scale(1.1); }  100% { transform: scale(1); } }

.v-zoom        { animation: v-zoom 4s infinite ease-in-out; }
.v-zoom-strong { animation: v-zoom-strong 4s infinite ease-in-out; }

/* ===== Blink (점멸) ===== */
@keyframes v-blink   { 0% { opacity: 0; } 30% { opacity: 0; } 31% { opacity: 1; } 99% { opacity: 1; } 100% { opacity: 0; } }
@keyframes v-blink-2 { 0% { opacity: 0; } 49% { opacity: 0; } 50% { opacity: 1; } 99% { opacity: 1; } 100% { opacity: 0; } }
@keyframes v-blink-3 { 0% { opacity: 1; } 24% { opacity: 1; } 25% { opacity: 0; } 99% { opacity: 0; } 100% { opacity: 1; } }

.v-blink   { animation: v-blink 1s infinite ease-in-out; }
.v-blink-2 { animation: v-blink-2 1s infinite ease-in-out; }
.v-blink-3 { animation: v-blink-3 1s infinite ease-in-out; }

/* ===== Fade loop (페이드 인-아웃 반복) ===== */
@keyframes v-fade-loop { 0% { opacity: 0; } 50% { opacity: 1; } 100% { opacity: 0; } }
.v-fade-loop { animation: v-fade-loop 3s infinite ease-in-out; }

/* ===== Light (네온/조명 플리커) ===== */
@keyframes v-light {
  0%, 31%, 34%, 39%, 42%, 47% { opacity: 0; }
  5%, 30%, 35%, 38%, 43%, 46% { opacity: 0.4; }
  50%, 51%, 54%, 55%, 60%, 67%, 68%, 100% { opacity: 1; }
  70% { opacity: 0.2; }
}
.v-light { animation: v-light 5s infinite; }

/* ===== Bright (밝기 호흡) ===== */
@keyframes v-bright { 0% { filter: brightness(0.5); } 50% { filter: brightness(1.2); } 100% { filter: brightness(0.5); } }
.v-bright { animation: v-bright 3s infinite ease-in-out; }
