/**
 * Module: Program Cards
 *
 * The card is a two-column grid over a photograph that stretches to whatever height the copy
 * sets. Global .media carries an aspect-ratio, so the media needs a definite width as well as
 * its height: given only a height, the ratio sizes the width off it and the photograph overruns
 * its track and buries the copy.
 */

.module.program-cards .intro {
	display: flex;
	flex-direction: column;
	gap: var(--text-spacing-xsmall);
	margin-bottom: var(--module-spacing-small);
	text-align: center;
}

/* Eight columns, and never longer than the comp's own line: as a share of the container the
   measure grew with the page, so on a wide monitor the deck ran half as long again as it does
   on the board. The comp's line is 784 wide inside a 1196 container. */
.module.program-cards .intro .description {
	margin: 0 auto;
	max-width: min(calc(8 * var(--one-column-width) + 7 * var(--gap)), calc(784rem / 16));
}

.module.program-cards .intro .description p {
	margin: 0;
}

.module.program-cards .intro .description p + p {
	margin-top: var(--text-spacing-xsmall);
}

/* The deck marks the audiences it names in bold and links them out. Bold alone is not a link,
   so the phrase takes the pollen rule the hero statement uses rather than a colour of its own. */
.module.program-cards .intro .description a {
	color: inherit;
	text-decoration-color: var(--pollen);
	text-decoration-line: underline;
	text-decoration-thickness: 2px;
	text-underline-offset: 4px;
}

.module.program-cards .intro .description a:is(:hover, :focus-visible) {
	text-decoration-color: var(--sun);
	text-underline-offset: 6px;
}

/* The direct-child selector is the test for the list state: below 650 Jazzy lifts the list into a
   wrapper of its own, and a stack of rows is not what a track is. */
.module.program-cards .container > .cards {
	display: flex;
	flex-direction: column;
	gap: var(--text-spacing-xxlarge);
}

.module.program-cards .cards {
	list-style: none;
	margin: 0;
	padding: 0;
}

/* Jazzy marks the list a carousel at every width so it can become one at a rung; where it stands
   down, the copy is still copy and has to be selectable. */
.module.program-cards .cards.jazzy-static {
	-webkit-user-select: auto;
	user-select: auto;
}

/* The pager belongs to the carousel, so it is only there while there is one. */
.module.program-cards .arrows {
	display: none;
}

.module.program-cards li {
	position: relative;
}

.module.program-cards .card {
	display: grid;
	grid-template-columns: calc(475 / 1196 * 100%) minmax(0, 1fr);
}

.module.program-cards .card .media {
	aspect-ratio: 475 / 312;
	height: 100%;
	width: 100%;
}

.module.program-cards .card .media::before,
.module.program-cards .card .media::after {
	content: '';
	inset: 0;
	position: absolute;
	transition: opacity var(--motion) var(--ease-out);
}

.module.program-cards .card .media::after {
	background-color: rgba(0, 0, 0, .5);
	z-index: 1;
}

.module.program-cards .card .media::before {
	background: var(--aqua);
	mix-blend-mode: hard-light;
	z-index: 2;
}

.module.program-cards .card .watermark {
	bottom: 0;
	color: var(--white);
	left: calc(175 / 475 * 100%);
	opacity: .25;
	pointer-events: none;
	position: absolute;
	transition: opacity var(--motion) var(--ease-out);
	width: calc(461 / 475 * 100%);
	z-index: 3;
}

.module.program-cards .card .watermark svg {
	display: block;
	height: auto;
	max-width: none;
	width: 100%;
}

/* Sized off its height, not its width: a wordmark twice as wide as the mark it replaces reads
   half as tall on a shared width, and these run from roughly 2:1 to 5:1. The width cap catches
   the widest of them, and `contain` is what keeps one in proportion once it does. */
.module.program-cards .card .media .logo {
	height: 64px;
	left: 50%;
	max-width: min(280px, 60%);
	object-fit: contain;
	position: absolute;
	top: 50%;
	transition: opacity var(--motion) var(--ease-out);
	translate: -50% -50%;
	width: auto;
	z-index: 4;
}

/* The photograph takes the card's 1.05 zoom; the mark laid over it does not, or it never
   renders at the size set above — it only ever appears while the card is hovered. */
.module.program-cards .card:hover .media .logo {
	transform: none;
}

.module.program-cards .sunray {
	color: var(--sun);
	left: -55px;
	opacity: 0;
	pointer-events: none;
	position: absolute;
	rotate: -12deg;
	scale: .7;
	top: -55px;
	transition: opacity var(--motion) var(--ease-out), rotate var(--motion-slow) var(--ease-out), scale var(--motion-slow) var(--ease-out);
	width: 110px;
	z-index: 2;
}

/* The mark is a sibling of the card it hangs off, so the row item is the hover target. */
.module.program-cards .cards > li:hover .sunray,
.module.program-cards .cards > li:focus-within .sunray {
	opacity: 1;
	rotate: 0deg;
	scale: 1;
}

.module.program-cards .sunray svg {
	display: block;
	height: auto;
	max-width: none;
	width: 100%;
}

.module.program-cards .card .content {
	--panel-inset: var(--text-spacing-xlarge);
	display: flex;
	flex-direction: column;
	gap: var(--text-spacing-medium);
	justify-content: space-between;
	padding: var(--text-spacing-large) var(--panel-inset) var(--text-spacing-small);
}

.module.program-cards .card .text {
	display: flex;
	flex-direction: column;
	gap: var(--text-spacing-xxsmall);
}

.module.program-cards .card .article-title {
	margin: 0;
}

