/**
 * TW Builder — 섹션/콘텐츠/미디어 등장 애니메이션
 * 뷰포트 진입 후 .twb-anim-play 가 붙으면 재생 (twb-animations.js)
 */
@media (prefers-reduced-motion: reduce) {
    /* 큰 움직임(섹션·미디어만 끔 — 콘텐츠 텍스트 페이드는 유지) */
    section.twb-anim:not(.twb-anim--none) {
        opacity: 1 !important;
        transform: none !important;
    }
    section.twb-anim.twb-anim-play {
        animation: none !important;
    }
    .twb-anim-media:not(.twb-anim-media--none) {
        opacity: 1 !important;
        transform: none !important;
    }
    .twb-anim-media.twb-anim-play {
        animation: none !important;
    }
    .twb-anim-content.twb-anim-play {
        animation-duration: 0.35s !important;
        animation-delay: 0s !important;
    }
}

/* ---- 변수: 섹션 ---- */
.twb-anim-speed--xs { --twb-a-dur: 0.2s; }
.twb-anim-speed--fast { --twb-a-dur: 0.3s; }
.twb-anim-speed--normal { --twb-a-dur: 0.6s; }
.twb-anim-speed--slow { --twb-a-dur: 1s; }
.twb-anim-speed--slower { --twb-a-dur: 1.2s; }
.twb-anim-speed--xxslow { --twb-a-dur: 5s; }
/* 섹션(래퍼) 전용 — 관리자 속도 0.6s~1.6s (sec*) */
.twb-anim-speed--sec600 { --twb-a-dur: 0.6s; }
.twb-anim-speed--sec1000 { --twb-a-dur: 1s; }
.twb-anim-speed--sec1200 { --twb-a-dur: 1.2s; }
.twb-anim-speed--sec1400 { --twb-a-dur: 1.4s; }
.twb-anim-speed--sec1600 { --twb-a-dur: 1.6s; }
.twb-anim-delay--none { --twb-a-delay: 0s; }
.twb-anim-delay--short { --twb-a-delay: 0.2s; }
.twb-anim-delay--mid { --twb-a-delay: 0.4s; }
.twb-anim-delay--long { --twb-a-delay: 0.6s; }
.twb-anim-delay--xl { --twb-a-delay: 0.8s; }
.twb-anim-delay--xxl { --twb-a-delay: 1s; }

/* ---- 변수: 콘텐츠 ---- */
.twb-anim-content-speed--xs { --twb-ac-dur: 0.2s; }
.twb-anim-content-speed--fast { --twb-ac-dur: 0.3s; }
.twb-anim-content-speed--normal { --twb-ac-dur: 0.6s; }
.twb-anim-content-speed--slow { --twb-ac-dur: 1s; }
.twb-anim-content-speed--slower { --twb-ac-dur: 1.2s; }
.twb-anim-content-speed--xxslow { --twb-ac-dur: 5s; }
.twb-anim-content-delay--none { --twb-ac-delay: 0s; }
.twb-anim-content-delay--short { --twb-ac-delay: 0.2s; }
.twb-anim-content-delay--mid { --twb-ac-delay: 0.4s; }
.twb-anim-content-delay--long { --twb-ac-delay: 0.6s; }
.twb-anim-content-delay--xl { --twb-ac-delay: 0.8s; }
.twb-anim-content-delay--xxl { --twb-ac-delay: 1s; }

