/*
Theme Name:   Capitol Hill Chorale
Theme URI:    https://capitolhillchorale.org
Author:       Trapeze
Description:  Block theme for the Capitol Hill Chorale. Ships three color palettes as
              style variations. Designed to hold up on text-heavy pages with no imagery.
Version:      1.0.0
Requires at least: 6.7
Tested up to: 7.0
Requires PHP: 8.2
License:      GPL-2.0-or-later
License URI:  https://www.gnu.org/licenses/gpl-2.0.html
Text Domain:  chc
Tags:         one-column, block-patterns, full-site-editing, editor-style, custom-colors
*/

/*
 * Almost everything is in theme.json. This file is for the handful of things
 * theme.json cannot express.
 */

/* A quick crossfade between pages, via the cross-document View Transitions
 * API. Pure progressive enhancement: browsers without it simply navigate. */
@view-transition {
	navigation: auto;
}

::view-transition-old(root),
::view-transition-new(root) {
	animation-duration: 0.18s;
}

/* Section-nav items carry per-item view-transition names (see the block's
 * render.php), so between sibling pages the persistent entries glide to
 * their new positions while the root — present only on child pages —
 * fades in or out instead of causing a layout jump. */
::view-transition-group(*) {
	animation-duration: 0.22s;
	animation-timing-function: ease;
}

/* Respect reduced-motion preferences for anything that animates. A shortened
 * duration is not enough: the view()-timeline entrances ignore duration and
 * would still hold elements transparent until scrolled into view. The `*`
 * selector cannot reach the view-transition pseudo-elements, so they get
 * their own explicit kill. */
@media (prefers-reduced-motion: reduce) {
	*,
	*::before,
	*::after {
		animation: none !important;
		transition-duration: 0.01ms !important;
		scroll-behavior: auto !important;
	}

	::view-transition-group(*),
	::view-transition-old(*),
	::view-transition-new(*) {
		animation: none !important;
	}
}

/* Visible focus ring — the default outline disappears against dark buttons. */
:where(a, button, input, select, textarea, [tabindex]):focus-visible {
	outline: 2px solid var(--wp--preset--color--primary);
	outline-offset: 2px;
}

/* Skip link, shown only when focused. */
.chc-skip-link {
	position: absolute;
	left: -9999px;
	z-index: 999;
	padding: 0.75em 1.25em;
	background: var(--wp--preset--color--contrast);
	color: var(--wp--preset--color--base);
	text-decoration: none;
}

.chc-skip-link:focus {
	left: var(--wp--preset--spacing--30);
	top: var(--wp--preset--spacing--30);
}

/*
 * Concert date "eyebrow" — small caps line above a concert title.
 * Used by the concert templates and the upcoming-concerts pattern.
 */
.chc-eyebrow {
	font-size: var(--wp--preset--font-size--small);
	font-weight: 600;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	color: var(--wp--preset--color--secondary);
}

/* Centered subtitles read badly with a one-word last line; balance the break. */
.is-style-text-subtitle {
	text-wrap: balance;
}

/* Multi-line titles break evenly rather than stranding a word, and page
 * titles get a real pause before the body — a chapter-opener's breath, not
 * the uniform block gap. Applies to every interior page-title form: post
 * titles, archive query titles, and the hand-written h1 that opens each
 * archive template. */
.wp-block-post-title {
	text-wrap: balance;
}

main .wp-block-post-title,
main .wp-block-query-title,
main > h1.wp-block-heading {
	margin-bottom: var(--wp--preset--spacing--40);
}

/* A short gold tick under page titles: now that interior h1s sit closer to
 * the content headings in size, this is what says "chapter, not section".
 * Concert and album singles skip it — their season chip and byline already
 * do that job, and a tick between title and byline would crowd. */
.chc-page-title.wp-block-post-title::after,
main .wp-block-query-title::after,
main > h1.wp-block-heading::after {
	content: "";
	display: block;
	width: 2.75rem;
	margin-top: 0.4em;
	border-bottom: 3px solid var(--wp--preset--color--primary);
}

/*
 * Prose rhythm: headings inside page/post copy open a new thought, so they
 * carry more space above than the uniform block gap — without it, a Donate
 * heading sits as close to the previous paragraph as that paragraph's own
 * lines sit to each other.
 */
/* Imported copy sometimes opens with its own h1; inside content it ranks
 * below the page title — a rung between the title (44px, gold tick) and
 * the 30px section h2s, never a twin of the title. */
.wp-block-post-content h1 {
	font-size: clamp(1.6rem, 1.3rem + 1vw, 2.1rem);
}

.wp-block-post-content > h1,
.wp-block-post-content > h2 {
	margin-top: var(--wp--preset--spacing--60);
}

.wp-block-post-content > h3 {
	margin-top: var(--wp--preset--spacing--50);
}

.wp-block-post-content > h1:first-child,
.wp-block-post-content > h2:first-child,
.wp-block-post-content > h3:first-child {
	/* A small step, not the full section pause: enough for the page title
	 * to stand alone above a leading heading. */
	margin-top: var(--wp--preset--spacing--30);
}

/* ---------------------------------------------------------------------------
 * Email signup — see patterns/email-signup.php.
 * ------------------------------------------------------------------------ */
