/**
 * play-juice.css — the shared motion library (visual-identity.md §6, decision V4).
 *
 * Sibling to play-polish.css; loaded after it and scoped to body.play-app. These are the
 * CSS halves of the window.TPQJuice primitives (play-juice.js): route transitions, the
 * loot-reveal pop/burst, level-up flourish, floating numbers, reward bursts, hitstop,
 * tactile press, idle micro-motion — plus the .tpq-scene-vignette composition helper (§7).
 *
 * HARD RULES (§6.2):
 *   - transforms/opacity ONLY — no layout-thrashing properties are ever animated here.
 *   - every animation collapses to none under prefers-reduced-motion (block at the bottom).
 *   - nothing here delays or blocks input (no pointer-events games on live UI).
 */

/* ---- routeEnter — subtle fade/slide on #playMain content swaps (≤150ms) ---- */
body.play-app .play-main.tpq-route-enter {
	animation: tpq-route-enter 0.14s ease-out;
}
@keyframes tpq-route-enter {
	from { opacity: 0.4; transform: translateY(6px); }
	to { opacity: 1; transform: none; }
}

/* ---- lootReveal — rarity-tinted scale-in pop on the loot spotlight ---- */
body.play-app .tpq-juice-pop {
	animation: tpq-juice-pop 0.55s cubic-bezier(0.2, 1.5, 0.4, 1) both;
}
@keyframes tpq-juice-pop {
	0% { opacity: 0; transform: scale(0.65); }
	60% { opacity: 1; transform: scale(1.06); }
	100% { opacity: 1; transform: scale(1); }
}

/* ---- levelUpFlourish — medal pop + breathing gold glow ring ---- */
body.play-app .tpq-juice-levelup {
	animation:
		tpq-juice-levelup-pop 0.7s cubic-bezier(0.2, 1.5, 0.4, 1) both,
		tpq-juice-levelup-glow 1.9s ease-in-out 0.7s 3;
	border-radius: inherit;
}
@keyframes tpq-juice-levelup-pop {
	0% { opacity: 0; transform: scale(0.4) rotate(-6deg); }
	65% { opacity: 1; transform: scale(1.12) rotate(2deg); }
	100% { opacity: 1; transform: scale(1) rotate(0); }
}
@keyframes tpq-juice-levelup-glow {
	0%, 100% { filter: drop-shadow(0 0 2px rgba(255, 215, 94, 0.25)); }
	50% { filter: drop-shadow(0 0 10px rgba(255, 215, 94, 0.75)); }
}