/* ---- 변수: 미디어 (배경 등 — 2~15초) ---- */
.twb-anim-media-speed--m2 { --twb-am-dur: 2s; }
.twb-anim-media-speed--m3 { --twb-am-dur: 3s; }
.twb-anim-media-speed--m4 { --twb-am-dur: 4s; }
.twb-anim-media-speed--m5 { --twb-am-dur: 5s; }
.twb-anim-media-speed--m6 { --twb-am-dur: 6s; }
.twb-anim-media-speed--m7 { --twb-am-dur: 7s; }
.twb-anim-media-speed--m8 { --twb-am-dur: 8s; }
.twb-anim-media-speed--m9 { --twb-am-dur: 9s; }
.twb-anim-media-speed--m10 { --twb-am-dur: 10s; }
.twb-anim-media-speed--m11 { --twb-am-dur: 11s; }
.twb-anim-media-speed--m12 { --twb-am-dur: 12s; }
.twb-anim-media-speed--m13 { --twb-am-dur: 13s; }
.twb-anim-media-speed--m14 { --twb-am-dur: 14s; }
.twb-anim-media-speed--m15 { --twb-am-dur: 15s; }
/* 구버전 토큰(재저장·캐시) → 근접 초 */
.twb-anim-media-speed--xs { --twb-am-dur: 2s; }
.twb-anim-media-speed--fast { --twb-am-dur: 3s; }
.twb-anim-media-speed--normal { --twb-am-dur: 6s; }
.twb-anim-media-speed--slow { --twb-am-dur: 9s; }
.twb-anim-media-speed--slower { --twb-am-dur: 12s; }
.twb-anim-media-speed--xxslow { --twb-am-dur: 15s; }
.twb-anim-media-delay--none { --twb-am-delay: 0s; }
.twb-anim-media-delay--short { --twb-am-delay: 0.2s; }
.twb-anim-media-delay--mid { --twb-am-delay: 0.4s; }
.twb-anim-media-delay--long { --twb-am-delay: 0.6s; }
.twb-anim-media-delay--xl { --twb-am-delay: 0.8s; }
.twb-anim-media-delay--xxl { --twb-am-delay: 1s; }

/* 반복 (animation-iteration-count) */
.twb-anim-repeat--once { --twb-a-iter: 1; }
.twb-anim-repeat--infinite { --twb-a-iter: infinite; }
.twb-anim-content-repeat--once { --twb-ac-iter: 1; }
.twb-anim-content-repeat--infinite { --twb-ac-iter: infinite; }
/*
 * 콘텐츠 "무한 반복": 요소마다 infinite 를 주면 지연(순차 등장)과 맞지 않고 각각 따로 도는 문제 발생.
 * 콘텐츠·미디어 한 사이클이 끝난 뒤 다시 → CSS 는 1회만 재생, twb-animations.js 가 루프. (섹션 래퍼는 뷰포트 진입 1회만, twb-anim-repeat--once 고정)
 */
.twb-anim-content.twb-anim-content-repeat--infinite.twb-anim-play {
    --twb-ac-iter: 1 !important;
}
.twb-anim-media-repeat--once { --twb-am-iter: 1; }
.twb-anim-media-repeat--infinite { --twb-am-iter: infinite; }

/* fade-up: 아래쪽에 있다가 제자리(위로 올라오며 등장) / fade-down: 위쪽에 있다가 제자리(아래로 내려오며 등장) */
@keyframes twb-sec-fade-up {
    from { opacity: 0; transform: translate3d(0, 36px, 0); }
    to { opacity: 1; transform: translate3d(0, 0, 0); }
}
@keyframes twb-sec-fade-down {
    from { opacity: 0; transform: translate3d(0, -36px, 0); }
    to { opacity: 1; transform: translate3d(0, 0, 0); }
}
/* fade-left: 왼쪽 바깥(음수 X)에서 제자리로 / fade-right: 오른쪽 바깥(양수 X)에서 제자리로 */
@keyframes twb-sec-fade-left {
    from { opacity: 0; transform: translateX(-28px); }
    to { opacity: 1; transform: translateX(0); }
}
@keyframes twb-sec-fade-right {
    from { opacity: 0; transform: translateX(28px); }
    to { opacity: 1; transform: translateX(0); }
}

/* 섹션: 재생 전 */
section.twb-anim:not(.twb-anim--none):not(.twb-anim-play) {
    opacity: 0;
}
section.twb-anim.twb-anim--fade-up:not(.twb-anim-play) {
    transform: translate3d(0, 36px, 0);
}
section.twb-anim.twb-anim--fade-down:not(.twb-anim-play) {
    transform: translate3d(0, -36px, 0);
}
section.twb-anim.twb-anim--fade-left:not(.twb-anim-play) {
    transform: translateX(-28px);
}
section.twb-anim.twb-anim--fade-right:not(.twb-anim-play) {
    transform: translateX(28px);
}

