/*
 Holographic card effect - shared mechanics (tilt/lift transforms, shine/glare
 layer positioning, no-JS fallback). Adapted from pokemon-cards-css's
 base.css: https://github.com/simeydotme/pokemon-cards-css

 Load this ALWAYS, then load exactly one effect file (regular-holo.css,
 reverse-holo.css, rainbow-alt.css, ...) to pick the actual shine/glare look.
 Everything is namespaced .holo-card* so it can't collide with the separate,
 pre-existing .card/.cardflipper/.front/.back rules in css/main.css.
*/

:root {
	--pointer-x: 50%;
	--pointer-y: 50%;
	--background-x: 50%;
	--background-y: 50%;
	--pointer-from-center: 0;
	--pointer-from-top: 0.5;
	--pointer-from-left: 0.5;
	--card-opacity: 0;
	--card-scale: 1;
	--translate-x: 0px;
	--translate-y: 0px;
	--rotate-x: 0deg;
	--rotate-y: 0deg;

	--holo-red: #f80e35;
	--holo-yellow: #eedf10;
	--holo-green: #21e985;
	--holo-blue: #0dbde9;
	--holo-violet: #c929f1;

	/* shared defaults used by several effect files (amazing-rare, shiny-vmax,
	   rainbow-alt) - no texture asset unless an effect overrides --foil */
	--glitter: url("../../images/holo/glitter.png");
	/* glitter.png isn't a seamlessly-tileable texture (verified: its left and
	   right edges don't match) - at the vendor's own 25% size it repeats 4x4
	   across the card, showing a visible seam at every tile boundary
	   (including dead center, at the 50% mark). Sized at 140% here instead,
	   it's larger than the card box in both dimensions, so only one instance
	   ever shows - no repeat, no seam. */
	--glittersize: 140%;
	--foil: none;
	--imgsize: cover;
	--angle: 133deg;
	--space: 5%;

	--sunpillar-1: hsl(2, 100%, 73%);
	--sunpillar-2: hsl(53, 100%, 69%);
	--sunpillar-3: hsl(93, 100%, 69%);
	--sunpillar-4: hsl(176, 100%, 76%);
	--sunpillar-5: hsl(228, 100%, 74%);
	--sunpillar-6: hsl(283, 100%, 73%);
	--sunpillar-clr-1: var(--sunpillar-1);
	--sunpillar-clr-2: var(--sunpillar-2);
	--sunpillar-clr-3: var(--sunpillar-3);
	--sunpillar-clr-4: var(--sunpillar-4);
	--sunpillar-clr-5: var(--sunpillar-5);
	--sunpillar-clr-6: var(--sunpillar-6);
}

.holo-card {
	display: inline-block;
	/* space between cards, moved here (off of #selected_cardback, see below)
	   so it sits outside the glow instead of inside it */
	margin: 5px;
}

/* perspective belongs on the PARENT of the rotated element (.translater),
   not on .rotator itself - the vendor puts it on both because their
   .card__rotator also flips a separate card-back face in its own 3D space
   (a mechanic we don't have here), so a second perspective there was adding
   extra, unwanted distortion on top of the tilt rather than helping it. */
/* NOTE: no "transition: transform" here on purpose - the JS (js/holo-crowley.js)
   already smooths every value toward its target with its own per-frame lerp,
   so a CSS transition on top of that was fighting it (two separate smoothing
   systems stacked), which is what made the tilt feel inconsistent/laggy. The
   :not(.js-interactive) fallback below has its own transition for the no-JS case. */
.holo-card__translater {
	display: inline-block;
	perspective: 600px;
	transform-style: preserve-3d;
	/* --translate-x/-y are only ever non-zero while a card is popped over
	   (see the click-to-zoom handling in js/holo-crowley.js) - the delta in
	   px needed to recenter the card in the viewport, animated by its own
	   spring instance alongside --card-scale */
	transform: translate3d(var(--translate-x), var(--translate-y), 0) scale(var(--card-scale));
}

.holo-card__rotator {
	display: inline-block;
	/* containing block for .holo-card__backface's position:absolute - it
	   needs to size/position itself against THIS box (which auto-sizes to
	   #selected_cardback, its only normal-flow child), not some further-out
	   ancestor */
	position: relative;
	transform-style: preserve-3d;
	transform: rotateY(var(--rotate-x)) rotateX(var(--rotate-y));
	transition: box-shadow 0.3s ease;
	border-radius: 8px;
}

/* Crowley deck only (see $holo in inc/libcard.php's DrawCard2(), which is
   what actually adds this element) - the classic two-sided flip-card CSS
   trick: a same-size layer rotated 180deg from the front (#selected_cardback,
   both backface-visibility:hidden), sharing .holo-card__rotator's 3D space
   via its transform-style:preserve-3d. Without this, any rotation past
   90deg - most visibly the popover's click-to-zoom spin - showed either a
   mirrored front face or nothing, instead of the card's actual back design. */
