/* 3D Donor Gallery — front-end styles */

.donor3d-gallery {
	--donor3d-height: 600px;
	--donor3d-accent: #2b6cb0;
	position: relative;
	/* Full-bleed: escape the theme's content column and span the viewport.
	   `100vw` counts the scrollbar, which would push the element a few pixels
	   past each edge and give some themes a horizontal scrollbar. The script
	   measures the scrollbar once and publishes it as --donor3d-sbw; until then
	   the fallback of 0 behaves like plain 100vw. */
	--donor3d-vw: calc(100vw - var(--donor3d-sbw, 0px));
	width: var(--donor3d-vw);
	max-width: var(--donor3d-vw);
	margin-left: calc(50% - var(--donor3d-vw) / 2);
	margin-right: calc(50% - var(--donor3d-vw) / 2);
	height: var(--donor3d-height);
	min-height: 320px;
	margin-top: 0;
	margin-bottom: 1.5em;
	background: #10121a;
	overflow: hidden;
	color: #fff;
	font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
	-webkit-user-select: none;
	user-select: none;
}

.donor3d-canvas-wrap {
	position: absolute;
	inset: 0;
}

.donor3d-canvas-wrap canvas {
	display: block;
	width: 100% !important;
	height: 100% !important;
	touch-action: none;
	cursor: grab;
}

.donor3d-canvas-wrap.is-looking canvas {
	cursor: grabbing;
}

.donor3d-canvas-wrap.can-click canvas {
	cursor: pointer;
}

/* Loading + status text */
.donor3d-loading {
	position: absolute;
	inset: 0;
	display: flex;
	align-items: center;
	justify-content: center;
	font-size: 15px;
	letter-spacing: .3px;
	color: #cbd5e1;
	background: #10121a;
	z-index: 5;
}

/* Bottom hint bar */
.donor3d-hint {
	position: absolute;
	left: 50%;
	bottom: 14px;
	transform: translateX(-50%);
	background: rgba(0, 0, 0, .55);
	backdrop-filter: blur(4px);
	padding: 7px 14px;
	font-size: 12.5px;
	line-height: 1;
	color: #e2e8f0;
	white-space: nowrap;
	max-width: calc(100% - 24px);
	overflow: hidden;
	text-overflow: ellipsis;
	pointer-events: none;
	z-index: 6;
	transition: opacity .4s ease;
}

/* On a phone the hint would sit on top of the joystick, and truncating it to
   one line loses the half that explains tapping. Lift it clear and let it wrap. */
@media (max-width: 720px) {
	.donor3d-hint {
		white-space: normal;
		text-align: center;
		line-height: 1.35;
		max-width: calc(100% - 28px);
	}
}

.donor3d-gallery.is-touch .donor3d-hint {
	bottom: 124px;
}

/* Start / enter overlay */
.donor3d-enter {
	position: absolute;
	inset: 0;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 14px;
	text-align: center;
	background: rgba(8, 10, 16, .72);
	backdrop-filter: blur(2px);
	z-index: 8;
	cursor: pointer;
	transition: opacity .4s ease;
}

.donor3d-enter .donor3d-enter-btn {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	padding: 12px 22px;
	background: var(--donor3d-accent);
	color: #fff;
	font-size: 15px;
	font-weight: 600;
	box-shadow: 0 8px 24px rgba(0, 0, 0, .35);
}

.donor3d-enter .donor3d-enter-sub {
	font-size: 12.5px;
	color: #cbd5e1;
	max-width: 320px;
}

.donor3d-enter.is-hidden {
	opacity: 0;
	pointer-events: none;
}

/* Detail card — a large centred panel, the way Artsteps presents an artwork.
   The artwork sits left at the same aspect as its panel on the wall, with the
   donor's name and text alongside it. */
.donor3d-card {
	position: absolute;
	left: 50%;
	top: 50%;
	transform: translate(-50%, -50%) scale(.94);
	width: min(940px, calc(100% - 48px));
	max-height: calc(100% - 48px);
	display: flex;
	flex-direction: row;
	align-items: stretch;
	overflow: hidden;
	background: #fff;
	color: #1a202c;
	box-shadow: 0 30px 90px rgba(0, 0, 0, .55);
	opacity: 0;
	pointer-events: none;
	transition: opacity .28s ease, transform .28s ease;
	z-index: 9;
}

.donor3d-card.is-open {
	opacity: 1;
	transform: translate(-50%, -50%) scale(1);
	pointer-events: auto;
}

/* Dim the room behind the open card so the artwork reads clearly. */
.donor3d-card-backdrop {
	position: absolute;
	inset: 0;
	background: rgba(8, 10, 16, .55);
	backdrop-filter: blur(2px);
	opacity: 0;
	pointer-events: none;
	transition: opacity .28s ease;
	z-index: 8;
}

.donor3d-card-backdrop.is-open {
	opacity: 1;
	pointer-events: auto;
}