section.twb-anim.twb-anim--fade-up.twb-anim-play {
    animation: twb-sec-fade-up var(--twb-a-dur, 0.6s) ease var(--twb-a-delay, 0s) var(--twb-a-iter, 1) normal both;
}
section.twb-anim.twb-anim--fade-down.twb-anim-play {
    animation: twb-sec-fade-down var(--twb-a-dur, 0.6s) ease var(--twb-a-delay, 0s) var(--twb-a-iter, 1) normal both;
}
section.twb-anim.twb-anim--fade-left.twb-anim-play {
    animation: twb-sec-fade-left var(--twb-a-dur, 0.6s) ease var(--twb-a-delay, 0s) var(--twb-a-iter, 1) normal both;
}
section.twb-anim.twb-anim--fade-right.twb-anim-play {
    animation: twb-sec-fade-right var(--twb-a-dur, 0.6s) ease var(--twb-a-delay, 0s) var(--twb-a-iter, 1) normal both;
}

@keyframes twb-c-fade {
    from { opacity: 0; }
    to { opacity: 1; }
}
@keyframes twb-c-fade-up {
    from { opacity: 0; transform: translate3d(0, 22px, 0); }
    to { opacity: 1; transform: translate3d(0, 0, 0); }
}
@keyframes twb-c-fade-down {
    from { opacity: 0; transform: translate3d(0, -22px, 0); }
    to { opacity: 1; transform: translate3d(0, 0, 0); }
}
@keyframes twb-c-fade-left {
    from { opacity: 0; transform: translate3d(-28px, 0, 0); }
    to { opacity: 1; transform: translate3d(0, 0, 0); }
}
@keyframes twb-c-fade-right {
    from { opacity: 0; transform: translate3d(28px, 0, 0); }
    to { opacity: 1; transform: translate3d(0, 0, 0); }
}

/* 콘텐츠: 재생 전 */
.twb-anim-content.twb-anim-content--fade:not(.twb-anim-play) {
    opacity: 0;
}
.twb-anim-content.twb-anim-content--fade-up:not(.twb-anim-play) {
    opacity: 0;
    transform: translate3d(0, 22px, 0);
}
.twb-anim-content.twb-anim-content--fade-down:not(.twb-anim-play) {
    opacity: 0;
    transform: translate3d(0, -22px, 0);
}
.twb-anim-content.twb-anim-content--fade-left:not(.twb-anim-play) {
    opacity: 0;
    transform: translate3d(-28px, 0, 0);
}
.twb-anim-content.twb-anim-content--fade-right:not(.twb-anim-play) {
    opacity: 0;
    transform: translate3d(28px, 0, 0);
}

.twb-anim-content.twb-anim-content--fade.twb-anim-play {
    animation: twb-c-fade var(--twb-ac-dur, 0.6s) ease var(--twb-ac-delay, 0s) var(--twb-ac-iter, 1) normal both;
}
.twb-anim-content.twb-anim-content--fade-up.twb-anim-play {
    animation: twb-c-fade-up var(--twb-ac-dur, 0.6s) ease var(--twb-ac-delay, 0s) var(--twb-ac-iter, 1) normal both;
}
.twb-anim-content.twb-anim-content--fade-down.twb-anim-play {
    animation: twb-c-fade-down var(--twb-ac-dur, 0.6s) ease var(--twb-ac-delay, 0s) var(--twb-ac-iter, 1) normal both;
}
.twb-anim-content.twb-anim-content--fade-left.twb-anim-play {
    animation: twb-c-fade-left var(--twb-ac-dur, 0.6s) ease var(--twb-ac-delay, 0s) var(--twb-ac-iter, 1) normal both;
}
.twb-anim-content.twb-anim-content--fade-right.twb-anim-play {
    animation: twb-c-fade-right var(--twb-ac-dur, 0.6s) ease var(--twb-ac-delay, 0s) var(--twb-ac-iter, 1) normal both;
}

@keyframes twb-m-fade {
    from { opacity: 0; }
    to { opacity: 1; }
}
/*
 * zoom-in / zoom-out: 고급설정 라벨과 동일 — 단방향만 (펄스 계열과 구분).
 * - 확대(zoom-in): 100% → 120% 에서 유지 (왕복 아님)
 * - 축소(zoom-out): 120% → 100% 에서 유지
 * 히어로 기본·중앙형은 AOS 대신 이 키프레임 + .twb-anim-media. 슬라이더형 배경은 data-aos 줌(아래 블록)과 의미 맞춤.
 */
