/**
 * CBUS Soul Fest directory styles.
 *
 * Covers the artist, vendor and sponsor grids, the detail popup those cards
 * open, and the gallery lightbox. Lives beside the mu-plugin that prints the
 * markup so the two stay together.
 */

.sf-grid,
.sf-sponsors,
.sf-gallery,
.sf-lightbox {
	--sf-purple: #5f1c62;
	--sf-red: #d2222a;
	--sf-ink: #4c4c4c;
	--sf-white: #fff;
	--sf-tile: #f0f0ed;
}

/* -------------------------------------------------------------------- grid */

.sf-grid {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: 40px 30px;
	margin: 20px 0 0;
	text-align: left;
}

@media (max-width: 991px) {
	.sf-grid {
		grid-template-columns: repeat(2, minmax(0, 1fr));
		gap: 30px 20px;
	}
}

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

/* -------------------------------------------------------------------- card */

/*
 * The whole card is the control when there is a popup behind it. It is a real
 * button so it is reachable by keyboard and announced as something that opens
 * a dialog; the styling just undoes the browser's button chrome.
 */
.sf-card__trigger {
	display: block;
	width: 100%;
	padding: 0;
	border: 0;
	background: none;
	color: inherit;
	font: inherit;
	text-align: left;
	cursor: pointer;
}

.sf-card__trigger:focus-visible {
	outline: 3px solid var(--sf-red);
	outline-offset: 4px;
}

.sf-card__media {
	display: block;
	border-radius: 14px;
	overflow: hidden;
	line-height: 0;
	background: var(--sf-tile);
}

.sf-card__img {
	width: 100%;
	height: auto;
	aspect-ratio: 1 / 1;
	object-fit: cover;
	transition: transform 0.35s ease;
}

.sf-card__trigger:hover .sf-card__img,
.sf-card__trigger:focus-visible .sf-card__img,
.sf-card__media:hover .sf-card__img {
	transform: scale(1.04);
}

.sf-card__body {
	display: block;
	padding-top: 14px;
}

.sf-card__title {
	display: block;
	font-family: "Gotham", sans-serif;
	font-weight: 700;
	font-size: 2rem;
	line-height: 1.2;
	color: var(--sf-purple);
	text-decoration: none;
}

.sf-card__trigger:hover .sf-card__title,
a.sf-card__title:hover {
	color: var(--sf-red);
}

.sf-card__meta {
	display: block;
	margin: 6px 0 0;
	font-size: 1.5rem;
	line-height: 1.35;
	color: var(--sf-ink);
}

/* ------------------------------------------------------------------- popup */

.sf-modal {
	position: fixed;
	z-index: 10000;
	inset: 0;
	display: flex;
	align-items: flex-start;
	justify-content: center;
	padding: 5vh 20px;
	overflow-y: auto;
}

.sf-modal[hidden] {
	display: none;
}

.sf-modal__backdrop {
	position: fixed;
	inset: 0;
	background-color: rgba(35, 32, 32, 0.7);
}

.sf-modal__dialog {
	position: relative;
	z-index: 1;
	width: 100%;
	max-width: 760px;
	margin: auto;
	padding: 40px;
	border-radius: 14px;
	background-color: var(--sf-white);
	color: var(--sf-ink);
	text-align: left;
}

.sf-modal__close {
	position: absolute;
	top: 12px;
	right: 16px;
	width: 40px;
	height: 40px;
	padding: 0;
	border: 0;
	background: none;
	color: var(--sf-purple);
	font-size: 3.2rem;
	line-height: 1;
	cursor: pointer;
}

.sf-modal__close:hover {
	color: var(--sf-red);
}

.sf-modal__header {
	display: flex;
	flex-wrap: wrap;
	gap: 24px;
	align-items: flex-start;
}

.sf-modal__image {
	flex: 0 0 auto;
	width: 180px;
	border-radius: 10px;
	overflow: hidden;
}

.sf-modal__image img {
	display: block;
	width: 100%;
	height: auto;
}

.sf-modal__intro {
	flex: 1 1 260px;
	min-width: 0;
}

.sf-modal__title {
	margin: 0;
	font-size: 2.8rem;
	line-height: 1.15;
	color: var(--sf-purple);
}

.sf-modal__map {
	display: flex;
	align-items: flex-start;
	gap: 8px;
	margin: 12px 0 0;
	font-size: 1.5rem;
	line-height: 1.35;
	color: var(--sf-red);
	text-decoration: none;
}

.sf-modal__map:hover {
	text-decoration: underline;
}

.sf-modal__pin {
	flex: 0 0 auto;
	margin-top: 2px;
}