/* ---- numberFloat — rising +gold / +xp / −hp tab (tabular numerals) ---- */
.tpq-juice-host { position: relative; }
body.play-app .tpq-juice-float {
	position: absolute;
	left: 50%;
	top: 18%;
	z-index: 5;
	font-family: var(--font-numeric, "Fredoka", sans-serif);
	font-variant-numeric: tabular-nums;
	font-weight: 800;
	font-size: 1rem;
	color: #ffe07a;
	text-shadow: 0 1px 3px rgba(0, 0, 0, 0.85);
	pointer-events: none;
	white-space: nowrap;
	animation: tpq-juice-float 1.1s ease-out both;
}
body.play-app .tpq-juice-float--xp { color: #9be7ff; }
body.play-app .tpq-juice-float--hp { color: #ff7a6b; }
@keyframes tpq-juice-float {
	0% { opacity: 0; transform: translate(-50%, 8px) scale(0.8); }
	18% { opacity: 1; transform: translate(-50%, 0) scale(1.05); }
	100% { opacity: 0; transform: translate(-50%, -42px) scale(1); }
}

/* ---- rewardBurst — coins/sparks fly outward from an origin ---- */
body.play-app .tpq-juice-burst-bit {
	position: absolute;
	left: 50%;
	top: 50%;
	z-index: 4;
	font-size: var(--burst-size, 0.85rem);
	pointer-events: none;
	animation: tpq-juice-burst 0.85s ease-out var(--burst-d, 0s) both;
}
@keyframes tpq-juice-burst {
	0% { opacity: 0; transform: translate(-50%, -50%) scale(0.4); }
	20% { opacity: 1; }
	100% {
		opacity: 0;
		transform: translate(calc(-50% + var(--burst-x, 0px)), calc(-50% + var(--burst-y, -40px))) scale(1);
	}
}

/* ---- hitstop — TPQJuice.hitstop() pauses in-flight juice for ≤120ms ---- */
body.tpq-juice-hitstop .tpq-juice-pop,
body.tpq-juice-hitstop .tpq-juice-levelup,
body.tpq-juice-hitstop .tpq-juice-float,
body.tpq-juice-hitstop .tpq-juice-burst-bit {
	animation-play-state: paused;
}

/* ---- tactilePress — press-scale on tap (HUD slots + action buttons) ----
   play-polish.css already presses .play-action-btn / .tpq-slot-frame on :active;
   these keep the press honest on surfaces polish doesn't reach, and back the
   TPQJuice.tactilePress() programmatic variant. */
body.play-app .tpq-slot:active .tpq-slot-icon { transform: scale(0.9); }
body.play-app .tpq-slot .tpq-slot-icon { transition: transform 0.08s ease; }
body.play-app .tpq-juice-pressed { transform: scale(0.95); transition: transform 0.08s ease; }

/* ---- idleMicro — subtle breathing on portraits/tiles ---- */
body.play-app .tpq-idle-micro {
	animation: tpq-idle-micro 4.5s ease-in-out infinite;
}
@keyframes tpq-idle-micro {
	0%, 100% { transform: translateY(0) scale(1); }
	50% { transform: translateY(-1px) scale(1.015); }
}

/* ---- Composition (§7): .tpq-scene-vignette — the duel arena's inset vignette as a
   reusable helper. ::after overlay so it stacks with the host's own box-shadow. ---- */
body.play-app .tpq-scene-vignette { position: relative; }
body.play-app .tpq-scene-vignette::after {
	content: "";
	position: absolute;
	inset: 0;
	border-radius: inherit;
	pointer-events: none;
	z-index: 1;
	box-shadow: inset 0 0 90px 24px rgba(8, 6, 14, 0.5);
}
/* Receipt/victory cards carry content right to the edge — soften the pull there. */
body.play-app .vv-lootbox-card.tpq-scene-vignette::after {
	box-shadow: inset 0 0 70px 12px rgba(8, 6, 14, 0.38);
}

/* ---- V3 hero medallion on the action bar (play-hud.js) ---- */
body.play-app .tpq-hero {
	position: relative;
	flex: 0 0 auto;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 0.15rem;
	margin: 0; /* rightmost item now — no leading offset */
	padding: 0;
	background: none;
	border: 0;
	cursor: pointer;
	font: inherit;
	color: var(--text, #e8ecf4);
	-webkit-tap-highlight-color: transparent;
}
body.play-app .tpq-hero-ring {
	position: relative;
	display: grid;
	place-items: center;
	width: 3.05rem;
	height: 3.05rem;
	border-radius: 999px;
	overflow: hidden;
	background:
		radial-gradient(120% 120% at 50% 0%, rgba(255, 224, 122, 0.16), rgba(255, 255, 255, 0) 60%),
		linear-gradient(180deg, #232838, #12141d);
	border: 2px solid rgba(241, 196, 15, 0.55);
	box-shadow:
		inset 0 1px 0 rgba(255, 255, 255, 0.18),
		inset 0 -4px 8px rgba(0, 0, 0, 0.55),
		0 2px 8px -2px rgba(0, 0, 0, 0.8);
	transition: transform 0.12s ease, border-color 0.15s ease;
}
body.play-app .tpq-hero:hover .tpq-hero-ring { transform: translateY(-2px); border-color: rgba(255, 224, 122, 0.85); }
body.play-app .tpq-hero:active .tpq-hero-ring { transform: translateY(0) scale(0.95); }
body.play-app .tpq-hero-img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	object-position: 50% 12%;
	image-rendering: auto; /* small avatar downscaled from large art — smooth, not jagged (see crest note) */
}
body.play-app .tpq-hero-emoji { font-size: 1.45rem; line-height: 1; }
body.play-app .tpq-hero-level {
	position: absolute;
	right: -3px;
	bottom: 0.85rem;
	min-width: 1.05rem;
	height: 1.05rem;
	padding: 0 0.2rem;
	display: grid;
	place-items: center;
	border-radius: 999px;
	font-family: var(--font-numeric, "Fredoka", sans-serif);
	font-size: 0.62rem;
	font-weight: 800;
	color: #2a1d03;
	background: var(--gold-grad, linear-gradient(180deg, #ffe07a, #d99e06));
	border: 2px solid #12131b;
	box-shadow: 0 2px 6px -1px rgba(0, 0, 0, 0.8);
	z-index: 2;
}
body.play-app .tpq-hero-label {
	font-size: 0.62rem;
	font-weight: 700;
	letter-spacing: 0.02em;
	color: rgba(180, 188, 204, 0.85);
	white-space: nowrap;
}
body.play-app .tpq-hero.is-locked .tpq-hero-ring { border-color: rgba(255, 255, 255, 0.12); filter: grayscale(0.7); opacity: 0.6; }
body.play-app .tpq-hero.is-locked { cursor: default; }
/* The medallion adds an 8th item to the bar — compact the row a touch earlier than the
   stock 380px breakpoint so all 7 slots + hero still fit phone widths (e.g. 390px). */
@media (max-width: 480px) {
	body.play-app .tpq-actionbar-inner:has(.tpq-hero) { gap: 0.22rem; }
	body.play-app .tpq-actionbar-inner:has(.tpq-hero) .tpq-slot-frame,
	body.play-app .tpq-actionbar-inner:has(.tpq-hero) .tpq-hero-ring {
		width: 2.6rem;
		height: 2.6rem;
	}
	body.play-app .tpq-actionbar-inner:has(.tpq-hero) .tpq-slot-icon { font-size: 1.25rem; }
	body.play-app .tpq-actionbar-inner:has(.tpq-hero) .tpq-slot-label,
	body.play-app .tpq-actionbar-inner:has(.tpq-hero) .tpq-hero-label { font-size: 0.56rem; }
	body.play-app .tpq-actionbar-inner:has(.tpq-hero) .tpq-hero-emoji { font-size: 1.2rem; }
	body.play-app .tpq-hero { margin-right: 0.1rem; }
	body.play-app .tpq-hero-level { bottom: 0.8rem; }
}
@media (max-width: 380px) {
	body.play-app .tpq-hero-ring { width: 2.6rem; height: 2.6rem; }
	body.play-app .tpq-hero-label { display: none; }
	body.play-app .tpq-hero-level { bottom: -2px; }
}
@media (max-width: 366px) {
	body.play-app .tpq-actionbar-inner:has(.tpq-hero) { gap: 0.2rem; }
	body.play-app .tpq-actionbar-inner:has(.tpq-hero) .tpq-slot-frame,
	body.play-app .tpq-actionbar-inner:has(.tpq-hero) .tpq-hero-ring {
		width: 2.35rem;
		height: 2.35rem;
	}
	body.play-app .tpq-actionbar-inner:has(.tpq-hero) .tpq-slot-icon { font-size: 1.1rem; }
}
@media (max-width: 330px) {
	body.play-app .tpq-hero-ring { width: 2.35rem; height: 2.35rem; }
	body.play-app .tpq-actionbar-inner:has(.tpq-hero) { gap: 0.18rem; }
	body.play-app .tpq-actionbar-inner:has(.tpq-hero) .tpq-slot-frame,
	body.play-app .tpq-actionbar-inner:has(.tpq-hero) .tpq-hero-ring {
		width: 2.1rem;
		height: 2.1rem;
	}
	body.play-app .tpq-actionbar-inner:has(.tpq-hero) .tpq-slot-icon { font-size: 1rem; }
	body.play-app .tpq-actionbar-inner:has(.tpq-hero) .tpq-hero-emoji { font-size: 1rem; }
}

/* ---- D65 SFX toggle (play-sfx.js) — unobtrusive, floats just above the HUD bar ---- */
body.play-app .tpq-sfx-toggle {
	display: none;
	position: fixed;
	right: max(0.5rem, var(--play-safe-right, 0px));
	bottom: calc(var(--tpq-bar-h, 4.9rem) + var(--play-safe-bottom, 0px) + 0.45rem);
	z-index: 158;
	width: 1.9rem;
	height: 1.9rem;
	place-items: center;
	padding: 0;
	border-radius: 999px;
	font-size: 0.85rem;
	line-height: 1;
	color: rgba(232, 236, 244, 0.8);
	background: rgba(16, 18, 28, 0.72);
	border: 1px solid rgba(255, 255, 255, 0.14);
	box-shadow: 0 2px 8px -2px rgba(0, 0, 0, 0.7);
	cursor: pointer;
	opacity: 0.65;
	transition: opacity 0.15s ease, border-color 0.15s ease;
	-webkit-tap-highlight-color: transparent;
}
body.play-app.play-hud-active .tpq-sfx-toggle { display: grid; }
body.play-app .tpq-sfx-toggle:hover { opacity: 1; }
body.play-app .tpq-sfx-toggle.is-on {
	opacity: 0.9;
	color: var(--gold-bright, #ffd75e);
	border-color: rgba(241, 196, 15, 0.45);
}

/* ---- Reduced motion: every juice animation is a no-op (§6.2 hard rule) ---- */
@media (prefers-reduced-motion: reduce) {
	body.play-app .play-main.tpq-route-enter,
	body.play-app .tpq-juice-pop,
	body.play-app .tpq-juice-levelup,
	body.play-app .tpq-juice-float,
	body.play-app .tpq-juice-burst-bit,
	body.play-app .tpq-idle-micro {
		animation: none;
	}
	body.play-app .tpq-juice-float { opacity: 0; }
	body.play-app .tpq-juice-burst-bit { opacity: 0; }
	body.play-app .tpq-slot .tpq-slot-icon,
	body.play-app .tpq-juice-pressed,
	body.play-app .tpq-hero-ring {
		transition: none;
		transform: none;
	}
}
/* ── Collection hub (D62) — completion strips ─────────────────────────────── */
.play-collection-overall { display: flex; flex-direction: column; gap: 8px; margin: 10px 0 14px; }
.play-collection-strip { display: flex; align-items: center; gap: 10px; }
.play-collection-label { font-size: 0.82rem; font-weight: 600; min-width: 138px; }
.play-collection-bar {
	flex: 1;
	height: 8px;
	border-radius: 5px;
	background: rgba(255, 255, 255, 0.12);
	overflow: hidden;
}
.play-collection-fill {
	display: block;
	height: 100%;
	border-radius: 5px;
	background: linear-gradient(90deg, #ffe07a, #d99e06);
	transition: width 0.6s cubic-bezier(0.25, 0.8, 0.4, 1);
}
.play-collection-count { font-size: 0.78rem; opacity: 0.85; white-space: nowrap; }
