/* ==========================================================================
   games.css
   Game cards, game rows, app show page, screenshots, trailers, prose,
   similar games rail card.
   ========================================================================== */

/* ==========================================================================
   Game card (grid)
   ========================================================================== */

.game-card {
	position: relative;
	display: flex;
	flex-direction: column;
	background: var(--surface-1);
	border: 1px solid var(--border);
	border-radius: var(--r-lg);
	padding: var(--s-3);
	box-shadow: var(--inner-hi);
	transition:
		transform var(--dur) var(--ease),
		border-color var(--dur) var(--ease),
		box-shadow var(--dur) var(--ease);
	overflow: hidden;
	text-decoration: none;
	color: inherit;
}

.game-card:hover {
	transform: translateY(-3px);
	border-color: var(--border-strong);
	box-shadow:
		var(--inner-hi),
		var(--shadow-lg),
		0 0 30px color-mix(in srgb, var(--violet) 15%, transparent);
	text-decoration: none;
	color: inherit;
}

.game-card:focus-within {
	border-color: var(--border-accent);
	box-shadow:
		0 0 0 3px color-mix(in srgb, var(--violet) 20%, transparent),
		var(--shadow);
}

.game-card__image-wrap {
	position: relative;
	border-radius: var(--r-md);
	overflow: hidden;
	margin-bottom: var(--s-3);
	background: var(--surface-2);
	aspect-ratio: 460 / 215;
}

.game-card__image-wrap::before {
	content: "";
	position: absolute;
	inset: 0;
	background: linear-gradient(
		180deg,
		rgba(7, 9, 15, 0.65) 0%,
		rgba(7, 9, 15, 0.25) 35%,
		transparent 55%
	);
	pointer-events: none;
	z-index: 1;
}

.game-card-image {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	transition: transform var(--dur-slow) var(--ease);
}

.game-card:hover .game-card-image {
	transform: scale(1.05);
}

.game-card-image-placeholder {
	width: 100%;
	height: 100%;
	background: linear-gradient(
		135deg,
		var(--surface-1) 0%,
		var(--surface-2) 50%,
		var(--surface-1) 100%
	);
	background-size: 200% 200%;
	animation: shimmer 2s var(--ease) infinite;
}

.game-card__image-wrap::after {
	content: "";
	position: absolute;
	inset: 0;
	background: linear-gradient(
		180deg,
		transparent 60%,
		rgba(7, 9, 15, 0.5) 100%
	);
	pointer-events: none;
	opacity: 0;
	transition: opacity var(--dur) var(--ease);
}

.game-card:hover .game-card__image-wrap::after {
	opacity: 1;
}

.game-card__badges {
	position: absolute;
	top: var(--s-2);
	left: var(--s-2);
	right: var(--s-2);
	display: flex;
	flex-wrap: wrap;
	gap: 4px;
	z-index: 2;
	pointer-events: none;
}

.game-card__badges > * {
	pointer-events: auto;
	-webkit-backdrop-filter: blur(6px) saturate(140%);
	backdrop-filter: blur(6px) saturate(140%);
}

/* ==========================================================================
   Trackable card (one-click "Want to Play")
   ponytail: trackable wrapper positions a tracked-state slot over the card
   image. The default .game-card remains the interactive surface; the track
   slot is its own element with its own focus ring, so focus order is
   image -> link -> track button.
   ========================================================================== */

.game-card-trackable {
	position: relative;
	display: flex;
	flex-direction: column;
}

.game-card-trackable > .game-card {
	flex: 1;
}

.game-card__track-slot {
	position: absolute;
	top: var(--s-2);
	right: var(--s-2);
	z-index: 3;
	pointer-events: none;
}

.game-card__track-slot > * {
	pointer-events: auto;
}

.game-card__track-btn {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	height: 30px;
	padding: 0 12px;
	font-family: var(--font-sans);
	font-size: var(--text-xs);
	font-weight: 600;
	letter-spacing: var(--tracking-snug);
	color: white;
	background: var(--aurora-violet);
	border: 1px solid rgba(255, 255, 255, 0.18);
	border-radius: var(--r-full);
	cursor: pointer;
	text-decoration: none;
	white-space: nowrap;
	user-select: none;
	-webkit-user-select: none;
	box-shadow:
		var(--inner-hi),
		0 4px 12px rgba(0, 0, 0, 0.4);
	transition:
		transform var(--dur-fast) var(--ease),
		background var(--dur) var(--ease),
		box-shadow var(--dur) var(--ease);
}

.game-card__track-btn:hover {
	background: var(--aurora);
	transform: translateY(-1px);
	box-shadow: var(--inner-hi), var(--shadow-glow);
	color: white;
	text-decoration: none;
}

.game-card__track-btn:active {
	transform: translateY(0);
}

.game-card__track-btn:focus-visible {
	outline: none;
	box-shadow:
		0 0 0 3px var(--border-accent),
		var(--inner-hi);
}

.game-card__track-btn--signin {
	background: var(--surface-2);
	border-color: var(--border-strong);
	color: var(--text);
}

.game-card__track-btn--signin:hover {
	background: var(--surface-3);
	color: var(--text);
	box-shadow: var(--inner-hi), var(--shadow-sm);
}

.game-card__tracked {
	display: inline-flex;
	align-items: center;
	height: 26px;
	padding: 0 12px;
	font-size: var(--text-xs);
	font-weight: 700;
	letter-spacing: 0.04em;
	text-transform: uppercase;
	color: white;
	background: rgba(16, 185, 129, 0.92);
	border: 1px solid rgba(255, 255, 255, 0.18);
	border-radius: var(--r-full);
	box-shadow:
		var(--inner-hi),
		0 4px 12px rgba(0, 0, 0, 0.4);
}

.game-card__tracked--want_to_play {
	background: rgba(248, 113, 113, 0.92);
}
.game-card__tracked--playing {
	background: rgba(16, 185, 129, 0.92);
}
.game-card__tracked--played {
	background: color-mix(in srgb, var(--violet) 92%, transparent);
}
.game-card__tracked--dropped {
	background: rgba(249, 115, 22, 0.92);
}

