/* ZQ STAGE4 手応え — 第2段・第3段の層 v1.19.2（2026-08-25）
 * 衝撃リング ／ 放射線 ／ 火花 ／ 画面端の閃光 ／ CHAIN表示 ／ FULL COMBO
 *
 * ★stage4-combo.css（第1段＝ヒットストップ・揺れ・数字）の上に**足すだけ**。
 *   第1段だけでも成立するように分けてあります。このファイルを外しても壊れません。
 *
 * ────────────────────────────────────────────
 * 市販ゲームが「濃い」理由は、絵が上手いからではありません。
 * ────────────────────────────────────────────
 * 1回の命中に**層を重ねている**からです。ただし全部を同時に出すと画面が潰れるので、
 * 層ごとに**始まる時刻と消える速さを変えます。** 速いものほど短く、遅いものほど長い。
 *
 *   リング     0ms 開始 / 420ms   いちばん速い。「点」を「面」に変える
 *   放射線     0ms 開始 / 300ms   速度感。短くないとうるさい
 *   火花       0ms 開始 / 560ms   散り方に個体差をつける
 *   画面端     20ms 開始 / 300ms  周辺視野に訴える。中央を汚さない
 *   揺れ       80ms 開始 / 240ms  第1段
 *   数字       120ms 開始 / 660ms いちばん遅くて長い
 *
 * ★この「速いものほど短い」を守らないと、混ざって泥のように見えます。
 *
 * ────────────────────────────────────────────
 * ★光過敏性発作について（教育現場なので譲れない）
 * ────────────────────────────────────────────
 * ・**繰り返す明滅はこのファイルに1つもありません。** infinite は0個。
 * ・明るく光る層（画面端・FULL COMBOの白飛び）は、いずれも
 *   **1回の発火につき1往復だけ**で、最大不透明度を抑えてあります。
 * ・FULL COMBO には JS 側で 1.2秒 の再発火止めを入れてあります。
 *   連打しても「1秒に3回以上の点滅」にはなりません。
 */

/* ============================================================
 * 共通の器。★1枚だけ作って使い回す。毎回作ると箱が溜まる。
 * ========================================================== */
.zqcb-layer {
	position: fixed;
	inset: 0;
	z-index: 54;              /* ミラボ(60)より後ろ。数字(55)よりさらに後ろ */
	pointer-events: none;     /* ★絶対にクリックを奪わない */
	overflow: hidden;
	contain: strict;          /* 中身の再計算を外に漏らさない（9〜20台対策） */
}

/* ============================================================
 * ① 衝撃リング — 点を面に変える。いちばん速い層
 * ========================================================== */
.zqcb-ring {
	position: absolute;
	left: 0;
	top: 0;
	width: var(--zqcb-r, 120px);
	height: var(--zqcb-r, 120px);
	margin-left: calc(var(--zqcb-r, 120px) / -2);
	margin-top: calc(var(--zqcb-r, 120px) / -2);
	border-radius: 50%;
	border: 3px solid rgba(255, 214, 140, .9);
	box-shadow:
		0 0 18px rgba(255, 170, 60, .55),
		inset 0 0 18px rgba(255, 170, 60, .35);
	/* ★加算合成。これが無いと「光」ではなく「絵の具」に見えます。
	   本番の画面で見て分かりました。ふつうに重ねると、盤面の上に
	   灰色の板を置いたようになり、カードの文字まで濁ります。 */
	mix-blend-mode: screen;
	animation: zqcb-ring 420ms cubic-bezier(.12, .78, .26, 1) 1 both;
	will-change: transform, opacity;
}

@keyframes zqcb-ring {
	0% { opacity: 0; transform: scale(.18); border-width: 6px; }
	14% { opacity: 1; }
	100% { opacity: 0; transform: scale(1); border-width: 1px; }
}

/* 2枚目を遅らせて重ねると厚みが出る。★同じ形を2回ではなく、速度を変える */
.zqcb-ring.b {
	border-color: rgba(255, 255, 255, .55);
	animation-duration: 300ms;
	animation-delay: 60ms;
}

/* ============================================================
 * ② 放射線 — 速度感。★短くしないとうるさい
 *   conic-gradient 1枚で描く。線を何本も DOM で作らない（軽さのため）
 * ========================================================== */
