@charset "UTF-8";
/*
 * 演出のスタイル
 *
 * Figma「TOPページ-パソコン版」に書かれた赤字のメモを実装したもの。
 * 発火は js/scroll-fx.js が付ける .is-inview に任せ、ここは見た目だけを持つ。
 *
 * ── 動きの決まり ───────────────────────────────
 * 1. カーブは1つに統一する（--ease-soft）。
 *    速く動き出してゆっくり止まる形。止まり際が長いので、
 *    同じ距離でも「ぬるっ」と柔らかく見える。
 * 2. 跳ね返し（オーバーシュート）は原則使わない。
 *    Figma が「にょきっと」と指定したタブだけ、ごく浅く残す。
 * 3. 移動距離は小さく。24〜40px に収める。
 *    大きく動かすほど速度が要り、目が追えず固い印象になる。
 * 4. 横に並ぶものは順にずらす（--i）。同時に出ると「バン」と出て固い。
 * 5. 動かすのは opacity / transform だけ。
 *    幅・高さ・色・影を毎フレーム変えるとペイントが走ってカクつく。
 * ──────────────────────────────────────────
 */

:root {
	/* カーブ（--ease-soft）は tokens.css で定義。サイト全体で共通 */

	/* 出る速さ。大きいものほど長くする */
	--fx-fast: 0.7s;
	--fx-base: 0.95s;
	--fx-slow: 1.25s;

	/* 横に並ぶものをずらす量 */
	--fx-stagger: 70ms;
}

/* 並び順を受け取って遅らせる。--i が無ければ 0 */
.has-js [data-fx] {
	transition-delay: calc(var(--i, 0) * var(--fx-stagger));
}

/* ============================================================
 * 1. 下からフェードアップ
 * Figma:「角丸背景が、スクロールするとフェードアップ」(6136:429 / 6136:488 / 6125:406)
 * ========================================================== */

.has-js [data-fx="up"] {
	opacity: 0;
	translate: 0 32px;
	transition: opacity var(--fx-base) var(--ease-soft),
		translate var(--fx-base) var(--ease-soft);
	transition-delay: calc(var(--i, 0) * var(--fx-stagger));
}

.has-js [data-fx="up"].is-inview {
	opacity: 1;
	translate: 0 0;
}

/*
 * 帯の地色は ::before が持っているので、親に .is-inview が付いたら
 * 疑似要素のほうを動かす。面積が大きいぶんゆっくり出す。
 */
/*
 * ミウルのおうちの上端の波も、この ::before に一緒に描いてある（front-page-sections.css の .band--miuru::before）。
 * 以前は波だけ別の要素で最初から出ていて、地色があとからせり上がり、別々に出て見えた（2026-09-30）。
 */
.has-js [data-fx="up-band"]::before {
	opacity: 0;
	translate: 0 40px;
	transition: opacity var(--fx-slow) var(--ease-soft),
		translate var(--fx-slow) var(--ease-soft);
}

.has-js [data-fx="up-band"].is-inview::before {
	opacity: 1;
	translate: 0 0;
}

/* ============================================================
 * 2. 文字がぬるりと現れる
 * Figma:「テキストタイトルと本文が『文字がぬるりと現れる』」(6136:483 ほか)
 *        参考 https://b-risk.jp/blog/2021/01/anim-reference/
 *
 * 隠すのに clip-path は使えない（工程8の記録を参照）。
 * 可視領域が 0 になると IntersectionObserver が交差を認めず、永久に出てこない。
 * ========================================================== */

.has-js [data-fx="text"] {
	opacity: 0;
	translate: 0 20px;
	transition: opacity var(--fx-base) var(--ease-soft),
		translate var(--fx-base) var(--ease-soft);
	transition-delay: calc(var(--i, 0) * var(--fx-stagger));
}

.has-js [data-fx="text"].is-inview {
	opacity: 1;
	translate: 0 0;
}

/* ============================================================
 * 3. 一度だけ拡大→縮小
 * Figma:「各タイトルは最初だけ一度拡大→縮小する動き」(6103:545 / 6136:489 / 6136:490)
 * 指示どおり一度大きくなるが、行き過ぎは 3% に留めて柔らかく見せる。
 * ========================================================== */

