/*
 * Chess Nightmare: .cn-card3d holographic card.
 *
 * Driven by custom properties written by card3d.js:
 *   --rx, --ry   tilt in degrees (unitless numbers)
 *   --mx, --my   pointer position over the card (0%..100%)
 *   --pos        foil offset (-25%..25%)
 *   --hyp        distance of the pointer from centre (0..1)
 * Rarity intensities, keyed on [data-rarity] below (JS normalises the value):
 *   --cn-glare, --cn-foil, --cn-sparkle
 * Optional hooks:
 *   --cn-foil-mask           url() of a frame overlay; the foil only shows where it is opaque
 *   --cn-card3d-art-scale    zoom the front art to crop a printed white margin (default 1)
 *   --cn-card3d-back-scale   same for the back image
 *   --cn-card3d-ratio        card aspect ratio (default 5 / 7, i.e. 750x1050)
 *
 * Moving layers are oversized and moved with transform, so the per-frame work is
 * transform and opacity. Only the 1.5px edge highlight repaints.
 */

.cn-card3d {
	/* Local aliases of the theme tokens, with EPIC fallbacks so the component
	   also works outside the theme (demo page, NFC view). */
	--c3-gold: var(--cn-gold, #c9a227);
	--c3-gold-soft: var(--cn-gold-soft, #e6cc72);
	--c3-ember: var(--cn-ember, #d1442f);
	--c3-steel: var(--cn-steel, #8b8578);
	--c3-panel: var(--cn-panel, #1b150e);
	--c3-abyss: var(--cn-abyss, #0b0906);
	--c3-ease: cubic-bezier(.2, .8, .2, 1);

	--rx: 0;
	--ry: 0;
	--mx: 50%;
	--my: 50%;
	--pos: 0%;
	--hyp: 0;
	--cn-glare: .35;
	--cn-foil: 0;
	--cn-sparkle: 0;
	--cn-card3d-accent: var(--c3-gold);
	--cn-card3d-edge: color-mix(in srgb, var(--c3-gold) 45%, transparent);
	--cn-card3d-radius: 4.2% / 3%;

	position: relative;
	display: block;
	width: 100%;
	aspect-ratio: var(--cn-card3d-ratio, 5 / 7);
	margin: 0;
	padding: 0;
	border: 0;
	border-radius: var(--cn-card3d-radius);
	background: none;
	color: inherit;
	font: inherit;
	cursor: pointer;
	perspective: 800px;
	-webkit-tap-highlight-color: transparent;
	touch-action: manipulation;
	translate: 0 0;
	transition: translate .25s var(--c3-ease);
}

.cn-card3d:focus { outline: none; }
.cn-card3d:focus-visible {
	outline: 2px solid var(--c3-gold-soft);
	outline-offset: 3px;
}

.cn-card3d.is-active { translate: 0 -6px; }

/* Perspective scales with the card: ~3x its width. */
.cn-card3d--hero { perspective: 1300px; }

/* Rarity: edge colour + effect intensities. */
.cn-card3d[data-rarity="comun"] {
	--cn-card3d-edge: color-mix(in srgb, var(--c3-steel) 40%, transparent);
}
.cn-card3d[data-rarity="rara"] {
	--cn-glare: .75;
}
.cn-card3d[data-rarity="epica"] {
	--cn-glare: .8;
	--cn-foil: .55;
	--cn-card3d-edge: color-mix(in srgb, var(--c3-gold-soft) 55%, transparent);
}
.cn-card3d[data-rarity="legendaria"] {
	--cn-glare: .9;
	--cn-foil: .7;
	--cn-sparkle: 1;
	--cn-card3d-edge: color-mix(in srgb, var(--c3-gold-soft) 75%, transparent);
}

/* Type accent: used only for the ambient under-glow. */
.cn-card3d[data-type="ataque"] { --cn-card3d-accent: var(--c3-ember); }
.cn-card3d[data-type="defensiva"] { --cn-card3d-accent: #5b7fa6; }
.cn-card3d[data-type="magica"] { --cn-card3d-accent: #8a5cf6; }
.cn-card3d[data-type="objeto"] { --cn-card3d-accent: var(--c3-gold); }

/* ---------- Shadow: sits on the "table", slides away from the light ---------- */

.cn-card3d__shadow {
	position: absolute;
	inset: 6% 7% -3%;
	border-radius: 8%;
	pointer-events: none;
	background: radial-gradient(closest-side, rgba(0, 0, 0, .9), rgba(0, 0, 0, .55) 60%, transparent);
	filter: blur(16px);
	opacity: .85;
	transform: translate3d(calc(var(--ry) * -1.4px), calc(var(--rx) * 1.4px + 16px), 0);
	transition: opacity .25s var(--c3-ease), translate .25s var(--c3-ease);
}

.cn-card3d__shadow::after {
	content: "";
	position: absolute;
	inset: 10% 0 -6%;
	border-radius: inherit;
	background: radial-gradient(closest-side, var(--cn-card3d-accent), transparent);
	opacity: 0;
	transition: opacity .4s var(--c3-ease);
}

.cn-card3d.is-active .cn-card3d__shadow {
	opacity: 1;
	translate: 0 10px;
}
.cn-card3d.is-active .cn-card3d__shadow::after { opacity: .28; }

/* ---------- 3D stack ---------- */

.cn-card3d__tilt,
.cn-card3d__inner {
	position: absolute;
	inset: 0;
	display: block;
	transform-style: preserve-3d;
	border-radius: var(--cn-card3d-radius);
}

.cn-card3d__tilt {
	transform: rotateX(calc(var(--rx) * 1deg)) rotateY(calc(var(--ry) * 1deg));
}

.cn-card3d__inner {
	transition: transform .65s var(--c3-ease);
}

.cn-card3d.is-flipped .cn-card3d__inner { transform: rotateY(180deg); }

.cn-card3d.is-interacting .cn-card3d__tilt { will-change: transform; }

.cn-card3d__face {
	position: absolute;
	inset: 0;
	display: block;
	overflow: hidden;
	border-radius: var(--cn-card3d-radius);
	background: var(--c3-panel);
	-webkit-backface-visibility: hidden;
	backface-visibility: hidden;
	isolation: isolate;
}

.cn-card3d__face--back { transform: rotateY(180deg); }

.cn-card3d__img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	-webkit-user-drag: none;
	user-select: none;
	pointer-events: none;
}

.cn-card3d__face--front .cn-card3d__img { transform: scale(var(--cn-card3d-art-scale, 1)); }
.cn-card3d__face--back .cn-card3d__img { transform: scale(var(--cn-card3d-back-scale, 1)); }

/* ---------- Holo foil (epica, legendaria) ---------- */

.cn-card3d__foil {
	position: absolute;
	inset: 0;
	display: block;
	pointer-events: none;
	mix-blend-mode: color-dodge;
	opacity: calc(var(--cn-foil) * (.35 + var(--hyp) * .65));
	/* Without a frame mask, weight the foil towards the border like a printed frame foil. */
	-webkit-mask-image: var(--cn-foil-mask, radial-gradient(115% 90% at 50% 46%, rgba(0, 0, 0, .25) 36%, #000 78%));
	mask-image: var(--cn-foil-mask, radial-gradient(115% 90% at 50% 46%, rgba(0, 0, 0, .25) 36%, #000 78%));
	-webkit-mask-size: 100% 100%;
	mask-size: 100% 100%;
}

.cn-card3d__foil::before {
	content: "";
	position: absolute;
	inset: -50%;
	/* One wide sheen band (gold, rose, violet, teal) separated by black gaps,
	   which color-dodge ignores, so a single band sweeps across as the card tilts.
	   Fine diffraction lines sit on top. */
	background-image:
		repeating-linear-gradient(
			62deg,
			rgba(0, 0, 0, .35) 0,
			rgba(0, 0, 0, .35) .5%,
			rgba(255, 255, 255, .08) .8%,
			rgba(0, 0, 0, .35) 1.1%
		),
		repeating-linear-gradient(
			118deg,
			#000 0%,
			#000 6%,
			hsl(44 80% 62%) 10%,
			hsl(18 72% 60%) 12.5%,
			hsl(330 58% 62%) 15%,
			hsl(268 56% 66%) 17.5%,
			hsl(192 62% 58%) 20%,
			#000 25%,
			#000 30%
		);
	background-blend-mode: color-dodge;
	transform: translate3d(var(--pos), var(--pos), 0);
}

.cn-card3d.is-interacting .cn-card3d__foil::before { will-change: transform; }

/* ---------- Sparkle (legendaria only) ---------- */

.cn-card3d__sparkle {
	position: absolute;
	inset: 0;
	display: none;
	pointer-events: none;
	mix-blend-mode: color-dodge;
	opacity: calc(var(--cn-sparkle) * (.25 + var(--hyp) * .75));
	-webkit-mask-image: var(--cn-foil-mask, radial-gradient(120% 95% at 50% 46%, rgba(0, 0, 0, .35) 30%, #000 80%));
	mask-image: var(--cn-foil-mask, radial-gradient(120% 95% at 50% 46%, rgba(0, 0, 0, .35) 30%, #000 80%));
	-webkit-mask-size: 100% 100%;
	mask-size: 100% 100%;
}

.cn-card3d[data-rarity="legendaria"] .cn-card3d__sparkle { display: block; }

.cn-card3d__sparkle::before,
.cn-card3d__sparkle::after {
	content: "";
	position: absolute;
	inset: -8%;
	background-repeat: repeat;
	transform: translate3d(calc(var(--ry) * -.9px), calc(var(--rx) * .9px), 0);
	animation: cn-card3d-twinkle 2.8s ease-in-out infinite alternate paused;
}

.cn-card3d__sparkle::before {
	background-image:
		radial-gradient(circle at 22% 31%, #fff 0 .9px, transparent 2px),
		radial-gradient(circle at 71% 64%, rgba(255, 236, 190, .95) 0 1.1px, transparent 2.6px);
	background-size: 37px 43px, 59px 53px;
}

.cn-card3d__sparkle::after {
	background-image:
		radial-gradient(circle at 48% 12%, rgba(255, 246, 220, .9) 0 .8px, transparent 1.9px),
		radial-gradient(circle at 12% 77%, #fff 0 1.3px, transparent 3px);
	background-size: 31px 29px, 71px 67px;
	animation-delay: -1.4s;
}

.cn-card3d.is-inview .cn-card3d__sparkle::before,
.cn-card3d.is-inview .cn-card3d__sparkle::after { animation-play-state: running; }

@keyframes cn-card3d-twinkle {
	0% { opacity: .15; }
	45% { opacity: 1; }
	100% { opacity: .35; }
}

/* ---------- Glare: a candle-warm hotspot that follows the pointer ---------- */

.cn-card3d__glare {
	position: absolute;
	inset: 0;
	display: block;
	pointer-events: none;
	mix-blend-mode: overlay;
	opacity: 0;
	transition: opacity .3s var(--c3-ease);
}

.cn-card3d__glare::before {
	content: "";
	position: absolute;
	inset: -50%;
	background: radial-gradient(
		circle at 50% 50%,
		rgba(255, 252, 240, 1) 0%,
		rgba(255, 238, 200, .6) 10%,
		rgba(255, 236, 196, 0) 28%,
		rgba(0, 0, 0, .4) 50%
	);
	/* The layer is twice the card size, so half the offset lands the hotspot on the pointer. */
	transform: translate3d(calc((var(--mx) - 50%) / 2), calc((var(--my) - 50%) / 2), 0);
}

/* The back face is mirrored by the flip, so mirror X to keep the light under the pointer. */
.cn-card3d__face--back .cn-card3d__glare::before {
	transform: translate3d(calc((50% - var(--mx)) / 2), calc((var(--my) - 50%) / 2), 0);
}

.cn-card3d.is-active .cn-card3d__glare { opacity: var(--cn-glare); }

/* ---------- Edge light: gilded hairline that catches the light ---------- */

.cn-card3d__edge {
	position: absolute;
	inset: 0;
	display: block;
	border-radius: inherit;
	pointer-events: none;
	box-shadow:
		inset 0 0 0 1px var(--cn-card3d-edge),
		inset 0 0 28px rgba(0, 0, 0, .45);
}

.cn-card3d__edge::before {
	content: "";
	position: absolute;
	inset: 0;
	padding: 1.5px;
	border-radius: inherit;
	background: radial-gradient(70% 55% at var(--mx) var(--my), var(--c3-gold-soft), transparent 70%);
	-webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
	-webkit-mask-composite: xor;
	mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0);
	opacity: calc(.15 + var(--hyp) * .85);
	transition: opacity .3s var(--c3-ease);
}

.cn-card3d:not(.is-active) .cn-card3d__edge::before { opacity: .15; }

/* ---------- Companions: hint + gyroscope toggle ---------- */

.cn-card3d-controls {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;
	gap: .5rem 1rem;
	margin-top: 1.6rem;
}

.cn-card3d-hint {
	margin: 0;
	color: var(--cn-steel, #8b8578);
	font-size: .9rem;
	font-style: italic;
	text-align: center;
}

.cn-card3d-gyro {
	padding: .45rem 1rem;
	border: 1px solid color-mix(in srgb, var(--c3-gold, #c9a227) 45%, transparent);
	border-radius: 999px;
	background: transparent;
	color: var(--cn-parchment, #ece0c6);
	font: inherit;
	font-size: .9rem;
	cursor: pointer;
	transition: border-color .2s var(--c3-ease, ease), background-color .2s var(--c3-ease, ease);
}
.cn-card3d-gyro[hidden] { display: none; }
.cn-card3d-gyro[aria-pressed="true"] {
	border-color: var(--cn-gold-soft, #e6cc72);
	background: color-mix(in srgb, var(--cn-gold, #c9a227) 14%, transparent);
}
.cn-card3d-gyro:focus-visible {
	outline: 2px solid var(--cn-gold-soft, #e6cc72);
	outline-offset: 3px;
}

/* ---------- Reduced motion: no tilt, flip becomes a crossfade ---------- */

@media (prefers-reduced-motion: reduce) {
	.cn-card3d,
	.cn-card3d.is-active { translate: none; transition: none; }

	.cn-card3d__tilt,
	.cn-card3d__inner,
	.cn-card3d.is-flipped .cn-card3d__inner,
	.cn-card3d__face--back { transform: none; }

	.cn-card3d__inner { transition: none; }

	.cn-card3d__face {
		-webkit-backface-visibility: visible;
		backface-visibility: visible;
		transition: opacity .4s var(--c3-ease);
	}
	.cn-card3d__face--back,
	.cn-card3d.is-flipped .cn-card3d__face--front { opacity: 0; }
	.cn-card3d.is-flipped .cn-card3d__face--back { opacity: 1; }

	.cn-card3d__shadow { transform: translate3d(0, 16px, 0); transition: none; }
	.cn-card3d__glare,
	.cn-card3d.is-active .cn-card3d__glare { opacity: 0; }
	.cn-card3d__sparkle::before,
	.cn-card3d__sparkle::after { animation: none; opacity: .6; }
}
