/* JS(useReveal)가 data-reveal="mask" 요소를 감싸는 overflow:hidden 마스크 */
.reveal-mask {
	overflow: hidden;
}

/* ------------------------------------------------------------------
 * Reveal 등장 모션
 * JS(useReveal)는 뷰포트 진입 시 .is-reveal 만 붙인다.
 * "어떤 모션이냐"는 여기서 data-reveal 속성값으로 분기한다.
 * 각 변형은 자기 숨김 상태(.is-reveal 이전)를 전부 명시한다
 * → 우선순위(specificity) 충돌 없이 독립적으로 동작한다.
 *
 *   - data-reveal            : 기본 (아래→위 슬라이드 + 페이드)
 *   - data-reveal="blur"     : 기본 + 블러
 *   - data-reveal="mask"     : 마스크 안에서 아래에서 완전히 올라옴 (JS가 래핑)
 *   - data-reveal="custom"   : JS/CSS 모두 관여 안 함 (직접 처리)
 * ------------------------------------------------------------------ */

/* 공통 전환 규칙 (custom 제외 모든 reveal)
 *
 * ⚠️ will-change 는 값이 남아 있는 동안 그 요소를 쌓임 맥락(stacking context)으로 만든다.
 *    transform 이 없어도 그렇다. 그대로 두면 등장이 끝난 뒤에도 형제 블록이 저마다 맥락이 되어
 *    DOM 뒤쪽 블록이 앞쪽을 덮고, 앞쪽 자식의 z-index 는 그 벽을 넘지 못한다
 *    (영아트페어 연도 드롭다운이 수상작 슬라이더에 가려졌던 원인 · 2026-08-10).
 *    그래서 useReveal 이 transitionend 시점에 will-change: auto 로 거둔다.
 *    여기서 지우면 등장 직전 레이어 승격 힌트가 사라지므로 CSS 는 그대로 두고 JS 가 푼다.
 */
[data-reveal]:not([data-reveal='custom']) {
	transition:
		opacity 0.6s ease-out,
		transform 0.6s ease-out,
		filter 0.6s ease-out;
	will-change: opacity, transform, filter;
}

/* 기본: 슬라이드 + 페이드 (data-reveal, 값 없음) */
[data-reveal='']:not(.is-reveal) {
	opacity: 0;
	transform: translateY(20px);
}

/* blur: 슬라이드 + 페이드 + 블러 */
[data-reveal='blur']:not(.is-reveal) {
	opacity: 0;
	transform: translateY(20px);
	filter: blur(5px);
}

/* mask: 감싸이기 전(JS 래핑 전)엔 잘못된 위치 노출을 막기 위해 숨김만 */
[data-reveal='mask']:not(.is-reveal) {
	opacity: 0;
}

/* mask: 마스크로 감싸인 뒤 — 아래에서 완전히 올라오는 슬라이드 */
.reveal-mask > [data-reveal='mask']:not(.is-reveal) {
	opacity: 1;
	transform: translateY(100%);
}
