/*
 * Product launch landing page.
 * Loaded on templates/template-product-launch.php only, after style.css and
 * responsive-fixes.css.
 *
 * Built from the approved "Option 3" Figma frame. The page is darker than the
 * rest of the site on purpose — it is the launch campaign's own look. Type and
 * button shapes still follow the homepage redesign (css/homepage-v2.css):
 * Erbaum for headings, Inter for body copy, brand gold on dark.
 */

:root {
	/* Must stay equal to the solid fill of images/launch-hero-ridge.png, or the
	   ridge shows a seam where it meets the section below it. */
	--launch-bg: #161515;
	--launch-panel: #272727;       /* card face */
	--launch-panel-2: #1f1d1d;     /* detail panel face */
	/* The value the design's own chevron SVG ships, which its panel gold matches
	   too — a muted bronze, not the homepage's brighter #b17e20. Used for every
	   gold element on this page. */
	--launch-gold: #a37a44;
	--launch-gold-hover: #b58e59;
	--launch-amber: #f6a700;       /* PLAY NOW only, matching the game itself */
	--launch-amber-hover: #ffb81c;
	--launch-cream: #e5e0d9;
	--launch-text: #c9c4bd;
	--launch-text-dim: #9a938c;
	--launch-line: #3a3531;
}

.launch-page {
	background-color: var(--launch-bg);
	color: var(--launch-text);
	overflow-x: clip;
}

/* Two class names deep, so the per-section colours further down (which are all
   `.launch-page .launch-*`) still win over this default. */
.launch-page h1,
.launch-page h2,
.launch-page h3 {
	color: var(--launch-cream);
	font-family: var(--font-heading);
	text-transform: uppercase;
	letter-spacing: 0.01em;
	margin: 0;
}

/*
 * Resets for what style.css imposes site-wide: `.inner { text-align: left }`,
 * `p { text-align: left }` and the default paragraph margins.
 *
 * `:where()` keeps these at the specificity of a bare element selector, so they
 * still beat style.css on source order but lose to every component class below.
 * Written plainly — `.launch-page p` — they score 0,1,1 and quietly outrank
 * rules like `.launch-hero__text` (0,1,0), which silently drops any
 * `margin: … auto …` and leaves the block flush left instead of centred.
 */
:where(.launch-page) .inner,
:where(.launch-page) p,
:where(.launch-page) li {
	text-align: inherit;
}

:where(.launch-page) p {
	margin: 0;
}

/* :where() for the same reason as the p and .inner resets above: written plainly
   this scores 0,1,1 and outranks component classes like .launch-card__applications
   (0,1,0), which silently dropped its `margin-top: auto` and left the list
   stranded at the top of the card. */
/* `li` is in here because style.css gives every list item a 50px left margin,
   which pushed the card's application list half way across the card. */
:where(.launch-page) ul,
:where(.launch-page) li {
	list-style: none;
	margin: 0;
	padding: 0;
}

.launch-page .sr-only {
	position: absolute;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
	white-space: nowrap;
	border: 0;
}

/* Sits on the title's cap line, as the design has it. `sup`'s default
   vertical-align: super lifted it clear of the word entirely. */
.launch-tm {
	font-size: 0.3em;
	vertical-align: baseline;
	position: relative;
	top: -1.55em;
	margin-left: 0.12em;
}

/* ------------------------------------------------------------------ */
/* Bands                                                               */
/* ------------------------------------------------------------------ */

.launch-band {
	background-color: var(--launch-bg);
	padding: 72px 0;
	position: relative;
	text-align: center;
}

.launch-band--paper {
	background-color: #fff;
	color: #262524;
	text-align: left;
}

.launch-band--paper h1,
.launch-band--paper h2,
.launch-band--paper h3 {
	color: #262524;
}

/* ------------------------------------------------------------------ */
/* Buttons                                                             */
/* ------------------------------------------------------------------ */

.launch-btn,
.launch-btn-outline {
	display: inline-block;
	font-family: var(--font-heading);
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.06em;
	text-decoration: none;
	line-height: 1;
	transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}

/*
 * PLAY NOW is the design's own artwork rather than a CSS button, so there is no
 * type or border to style — only the size it renders at and how it responds.
 * Its accessible name comes from aria-label on the link; see launch-game.php.
 */
.launch-btn--play {
	display: inline-block;
	width: clamp(180px, 16.55vw, 238px);  /* 238.36px at 1440, per the design */
	line-height: 0;
	transition: transform 0.12s ease, filter 0.12s ease;
}

.launch-btn--play img {
	display: block;
	width: 100%;
	height: auto;
	/* Pixel art: keep the edges hard when it scales. */
	image-rendering: pixelated;
}

.launch-btn--play:hover,
.launch-btn--play:focus-visible {
	filter: brightness(1.08);
}

.launch-btn--play:active {
	transform: translateY(2px);
}

.launch-btn-outline {
	background-color: transparent;
	color: var(--launch-gold);
	border: 1px solid var(--launch-gold);
	padding: 13px 26px;
	font-size: 13px;
}

.launch-btn-outline:hover,
.launch-btn-outline:focus-visible {
	background-color: var(--launch-gold);
	color: #171513;
}

.launch-page a:focus-visible,
.launch-page button:focus-visible {
	outline: 2px solid var(--launch-amber);
	outline-offset: 3px;
}

/* ------------------------------------------------------------------ */
/* Placeholders — until the 3D renders and console artwork land (#78)   */
/* ------------------------------------------------------------------ */

.launch-placeholder {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 100%;
	min-height: 160px;
	padding: 20px;
	background-color: #2e2b28;
	border: 1px dashed #5b554e;
	color: var(--launch-text-dim);
	font-size: 13px;
	text-align: center;
	text-transform: uppercase;
	letter-spacing: 0.08em;
}

/* The hero placeholder lies behind the copy rather than above it, so the band
   keeps the height it will have once the real illustration lands. */
.launch-placeholder--hero {
	position: absolute;
	inset: 0;
	min-height: 0;
	align-items: flex-start;
	padding-top: 40px;
}

.launch-placeholder--console {
	aspect-ratio: 16 / 9;
	min-height: 0;
}

.launch-placeholder--gun {
	min-height: 150px;
}

/* ------------------------------------------------------------------ */
/* Hero                                                                */
/* ------------------------------------------------------------------ */

/*
 * Hero geometry, measured off the Figma "Option 3" frame. All the design's
 * y-values are taken from the top of that frame, which includes the site
 * header; the header ends at y=185, so everything here is that value minus 185.
 *
 *   hero photo      y  126 → 1314
 *   ridge overlay   y  921 → 1328  (1439 x 407)
 *   h1              y  449 (max-width  958)
 *   sub-headline    y  703 (max-width 1074)
 *   intro           y  803 (max-width  667)
 *
 * The ridge is not here: it belongs to the game band below, which reaches up
 * over this one. See .launch-game__ridge.
 */