@media (prefers-reduced-motion: reduce) {
	.game-card__track-btn,
	.game-card__track-btn:hover {
		transition: none;
		transform: none;
	}
}

/* ==========================================================================
   Trackable row (one-click "Want to Play" on list rows)
   ponytail: trackable wrapper positions a tracked-state slot at the right
   edge of the row, vertically centered. The row's own <a> stays clickable
   in the area not covered by the slot.
   ========================================================================== */

.game-row-trackable {
	position: relative;
	display: flex;
	flex-direction: column;
}

.game-row-trackable > .game-row {
	flex: 1;
}

.game-row__track-slot {
	position: absolute;
	top: 80%;
	right: var(--s-1);
	transform: translateY(-50%);
	z-index: 3;
	pointer-events: none;
}

.game-row__track-slot > * {
	pointer-events: auto;
}

/* ponytail: row track button — smaller than card button to fit row height */
.game-row__track-slot .game-card__track-btn {
	height: 26px;
	padding: 0 10px;
	font-size: 11px;
}

.game-row__track-slot .game-card__tracked {
	height: 22px;
	padding: 0 10px;
	font-size: 10px;
}

@media (prefers-reduced-motion: reduce) {
	.game-row__track-slot .game-card__track-btn,
	.game-row__track-slot .game-card__track-btn:hover {
		transition: none;
		transform: none;
	}
}

.game-card-rank {
	position: absolute;
	top: -8px;
	left: -8px;
	z-index: 10;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 36px;
	height: 36px;
	background: var(--aurora-warm);
	color: white;
	font-weight: 800;
	font-size: var(--text-sm);
	border-radius: 50%;
	box-shadow:
		0 4px 16px rgba(252, 165, 165, 0.4),
		inset 0 1px 0 rgba(255, 255, 255, 0.3);
}

.game-card-content {
	display: flex;
	flex-direction: column;
	gap: var(--s-2);
	flex: 1;
	min-width: 0;
	overflow: hidden;
}

.game-card-title-wrapper {
	display: flex;
	align-items: center;
	gap: var(--s-2);
	min-width: 0;
}

.game-card-title {
	flex: 1;
	min-width: 0;
	font-size: var(--text-md);
	font-weight: 600;
	color: var(--text);
	margin: 0;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
	line-height: var(--leading-snug);
}

.game-card-title a {
	color: var(--text);
	text-decoration: none;
}

/* Stretch the title link to cover the whole card, making the entire card clickable */
.game-card-title a::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 1;
}

.game-card {
	cursor: pointer;
}

.game-card-title a:hover {
	color: white;
	text-decoration: none;
}

.game-card-title a:focus-visible {
	outline: 2px solid var(--border-accent);
	outline-offset: 2px;
	border-radius: 4px;
}

.game-card-badge {
	flex-shrink: 0;
}

.game-card-meta {
	display: flex;
	flex-direction: column;
	gap: 4px;
	margin-top: auto;
	font-size: var(--text-sm);
	min-width: 0;
	overflow: hidden;
}

.game-card-rating {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	align-self: flex-start;
	max-width: 100%;
	padding: 3px 8px;
	font-size: var(--text-xs);
	font-weight: 700;
	letter-spacing: -0.01em;
	color: var(--score-pos);
	background: rgba(34, 197, 94, 0.12);
	border: 1px solid rgba(34, 197, 94, 0.28);
	border-radius: var(--r-sm);
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
	line-height: 1.3;
}

.game-card-rating::before {
	content: "";
	width: 6px;
	height: 6px;
	border-radius: 50%;
	background: currentColor;
	flex-shrink: 0;
	box-shadow: 0 0 6px currentColor;
}

.game-card-rating.score--positive {
	color: var(--score-pos);
	background: rgba(34, 197, 94, 0.12);
	border-color: rgba(34, 197, 94, 0.28);
}
.game-card-rating.score--mixed {
	color: var(--score-mixed);
	background: var(--warning-soft);
	border-color: var(--warning-border);
}
.game-card-rating.score--negative {
	color: var(--score-neg);
	background: rgba(248, 113, 113, 0.12);
	border-color: rgba(248, 113, 113, 0.28);
}

.game-card-reviews {
	color: var(--text-3);
	font-size: var(--text-xs);
	font-weight: 500;
}

.game-card-trending {
	color: var(--cyan);
	font-weight: 600;
	font-size: var(--text-sm);
	display: inline-flex;
	align-items: center;
	gap: 6px;
}

.game-card-trending::before {
	content: "↑";
	font-size: var(--text-md);
}

.game-card-release-date {
	color: var(--text-3);
	font-size: var(--text-xs);
	font-weight: 500;
}

.game-card-price {
	color: var(--score-pos);
	font-weight: 700;
	font-size: var(--text-md);
}

.game-card-original-price {
	color: var(--text-3);
	font-size: var(--text-xs);
	text-decoration: line-through;
	margin-right: var(--s-1);
}

.game-card-price-row {
	display: flex;
	align-items: center;
	gap: var(--s-2);
	margin-top: var(--s-2);
	flex-wrap: wrap;
}

.game-card-price.price-free {
	color: var(--success);
}

.game-card-discount {
	background: var(--aurora-warm);
	color: white;
	font-size: 10px;
	font-weight: 800;
	padding: 2px 6px;
	border-radius: 4px;
	letter-spacing: 0.02em;
}

.game-card-trackers {
	color: var(--cyan);
	font-weight: 600;
	font-size: var(--text-sm);
}

.game-card-players {
	color: var(--pink);
	font-weight: 600;
	font-size: var(--text-sm);
}

.game-card-desc {
	color: var(--text-2);
	font-size: var(--text-sm);
	line-height: var(--leading-snug);
	margin: 0;
	display: -webkit-box;
	-webkit-line-clamp: 3;
	-webkit-box-orient: vertical;
	overflow: hidden;
}