@keyframes twb-m-zoom-in {
    from { opacity: 1; transform: scale(1); }
    to { opacity: 1; transform: scale(1.2); }
}
@keyframes twb-m-zoom-out {
    from { opacity: 1; transform: scale(1.2); }
    to { opacity: 1; transform: scale(1); }
}
@keyframes twb-m-slide-left {
    from { opacity: 0; transform: translateX(-24px); }
    to { opacity: 1; transform: translateX(0); }
}
@keyframes twb-m-slide-right {
    from { opacity: 0; transform: translateX(24px); }
    to { opacity: 1; transform: translateX(0); }
}

/* pulse: scale 은 항상 ≥1 (100% 미만이면 레이어가 작아져 흰 여백 발생) */
/* pulse-out-in (확대 후 축소): 100% → 120% → 100% */
@keyframes twb-m-pulse-out-in {
    0%, 100% { opacity: 1; transform: scale(1); }
    50% { opacity: 1; transform: scale(1.2); }
}

/* pulse-in-out (축소 후 확대): 120% → 100% → 120% */
@keyframes twb-m-pulse-in-out {
    0%, 100% { opacity: 1; transform: scale(1.2); }
    50% { opacity: 1; transform: scale(1); }
}

/* 미디어: 재생 전 */
.twb-anim-media.twb-anim-media--fade:not(.twb-anim-play) {
    opacity: 0;
}
.twb-anim-media.twb-anim-media--zoom-in:not(.twb-anim-play) {
    opacity: 1;
    transform: scale(1);
}
.twb-anim-media.twb-anim-media--zoom-out:not(.twb-anim-play) {
    opacity: 1;
    transform: scale(1.2);
}
.twb-anim-media.twb-anim-media--slide-left:not(.twb-anim-play) {
    opacity: 0;
    transform: translateX(-24px);
}
.twb-anim-media.twb-anim-media--slide-right:not(.twb-anim-play) {
    opacity: 0;
    transform: translateX(24px);
}
.twb-anim-media.twb-anim-media--pulse-out-in:not(.twb-anim-play) {
    opacity: 1;
    transform: scale(1);
}
.twb-anim-media.twb-anim-media--pulse-in-out:not(.twb-anim-play) {
    opacity: 1;
    transform: scale(1.2);
}

.twb-anim-media.twb-anim-media--fade.twb-anim-play {
    animation: twb-m-fade var(--twb-am-dur, 0.6s) ease var(--twb-am-delay, 0s) var(--twb-am-iter, 1) normal both;
}
.twb-anim-media.twb-anim-media--zoom-in.twb-anim-play {
    transform-origin: center center;
    animation: twb-m-zoom-in var(--twb-am-dur, 0.6s) ease-in-out var(--twb-am-delay, 0s) var(--twb-am-iter, 1) normal both;
}
.twb-anim-media.twb-anim-media--zoom-out.twb-anim-play {
    transform-origin: center center;
    animation: twb-m-zoom-out var(--twb-am-dur, 0.6s) ease-in-out var(--twb-am-delay, 0s) var(--twb-am-iter, 1) normal both;
}
.twb-anim-media.twb-anim-media--slide-left.twb-anim-play {
    animation: twb-m-slide-left var(--twb-am-dur, 0.6s) ease var(--twb-am-delay, 0s) var(--twb-am-iter, 1) normal both;
}
.twb-anim-media.twb-anim-media--slide-right.twb-anim-play {
    animation: twb-m-slide-right var(--twb-am-dur, 0.6s) ease var(--twb-am-delay, 0s) var(--twb-am-iter, 1) normal both;
}
/* pulse: 속도는 --twb-am-dur 한 사이클(0→50→100%) */
.twb-anim-media.twb-anim-media--pulse-out-in.twb-anim-play,
.twb-anim-media.twb-anim-media--pulse-in-out.twb-anim-play {
    transform-origin: center center;
}
.twb-anim-media.twb-anim-media--pulse-out-in.twb-anim-play {
    animation: twb-m-pulse-out-in var(--twb-am-dur, 0.6s) linear var(--twb-am-delay, 0s) var(--twb-am-iter, 1) normal both;
}
.twb-anim-media.twb-anim-media--pulse-in-out.twb-anim-play {
    animation: twb-m-pulse-in-out var(--twb-am-dur, 0.6s) linear var(--twb-am-delay, 0s) var(--twb-am-iter, 1) normal both;
}

