/**
 * Game frame sizing.
 * ----------------------------------------------------------------------
 * .game-root's shape/ratio comes from the --tkge-aspect custom property
 * set inline per-game in tkge_render_game_embed() (9:16 Vertical, 16:9
 * Desktop, 1:1 Square, or the game's own native width/height for
 * Flexible mode) — that keeps this stylesheet itself mode-agnostic.
 *
 * .game-root--fill (Frame mode: "Fill Frame") skips the aspect-ratio
 * box entirely and instead gives the iframe a generous, viewport-based
 * height. This is the right choice for full, self-adaptive games —
 * ones that already detect mobile vs. desktop internally and lay
 * themselves out accordingly (menus, HUD, squad-select screens, etc.)
 * rather than being a single fixed-shape canvas. Forcing that kind of
 * game into a rigid 9:16/16:9/1:1 box is exactly what makes intro
 * screens, buttons, or HUD panels get sliced off by this wrapper's
 * overflow:hidden — the box was simply too short/narrow for the
 * content the game actually renders inside it.
 *
 * On mobile, "tall" frames (Vertical, Square, any Flexible game that's
 * taller than it is wide, and Fill) switch from a width-driven aspect
 * ratio to using most of the viewport height instead, so the game
 * actually fills most of the phone screen rather than staying small
 * and letterboxed. Every other mode still gets a defensive min-height
 * on mobile so a wide/short box (e.g. 16:9 Desktop on a narrow phone)
 * can't collapse to something too short to show its own UI.
 *
 * The `!important` + doubled-up class selectors below aren't decorative
 * — many WP themes ship a generic responsive-embed rule like
 * `.entry-content iframe { height: auto; }` for oEmbeds, which has
 * higher specificity than a bare `.game-root__frame` and will silently
 * collapse the iframe back down even though this file "wins" in file
 * order. Doubling the class (`.game-root.game-root--active
 * .game-root__frame`) raises our own specificity above that kind of
 * compound theme selector, and `!important` covers the (rarer) case
 * where the theme rule is `!important` too. See game-embed-sizing.js
 * for the JS-level backstop on top of this.
 */
.game-root {
	position: relative;
	width: 100%;
	max-width: 100%;
	margin: 0 auto;
	aspect-ratio: var( --tkge-aspect, auto );
	overflow: hidden;
}

.game-root__frame,
.game-root.game-root--active .game-root__frame {
	display: block;
	width: 100% !important;
	height: 100% !important;
	border: 0 !important;
	max-width: none !important;
	max-height: none !important;
}

/*
 * Scale-fit (Flexible mode only): the iframe is deliberately NOT
 * stretched to 100%/100% here. It's sized to the game's real native
 * pixel dimensions (set inline by game-embed-sizing.js's
 * applyScaleFit(), from the data-tkge-native-w/-h attributes
 * tkge_render_game_embed() outputs) and then visually scaled down or up
 * with a CSS transform to fit whatever space .game-root actually has.
 * Rendering at native size means nothing the game draws can overflow
 * its own iframe viewport and get cropped by .game-root's
 * overflow:hidden — the transform only ever shrinks/grows the already-
 * complete picture, it never crops it. `position: absolute` lets
 * applyScaleFit() center the (possibly letterboxed) result inside the
 * box via top/left, independent of the transform's own scaling origin.
 */
.game-root--scale-fit .game-root__frame,
.game-root.game-root--active.game-root--scale-fit .game-root__frame {
	position: absolute;
	top: 0;
	left: 0;
	width: auto !important;
	height: auto !important;
	transform-origin: 0 0;
}

.game-root--vertical,
.game-root--square {
	max-width: 480px;
}

/* Fill Frame: no forced ratio — a tall, capped-height box that scales
   with the viewport instead of squeezing to a fixed shape. */
.game-root--fill,
.game-root.game-root--fill {
	aspect-ratio: unset !important;
	height: min( 85vh, 900px ) !important;
	min-height: 520px !important;
}

.game-root__placeholder {
	display: flex;
	align-items: center;
	justify-content: center;
	min-height: 200px;
	text-align: center;
	padding: 2rem;
}

/*
 * Frame visual removal (mobile only).
 * ----------------------------------------------------------------------
 * .game-frame is the THEME's own wrapper (patterns/game.php in
 * trikdang-flex — a dashed-border, padded "dog-ear" box), tagged with
 * .game-frame--game-active by game-embed-sizing.js at runtime (see that
 * file for why it has to be done from JS rather than a plugin template).
 * Scoped to the max-width:782px query below: on mobile the border/
 * background/dog-ear would clash with the game filling the screen
 * during active play, so those are stripped there. On desktop a live
 * game stays sitting inside the theme's decorative box, same as it did
 * before a game was launched.
 *
 * padding is deliberately left OUT of this override (unlike border/
 * background/box-shadow below) so the block's own WordPress padding
 * setting still controls the gap between the frame's edge and the game
 * on mobile. This is safe for the edge-to-edge width breakout in
 * game-embed-sizing.js: that measures/sets the frame's own border-box
 * position and width, which its OWN padding doesn't affect (padding
 * sits inside the border box) — so the frame's outer edges still land
 * flush with the screen regardless of what padding value is set, and
 * the padding just insets the game visually within that flush box.
 */