/* Game card label/value (used on app show price section) */
.game-card__label {
	color: var(--text-3);
	font-size: var(--text-xs);
	text-transform: uppercase;
	letter-spacing: var(--tracking-wide);
	font-weight: 600;
}

.game-card__value {
	font-size: var(--text-xl);
	font-weight: 700;
	margin-top: var(--s-1);
	font-variant-numeric: tabular-nums;
	color: var(--text);
}

/* ==========================================================================
   Game list (rows)
   ========================================================================== */

.game-list {
	display: flex;
	flex-direction: column;
	gap: var(--s-2);
}

.game-row {
	position: relative;
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--s-2) var(--s-3);
	padding: var(--s-2) var(--s-3);
	border-radius: var(--r-md);
	background: var(--surface-2);
	min-height: 72px;
	overflow: hidden;
	isolation: isolate;
	box-shadow: inset 0 0 0 1px transparent;
	transition: box-shadow var(--dur-fast) var(--ease);
	text-decoration: none;
	color: inherit;
}

.game-row:focus-visible {
	outline: 2px solid var(--border-accent);
	outline-offset: 2px;
	border-radius: var(--r-md);
}

.game-row + .game-row {
	margin-top: var(--s-2);
}

.game-row::before {
	content: "";
	position: absolute;
	inset: -1px;
	background-image: var(--game-image, none);
	background-size: cover;
	background-position: center;
	transition: transform var(--dur-slow) var(--ease);
	z-index: -2;
}

.game-row::after {
	content: "";
	position: absolute;
	inset: -1px;
	background: linear-gradient(
		to right,
		rgba(7, 9, 15, 1) 0%,
		rgba(7, 9, 15, 0.9) 30%,
		rgba(7, 9, 15, 0.35) 65%,
		transparent 100%
	);
	z-index: -1;
	pointer-events: none;
}

.game-row:hover {
	box-shadow: inset 0 0 0 1px var(--border-strong);
}

.game-row:hover::before {
	transform: scale(1.04);
}

.game-row-ranked {
	padding-left: 4px;
}

.game-row-rank {
	min-width: 36px;
	font-weight: 700;
	font-size: var(--text-sm);
	color: rgba(255, 255, 255, 0.75);
	text-align: center;
	font-variant-numeric: tabular-nums;
}

.game-row-rank.rank-top-1 {
	color: #fbbf24;
	font-size: var(--text-md);
}
.game-row-rank.rank-top-2 {
	color: #e5e7eb;
	font-size: var(--text-md);
}
.game-row-rank.rank-top-3 {
	color: #fb923c;
	font-size: var(--text-md);
}

.game-row-loading {
	opacity: 0.6;
}

.game-row-loading::before {
	background: linear-gradient(
		90deg,
		rgba(255, 255, 255, 0.04) 25%,
		rgba(255, 255, 255, 0.1) 50%,
		rgba(255, 255, 255, 0.04) 75%
	);
	background-size: 200% 100%;
	animation: shimmer 1.5s infinite;
}

.game-row-loading .loading-text {
	display: block;
	height: 14px;
	width: 120px;
	background: linear-gradient(
		90deg,
		rgba(255, 255, 255, 0.04) 25%,
		rgba(255, 255, 255, 0.1) 50%,
		rgba(255, 255, 255, 0.04) 75%
	);
	background-size: 200% 100%;
	animation: shimmer 1.5s infinite;
	border-radius: var(--r-sm);
}

@media (prefers-reduced-motion: reduce) {
	.game-row-loading::before,
	.game-row-loading .loading-text {
		animation: none;
		background: rgba(255, 255, 255, 0.06);
	}
}

.game-row-title-wrapper {
	display: flex;
	align-items: center;
	gap: var(--s-2);
	min-width: 0;
	flex: 1;
	overflow: hidden;
}

.game-row-title {
	flex: 1;
	min-width: 0;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
	color: white;
	text-decoration: none;
	font-size: var(--text-sm);
	font-weight: 600;
	text-shadow: 0 1px 2px rgba(0, 0, 0, 0.4);
	transition: color var(--dur-fast) var(--ease);
}

.game-row-meta {
	display: flex;
	align-items: center;
	gap: var(--s-2);
	flex-wrap: wrap;
	min-width: 0;
	font-variant-numeric: tabular-nums;
	flex-basis: 100%;
	margin-top: var(--s-1);
}

.game-row-score {
	display: inline-flex;
	align-items: center;
	gap: var(--s-2);
	padding: 2px 6px;
	font-size: 11px;
	font-weight: 700;
	letter-spacing: -0.01em;
	color: var(--score-pos);
	background: rgba(34, 197, 94, 0.1);
	border: 1px solid rgba(34, 197, 94, 0.24);
	border-radius: var(--r-sm);
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
	min-width: 0;
	max-width: 100%;
	flex-shrink: 1;
}

.game-row-score.score--positive {
	color: var(--score-pos);
	background: rgba(34, 197, 94, 0.1);
	border-color: rgba(34, 197, 94, 0.24);
}
.game-row-score.score--mixed {
	color: var(--score-mixed);
	background: color-mix(in srgb, var(--warning) 10%, transparent);
	border-color: color-mix(in srgb, var(--warning) 24%, transparent);
}
.game-row-score.score--negative {
	color: var(--score-neg);
	background: rgba(248, 113, 113, 0.1);
	border-color: rgba(248, 113, 113, 0.24);
}

.game-row-reviews {
	color: rgba(255, 255, 255, 0.7);
	font-size: var(--text-xs);
	white-space: nowrap;
	margin-left: var(--s-2);
	width: 100%;
}

.game-row-trending {
	color: var(--cyan);
	font-weight: 600;
	font-size: var(--text-xs);
}

.game-row-date {
	color: rgba(255, 255, 255, 0.7);
	font-size: var(--text-xs);
}

.game-row-price {
	font-weight: 700;
	font-size: var(--text-xs);
	color: var(--score-pos);
}

.game-row-price.price-free {
	color: var(--success);
}

.game-row-original-price {
	color: rgba(255, 255, 255, 0.55);
	font-size: var(--text-xs);
	text-decoration: line-through;
}