/* 히어로 배경 레이어: cover + 클리핑 (스킨별 전용 클래스) */
.twb-hero-default__bg-layer,
.twb-hero-center__bg-layer {
    background-size: cover;
    background-position: center center;
    background-repeat: no-repeat;
}
.twb-hero-default:has(.twb-hero-default__bg-layer),
.twb-hero-center:has(.twb-hero-center__bg-layer) {
    overflow: hidden;
}

/*
 * AOS 2.x: aos.css의 [data-aos-duration] 미리 정의 값(대략 3000ms 이하)만 transition-duration에 연결됨.
 * PHP/미리보기에서 출력하는 ms(예: 미디어 m6=6초)는 --twb-aos-dur 로 강제 적용.
 * duration만 주고 transition-property 가 비어 있으면 transform 보간이 안 되어 줌이 ‘속도 안 먹음’처럼 보일 수 있음.
 */
[data-aos][style*="--twb-aos-dur"] {
    transition-property: opacity, transform !important;
    transition-duration: var(--twb-aos-dur) !important;
    transition-delay: var(--twb-aos-del, 0ms) !important;
    transition-timing-function: ease-out !important;
}

/*
 * 히어로 배경·비디오 AOS 줌 — 스킨 루트(.twb-hero-default / .twb-hero-center) + 레이어
 */
.twb-hero-default[data-aos="zoom-in"]:not(.aos-animate),
.twb-hero-default .twb-hero-default__bg-layer[data-aos="zoom-in"]:not(.aos-animate),
.twb-hero-default .twb-hero-default__video-bg[data-aos="zoom-in"]:not(.aos-animate),
.twb-hero-center[data-aos="zoom-in"]:not(.aos-animate),
.twb-hero-center .twb-hero-center__bg-layer[data-aos="zoom-in"]:not(.aos-animate),
.twb-hero-center .twb-hero-center__video-bg[data-aos="zoom-in"]:not(.aos-animate),
.twb-hero-slider__slide-img[data-aos="zoom-in"]:not(.aos-animate) {
    opacity: 1 !important;
    transform: scale(1) !important;
    transform-origin: center center;
}
.twb-hero-default[data-aos="zoom-in"].aos-animate,
.twb-hero-default .twb-hero-default__bg-layer[data-aos="zoom-in"].aos-animate,
.twb-hero-default .twb-hero-default__video-bg[data-aos="zoom-in"].aos-animate,
.twb-hero-center[data-aos="zoom-in"].aos-animate,
.twb-hero-center .twb-hero-center__bg-layer[data-aos="zoom-in"].aos-animate,
.twb-hero-center .twb-hero-center__video-bg[data-aos="zoom-in"].aos-animate,
.twb-hero-slider__slide-img[data-aos="zoom-in"].aos-animate {
    opacity: 1 !important;
    transform: scale(1.2) !important;
    transform-origin: center center;
}
.twb-hero-default[data-aos="zoom-out"]:not(.aos-animate),
.twb-hero-default .twb-hero-default__bg-layer[data-aos="zoom-out"]:not(.aos-animate),
.twb-hero-default .twb-hero-default__video-bg[data-aos="zoom-out"]:not(.aos-animate),
.twb-hero-center[data-aos="zoom-out"]:not(.aos-animate),
.twb-hero-center .twb-hero-center__bg-layer[data-aos="zoom-out"]:not(.aos-animate),
.twb-hero-center .twb-hero-center__video-bg[data-aos="zoom-out"]:not(.aos-animate),
.twb-hero-slider__slide-img[data-aos="zoom-out"]:not(.aos-animate) {
    opacity: 1 !important;
    transform: scale(1.2) !important;
    transform-origin: center center;
}
.twb-hero-default[data-aos="zoom-out"].aos-animate,
.twb-hero-default .twb-hero-default__bg-layer[data-aos="zoom-out"].aos-animate,
.twb-hero-default .twb-hero-default__video-bg[data-aos="zoom-out"].aos-animate,
.twb-hero-center[data-aos="zoom-out"].aos-animate,
.twb-hero-center .twb-hero-center__bg-layer[data-aos="zoom-out"].aos-animate,
.twb-hero-center .twb-hero-center__video-bg[data-aos="zoom-out"].aos-animate,
.twb-hero-slider__slide-img[data-aos="zoom-out"].aos-animate {
    opacity: 1 !important;
    transform: scale(1) !important;
    transform-origin: center center;
}