.zqcb-rays {
	position: absolute;
	left: 0;
	top: 0;
	width: var(--zqcb-ray, 620px);
	height: var(--zqcb-ray, 620px);
	margin-left: calc(var(--zqcb-ray, 620px) / -2);
	margin-top: calc(var(--zqcb-ray, 620px) / -2);
	border-radius: 50%;
	/* ★repeating- を付けること。
	   conic-gradient は最後の停止位置より先を**繰り返さず、最後の色で埋めます。**
	   90度分だけ書いていたら、線が画面の4分の1にしか出ませんでした（本番の画面で発覚）。
	   周期 15度 ＝ 24本。太さと間隔をばらして、機械的な放射状に見えないようにする。 */
	background: repeating-conic-gradient(from 0deg,
			rgba(255, 232, 180, .62) 0deg 1.2deg,
			transparent 1.2deg 5.5deg,
			rgba(255, 220, 150, .34) 5.5deg 6.4deg,
			transparent 6.4deg 10deg,
			rgba(255, 240, 200, .50) 10deg 10.8deg,
			transparent 10.8deg 15deg);
	/* 内側は空ける（中心が潰れる）、外側は早めに消す（盤面の下まで届かせない） */
	-webkit-mask-image: radial-gradient(circle, transparent 10%, #000 26%, rgba(0, 0, 0, .55) 48%, transparent 66%);
	mask-image: radial-gradient(circle, transparent 10%, #000 26%, rgba(0, 0, 0, .55) 48%, transparent 66%);
	mix-blend-mode: screen;   /* ★光として重ねる。ふつうに重ねると灰色の板になる */
	opacity: .8;
	animation: zqcb-rays 300ms cubic-bezier(.1, .8, .3, 1) 1 both;
	will-change: transform, opacity;
}

@keyframes zqcb-rays {
	0% { opacity: 0; transform: scale(.3) rotate(0deg); }
	18% { opacity: .95; }
	100% { opacity: 0; transform: scale(1.05) rotate(9deg); }
}

/* ============================================================
 * ③ 火花 — ★散り方に個体差をつける。全部同じだと花火のイラストに見える
 *   飛ぶ向き・距離・大きさ・速さは JS が1粒ずつ変数で渡す
 * ========================================================== */
.zqcb-spark {
	position: absolute;
	left: 0;
	top: 0;
	width: var(--zqcb-sw, 4px);
	height: var(--zqcb-sh, 4px);
	border-radius: 2px;
	background: var(--zqcb-sc, #ffd27a);
	box-shadow: 0 0 10px rgba(255, 190, 90, .95);
	mix-blend-mode: screen;   /* ★光として重ねる */
	animation: zqcb-spark var(--zqcb-sd, 520ms) cubic-bezier(.14, .7, .2, 1) 1 both;
	will-change: transform, opacity;
}

@keyframes zqcb-spark {
	0% { opacity: 0; transform: translate3d(0, 0, 0) scale(.5); }
	10% { opacity: 1; transform: translate3d(calc(var(--zqcb-dx, 40px) * .18), calc(var(--zqcb-dy, 40px) * .18), 0) scale(1.15); }
	/* 途中で失速し、最後に少し落ちる。重力があるように見える */
	70% { opacity: .9; transform: translate3d(calc(var(--zqcb-dx, 40px) * .92), calc(var(--zqcb-dy, 40px) * .92 + 10px), 0) scale(.8); }
	100% { opacity: 0; transform: translate3d(var(--zqcb-dx, 40px), calc(var(--zqcb-dy, 40px) + 26px), 0) scale(.4); }
}

/* ============================================================
 * ④ 画面端の閃光 — ★中央を汚さずに「強さ」を伝える
 *   周辺視野は明るさの変化に敏感なので、端だけで十分効きます
 * ========================================================== */
.zqcb-vig {
	position: absolute;
	inset: 0;
	background: radial-gradient(ellipse at center,
			transparent 52%,
			rgba(255, 140, 40, var(--zqcb-vo, .22)) 88%,
			rgba(255, 90, 20, calc(var(--zqcb-vo, .22) * 1.4)) 100%);
	mix-blend-mode: screen;   /* ★光として重ねる */
	animation: zqcb-vig 300ms ease-out 1 both;
	animation-delay: 20ms;
}

@keyframes zqcb-vig {
	0% { opacity: 0; }
	22% { opacity: 1; }
	100% { opacity: 0; }
}

/* ============================================================
 * ⑤ CHAIN 表示
 *   ★数字（-100）とぶつからないよう、**上に**置いて色を変える。
 *     同じ場所に2つ出すと、どちらも読めません。
 * ========================================================== */
.zqcb-chain {
	position: fixed;
	z-index: 56;
	pointer-events: none;
	font-weight: 900;
	font-size: 30px;
	line-height: 1;
	letter-spacing: .06em;
	color: #bfe9ff;
	text-shadow:
		0 2px 0 #05304a,
		0 0 14px rgba(120, 210, 255, .9),
		0 0 34px rgba(60, 170, 255, .55);
	animation: zqcb-chain 820ms cubic-bezier(.16, .9, .3, 1) 1 both;
	will-change: transform, opacity;
}

.zqcb-chain.n3 {
	font-size: 38px;
	color: #ffd9f2;
	text-shadow:
		0 2px 0 #4a0533,
		0 0 16px rgba(255, 130, 220, .9),
		0 0 40px rgba(255, 60, 190, .55);
}

@keyframes zqcb-chain {
	0% { opacity: 0; transform: translate(-50%, 8px) scale(.55) skewX(-10deg); }
	14% { opacity: 1; transform: translate(-50%, 0) scale(1.22) skewX(4deg); }
	26% { transform: translate(-50%, 0) scale(1) skewX(0deg); }
	72% { opacity: 1; transform: translate(-50%, -6px) scale(1); }
	100% { opacity: 0; transform: translate(-50%, -22px) scale(.96); }
}

/* ============================================================
 * ⑥ FULL COMBO
 *   設計書は3秒。★v2 の音が 5.2秒だったので、**絵を3.0秒に合わせて音を切る**方針。
 *   絵の都合で音を伸ばすのではなく、画面に音を合わせる。
 * ========================================================== */

/* 白飛び。★1回だけ。最大 .72 に抑える（真っ白にはしない） */
.zqcb-white {
	position: absolute;
	inset: 0;
	background: #fff;
	animation: zqcb-white 620ms cubic-bezier(.2, .9, .3, 1) 1 both;
}

@keyframes zqcb-white {
	0% { opacity: 0; }
	8% { opacity: .72; }
	100% { opacity: 0; }
}

/* 7列が順に光る。JS が --zqcb-i（0〜6）で遅らせる */
.zqcb-col {
	animation: zqcb-col 520ms ease-out 1 both;
	animation-delay: calc(var(--zqcb-i, 0) * 62ms);
}

@keyframes zqcb-col {
	0% { box-shadow: 0 0 0 0 rgba(255, 226, 150, 0); }
	30% { box-shadow: 0 0 0 4px rgba(255, 226, 150, .95), 0 0 26px 8px rgba(255, 180, 60, .7); }
	100% { box-shadow: 0 0 0 0 rgba(255, 226, 150, 0); }
}

/* 中央の大書き */
.zqcb-title {
	position: fixed;
	/* left は JS が命中点に合わせて入れる（ミラボが開いていると盤面の中心がずれるため）。
	   50% 固定にすると、ミラボの下に半分隠れます。 */
	z-index: 57;
	pointer-events: none;
	text-align: center;
	white-space: nowrap;
	animation: zqcb-title 1700ms cubic-bezier(.15, .9, .25, 1) 1 both;
	will-change: transform, opacity;
}

.zqcb-title b {
	display: block;
	font-size: 52px;
	font-weight: 900;
	letter-spacing: .04em;
	line-height: 1;
	color: #fff3cf;
	text-shadow:
		0 3px 0 #6b3200,
		0 0 20px rgba(255, 200, 90, .95),
		0 0 60px rgba(255, 140, 20, .6);
}

.zqcb-title i {
	display: block;
	margin-top: 10px;
	font-size: 15px;
	font-style: normal;
	letter-spacing: .22em;
	color: #ffd9a0;
	opacity: .92;
}

@keyframes zqcb-title {
	0% { opacity: 0; transform: translate(-50%, 14px) scale(.86); letter-spacing: .3em; }
	10% { opacity: 1; transform: translate(-50%, 0) scale(1.04); }
	18% { transform: translate(-50%, 0) scale(1); }
	78% { opacity: 1; transform: translate(-50%, 0) scale(1); }
	100% { opacity: 0; transform: translate(-50%, -16px) scale(.98); }
}

/* ============================================================
 * ★動きが苦手な人（prefers-reduced-motion）
 *   飛ぶもの・回るもの・光るものを全部止めます。
 *   ただし「何が起きたか」は残す＝CHAIN と FULL COMBO の文字だけ静かに出す。
 * ========================================================== */
@media (prefers-reduced-motion: reduce) {

	.zqcb-ring,
	.zqcb-rays,
	.zqcb-spark,
	.zqcb-vig,
	.zqcb-white,
	.zqcb-col {
		display: none !important;
	}

	.zqcb-chain,
	.zqcb-title {
		animation: zqcb-calm 900ms linear 1 both;
	}

	@keyframes zqcb-calm {
		0% { opacity: 0; transform: translate(-50%, 0); }
		12% { opacity: 1; transform: translate(-50%, 0); }
		80% { opacity: 1; transform: translate(-50%, 0); }
		100% { opacity: 0; transform: translate(-50%, 0); }
	}
}

/* 画面が狭いとき */
@media (max-width: 560px) {
	.zqcb-title b { font-size: 34px; }
	.zqcb-title i { font-size: 12px; letter-spacing: .16em; }
	.zqcb-chain { font-size: 24px; }
	.zqcb-chain.n3 { font-size: 30px; }
}