.holo-card__backface {
	position: absolute;
	inset: 0;
	backface-visibility: hidden;
	transform: rotateY(180deg);
	background-size: cover;
	background-position: center;
	border-radius: 8px;
}

/* #selected_cardback already provides its own spacing/float for the
   original (non-holo) grid layout; both are redundant once wrapped in
   .holo-card, and #selected_cardback's margin was being counted into
   .holo-card__rotator's shrink-to-fit box, pushing any glow away from the
   card's actual border. Neutralize both here, spacing now lives on .holo-card. */
.holo-card__rotator #selected_cardback {
	float: none;
	margin: 0;
}

/* SHINE + GLARE overlays, sized to #selected_cardback's own box (they are
   children of #selected_cardback, which is already position:relative,
   overflow:hidden and border-radius:8px - see css/main.css) */
.holo-card__shine,
.holo-card__glare {
	position: absolute;
	inset: 0;
	border-radius: 8px;
	pointer-events: none;
}

/* base defaults every effect file inherits unless it overrides them - the
   vendor's own .card__shine sets exactly this mix-blend-mode as its default;
   effect files that never re-declare their own (rainbow-alt, amazing-rare,
   shiny-vmax, trainer-gallery-holo) were silently falling back to the
   browser default "normal" blend without this, which just washes a
   translucent layer over the art instead of enhancing it. */
.holo-card__shine,
.holo-card__shine:before,
.holo-card__shine:after {
	mix-blend-mode: color-dodge;
	opacity: var(--card-opacity);
}

/* default - effect files may override with their own (usually lower) value.
   background-image matches the vendor's own base.css default too - at least
   one effect (regular-holo.css) relies on it rather than setting its own */
.holo-card__glare {
	opacity: var(--card-opacity);
	background-image: radial-gradient(farthest-corner circle at var(--pointer-x) var(--pointer-y),
		hsla(0, 0%, 100%, 0.8) 10%,
		hsla(0, 0%, 100%, 0.65) 20%,
		hsla(0, 0%, 0%, 0.5) 90%
	);
}

.holo-card__shine:before,
.holo-card__shine:after {
	content: "";
	position: absolute;
	inset: 0;
	border-radius: 8px;
}

/* Several effects (amazing-rare, v-full-art, shiny-rare/-v, v-star, v-max,
   v-regular, trainer-gallery-secret-rare, ...) share one background-image
   declaration between .holo-card__shine and its :before/:after via
   var(--sunpillar-clr-1..6), same as the vendor. Without this remapping,
   every layer would render the exact same rainbow band stacked on itself;
   the vendor's own base.css rotates the 6 hues by a different amount per
   pseudo-element so each layer's band is phase-shifted from the others,
   which is what actually gives these effects their layered depth. */
.holo-card__shine:before,
.holo-card__shine:after {
	--sunpillar-clr-1: var(--sunpillar-5);
	--sunpillar-clr-2: var(--sunpillar-6);
	--sunpillar-clr-3: var(--sunpillar-1);
	--sunpillar-clr-4: var(--sunpillar-2);
	--sunpillar-clr-5: var(--sunpillar-3);
	--sunpillar-clr-6: var(--sunpillar-4);
}

.holo-card__shine:after {
	--sunpillar-clr-1: var(--sunpillar-6);
	--sunpillar-clr-2: var(--sunpillar-1);
	--sunpillar-clr-3: var(--sunpillar-2);
	--sunpillar-clr-4: var(--sunpillar-3);
	--sunpillar-clr-5: var(--sunpillar-4);
	--sunpillar-clr-6: var(--sunpillar-5);
}

/* EMBOSS: a highlight/shadow pair that shifts opposite each other as the
   pointer moves, simulating a raised bump catching light from the pointer's
   direction rather than a flat printed texture - reuses .holo-card__glare's
   otherwise-unused :before (no new DOM/PHP needed). At rest
   (--pointer-from-left/top = 0.5, their idle value) both gradients sit
   exactly on top of each other and cancel out, so this only becomes visible
   once the pointer starts moving, same as every other layer here. Shared in
   base.css (not a single effect file) so every effect gets this raised feel,
   including flatter ones like trainer-gallery-holo.css that are otherwise
   just a printed-looking rainbow sheen. */