/*
 * aos.css [data-aos^=fade]{opacity:0} 가 슬라이드 배경 <img> 에도 적용되면 .aos-animate 전까지 이미지가 안 보이고 그라데이션만 보임.
 * zoom-* 는 위 블록에서 처리 — fade·fade-up 등 동일.
 */
[data-twb-hero-slider].twb-hero-slider .twb-hero-slider__slide-img[data-aos^="fade"] {
    opacity: 1 !important;
    transform: none !important;
}

/*
 * hero-slider: 레거시 data-twb-aos 도 :is 로 대응
 * slide 계열은 aos-animate 전 opacity:1 이었으나, AOS.init 전 FOUC 를 막기 위해 aos-prehide 동안은 아래 블록 끝의 규칙이 우선한다.
 */
[data-twb-hero-slider].twb-hero-slider:not(.twb-hero-slider--aos-prehide) :is([data-aos^="slide"], [data-twb-aos^="slide"]):not(.aos-animate) {
    opacity: 1;
}
/*
 * 활성 슬라이드 + aos-ready: 전환 시 refresh 에서 aos-animate 를 떼는 순간 위 규칙이 opacity 1 을 주어 텍스트가 한 프레임 보였다가 다시 애니되는 깜빡임이 난다.
 * 활성 슬라이드의 slide 타입은 aos-animate 가 붙기 전까지 fade 계열과 같이 숨김(특이도로 위 블록 덮어씀).
 */
/* slide-left/right 는 [data-aos^="slide"] 에 매칭됨 — 배경 .twb-hero-slider__slide-img 까지 숨기면 이미지가 안 보임 */
[data-twb-hero-slider].twb-hero-slider.twb-hero-slider--aos-ready .swiper-slide-active :is([data-aos^="slide"], [data-twb-aos^="slide"]):not(.aos-animate):not(.twb-hero-slider__slide-img) {
    opacity: 0;
    pointer-events: none;
}
/* 배경 <img>(.twb-hero-slider__slide-img)는 fade/zoom 등이 slide 접두어가 아니어 아래 규칙에만 걸리면 opacity:0 → 그라데이션만 보임(팝업 전체 미리보기 등). zoom-in/out 는 위 블록에서 이미 예외 처리됨 */
/* .hero-anim 텍스트는 twb-hero-slider-enter.css + JS 상태만 사용 — data-aos 잔존 시에도 여기서 숨기지 않음 */
[data-twb-hero-slider].twb-hero-slider
    :is([data-aos], [data-twb-aos]):not(:is([data-aos^="slide"], [data-twb-aos^="slide"])):not(.aos-animate):not(.twb-hero-slider__slide-img):not(.hero-anim) {
    opacity: 0;
}
[data-twb-hero-slider].twb-hero-slider
    :is([data-aos], [data-twb-aos]):not(:is([data-aos^="slide"], [data-twb-aos^="slide"])).aos-animate {
    opacity: 1;
}

/* hero-slider 활성 슬라이드: AOS transition 과 중복 보간 시 끝에서 미세 번쩍임 방지 — 배경 줌(data-aos=zoom-*) 은 transform 보간 필요 */
[data-twb-hero-slider].twb-hero-slider .swiper-slide-active :is([data-aos], [data-twb-aos]).aos-animate:not(.twb-hero-slider__slide-img) {
    transition: none !important;
}

[data-twb-hero-slider].twb-hero-slider .swiper-slide-active .twb-hero-slider__actions.aos-animate {
    isolation: isolate;
}

/* Swiper init 전 FOUC — twb-mainpage-public.css 와 동기. 준비 후 표시는 twb-hero-slider-enter.css 의 상태 클래스만 */
[data-twb-hero-slider].twb-hero-slider.twb-hero-slider--aos-prehide .twb-hero-slider__content > .hero-anim {
    opacity: 0 !important;
    visibility: hidden !important;
    transform: translate3d(0, 24px, 0) !important;
    pointer-events: none !important;
}

[data-twb-hero-slider].twb-hero-slider.twb-hero-slider--aos-prehide {
    transition: none !important;
}