.sf-modal__links {
	display: flex;
	flex-wrap: wrap;
	gap: 14px;
	margin: 16px 0 0;
	padding: 0;
	list-style: none;
}

.sf-modal__links li {
	margin: 0;
}

.sf-modal__links li::before {
	content: none;
}

.sf-modal__links a {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 38px;
	height: 38px;
	border-radius: 50%;
	background-color: var(--sf-purple);
	color: var(--sf-white);
	font-size: 1.7rem;
	text-decoration: none;
}

.sf-modal__links a:hover {
	background-color: var(--sf-red);
	color: var(--sf-white);
}

.sf-modal__details {
	display: flex;
	flex-wrap: wrap;
	gap: 24px 40px;
	margin: 32px 0 0;
	padding: 24px 0 0;
	border-top: 1px solid rgba(95, 28, 98, 0.15);
}

.sf-modal__detail {
	flex: 1 1 160px;
	min-width: 0;
}

.sf-modal__detail-heading,
.sf-modal__about-heading {
	margin: 0 0 6px;
	font-size: 1.3rem;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.06em;
	color: var(--sf-purple);
	opacity: 0.75;
}

.sf-modal__detail ul {
	margin: 0;
	padding: 0;
	list-style: none;
}

.sf-modal__detail li {
	margin: 0;
	font-size: 1.5rem;
	line-height: 1.5;
}

.sf-modal__detail li::before {
	content: none;
}

.sf-modal__about {
	margin: 32px 0 0;
	padding: 24px 0 0;
	border-top: 1px solid rgba(95, 28, 98, 0.15);
}

.sf-modal__about p:last-child {
	margin-bottom: 0;
}

/* The page behind a dialog should not scroll with it. */
body.sf-modal-open {
	overflow: hidden;
}

@media (max-width: 600px) {
	.sf-modal {
		padding: 0;
	}

	.sf-modal__dialog {
		min-height: 100%;
		border-radius: 0;
		padding: 56px 20px 40px;
	}

	.sf-modal__image {
		width: 140px;
	}

	.sf-modal__title {
		font-size: 2.2rem;
	}
}

/* ---------------------------------------------------------------- sponsors */

.sf-sponsors {
	display: grid;
	grid-template-columns: repeat(4, minmax(0, 1fr));
	gap: 36px 30px;
	align-items: center;
	margin-top: 24px;
}

@media (max-width: 991px) {
	.sf-sponsors {
		grid-template-columns: repeat(3, minmax(0, 1fr));
	}
}

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

.sf-sponsor {
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 10px;
}

.sf-sponsor__img {
	max-width: 100%;
	height: auto;
	transition: transform 0.3s ease;
}

.sf-sponsor:hover .sf-sponsor__img {
	transform: scale(1.05);
}

/* ----------------------------------------------------------------- gallery */

.sf-gallery {
	display: grid;
	grid-template-columns: repeat(5, minmax(0, 1fr));
	gap: 14px;
	margin-top: 24px;
}

@media (max-width: 991px) {
	.sf-gallery {
		grid-template-columns: repeat(3, minmax(0, 1fr));
	}
}

@media (max-width: 600px) {
	.sf-gallery {
		grid-template-columns: repeat(2, minmax(0, 1fr));
		gap: 10px;
	}
}

.sf-gallery__item {
	display: block;
	width: 100%;
	padding: 0;
	border: 0;
	border-radius: 12px;
	overflow: hidden;
	line-height: 0;
	background: var(--sf-tile);
	cursor: pointer;
}

.sf-gallery__item:focus-visible {
	outline: 3px solid var(--sf-red);
	outline-offset: 3px;
}

.sf-gallery__img {
	width: 100%;
	height: 100%;
	aspect-ratio: 1 / 1;
	object-fit: cover;
	transition: transform 0.35s ease;
}

.sf-gallery__item:hover .sf-gallery__img {
	transform: scale(1.06);
}

/* ---------------------------------------------------------------- lightbox */

.sf-lightbox {
	position: fixed;
	z-index: 10001;
	inset: 0;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 24px;
}

.sf-lightbox[hidden] {
	display: none;
}

.sf-lightbox__backdrop {
	position: fixed;
	inset: 0;
	background-color: rgba(20, 8, 22, 0.88);
}

.sf-lightbox__stage {
	position: relative;
	z-index: 1;
	display: flex;
	align-items: center;
	gap: 16px;
	max-width: 100%;
	max-height: 100%;
}

.sf-lightbox__figure {
	margin: 0;
	max-width: 100%;
	min-width: 0;
	text-align: center;
}