.module.program-cards .card .location {
	align-items: center;
	display: flex;
	gap: var(--text-spacing-xxsmall);
	margin: 0;
}

.module.program-cards .card .location .icon {
	flex-shrink: 0;
}

/* Doubles the .text gap: the title and location are one tight stack, the deck stands off it. */
.module.program-cards .card .deck {
	margin-top: var(--text-spacing-xxsmall);
}

.module.program-cards .card .deck p {
	margin: 0;
}

.module.program-cards .card .deck p + p {
	margin-top: var(--text-spacing-xsmall);
}

/* The label stays flush left with the copy and the arrow goes out to the panel's bottom-right
   corner, 24px off both edges. The pull-out is what buys the right-hand 24 without taking the
   copy off its own inset. */
.module.program-cards .card .btn.secondary {
	align-self: stretch;
	justify-content: space-between;
	margin-right: calc(var(--text-spacing-small) - var(--panel-inset));
}

.module.program-cards .card:hover .btn.secondary .arrow,
.module.program-cards .card:focus-within .btn.secondary .arrow {
	background: var(--sun-light);
}

.module.program-cards .card .media::before,
.module.program-cards .card .media::after,
.module.program-cards .card .media .logo,
.module.program-cards .card .watermark {
	opacity: 0;
}

.module.program-cards .card:not(.has-logo) .media::after {
	background-color: rgba(0, 0, 0, .6);
}

.module.program-cards .card:not(.has-logo) .media img {
	transition: filter var(--motion) var(--ease-out), transform var(--motion) var(--ease-out);
}

.module.program-cards .card:not(.has-logo):hover .media img,
.module.program-cards .card:not(.has-logo):focus-within .media img {
	filter: grayscale(1);
}

.module.program-cards .card:hover .media::before,
.module.program-cards .card:hover .media::after,
.module.program-cards .card:hover .media .logo,
.module.program-cards .card:focus-within .media::before,
.module.program-cards .card:focus-within .media::after,
.module.program-cards .card:focus-within .media .logo {
	opacity: 1;
}

.module.program-cards .card:hover .watermark,
.module.program-cards .card:focus-within .watermark {
	opacity: .25;
}

/***************************************************************************************************************************************************************************************/
/* MQ MAX-WIDTH 950 - Tablet Sizes */
/***************************************************************************************************************************************************************************************/

@media (max-width: calc(950rem / 16)) {
	/* A tap on a touch screen fires :hover for an instant, which flashed the whole card state on
	   the way to the link. Held at rest here — and only against :hover, so a card reached by
	   keyboard still lights: focus arrives without a pointer, so this never matches. */
	.module.program-cards .cards > li:hover .sunray {
		opacity: 0;
		rotate: -12deg;
		scale: .7;
	}

	.module.program-cards .card:hover .media::before,
	.module.program-cards .card:hover .media::after,
	.module.program-cards .card:hover .media .logo,
	.module.program-cards .card:hover .watermark {
		opacity: 0;
	}

	.module.program-cards .card:not(.has-logo):hover .media img {
		filter: none;
	}

	.module.program-cards .card:hover .media img {
		transform: none;
	}

	.module.program-cards .card:hover .btn.secondary .arrow {
		background: var(--sun);
	}

	.module.program-cards .intro .description {
		max-width: none;
	}

	.module.program-cards .card {
		grid-template-columns: 1fr;
	}

	.module.program-cards .card .media {
		aspect-ratio: 16 / 9;
	}

	.module.program-cards .card .content {
		--panel-inset: var(--text-spacing-medium);
		gap: var(--text-spacing-small);
		padding: var(--text-spacing-medium) var(--panel-inset) var(--text-spacing-small);
	}

	.module.program-cards .sunray {
		left: -20px;
		top: -28px;
		width: 80px;
	}
}

/***************************************************************************************************************************************************************************************/
/* MQ MAX-WIDTH 650 - Mobile Sizes */
/***************************************************************************************************************************************************************************************/

@media (max-width: calc(650rem / 16)) {
	.module.program-cards .card .content {
		--panel-inset: var(--text-spacing-small);
		padding: var(--text-spacing-small);
	}

	.module.program-cards:not(:has(.jazzy-static)) .arrows {
		display: flex;
		gap: var(--text-spacing-xxsmall);
		justify-content: center;
		margin-bottom: var(--text-spacing-medium);
	}

	/* The intro carries the band's step down to the cards, and the pager is now between them. */
	.module.program-cards:not(:has(.jazzy-static)) .intro {
		margin-bottom: var(--text-spacing-medium);
	}

	/* The mark hangs off the card's top-left corner, outside the box the track clips. The clip is
	   pushed out to make room for it and pulled back by the same amount, so the track keeps the
	   width Jazzy measured and the slides keep their places. A clip margin would have done this in
	   one line, and adds the overhang to the page's own scrollable width instead. */
	.module.program-cards .jazzy-carousel-wrapper {
		margin-left: calc(-1 * var(--container-outer-padding));
		margin-top: -28px;
		padding-left: var(--container-outer-padding);
		padding-top: 28px;
		width: calc(100% + var(--container-outer-padding) * 2);
	}

	/* The card's own arrow steps down a cut: at the Large size it is the biggest thing in a panel
	   the width of the screen, and the title above it is what should be. */
	.module.program-cards .card .btn.secondary.large .arrow {
		height: 34px;
		width: 48px;
	}

	.module.program-cards .card .btn.secondary.large .arrow svg {
		height: 11px;
		width: 13px;
	}

	.module.program-cards .card .deck {
		margin-top: 0;
	}

	.module.program-cards .intro {
		gap: var(--text-spacing-xxsmall);
	}
}
