/**
 * AOSE WordPress
 * aose-motion.css
 *
 * AOSE 共通モーション
 * 対象：aose.jp / SWELL CHILD
 *
 * 役割：
 * - HERO 12秒 Zoom
 * - Reveal
 * - Card Reveal
 * - Hover
 * - Text Link Arrow
 * - Motion Stop / Pause UI
 * - prefers-reduced-motion
 * - JS失敗時の安全な初期表示
 *
 * 重要：
 * - CSSだけで本文を非表示にしない
 * - JSが正常に準備できた場合のみRevealを有効化する
 * - HERO Zoomは1回だけ
 * - HERO Zoomには停止操作を用意する
 * - Reduced Motion時は実質静止表示
 *
 * Based on:
 * 青清 AOSE WordPress再構築 全体設計仕様書 v1.0
 */


/* =========================================================
   1. MOTION BASE
   ========================================================= */

/*
 * Motion用の共通変数。
 *
 * 数値そのものの正本は
 * aose-tokens.css。
 */
.aose-page {
	--aose-reveal-distance: var(--aose-space-2);
}


/* =========================================================
   2. HERO ZOOM
   ========================================================= */

/*
 * 初期状態。
 *
 * JSが動かなければ
 * HERO画像は静止画のまま表示される。
 */
.aose-hero__media img {
	transform: scale(
		var(--aose-motion-hero-scale-start)
	);
	transform-origin: center center;
}


/*
 * HERO Zoomを使用するHEROには
 *
 * .aose-hero--zoom
 *
 * を付ける。
 *
 * さらにJSが正常に初期化された場合のみ、
 * ancestorへ .aose-motion-ready が付与されて
 * animationを開始する。
 */
.aose-motion-ready
.aose-hero--zoom
.aose-hero__media img {
	animation-name: aoseHeroZoom;
	animation-duration:
		var(--aose-motion-hero-duration);
	animation-timing-function:
		var(--aose-ease);
	animation-delay: 0s;
	animation-iteration-count: 1;
	animation-direction: normal;
	animation-fill-mode: forwards;
}


/*
 * HERO Zoom。
 *
 * 1 → 1.035
 * 1回のみ。
 */
@keyframes aoseHeroZoom {

	from {
		transform: scale(
			var(--aose-motion-hero-scale-start)
		);
	}

	to {
		transform: scale(
			var(--aose-motion-hero-scale-end)
		);
	}

}


/* =========================================================
   3. HERO PAUSE / STOP STATE
   ========================================================= */

/*
 * JSからPause状態にする。
 */
.aose-hero--zoom.is-paused
.aose-hero__media img {
	animation-play-state: paused;
}


/*
 * 完了後。
 *
 * JSからis-completeを付与する場合に使用。
 */
.aose-hero--zoom.is-complete
.aose-hero__media img {
	animation: none;
	transform: scale(
		var(--aose-motion-hero-scale-end)
	);
}


/*
 * 明示的にMotionを停止する状態。
 */
.aose-hero--zoom.is-motion-disabled
.aose-hero__media img {
	animation: none;
	transform: scale(1);
}


/* =========================================================
   4. HERO MOTION CONTROL
   ========================================================= */

/*
 * HEROの停止操作。
 *
 * 実際のbutton生成・aria-label・状態変更は
 * aose-motion.js側で行う。
 */
.aose-motion-control {
	position: absolute;
	right: var(--aose-space-3);
	bottom: var(--aose-space-3);
	z-index: 3;

	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: var(--aose-space-1);

	min-width: 44px;
	min-height: 44px;
	padding:
		0.5rem
		0.75rem;

	border:
		1px solid
		rgba(255, 255, 255, 0.72);
	border-radius: var(--aose-radius-pill);

	background:
		rgba(40, 38, 34, 0.48);

	color: var(--aose-color-white);

	font-family: var(--aose-font-ui);
	font-size: 0.8125rem;
	font-weight: var(--aose-font-weight-medium);
	line-height: 1.4;

	cursor: pointer;
}


/*
 * Keyboard Focus。
 */
.aose-motion-control:focus-visible {
	outline:
		2px solid
		var(--aose-color-white);
	outline-offset: 3px;
}


/* =========================================================
   5. REVEAL
   ========================================================= */

/*
 * 最重要：
 *
 * 通常状態では表示しておく。
 *
 * JS無効・JS失敗時でも
 * 本文やカードが消えない。
 */
.aose-reveal {
	opacity: 1;
	transform: none;
}


/*
 * Revealを使う準備が完全に整った場合だけ、
 *
 * .aose-motion-ready
 * .aose-motion-observer-ready
 *
 * の両方をancestorへ付ける。
 *
 * この2条件が揃ったときだけ
 * 初期非表示へ変更する。
 */