.has-js [data-fx="pop"] {
	opacity: 0;
}

.has-js [data-fx="pop"].is-inview {
	opacity: 1;
	animation: mdn-pop var(--fx-base) var(--ease-soft) both;
}

@keyframes mdn-pop {
	0% {
		opacity: 0;
		scale: 0.94;
	}

	60% {
		opacity: 1;
		scale: 1.03;
	}

	100% {
		opacity: 1;
		scale: 1;
	}
}

/* ============================================================
 * 4. ミウルの影が下から登場
 * Figma:「初回のみスクロールすると ミウルの影が下から登場↑」(6113:698 ほか)
 *
 * .deco-layer__item でもあり、そちらが opacity: var(--op) を持っている。
 * こちらを後から読ませるわけにいかないのでクラスを足して詳細度で勝たせる。
 * 出たあとの濃さは Figma の指定値（--op）に戻す。
 * ========================================================== */

/*
 * 出るまでの時間は「遅れ（data-fx-delay）＋ ここのフェード」の合計で考える。
 * 合計が長いと、出切るころにはスクロールが進んで画面の外へ抜けてしまい、
 * 一度も見えないことになる（--fx-slow 1.25s ＋ 450ms で実際にそうなった）。
 */
.has-js .deco-layer__item[data-fx="shade"] {
	opacity: 0;
	translate: 0 40%;
	transition: opacity var(--fx-fast) var(--ease-soft),
		translate var(--fx-fast) var(--ease-soft);
}

.has-js .deco-layer__item[data-fx="shade"].is-inview {
	opacity: var(--op, 1);
	translate: 0 0;
}

/* ============================================================
 * 5. ランキングのタブが下からにょきっと
 * Figma:「ランキングタブも最初は少し上ににょきっとでてくる動き」(6124:405)
 * ここだけ「にょきっと」の指定があるので、浅い跳ね返しを残す。
 * ========================================================== */

.has-js [data-fx="tab"] {
	opacity: 0;
	translate: 0 20px;
	transition: opacity var(--fx-fast) var(--ease-soft),
		translate var(--fx-fast) cubic-bezier(0.22, 1.2, 0.36, 1);
}

.has-js [data-fx="tab"].is-inview {
	opacity: 1;
	translate: 0 0;
}

/* ============================================================
 * 6. 順位アイコンは一度大きく、白枠は一度小さく
 * Figma:「ランキング番号アイコンは、一度大きくなりつつ 白外枠は、一度ちいさくなる動き」(6113:701)
 *        参考 https://b-risk.jp/blog/2021/11/hover-reference/
 * ========================================================== */

.has-js [data-fx="rank"] {
	opacity: 0;
}

.has-js [data-fx="rank"].is-inview {
	opacity: 1;
	animation: mdn-rank-shrink var(--fx-base) var(--ease-soft) both;
	animation-delay: calc(var(--i, 0) * var(--fx-stagger));
}

.has-js [data-fx="rank"].is-inview .info-card__rank {
	animation: mdn-rank-grow var(--fx-base) var(--ease-soft) both;
	animation-delay: calc(var(--i, 0) * var(--fx-stagger));
}

@keyframes mdn-rank-grow {
	0% {
		scale: 0.8;
	}

	55% {
		scale: 1.14;
	}

	100% {
		scale: 1;
	}
}

@keyframes mdn-rank-shrink {
	0% {
		opacity: 0;
		scale: 1.04;
	}

	60% {
		opacity: 1;
		scale: 0.99;
	}

	100% {
		opacity: 1;
		scale: 1;
	}
}

/* ============================================================
 * 7. 帯の地色がスクロールで白⇄黄緑に変わる
 * Figma:「背景はスクロールするときに白から黄緑へふわっと変わる」(6122:403)
 *        「背景はスクロールするときに黄緑から白へふわっと変わる」(6136:417)
 *
 * js/scroll-fx.js が帯の通過具合を --p（0〜1）で渡してくる。
 *
 * グラデーションを毎フレーム作り直すとそのたびにペイントが走る。
 * 行き先の色をもう1枚重ねておいて、その opacity だけを動かす。
 * 不透明度の変化は合成で済むので、スクロール中でも重くならない。
 * ========================================================== */