.sf-lightbox__img {
	display: block;
	max-width: 100%;
	/* Leaves room for the caption and the close control. */
	max-height: 78vh;
	width: auto;
	height: auto;
	margin: 0 auto;
	border-radius: 8px;
}

.sf-lightbox__caption {
	margin: 14px auto 0;
	max-width: 70ch;
	color: rgba(255, 255, 255, 0.85);
	font-size: 1.5rem;
	line-height: 1.4;
}

.sf-lightbox__caption:empty {
	display: none;
}

.sf-lightbox__close,
.sf-lightbox__nav {
	flex: 0 0 auto;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 0;
	border: 0;
	border-radius: 50%;
	background-color: rgba(255, 255, 255, 0.12);
	color: #fff;
	cursor: pointer;
	transition: background-color 0.2s ease;
}

.sf-lightbox__close:hover,
.sf-lightbox__nav:hover {
	background-color: rgba(255, 255, 255, 0.28);
}

.sf-lightbox__close:focus-visible,
.sf-lightbox__nav:focus-visible {
	outline: 3px solid #fff;
	outline-offset: 3px;
}

.sf-lightbox__nav {
	width: 56px;
	height: 56px;
	font-size: 4rem;
	line-height: 1;
}

.sf-lightbox__close {
	position: absolute;
	top: -8px;
	right: -8px;
	z-index: 2;
	width: 44px;
	height: 44px;
	font-size: 2.8rem;
	line-height: 1;
}

@media (max-width: 700px) {
	.sf-lightbox {
		padding: 12px;
	}

	.sf-lightbox__stage {
		gap: 6px;
	}

	.sf-lightbox__nav {
		width: 44px;
		height: 44px;
		font-size: 3rem;
	}

	.sf-lightbox__close {
		top: 0;
		right: 0;
	}
}

/* ==========================================================================
   Directory pages, ported from Jazz & Ribs. September 2026.

   The client asked for the Food Vendors, Lineup and Sponsors pages to be set
   up the same as the Jazz & Ribs ones. This is that build's own stylesheet,
   carried across rather than reinterpreted, so the two sites stay in step.
   The class names are kept as they are on Jazz & Ribs for the same reason.

   Two things are deliberately different. The palette is declared once at the
   top, in Soul Fest's colours. And these grids sit on white here where they
   sit on the dark festival purple over there, so anything that was white for
   contrast is the brand purple instead.
   ========================================================================== */

.jrf-grid__section {
	--jrf-dark: #5F1C62;
	--jrf-brand: #D2222A;
	--jrf-accent: #F1BF2A;
	--jrf-ink: #4C4C4C;
	--jrf-white: #fff;
	--jrf-gap: 30px;
	--jrf-radius: 6px;
}

/* ---------------------------------------------------------------- headings */

.jrf-grid__heading {
	margin: 0 0 40px;
	text-align: center;
	color: var(--jrf-dark);
}

.jrf-grid__empty {
	text-align: center;
	color: var(--jrf-ink);
	opacity: 0.75;
}

/* ------------------------------------------------------------------- grids */

.jrf-grid {
	display: grid;
	grid-template-columns: repeat(1, minmax(0, 1fr));
	gap: var(--jrf-gap);
	margin: 0;
	padding: 0;
	list-style: none;
}