.aose-motion-ready.aose-motion-observer-ready
.aose-reveal {
	opacity: 0;
	transform:
		translateY(
			var(--aose-reveal-distance)
		);

	transition:
		opacity
		var(--aose-motion-reveal-duration)
		var(--aose-ease),

		transform
		var(--aose-motion-reveal-duration)
		var(--aose-ease);
}


/*
 * IntersectionObserverで
 * 表示領域へ入ったら
 * JSから .is-visible を付与する。
 */
.aose-motion-ready.aose-motion-observer-ready
.aose-reveal.is-visible {
	opacity: 1;
	transform: translateY(0);
}


/* =========================================================
   6. REVEAL VARIANTS
   ========================================================= */

/*
 * Fadeのみ。
 */
.aose-motion-ready.aose-motion-observer-ready
.aose-reveal--fade {
	opacity: 0;
	transform: none;
}


/*
 * Fade表示。
 */
.aose-motion-ready.aose-motion-observer-ready
.aose-reveal--fade.is-visible {
	opacity: 1;
	transform: none;
}


/*
 * 上方向からのReveal。
 */
.aose-motion-ready.aose-motion-observer-ready
.aose-reveal--up {
	transform:
		translateY(
			calc(
				var(--aose-reveal-distance) * -1
			)
		);
}


/*
 * 最終位置。
 */
.aose-motion-ready.aose-motion-observer-ready
.aose-reveal--up.is-visible {
	transform: translateY(0);
}


/* =========================================================
   7. CARD REVEAL
   ========================================================= */

/*
 * Card専用Reveal。
 *
 * duration 650ms。
 */
.aose-motion-ready.aose-motion-observer-ready
.aose-card.aose-reveal {
	transition-duration:
		var(--aose-motion-card-duration);
}


/*
 * Card Stagger。
 *
 * 大量のカードが長時間順次表示されないよう、
 * 最大3段階程度までを基本とする。
 */
.aose-reveal--delay-1 {
	--aose-reveal-delay:
		var(--aose-motion-card-delay);
}

.aose-reveal--delay-2 {
	--aose-reveal-delay:
		calc(
			var(--aose-motion-card-delay) * 2
		);
}

.aose-reveal--delay-3 {
	--aose-reveal-delay:
		calc(
			var(--aose-motion-card-delay) * 3
		);
}


/*
 * Delay適用。
 */
.aose-motion-ready.aose-motion-observer-ready
.aose-reveal--delay-1,
.aose-motion-ready.aose-motion-observer-ready
.aose-reveal--delay-2,
.aose-motion-ready.aose-motion-observer-ready
.aose-reveal--delay-3 {
	transition-delay:
		var(--aose-reveal-delay);
}


/*
 * 表示後はDelayを不要にする。
 */
.aose-motion-ready.aose-motion-observer-ready
.aose-reveal.is-visible {
	transition-delay:
		var(--aose-reveal-delay, 0ms);
}


/* =========================================================
   8. CARD HOVER
   ========================================================= */

/*
 * Hover可能なデバイスだけに適用する。
 *
 * Touch端末へhover依存を持ち込まない。
 */
@media (hover: hover) and (pointer: fine) {

	/*
	 * Card image
	 */
	.aose-card__media img {
		transition:
			transform
			var(--aose-motion-hover)
			var(--aose-ease);
	}


	/*
	 * Card hover
	 * scale 1.04
	 */
	.aose-card__link:hover
	.aose-card__media img {
		transform:
			scale(
				var(--aose-motion-card-image-scale)
			);
	}


	/*
	 * Card外枠。
	 */
	.aose-card {
		transition:
			box-shadow
			var(--aose-motion-hover)
			var(--aose-ease);
	}


	.aose-card:has(.aose-card__link:hover) {
		box-shadow:
			var(--aose-shadow-raised);
	}

}


/* =========================================================
   9. BUTTON HOVER
   ========================================================= */

@media (hover: hover) and (pointer: fine) {

	.aose-button {
		transition:
			transform
			var(--aose-motion-hover-fast)
			var(--aose-ease),

			box-shadow
			var(--aose-motion-hover-fast)
			var(--aose-ease),

			opacity
			var(--aose-motion-hover-fast)
			var(--aose-ease);
	}


	.aose-button:hover {
		box-shadow:
			var(--aose-shadow-raised);
	}


	.aose-button--primary:hover {
		opacity: 0.92;
	}


	.aose-button--secondary:hover {
		transform: translateY(-1px);
	}


	.aose-button--light:hover {
		opacity: 0.92;
	}

}


/* =========================================================
   10. TEXT LINK ARROW
   ========================================================= */

.aose-text-link::after {
	transform: translateX(0);
}


/*
 * Hover可能な端末だけ。
 */
@media (hover: hover) and (pointer: fine) {

	.aose-text-link::after {
		transition:
			transform
			var(--aose-motion-hover-fast)
			var(--aose-ease);
	}


	.aose-text-link:hover::after {
		transform:
			translateX(
				var(--aose-motion-arrow-distance)
			);
	}

}