.launch-hero {
	padding: 0;
	/*
	 * The band stops at frame y=1105 — the row where the ridge is opaque right
	 * across its width, so nothing painted from this boundary down can clip it.
	 * 1105 - 185 = 920px. The photo carries on past it at its full 1143px and
	 * the ridge covers the difference, exactly as the design layers them.
	 * Scales at 920/1440 = 63.9vw; min-height rather than height so long copy
	 * can never be clipped.
	 */
	min-height: clamp(450px, 63.9vw, 920px);
	/* Not clipped: the photo is taller than the band on purpose and has to stay
	   visible under the ridge's dithering, which reaches down into the band
	   below. The ridge and that band's background cover whatever is left. */
	overflow: visible;
}

.launch-hero__image {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	/* Deliberately taller than the band: the photo keeps the full 1143px frame
	   it was composed in, and the band clips the bottom. Sizing it to the band
	   instead would re-crop the artwork and shift the welder. */
	height: clamp(560px, 79.4vw, 1143px);
	object-fit: cover;
	/*
	 * Held near the top, because the head is near the top.
	 *
	 * The artwork is 1440 x 1188 and the welder's hair starts 90px down — 7.6%.
	 * cover scales the image to the band's width, so the wider the screen the
	 * more height spills over and gets cropped. Centred, at 1920 that took 220px
	 * off the top and cut his head off, which is what the client reported.
	 *
	 * 12% keeps the hair clear at every width we care about: 82px of headroom at
	 * 1512, 67px at 1920, 44px at 2560. It costs height at the bottom of the
	 * frame instead, where the ridge and the copy already cover the artwork.
	 */
	object-position: 50% 12%;
}

.launch-hero__image--mobile {
	display: none;
}

/* Sits on the hero's bottom edge and creeps up over the photo. Its solid fill
   is the page background, so it and the section below join with no seam — keep
   --launch-bg equal to the PNG's fill (#161515) or the join will show. */
/* Very light scrim. The illustration is already dark behind the copy, so this
   only has to hold the contrast steady across different crops. */
.launch-hero--has-image::after {
	content: "";
	position: absolute;
	inset: 0;
	background: linear-gradient(
		to bottom,
		rgba(21, 19, 19, 0.3) 0%,
		rgba(21, 19, 19, 0.12) 34%,
		rgba(21, 19, 19, 0) 62%
	);
	pointer-events: none;
}

.launch-hero__inner {
	position: relative;
	z-index: 2;
	padding-top: clamp(72px, 18.33vw, 264px); /* h1 top: 449 - 185 */
	/* Keeps the copy clear of the ridge reaching up from the band below. Tracks
	   the ridge's own offset, plus slack so the two never meet on wide screens. */
	padding-bottom: calc(12.92vw + 24px);
}

.launch-hero__copy {
	text-align: center;
}

/*
 * Type sizes are solved against the real Erbaum metrics, not eyeballed: each
 * one is the size at which a line's rendered width matches the same line in the
 * design at 1440px (h1 "A NEW ERA IS" = 753px, sub-headline line 2 = 706px).
 * The vw values are those sizes over 1440 so everything scales together.
 */
.launch-page .launch-hero__title {
	max-width: 958px;
	margin: 0 auto;
	font-size: clamp(47px, 7.78vw, 112px);
	line-height: 0.94; /* 105px, the design's line spacing */
	color: #dad5ce;
	text-shadow: 0 4px 24px rgba(0, 0, 0, 0.55);
	/* Two even lines ("A NEW ERA / IS UPON US") rather than a full first line
	   with the leftovers below, without a <br> the client cannot edit. */
	text-wrap: balance;
}

/* The client asked for "New Era" in gold. Which words these are is the
   launch_hero_title_accent field; see treg_launch_highlight(). */
.launch-page .launch-hero__title-accent {
	color: var(--launch-gold-hover);
}

/*
 * Spacing is set from the gaps between the *ink* in the design, not between
 * Figma's text boxes: the sub-headline's box carries about 22px of empty space
 * above its cap line that CSS line-height does not reproduce, so matching the
 * boxes would leave the copy visibly tighter than the design. Ink to ink, the
 * design runs 79.5px from the headline's baseline to the sub-headline's caps,
 * and 32.8px from there to the intro's.
 */
.launch-hero__subtitle {
	max-width: 1074px;
	margin: clamp(16px, 2.43vw, 35px) auto 0;
	font-family: var(--font-heading);
	font-weight: 700;
	font-size: clamp(17px, 2.01vw, 29px);
	line-height: 1.27;
	text-transform: uppercase;
	color: #e6dfd8;
	text-shadow: 0 2px 14px rgba(0, 0, 0, 0.65);
	/* The 1074px box is wider than the design's own line break, so an unbalanced
	   wrap strands "YOU." alone on line two. Balancing gets back to the design's
	   two even lines without hard-coding a <br> the client cannot edit. */
	text-wrap: balance;
}

.launch-hero__text {
	/* Wide enough for the one-sentence intro (726px at the 17.81px cap) to sit
	   on one line on desktop, with room for font rendering differences. */
	max-width: 760px;
	margin: clamp(13px, 1.46vw, 21px) auto 0;
	font-size: clamp(14px, 1.237vw, 17.81px);
	line-height: 1.235; /* 22px at 17.81px, matching the design's 66px three-line block */
	color: #e6dfd8;
	text-shadow: 0 2px 10px rgba(0, 0, 0, 0.75);
}

/* ------------------------------------------------------------------ */
/* Game band                                                           */
/* ------------------------------------------------------------------ */

/*
 * Game band. Measured off the design crop, whose frame maps to the Figma
 * "Option 3" y-values via the console group at y=1385:
 *
 *   ridge          y  921 → 1328   (this section's top edge, reaching up)
 *   dither ends    y 1067          ← the hero band stops here
 *   heading ink    y 1138.7 → 1195.1
 *   lede ink       y 1227.5 → 1281.5
 *   console top    y 1385
 *
 * So relative to this band's top (1067): heading at 71.7, lede 32.4 below the
 * heading, console 103.5 below the lede.
 */
.launch-game {
	/*
	 * No background-color of its own: .launch-band already supplies one, and
	 * that is the point — it paints from this band's top edge down, and the
	 * ridge's lowest opaque row now sits 2px above that edge, so it can no
	 * longer clip the dithering. Getting this wrong is what produced the flat
	 * horizontal edge on the right, where the ridge's silhouette dips lowest.
	 */
	/*
	 * The design's own pixel-grid artwork, which replaces the radial-gradient
	 * that stood in for it. The file is white marks over black at 11% alpha;
	 * composited normally its black would darken the band into a visible
	 * rectangle, so it is screened on ::after instead, where black is a no-op
	 * and only the marks show. Sized 1463/1440 wide, as the design places it.
	 */
	background-image: none;
	position: relative;
	/*
	 * Above the hero, so the ridge reaching up out of this band lands on top of
	 * the hero photo rather than behind it. Also makes this band a stacking
	 * context, which contains the ::after screen blend below — without that the
	 * blend reaches past the band and lightens the photo showing through.
	 */
	z-index: 1;
	/* Not hidden: the ridge has to spill out of the top of this band. */
	overflow: visible;
	/* 40px under the console, not 90: the gap down to "Know your enemy" read
	   as empty (#183). The phone padding further down sets its own. */
	padding: clamp(40px, 4.51vw, 65px) 0 40px;
}