.donor3d-card-logo {
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 26px;
	background: #f7fafc;
	/* Same shape as the panel this artwork hangs on in the room. The ratio is
	   set per donor from its wall size; this is the usual 1.484 x 2 canvas. */
	aspect-ratio: var(--donor3d-art-aspect, .7422);
	height: min(50vh, 380px);
	width: auto;
	flex: 0 0 auto;
	border-right: 1px solid #e7ecf1;
}

.donor3d-card-logo img {
	/* Fill the panel rather than sitting at the crop's own pixel size, which is
	   small. JS caps the enlargement per logo so nothing turns to mush. */
	width: 100%;
	height: 100%;
	object-fit: contain;
}

.donor3d-card-body {
	flex: 1 1 auto;
	min-width: 0;
	padding: 30px 34px;
	overflow-y: auto;
	display: flex;
	flex-direction: column;
	justify-content: center;
}

.donor3d-card-body h3 {
	margin: 0 0 12px;
	font-size: 26px;
	line-height: 1.2;
	color: #1a202c;
}

.donor3d-card-text {
	font-size: 15.5px;
	line-height: 1.65;
	color: #4a5568;
}

/* Stack on narrow screens, where a side-by-side split leaves no room for
   either half. */
@media (max-width: 720px) {
	.donor3d-card {
		flex-direction: column;
	}

	.donor3d-card-logo {
		height: min(38vh, 260px);
		width: 100%;
		aspect-ratio: auto;
		border-right: 0;
		border-bottom: 1px solid #e7ecf1;
	}
}

@media (max-width: 640px) {
	.donor3d-card-logo {
		padding: 18px;
	}

	.donor3d-card-body {
		padding: 18px 20px 22px;
	}

	.donor3d-card-body h3 {
		font-size: 21px;
	}
}

.donor3d-card-text p {
	margin: 0 0 .7em;
}

.donor3d-card-text p:last-child {
	margin-bottom: 0;
}

.donor3d-card-visit {
	display: inline-block;
	/* The body is a flex column, which would otherwise stretch this to the full
	   width and make a link look like a page-wide bar. */
	align-self: flex-start;
	margin-top: 16px;
	padding: 9px 16px;
	background: var(--donor3d-accent);
	color: #fff !important;
	font-size: 13.5px;
	font-weight: 600;
	text-decoration: none;
}

/* Scoped and fully reset: themes style bare <button> with padding, min-height,
   letter-spacing and a pill radius, which turns this into an egg. */
.donor3d-gallery .donor3d-card-close {
	position: absolute;
	top: 12px;
	right: 12px;
	box-sizing: border-box;
	width: 36px;
	height: 36px;
	min-width: 0;
	min-height: 0;
	max-width: none;
	padding: 0;
	margin: 0;
	border: 0;
	border-radius: 50%;
	/* Sits on the white card, so a filled dark blob reads as heavy. Plain mark
	   by default, with the circle appearing only on hover. */
	background: transparent;
	color: #98a2b3;
	line-height: 1;
	letter-spacing: 0;
	text-transform: none;
	box-shadow: none;
	cursor: pointer;
	display: flex;
	align-items: center;
	justify-content: center;
	flex: none;
	z-index: 3;
	/* Stop the browser drawing native button chrome over the circle. */
	-webkit-appearance: none;
	appearance: none;
	transition: background .18s ease;
}

.donor3d-gallery .donor3d-card-close svg {
	display: block;
	width: 17px;
	height: 17px;
	fill: none;
	stroke: currentColor;
	stroke-width: 2.3;
	stroke-linecap: round;
}

.donor3d-gallery .donor3d-card-close:hover,
.donor3d-gallery .donor3d-card-close:focus-visible {
	background: rgba(15, 23, 42, .07);
	color: #1a202c;
}

/* Virtual joystick (touch) */
.donor3d-joystick {
	position: absolute;
	left: 18px;
	bottom: 18px;
	width: 92px;
	height: 92px;
	border-radius: 50%;
	background: rgba(255, 255, 255, .1);
	border: 1.5px solid rgba(255, 255, 255, .25);
	z-index: 7;
	display: none;
	touch-action: none;
}

.donor3d-gallery.is-touch .donor3d-joystick {
	display: block;
}

.donor3d-joystick-knob {
	position: absolute;
	left: 50%;
	top: 50%;
	width: 40px;
	height: 40px;
	margin: -20px 0 0 -20px;
	border-radius: 50%;
	background: rgba(255, 255, 255, .55);
	transition: background .2s;
}

/* Empty-state notice (admins only) */
.donor3d-empty {
	padding: 20px;
	border: 1px dashed #94a3b8;
	background: #f8fafc;
	color: #475569;
	font-size: 14px;
}

@media (max-width: 600px) {
	.donor3d-card {
		/* Stays centred via left:50% + translate(-50%) — pinning both edges
		   here would fight the transform and push the card off-screen. */
		width: calc(100% - 20px);
	}
}