@media ( max-width: 782px ) {
	.game-frame.game-frame--game-active {
		border: 0 !important;
		border-radius: 0 !important;
		background: none !important;
		box-shadow: none !important;
	}

	/* The theme's .dog-ear fold-corner decoration (::before/::after) is
	   part of what makes this box feel "designed", but once the border/
	   padding that contained it is gone, the folded triangle has
	   nothing to sit against and just floats oddly over the game. Same
	   neutralizing technique as .game-card--no-fold in game-cards.css. */
	.game-frame.game-frame--game-active::before,
	.game-frame.game-frame--game-active::after {
		content: none !important;
		display: none !important;
		border: none !important;
		background: none !important;
		box-shadow: none !important;
	}
}

@media ( max-width: 782px ) {
	.game-root--tall,
	.game-root--fill,
	.game-root.game-root--tall,
	.game-root.game-root--fill {
		width: 100%;
		max-width: 100%;
		/* Fits the game to whatever's actually left of the screen once the
		   site header and the Subscribe/Like/Share/Support row below the
		   frame are accounted for, using their real measured heights
		   (--tkge-header-h / --tkge-actions-h, set by game-embed-sizing.js)
		   rather than a flat guess — so game + actions row together land
		   at roughly 98-100% of the viewport's height instead of leaving a
		   large gap (guessed too small) or forcing extra scroll (guessed
		   too big). 100svh (not dvh, not vh) is used deliberately: dvh
		   is a *live* unit that the browser keeps recalculating as its
		   own address bar collapses/expands while the page scrolls, so
		   a height tied to it keeps growing taller on every scroll-down
		   instead of being set once — svh is the stable "toolbar fully
		   expanded" height and doesn't change as you scroll, so the
		   frame fits the screen once at load and then stays put. The
		   8px is slack for margins/gaps between the three; the fallback
		   numbers (64px/64px) are only used before JS has measured
		   anything, e.g. for a split second on first paint. */
		height: calc( 100svh - var( --tkge-header-h, 64px ) - var( --tkge-actions-h, 64px ) - 8px ) !important;
		max-height: calc( 100svh - var( --tkge-header-h, 64px ) - var( --tkge-actions-h, 64px ) - 8px ) !important;
		min-height: 320px !important;
		aspect-ratio: unset !important;
	}

	/* Safety net for every other mode on mobile (e.g. Desktop 16:9,
	   or a landscape-shaped Flexible game) — a width-driven ratio on a
	   narrow phone screen can shrink to a sliver tall enough to clip
	   HUD/menu content. This puts a floor under it without changing
	   how the mode behaves on wider screens. */
	.game-root:not( .game-root--tall ):not( .game-root--fill ) {
		min-height: 320px;
	}

	/*
	 * Mobile edge-to-edge frame (width breakout only).
	 * ----------------------------------------------------------------------
	 * Border/padding/background/dog-ear removal now lives above, outside
	 * this media query, and applies at every width. What's left here is
	 * just the mobile-only "stretch to the actual screen edges" part.
	 *
	 * This used to be done with the classic `left: 50%; margin-left:
	 * -50vw` full-bleed trick. That trick only cancels out correctly when
	 * the frame's containing block happens to be exactly viewport-width
	 * and horizontally centered on the page — an assumption about the
	 * THEME's layout that this plugin has no way to guarantee. When it
	 * doesn't hold, the box doesn't end up flush with the screen edges;
	 * it gets shifted sideways and spills off past the right edge
	 * instead, which is exactly the "pushed off screen" symptom this
	 * replaces. `width`/`margin-left` are instead set directly, in
	 * pixels, from JS (game-embed-sizing.js's applyFrameBreakout()) using
	 * the frame's actual measured position — that can't drift off-screen
	 * regardless of how the theme pads or centers its containers, and is
	 * re-measured on load/resize/orientation change. This file just
	 * reserves `position: relative` so those pixel offsets have somewhere
	 * to apply from.
	 */
	.game-frame.game-frame--game-active {
		position: relative;
		/* See the matching comment in game-fullpage.css: 0px for a normal
		   in-flow header, or the header's real height when it's fixed/
		   stuck-sticky and therefore overlapping this box's top edge
		   instead of sitting above it. Without this, the game's height is
		   already correctly shrunk to fit under the header, but the box
		   still starts at y=0 and loses that same height off its visible
		   top instead. */
		margin-top: var( --tkge-header-overlap-h, 0px );
	}

	/* Belt-and-suspenders: even with the width/margin-left now measured
	   precisely in JS rather than guessed via 100vw, this stays as a
	   safety net against any stray sub-pixel rounding. Scoped to only
	   pages that actually have an active, edge-to-edge game frame (rather
	   than a blanket site-wide rule) via :has(). */
	body:has( .game-frame--game-active ) {
		overflow-x: hidden;
	}
}