.game-row-discount {
	background: var(--aurora-warm);
	color: white;
	font-size: 10px;
	font-weight: 800;
	padding: 2px 6px;
	border-radius: 4px;
	letter-spacing: 0.02em;
}

.game-row-trackers {
	color: var(--cyan);
	font-weight: 600;
	font-size: var(--text-xs);
}

.game-row-players {
	color: var(--pink);
	font-weight: 600;
	font-size: var(--text-xs);
}

.game-row-status {
	display: inline-flex;
	align-items: center;
	padding: 2px 8px;
	font-size: 10px;
	font-weight: 700;
	border-radius: var(--r-full);
	text-transform: uppercase;
	letter-spacing: 0.04em;
	margin-left: var(--s-2);
	flex-shrink: 0;
}

.game-row-status.badge-want {
	color: #fca5a5;
	background: rgba(248, 113, 113, 0.18);
}

.game-row-status.badge-playing {
	color: #6ee7b7;
	background: rgba(16, 185, 129, 0.18);
}

.game-row-status.badge-played {
	color: #fecaca;
	background: var(--border-accent-soft);
}

.game-row-status.badge-dropped {
	color: #fdba74;
	background: rgba(249, 115, 22, 0.18);
}

/* Mobile row */
@media (max-width: 768px) {
	.game-row {
		gap: var(--s-2);
		padding: var(--s-2);
		min-height: 64px;
	}
	.game-row-rank {
		min-width: 24px;
		font-size: var(--text-xs);
	}
	.game-row-rank.rank-top-1,
	.game-row-rank.rank-top-2,
	.game-row-rank.rank-top-3 {
		font-size: var(--text-sm);
	}
	.game-row-meta {
		gap: var(--s-2);
	}
}

/* ==========================================================================
   Game rail card (used by trending rail and similar games)
   ========================================================================== */

.game-rail-card {
	display: block;
	text-decoration: none;
	color: inherit;
	border-radius: var(--r-md);
	background: var(--surface-1);
	border: 1px solid var(--border);
	overflow: hidden;
	transition:
		transform var(--dur) var(--ease),
		border-color var(--dur) var(--ease),
		box-shadow var(--dur) var(--ease);
	box-shadow: var(--inner-hi);
}

.game-rail-card:hover {
	transform: translateY(-3px);
	border-color: var(--border-strong);
	box-shadow:
		var(--inner-hi),
		var(--shadow-lg),
		0 0 24px color-mix(in srgb, var(--violet) 15%, transparent);
	text-decoration: none;
	color: inherit;
}

.game-rail-card:focus-visible {
	outline: none;
	border-color: var(--border-accent);
	box-shadow: 0 0 0 3px color-mix(in srgb, var(--violet) 25%, transparent);
}

.game-rail-card__image-wrapper {
	position: relative;
	aspect-ratio: 460 / 215;
	overflow: hidden;
	background: var(--surface-2);
}

.game-rail-card__image {
	width: 100%;
	height: 100%;
	object-fit: cover;
	transition: transform var(--dur-slow) var(--ease);
}

.game-rail-card:hover .game-rail-card__image {
	transform: scale(1.05);
}

.game-rail-card__image-placeholder {
	width: 100%;
	height: 100%;
	background: linear-gradient(
		135deg,
		var(--surface-1) 0%,
		var(--surface-2) 50%,
		var(--surface-1) 100%
	);
	background-size: 200% 200%;
	animation: shimmer 2s var(--ease) infinite;
}

.game-rail-card__badge {
	position: absolute;
	top: var(--s-2);
	right: var(--s-2);
	padding: 3px 8px;
	border-radius: var(--r-sm);
	font-size: 10px;
	font-weight: 800;
	z-index: 1;
	text-transform: uppercase;
	letter-spacing: 0.04em;
}

.game-rail-card__badge--discount {
	color: white;
	background: var(--aurora-warm);
}