/*
 * The ridge sits 146px above this band's top edge, so its dithered crest lands
 * over the hero photo and its solid fill covers the join.
 *
 * Height is left to the natural ratio (2878 x 814 = 28.28vw, the design's 407px
 * at 1440px wide) rather than capped. A cap plus object-fit: cover would rescale
 * the artwork independently of the offsets below, and those offsets have to
 * track the ridge's own profile exactly — see .launch-game::before.
 */
.launch-game::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 0;
	background-image: url("../images/launch-game-grid.png");
	background-size: 101.6% auto;
	background-position: center top;
	background-repeat: no-repeat;
	/*
	 * Screened at full strength, which is the artwork's own: its marks are white
	 * at 11% alpha, so each lands at about #302f2f over the #161515 band. No
	 * extra opacity — dialling this down to 0.2 put the marks at roughly +5 luma
	 * and they all but disappeared. Turn it down here if it ever needs to
	 * recede, but the file already carries its intended weight.
	 */
	mix-blend-mode: screen;
	pointer-events: none;
}

.launch-game__ridge {
	position: absolute;
	left: 0;
	/*
	 * -186px at 1440. The ridge's silhouette is not level: its lowest fully
	 * opaque row is 184px down, at 83% across. Pushing it up by 186 puts that
	 * row 2px above this band's top edge, so the band's background starts below
	 * the whole silhouette and the dithering reads against the hero photo right
	 * across the width.
	 */
	top: -12.92vw;
	z-index: 1;
	width: 100%;
	height: auto;
	pointer-events: none;
}

/* Above the ridge and the decoration, which would otherwise cover the copy. */
.launch-game > .inner {
	position: relative;
	z-index: 2;
}

.launch-page .launch-game__heading {
	max-width: 1229px;
	margin: 0 auto;
	color: var(--launch-gold);
	font-size: clamp(20px, 2.072vw, 29.84px);
	line-height: 1.168; /* 34.9px, the design's line spacing */
}

.launch-game__text {
	/* Width does the wrapping. Fixed <br>s matched the design at 1440 but broke
	   badly once the text reflowed on a phone. */
	max-width: 560px;
	margin: clamp(14px, 1.6vw, 23px) auto 0;
	color: #f7f1ea;
	font-size: clamp(14px, 1.237vw, 17.81px);
	line-height: 1.258; /* 22.4px at 17.81px, the design's line spacing */
}

/*
 * Console. The frame artwork has a transparent middle, so the game media sits
 * behind it and shows through. Both are positioned against the same box, which
 * holds the design's 926.86 x 532 proportion at any width.
 */
.launch-game__console {
	position: relative;
	max-width: 927px;
	aspect-ratio: 926.86 / 532;
	margin: clamp(48px, 6.74vw, 97px) auto 0;
}

/* The game's slot inside the frame: 880 x 468 at (25, 29) of the frame, as a
   share of it, so it tucks under the frame's inner edge with no hairline gap. */
.launch-game__screen {
	position: absolute;
	left: 2.697%;
	top: 5.451%;
	width: 94.945%;
	height: 87.970%;
	overflow: hidden;
	background-color: #100f0e;
}