.holo-card__glare:before {
	content: "";
	position: absolute;
	inset: 0;
	border-radius: 8px;
	background-image:
		radial-gradient(circle at calc(50% + (var(--pointer-from-left) - 0.5) * 70%) calc(50% + (var(--pointer-from-top) - 0.5) * 70%),
			hsla(0, 0%, 100%, 0.55) 0%, hsla(0, 0%, 100%, 0) 55%),
		radial-gradient(circle at calc(50% - (var(--pointer-from-left) - 0.5) * 70%) calc(50% - (var(--pointer-from-top) - 0.5) * 70%),
			hsla(0, 0%, 0%, 0.55) 0%, hsla(0, 0%, 0%, 0) 55%);
	mix-blend-mode: overlay;
	opacity: var(--card-opacity);
	pointer-events: none;
}

/* No-JS / JS-not-yet-initialized fallback: a fixed shimmer on hover */
.holo-card:not(.js-interactive):hover {
	--pointer-x: 25%;
	--pointer-y: 10%;
	--background-x: 44%;
	--background-y: 36%;
	--pointer-from-center: 0.6;
	--pointer-from-top: 0.1;
	--pointer-from-left: 0.25;
	--card-opacity: 1;
	--card-scale: 1.05;
	--rotate-x: 7deg;
	--rotate-y: -12deg;
}

.holo-card:not(.js-interactive) .holo-card__translater,
.holo-card:not(.js-interactive) .holo-card__rotator,
.holo-card:not(.js-interactive) .holo-card__shine,
.holo-card:not(.js-interactive) .holo-card__shine:before,
.holo-card:not(.js-interactive) .holo-card__shine:after,
.holo-card:not(.js-interactive) .holo-card__glare {
	transition: all 0.3s ease;
}

/* CLICK-TO-POPOVER: only wired up in js/holo-crowley.js for cards the PHP
   explicitly flags with data-popover="1" (single-card view pages - see
   inc/libcard.php's DrawCard2()/CardDetails()) - never the "Show All Cards"
   grid or a random spread, where zooming any one of many cards to the
   center of the screen wouldn't make sense. --translate-x/-y and
   --card-scale for this are driven by their own spring instance in JS,
   separate from the tilt-tracking one, and z-index only needs to jump once
   actually popped - it stays in normal flow the rest of the time. */
.holo-card[data-popover="1"] {
	cursor: zoom-in;
}

/* .holo-card sits nested inside .front/.back (transform:rotateY, css/main.css)
   and .flip-container (perspective, css/main.css) - both create their own
   local stacking context, which traps any z-index set on a descendant no
   matter how high: the browser resolves .front/.flip-container's own
   position in ITS parent's stacking context first, and #holo-popover-
   backdrop (a direct child of <body>, outside all of that) was never
   competing with .holo-card directly - it was competing with .front's
   whole nested subtree, capped below the backdrop regardless of
   .holo-card's own z-index. That's why activating this class alone dimmed
   the popped card too instead of lifting it above the dim.
   The fix (js/holo-crowley.js's openPopover()): physically reparent the
   card to be a direct child of <body> - a true sibling of the backdrop, in
   the SAME (root) stacking context, where z-index finally means what it
   says - leaving a same-size placeholder behind in its original slot so
   the surrounding layout doesn't reflow, and restoring it there when
   closed. Once reparented, .front .holo-card/.back .holo-card's own
   position:absolute (css/main.css) no longer even matches (different DOM
   parent), so this can define its own positioning from scratch. */
.holo-card.popover-active {
	position: fixed;
	top: 50%;
	left: 50%;
	z-index: 99999;
	cursor: zoom-out;
	/* .front .holo-card/.back .holo-card's margin:0 (css/main.css) stops
	   matching the instant this card is reparented to <body> - without an
	   override here it falls back to the base .holo-card's margin:5px
	   (grid spacing between cards elsewhere), which - unlike in normal
	   flow - actually shifts a position:fixed;top/left:50% box's rendered
	   position by that much, throwing off the fixed-point math the close
	   animation's target (closePopover(), js/holo-crowley.js) relies on. */
	margin: 0;
}

/* the base -50%/-50% self-centering (top/left:50% only places this box's
   OWN top-left corner at the viewport center) has to layer in before the
   animated translate-x/y and scale, but only while popped - added here via
   extra specificity rather than unconditionally in .holo-card__translater's
   own transform, which needs to stay a plain identity offset the rest of
   the time (every other context this class renders in - grids, random
   spreads - never expects to be shifted by half its own size). */
.holo-card.popover-active .holo-card__translater {
	transform: translate(-50%, -50%) translate3d(var(--translate-x), var(--translate-y), 0) scale(var(--card-scale));
}

#holo-popover-backdrop {
	position: fixed;
	inset: 0;
	background: rgba(0, 0, 0, 0);
	z-index: 99998;
	pointer-events: none;
	transition: background 0.3s ease;
}

#holo-popover-backdrop.active {
	background: rgba(0, 0, 0, 0.8);
	pointer-events: auto;
	cursor: zoom-out;
}
