/*
 * Shared structural chrome: header/nav, footer, containers, cards, buttons,
 * and grid utilities reused across every page template. Design tokens live
 * in tokens.css; this file is layout/component shape only.
 */

*,
*::before,
*::after {
	box-sizing: border-box;
}

/*
 * The reset above never touched body's own box - browsers apply an
 * unconditional 8px margin to <body> by default (part of the UA
 * stylesheet, independent of any theme CSS), which was showing up as a
 * gap above the header/logo/nav on every page.
 */
html,
body {
	margin: 0;
	padding: 0;
}

img {
	max-width: 100%;
	display: block;
}

a {
	color: inherit;
	text-decoration: none;
}

/*
 * 1080px is the *content* width - the gutter sits outside it, so the
 * max-width has to account for both sides of the padding (everything is
 * border-box per the reset above). Hence the gutter as its own custom
 * property rather than repeating the clamp() in the calc().
 */
.container {
	--gutter: clamp(20px, 6vw, 100px);
	max-width: calc(1080px + var(--gutter) * 2);
	margin-inline: auto;
	padding-inline: var(--gutter);
}

/* Header */

.site-header {
	position: sticky;
	top: 0;
	z-index: 10;
	display: flex;
	align-items: flex-start;
	justify-content: space-between;
	gap: var(--space-md);
	padding-block: 40px var(--space-sm);
	padding-inline: clamp(20px, 6vw, 100px);
	opacity: 1;
	filter: blur(0px);
	transition: opacity 0.5s ease, filter 0.5s ease;
}

/*
 * Toggled by assets/js/header-scroll.js on scroll direction - fades and
 * blurs out scrolling down (away from the top), fades and un-blurs back in
 * scrolling up. Stays fully visible near the very top regardless of
 * direction so it doesn't flicker on tiny scroll jitters.
 */
.site-header--hidden {
	opacity: 0;
	filter: blur(10px);
	pointer-events: none;
}

.site-branding img {
	width: 106px;
	height: auto;
}

/*
 * The Figma design keeps the nav bar itself compact but leaves ~240px of
 * clear space between the top of the viewport and wherever a page's own
 * content begins (measured to the content container, not the heading text)
 * - not a tall sticky header, which would eat viewport on every scroll.
 * .site-header renders at ~101px (40px top + 10px bottom padding + the
 * 51px logo, its tallest child, top-aligned against the nav via
 * align-items: flex-start) so the remaining ~139px lives here instead.
 */
.site-main {
	padding-top: 139px;
}

.primary-menu {
	display: flex;
	gap: var(--space-sm);
	list-style: none;
	margin: 0;
	padding: 0;
	font-family: var(--font-cormorant);
	font-weight: 700;
	font-size: 0.75rem;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	text-shadow: 0 0 1px var(--color-white);
}

.primary-menu .current-menu-item > a {
	text-shadow: 0 0 4px var(--color-white);
}

/* Footer */

.site-footer {
	background-color: var(--color-surface);
	margin-top: 270px;
}

.site-footer__inner {
	display: grid;
	grid-template-columns: 1fr;
	gap: var(--space-md);
	padding-block: var(--space-lg);
}

.site-footer__links {
	display: flex;
	gap: var(--space-lg);
}

.site-footer__links ul {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: var(--space-sm);
	font-family: var(--font-mono);
	font-size: var(--text-mono);
	letter-spacing: 0.08em;
	text-transform: uppercase;
}

.site-footer__social {
	display: flex;
	gap: var(--space-sm);
}

.site-footer__legal ul {
	list-style: none;
	margin: 0 0 var(--space-sm);
	padding: 0;
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-sm) var(--space-md);
	font-family: var(--font-mono);
	font-size: var(--text-mono);
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--color-text-secondary);
}

.site-footer__legal p {
	font-family: var(--font-mono);
	font-size: var(--text-mono);
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--color-text-secondary);
}