.launch-game__media {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.launch-game__frame {
	position: relative;   /* above the screen, which is absolute */
	display: block;
	width: 100%;
	height: auto;
	pointer-events: none;
}

/* Between the lede and the console since #180, so the console's own top
   margin is the gap below it. */
.launch-game__actions {
	margin-top: 38px;
}

.launch-game__actions + .launch-game__console {
	margin-top: 48px;
}

/* The screen opens the game (#210). Desktop only, as Play Now is. */
@media (min-width: 768px) {
	.launch-game__console[data-game-play-proxy] {
		cursor: pointer;
	}
}

/*
 * The phone stand-in for Play Now. Sizes are from the design's 402px mobile
 * frame: heading 19.5px on 24px, note 13px on 15.6px, keys 41px wide, and the
 * gaps 40 / 17 / 22 between console, heading, note and keys.
 */
.launch-game__note {
	display: none;
	margin-top: 40px;
}

.launch-page .launch-game__note-heading {
	color: var(--launch-gold);
	font-size: 19.5px;
	line-height: 1.23;
	/* Two lines, as the design breaks it: "Ready to / strike an arc?" */
	max-width: 11em;
	margin: 0 auto;
}

.launch-game__note-text {
	margin-top: 17px;
	color: #e5dfd9;
	font-family: var(--font-heading);
	font-size: 13px;
	line-height: 1.2;
	text-transform: uppercase;
	letter-spacing: 0.03em;
	max-width: 13em;
	margin-left: auto;
	margin-right: auto;
}

/* The design's ZXC keys. The earlier artwork was a W over A-S-D, two rows in a
   near-square; this one is a single row of three, so it is set wider. */
.launch-game__keys {
	display: block;
	width: 88px;
	height: auto;
	margin: 22px auto 0;
}

/* ------------------------------------------------------------------ */
/* "Know your enemy" cards (Option 7)                                  */
/* ------------------------------------------------------------------ */

/*
 * A shade lighter than the page, entered through a dithered edge at the top and
 * fading back to the page colour at the bottom, where the gun cards begin.
 */
/* .launch-page so it outranks the phone padding every band gets further down;
   the ridge has to sit flush with the band's top edge. */
.launch-page .launch-enemies {
	padding-top: 0;
	padding-bottom: 120px;
	background: linear-gradient(to bottom, #1c1b1b 70%, var(--launch-bg));
	overflow: hidden;
}

/* Its top rows are the page colour and its bottom rows this band's, so it
   stretches edge to edge with no seam on either side. */
.launch-enemies__ridge {
	display: block;
	width: 100%;
	height: clamp(60px, 8.3vw, 120px);
	object-fit: cover;
	object-position: center top;
	pointer-events: none;
}

.launch-page .launch-enemies__heading {
	margin: clamp(16px, 2vw, 28px) auto 0;
	color: var(--launch-gold);
	font-size: clamp(20px, 2.08vw, 30px);
	line-height: 1.19;
}

/* Two lines on a desktop, not three (#183). */
.launch-enemies__text {
	max-width: 800px;
	margin: 12px auto 0;
	color: var(--launch-cream);
	font-size: clamp(14px, 1.237vw, 17.81px);
	line-height: 1.19;
}

.launch-enemies__carousel {
	position: relative;
	margin-top: clamp(40px, 6.9vw, 99px);
}

.launch-page .launch-enemies__list {
	display: grid;
	grid-template-columns: repeat(4, minmax(0, 1fr));
	gap: 54px;
	max-width: 1234px;
	margin: 0 auto;
	padding: 0;
	list-style: none;
}

/* The arrows only exist for the phone strip. */
.launch-enemies__arrow {
	display: none;
}

/*
 * Card: the same frame artwork as the gun cards (see .launch-card), 263 x 589 in
 * the design, around a face that is lit from the top left.
 */
.launch-page .launch-enemy {
	position: relative;
	display: flex;
	flex-direction: column;
	margin: 0;
	padding: 8px 8px 24px;
	text-align: center;
	background-image: linear-gradient(-64deg, #2f2f2f 5%, #282828 64%);
	border: 13px solid transparent;
	border-image-source: url("../images/launch-card-frame.png");
	border-image-slice: 56 fill;
	border-image-width: 26px;
	border-image-repeat: stretch;
}

/* The inset panel the character stands in: 242 x 359 in the design. */
.launch-enemy__art {
	position: relative;
	aspect-ratio: 242 / 359;
	padding-top: 16px;
	overflow: hidden;
	background:
		radial-gradient(ellipse 120% 80% at 50% 100%, rgba(35, 35, 35, 0) 12%, #2b2b2b 100%),
		linear-gradient(to bottom, #2f2f2f 20%, #282828);
	box-shadow: inset -2px -2px 0 #4f4f4f, inset 2px 2px 0 #1b1b1b;
}

/* The design sets the name behind the character, who stands in front of it. */
.launch-enemy__eyebrow,
.launch-page .launch-enemy__name {
	position: relative;
	z-index: 0;
}

.launch-enemy__eyebrow {
	color: var(--launch-gold);
	font-family: var(--font-heading);
	font-weight: 700;
	font-size: 12.95px;
	line-height: 1.55;
	text-transform: uppercase;
}

.launch-page .launch-enemy__name {
	margin-top: 8px;
	color: var(--launch-cream);
	font-weight: 900;
	font-size: clamp(26px, 2.62vw, 37.7px);
	line-height: 0.85;
	letter-spacing: -0.023em;
	text-transform: uppercase;
}

/* The art is cut out on transparency and runs a little wider than the panel,
   standing on its floor. */
.launch-enemy__image {
	position: absolute;
	z-index: 1;
	/* Sized so the head just meets the second line of the name, as in the
	   design, rather than covering it. */
	left: -2%;
	bottom: 0;
	width: 104%;
	height: auto;
}

/* Sentence case, as the text is written: the client found the all-caps
   descriptions hard to read (#184). The names, eyebrows and the "Solution"
   label stay in caps. */
.launch-enemy__problem,
.launch-enemy__solution {
	font-family: var(--font-heading);
	font-size: 13.08px;
	line-height: 1.33;
	letter-spacing: 0.02em;
}

.launch-enemy__problem {
	/* 160px at 13px in the design; a touch more because Erbaum runs wider than
	   the Figma face. */
	max-width: 13em;
	margin: 20px auto 0;
	color: var(--launch-cream);
}

.launch-enemy__solution {
	max-width: 17em;
	margin: 16px auto 0;
	color: var(--launch-gold);
}

.launch-enemy__solution b {
	display: block;
	margin-bottom: 4px;
	font-size: 17.08px;
	font-weight: 700;
	text-transform: uppercase;
}

/* ------------------------------------------------------------------ */
/* Gun cards                                                           */
/* ------------------------------------------------------------------ */

.launch-guns {
	padding-top: 86px;
}

.launch-page .launch-guns__heading {
	display: flex;
	flex-direction: column;
	gap: 8px;
	font-size: clamp(20px, 2.4vw, 29px);
	line-height: 1.2;
}

.launch-guns__heading-sub {
	color: var(--launch-gold);
}

/*
 * Card grid. The design's cards are 375 x 510 with about 47px between them,
 * filling the 1220px the row occupies at 1440. The gap between the section's
 * gold sub-heading and the frames' top edge measures 103px, baseline to edge.
 */
.launch-guns__grid {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: 48px;
	margin-top: clamp(40px, 6.6vw, 95px);
	/* Not stretched: with a stretched height, the cards' aspect-ratio would work
	   backwards off the row and make them narrower than their column. */
	align-items: start;
}

/*
 * Cards fill row 1 and panels sit on row 2 across the whole width. All three
 * panels share that one area, which is fine because only one is ever open.
 *
 * Saying which row each belongs on — rather than letting them flow — is what
 * lets the markup keep each panel next to its own card. On a phone the grid
 * drops to one column, these rules come off, and placement follows the
 * document, so a panel opens directly under the card it came from.
 */
/*
 * Landing on /newera/#launch-card-wingman (#128) puts the card clear of the
 * sticky top bar rather than under it.
 */
.launch-card {
	scroll-margin-top: 96px;
}

.launch-card {
	grid-row: 1;
}

.launch-panel {
	grid-column: 1 / -1;
	grid-row: 2;
}

/*
 * Card. The frame is the design's artwork rather than a CSS border, drawn with
 * border-image so the decorated corners keep their shape while the card grows
 * with its content — an absolutely positioned overlay would stretch them.
 *
 * The source bars are 27px with corner detail reaching 52px in, so the slice is
 * 56. border-image-width is larger than border-width on purpose: it draws the
 * corners at their own proportions and lets them reach inward over the padding,
 * while the content is only inset by the 13px the bars actually occupy.
 */
.launch-page .launch-card {
	position: relative;
	/*
	 * The design's card is 375 x 510. The ratio lives here while the card is
	 * only ever the collapsed face — it measures the border box, so it lands on
	 * the design's figure exactly. On a phone, where a panel moves inside, it
	 * hands over to the face; see the 899px block.
	 */
	aspect-ratio: 375 / 510;
	/* A column so the face can fill the card's height — that is what puts the
	   Learn More on the bottom edge — and so a panel moved in on a phone stacks
	   below it. */
	display: flex;
	flex-direction: column;
	padding: 26px 22px 22px;
	text-align: left;
	background-color: #2a2a2a;
	border: 13px solid transparent;
	border-image-source: url("../images/launch-card-frame.png");
	border-image-slice: 56 fill;
	border-image-width: 26px;
	border-image-repeat: stretch;
}

/*
 * The face is the card as it reads collapsed. It holds the design's 375 x 510
 * and the layout, so that when a panel is moved inside the card on a phone the
 * collapsed part keeps its proportions instead of stretching.
 *
 * The design's card is 375 x 510 with the gun masked from y+69 and the
 * application list starting at y+268 — the two overlap, so the copy sits over
 * the render rather than below it. The ratio is a floor: longer copy still
 * grows the face.
 */
.launch-card__face {
	position: relative;
	display: flex;
	flex-direction: column;
	flex: 1;
}

/* The same pixel-grid artwork the game band uses, held inside the frame. */
.launch-card::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 0;
	background-image: url("../images/launch-game-grid.png");
	background-size: 160% auto;
	background-position: 58% 38%;
	background-repeat: no-repeat;
	mix-blend-mode: screen;
	opacity: 0.9;
	/* Gathered behind the render and falling away from it, rather than running
	   evenly to the frame. Both spellings carry the same value — leaving the
	   prefixed one on an older gradient would quietly win in WebKit. */
	-webkit-mask-image: radial-gradient(ellipse 42% 38% at 70% 50%, #000 30%, transparent 100%);
	mask-image: radial-gradient(ellipse 42% 38% at 70% 50%, #000 30%, transparent 100%);
	pointer-events: none;
}

/* Above the grid and the render. The figure is deliberately excluded. */
.launch-card__title,
.launch-card__applications,
.launch-card__more {
	position: relative;
	z-index: 1;
}

.launch-page .launch-card__title {
	font-size: clamp(24px, 2.81vw, 40.49px);
	line-height: 1.05;
}

/*
 * The render is a layer, not a block in the flow: it is masked to 351 x 379
 * from y+69 of a 484-tall card and cropped, and the copy sits over its empty
 * lower-left. Inset in percentages so it tracks the card at any width.
 */
.launch-card__figure {
	position: absolute;
	left: 0;
	right: 0;
	top: 14.26%;      /*  69 / 484 */
	height: 78.31%;   /* 379 / 484 */
	z-index: 0;
	overflow: hidden;
}

.launch-card__image {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* The Tough Gun render is squarer than the other two, so cover trims ~23px
   off each side and the nozzle lost its tip (#181). Anchored left, the trim
   comes off the handle end, which already runs off the render's edge. */
#launch-card-tough-gun .launch-card__image {
	object-position: left center;
}

.launch-card__applications {
	/* Bottom-aligned, so the list and button sit over the render's empty corner
	   wherever the card's height lands. */
	margin-top: auto;
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 14px;
	font-family: var(--font-heading);
	font-size: 13px;
	text-align: left;
	text-transform: uppercase;
	letter-spacing: 0.14em;
	color: var(--launch-cream);
}

.launch-card__applications li {
	position: relative;
	padding-left: 22px;
	line-height: 1.35;
}

.launch-card__applications li::before {
	content: "";
	position: absolute;
	left: 0;
	top: 0.15em;
	width: 12px;
	height: 20px;
	/* The design's pixel chevron, masked so it takes the gold from the
	   stylesheet rather than the colour baked into the file. */
	background-color: var(--launch-gold);
	-webkit-mask: url("../images/launch-chevron.svg") no-repeat center / contain;
	mask: url("../images/launch-chevron.svg") no-repeat center / contain;
}

/*
 * Learn More. Sampling the design gives a 1px black hairline with a single
 * light line inside its top edge, the card's own #2a2a2a as the face and the
 * brand gold for the label — not the gold outline the shared button style
 * draws, so most of that is overridden here. Its box is 324 x 45 in the design,
 * a ratio of about 7.2.
 */
.launch-page .launch-card__more {
	align-self: stretch;
	/* The design's button is 324 x 45; holding the ratio keeps it in proportion
	   whatever width the card ends up at. */
	aspect-ratio: 324 / 45;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 0 16px;
	text-align: center;
	background-color: #2a2a2a;
	border: 1px solid #000;
	box-shadow: inset 0 1px 0 #6a6a6a;
	color: var(--launch-gold);
	font-size: 14px;
	letter-spacing: 0.1em;
}

.launch-page .launch-card__more:hover,
.launch-page .launch-card__more:focus-visible {
	background-color: #333;
	color: var(--launch-cream);
}

.launch-card__applications + .launch-card__more {
	margin-top: 32px;
}

/* ------------------------------------------------------------------ */
/* Gun detail panels                                                   */
/* ------------------------------------------------------------------ */

.launch-page .launch-panel {
	position: relative;
	display: grid;
	grid-template-columns: 1fr;
	gap: 28px;
	/* The design's panel is 1235 x 633. As a floor, not a cap: a panel with more
	   copy than fits still grows. */
	aspect-ratio: 1235 / 633;
	/* minmax(0, 1fr), not the implicit auto: a grid column is at least as wide as
	   its content's longest unbreakable word, and at these title sizes one name
	   is enough to push the whole panel past its own frame. */
	grid-template-columns: minmax(0, 1fr);
	padding: clamp(28px, 4.9vw, 70px) 50px 34px clamp(28px, 3.8vw, 55px);
	text-align: left;
	/* Same face as the cards. */
	background-color: #2a2a2a;
	/* Same frame artwork and slice as the cards — the design uses one border
	   treatment for both, only at different sizes. */
	border: 13px solid transparent;
	border-image-source: url("../images/launch-panel-frame.png");
	border-image-slice: 56 fill;
	border-image-width: 26px;
	border-image-repeat: stretch;
}

.launch-panel:focus {
	outline: none;
}

/*
 * With a render, the copy keeps the left 56% and the render sits on the right,
 * behind it. The design overlaps them — its panel is 1235 wide with the copy
 * running to about 620 and the render from 401 to 1203 — so the render's empty
 * left edge passes over the end of the spec columns.
 */
.launch-page .launch-panel:has(.launch-panel__figure) .launch-panel__copy {
	/* Wide enough to keep the spec columns on single lines, and narrow enough to
	   clear the render's nozzle. */
	max-width: 53%;
}

.launch-panel__copy {
	position: relative;
	z-index: 1;
	/* Lets this shrink below its content's natural width, so the guard above can
	   do its job. */
	min-width: 0;
}

.launch-panel__badge {
	position: absolute;
	top: 13%;
	right: 6%;
}

.launch-panel__badge img {
	display: block;
	width: clamp(110px, 11.8vw, 170px);
	height: auto;
}

.launch-panel__badge span {
	display: inline-block;
	padding: 9px 16px;
	border: 1px solid var(--launch-gold);
	border-radius: 999px;
	color: var(--launch-gold);
	font-family: var(--font-heading);
	font-size: 11px;
	text-transform: uppercase;
	letter-spacing: 0.1em;
	white-space: nowrap;
}

.launch-page .launch-panel__title {
	font-size: clamp(34px, 5.4vw, 77.8px);
	line-height: 1.05;
	/* Keep the title clear of the launch-date badge. */
	padding-right: 130px;
	/*
	 * The copy column is sized for the spec grid, which is narrower than a long
	 * name needs at this size — "Tough Gun" was breaking across two lines. The
	 * title runs past it instead; there is nothing but the render's empty upper
	 * left beside it. Percentages cannot do this, since they resolve against
	 * that same parent.
	 */
	white-space: nowrap;
}

.launch-panel__tagline {
	/* 83px below the title in the design. */
	margin-top: clamp(24px, 4.7vw, 68px);
	/* Two lines, as the design breaks it. Wider than the design's own 184px
	   because this Erbaum sets wider than the one the Figma file uses — the same
	   difference the hero headline shows. */
	max-width: 43.4%;
	color: var(--launch-gold);
	font-family: var(--font-heading);
	font-weight: 700;
	font-size: clamp(18px, 1.67vw, 24px);
	line-height: 1.36;
	text-transform: uppercase;
	letter-spacing: 0.04em;
}

.launch-panel__text {
	margin-top: clamp(14px, 1.7vw, 24px);
	/* Three short lines, as the design has it — again a little wider than the
	   design's 260px to land the same break with this cut of Erbaum. */
	max-width: 52.8%;
	color: #aba8a3;
	font-size: 15px;
	line-height: 1.38;
}

.launch-panel__specs {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	/* 20px, not 36: the longest spec line needs about 291px and a wider gutter
	   left the column 5px short, wrapping "Ready to Weld out of the box". */
	gap: 12px 20px;
	/* 84px below the description in the design. */
	margin-top: clamp(20px, 3.2vw, 46px);
	padding-top: 24px;
}

.launch-panel__specs:has(.launch-panel__spec-list:only-child) {
	grid-template-columns: minmax(0, 1fr);
}

.launch-panel__spec-list {
	display: flex;
	flex-direction: column;
	gap: 13px;
	font-family: var(--font-heading);
	font-size: 14px;
	color: #c9c5bf;
	text-transform: uppercase;
	letter-spacing: 0.03em;
}

.launch-panel__spec-list li {
	position: relative;
	padding-left: 22px;
	line-height: 1.35;
}

.launch-panel__spec-list li::before {
	content: "";
	position: absolute;
	left: 0;
	top: 0.15em;
	width: 12px;
	height: 20px;
	/* The design's pixel chevron, masked so it takes the gold from the
	   stylesheet rather than the colour baked into the file. */
	background-color: var(--launch-gold);
	-webkit-mask: url("../images/launch-chevron.svg") no-repeat center / contain;
	mask: url("../images/launch-chevron.svg") no-repeat center / contain;
}

.launch-panel__soon {
	margin-top: 26px;
	color: var(--launch-gold);
	font-family: var(--font-heading);
	font-size: 13px;
	text-transform: uppercase;
	letter-spacing: 0.08em;
}

/*
 * The render is taller than the panel, so object-fit sizes it to the panel's
 * height rather than an overflow clip doing the work. Nothing then has to
 * reach outside the frame.
 */
.launch-panel__figure {
	position: absolute;
	right: 0;
	top: 0;
	bottom: 0;
	/* The design's render occupies the panel from 40% across to its right edge,
	   and runs the full height into the bottom corner. */
	left: 40%;
	z-index: 0;
	pointer-events: none;
}

.launch-panel__figure img {
	display: block;
	width: 100%;
	height: 100%;
	/* contain, anchored into the corner. The file is trimmed to the gun itself,
	   so the anchor lands on artwork rather than on transparent margin — which
	   is what let it reach the corner at all. cover magnifies that same trimmed
	   file well past the design's size. */
	object-fit: contain;
	object-position: right bottom;
}

/* The same pixel-grid artwork the cards carry, gathered behind the render. */
.launch-panel::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 0;
	background-image: url("../images/launch-game-grid.png");
	background-size: 90% auto;
	background-position: 62% 40%;
	background-repeat: no-repeat;
	mix-blend-mode: screen;
	opacity: 0.9;
	-webkit-mask-image: radial-gradient(ellipse 34% 46% at 62% 50%, #000 30%, transparent 100%);
	mask-image: radial-gradient(ellipse 34% 46% at 62% 50%, #000 30%, transparent 100%);
	pointer-events: none;
}

/* Above the render, which reaches under this side of the panel. */
.launch-panel__badge {
	z-index: 2;
}

/* Nothing to close until the script turns the panels into a disclosure, so the
   button stays hidden until product-launch.js marks the page as enhanced. */
.launch-panel__close {
	display: none;
	position: absolute;
	top: 14px;
	right: 14px;
	width: 34px;
	height: 34px;
	padding: 0;
	background: none;
	border: 1px solid var(--launch-line);
	color: var(--launch-text-dim);
	cursor: pointer;
}

.launch-page--enhanced .launch-panel__close {
	display: flex;
	align-items: center;
	justify-content: center;
}

/* The same cross the alert bar uses, masked so it takes the button's colour
   and follows it on hover. */
.launch-panel__close span[aria-hidden] {
	display: block;
	width: 12px;
	height: 12px;
	background-color: currentColor;
	-webkit-mask: url("../images/close-btn.svg") no-repeat center / contain;
	mask: url("../images/close-btn.svg") no-repeat center / contain;
}

.launch-panel__close:hover {
	border-color: var(--launch-gold);
	color: var(--launch-gold);
}

/* `hidden` alone loses to `display: grid` on .launch-panel. */
.launch-panel[hidden] {
	display: none;
}

/* ------------------------------------------------------------------ */
/* Closing CTA                                                         */
/* ------------------------------------------------------------------ */

/*
 * Closing call to action.
 *
 * Measured off the design at 1440: 170px from the cards' bottom edge to the top
 * of the heading's capitals, 50px from the foot of the capitals to the top of
 * the button artwork, and 148px from the foot of the artwork to the end of the
 * band. The padding here is what is left after the type's own leading, so it
 * does not read as those figures — .launch-cta__heading carries the rest.
 */
.launch-cta {
	padding-top: 82px;
	padding-bottom: 140px;
	/* Above the grid below. */
	z-index: 0;
}

/*
 * The same pixel-grid artwork as the game band, gathered into the bottom right
 * the way the design has it rather than running evenly across the band. Screened
 * at the artwork's own strength — see .launch-game::after on why it is not
 * dialled down.
 */
.launch-cta::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: -1;
	background-image: url("../images/launch-game-grid.png");
	background-size: 118% auto;
	/*
	 * The artwork's marks live in its middle third — its last tenth is blank, so
	 * anchoring the bottom edge showed almost nothing. 62% lands its densest rows
	 * along the foot of the band, which is where the design has them.
	 */
	background-position: 100% 62%;
	background-repeat: no-repeat;
	mix-blend-mode: screen;
	/* Clear at the top left and building into the bottom right, as the design
	   has it. Both spellings carry the same value — leaving the prefixed one on
	   an older gradient would quietly win in WebKit. */
	-webkit-mask-image: linear-gradient(to top left, #000 24%, transparent 70%);
	mask-image: linear-gradient(to top left, #000 24%, transparent 70%);
	pointer-events: none;
}

.launch-page .launch-cta__heading {
	/*
	 * Wide enough for "NOT SURE WHAT GUN IS RIGHT" and too narrow for the "FOR"
	 * that follows it, which is where the design breaks the line. In em so the
	 * break holds when the clamp below shrinks the type: the line is 16.4em and
	 * the line with "FOR" on it is 18.8em.
	 */
	max-width: 17.5em;
	margin: 0 auto;
	color: var(--launch-gold);
	/* 38px in the design's 1440 frame, where its capitals measure 27.5px. */
	font-size: clamp(22px, 2.64vw, 38px);
	line-height: 1.19;
}

.launch-cta__actions {
	margin-top: 49px;
}

/*
 * The button is artwork at its own size, half the file's 682 x 131 because the
 * file is a 2x export. Its drop shadow is part of the picture, so the box
 * includes it.
 */
.launch-btn--quiz {
	display: inline-block;
	/*
	 * The width belongs on the link, not on the picture inside it. Sized on the
	 * picture, the link shrink-to-fits to the file's intrinsic 682px instead —
	 * so the link came out twice the button's width and the button sat against
	 * its left edge rather than centred under the heading.
	 */
	width: 341px;
	max-width: 100%;
	line-height: 0;
	transition: filter 0.12s ease, transform 0.12s ease;
}

.launch-btn--quiz img {
	display: block;
	width: 100%;
	height: auto;
}

.launch-btn--quiz:hover,
.launch-btn--quiz:focus-visible {
	filter: brightness(1.08);
}

.launch-btn--quiz:active {
	transform: translateY(2px);
}

/* ------------------------------------------------------------------ */
/* Editor content, when the page has any                               */
/* ------------------------------------------------------------------ */

.launch-editor-content {
	max-width: 820px;
}

/* ------------------------------------------------------------------ */
/* Tablet                                                              */
/* ------------------------------------------------------------------ */

@media (max-width: 1024px) {
	/* Not enough width to run the render beside the copy. */
	.launch-page .launch-panel:has(.launch-panel__figure) .launch-panel__copy {
		max-width: none;
	}

	.launch-panel__figure {
		display: none;
	}

	/* These are held narrow on desktop to clear the render. With the render gone
	   there is nothing to clear, and the narrow measure only forces more lines. */
	.launch-panel__tagline,
	.launch-panel__text {
		max-width: none;
	}

	/* Long spec lines have nowhere to go at this width; let them break rather
	   than push past the frame. */
	.launch-panel__spec-list {
		font-size: 13px;
		letter-spacing: 0.02em;
		overflow-wrap: anywhere;
	}

	.launch-card__applications {
		overflow-wrap: anywhere;
	}

	/* No spare width out here, so let long names break. */
	.launch-page .launch-panel__title {
		white-space: normal;
	}

	.launch-panel {
		padding: 36px 32px;
	}

	.launch-panel__badge {
		right: 32px;
	}
}

/* ------------------------------------------------------------------ */
/* Phone                                                               */
/* ------------------------------------------------------------------ */

/* ------------------------------------------------------------------ */
/* One column: cards and panels flow in document order, so each panel   */
/* opens directly beneath its own card.                                 */
/* ------------------------------------------------------------------ */

@media (max-width: 899px) {
	.launch-guns__grid {
		grid-template-columns: minmax(0, 1fr);
		gap: 20px;
	}

	/* Off the explicit rows, so placement follows the document instead. */
	.launch-card,
	.launch-panel {
		grid-row: auto;
		grid-column: auto;
	}

	/*
	 * A panel moved inside its card stops being a panel: no frame of its own, no
	 * face of its own, no name repeated. It is the part of the card that shows
	 * when the card is expanded. product-launch.js does the moving.
	 */
	/*
	 * With a panel inside it, the card has to grow — so the proportion moves to
	 * the face, which stays the collapsed card whatever is added below it.
	 */
	.launch-page .launch-card {
		aspect-ratio: auto;
	}

	.launch-card__face {
		aspect-ratio: 375 / 510;
		flex: none;
	}

	.launch-card > .launch-panel {
		aspect-ratio: auto;
		margin-top: 26px;
		padding: 0;
		border: 0;
		background: none;
		overflow: visible;
	}

	.launch-card > .launch-panel::before {
		display: none;
	}

	/* The card already carries the name, and the close button is the card's own
	   Learn More. */
	.launch-card > .launch-panel .launch-panel__close {
		display: none;
	}

	.launch-card > .launch-panel .launch-panel__title {
		position: absolute;
		width: 1px;
		height: 1px;
		padding: 0;
		margin: -1px;
		overflow: hidden;
		clip: rect(0, 0, 0, 0);
		white-space: nowrap;
	}

	.launch-card > .launch-panel .launch-panel__badge {
		position: static;
		margin: 0 0 18px;
	}

	.launch-card > .launch-panel .launch-panel__tagline {
		margin-top: 0;
	}

	/*
	 * The render sits behind the copy, and at this width the copy crosses the
	 * body of the gun rather than its empty corner. A scrim holds the contrast.
	 *
	 * It hangs off the list rather than the render, because how far up the copy
	 * reaches depends on the wording: Tough Gun's application names wrap to two
	 * lines on a narrow card and the list then starts a third of the way up the
	 * render, well above where a gradient fixed to the render has darkened.
	 * Anchored here it starts just above the first bullet whatever the wrapping.
	 *
	 * It sits behind its own list — negative z-index inside the stacking context
	 * the list already makes — which still puts it above the render.
	 */
	.launch-card__applications::before {
		content: "";
		position: absolute;
		z-index: -1;
		/* Out to the card's padding edge, and down past the gap to the button. */
		left: -22px;
		right: -22px;
		top: -72px;
		bottom: -32px;
		background: linear-gradient(
			to bottom,
			rgba(42, 42, 42, 0) 0,
			rgba(42, 42, 42, 0.88) 72px,
			rgba(42, 42, 42, 0.94) 100%
		);
		pointer-events: none;
	}
}

@media (max-width: 767px) {
	.launch-band {
		padding: 52px 0;
	}

	/* The hero's own padding is already fluid; only the top needs easing off,
	   since 18.33vw is too tight above the headline at phone widths. */
	.launch-hero__inner {
		padding-top: 64px;
	}

	.launch-hero--has-mobile-image .launch-hero__image {
		display: none;
	}

	.launch-hero--has-mobile-image .launch-hero__image--mobile {
		display: block;
	}

	.launch-game {
		padding: 56px 0 64px;
	}

	/* The game is desktop only: swap the button for the note. */
	.launch-game__actions {
		display: none;
	}

	/* The hidden button is still the console's previous sibling, so put back
	   the console's own gap under the lede. */
	.launch-game__actions + .launch-game__console {
		margin-top: clamp(48px, 6.74vw, 97px);
	}

	.launch-game__note {
		display: block;
	}

	/*
	 * Two bands' padding met between the keys and the cards heading — 52px each
	 * — which left far more air there than anywhere else on the page. Half from
	 * each side closes it without singling either band out.
	 */
	.launch-game {
		padding-bottom: 26px;
	}

	.launch-page .launch-guns {
		padding-top: 26px;
	}

	/* The two lines are one heading, so they read on their own leading. */
	.launch-page .launch-guns__heading {
		gap: 0;
	}

	.launch-guns__grid {
		margin-top: 34px;
	}

	.launch-panel {
		padding: 30px 20px;
	}

	/*
	 * 118% of a phone's width is shorter than the band is tall, which would leave
	 * the artwork floating in the middle of it. Size to the band's height here and
	 * let the width crop instead, keeping the right-hand side the design shows.
	 */
	.launch-cta::before {
		background-size: auto 115%;
	}

	/* Not enough width to float the badge beside the title. */
	.launch-panel__badge {
		position: static;
		margin-bottom: 16px;
	}

	.launch-panel__title {
		padding-right: 44px;
	}

	.launch-panel__specs {
		grid-template-columns: minmax(0, 1fr);
	}

}

/* Reduced motion is handled in product-launch.js: CSS cannot pause a video,
   and an animated GIF cannot be paused at all, so the script swaps the GIF for
   its first frame and holds the video on its poster. */

/* ------------------------------------------------------------------ */
/* The game, in a lightbox                                             */
/* ------------------------------------------------------------------ */

/*
 * Opened by PLAY NOW instead of leaving the page. A native <dialog>, so the
 * focus trap, Escape and the inert background come from the browser.
 */
.launch-page .launch-game__dialog {
	width: min(1200px, 94vw);
	max-width: none;
	max-height: 94vh;
	padding: 0;
	border: 0;
	background: transparent;
	overflow: visible;
	color: var(--launch-text);
}

.launch-page .launch-game__dialog::backdrop {
	background-color: rgba(8, 8, 8, 0.88);
}

.launch-game__dialog-inner {
	position: relative;
	display: flex;
	flex-direction: column;
	gap: 22px;
	max-height: 94vh;
	padding: 26px;
	background-color: var(--launch-bg);
	border: 1px solid var(--launch-line);
	overflow-y: auto;
}

/*
 * The game's own frame. 880 x 468 is the window the console artwork is drawn
 * around, so the game keeps the shape it was built for instead of being
 * letterboxed inside a 16:9 box.
 */
.launch-game__dialog-frame {
	position: relative;
	aspect-ratio: 880 / 468;
	background-color: #000;
}

.launch-game__dialog-frame:empty {
	display: none;
}

.launch-game__dialog-iframe {
	display: block;
	width: 100%;
	height: 100%;
	border: 0;
}

/*
 * Inside the panel, not hung off its corner.
 *
 * It used to sit at -13px on both sides, which put it outside the box
 * altogether — detached from the panel, over the page behind it, and close to
 * being clipped by the window edge once the dialog reached 94vw. It now tucks
 * into the panel's own top-right corner, over the game's corner, which is why
 * it carries a solid background.
 */
.launch-page .launch-game__dialog-close {
	position: absolute;
	top: 10px;
	right: 10px;
	z-index: 2;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 34px;
	height: 34px;
	padding: 0;
	background-color: var(--launch-bg);
	border: 1px solid var(--launch-line);
	color: var(--launch-text-dim);
	cursor: pointer;
}

.launch-page .launch-game__dialog-close:hover,
.launch-page .launch-game__dialog-close:focus-visible {
	border-color: var(--launch-gold);
	color: var(--launch-gold);
}

/* The same cross as the alert bar and the gun panels. */
.launch-game__dialog-close span[aria-hidden] {
	display: block;
	width: 12px;
	height: 12px;
	background-color: currentColor;
	-webkit-mask: url("../images/close-btn.svg") no-repeat center / contain;
	mask: url("../images/close-btn.svg") no-repeat center / contain;
}

/* The controls, under the game — what the client asked to keep in the same box. */
.launch-page .launch-game__dialog-help-heading {
	font-size: 18px;
	line-height: 1.2;
	color: var(--launch-gold);
	text-align: left;
}

.launch-game__dialog-help-list {
	display: flex;
	flex-wrap: wrap;
	gap: 8px 32px;
	margin-top: 12px;
	font-family: "Erbaum", sans-serif;
	font-size: 13px;
	line-height: 1.35;
	text-transform: uppercase;
	letter-spacing: 0.06em;
	color: var(--launch-cream);
	text-align: left;
}

@media (max-width: 767px) {
	.launch-game__dialog-inner {
		gap: 16px;
		padding: 18px;
	}

	.launch-game__dialog-help-list {
		flex-direction: column;
		gap: 8px;
	}
}

/* Fullscreen and the focus hint, the two controls /pixel/ puts under the game. */
.launch-game__dialog-tools {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 10px 16px;
	margin-top: -8px;
}

.launch-page .launch-game__dialog-fullscreen {
	flex: 0 0 auto;
	padding: 7px 16px;
	background: none;
	border: 1px solid var(--launch-line);
	color: var(--launch-text);
	font-family: "Erbaum", sans-serif;
	font-size: 12px;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	cursor: pointer;
	transition: border-color 0.15s ease, color 0.15s ease;
}

.launch-page .launch-game__dialog-fullscreen:hover,
.launch-page .launch-game__dialog-fullscreen:focus-visible {
	border-color: var(--launch-gold);
	color: var(--launch-gold);
}

.launch-page .launch-game__dialog-hint {
	flex: 1 1 260px;
	margin: 0;
	color: var(--launch-text-dim);
	font-size: 13px;
	line-height: 1.35;
	text-align: left;
}

/* ------------------------------------------------------------------ */
/* Enemy cards: two across on a tablet, a swipe strip on a phone        */
/* ------------------------------------------------------------------ */

@media (max-width: 1024px) {
	.launch-page .launch-enemies__list {
		grid-template-columns: repeat(2, minmax(0, 260px));
		justify-content: center;
		gap: 32px;
	}
}

/*
 * One card at a time, 284px wide in the design's 402px frame, with the pixel
 * arrows either side of it. Scroll snapping does the work, so it swipes with
 * JavaScript off; the script only wires the arrows.
 */
@media (max-width: 767px) {
	.launch-page .launch-enemies {
		padding-bottom: 72px;
	}

	.launch-enemies__carousel {
		margin-left: -20px;
		margin-right: -20px;
	}

	/* Side padding of half the strip less half a card, so the first and last
	   cards can still snap to the middle. */
	.launch-page .launch-enemies__list {
		display: flex;
		/* Not the tablet's centring: centred overflow spills off the left edge
		   too, where it cannot be scrolled back to. */
		justify-content: flex-start;
		gap: 60px;
		max-width: none;
		padding: 0 calc(50% - 142px);
		overflow-x: auto;
		scroll-snap-type: x mandatory;
		scrollbar-width: none;
		overscroll-behavior-x: contain;
	}

	.launch-enemies__list::-webkit-scrollbar {
		display: none;
	}

	/* The strip takes keyboard focus on a phone (product-launch.js). */
	.launch-page .launch-enemies__list:focus-visible {
		outline: 2px solid var(--color-primary, #b17e20);
		outline-offset: 4px;
	}

	.launch-page .launch-enemy {
		flex: 0 0 284px;
		scroll-snap-align: center;
	}

	.launch-enemies__arrow {
		display: block;
		position: absolute;
		top: 45%;
		z-index: 2;
		width: 44px;
		height: 44px;
		padding: 0;
		border: 0;
		background: none;
		cursor: pointer;
	}

	.launch-enemies__arrow::before {
		content: "";
		position: absolute;
		top: 8px;
		left: 13px;
		width: 17px;
		height: 28px;
		/* The design's pixel chevron, the same one the gun cards use. */
		background-color: var(--launch-gold);
		-webkit-mask: url("../images/launch-chevron.svg") no-repeat center / contain;
		mask: url("../images/launch-chevron.svg") no-repeat center / contain;
	}

	.launch-enemies__arrow--prev {
		left: 8px;
	}

	.launch-enemies__arrow--prev::before {
		transform: scaleX(-1);
	}

	.launch-enemies__arrow--next {
		right: 8px;
	}

	/* .launch-page so the theme's disabled-button fill does not win. */
	.launch-page .launch-enemies__arrow,
	.launch-page .launch-enemies__arrow[disabled] {
		background: none;
		box-shadow: none;
	}

	.launch-enemies__arrow[disabled] {
		opacity: 0.3;
		cursor: default;
	}
}