.chc-signup {
	/* Fill the column up to the cap: as a centered flex child the form otherwise
	 * shrinks to fit-content, which is exactly wide enough to wrap the button
	 * under the input. */
	width: 100%;
	margin-top: var(--wp--preset--spacing--40);
	max-width: 34rem;
}

.chc-print-panel .chc-signup {
	margin-inline: auto;
}

.chc-signup__label {
	display: block;
	margin-bottom: 0.4em;
	font-size: var(--wp--preset--font-size--small);
	font-weight: 600;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--wp--preset--color--secondary);
}

.chc-signup__row {
	display: flex;
	flex-wrap: wrap;
	gap: 0.5rem;
}

.chc-signup__input {
	flex: 1 1 12rem;
	min-width: 0;
	padding: 0.85em 1em;
	font-family: inherit;
	font-size: var(--wp--preset--font-size--medium);
	color: var(--wp--preset--color--contrast);
	background: var(--wp--preset--color--base);
	border: 1px solid color-mix(in srgb, var(--wp--preset--color--contrast) 30%, transparent);
	border-radius: 2px;
}

.chc-signup__input:focus-visible {
	outline: 2px solid var(--wp--preset--color--primary);
	outline-offset: 1px;
}

.chc-signup__button {
	flex: 0 0 auto;
	cursor: pointer;
	border: 0;
}

/* ---------------------------------------------------------------------------
 * Sponsor wall — see blocks/sponsor-wall/.
 *
 * The whole point is that every logo occupies an identical cell regardless of its
 * intrinsic proportions. A fixed cell height plus object-fit: contain does that; without
 * it a wide wordmark dwarfs a stacked lockup and the grid stops reading as one set.
 * ------------------------------------------------------------------------ */
.chc-sponsor-wall__heading {
	margin: 0 0 var(--wp--preset--spacing--50);
	text-align: center;
}

.chc-sponsor-wall__level {
	margin: var(--wp--preset--spacing--50) 0 var(--wp--preset--spacing--30);
	text-align: center;
	font-size: var(--wp--preset--font-size--small);
	font-weight: 600;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	color: var(--wp--preset--color--secondary);
}

.chc-sponsor-wall__grid {
	list-style: none;
	margin: 0;
	padding: 0;
	display: grid;
	/* Two columns even on phones — one logo per row made the wall a very long scroll. */
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: var(--wp--preset--spacing--40);
	align-items: stretch;
}

@media (min-width: 48em) {
	.chc-sponsor-wall__grid {
		grid-template-columns: repeat(var(--chc-sponsor-columns, 3), minmax(0, 1fr));
	}
}

.chc-sponsor-wall__item {
	background-color: #ffffff;
	border-radius: 4px;
	border: 1px solid color-mix(in srgb, var(--wp--preset--color--secondary) 12%, transparent);
	display: flex;
	align-items: center;
	justify-content: center;
	min-height: 7rem;
	padding: var(--wp--preset--spacing--30);
}

.chc-sponsor-wall__link {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 100%;
	height: 100%;
	text-decoration: none;
}

.chc-sponsor-wall__img {
	max-width: 100%;
	max-height: 5rem;
	width: auto;
	height: auto;
	object-fit: contain;
}

.chc-sponsor-wall__name {
	text-align: center;
	font-size: var(--wp--preset--font-size--small);
	color: var(--wp--preset--color--secondary);
}

/*
 * Optional unifier for logos in clashing brand colours. Restores full colour on hover
 * and for anyone who prefers reduced motion not to hide information.
 */
.chc-sponsor-wall--grayscale .chc-sponsor-wall__img {
	filter: grayscale(100%);
	opacity: 0.75;
	transition: filter 0.2s ease, opacity 0.2s ease;
}

.chc-sponsor-wall--grayscale .chc-sponsor-wall__link:hover .chc-sponsor-wall__img,
.chc-sponsor-wall--grayscale .chc-sponsor-wall__link:focus-visible .chc-sponsor-wall__img {
	filter: grayscale(0);
	opacity: 1;
}

/* ---------------------------------------------------------------------------
 * Concert grid — see blocks/concert-grid/.
 * ------------------------------------------------------------------------ */
.chc-concert-grid__heading {
	margin: 0 0 var(--wp--preset--spacing--50);
}

.chc-concert-grid__list {
	list-style: none;
	margin: 0;
	padding: 0;
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
	gap: var(--wp--preset--spacing--50);
}

@media (min-width: 48em) {
	.chc-concert-grid__list {
		grid-template-columns: repeat(var(--chc-concert-columns, 3), minmax(0, 1fr));
	}
}

.chc-concert-grid__item > * + * {
	margin-top: 0.4em;
}

.chc-concert-grid__item {
	transition: transform 0.25s ease;
}

.chc-concert-grid__item:hover,
.chc-concert-grid__item:focus-within {
	transform: translateY(-4px);
}

.chc-concert-grid__media {
	position: relative;
	display: block;
	margin-bottom: var(--wp--preset--spacing--30);
	overflow: hidden;
	border-radius: 2px;
}

.chc-concert-grid__img,
.chc-concert-grid__placeholder {
	display: block;
	width: 100%;
	/* height:auto is required or the img's height attribute defeats aspect-ratio —
	   these imgs carry a custom class, so core's wp-image height:auto never matches. */
	height: auto;
	aspect-ratio: var(--chc-card-aspect, 16 / 9);
	object-fit: cover;
	transition: transform 0.4s ease;
}