@media screen and (min-width: 600px) {
	.jrf-grid {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

@media screen and (min-width: 900px) {
	.jrf-grid {
		grid-template-columns: repeat(4, minmax(0, 1fr));
	}
}

.jrf-grid__item {
	display: flex;
	flex-direction: column;
	margin: 0;
}

.jrf-grid__item::before {
	content: none;
}

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

.jrf-card {
	border-radius: var(--jrf-radius);
	overflow: hidden;
}

/*
 * Logo cards are a tile with the logo centred and given breathing room, so
 * wordmarks and square marks of different proportions all sit consistently.
 * A fixed ratio keeps every tile the same height whatever is inside it. On a
 * white page the tile needs an outline to read as a tile at all.
 */
.jrf-card--logo {
	display: flex;
	align-items: center;
	justify-content: center;
	aspect-ratio: 1 / 1;
	padding: 24px;
	background-color: var(--jrf-white);
	border: 1px solid rgba(95, 28, 98, 0.14);
}

.jrf-card--logo .jrf-card__image {
	width: auto;
	max-width: 100%;
	max-height: 100%;
	height: auto;
	object-fit: contain;
}

/* Vendor and artist cards are a photo filling the tile. */
.jrf-card--photo {
	aspect-ratio: 1 / 1;
	background-color: rgba(95, 28, 98, 0.06);
}

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

.jrf-card__name {
	margin: 16px 0 0;
	font-family: "Gotham", sans-serif;
	font-weight: 700;
	font-size: 1.8rem;
	line-height: 1.25;
	color: var(--jrf-dark);
}

/* ------------------------------------------------------------------ lineup */

.jrf-artist__stage {
	display: flex;
	align-items: flex-start;
	gap: 6px;
	margin: 6px 0 0;
	font-size: 1.4rem;
	line-height: 1.3;
	color: var(--jrf-ink);
}

.jrf-artist__pin {
	flex: 0 0 auto;
	margin-top: 2px;
	color: var(--jrf-brand);
}

/* -------------------------------------------------------------- filter bar */

.jrf-filters,
.jrf-lineup__controls {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 16px;
	margin: 0 0 30px;
}

.jrf-lineup__controls {
	justify-content: space-between;
}

.jrf-filters__label {
	margin: 0;
	font-size: 1.8rem;
	font-weight: 700;
	color: var(--jrf-dark);
}

/*
 * The theme forces labels to full width, which would put each control on a
 * row of its own. Reset that here rather than globally.
 */
.jrf-filters__control {
	flex: 0 0 auto;
	width: auto;
	margin: 0;
}

.jrf-filters__control select {
	min-width: 200px;
	padding: 10px 14px;
	border: 1px solid rgba(95, 28, 98, 0.25);
	border-radius: 4px;
	background-color: var(--jrf-white);
	color: var(--jrf-ink);
	font: inherit;
	font-size: 1.5rem;
	line-height: 1.2;
}

.jrf-filters__control select:focus-visible {
	outline: 3px solid var(--jrf-brand);
	outline-offset: 2px;
}

.jrf-filters__reset {
	padding: 10px 14px;
	border: 1px solid rgba(95, 28, 98, 0.35);
	border-radius: 4px;
	background: transparent;
	color: var(--jrf-dark);
	font: inherit;
	font-size: 1.4rem;
	cursor: pointer;
}

.jrf-filters__reset:hover {
	border-color: var(--jrf-dark);
	background-color: rgba(95, 28, 98, 0.08);
}

/* ------------------------------------------------- cards that open a popup */

/*
 * The whole card is the control. It is a real button so it is reachable by
 * keyboard and announced as something that opens a dialog; the styling just
 * undoes the browser's button chrome.
 */
.jrf-card__trigger {
	display: block;
	width: 100%;
	padding: 0;
	border: 0;
	background: none;
	color: inherit;
	font: inherit;
	text-align: left;
	cursor: pointer;
}

.jrf-card__trigger .jrf-card {
	transition: box-shadow 0.3s ease, transform 0.3s ease;
}

.jrf-card__trigger:hover .jrf-card,
.jrf-card__trigger:focus-visible .jrf-card {
	transform: translateY(-4px);
	box-shadow: 0 12px 32px rgba(95, 28, 98, 0.22);
}

.jrf-card__trigger:focus-visible {
	outline: 3px solid var(--jrf-brand);
	outline-offset: 4px;
}

@media (prefers-reduced-motion: reduce) {
	.jrf-card__trigger .jrf-card {
		transition: none;
	}

	.jrf-card__trigger:hover .jrf-card,
	.jrf-card__trigger:focus-visible .jrf-card {
		transform: none;
	}
}

/* ------------------------------------------------------------------- popup */

.jrf-modal {
	position: fixed;
	z-index: 10000;
	inset: 0;
	display: flex;
	align-items: flex-start;
	justify-content: center;
	padding: 5vh 20px;
	overflow-y: auto;
}

.jrf-modal[hidden] {
	display: none;
}

.jrf-modal__backdrop {
	position: fixed;
	inset: 0;
	background-color: rgba(35, 32, 32, 0.7);
}

.jrf-modal__dialog {
	position: relative;
	z-index: 1;
	width: 100%;
	max-width: 760px;
	margin: auto;
	padding: 40px;
	border-radius: 20px;
	background-color: var(--jrf-white);
	color: var(--jrf-ink);
	text-align: left;
}

.jrf-modal__close {
	position: absolute;
	top: 12px;
	right: 16px;
	width: 40px;
	height: 40px;
	padding: 0;
	border: 0;
	background: none;
	color: var(--jrf-ink);
	font-size: 3.2rem;
	line-height: 1;
	cursor: pointer;
}

.jrf-modal__close:hover {
	color: var(--jrf-brand);
}

.jrf-modal__header {
	display: flex;
	flex-wrap: wrap;
	gap: 24px;
	align-items: flex-start;
}

.jrf-modal__image {
	flex: 0 0 auto;
	width: 180px;
	border-radius: 10px;
	overflow: hidden;
}

.jrf-modal__image img {
	display: block;
	width: 100%;
	height: auto;
}

.jrf-modal__image--logo {
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 12px;
	border: 1px solid rgba(35, 32, 32, 0.1);
}

.jrf-modal__intro {
	flex: 1 1 260px;
	min-width: 0;
}

.jrf-modal__title {
	margin: 0;
	font-size: 2.8rem;
	line-height: 1.15;
	color: var(--jrf-dark);
}

.jrf-modal__map {
	display: flex;
	align-items: flex-start;
	gap: 8px;
	margin: 12px 0 0;
	font-size: 1.5rem;
	line-height: 1.35;
	color: var(--jrf-brand);
	text-decoration: none;
}

.jrf-modal__map:hover {
	text-decoration: underline;
}

.jrf-modal__pin {
	flex: 0 0 auto;
	margin-top: 2px;
}

.jrf-modal__links {
	display: flex;
	flex-wrap: wrap;
	gap: 14px;
	margin: 16px 0 0;
	padding: 0;
	list-style: none;
}

.jrf-modal__links li {
	margin: 0;
}

.jrf-modal__links li::before {
	content: none;
}

.jrf-modal__links a {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 38px;
	height: 38px;
	border-radius: 50%;
	background-color: var(--jrf-dark);
	color: var(--jrf-white);
	font-size: 1.7rem;
	text-decoration: none;
}

.jrf-modal__links a:hover {
	background-color: var(--jrf-brand);
	color: var(--jrf-white);
}

.jrf-modal__details {
	display: flex;
	flex-wrap: wrap;
	gap: 24px 40px;
	margin: 32px 0 0;
	padding: 24px 0 0;
	border-top: 1px solid rgba(95, 28, 98, 0.15);
}

.jrf-modal__detail {
	flex: 1 1 160px;
	min-width: 0;
}

.jrf-modal__detail-heading,
.jrf-modal__about-heading {
	margin: 0 0 6px;
	font-size: 1.3rem;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.06em;
	color: var(--jrf-dark);
	opacity: 0.75;
}

.jrf-modal__detail ul {
	margin: 0;
	padding: 0;
	list-style: none;
}

.jrf-modal__detail li {
	margin: 0;
	font-size: 1.5rem;
	line-height: 1.5;
}

.jrf-modal__detail li::before {
	content: none;
}

.jrf-modal__about {
	margin: 32px 0 0;
	padding: 24px 0 0;
	border-top: 1px solid rgba(95, 28, 98, 0.15);
}

.jrf-modal__about p:last-child {
	margin-bottom: 0;
}

/* The page behind a dialog should not scroll with it. */
body.jrf-modal-open {
	overflow: hidden;
}

@media screen and (max-width: 600px) {
	.jrf-modal {
		padding: 0;
	}

	.jrf-modal__dialog {
		min-height: 100%;
		border-radius: 0;
		padding: 56px 20px 40px;
	}

	.jrf-modal__image {
		width: 140px;
	}

	.jrf-modal__title {
		font-size: 2.2rem;
	}
}

/* --- the hidden attribute has to win ---------------------------------------
 *
 * Grid items, the filter bars and the empty-state line all carry a display
 * value, and a display rule beats the browser's own [hidden] styling. Without
 * this the filters compute the right answer and nothing moves on screen, and
 * the controls show before their behaviour is attached.
 */
.jrf-grid__item[hidden],
.jrf-grid__empty[hidden],
.jrf-filters[hidden],
.jrf-lineup__controls[hidden] {
	display: none !important;
}

/* --- winning over the block's own text colour -----------------------------
 *
 * These grids sit inside a block that sets a colour on every paragraph it
 * contains, at two classes deep. The card name and the lines around it are
 * scoped one level further here so they keep the colours above rather than
 * inheriting the block's body colour.
 */
.jrf-grid__section .jrf-card__name {
	color: var(--jrf-dark);
}

.jrf-grid__section .jrf-artist__stage {
	color: var(--jrf-ink);
}

.jrf-grid__section .jrf-filters__label {
	color: var(--jrf-dark);
}

.jrf-grid__section .jrf-grid__empty {
	color: var(--jrf-ink);
}

.jrf-modal .jrf-modal__title {
	color: var(--jrf-dark);
}

.jrf-modal .jrf-modal__detail-heading,
.jrf-modal .jrf-modal__about-heading {
	color: var(--jrf-dark);
}

/* The popup carries its own palette; it is printed outside the grid section
   in the sponsor case, so the variables are declared on it as well. */
.jrf-modal {
	--jrf-dark: #5F1C62;
	--jrf-brand: #D2222A;
	--jrf-ink: #4C4C4C;
	--jrf-white: #fff;
}

/* ==========================================================================
   Directory on a colour band.

   On Jazz & Ribs these grids sit on the festival's dark colour, full width,
   and everything on them is white. The shortcodes now sit in their own full
   width block set to the Soul Fest purple, so the colours below follow the
   block's own light or dark setting rather than being fixed. A directory
   dropped into a light block still reads correctly.
   ========================================================================== */

.content-light .jrf-grid__section,
.content-light .jrf-modal {
	--jrf-dark: #5F1C62;
	--jrf-brand: #F1BF2A;
	--jrf-ink: #4C4C4C;
}

.content-light .jrf-grid__section .jrf-grid__heading,
.content-light .jrf-grid__section .jrf-card__name,
.content-light .jrf-grid__section .jrf-artist__stage,
.content-light .jrf-grid__section .jrf-filters__label,
.content-light .jrf-grid__section .jrf-grid__empty {
	color: #FFFFFF;
}

.content-light .jrf-grid__section .jrf-artist__pin {
	color: #F1BF2A;
}

/* The controls are white tiles on the band, the way they are on Jazz & Ribs,
   so they need no outline of their own. */
.content-light .jrf-grid__section .jrf-filters__control select {
	border: 0;
}

.content-light .jrf-grid__section .jrf-filters__reset {
	border-color: rgba(255, 255, 255, 0.5);
	color: #FFFFFF;
}

.content-light .jrf-grid__section .jrf-filters__reset:hover {
	border-color: #FFFFFF;
	background-color: rgba(255, 255, 255, 0.12);
}

/* A white logo tile needs no outline once it is on a colour. */
.content-light .jrf-grid__section .jrf-card--logo {
	border: 0;
}

.content-light .jrf-grid__section .jrf-card--photo {
	background-color: rgba(255, 255, 255, 0.08);
}

.content-light .jrf-grid__section .jrf-card__trigger:hover .jrf-card,
.content-light .jrf-grid__section .jrf-card__trigger:focus-visible .jrf-card {
	box-shadow: 0 12px 32px rgba(0, 0, 0, 0.25);
}

/* The popup is a white dialog wherever it is opened from, so it keeps the
   purple headings rather than inheriting the band's light text. */
.jrf-modal .jrf-modal__title,
.jrf-modal .jrf-modal__detail-heading,
.jrf-modal .jrf-modal__about-heading {
	color: #5F1C62;
}

.jrf-modal .jrf-modal__dialog,
.jrf-modal .jrf-modal__detail li,
.jrf-modal .jrf-modal__about p {
	color: #4C4C4C;
}

.jrf-modal .jrf-modal__map {
	color: #D2222A;
}

/* The block wraps its content at the theme's reading width, which is right
   for copy and too narrow for a four across grid. The directory takes the
   full block width instead. */
.fwt__container--inner:has(.jrf-grid__section) {
	max-width: 1252px;
	width: 100%;
}

/* ================================================================
 * Schedule
 *
 * The day tabbed stage timetable, carried across from Jazz & Ribs and
 * recoloured. What carries the colour is the day, not the stage: every
 * set on day one is purple, day two red, day three yellow, and that
 * day's tab matches. The shortcode tags each tab and panel with its day
 * position and the rules below do the rest.
 * ================================================================ */

.jrf-schedule__section {
	--jrf-dark: #5F1C62;
	--jrf-brand: #D2222A;
	--jrf-ink: #4C4C4C;
	--jrf-white: #fff;
}

/*
 * Colours and proportions follow the timetable on the current site. The one
 * thing that carries the colour there is the day, not the stage: every set on
 * Friday is maroon, Saturday gold, Sunday coral, and the tab for that day uses
 * the same colour. The block tags each tab and panel with its day position and
 * the three blocks below do the rest.
 */
.jrf-schedule {
	/*
	 * One knob controls the whole timetable. Every block offset and height is
	 * this many pixels per minute; 1.6667 is the current site's 100px hour.
	 */
	--jrf-min: 1.6667px;
	--jrf-header-h: 104px;
	--jrf-rule: #c2c2c2;
	--jrf-schedule-ink: #5F1C62;

	/* Day one, day two, day three. */
	--jrf-day-1: #5F1C62;
	--jrf-day-2: #D2222A;
	--jrf-day-3: #F1BF2A;

	/*
	 * The festival yellow is too light to read as text on white, so a
	 * darker amber stands in for the resting tab. The tab still fills with
	 * the real yellow once it is selected.
	 */
	--jrf-day-3-rest: #8A6A0F;

	background-color: var(--jrf-white);
	border-radius: 10px;
	box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.13);
	overflow: hidden;
}

/* ---------------------------------------------------------------- day tabs */

.jrf-schedule__tabs {
	display: flex;
	flex-wrap: wrap;
	border-bottom: 1px solid var(--jrf-rule);
	border-radius: 10px 10px 0 0;
}

.jrf-schedule__tab {
	flex: 1 1 0;
	min-width: 140px;
	padding: 30px 12px;
	border: 0;
	background: transparent;
	font: inherit;
	text-align: center;
	cursor: pointer;
	transition: background-color 0.25s ease, color 0.25s ease;
}

.jrf-schedule__tab:first-child {
	border-radius: 10px 0 0 0;
}

.jrf-schedule__tab:last-child {
	border-radius: 0 10px 0 0;
}

.jrf-schedule__tab-date {
	display: block;
	font-size: 1.6rem;
	line-height: 1.3;
}

.jrf-schedule__tab-day {
	display: block;
	font-size: 3.6rem;
	font-weight: 700;
	line-height: 44px;
	text-transform: uppercase;
}

/*
 * A resting tab is its day's colour on white; the selected tab inverts, and
 * the gold day takes dark text because white on gold does not read.
 */
.jrf-schedule__tab[data-jrf-day="1"] {
	color: var(--jrf-day-1);
}

.jrf-schedule__tab[data-jrf-day="2"] {
	color: var(--jrf-day-2);
}

.jrf-schedule__tab[data-jrf-day="3"] {
	color: var(--jrf-day-3-rest);
}

.jrf-schedule__tab[data-jrf-day="1"][aria-selected="true"] {
	background-color: var(--jrf-day-1);
	color: var(--jrf-white);
}

.jrf-schedule__tab[data-jrf-day="2"][aria-selected="true"] {
	background-color: var(--jrf-day-2);
	color: var(--jrf-white);
}

.jrf-schedule__tab[data-jrf-day="3"][aria-selected="true"] {
	background-color: var(--jrf-day-3);
	color: var(--jrf-schedule-ink);
}

.jrf-schedule__tab[data-jrf-day="3"]:hover:not([aria-selected="true"]) {
	color: var(--jrf-schedule-ink);
}

.jrf-schedule__tab:focus-visible {
	outline: 3px solid var(--jrf-schedule-ink);
	outline-offset: -3px;
}

/* ---------------------------------------------------------------- timetable */

.jrf-schedule__panel {
	padding: 43px 0 28px;
}

.jrf-schedule__grid {
	position: relative;
	display: flex;
	gap: 0 63px;
	padding: 0 60px 0 20px;
}

/*
 * The hour rules are drawn once across the whole grid rather than inside each
 * stage column, so they read as continuous lines behind the sets the way they
 * do on the current site, instead of breaking at every column gap. It is the
 * grid's first child, so the sets paint over it.
 */
.jrf-schedule__grid::before {
	content: "";
	position: absolute;
	left: 94px;
	right: 60px;
	top: var(--jrf-header-h);
	height: calc(var(--jrf-span) * var(--jrf-min));
	background-image: linear-gradient(to bottom, var(--jrf-rule) 1px, transparent 1px);
	background-size: 100% calc(60 * var(--jrf-min));
	pointer-events: none;
}

.jrf-schedule__axis {
	position: relative;
	flex: 0 0 auto;
	width: 74px;
	/* Clears the stage heading row so the ticks line up with the tracks. */
	padding-top: var(--jrf-header-h);
	height: calc(var(--jrf-span) * var(--jrf-min) + var(--jrf-header-h));
}

.jrf-schedule__tick {
	position: absolute;
	right: 14px;
	top: calc(var(--jrf-header-h) + var(--jrf-offset) * var(--jrf-min));
	transform: translateY(-50%);
	font-size: 1.8rem;
	font-weight: 700;
	line-height: 22px;
	/* The hour rail is one colour on the current site whatever the day. */
	color: var(--jrf-day-1);
	white-space: nowrap;
}

.jrf-schedule__column {
	display: flex;
	flex: 1 1 0;
	flex-direction: column;
	min-width: 0;
}

.jrf-schedule__stage {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	/* Fixed rather than min so every column's track starts at the same y. */
	height: var(--jrf-header-h);
	text-align: center;
}

.jrf-schedule__stage-name {
	margin: 0;
	font-size: 1.8rem;
	font-weight: 600;
	line-height: 1.25;
	color: var(--jrf-schedule-ink);
}

.jrf-schedule__stage-presenter {
	margin: 8px 0 0;
	line-height: 1.3;
	color: var(--jrf-schedule-ink);
}

.jrf-schedule__presented-by {
	display: block;
	font-size: 1.4rem;
	font-weight: 400;
	letter-spacing: 1px;
	text-transform: uppercase;
}

.jrf-schedule__sponsor {
	display: block;
	font-size: 1.8rem;
	font-weight: 700;
}

.jrf-schedule__track {
	position: relative;
	height: calc(var(--jrf-span) * var(--jrf-min));
}

.jrf-schedule__set {
	position: absolute;
	left: 0;
	right: 0;
	top: calc(var(--jrf-offset) * var(--jrf-min));
	height: calc(var(--jrf-duration) * var(--jrf-min));
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	padding: 5px;
	border-radius: 10px;
	text-align: center;
	overflow: hidden;
}

.jrf-schedule__panel[data-jrf-day="1"] .jrf-schedule__set {
	background-color: var(--jrf-day-1);
	color: var(--jrf-white);
}

.jrf-schedule__panel[data-jrf-day="2"] .jrf-schedule__set {
	background-color: var(--jrf-day-2);
	color: var(--jrf-white);
}

.jrf-schedule__panel[data-jrf-day="3"] .jrf-schedule__set {
	background-color: var(--jrf-day-3);
	color: var(--jrf-schedule-ink);
}

.jrf-schedule__set-name {
	margin: 0;
	font-size: 1.6rem;
	font-weight: 700;
	line-height: 1.2;
}

.jrf-schedule__set-time {
	margin: 4px 0 0;
	font-size: 1.4rem;
	font-weight: 400;
	letter-spacing: 1px;
	line-height: 1.2;
	text-transform: uppercase;
}

.jrf-schedule__notice {
	margin: 20px 60px 0;
	padding: 12px 16px;
	background-color: rgba(95, 28, 98, 0.07);
	border-radius: 6px;
	font-size: 1.4rem;
}

/*
 * Below the grid breakpoint the timetable stops being a timetable. The axis
 * goes away and each stage becomes a chronological list, which is the same
 * DOM reflowed rather than a second copy of the markup. The current site
 * scrolls sideways here instead; this reads better on a phone and keeps the
 * colours the same.
 */
@media screen and (max-width: 899px) {
	.jrf-schedule__grid {
		flex-direction: column;
		gap: 30px;
		padding: 0 20px;
	}

	.jrf-schedule__axis,
	.jrf-schedule__grid::before {
		display: none;
	}

	.jrf-schedule__stage {
		height: auto;
		align-items: flex-start;
		padding-bottom: 12px;
		border-bottom: 1px solid var(--jrf-rule);
		text-align: left;
	}

	.jrf-schedule__track {
		display: flex;
		flex-direction: column;
		gap: 10px;
		height: auto;
		padding-top: 12px;
		background-image: none;
	}

	.jrf-schedule__set {
		position: static;
		height: auto;
		flex-direction: row;
		align-items: baseline;
		justify-content: space-between;
		gap: 12px;
		padding: 12px 14px;
		text-align: left;
	}

	.jrf-schedule__set-time {
		margin: 0;
		flex: 0 0 auto;
	}

	.jrf-schedule__notice {
		margin: 20px 20px 0;
	}
}

/*
 * A set block opens that artist's popup, so it is a button. These rules take
 * the browser's own button styling back off, since the block itself is drawn
 * by the timetable rules above, and give it something to say on hover and on
 * keyboard focus.
 */
button.jrf-schedule__set {
	width: 100%;
	margin: 0;
	border: 0;
	font: inherit;
	color: inherit;
	-webkit-appearance: none;
	appearance: none;
	cursor: pointer;
	transition: transform 0.15s ease, box-shadow 0.15s ease;
}

button.jrf-schedule__set:hover,
button.jrf-schedule__set:focus-visible {
	transform: scale(1.02);
	box-shadow: 0 4px 14px rgba(0, 0, 0, 0.25);
}

button.jrf-schedule__set:focus-visible {
	outline: 2px solid currentColor;
	outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
	button.jrf-schedule__set {
		transition: none;
	}

	button.jrf-schedule__set:hover,
	button.jrf-schedule__set:focus-visible {
		transform: none;
	}
}

/*
 * The block wrapper colours its own paragraphs, and that rule outranks the
 * single class rules above, so the stage headings were coming out body grey.
 * These repeat them one level deeper.
 */
.jrf-schedule .jrf-schedule__stage-name,
.jrf-schedule .jrf-schedule__stage-presenter {
	color: var(--jrf-schedule-ink);
}