@media (min-width: 768px) {
	.site-footer__inner {
		grid-template-columns: 1fr auto;
		grid-template-areas:
			"links   brand"
			"social  brand"
			"legal   legal";
	}
	.site-footer__links { grid-area: links; }
	.site-footer__social { grid-area: social; }
	.site-footer__brand { grid-area: brand; }
	.site-footer__legal { grid-area: legal; }
}

/* Cards */

.card {
	background-color: var(--color-surface);
	box-shadow: 0 0 10px 0 #5d5d5d;
	padding: var(--space-md);
}

/* Buttons */

.button {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	background-color: var(--color-text);
	color: var(--color-bg);
	font-family: var(--font-cormorant);
	font-weight: 700;
	font-size: 1.125rem;
	letter-spacing: 0.03em;
	line-height: 1;
	text-shadow: 0 0 2px #909090;
	padding: 14px 24px;
	filter: drop-shadow(0 0 5px #5d5d5d);
	border: none;
	cursor: pointer;
}

.button--secondary {
	background-color: transparent;
	color: var(--color-text);
	border: 1px solid var(--color-text);
	filter: none;
}

/*
 * Media carousel: a full-bleed overlay-card slider, shared by the Film
 * Guide's Team Picks strip and the Blog index's Featured Posts strip (same
 * visual recipe - big background image + a dark overlay panel bottom-left -
 * just different inner content per template part). Horizontal scroll-snap
 * carries the base interaction with zero JS; carousel.js progressively
 * enhances the prev/next arrows to advance by one card.
 */

.carousel-wrap {
	position: relative;
}

.carousel-nav {
	display: flex;
	justify-content: flex-end;
	gap: var(--space-sm);
	margin-bottom: var(--space-sm);
}

.carousel-arrow {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 32px;
	height: 32px;
	background: transparent;
	border: 1px solid var(--color-text-secondary);
	border-radius: 50%;
	color: var(--color-text);
	font-family: var(--font-clarendon);
	font-size: 1.1rem;
	line-height: 1;
	cursor: pointer;
}

.carousel-track {
	display: flex;
	gap: var(--space-sm);
	overflow-x: auto;
	scroll-snap-type: x mandatory;
}

.featured-card {
	position: relative;
	flex: 0 0 90%;
	scroll-snap-align: start;
	aspect-ratio: 16 / 9;
	overflow: hidden;
	background-color: #000;
}

.featured-card__media {
	position: absolute;
	inset: 0;
}

.featured-card__media img {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.featured-card__body {
	position: relative;
	max-width: 28em;
	margin: var(--space-lg);
	padding: var(--space-md);
	background-color: rgba(35, 35, 35, 0.9);
}

.featured-card__tags {
	display: flex;
	gap: var(--space-xs);
	margin-bottom: var(--space-sm);
}

.featured-card__meta {
	margin: 0 0 var(--space-sm);
	color: var(--color-text-secondary);
}

.featured-card__actions {
	display: flex;
	gap: var(--space-sm);
	margin-top: var(--space-sm);
}

.featured-card--team-pick .featured-card__body {
	position: absolute;
	left: 35px;
	bottom: 35px;
	display: flex;
	flex-direction: column;
	width: min(360px, calc(100% - 70px));
	max-width: none;
	aspect-ratio: 1;
	margin: 0;
	overflow: hidden;
}

.featured-card--team-pick .featured-card__actions {
	margin-top: auto;
}

.featured-card--team-pick .featured-card__eyebrow {
	margin: 0 0 14px;
	font-family: var(--font-cormorant);
	font-size: 16px;
	font-weight: 700;
	line-height: 1.5;
	letter-spacing: 0.08em;
	text-transform: uppercase;
}

.featured-card--team-pick .featured-card__eyebrow + h2 {
	margin-top: 0;
}

.featured-card--team-pick .featured-card__actions .button {
	width: auto;
}

.carousel-wrap--team-picks .carousel-track {
	position: relative;
	display: grid;
	overflow: visible;
	scroll-snap-type: none;
}

.carousel-wrap--team-picks .featured-card {
	grid-area: 1 / 1;
	width: 100%;
	flex-basis: 100%;
	aspect-ratio: 1080 / 625;
	box-shadow: 0 0 10px #5d5d5d;
	visibility: hidden;
	opacity: 0;
}

.carousel-wrap--team-picks .featured-card:first-child {
	visibility: visible;
	opacity: 1;
}

.carousel-wrap--team-picks .carousel-nav {
	min-height: 33px;
}

.carousel-wrap--team-picks .carousel-arrow {
	width: 23px;
	height: 33px;
	padding: 0;
	border: 0;
	border-radius: 0;
}

.carousel-wrap--team-picks .carousel-arrow img {
	width: 23px;
	height: 33px;
	max-width: none;
}

.schedule-page {
	overflow-x: clip;
}

/* Schedule / film / event cards */

.schedule-card__media {
	/* Rendered as an <a> in the card template parts, so needs an explicit
	   block display for the aspect-ratio/margins below to apply. */
	display: block;
	aspect-ratio: 4 / 3;
	background-color: #000;
	/* Bleeds out of .card's own padding so the image sits edge-to-edge on
	   the top/left/right, matching the Figma cards - only the bottom stays
	   inset, as the 32px gap to the title below. */
	margin: calc(var(--space-md) * -1) calc(var(--space-md) * -1) 32px;
	overflow: hidden;
}

/*
 * h3 keeps the browser's default ~1em top margin, which would collapse
 * against the media's bottom margin above and make that 32px gap depend on
 * the heading's font-size rather than the design value. Zeroed so the gap
 * is exactly what .schedule-card__media declares.
 */
.schedule-card > h3,
.blog-card > h3 {
	margin-top: 0;
}

.schedule-card__media img {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.schedule-card__media--placeholder {
	background: linear-gradient( 135deg, var(--color-surface), var(--color-bg) );
}

.schedule-card__tags {
	display: flex;
	gap: var(--space-xs);
	margin-block: var(--space-sm);
	overflow-x: auto;
	scrollbar-width: none;
	color: #888;
}

.schedule-card__tags::-webkit-scrollbar {
	display: none;
}

.schedule-card__tags .tag {
	flex-shrink: 0;
	white-space: nowrap;
}

.schedule-card__meta {
	margin: 0 0 var(--space-sm);
	color: #888;
}

.schedule-card__meta div {
	display: flex;
	gap: var(--space-sm);
}

.schedule-card__meta dt {
	color: inherit;
	min-width: 6em;
}

.schedule-card__meta dd {
	margin: 0;
}

.schedule-card__when p {
	display: flex;
	align-items: center;
	gap: var(--space-xs);
	margin: 0 0 var(--space-xs);
	color: #dbdbdb;
	font-family: var(--font-cormorant);
	font-size: 18px;
	font-weight: 700;
	letter-spacing: 0.03em;
	line-height: 1.3;
}

.schedule-card__when p:last-child {
	margin-bottom: 0;
}

.schedule-card__when-icon {
	flex: 0 0 23px;
	width: 23px;
	height: 21px;
}

.schedule-card__actions {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 20px;
	margin-top: auto;
	padding-top: 50px;
}

.schedule-card {
	display: flex;
	flex-direction: column;
	padding-bottom: 27px;
}

.schedule-card__actions .button {
	width: auto;
}

/* Hero */

.hero {
	text-align: center;
	padding-block: var(--space-lg);
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--space-sm);
}

.hero p {
	max-width: 40em;
	color: var(--color-text-secondary);
}

.hero__logo {
	width: min(517px, 80vw);
	height: auto;
	margin-bottom: var(--space-sm);
}

.section-heading {
	display: block;
	height: auto;
	margin-bottom: var(--space-md);
}

/* Homepage module composition */

.home-page {
	margin-top: -139px;
}

.home-hero {
	min-height: 1080px;
	padding-top: 150px;
	display: flex;
	flex-direction: column;
	align-items: center;
	text-align: center;
}

.home-hero__logo {
	width: min(760px, 82vw);
	height: auto;
	margin-inline: auto;
}

.home-hero__copy {
	max-width: 720px;
	margin-top: 90px;
}

.home-hero__copy h1 {
	max-width: 540px;
	margin: 0 auto var(--space-md);
}

.home-hero__copy p {
	margin: 0;
	color: var(--color-text-secondary);
}

.home-hero__media {
	width: 100%;
	margin: 110px 0 0;
	aspect-ratio: 16 / 7;
	border: 1px solid var(--color-text-secondary);
	border-radius: 20px;
	box-shadow: 0 0 10px rgba(255, 255, 255, 0.55);
	overflow: hidden;
}

.home-hero__image {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.home-section {
	margin-top: 140px;
}

.home-section__heading {
	display: flex;
	align-items: flex-end;
	justify-content: space-between;
	gap: var(--space-md);
}

.home-section__all {
	margin-bottom: var(--space-md);
	text-decoration: underline;
}

.home-featured .carousel-nav {
	margin-top: calc((32px + var(--space-sm)) * -1);
}

.home-featured .featured-card {
	flex-basis: min(90%, 920px);
}

.home-sponsors {
	margin-top: 120px;
	overflow: hidden;
	text-align: center;
}

.home-sponsors h2 {
	margin-bottom: var(--space-lg);
}

.home-sponsors .sponsor-row {
	flex-wrap: nowrap;
	justify-content: flex-start;
	width: max-content;
	min-width: 100%;
	padding-inline: var(--space-lg);
}

.festival-guide-grid .card,
.ticket-tier,
.promo-card {
	display: flex;
	flex-direction: column;
	min-height: 270px;
}

.festival-guide-grid .card .button,
.ticket-tier .button,
.promo-card .button {
	align-self: flex-start;
	margin-top: auto;
}

.ticket-tier-grid > .ticket-tier:first-child {
	grid-column: 1 / -1;
}

.promo-card {
	padding: 0;
	overflow: hidden;
}

.promo-card__media {
	aspect-ratio: 16 / 9;
	overflow: hidden;
}

.promo-card__image {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.promo-card__body {
	display: flex;
	flex-direction: column;
	flex: 1;
	padding: var(--space-md);
}

.promo-card__eyebrow {
	margin: 0 0 var(--space-xs);
}

.promo-card__body h2 {
	margin-top: 0;
}

@media (max-width: 767px) {
	.home-hero {
		min-height: auto;
		padding-top: 120px;
	}

	.home-hero__copy {
		margin-top: var(--space-lg);
	}

	.home-hero__media {
		margin-top: var(--space-xl);
		border-radius: 12px;
		aspect-ratio: 4 / 3;
	}

	.home-section {
		margin-top: 90px;
	}

	.home-featured .carousel-nav {
		margin-top: 0;
	}

	.ticket-tier-grid > .ticket-tier:first-child {
		grid-column: auto;
	}
}

/* Ticket tiers */

.ticket-tier__name {
	margin: 0 0 var(--space-xs);
}

.ticket-tier__price {
	font-family: var(--font-clarendon);
	font-weight: 500;
	font-size: var(--text-h3);
	margin: 0 0 var(--space-sm);
}

.ticket-tier__fine-print {
	font-size: var(--text-mono);
	color: var(--color-text-secondary);
}

.ticket-tier .button {
	margin-top: var(--space-sm);
}

/* Blog cards */

.blog-card .tag {
	color: #888;
}

.blog-card__meta {
	font-family: var(--font-cormorant);
	color: #888;
	margin: 28px 0 var(--space-sm);
}

.blog-card .button {
	margin-top: var(--space-sm);
}

/* Sponsors */

.sponsor-row {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;
	gap: var(--space-lg);
}

.sponsor-row img {
	max-height: 80px;
	width: auto;
	filter: grayscale(1);
	opacity: 0.7;
}

/* Blog single */

.entry-hero {
	box-shadow: 0 0 10px 0 #fff;
}

.entry-hero img {
	width: 100%;
	height: auto;
}

/*
 * Blog post body column. Scoped to the .film-single__synopsis.entry-content
 * pair (unique to single.php) so the Film/Event singles, which share the
 * synopsis class but not this measure, are unaffected.
 */
.film-single__synopsis.entry-content {
	max-width: 560px;
	/* Sits at the right edge of its grid column rather than the left, so
	   the gap between it and the meta box on the left absorbs the slack. */
	justify-self: end;
}

.entry-content > p {
	font-size: 16px;
	line-height: 1.5;
	letter-spacing: 0.03em;
}

/* Standfirst - the opening paragraph runs larger and dimmed. */
.entry-content > p:first-of-type {
	font-size: 22px;
	color: #888;
}

/*
 * 180px of clear space above "You may also like". The h2's own default top
 * margin is zeroed rather than left to collapse into this one, so the gap
 * is exactly the design value instead of whichever of the two is larger.
 */
.related-posts {
	margin-top: 180px;
}

.related-posts > h2 {
	margin-top: 0;
}

.entry-content blockquote {
	position: relative;
	margin: var(--space-lg) 0;
	padding: var(--space-lg) var(--space-md) var(--space-md);
	background-color: var(--color-surface);
	border: 1px solid var(--color-text-secondary);
}

.entry-content blockquote::before {
	content: "\201C";
	position: absolute;
	top: 0;
	left: var(--space-md);
	font-family: var(--font-clarendon);
	font-size: 2.5rem;
	color: var(--color-text-secondary);
	line-height: 1;
}

.entry-content blockquote p {
	margin: 0;
	color: var(--color-text-secondary);
	font-style: italic;
}

.entry-content blockquote p + p {
	margin-top: var(--space-sm);
}

.entry-content blockquote cite {
	display: block;
	margin-top: var(--space-sm);
	font-style: normal;
	color: var(--color-text-secondary);
	font-size: var(--text-mono);
}

.entry-content .wp-block-gallery {
	margin: var(--space-lg) 0;
}

.entry-content .wp-block-gallery figure {
	margin: 0;
}

.entry-content figure.wp-block-image {
	margin: var(--space-lg) 0;
}

.entry-content .wp-block-gallery img,
.entry-content figure.wp-block-image img {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* Single Film / Event */

.back-link {
	display: inline-flex;
	align-items: center;
	gap: var(--space-xs);
	color: var(--color-text-secondary);
	letter-spacing: 0.08em;
	text-transform: uppercase;
	text-decoration: underline;
}

.back-link__icon {
	flex-shrink: 0;
}

.film-single__header {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: var(--space-sm);
}

.film-single__actions {
	display: flex;
	gap: var(--space-sm);
}

.film-single__details {
	display: grid;
	grid-template-columns: 1fr;
	gap: var(--space-md);
}

/*
 * The Figma meta box (tag + Date/Author/Share list) has one glowing line
 * above and below the whole box - not a divider between every row. Drawn
 * as pseudo-elements rather than a plain `border` because the line itself
 * carries a soft blur/glow (box-shadow) that a border alone can't do.
 */
.film-single__meta-col {
	position: relative;
	/*
	 * align-self keeps the box sized to its own content. As a grid item it
	 * would otherwise stretch to the full row height, dragging the bottom
	 * line down to wherever the body copy in the next column happens to end.
	 */
	align-self: start;
	padding-block: 35px 32px;
	/* Everything inside the box is #888 - the tag's border picks this up
	   too, since .tag borders in currentColor. */
	color: #888;
}

.film-single__meta-col::before,
.film-single__meta-col::after {
	content: "";
	position: absolute;
	left: 0;
	right: 0;
	height: 1px;
	background-color: #909090;
	box-shadow: 0 0 2px #909090;
}

.film-single__meta-col::before {
	top: 0;
}

.film-single__meta-col::after {
	bottom: 0;
}

.film-single__meta {
	margin: var(--space-sm) 0 0;
}

.film-single__meta div {
	display: flex;
	gap: var(--space-sm);
	padding-block: var(--space-xs);
}

.film-single__meta dt {
	/* Inherits the #888 set on .film-single__meta-col - the labels aren't
	   dimmed relative to their values inside this box. */
	color: inherit;
	min-width: 8em;
}

.film-single__meta dd {
	margin: 0;
}

.film-single__synopsis :first-child {
	margin-top: 0;
}

@media (min-width: 768px) {
	.film-single__details {
		grid-template-columns: 1fr 2fr;
	}
}

.person-spotlight {
	display: flex;
	flex-direction: column;
	gap: var(--space-md);
}

.person-spotlight__media img {
	width: 100%;
	object-fit: cover;
}

.tickets-volunteer {
	overflow: hidden;
	padding: 0;
}

.tickets-volunteer .person-spotlight__body {
	display: flex;
	flex: 1 1 auto;
	flex-direction: column;
	align-items: flex-start;
	padding: var(--space-md);
}

.tickets-volunteer .person-spotlight__body > .font-mono {
	margin-bottom: var(--space-xs);
}

.tickets-volunteer__copy {
	margin-bottom: var(--space-lg);
}

.tickets-volunteer__copy > :last-child {
	margin-bottom: 0;
}

.tickets-volunteer .button {
	margin-top: auto;
}

.tickets-volunteer .person-spotlight__media {
	min-height: 320px;
}

.tickets-volunteer .person-spotlight__media img {
	display: block;
	height: 100%;
}

@media (min-width: 768px) {
	.person-spotlight {
		flex-direction: row;
	}
	.person-spotlight__media {
		flex: 0 0 40%;
	}

	.tickets-volunteer {
		align-items: stretch;
		gap: 0;
		min-height: 485px;
	}

	.tickets-volunteer .person-spotlight__body {
		padding: var(--space-lg);
	}

	.tickets-volunteer .person-spotlight__media {
		min-height: 0;
	}
}

.person-card__role {
	color: var(--color-text-secondary);
	margin-bottom: var(--space-sm);
}

/* Schedule: List/Calendar toggle (CSS-only, no JS) */

.schedule-header {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: var(--space-sm);
}

.schedule-controls {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--space-md);
}

.view-toggle {
	display: flex;
	align-items: center;
	gap: var(--space-sm);
	font-family: var(--font-cormorant);
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.08em;
	font-size: var(--text-mono);
}

.view-toggle input {
	position: absolute;
	opacity: 0;
	width: 1px;
	height: 1px;
}

.view-toggle label {
	cursor: pointer;
	color: var(--color-text-secondary);
}

/*
 * The radios now live inside .view-toggle__switch, a sibling of both
 * labels rather than directly adjacent to either - :has() scoped to
 * .view-toggle (not a plain `input:checked + label`) is what lets either
 * label react regardless of DOM order.
 */
.view-toggle:has(#view-calendar:checked) label[for="view-calendar"],
.view-toggle:has(#view-list:checked) label[for="view-list"] {
	color: var(--color-text);
	text-decoration: underline;
}

.view-toggle__switch {
	position: relative;
	display: inline-flex;
	align-items: center;
	width: 34px;
	height: 18px;
	flex-shrink: 0;
}

/*
 * Overrides the generic 1px hit area above: each radio covers its own half
 * of the visible switch (left = Calendar, right = List) so clicking the
 * switch itself - not just the text labels beside it - toggles the view.
 * The transparent radios retain the text-label interaction. The track is a
 * real button layered above them so clicking anywhere on it reverses the
 * current selection (schedule-view-toggle.js).
 */
.view-toggle .view-toggle__switch input {
	position: absolute;
	inset: 0;
	width: 50%;
	height: 100%;
	margin: 0;
	cursor: pointer;
}

.view-toggle .view-toggle__switch input#view-list {
	left: 50%;
}

.view-toggle__track {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	padding: 0;
	background: transparent;
	border: 1px solid var(--color-text-secondary);
	border-radius: 999px;
	cursor: pointer;
	z-index: 1;
}

.view-toggle__track:focus-visible {
	outline: 2px solid var(--color-text);
	outline-offset: 3px;
}

.view-toggle__knob {
	position: absolute;
	top: 2px;
	left: 2px;
	width: 12px;
	height: 12px;
	border-radius: 50%;
	background: var(--color-text);
	transition: transform 0.15s ease;
}

.view-toggle__switch:has(#view-list:checked) .view-toggle__knob {
	transform: translateX(16px);
}

.filter-control {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	color: var(--color-text-secondary);
	font-family: var(--font-cormorant);
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.08em;
	font-size: var(--text-mono);
}

.filter-control__chevron {
	flex-shrink: 0;
}

.schedule-view--calendar {
	display: none;
}

/*
 * The toggle inputs live inside .schedule-header, nested two levels above
 * the .schedule-view panels - a plain sibling combinator (~) can't reach
 * across that, since it requires a shared parent. :has() scoped to the
 * common .schedule-page wrapper is what actually works.
 */
.schedule-page:has(#view-calendar:checked) .schedule-view--list {
	display: none;
}

.schedule-page:has(#view-calendar:checked) .schedule-view--calendar {
	display: block;
}

.load-more {
	display: flex;
	justify-content: center;
	margin-top: var(--space-lg);
}

/* Schedule: Calendar view hour timeline */

.calendar-day-nav {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: var(--space-lg);
	scroll-margin-top: var(--space-lg);
}

.calendar-day-nav h2 {
	margin: 0;
	min-width: 14em;
	text-align: center;
}

.calendar-day-nav__arrow {
	font-family: var(--font-clarendon);
	font-size: 1.5rem;
	line-height: 1;
	cursor: pointer;
}

.calendar-day-nav__arrow--disabled {
	color: var(--color-surface);
	cursor: default;
}

.calendar-timeline {
	--hour-width: 180px;
	--label-width: 160px;
	--lane-height: 84px;
	overflow-x: auto;
}

.calendar-timeline__scroll {
	position: relative;
	width: fit-content;
	min-width: 100%;
}

.calendar-timeline__row {
	display: grid;
	grid-template-columns: var(--label-width) repeat(var(--hour-count), var(--hour-width));
	border-top: 1px solid var(--color-surface);
	min-height: calc(var(--lane-count, 1) * var(--lane-height));
}

.calendar-timeline__header {
	border-top: none;
	min-height: auto;
}

.calendar-timeline__label-cell {
	position: sticky;
	left: 0;
	z-index: 1;
	display: flex;
	align-items: center;
	padding: var(--space-sm);
	background-color: var(--color-bg);
	color: var(--color-text-secondary);
}

.calendar-timeline__hour-cell {
	display: flex;
	align-items: center;
	justify-content: center;
	padding: var(--space-sm);
	color: var(--color-text-secondary);
	border-left: 1px solid var(--color-surface);
}

.calendar-timeline__track {
	position: relative;
	grid-column: 2 / -1;
	background-image: repeating-linear-gradient(
		to right,
		var(--color-surface) 0,
		var(--color-surface) 1px,
		transparent 1px,
		transparent var(--hour-width)
	);
}

.calendar-block {
	position: absolute;
	top: calc(var(--lane) * var(--lane-height) + var(--space-xs));
	left: calc(var(--offset) * var(--hour-width));
	width: calc(var(--duration) * var(--hour-width) - var(--space-sm));
	height: calc(var(--lane-height) - var(--space-sm));
	display: flex;
	flex-direction: column;
	justify-content: center;
	gap: 4px;
	overflow: hidden;
	background-color: var(--color-surface);
	border: 1px solid var(--color-text-secondary);
	padding: var(--space-xs) var(--space-sm);
	color: var(--color-text);
}

.calendar-block__top {
	display: flex;
	align-items: center;
	gap: var(--space-sm);
	white-space: nowrap;
}

.calendar-block__tag {
	font-size: var(--text-mono);
	padding: 0.2em 0.6em;
}

.calendar-block__meta {
	font-family: var(--font-mono);
	font-size: var(--text-mono);
	letter-spacing: 0.08em;
	color: var(--color-text-secondary);
	white-space: nowrap;
}

.calendar-block__title {
	font-family: var(--font-clarendon);
	font-weight: 500;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	font-size: 0.9rem;
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}

.calendar-timeline__now {
	position: absolute;
	top: 0;
	bottom: 0;
	left: calc(var(--label-width) + var(--offset) * var(--hour-width));
	width: 1px;
	background-color: var(--color-white);
	box-shadow: 0 0 6px var(--color-white);
	z-index: 2;
}

.calendar-timeline__now::before {
	content: "";
	position: absolute;
	top: 0;
	left: -4px;
	border: 4px solid transparent;
	border-top-color: var(--color-white);
}

/*
 * .filter-control select - the Blog index's Filter/Sort are real <select>
 * elements (unlike Schedule's inert Filter/Rounds chrome above, category
 * and sort order are well-defined here) wrapped in the same .filter-control
 * label + chevron shell for a consistent look. appearance:none drops the
 * browser's native arrow in favor of the shared SVG chevron.
 */
.filter-control select {
	appearance: none;
	background: transparent;
	color: inherit;
	border: none;
	font: inherit;
	text-transform: inherit;
	letter-spacing: inherit;
	cursor: pointer;
}

.filter-control select:focus-visible {
	outline: 1px solid var(--color-text);
}

/* Accordion (FAQs) */

.accordion {
	display: grid;
	gap: 8px;
}

.accordion__item {
	background-color: var(--color-surface);
	box-shadow: 0 0 10px 0 #5d5d5d;
}

.accordion__heading {
	margin: 0;
	font-family: var(--font-cormorant);
	font-size: var(--text-body);
	font-weight: 700;
	line-height: 1.5;
	letter-spacing: 0.03em;
	text-transform: none;
}

.accordion__trigger {
	appearance: none;
	background: transparent;
	border: 0;
	color: #888;
	cursor: pointer;
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--space-sm);
	width: 100%;
	padding: var(--space-md);
	font: inherit;
	text-align: left;
}

.accordion__trigger:focus-visible {
	outline: 2px solid #dbdbdb;
	outline-offset: -4px;
}

.accordion__icons {
	display: grid;
	place-items: center;
	flex-shrink: 0;
	width: 36px;
	min-height: 23px;
}

.accordion__icon {
	display: block;
	grid-area: 1 / 1;
}

.accordion__icon--minus,
.accordion__trigger[aria-expanded="true"] .accordion__icon--caret {
	visibility: hidden;
	opacity: 0;
}

.accordion__trigger[aria-expanded="true"] .accordion__icon--minus {
	visibility: visible;
	opacity: 1;
}

.accordion__content {
	color: #dbdbdb;
}

.accordion--ready .accordion__content {
	height: 0;
	overflow: hidden;
	opacity: 0;
}

.accordion__content-inner {
	padding: 0 var(--space-md) var(--space-md);
}

.accordion__content-inner > :last-child {
	margin-bottom: 0;
}

/* Grids */

.grid {
	display: grid;
	gap: var(--space-md);
	grid-template-columns: 1fr;
}

@media (min-width: 768px) {
	.grid--2 { grid-template-columns: repeat(2, 1fr); }
	.grid--3 { grid-template-columns: repeat(3, 1fr); }
	.grid--6 { grid-template-columns: repeat(3, 1fr); }
}

@media (min-width: 1024px) {
	.grid--6 { grid-template-columns: repeat(6, 1fr); }
}