/* Card artwork ratio per grid: wide is the default; square and portrait fill
   taller sections and stack better on phones. */
.chc-concert-grid--square {
	--chc-card-aspect: 1 / 1;
}

/* Folded 8.5x11 program cover proportions (5.5in x 8.5in). */
.chc-concert-grid--portrait {
	--chc-card-aspect: 11 / 17;
}

.chc-concert-grid__item:hover .chc-concert-grid__img,
.chc-concert-grid__item:focus-within .chc-concert-grid__img {
	transform: scale(1.04);
}

/*
 * The excerpt is supplementary on cards (the single page carries it in full),
 * so it lives as a hover/keyboard-focus reveal over the artwork rather than
 * padding out every card. Pointer-coarse devices simply never see it.
 */
.chc-concert-grid__reveal {
	position: absolute;
	inset: 0;
	display: flex;
	align-items: flex-end;
	padding: var(--wp--preset--spacing--40);
	font-size: var(--wp--preset--font-size--small);
	line-height: 1.45;
	color: #fff;
	background: linear-gradient(to top, rgba(10, 8, 8, 0.86) 0%, rgba(10, 8, 8, 0.45) 55%, rgba(10, 8, 8, 0) 100%);
	opacity: 0;
	transition: opacity 0.3s ease;
}

.chc-concert-grid__item:hover .chc-concert-grid__reveal,
.chc-concert-grid__item:focus-within .chc-concert-grid__reveal {
	opacity: 1;
}

/* Cards drift up as they enter the viewport, where the browser supports
   scroll-driven animations; everywhere else they are simply visible. */
@supports (animation-timeline: view()) {
	.chc-concert-grid__item {
		animation: chc-card-enter both;
		animation-timeline: view();
		animation-range: entry 0% entry 40%;
	}
}

@keyframes chc-card-enter {
	from {
		opacity: 0.2;
		transform: translateY(18px);
	}

	to {
		opacity: 1;
		transform: translateY(0);
	}
}

/*
 * Concerts with no surviving artwork get a typeset cover instead of a blank
 * tile: title centred in Prata on the surface tint, framed by a hairline —
 * the archive's paper-program era should read as intentional, not broken.
 */
.chc-concert-grid__placeholder {
	display: flex;
	align-items: center;
	justify-content: center;
	/* border-box, or the percentage padding stacks on top of the aspect ratio
	 * and these tiles come out taller than the artwork cards beside them. */
	box-sizing: border-box;
	padding: 8%;
	background: var(--wp--preset--color--surface);
	border: 1px solid color-mix(in srgb, var(--wp--preset--color--secondary) 18%, transparent);
	box-shadow: inset 0 0 0 6px var(--wp--preset--color--surface), inset 0 0 0 7px color-mix(in srgb, var(--wp--preset--color--secondary) 25%, transparent);
}

.chc-concert-grid__media:has(.chc-concert-grid__placeholder),
.chc-concert-grid__media:has(.chc-concert-grid__album) {
	text-decoration: none;
	color: var(--wp--preset--color--contrast);
}

.chc-concert-grid__placeholder-title {
	font-family: var(--wp--preset--font-family--heading);
	font-size: clamp(1rem, 1.4vw + 0.5rem, 1.4rem);
	line-height: 1.3;
	text-align: center;
	color: var(--wp--preset--color--contrast);
	text-wrap: balance;
}

/*
 * Square album art in a wide card: the cover keeps its full square beside a
 * typeset title panel — the placeholder treatment's sibling, so the CD-cover
 * era and the paper-program era read as one family.
 */
.chc-concert-grid__album {
	display: flex;
	width: 100%;
	aspect-ratio: var(--chc-card-aspect, 16 / 9);
}

.chc-concert-grid__album-art {
	flex: none;
	/* width:auto beats the img's width attribute so the square derives from
	 * the card height via the aspect ratio. */
	width: auto;
	height: 100%;
	aspect-ratio: 1;
	object-fit: cover;
}

.chc-concert-grid__album-panel {
	flex: 1;
	display: flex;
	align-items: center;
	justify-content: center;
	box-sizing: border-box;
	min-width: 0;
	padding: 6%;
	background: var(--wp--preset--color--surface);
	border: 1px solid color-mix(in srgb, var(--wp--preset--color--secondary) 18%, transparent);
	border-left: none;
	box-shadow: inset 0 0 0 6px var(--wp--preset--color--surface), inset 0 0 0 7px color-mix(in srgb, var(--wp--preset--color--secondary) 25%, transparent);
}

/*
 * Season sections (groupBySeason): a small-caps label with a hairline rule —
 * a wayfinding mark, not a heading competing with the cards.
 */
.chc-concert-grid__season-group {
	margin-top: var(--wp--preset--spacing--60);
}

.chc-concert-grid__season-group:first-of-type {
	margin-top: var(--wp--preset--spacing--50);
}

.chc-concert-grid__season-label {
	display: flex;
	align-items: center;
	gap: var(--wp--preset--spacing--30);
	margin: 0 0 var(--wp--preset--spacing--40);
	font-size: var(--wp--preset--font-size--small);
	font-weight: 600;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	color: var(--wp--preset--color--secondary);
}

.chc-concert-grid__season-label::after {
	content: "";
	flex: 1;
	border-top: 1px solid color-mix(in srgb, currentColor 30%, transparent);
}