.has-js [data-fx-shift]::after {
	content: "";
	position: absolute;
	inset: 0;
	opacity: var(--p, 0);
	z-index: -2;
	pointer-events: none;
}

.has-js [data-fx-shift="to-green"]::after {
	background: rgb(202 238 171 / 30%);
}

.has-js [data-fx-shift="to-white"]::after {
	background: var(--midori-band-light);
}

/* ============================================================
 * 8. 背景の模様をゆっくり動かす
 * Figma:「背景の模様はゆったりうごいていてほしい」(6124:404 / 6136:430)
 *        参考 https://zenn.dev/nishinoshake/articles/da07f2735c0d9f
 *
 * 揃って動くと機械的に見えるので、周期・向き・開始位置をずらして
 * それぞれ勝手に漂っているようにする。
 * 動かすのは translate / rotate / scale だけなので合成で済む。
 * ========================================================== */

/*
 * ⚠️ `005 *` の丸い塊も、帯の中の飾りと同じ「4点を巡る経路」にしてある（2026-09-18）。
 * ⚠️ 画像名が `deco-leaf.png` だが**葉ではなく丸い塊**（雲のような丸が重なった形）。
 *    「緑区をもっと知ろう！楽しもう！」の背後などに敷いてある、あの飾り。
 *
 * 以前は `mdn-drift` 1本を `alternate` で往復させていたが、
 *   - 6枚とも同じ向き（右上へ）にしか動かない
 *   - 38秒かけて 21px ＝ **0.56px/秒** で、止まっているようにしか見えない
 * という状態だった。往復は同じ線の上を行き来するだけなので規則も読めてしまう。
 *
 * いまは a〜d の4経路を配り、向き・周期・開始位置をばらしている。
 * 周期は割り切れない数にして、揃って同じ位置に戻らないようにする。
 *
 * ⚠️ `will-change` は **`translate, rotate, scale`**。
 *    `transform` と書いても個別プロパティには効かない（前はこれを間違えていた）。
 */
.deco-layer__item:not([data-fx]) {
	will-change: translate, rotate, scale;
}

.deco-layer__item:not([data-fx]):nth-child(4n + 1) {
	animation: mdn-leaf-a 47s ease-in-out infinite;
}

.deco-layer__item:not([data-fx]):nth-child(4n + 2) {
	animation: mdn-leaf-b 53s ease-in-out -13s infinite;
}

.deco-layer__item:not([data-fx]):nth-child(4n + 3) {
	animation: mdn-leaf-c 59s ease-in-out -19s infinite;
}

.deco-layer__item:not([data-fx]):nth-child(4n) {
	animation: mdn-leaf-d 67s ease-in-out -29s infinite;
}

/*
 * ⚠️ 丸い塊は6枚なので、4経路を配ると 5・6枚目が 1・2枚目と**完全に同期**する
 *    （同じ経路・同じ周期・同じ開始位置）。周期と開始位置をずらして重なりを外す。
 *    周期は 47 / 53 / 59 / 67 / 49 / 73 と、割り切れない組み合わせにしてある。
 */
.deco-layer__item:not([data-fx]):nth-child(5) {
	animation-duration: 49s;
	animation-delay: -23s;
}

.deco-layer__item:not([data-fx]):nth-child(6) {
	animation-duration: 73s;
	animation-delay: -37s;
}

/*
 * 振れ幅は ±115px まで（2026-09-18 に ±48 → ±75 → ±115px と広げた）。
 *
 * ⚠️ 丸い塊の画像は**絵が端まで詰まっていて透明の余白が無い**（実測 左0 右1 上1 下0px）。
 *    大きく動かすと、箱（`.deco-layer` は overflow:hidden）の外に出ていた辺が
 *    内側に入り、絵の直線的な縁が見えることがある。
 *    ただし不透明度10%の背景飾りなので、多少入っても実害は出ない。
 *    **広げるときは経路を一周させて「内側に入る最大量」を測ってから決めること。**
 *
 * 速くなりすぎないよう、振れ幅を 1.6 倍にしたぶん周期も伸ばしてある。
 *
 * scale は 1 以上にしか振らない（縮めると同じ理由で縁が内側へ入る）。
 * 絵が 650px 近いので、1.07 の膨らみが「動いている」ことを伝える。
 * 経由点の % も等間隔にしない。
 */