/* =========================================================
   11. STORY / MEDIA HOVER
   ========================================================= */

/*
 * Story画像には通常、
 * 常時Hover Zoomを強制しない。
 *
 * 明示的に
 * .aose-media--interactive
 * を付けた場合だけ有効。
 */
@media (hover: hover) and (pointer: fine) {

	.aose-media--interactive img {
		transition:
			transform
			var(--aose-motion-hover)
			var(--aose-ease);
	}


	.aose-media--interactive:hover img {
		transform:
			scale(
				var(--aose-motion-card-image-scale)
			);
	}

}


/* =========================================================
   12. MOTION CONTROL HOVER
   ========================================================= */

@media (hover: hover) and (pointer: fine) {

	.aose-motion-control {
		transition:
			background-color
			var(--aose-motion-hover-fast)
			var(--aose-ease),

			border-color
			var(--aose-motion-hover-fast)
			var(--aose-ease);
	}


	.aose-motion-control:hover {
		background:
			rgba(40, 38, 34, 0.68);

		border-color:
			var(--aose-color-white);
	}

}


/* =========================================================
   13. REDUCED MOTION
   ========================================================= */

/*
 * OS / Browserで
 * 動きを減らす設定が有効な場合。
 *
 * HERO Zoom
 * Reveal
 * Hover Scale
 * Arrow Move
 *
 * を停止または実質無効化する。
 */
@media (prefers-reduced-motion: reduce) {

	/*
	 * HERO
	 */
	.aose-motion-ready
	.aose-hero--zoom
	.aose-hero__media img,
	.aose-hero--zoom
	.aose-hero__media img {
		animation: none;
		transform: scale(1);
	}


	/*
	 * Reveal
	 */
	.aose-motion-ready.aose-motion-observer-ready
	.aose-reveal,
	.aose-motion-ready.aose-motion-observer-ready
	.aose-reveal.is-visible {
		opacity: 1;
		transform: none;
		transition: none;
	}


	/*
	 * Card
	 */
	.aose-card,
	.aose-card__media img {
		transition: none;
	}


	.aose-card__link:hover
	.aose-card__media img {
		transform: none;
	}


	/*
	 * Button
	 */
	.aose-button,
	.aose-button:hover {
		transition: none;
		transform: none;
	}


	/*
	 * Text Link
	 */
	.aose-text-link::after,
	.aose-text-link:hover::after {
		transition: none;
		transform: none;
	}


	/*
	 * Interactive Media
	 */
	.aose-media--interactive img,
	.aose-media--interactive:hover img {
		transition: none;
		transform: none;
	}

}


/* =========================================================
   14. JS FAILURE SAFETY
   ========================================================= */

/*
 * 通常状態では
 *
 * opacity:1
 * transform:none
 *
 * が正本。
 *
 * JSが途中で失敗した場合、
 * aose-motion-ready /
 * aose-motion-observer-ready
 * をJS側で削除すれば
 * 即座に通常表示へ戻る。
 */


/*
 * 明示的なFallback状態。
 */
.aose-motion-fallback
.aose-reveal {
	opacity: 1 !important;
	transform: none !important;
	transition: none !important;
}


/*
 * Motion Fallback時のHERO。
 */
.aose-motion-fallback
.aose-hero--zoom
.aose-hero__media img {
	animation: none !important;
	transform: scale(1) !important;
}


/* =========================================================
   15. IMPLEMENTATION RULES
   ========================================================= */

/*
 * AOSE Motionでは以下を原則とする。
 *
 * 1.
 * HTMLの初期状態では
 * 本文・Card・Buttonを表示する。
 *
 * 2.
 * JSの準備が正常に完了してから
 * .aose-motion-ready を付ける。
 *
 * 3.
 * IntersectionObserverの準備完了後にのみ
 * .aose-motion-observer-ready を付ける。
 *
 * 4.
 * Reveal対象が表示領域へ入ったら
 * .is-visible を付与する。
 *
 * 5.
 * JSエラー時にはReady Classを解除し、
 * 必要なら .aose-motion-fallback を付ける。
 *
 * 6.
 * HERO Zoomは12秒・1回のみ。
 *
 * 7.
 * HERO Zoomを自動再ループさせない。
 *
 * 8.
 * HERO Zoomを使う場合は
 * 停止操作を実装する。
 *
 * 9.
 * 停止操作を実装・検証できない場合は
 * HEROを静止画とする。
 *
 * 10.
 * B/C型固定ページや通常投稿では
 * 不必要なRevealを大量に使用しない。
 *
 * 11.
 * 材料・STEP・営業情報等、
 * 重要な実用情報は初期表示を基本とする。
 *
 * 12.
 * Hoverがなくても
 * 内容・操作・リンク先が分かること。
 */