.chc-concert-grid__title {
	margin: 0;
	font-size: var(--wp--preset--font-size--large);
}

/* Film cards: title as a quiet caption line, sized with the date eyebrow. */
.chc-concert-grid__title--small {
	font-family: var(--wp--preset--font-family--body);
	font-size: var(--wp--preset--font-size--small);
	font-weight: 600;
	letter-spacing: 0.02em;
}

.chc-concert-grid__title a {
	text-decoration: none;
	color: inherit;
}

.chc-concert-grid__title a:hover,
.chc-concert-grid__title a:focus {
	text-decoration: underline;
}

.chc-concert-grid__season,
.chc-concert-grid__excerpt {
	font-size: var(--wp--preset--font-size--small);
	color: var(--wp--preset--color--secondary);
}

/* Upcoming concerts — see blocks/upcoming-concerts/. */
.chc-upcoming__heading {
	margin: 0 0 var(--wp--preset--spacing--50);
	font-size: var(--wp--preset--font-size--xx-large);
}

.chc-upcoming__empty {
	margin: 0;
}

.chc-upcoming__list {
	list-style: none;
	margin: 0;
	padding: 0;
	display: grid;
	gap: var(--wp--preset--spacing--50);
}

.chc-upcoming__item > * + * {
	margin-top: 0.5em;
}

.chc-upcoming__image {
	display: block;
	margin-bottom: var(--wp--preset--spacing--30);
}

.chc-upcoming__image img {
	width: 100%;
	height: auto;
	aspect-ratio: 16 / 9;
	object-fit: cover;
}

/* A program cover standing in for the banner shows whole, at cover size —
 * not inflated to column width or cropped to 16:9. */
.chc-upcoming__image.is-portrait img {
	width: auto;
	max-width: min(18rem, 100%);
	aspect-ratio: 11 / 17;
	box-shadow: 0 1px 10px color-mix(in srgb, var(--wp--preset--color--contrast) 18%, transparent);
	border-radius: 2px;
}

.chc-upcoming__title {
	font-size: var(--wp--preset--font-size--x-large);
	margin: 0;
}

.chc-upcoming__title a {
	text-decoration: none;
	color: inherit;
}

.chc-upcoming__title a:hover,
.chc-upcoming__title a:focus {
	text-decoration: underline;
}

.chc-upcoming__venue {
	color: var(--wp--preset--color--secondary);
}

/*
 * The band adapts to how much has been announced. Three or more: the grid.
 * Two: a balanced pair. One: a spotlight — cover beside the full details,
 * treating the lone announcement as a feature rather than a stranded card.
 */
@media (min-width: 48em) {
	.chc-upcoming__list {
		grid-template-columns: repeat(auto-fit, minmax(18rem, 1fr));
	}

	.chc-upcoming--two .chc-upcoming__list {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}

	.chc-upcoming--one .chc-upcoming__list {
		grid-template-columns: 1fr;
	}

	.chc-upcoming--one .chc-upcoming__item {
		display: grid;
		grid-template-columns: minmax(13rem, 17rem) 1fr;
		column-gap: var(--wp--preset--spacing--60);
		align-items: start;
	}

	.chc-upcoming--one .chc-upcoming__image {
		grid-column: 1;
		grid-row: 1 / span 8;
		margin-bottom: 0;
	}

	.chc-upcoming--one .chc-upcoming__image.is-portrait img {
		max-width: 100%;
	}

	.chc-upcoming--one .chc-upcoming__item > :not(.chc-upcoming__image) {
		grid-column: 2;
	}

	.chc-upcoming--one .chc-upcoming__title {
		font-size: var(--wp--preset--font-size--xx-large);
	}
}

/* Concert details panel — see blocks/concert-details/. */
.chc-concert-details {
	background: var(--wp--preset--color--surface);
	padding: var(--wp--preset--spacing--50);
}

/*
 * After the performance the details step back: a small-caps byline where the
 * panel was, with the still-useful actions (program, recording) as pills.
 */
.chc-concert-details--past {
	background: none;
	padding: 0;
}

.chc-concert-details__byline {
	margin: 0;
	font-size: var(--wp--preset--font-size--small);
	font-weight: 600;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	color: var(--wp--preset--color--secondary);
}

.chc-concert-details__actions {
	display: flex;
	flex-wrap: wrap;
	gap: 0.5rem 1.75rem;
	margin-top: var(--wp--preset--spacing--30);
}

.chc-concert-details__action {
	position: relative;
	display: inline-flex;
	align-items: center;
	gap: 0.45em;
	padding: 0.2em 0;
	font-size: var(--wp--preset--font-size--medium);
	color: var(--wp--preset--color--contrast);
	text-decoration: none;
}

.chc-concert-details__action svg {
	color: var(--wp--preset--color--primary);
	flex: none;
}

.chc-concert-details__action::after {
	content: "";
	position: absolute;
	left: 0;
	right: 100%;
	bottom: 0;
	border-bottom: 2px solid var(--wp--preset--color--primary);
	transition: right 0.25s ease;
}

.chc-concert-details__action:hover::after,
.chc-concert-details__action:focus-visible::after {
	right: 0;
}

/*
 * Concert-to-concert navigation — see blocks/concert-nav/. A quiet wayfinding
 * row: it should be findable when wanted and invisible when not.
 */