@keyframes mdn-leaf-a {
	0% { translate: 0 0; scale: 1; rotate: 0deg; }
	24% { translate: 107px -64px; scale: 1.07; rotate: 2.2deg; }
	53% { translate: 46px 101px; scale: 1.03; rotate: -1.7deg; }
	76% { translate: -90px 41px; scale: 1.1; rotate: 1.1deg; }
	100% { translate: 0 0; scale: 1; rotate: 0deg; }
}

@keyframes mdn-leaf-b {
	0% { translate: 0 0; scale: 1; rotate: 0deg; }
	24% { translate: -83px 95px; scale: 1.1; rotate: -2.1deg; }
	53% { translate: 69px 110px; scale: 1.04; rotate: 1.5deg; }
	76% { translate: 113px -54px; scale: 1.06; rotate: -1deg; }
	100% { translate: 0 0; scale: 1; rotate: 0deg; }
}

@keyframes mdn-leaf-c {
	0% { translate: 0 0; scale: 1; rotate: 0deg; }
	24% { translate: 52px 115px; scale: 1.04; rotate: 1.7deg; }
	53% { translate: -110px 58px; scale: 1.1; rotate: -1.4deg; }
	76% { translate: -64px -93px; scale: 1.03; rotate: 2.1deg; }
	100% { translate: 0 0; scale: 1; rotate: 0deg; }
}

@keyframes mdn-leaf-d {
	0% { translate: 0 0; scale: 1; rotate: 0deg; }
	24% { translate: -73px -103px; scale: 1.03; rotate: 1.4deg; }
	53% { translate: 101px -37px; scale: 1.07; rotate: -2.2deg; }
	76% { translate: 61px 98px; scale: 1.1; rotate: 1deg; }
	100% { translate: 0 0; scale: 1; rotate: 0deg; }
}

/*
 * 帯の中に切り抜いてある丸い飾り（Figma の 001 / 002）。
 *
 * 往復（alternate）だと同じ線の上を行き来するだけなので、
 * しばらく見ていると規則が読めてしまう。
 * **4点を巡る経路**にして、始点と終点を同じにしてある。
 * こうすると infinite で切れ目なく回り続け、行き先が読めない。
 *
 * ランダムに見せているのは、4点それぞれに
 *   別の経路（a〜d）／別の周期（72〜96秒）／負の delay で別の開始位置
 * を与えているから。CSS だけで本当の乱数は引けないので、
 * 周期を割り切れない数にして、揃って同じ位置に戻らないようにしている。
 *
 * 経由点の % も等間隔にしない（22 / 48 / 71）。等間隔だと拍が揃って
 * 「一定のリズムで動いている」と分かってしまう。
 *
 * 動かすのは translate と rotate だけなので合成で済む。
 * 絵が大きいぶん 30px 程度でもゆったりした移動に見える。
 */
.band__deco img,
.ranking__deco-box {
	/* transform ではなく個別プロパティを使っているので、指定もそちらに合わせる */
	will-change: translate, rotate, scale;
}

/*
 * ⚠️ ピックアップ／イベント情報の帯の中の飾り（`001 *`）は**動かさない**（2026-09-18 の依頼）。
 *    ここだけ不透明度50%で目立つため、動かすと「背景がここだけ動いている」ように見えていた。
 *    動かすのは背景の丸い塊（`005 *`）のほう。
 *    戻すときは下の2行のコメントを外す。
 */
/*
.band__deco img:nth-child(1) {
	animation: mdn-float-a 46s ease-in-out infinite;
}

.band__deco img:nth-child(2) {
	animation: mdn-float-b 58s ease-in-out -23s infinite;
}
*/

.ranking__deco-box:nth-child(1) {
	animation: mdn-float-c 62s ease-in-out -41s infinite;
}

.ranking__deco-box:nth-child(2) {
	animation: mdn-float-d 52s ease-in-out -14s infinite;
}

