/* ═══════════════════════════════════════════════════════════════
   Previous-project modal
   Scrim  black @ 80%
   Card   1080x561, #F7F7F7, radius 20
   Image  480x480, radius 10, inset 40 left / 41 top
   Close  68px circle #2B5F94, X 24x24 stroke #F7F7F7 2px
   Title  28/38 Heavy #210202, 490 wide
   Body   16/26 Regular #210202, 490 wide, 10px between paras
   ═══════════════════════════════════════════════════════════════ */
.card-modal {
	/* The gutter is up to 100px, which as a TOP AND BOTTOM inset spent 200px
	   of a short screen before the card got a say — enough on its own to push
	   the image into a scroll. Sideways it still reads as the page gutter;
	   vertically 40px is all the breathing room the scrim needs. */
	--modal-pad-y: min(var(--gd-gutter), 40px);
	align-items: center;
	display: flex;
	inset: 0;
	justify-content: center;
	opacity: 0;
	padding: var(--modal-pad-y) var(--gd-gutter);
	position: fixed;
	transition: opacity .3s var(--gd-ease), visibility 0s linear .3s;
	visibility: hidden;
	z-index: 2000;
}
.card-modal.is-open {
	opacity: 1;
	transition-delay: 0s;
	visibility: visible;
}

.card-modal__scrim {
	background: #000;
	inset: 0;
	opacity: .8;
	position: absolute;
}

.card-modal__card {
	background: var(--gd-panel-light);
	border-radius: var(--gd-radius-card);
	display: flex;
	gap: 30px;
	/* 100% of the flex parent's content box, which is already the viewport
	   less --modal-pad-y top and bottom — so this stays in step with the
	   padding above instead of restating it. overflow-y is a last resort
	   only; the rules below are what keep it from ever being reached. */
	max-height: 100%;
	max-width: 1080px;
	overflow-y: auto;
	padding: 40px;
	position: relative;
	transform: translateY(16px) scale(.98);
	transition: transform .35s var(--gd-ease);
	width: 100%;
}
.card-modal.is-open .card-modal__card {
	transform: none;
}

.card-modal__media {
	flex: 0 0 480px;
	max-width: 480px;
	min-height: 0;
}

/* The square is the design's intent, not a hard promise: at 480px tall plus
   80px of card padding the row needed 560px of screen, so any laptop under
   ~730px tall got a scrollbar and a cropped card. Cap the height at what the
   screen actually has and let the square become a landscape crop — object-fit
   is cover, so the subject holds and only the framing tightens. */
.card-modal__media img {
	aspect-ratio: 1 / 1;
	border-radius: var(--gd-radius-tile);
	display: block;
	max-height: calc(100vh - var(--modal-pad-y) * 2 - 80px);
	max-height: calc(100svh - var(--modal-pad-y) * 2 - 80px);
	object-fit: cover;
	width: 100%;
}

.card-modal__body {
	align-self: center;
	flex: 1 1 auto;
	max-width: 490px;
	min-width: 0;
}

.card-modal__title {
	color: var(--gd-field-ink);
	font-size: clamp(22px, 20.25px + 0.4484vw, 28px);
	font-weight: var(--gd-heavy);
	line-height: clamp(30px, 27.67px + 0.5979vw, 38px);
	margin: 0 0 13px;
	padding-right: 60px;
}

.card-modal__text {
	color: var(--gd-field-ink);
	font-size: 16px;
	line-height: 26px;
}
.card-modal__text p {
	margin: 0;
	padding: 0;
}
.card-modal__text p + p {
	margin-top: 10px;
}

/* ── Close button ────────────────────────────────────────────── */
.card-modal__close {
	align-items: center;
	background: var(--gd-blue);
	border: 0;
	border-radius: 50%;
	cursor: pointer;
	display: flex;
	height: 68px;
	justify-content: center;
	padding: 0;
	position: absolute;
	right: 30px;
	top: 36px;
	transition: background-color .3s var(--gd-ease), transform .3s var(--gd-ease);
	width: 68px;
	z-index: 2;
}
.card-modal__close:hover {
	background: var(--gd-blue-dark);
	transform: rotate(90deg);
}

.card-modal__close::before,
.card-modal__close::after {
	background: var(--gd-panel-light);
	content: "";
	height: 2px;
	inset: 0;
	margin: auto;
	position: absolute;
	width: 24px;
}
.card-modal__close::before {
	transform: rotate(45deg);
}
.card-modal__close::after  {
	transform: rotate(-45deg);
}

body.card-modal-open {
	overflow: hidden;
}

@media (max-width: 1100px) {
	.card-modal__card {
	flex-direction: column;
	gap: 24px;
	padding: 30px;
}
	/* Stacked, the square is measured off the FULL card width, so a 700px-wide
	   card asked for a 700px-tall image and pushed the copy off the bottom of
	   the screen. Let the image be the one thing that gives: the body keeps its
	   natural height (0 0 auto), the media shrinks into whatever is left of the
	   card's max-height. min-height:0 is what permits it — a flex item will not
	   shrink below a replaced child's natural size without it. */
	/* display:contents dissolves the wrapper so the IMAGE is the flex item.
	   Shrinking the wrapper instead left the img at its square height, clipped
	   top-anchored by overflow — object-fit never got a say. As the flex item
	   it shrinks itself, and cover crops it from the centre as intended. */
	.card-modal__media {
	display: contents;
}
	.card-modal__media img {
	flex: 0 1 auto;
	max-height: none;
	min-height: 0;
}
	.card-modal__body {
	align-self: stretch;
	flex: 0 0 auto;
	max-width: none;
}
	.card-modal__close {
	height: 48px;
	right: 20px;
	top: 20px;
	width: 48px;
}
	.card-modal__close::before,
	.card-modal__close::after {
	width: 18px;
}
	.card-modal__title {
	padding-right: 44px;
}
}

@media (prefers-reduced-motion: reduce) {
	.card-modal,
	.card-modal__card,
	.card-modal__close {
	transition: none;
}
	.card-modal__card {
	transform: none;
}
}