.chc-concert-nav {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	justify-content: space-between;
	gap: var(--wp--preset--spacing--30) var(--wp--preset--spacing--40);
	font-size: var(--wp--preset--font-size--small);
}

.chc-concert-nav__link {
	display: grid;
	gap: 0.2em;
	max-width: 18rem;
	text-decoration: none;
}

.chc-concert-nav__link--next {
	text-align: right;
}

.chc-concert-nav__label,
.chc-concert-nav__season {
	font-weight: 600;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	color: var(--wp--preset--color--secondary);
}

.chc-concert-nav__title {
	font-family: var(--wp--preset--font-family--heading);
	font-size: var(--wp--preset--font-size--medium);
	color: var(--wp--preset--color--contrast);
}

.chc-concert-nav__link:hover .chc-concert-nav__title,
.chc-concert-nav__link:focus-visible .chc-concert-nav__title {
	text-decoration: underline;
	text-underline-offset: 3px;
}

.chc-concert-nav__season {
	text-decoration: none;
}

.chc-concert-nav__season:hover,
.chc-concert-nav__season:focus-visible {
	text-decoration: underline;
	text-underline-offset: 3px;
}

/* Anchored season groups land below the sticky-free header with air to spare. */
.chc-concert-grid__season-group {
	scroll-margin-top: var(--wp--preset--spacing--50);
}

/*
 * Within-section navigation — see blocks/section-nav/. The main nav stays
 * flat; a page family gets this instead. In the flow on narrow screens,
 * out in the right-hand gutter beside the content on wide ones.
 */
main {
	position: relative;
}

.chc-section-nav {
	margin-bottom: var(--wp--preset--spacing--40);
	font-size: var(--wp--preset--font-size--small);
}

.chc-section-nav__list {
	list-style: none;
	margin: 0;
	padding: 0;
	display: grid;
	gap: 0.4em;
}

/* Hierarchy carried by type alone: the section root in Prata, its pages in
 * the body sans beneath — an outline, not a boxed widget. */
.chc-section-nav__item.is-root {
	font-family: var(--wp--preset--font-family--heading);
	font-size: var(--wp--preset--font-size--medium);
	margin-bottom: 0.15em;
}

.chc-section-nav__item a {
	text-decoration: none;
	color: var(--wp--preset--color--contrast);
}

.chc-section-nav__item a:hover,
.chc-section-nav__item a:focus-visible {
	text-decoration: underline;
	text-underline-offset: 3px;
}

.chc-section-nav__item.is-current > span {
	font-weight: 600;
	color: var(--wp--preset--color--primary);
}

@media (min-width: 1260px) {
	.chc-section-nav {
		position: absolute;
		top: 0;
		right: calc(50% + 368px + var(--wp--preset--spacing--60));
		width: min(15rem, calc(50vw - 368px - var(--wp--preset--spacing--60) - var(--wp--preset--spacing--50)));
		margin-bottom: 0;
	}
}

.chc-concert-details__list {
	margin: 0;
	display: grid;
	gap: var(--wp--preset--spacing--30);
}

.chc-concert-details__row {
	display: grid;
	gap: 0.15em;
}

.chc-concert-details__row dt {
	font-size: var(--wp--preset--font-size--small);
	font-weight: 600;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	color: var(--wp--preset--color--secondary);
}

.chc-concert-details__row dd {
	margin: 0;
	/* Self-clamped: the `large` preset is fluid and reaches 36px on desktop,
	 * which set panel dates competing with the page title. */
	font-size: clamp(1.125rem, 1rem + 0.5vw, 1.4rem);
	font-family: var(--wp--preset--font-family--heading);
}

/* Performance list inside the concert details panel. */
.chc-performances {
	list-style: none;
	margin: 0;
	padding: 0;
	display: grid;
	gap: 0.4em;
}

.chc-performances__item {
	display: block;
}

/* A date is one phrase; wrap between performances, never inside one. */
.chc-performances__item time {
	white-space: nowrap;
}

.chc-performances__time::before {
	content: " · ";
}

.chc-performances__venue {
	display: block;
	font-family: var(--wp--preset--font-family--body);
	font-size: var(--wp--preset--font-size--small);
	color: var(--wp--preset--color--secondary);
}

.chc-concert-details__time::before {
	content: " · ";
}

.chc-concert-details__address {
	display: block;
	font-family: var(--wp--preset--font-family--body);
	font-size: var(--wp--preset--font-size--medium);
	color: var(--wp--preset--color--secondary);
}

.chc-concert-details__cta {
	margin-top: var(--wp--preset--spacing--40);
}

/* Columns as room allows — auto-fit rather than a rigid pair, so a long
   Prata date never gets pinched into wrapping mid-phrase. */
@media (min-width: 40em) {
	.chc-concert-details__list {
		grid-template-columns: repeat(auto-fit, minmax(min(100%, 18rem), 1fr));
		gap: var(--wp--preset--spacing--40);
	}
}

/*
 * Buttons rendered as outline rather than solid. Registered as a block style in
 * functions.php so editors can pick it from the block toolbar.
 */
.wp-block-button.is-style-chc-outline .wp-block-button__link {
	background-color: transparent;
	color: var(--wp--preset--color--primary);
	box-shadow: inset 0 0 0 2px currentColor;
}