/*
 * 移動に加えて、ゆっくり膨らむ scale を混ぜてある。
 * 平行移動だけだと、絵が大きいぶん数十px 動いても「動いている」と気づけない。
 * 少し息をするように伸び縮みすると、目を向けたときに動きが分かる。
 *
 * scale は **1 以上にしか振らない**（縮めない）。縮めると絵の端が箱の内側へ入ってきて、
 * 箱の縁に切れ目が見えることがあるため。膨らむ側なら必ず外へ出る。
 * ピークの位置も4つでずらす（揃って膨らむと呼吸を合わせたように見える）。
 */
@keyframes mdn-float-a {
	0% { translate: 0 0; scale: 1; rotate: 0deg; }
	22% { translate: 52px -30px; scale: 1.03; rotate: 1deg; }
	48% { translate: 24px 48px; scale: 1.01; rotate: -0.8deg; }
	71% { translate: -44px 20px; scale: 1.04; rotate: 0.6deg; }
	100% { translate: 0 0; scale: 1; rotate: 0deg; }
}

@keyframes mdn-float-b {
	0% { translate: 0 0; scale: 1; rotate: 0deg; }
	22% { translate: -38px 35px; scale: 1.04; rotate: -0.9deg; }
	48% { translate: 31px 50px; scale: 1.01; rotate: 0.7deg; }
	71% { translate: 48px -26px; scale: 1.03; rotate: -0.4deg; }
	100% { translate: 0 0; scale: 1; rotate: 0deg; }
}

@keyframes mdn-float-c {
	0% { translate: 0 0; scale: 1; rotate: 0deg; }
	22% { translate: 22px 53px; scale: 1.02; rotate: 0.8deg; }
	48% { translate: -50px 26px; scale: 1.04; rotate: -0.6deg; }
	71% { translate: -28px -41px; scale: 1.01; rotate: 1deg; }
	100% { translate: 0 0; scale: 1; rotate: 0deg; }
}

@keyframes mdn-float-d {
	0% { translate: 0 0; scale: 1; rotate: 0deg; }
	22% { translate: -33px -45px; scale: 1.01; rotate: 0.6deg; }
	48% { translate: 45px -17px; scale: 1.03; rotate: -1deg; }
	71% { translate: 29px 43px; scale: 1.04; rotate: 0.4deg; }
	100% { translate: 0 0; scale: 1; rotate: 0deg; }
}

/* ============================================================
 * 9. カードの動き（Figma 側が「もしできたら」と書いていたもの）
 * Figma: 6116:391 / 参考 https://nicoli.jp
 * 触ったときに、カードが浮いて写真だけ少し寄る。
 *
 * will-change は常時つけない（数が多く、メモリを取るほうが害になる）。
 * 触れた時点で合成レイヤーに乗れば間に合う。
 * ========================================================== */

.info-card,
.course-card,
.pickup-card {
	transition: translate 0.45s var(--ease-soft), box-shadow 0.45s var(--ease-soft);
}

.info-card__photo,
.course-card__photo,
.pickup-card__photo {
	transition: scale 0.6s var(--ease-soft);
}

.info-card__link,
.course-card__link,
.pickup-card__link {
	display: block;
	overflow: hidden;
}

.info-card:hover,
.course-card:hover,
.pickup-card:hover {
	translate: 0 -5px;
	box-shadow: 0 10px 22px rgb(14 104 46 / 12%);
}

.info-card:hover .info-card__photo,
.course-card:hover .course-card__photo,
.pickup-card:hover .pickup-card__photo {
	scale: 1.04;
}

/* ============================================================
 * 10. 動きを減らす設定の人には出さない
 * ========================================================== */

@media (prefers-reduced-motion: reduce) {
.has-js [data-fx],
.has-js [data-fx="up-band"]::before {
		opacity: 1 !important;
		translate: none !important;
		scale: none !important;
		animation: none !important;
		transition: none !important;
		transition-delay: 0s !important;
	}

.has-js [data-fx-shift]::after {
		opacity: 0 !important;
	}

	.deco-layer__item,
	.band__deco img,
	.ranking__deco-box,
	.cat-card__band,
	.info-card,
	.course-card,
	.pickup-card,
	.info-card__photo,
	.course-card__photo,
	.pickup-card__photo {
		animation: none !important;
		transition: none !important;
	}

	.info-card:hover,
	.course-card:hover,
	.pickup-card:hover {
		translate: none;
		box-shadow: none;
	}
}