.game-rail-card__badge--free {
	color: white;
	background: linear-gradient(135deg, #22c55e, #16a34a);
}

.game-rail-card__content {
	padding: var(--s-3);
	display: flex;
	flex-direction: column;
	gap: 6px;
}

.game-rail-card__title {
	margin: 0;
	font-size: var(--text-sm);
	font-weight: 600;
	color: var(--text);
	line-height: var(--leading-snug);
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
}

.game-rail-card__meta {
	display: flex;
	align-items: center;
	gap: var(--s-2);
	font-size: var(--text-xs);
	color: var(--text-3);
}

.game-rail-card__score {
	font-size: var(--text-xs);
	font-weight: 700;
	font-variant-numeric: tabular-nums;
}

.game-rail-card__score.score-positive {
	color: var(--score-pos);
}
.game-rail-card__score.score-mixed {
	color: var(--score-mixed);
}
.game-rail-card__score.score-negative {
	color: var(--score-neg);
}

.game-rail-card__genre {
	font-size: 11px;
	color: var(--text-3);
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.game-rail-card__footer {
	display: flex;
	align-items: center;
	gap: var(--s-2);
	margin-top: 2px;
}

.game-rail-card__price {
	font-size: var(--text-sm);
	font-weight: 700;
	color: var(--text);
	font-variant-numeric: tabular-nums;
}

.game-rail-card__price--sale {
	color: var(--score-pos);
}
.game-rail-card__price--free {
	color: var(--success);
}

.game-rail-card__original-price {
	font-size: 11px;
	color: var(--text-3);
	text-decoration: line-through;
}

/* ==========================================================================
   App show page (game detail)
   ========================================================================== */

.game-page {
	max-width: 1200px;
	margin: 0 auto;
	padding: var(--s-4) var(--s-6) var(--s-10);
}

.game-page__hero {
	position: relative;
	min-height: 360px;
	border-radius: var(--r-2xl);
	overflow: hidden;
	margin-bottom: var(--s-7);
	background: var(--surface-1);
	border: 1px solid var(--border);
	box-shadow: var(--shadow);
}

.game-page__hero-image {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	opacity: 0.6;
	z-index: 0;
}

.game-page__hero-image--placeholder {
	background: var(--aurora);
	opacity: 0.4;
}

.game-page__hero-overlay {
	position: absolute;
	inset: 0;
	background:
		linear-gradient(
			180deg,
			rgba(7, 9, 15, 0.4) 0%,
			rgba(7, 9, 15, 0.85) 60%,
			rgba(7, 9, 15, 0.98) 100%
		),
		radial-gradient(
			ellipse at top right,
			color-mix(in srgb, var(--violet) 25%, transparent),
			transparent 60%
		);
	z-index: 1;
}

.game-page__hero-inner {
	position: relative;
	z-index: 2;
	padding: var(--s-8) var(--s-7);
	display: flex;
	flex-direction: column;
	gap: var(--s-3);
	min-height: 360px;
	justify-content: flex-end;
}

.game-title {
	font-family: var(--font-display);
	margin: 0;
	font-size: var(--text-5xl);
	font-weight: 800;
	letter-spacing: -0.03em;
	line-height: var(--leading-tight);
	color: white;
	text-shadow: 0 4px 24px rgba(0, 0, 0, 0.5);
}

.game-page__hero-actions {
	display: flex;
	align-items: center;
	gap: var(--s-3);
	flex-wrap: wrap;
	margin-top: var(--s-2);
}

.game-page__hero-badges {
	display: flex;
	align-items: center;
	gap: var(--s-2);
	flex-wrap: wrap;
}

.game-page__layout {
	display: grid;
	grid-template-columns: minmax(0, 1fr) 320px;
	gap: var(--s-7);
}

@media (max-width: 900px) {
	.game-page__layout {
		grid-template-columns: 1fr;
	}
}

.game-page__main {
	min-width: 0;
}

.game-page__sidebar {
	display: flex;
	flex-direction: column;
	gap: var(--s-5);
	position: sticky;
	top: calc(var(--nav-h) + var(--s-4));
	align-self: start;
	min-width: 0;
}

@media (max-width: 900px) {
	.game-page__sidebar {
		position: static;
		max-height: none;
	}
}

.game-short-description {
	margin: var(--s-4) 0 0;
	color: var(--text-2);
	font-size: var(--text-md);
	line-height: var(--leading-relaxed);
	max-width: 70ch;
}

.game-short-description a {
	color: var(--pink);
}

/* Header (legacy, kept for compatibility) */
.game-header {
	display: grid;
	grid-template-columns: 1fr 320px;
	gap: var(--s-6);
	align-items: start;
}

@media (max-width: 900px) {
	.game-header {
		grid-template-columns: 1fr;
	}
}

.game-header__image {
	width: 100%;
	border-radius: var(--r-md);
	display: block;
	background: var(--surface-1);
	border: 1px solid var(--border);
}

/* Game meta (key-value list) */
.game-meta {
	margin-top: var(--s-4);
	border: 1px solid var(--border);
	border-radius: var(--r-lg);
	background: var(--surface-1);
	padding: var(--s-2);
	box-shadow: var(--inner-hi);
}

.game-meta__row {
	display: grid;
	grid-template-columns: 130px 1fr;
	gap: var(--s-3);
	padding: var(--s-3);
	border-bottom: 1px solid var(--border);
	font-size: var(--text-sm);
}

.game-meta__row:last-child {
	border-bottom: 0;
}

.game-meta__label {
	color: var(--text-3);
	font-size: var(--text-xs);
	text-transform: uppercase;
	letter-spacing: var(--tracking-wide);
	font-weight: 600;
	align-self: center;
}

.game-meta__value {
	color: var(--text);
	font-size: var(--text-sm);
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 6px;
	min-width: 0;
	overflow-wrap: anywhere;
}

.game-meta__more {
	color: var(--text-3);
	font-size: var(--text-xs);
	font-weight: 500;
}

/* Game section (sub-section on show page) */
.game-section {
	margin-top: var(--s-7);
	padding-top: var(--s-7);
	border-top: 1px solid var(--border);
}

.game-section:first-of-type {
	border-top: 0;
	padding-top: 0;
	margin-top: 0;
}

.game-section__title {
	font-family: var(--font-display);
	margin: 0 0 var(--s-4);
	font-size: var(--text-xl);
	font-weight: 600;
	color: var(--text);
	letter-spacing: -0.01em;
	display: flex;
	align-items: center;
	gap: var(--s-2);
}

.game-section__title::before {
	content: "";
	width: 4px;
	height: 18px;
	background: var(--aurora);
	border-radius: var(--r-full);
}

/* Pills (platforms, genres)
   ponytail: .pill and .pill--* modifiers live in design-system.css. This file
   only owns the .pill-row layout container for pill grids. */
.pill-row {
	display: flex;
	flex-wrap: wrap;
	gap: var(--s-2);
}

.pill--platform {
	color: var(--cyan);
	border-color: rgba(127, 29, 29, 0.3);
	background: rgba(127, 29, 29, 0.1);
}

.pill--platform:hover {
	color: #fca5a5;
}

/* ponytail: section-shaped skeleton placeholder for lazy turbo frames.
   Matches the eventual section's rhythm (title + body rows) so the page
   doesn't jump when the frame resolves. */
.game-section-skeleton {
	display: flex;
	flex-direction: column;
	gap: var(--s-2);
	padding-top: var(--s-2);
}

.game-section-skeleton__title {
	height: 22px;
	width: 40%;
	border-radius: var(--r-sm);
}

.game-section-skeleton__row {
	border-radius: var(--r-sm);
}

/* Compact list (categories) */
.compact-list {
	margin: 0;
	padding-left: var(--s-5);
	color: var(--text-2);
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
	gap: var(--s-1) var(--s-4);
}

.compact-list li {
	font-size: var(--text-sm);
	line-height: var(--leading-relaxed);
}

/* Prose */
/* The reading measure, as a length rather than a `ch` unit.

   `ch` is the width of "0" in the *element's own* font, so the same 75ch means
   different widths on different elements: about 590px on the prose body at
   --text-sm, but about 760px on an <h2>, which uses --font-display at
   --text-xl. Steam writes whole paragraphs as headings, so the measure quietly
   dissolved on exactly the paragraphs that were longest. 37rem is the same
   measure the prose already had, stated once so it holds at any font size. */
.prose {
	--prose-measure: 37rem;
	border: 1px solid var(--border);
	border-radius: var(--r-lg);
	background: var(--surface-1);
	padding: var(--s-5);
	color: var(--text-2);
	line-height: var(--leading-relaxed);
	font-size: var(--text-sm);
	max-width: var(--prose-measure);
}

/* The About box fills its column instead of stopping at the reading measure.

   `max-width: 75ch` on .prose is a *text* constraint -- it keeps the language
   list and the system requirements from running to 100 characters a line. It
   was never about the box, and once the About section carries full-width
   illustrations and video it stops being one: capping the box capped the media
   too, leaving roughly 200px of dead space down the right of a 1200px page.

   So the box fills, and the measure moves inside it -- prose stays readable,
   media spans the full column. */
.prose.about-prose {
	max-width: none;
}

/* Descendant, not child: Steam nests its prose inside wrapper divs of its own,
   so a `> p` selector only reaches the paragraphs that happen to sit directly
   in the box and lets the rest run to the full column width. Media is
   unaffected -- none of these elements can contain a figure, an image or a
   video. */
.about-prose p,
.about-prose h1,
.about-prose h2,
.about-prose h3,
.about-prose ul,
.about-prose ol,
.about-prose blockquote {
	max-width: var(--prose-measure);
}

.prose a {
	color: var(--pink);
}

.prose h1,
.prose h2,
.prose h3 {
	color: var(--text);
	font-family: var(--font-display);
	margin: var(--s-5) 0 var(--s-3);
}

.prose h1 {
	font-size: var(--text-2xl);
}
.prose h2 {
	font-size: var(--text-xl);
}
.prose h3 {
	font-size: var(--text-lg);
}

.prose p {
	margin: 0 0 var(--s-3);
}
.prose p:last-child {
	margin-bottom: 0;
}

.prose ul,
.prose ol {
	margin: 0 0 var(--s-3);
	padding-left: var(--s-5);
}
.prose li {
	margin-bottom: var(--s-1);
}

.prose strong {
	color: var(--text);
	font-weight: 600;
}
.prose em {
	color: var(--text);
	font-style: italic;
}

/* Media inside the About section.

   Description media is inline in the prose, in the position Steam gave it, not
   a card grid beside or below it -- a description image has a place in the
   text, so it renders like one. The figure exists only to carry the block
   spacing; the image inside it fills the prose column the way the store page
   does.

   Selected by element rather than by class: the renderer emits no classes at
   all, so that the sanitizer can strip every class in the description as a
   matter of course. See DescriptionRenderer::ALLOWED_ATTRIBUTES. */
.about-prose figure {
	margin: var(--s-4) 0;
}

.about-prose figure img {
	display: block;
	width: 100%;
	height: auto;
	border-radius: var(--r-md);
	background: var(--surface-1);
}

/* Video takes the same treatment as an image: fill the column, keep the
   source aspect ratio.

   An earlier version capped these at `max-height: 70vh` with
   `object-fit: contain`, to stop a very tall asset from dominating the page.
   That is backwards for this content. 56 of 59 description videos are wide and
   never came near the cap, and the one tall outlier -- a 1170x6424 artbook
   reel -- is exactly the case it broke: the cap letterboxed a 5:1 video into a
   70vh-tall window, shrinking it to a narrow unreadable strip floating in a
   wide empty box. The store page simply renders it at full column width and
   lets it be tall, and so does this. */
.about-prose figure video {
	display: block;
	width: 100%;
	height: auto;
	background: var(--surface-1);
	border-radius: var(--r-md);
}

/* Screenshots */
.screenshot-grid {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: var(--s-3);
}

@media (max-width: 900px) {
	.screenshot-grid {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

.screenshot {
	display: block;
	border-radius: var(--r-md);
	overflow: hidden;
	border: 1px solid var(--border);
	background: var(--surface-1);
	position: relative;
	transition:
		transform var(--dur) var(--ease),
		border-color var(--dur) var(--ease),
		box-shadow var(--dur) var(--ease);
}

.screenshot:hover {
	transform: translateY(-2px);
	border-color: var(--border-strong);
	box-shadow: var(--shadow);
}

.screenshot img {
	display: block;
	width: 100%;
	height: auto;
	transition: transform var(--dur-slow) var(--ease);
}

.screenshot:hover img {
	transform: scale(1.04);
}

/* Gallery viewer — the native <dialog> that shows a screenshot full size */
.gallery {
	position: fixed;
	inset: 0;
	width: 100%;
	height: 100dvh;
	max-width: 100%;
	max-height: 100dvh;
	margin: 0;
	padding: 0;
	border: 0;
	background: transparent;
	color: var(--text);
}

/* ponytail: `display` MUST be scoped to [open]. The UA sheet hides a closed
   <dialog> via `dialog:not([open]) { display: none }`, and any author-level
   display beats it — an unscoped `display: flex` would leave the closed
   viewer painted over the page. */
.gallery[open] {
	display: flex;
	align-items: center;
	justify-content: center;
	padding: var(--s-8) var(--s-12);
}

.gallery::backdrop {
	background: rgba(7, 9, 15, 0.92);
	-webkit-backdrop-filter: blur(4px);
	backdrop-filter: blur(4px);
}

.gallery__image {
	max-width: 100%;
	max-height: 100%;
	object-fit: contain;
	border-radius: var(--r-md);
	box-shadow: var(--shadow-lg);
}

.gallery__nav,
.gallery__close {
	position: absolute;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 44px;
	height: 44px;
	padding: 0;
	border-radius: var(--r-full);
	border: 1px solid var(--border-strong);
	background: var(--surface-2);
	-webkit-backdrop-filter: var(--glass-blur);
	backdrop-filter: var(--glass-blur);
	box-shadow: var(--inner-hi);
	color: var(--text);
	font-size: var(--text-xl);
	line-height: 1;
	cursor: pointer;
	transition:
		background var(--dur) var(--ease),
		transform var(--dur) var(--ease);
}

.gallery__nav:hover,
.gallery__close:hover {
	background: var(--surface-3);
	transform: translateY(-2px);
}

.gallery__close {
	top: var(--s-4);
	right: var(--s-4);
}

.gallery__nav {
	top: 50%;
	margin-top: -22px;
}

.gallery__nav--prev {
	left: var(--s-4);
}

.gallery__nav--next {
	right: var(--s-4);
}

.gallery__counter {
	position: absolute;
	bottom: var(--s-4);
	left: 50%;
	transform: translateX(-50%);
	padding: var(--s-1) var(--s-3);
	border-radius: var(--r-full);
	border: 1px solid var(--border);
	background: var(--surface-2);
	-webkit-backdrop-filter: var(--glass-blur);
	backdrop-filter: var(--glass-blur);
	color: var(--text-2);
	font-size: var(--text-sm);
	font-variant-numeric: tabular-nums;
}

@media (max-width: 640px) {
	.gallery[open] {
		padding: var(--s-10) var(--s-2);
	}

	.gallery__nav {
		width: 36px;
		height: 36px;
		margin-top: -18px;
	}
}

/* Trailers */
.trailer-grid {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: var(--s-4);
}

@media (max-width: 640px) {
	.trailer-grid {
		grid-template-columns: 1fr;
	}
}

.trailer {
	width: 100%;
	border-radius: var(--r-md);
	border: 1px solid var(--border);
	background: var(--surface-1);
	box-shadow: var(--inner-hi);
}

/* Star rating */
.star-rating {
	display: inline-flex;
	align-items: center;
	gap: 2px;
}

.star-rating .star {
	cursor: pointer;
	transition: transform var(--dur-fast) var(--ease);
}

.star-rating .star:hover {
	transform: scale(1.15);
}

.star-rating-container {
	display: inline-flex;
	align-items: center;
	gap: var(--s-2);
}

.stars {
	display: flex;
	gap: 2px;
	align-items: center;
}

/* Price display */
.price {
	font-weight: 700;
	font-size: var(--text-md);
	color: var(--text);
	font-variant-numeric: tabular-nums;
}

.price--sale {
	color: var(--score-pos);
}
.price--free {
	color: var(--success);
}

.original-price {
	font-size: var(--text-xs);
	color: var(--text-3);
	text-decoration: line-through;
	margin-right: var(--s-1);
}

.discount {
	display: inline-flex;
	align-items: center;
	background: var(--aurora-warm);
	color: white;
	font-size: 11px;
	font-weight: 800;
	padding: 2px 8px;
	border-radius: var(--r-sm);
	letter-spacing: 0.02em;
}

/* Patch notice (used by apps#show, also see patches.css) */
.patch-notice {
	display: flex;
	gap: var(--s-4);
	padding: var(--s-5);
	background: color-mix(in srgb, var(--warning) 8%, transparent);
	border: 1px solid var(--warning-border);
	border-radius: var(--r-lg);
	position: relative;
	overflow: hidden;
}

.patch-notice::before {
	content: "";
	position: absolute;
	inset: 0;
	background: linear-gradient(
		135deg,
		color-mix(in srgb, var(--warning) 6%, transparent),
		transparent 60%
	);
	pointer-events: none;
}

.patch-notice__icon {
	font-size: var(--text-2xl);
	flex-shrink: 0;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 48px;
	height: 48px;
	background: var(--warning-soft);
	border: 1px solid var(--warning-border);
	border-radius: var(--r-md);
}

.patch-notice__content {
	flex: 1;
	position: relative;
	z-index: 1;
}

.patch-notice__title {
	margin: 0 0 var(--s-2);
	font-size: var(--text-md);
	font-weight: 600;
	color: var(--warning-text);
}

.patch-notice__content p {
	margin: 0 0 var(--s-3);
	color: var(--text-2);
	font-size: var(--text-sm);
	line-height: var(--leading-relaxed);
}

.patch-notice__links {
	display: flex;
	gap: var(--s-2);
	flex-wrap: wrap;
}

/* Slop notice (apps#show). Mirrors the patch-notice shape so the two
   "know this before you buy" blocks read as siblings, but tinted neutral
   instead of amber — the amber surface is reserved for patch problems. */
.slop-notice {
	display: flex;
	gap: var(--s-4);
	padding: var(--s-5);
	background: var(--surface-2);
	border: 1px dashed var(--border-strong);
	border-radius: var(--r-lg);
}

.slop-notice__icon {
	font-size: var(--text-2xl);
	flex-shrink: 0;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 48px;
	height: 48px;
	background: var(--surface-3);
	border: 1px dashed var(--border-strong);
	border-radius: var(--r-md);
}

.slop-notice__content {
	flex: 1;
	min-width: 0;
}

.slop-notice__title {
	margin: 0 0 var(--s-2);
	font-size: var(--text-md);
	font-weight: 600;
	color: var(--text);
}

.slop-notice__content p {
	margin: 0;
	color: var(--text-2);
	font-size: var(--text-sm);
	line-height: var(--leading-relaxed);
}

/* ==========================================================================
   Index page wrappers (developers, publishers, top_by_tag)
   ========================================================================== */

.developers-page,
.publishers-page,
.top-by-tag-section {
	max-width: 1100px;
	margin: 0 auto;
	padding: var(--s-4) var(--s-6) var(--s-10);
}

.tag-games {
	/* Markup-only hook on top of .game-grid; reserved for future
	   tag-specific layout overrides (e.g. tag-filter styling). */
}

/* ==========================================================================
   Game row badges (shared/games partials)
   ========================================================================== */

.game-row-badge {
	display: inline-flex;
	align-items: center;
	flex-shrink: 0;
}

/* ==========================================================================
   App show sidebar (restructured)

   Seven visual blocks instead of ten flat sections:
   1. .sidebar-group--glance   (no header, implicit top)
   2. .sidebar-group--themes   (Genres + Categories + Kinks)
   3. .sidebar-group           (Details: existing meta panel)
   4. .sidebar-group--alert    (AI-slop notice, when flagged)
   5. .sidebar-group--alert    (Patch required, no header)
   6. .sidebar-group           (More like this: similar + DLC)
   7. .sidebar-group--muted    (Admin: slop toggle)

   Only top-level group titles carry the aurora accent bar. Sub-items
   inside a group have no header — proximity + surface change signals
   grouping. This kills the aurora-bar repetition the critique flagged.

   Reduced-motion: no transitions on this surface (sidebar is static).
   ========================================================================== */

.sidebar-group {
	display: flex;
	flex-direction: column;
	gap: var(--s-3);
	min-width: 0;
}

.sidebar-group + .sidebar-group {
	margin-top: var(--s-6);
}

.sidebar-group__title {
	font-family: var(--font-sans);
	margin: 0;
	font-size: 11px;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: var(--tracking-wide);
	color: var(--text-3);
	display: flex;
	align-items: center;
	gap: var(--s-2);
}

.sidebar-group__title::before {
	content: "";
	width: 3px;
	height: 12px;
	background: var(--aurora);
	border-radius: var(--r-full);
	flex-shrink: 0;
}

.sidebar-group__count {
	margin-left: auto;
	color: var(--text-3);
	font-weight: 600;
	font-variant-numeric: tabular-nums;
	opacity: 0.7;
}

/* At-a-glance card — top-of-sidebar, no header */
.sidebar-group--glance {
	padding: var(--s-3);
	background: var(--surface-1);
	border: 1px solid var(--border);
	border-radius: var(--r-lg);
	box-shadow: var(--inner-hi);
}

.sidebar-group--glance .pill-row {
	gap: 6px;
}

.sidebar-group--glance .pill {
	font-size: 10px;
	height: 22px;
	padding: 0 10px;
}

/* Alert (patch) — colored border, no header */
.sidebar-group--alert {
	margin-top: var(--s-5);
}

/* Muted (admin) — last, less visual weight */
.sidebar-group--muted {
	opacity: 0.85;
}

.sidebar-group--muted .sidebar-group__title {
	color: var(--text-3);
	opacity: 0.7;
}

.sidebar-group--muted .sidebar-group__title::before {
	background: var(--border-strong);
}

/* Compact meta panel for the narrower sidebar (320px).
   130px label column was eating 40% of sidebar width; tightened to 92px. */
.game-meta--compact {
	margin-top: 0;
	padding: 0;
	background: transparent;
	border: 0;
	box-shadow: none;
}

.game-meta--compact .game-meta__row {
	grid-template-columns: 92px 1fr;
	padding: var(--s-2) 0;
	gap: var(--s-2);
	font-size: var(--text-sm);
}

.game-meta--compact .game-meta__label {
	font-size: 10px;
}

/* Price line (single fact, not 3 cards) */
.price-line {
	display: flex;
	align-items: baseline;
	gap: var(--s-2);
	font-family: var(--font-sans);
}

.price-line__current {
	font-size: var(--text-lg);
	font-weight: 700;
	color: var(--text);
	font-variant-numeric: tabular-nums;
}

.price-line__current--free {
	color: var(--success);
}

.price-line__current--sale {
	color: var(--score-pos);
}

.price-line__original {
	font-size: var(--text-xs);
	color: var(--text-3);
	text-decoration: line-through;
	font-variant-numeric: tabular-nums;
}

.price-line__discount {
	font-size: 11px;
	font-weight: 800;
	letter-spacing: 0.02em;
	color: white;
	background: var(--aurora-warm);
	padding: 2px 6px;
	border-radius: var(--r-sm);
}

/* Inline pill rows inside a sidebar group get tighter gaps */
.sidebar-group .pill-row {
	gap: 6px;
}

.sidebar-group .pill {
	font-size: var(--text-xs);
	height: 24px;
	padding: 0 var(--s-3);
}

/* Categories list — collapsed to pills (was 200px-wide bullet grid) */
.pill-row--compact .pill {
	height: 22px;
	padding: 0 10px;
	font-size: 10px;
	font-weight: 500;
}

/* "More like this" rail */
.more-like-this {
	display: flex;
	flex-direction: column;
	gap: var(--s-3);
}

/* DLC list inside "More like this" */
.dlc-list {
	margin: 0;
	padding: 0;
	list-style: none;
	display: flex;
	flex-direction: column;
	gap: var(--s-1);
}

.dlc-list li {
	padding: 0;
}

.dlc-list a {
	display: block;
	padding: var(--s-2) var(--s-3);
	font-size: var(--text-xs);
	color: var(--text-2);
	background: var(--surface-1);
	border: 1px solid var(--border);
	border-radius: var(--r-sm);
	text-decoration: none;
	transition:
		background var(--dur-fast) var(--ease),
		border-color var(--dur-fast) var(--ease),
		color var(--dur-fast) var(--ease);
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.dlc-list a:hover {
	background: var(--surface-2);
	border-color: var(--border-strong);
	color: var(--text);
	text-decoration: none;
}

@media (prefers-reduced-motion: reduce) {
	.dlc-list a {
		transition: none;
	}
}

/* ==========================================================================
   Entity games page
   ==========================================================================

   Same fix as .tags-page: this view also wrapped itself in .home-page, the
   home page's `1fr 320px` two-column grid, with no sidebar sibling to fill
   the 320px track. Single-column container like .game-page instead. */
.entity-games-page {
	max-width: 1200px;
	margin: 0 auto;
	padding: var(--s-4) var(--s-6) var(--s-10);
}

@media (max-width: 640px) {
	.entity-games-page {
		padding: var(--s-3) var(--s-4) var(--s-9);
	}
}

/* The hint's negative top margin exists to tuck under a follow row that sat
   directly above it. Here the follow row is up in the section header, which
   brings its own margin, so the hint starts a block of its own and the
   negative margin would only eat into the gap the header already made. */
.entity-games-page .entity-follow__hint {
	margin-top: 0;
}