.wp-block-button.is-style-chc-outline .wp-block-button__link:hover,
.wp-block-button.is-style-chc-outline .wp-block-button__link:focus {
	background-color: var(--wp--preset--color--primary);
	color: var(--wp--preset--color--base);
}

/* ------------------------------------------------------------------------
 * Inline SVG logo — fill is currentColor, so it takes the header's text color
 * and re-tints itself automatically under every style variation.
 * ------------------------------------------------------------------------ */
.chc-logo-link {
	display: block;
	color: inherit;
	line-height: 0;
}

.chc-logo {
	width: 104px;
	height: auto;
	display: block;
}

/* ------------------------------------------------------------------------
 * Wide-plus sections: on large screens, sections carrying .chc-wide-plus let
 * their alignwide children stretch beyond the global wide size — width
 * variation between sections is part of the homepage rhythm.
 * ------------------------------------------------------------------------ */
@media (min-width: 90rem) {
	.chc-wide-plus.is-layout-constrained > .alignwide {
		max-width: min(88rem, 100%);
	}
}

/* Listening grid: the watch link under a card title. */
.chc-concert-grid__watch {
	margin: 0;
	font-size: var(--wp--preset--font-size--small);
}

/* Between-seasons announcement line in the combined homepage concerts section. */
.chc-upcoming--compact .chc-upcoming__empty {
	margin: 0;
	font-size: var(--wp--preset--font-size--x-large);
	font-family: var(--wp--preset--font-family--heading);
	line-height: 1.3;
}

/* Gentle motion for interactive elements site-wide. */
.wp-element-button,
.wp-block-button__link {
	transition: background-color 0.2s ease, color 0.2s ease, transform 0.15s ease;
}

.wp-element-button:hover,
.wp-block-button__link:hover {
	transform: translateY(-1px);
}

/* ------------------------------------------------------------------------
 * Header: logo-only identity (the mark carries the wordmark), one row, with
 * a hairline base and an animated underline on navigation links.
 * ------------------------------------------------------------------------ */
.chc-header {
	border-bottom: 1px solid color-mix(in srgb, currentColor 12%, transparent);
}

.chc-header .chc-logo {
	width: clamp(120px, 12vw, 170px);
}

.chc-logo-link {
	transition: opacity 0.2s ease;
}

.chc-logo-link:hover {
	opacity: 0.75;
}

.chc-nav .wp-block-navigation-item__content {
	position: relative;
	padding-bottom: 2px;
}

.chc-nav .wp-block-navigation-item__content::after {
	content: "";
	position: absolute;
	left: 0;
	right: 100%;
	bottom: 0;
	border-bottom: 2px solid var(--wp--preset--color--primary);
	transition: right 0.25s ease;
}

.chc-nav .wp-block-navigation-item__content:hover::after,
.chc-nav .wp-block-navigation-item__content:focus-visible::after {
	right: 0;
}

/* The Tickets item exists for the mobile overlay only — the desktop row
 * already has the standalone Tickets button beside the nav. */
.chc-nav .chc-nav__tickets {
	display: none;
}

/* Between the phone overlay (below 600px) and a roomy desktop, the full menu
 * row plus the Tickets button overflows and wraps; tighter tracking keeps the
 * header to one line through the tablet range. */
@media (min-width: 600px) and (max-width: 1023px) {
	.chc-header .chc-logo {
		width: 104px;
	}

	.chc-nav .wp-block-navigation-item__content {
		font-size: var(--wp--preset--font-size--small);
	}

	.chc-nav .wp-block-navigation__container {
		gap: var(--wp--preset--spacing--30);
	}
}

/* ------------------------------------------------------------------------
 * Mobile menu overlay. Core ships a bare white sheet with small links; give
 * it the site's ground, display-size Prata links, and finger-size targets.
 * ------------------------------------------------------------------------ */
.chc-nav .wp-block-navigation__responsive-container.is-menu-open {
	background-color: var(--wp--preset--color--base);
	padding: var(--wp--preset--spacing--50) var(--wp--preset--spacing--50) var(--wp--preset--spacing--60);
}

.chc-nav .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content {
	align-items: flex-start;
	padding-top: var(--wp--preset--spacing--60);
}

.chc-nav .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__container {
	align-items: flex-start;
	gap: 0.4em;
}

.chc-nav .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item__content {
	font-family: var(--wp--preset--font-family--heading);
	font-size: clamp(1.75rem, 8vw, 2.25rem);
	line-height: 1.3;
	padding: 0.2em 0;
}

.chc-nav .wp-block-navigation__responsive-container.is-menu-open .chc-nav__tickets {
	display: block;
	margin-top: var(--wp--preset--spacing--40);
}

.chc-nav .wp-block-navigation__responsive-container.is-menu-open .chc-nav__tickets .wp-block-navigation-item__content {
	font-family: inherit;
	font-size: var(--wp--preset--font-size--medium);
	background-color: var(--wp--preset--color--primary);
	color: var(--wp--preset--color--base);
	padding: 0.75em 1.8em;
	border-radius: 2px;
}

.chc-nav .wp-block-navigation__responsive-container-close {
	padding: var(--wp--preset--spacing--40);
}

.chc-nav .wp-block-navigation__responsive-container-close svg {
	width: 28px;
	height: 28px;
}

/* Let the overlay's links rise in as it fades; the reduced-motion kill
 * switch above disables this wholesale. */
.chc-nav .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item {
	animation: chc-load-fade 0.45s ease both;
}

.chc-nav .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item:nth-child(2) { animation-delay: 0.05s; }
.chc-nav .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item:nth-child(3) { animation-delay: 0.1s; }
.chc-nav .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item:nth-child(4) { animation-delay: 0.15s; }
.chc-nav .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item:nth-child(5) { animation-delay: 0.2s; }
.chc-nav .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item:nth-child(6) { animation-delay: 0.25s; }
.chc-nav .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item:nth-child(7) { animation-delay: 0.3s; }


/* Platforms band: plain text links with the nav's sliding underline — the
   pill chrome dated the band; the names carry it fine on their own.
   .chc-textlink is the same treatment as a standalone class for links
   rendered outside a buttons block (album streaming links, etc.). */
.chc-textlink {
	position: relative;
	padding: 0.2em 0;
	color: var(--wp--preset--color--contrast);
	font-size: var(--wp--preset--font-size--medium);
	font-family: var(--wp--preset--font-family--heading);
	text-decoration: none;
}

.chc-textlink::after {
	content: "";
	position: absolute;
	left: 0;
	right: 100%;
	bottom: 0;
	border-bottom: 2px solid var(--wp--preset--color--primary);
	transition: right 0.25s ease;
}

.chc-textlink:hover::after,
.chc-textlink:focus-visible::after {
	right: 0;
}

.chc-platforms .wp-block-button__link {
	position: relative;
	background: none;
	border: none;
	border-radius: 0;
	padding: 0.2em 0;
	color: var(--wp--preset--color--contrast);
	font-size: var(--wp--preset--font-size--medium);
	font-family: var(--wp--preset--font-family--heading);
}

.chc-platforms .wp-block-button__link:hover {
	background: none;
	color: var(--wp--preset--color--contrast);
	transform: none;
}

.chc-platforms .wp-block-button__link::after {
	content: "";
	position: absolute;
	left: 0;
	right: 100%;
	bottom: 0;
	border-bottom: 2px solid var(--wp--preset--color--primary);
	transition: right 0.25s ease;
}

.chc-platforms .wp-block-button__link:hover::after,
.chc-platforms .wp-block-button__link:focus-visible::after {
	right: 0;
}

.chc-platforms .wp-block-buttons {
	gap: var(--wp--preset--spacing--40) var(--wp--preset--spacing--50);
}

/* ------------------------------------------------------------------------
 * Album list — see blocks/album-list/. Record-bin cards: a big square cover
 * with the details beneath, in a grid that fills a wide screen and stacks
 * to one column on phones.
 * ------------------------------------------------------------------------ */
.chc-album-list {
	list-style: none;
	margin: 0;
	padding: 0;
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(min(19rem, 100%), 1fr));
	gap: var(--wp--preset--spacing--50) var(--wp--preset--spacing--50);
}

.chc-album-list__item {
	display: flex;
	flex-direction: column;
	gap: var(--wp--preset--spacing--30);
}

.chc-album-list__cover-link {
	display: block;
}

.chc-album-list__cover {
	display: block;
	width: 100%;
	height: auto;
	aspect-ratio: 1;
	object-fit: cover;
	border-radius: 2px;
	box-shadow: 0 1px 10px color-mix(in srgb, var(--wp--preset--color--contrast) 20%, transparent);
	transition: transform 0.3s ease;
}

.chc-album-list__item:hover .chc-album-list__cover,
.chc-album-list__item:focus-within .chc-album-list__cover {
	transform: translateY(-3px);
}

.chc-album-list__body {
	display: grid;
	gap: var(--wp--preset--spacing--20);
}

/* Compact sans title, sized with the concert cards below — the cover art
 * usually carries the title already, so the text line is a caption, not a
 * headline. */
.chc-album-list__title {
	margin: 0;
	font-family: var(--wp--preset--font-family--body);
	font-size: var(--wp--preset--font-size--medium);
	font-weight: 600;
	line-height: 1.35;
}

.chc-album-list__title a {
	color: var(--wp--preset--color--contrast);
	text-decoration: none;
}

.chc-album-list__title a:hover,
.chc-album-list__title a:focus-visible {
	text-decoration: underline;
	text-underline-offset: 4px;
}

.chc-album-list__meta,
.chc-album-list__blurb {
	margin: 0;
}

.chc-album-list__blurb {
	font-size: var(--wp--preset--font-size--small);
	color: var(--wp--preset--color--secondary);
}

.chc-album-list__links {
	margin: 0;
	display: flex;
	flex-wrap: wrap;
	gap: 0.2em var(--wp--preset--spacing--40);
}

.chc-album-list__links .chc-textlink {
	font-family: var(--wp--preset--font-family--body);
	font-size: var(--wp--preset--font-size--small);
}

/* Album single — see blocks/album-details/ and templates/single-chc_album.html. */
.chc-album-cover img {
	border-radius: 2px;
	box-shadow: 0 2px 14px color-mix(in srgb, var(--wp--preset--color--contrast) 20%, transparent);
}

.chc-album-details {
	display: grid;
	gap: var(--wp--preset--spacing--30);
}

.chc-album-details__release,
.chc-album-details__links {
	margin: 0;
}

.chc-album-details__release a {
	color: inherit;
}

.chc-album-details__links {
	display: flex;
	flex-wrap: wrap;
	gap: 0.2em var(--wp--preset--spacing--40);
}

.chc-album-details__tracks {
	margin: var(--wp--preset--spacing--30) 0 0;
	padding: 0;
	list-style: none;
	counter-reset: chc-track;
	display: grid;
	gap: 0.45em;
}

.chc-album-details__track {
	display: flex;
	align-items: baseline;
	gap: 0.6em;
	counter-increment: chc-track;
}

/* Flex display swallows list markers, so the number is a counter instead. */
.chc-album-details__track::before {
	content: counter(chc-track, decimal-leading-zero);
	flex: none;
	min-width: 2ch;
	color: var(--wp--preset--color--secondary);
	font-size: var(--wp--preset--font-size--small);
	font-variant-numeric: tabular-nums;
}

.chc-album-details__track-title {
	font-family: var(--wp--preset--font-family--heading);
}

.chc-album-details__track-composer {
	color: var(--wp--preset--color--secondary);
	font-size: var(--wp--preset--font-size--small);
}

.chc-album-details__track-duration {
	margin-left: auto;
	color: var(--wp--preset--color--secondary);
	font-size: var(--wp--preset--font-size--small);
	font-variant-numeric: tabular-nums;
}

@supports (animation-timeline: view()) {
	.chc-sponsor-wall__item {
		animation: chc-card-enter both;
		animation-timeline: view();
		animation-range: entry 0% entry 35%;
	}
}

/* ------------------------------------------------------------------------
 * Print-style section divider: hairlines meeting a fleuron, like a program
 * book. The lines draw outward as the divider scrolls into view.
 * ------------------------------------------------------------------------ */
.chc-divider {
	display: none; /* shown by the Print Editorial variation */
	align-items: center;
	gap: var(--wp--preset--spacing--40);
	margin: 0 auto;
	max-width: var(--wp--style--global--content-size);
	color: var(--wp--preset--color--secondary);
	font-size: 1.15rem;
	line-height: 1;
}

.chc-divider::before,
.chc-divider::after {
	content: "";
	flex: 1;
	border-top: 1px solid color-mix(in srgb, currentColor 45%, transparent);
	transform-origin: center;
}

@supports (animation-timeline: view()) {
	.chc-divider::before,
	.chc-divider::after {
		animation: chc-divider-draw both;
		animation-timeline: view();
		animation-range: entry 0% entry 60%;
	}
}

@keyframes chc-divider-draw {
	from { transform: scaleX(0); }
	to { transform: scaleX(1); }
}

/* ------------------------------------------------------------------------
 * Load-in: the hero settles in as a stagger — eyebrow, then title, then
 * image. Runs once on page load; reduced-motion zeroes it like everything.
 * ------------------------------------------------------------------------ */
.chc-load-fade {
	animation: chc-load-fade 0.7s ease-out both;
}

.chc-load-fade--2 {
	animation-delay: 0.12s;
}

.chc-load-fade--3 {
	animation-delay: 0.24s;
}

@keyframes chc-load-fade {
	from {
		opacity: 0;
		transform: translateY(14px);
	}

	to {
		opacity: 1;
		transform: translateY(0);
	}
}

/* ------------------------------------------------------------------------
 * Print-editorial lane (the light theme's committed direction): structure
 * comes from rules and ornaments on one paper ground, not tinted bands.
 * ------------------------------------------------------------------------ */
/* Default (modern) lane: color blocks carry structure. The Print Editorial
   variation re-enables the ruled/ornamented treatment via its own CSS. */
.chc-rule-band {
	background-color: var(--wp--preset--color--surface);
}

.chc-print-panel {
	background-color: var(--wp--preset--color--surface);
	border-radius: 4px;
}

/* Drop caps are a Print Editorial gesture; the modern default suppresses them. */
.entry-content p.has-drop-cap:not(:focus)::first-letter {
	float: none;
	font-size: inherit;
	font-family: inherit;
	padding: 0;
	color: inherit;
	line-height: inherit;
}

/* ------------------------------------------------------------------------
 * Footer, set in the print lane: paper ground, a fleuron divider on top,
 * small-caps column heads, and a hairline above the legal line.
 * ------------------------------------------------------------------------ */
.chc-footer {
	background-color: var(--wp--preset--color--surface);
}

.chc-footer .wp-block-site-title a {
	text-decoration: none;
	color: inherit;
}

.chc-footer__legal {
	margin-top: var(--wp--preset--spacing--50);
	padding-top: var(--wp--preset--spacing--40);
	border-top: 1px solid color-mix(in srgb, var(--wp--preset--color--secondary) 30%, transparent);
	color: var(--wp--preset--color--secondary);
}

/* ------------------------------------------------------------------------
 * Viewport entrances: the fast fade-and-rise the hero uses on load also
 * greets section heads, the film embed, the platform row, and the signup
 * panel as they scroll into view. Same keyframes, same restraint.
 * ------------------------------------------------------------------------ */
@supports (animation-timeline: view()) {
	.entry-content > * > h2,
	.entry-content > * > * > h2,
	.chc-upcoming__empty,
	.entry-content .wp-block-embed,
	.chc-platforms .wp-block-buttons,
	.chc-print-panel {
		animation: chc-load-fade 1ms both;
		animation-timeline: view();
		animation-range: entry 0% entry 35%;
	}
}
