/**
 * Components — Buttons, cards, badges, forms, inputs, pills.
 *
 * @package WEO
 */

/* ═══════════════════════════════════════════
   Skip Link
   ═══════════════════════════════════════════ */

.skip-link {
	position: absolute;
	top: -100%;
	left: var(--space-md);
	z-index: 999;
	padding: var(--space-sm) var(--space-md);
	background: var(--accent);
	color: var(--white);
	font-family: var(--font-body);
	font-size: var(--text-small);
	font-weight: 600;
	border-radius: var(--radius-sm);
	text-decoration: none;
	transition: top var(--transition-fast);
}

.skip-link:focus {
	top: var(--space-sm);
	outline: 2px solid var(--accent);
	outline-offset: 2px;
}

/* ═══════════════════════════════════════════
   Buttons
   ═══════════════════════════════════════════ */

.btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: var(--space-sm);
	font-family: var(--font-body);
	font-weight: 600;
	font-size: var(--text-small);
	line-height: 1;
	padding: 11px 24px;
	border: none;
	border-radius: var(--radius-md);
	cursor: pointer;
	text-decoration: none;
	white-space: nowrap;
	transition: all 0.25s var(--ease-out-expo);
}

.btn:focus-visible {
	outline: 2px solid var(--accent);
	outline-offset: 2px;
}

/* Size modifier */
.btn--lg {
	font-size: var(--text-body);
	padding: 14px 32px;
}

/* ─── Primary ─── */

.btn--primary,
.btn--primary:visited {
	background: var(--accent);
	color: var(--white);
	box-shadow: 0 4px 20px rgba(224, 64, 160, 0.3);
}

.btn--primary:hover {
	background: var(--accent-hover);
	box-shadow: 0 8px 32px rgba(224, 64, 160, 0.4);
	transform: translateY(-2px);
}

.btn--primary:active {
	transform: translateY(0);
	box-shadow: 0 2px 12px rgba(224, 64, 160, 0.25);
}

.btn--primary:disabled,
.btn--primary[disabled] {
	background: var(--text-mid);
	color: #fff;
	box-shadow: none; 
	cursor: not-allowed;
	transform: none;
	pointer-events: none;
	opacity: 0.45;
}

/* ─── Ghost ─── */

.btn--ghost,
.btn--ghost:visited {
	background: transparent;
	color: var(--muted);
	border: 1.5px solid rgba(168, 156, 200, 0.3);
}

.btn--ghost:hover {
	border-color: var(--muted);
	transform: translateY(-2px);
}

.btn--ghost:active {
	transform: translateY(0);
}

/* ─── Accent Outline ─── */

.btn--accent-outline,
.btn--accent-outline:visited {
	background: transparent;
	color: var(--accent);
	border: 1.5px solid rgba(224, 64, 160, 0.35);
}

.btn--accent-outline:hover {
	background: var(--accent-light);
	border-color: var(--accent);
	transform: translateY(-1px);
}

.btn--accent-outline:active {
	transform: translateY(0);
}

/* Light-context ghost (for use on light backgrounds) */
.btn--ghost-light {
	background: transparent;
	color: var(--text-mid);
	border: 1.5px solid rgba(106, 96, 128, 0.15);
}

.btn--ghost-light:hover {
	border-color: var(--accent);
	color: var(--accent);
	transform: translateY(-1px);
}

/* ─── Dark (for use on light backgrounds) ─── */

.btn--dark {
	background: var(--dark);
	color: var(--white);
	border: 1.5px solid rgba(168, 156, 200, 0.15);
}

.btn--dark:hover {
	background: var(--charcoal);
	border-color: var(--subtle);
	transform: translateY(-1px);
}

.btn--dark:active {
	transform: translateY(0);
}

/* ═══════════════════════════════════════════
   Event Cards
   ═══════════════════════════════════════════ */

/* Direct grid child — `min-width: 0` defeats the CSS Grid "blowout" pattern
 * where a 1fr track lets `min-width: auto` resolve to the image's intrinsic
 * width (set via the <img> width/height HTML attributes). `.event-card`'s
 * own `overflow: hidden` already clips any pixel overflow inside the card;
 * we deliberately DON'T set `overflow: hidden` here, so the card's hover
 * lift, box-shadow halo, and focus outline can render outside the grid
 * item's bounds. Without min-width:0 the card can balloon past the
 * viewport on mobile while images are slow to load or broken. */
.events-grid__item {
	min-width: 0;
}

.event-card {
	background: var(--white);
	border-radius: 14px;
	overflow: hidden;
	border: 1px solid rgba(106, 96, 128, 0.1);
	box-shadow: 0 2px 12px rgba(14, 10, 24, 0.05);
	transition: all 0.3s var(--ease-out-expo);
	cursor: pointer;
	height: 100%;
}

.event-card__link {
	display: flex;
	flex-direction: column;
	height: 100%;
}

.event-card:hover {
	border-color: rgba(224, 64, 160, 0.25);
	box-shadow: 0 12px 40px rgba(14, 10, 24, 0.12), 0 0 0 1px rgba(224, 64, 160, 0.1);
	transform: translateY(-4px);
}

.event-card:focus-within {
	outline: 2px solid var(--accent);
	outline-offset: 2px;
}

/* ─── Image area ─── */

.event-card__image {
	position: relative;
	/* Padding-based 4:3 aspect ratio (3 ÷ 4 = 75%) — works in any rendering
	 * engine including Hotjar's session replay, where `aspect-ratio` isn't
	 * reliably honoured. Direct children are absolutely positioned to fill
	 * the box, since the padding-bottom trick gives no content height. The
	 * existing `.event-card__badges`, `.event-card__sold-out-overlay`, and
	 * `::after` are already `position: absolute` and continue to work. */
	padding-bottom: 75%;
	background: linear-gradient(135deg, var(--dark) 0%, var(--charcoal) 100%);
	overflow: hidden;
}

.event-card__image img {
	position: absolute;
	inset: 0;
	width: 100%;
	max-width: 100%;
	height: 100%;
	object-fit: cover;
}

/* Bottom gradient fade on image */
.event-card__image::after {
	content: '';
	position: absolute;
	bottom: 0;
	left: 0;
	right: 0;
	height: 60px;
	background: linear-gradient(to top, rgba(14, 10, 24, 0.6), transparent);
	pointer-events: none;
}

/* ─── Badges overlay ─── */

/* Audience indicator — coloured dot + audience name, bottom-left of card footer.
 * The wrapper is a flex row so the two pieces stay grouped against the seats
 * text on the right. min-width: 0 + truncation on the name prevents long
 * audience labels from squashing the seats text on narrow cards. The dot
 * mirrors the size of the sidebar's events-sidebar__filter-dot so the two
 * read as the same token across the page; colour is set via the --pill-color
 * custom property. */
.event-card__audience {
	display: inline-flex;
	align-items: center;
	gap: 7px;
	min-width: 0;
}

.event-card__audience-dot {
	display: inline-block;
	width: 10px;
	height: 10px;
	border-radius: 50%;
	background: var(--pill-color, var(--text-mid));
	flex-shrink: 0;
}

.event-card__audience-name {
	font-family: var(--font-body);
	font-size: var(--text-xs);
	color: var(--text-mid);
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
	font-weight: 700;
}

/* Corner badge stack — top-right of the card image. The container owns the
 * absolute positioning; its children (sale-end countdown on top, then whichever
 * value/access badge renders) are flow items that stack with a gap. z-index 3
 * keeps the access badges above the sold-out overlay (z-index 2), matching the
 * pre-stack behaviour. */
.event-card__badges {
	position: absolute;
	top: 12px;
	right: 12px;
	z-index: 3;
	display: flex;
	flex-direction: column;
	align-items: flex-end;
	gap: 6px;
}

/* Hidden until js/sale-countdown.js hydrates the badge — !important so the
 * countdown's own inline-flex display can't override the [hidden] attribute.
 * Shared across the card / hero / sidebar contexts. */
.weo-sale-countdown[hidden] {
	display: none !important;
}

/* Sale-end urgency countdown (red) — card variant. Shares the corner-badge
 * pill shape; sits at the top of .event-card__badges. */
.event-card__countdown-badge {
	display: inline-flex;
	align-items: center;
	background: var(--error);
	color: var(--white);
	font-family: var(--font-body);
	font-size: var(--text-xs);
	font-weight: 700;
	padding: 4px 10px;
	border-radius: var(--radius-sm);
	white-space: nowrap;
}

/* Ribbon tab — sits above the card in the archive grid. The 30px bottom
 * padding + -30px margin tuck the banner's lower half behind the card, so
 * only the tab (top padding + text) peeks above. Shared geometry; each
 * variant below supplies its own colours. Only ONE ribbon renders per card
 * (see parts/event-card.php) — the tuck assumes a single tab. */
.event-card__discount-banner,
.event-card__newbies-banner {
	position: relative;
	border-radius: 10px 10px 0 0;
	font-family: var(--font-body);
	font-size: var(--text-s);
	font-weight: 600;
	text-align: center;
	padding-top: 3px;
	padding-bottom: 30px;
	margin-bottom: -30px;
}

/* "Extra X% off" — charcoal text for AA contrast on gold (matches the
 * non-member badge). */
.event-card__discount-banner {
	background: #ffc107;
	color: var(--charcoal);
}

/* "Event for first-timers" — Newbies Night category. */
.event-card__newbies-banner {
	background: var(--newbies);
	color: var(--white);
}

/* Only when a ribbon is present, make the grid item a flex column so the card
 * fills the remaining height (keeps cards equal-height across a row), and raise
 * the card above the ribbon so it covers the tucked-under 30px. Non-ribbon grid
 * items are untouched and keep their existing height:100% behaviour. */
.events-grid__item:has(.event-card__discount-banner),
.events-grid__item:has(.event-card__newbies-banner) {
	display: flex;
	flex-direction: column;
}

.events-grid__item:has(.event-card__discount-banner) > .event-card,
.events-grid__item:has(.event-card__newbies-banner) > .event-card {
	flex: 1;
	min-height: 0;
	position: relative;
	z-index: 1;
}

.event-card__save-badge {
	background: rgba(48, 184, 112, 1);
	color: var(--white);
	font-family: var(--font-body);
	font-size: var(--text-xs);
	font-weight: 700;
	padding: 4px 10px;
	border-radius: var(--radius-sm);
}

.event-card__tier-badge {
	display: inline-flex;
	align-items: center;
	gap: 5px;
	background: var(--violet);
	color: var(--white);
	font-family: var(--font-body);
	font-size: var(--text-xs);
	font-weight: 700;
	padding: 4px 10px;
	border-radius: var(--radius-sm);
}

.event-card__tier-badge-icon {
	display: inline-flex;
	align-items: center;
}

.event-card__nonmember-badge {
	background: rgba(240, 200, 64, 0.95);
	color: var(--charcoal);
	font-family: var(--font-body);
	font-size: var(--text-xs);
	font-weight: 700;
	padding: 4px 10px;
	border-radius: var(--radius-sm);
}

/* Events showcase carousel uses the existing .event-carousel styles from
 * css/events.css (conditionally enqueued on the homepage via inc/enqueue.php
 * when the page_builder contains an events_grid block). No homepage-specific
 * styles needed — the section heading inherits from .section-heading. */

.event-card__title {
	font-size: var(--text-body);
	line-height: 1.2;
	margin: 7px 0 4px;
}

/* ─── Body ─── */

.event-card__body {
	padding: var(--space-md) 18px 12px;
	flex: 1;
}

.event-card--sold-out.is-visible .event-card__body {
	opacity: 0.3;
}

.event-card__meta {
	font-family: var(--font-body);
	font-size: var(--text-s);
	color: var(--text-mid);
	margin-bottom: 7px;
}

/* ─── Pricing row ─── */

.event-card__pricing {
	display: flex;
	align-items: baseline;
	gap: 8px;
}

.event-card__price {
	font-family: var(--font-display);
	font-weight: 700;
	font-size: var(--text-h3);
	color: var(--text-dark);
	letter-spacing: -0.02em;
}

.event-card__rrp {
	font-family: var(--font-body);
	font-size: var(--text-small);
	color: var(--text-mid);
	text-decoration: line-through;
}

/* ─── Footer ─── */

.event-card__footer {
	padding: 10px 18px;
	border-top: 1px solid rgba(106, 96, 128, 0.08);
	display: flex;
	justify-content: space-between;
	align-items: center;
}

.event-card__seats {
	font-family: var(--font-body);
	font-size: var(--text-s);
	font-weight: 600;
	color: var(--accent);
}

/* ═══════════════════════════════════════════
   Badges & Pills
   ═══════════════════════════════════════════ */

/* Generic audience badge pill */
.badge {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	font-family: var(--font-body);
	font-size: var(--text-xs);
	font-weight: 600;
	padding: 4px 10px;
	border-radius: var(--radius-sm);
	background: var(--accent-light);
	color: var(--accent);
	letter-spacing: 0.02em;
}

/* Trust / award badges */
.trust-badge {
	display: inline-flex;
	align-items: center;
	gap: var(--space-xs);
	font-family: var(--font-body);
	font-size: var(--text-xs);
	font-weight: 600;
	padding: 4px 10px;
	border-radius: var(--radius-sm);
}

.trust-badge--award {
	color: var(--gold);
	background: rgba(240, 200, 64, 0.08);
	border: 1px solid var(--gold-light);
}

.trust-badge--agto {
	color: var(--cyan);
	background: rgba(64, 184, 224, 0.08);
	border: 1px solid var(--cyan-light);
}

.trust-badge--trustpilot {
	color: var(--success);
	background: rgba(48, 184, 112, 0.08);
	border: 1px solid rgba(48, 184, 112, 0.15);
}

/* Hero-style CTA badge (pill with icon + text) */
.hero-badge {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	padding: 6px 16px;
	margin-bottom: 2em;
	border-radius: var(--radius-full);
	font-family: var(--font-body);
	font-size: var(--text-xs);
	font-weight: 600;
	letter-spacing: 0.04em;
	text-transform: uppercase;
}

.hero-badge--accent {
	background: rgba(224, 64, 160, 0.1);
	border: 1px solid rgba(224, 64, 160, 0.2);
	color: var(--accent);
}

/* Audience filter pills */
.pill {
	display: inline-flex;
	align-items: center;
	font-family: var(--font-body);
	font-size: var(--text-s);
	color: var(--text-mid);
	padding: 5px 14px;
	border-radius: var(--radius-full);
	border: 1px solid rgba(106, 96, 128, 0.12);
	cursor: pointer;
	transition: all var(--transition-fast);
	text-decoration: none;
}

.pill:hover,
.pill--active {
	border-color: var(--accent);
	color: var(--accent);
}

/* ═══════════════════════════════════════════
   Pricing Callout (inline price display)
   ═══════════════════════════════════════════ */

.price-display {
	display: flex;
	align-items: baseline;
	gap: 10px;
}

.price-display__amount {
	font-family: var(--font-display);
	font-weight: 700;
	font-size: var(--text-h2);
	color: var(--accent);
	letter-spacing: -0.03em;
	line-height: 1;
}

.price-display__rrp {
	font-family: var(--font-body);
	font-size: var(--text-small);
	color: var(--text-mid);
	text-decoration: line-through;
}

.price-display__savings {
	display: inline-flex;
	align-items: center;
	font-family: var(--font-body);
	font-size: var(--text-xs);
	font-weight: 700;
	color: var(--white);
	background: rgba(48, 184, 112, 0.9);
	padding: 3px 8px;
	border-radius: var(--radius-sm);
}

/* ═══════════════════════════════════════════
   Testimonial Card
   ═══════════════════════════════════════════ */

.testimonial-card {
	text-align: center;
	position: relative;
}

.testimonial-card__quote {
	font-family: var(--font-body);
	font-style: italic;
	font-size: var(--text-m);
	line-height: 1.6;
	color: var(--text-dark);
	font-weight: 400;
	margin-bottom: var(--space-xl);
}

.testimonial-card__attribution {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 14px;
}

.testimonial-card__avatar {
	width: 48px;
	height: 48px;
	border-radius: 50%;
	overflow: hidden;
	flex-shrink: 0;
}

/* Initial-letter avatar fallback */
.testimonial-card__avatar--initial {
	background: linear-gradient(135deg, var(--accent), #C040D0);
	display: flex;
	align-items: center;
	justify-content: center;
	font-family: var(--font-display);
	font-weight: 700;
	font-size: var(--text-m);
	color: var(--white);
}

.testimonial-card__name {
	font-family: var(--font-body);
	font-weight: 600;
	font-size: var(--text-body);
	color: var(--text-dark);
}

.testimonial-card__desc {
	font-family: var(--font-body);
	font-size: var(--text-body);
	color: var(--text-mid);
}

/* Carousel dots */
.carousel-dots {
	display: flex;
	justify-content: center;
	gap: var(--space-sm);
	margin-top: var(--space-xl);
}

.carousel-dot {
	width: 8px;
	height: 8px;
	border-radius: var(--radius-full);
	background: rgba(106, 96, 128, 0.15);
	border: none;
	padding: 0;
	cursor: pointer;
	transition: all 0.3s var(--ease-out-expo);
}

.carousel-dot--active {
	width: 28px;
	background: var(--accent);
}

/* ═══════════════════════════════════════════
   Testimonial Carousel — contained slide
   (photo left / quote right)
   ═══════════════════════════════════════════ */

/* Grid-stack: every slide occupies the same cell, so the Alpine enter/leave
   cross-fade overlaps the two slides instead of stacking the entering one
   below the leaving one in document flow. Stage height = tallest slide. */
.testimonial-carousel__stage {
	display: grid;
}

.testimonial-slide {
	grid-area: 1 / 1;
	display: grid;
	grid-template-columns: 1fr;
	background: var(--white);
	border-radius: var(--radius-lg);
	border: 1px solid rgba(106, 96, 128, 0.06);
	box-shadow: 0 2px 8px rgba(14, 10, 24, 0.03);
	overflow: hidden;
	text-align: left;
}

.testimonial-slide__media {
	position: relative;
	aspect-ratio: 4 / 3;
	overflow: hidden;
}

.testimonial-slide__media img {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* Photo-less slides: designed quote panel keeps the two-column composition */
.testimonial-slide__media--panel {
	background: linear-gradient(145deg, var(--midnight) 0%, #2A1A4A 55%, var(--accent) 170%);
	display: flex;
	align-items: center;
	justify-content: center;
}

.testimonial-slide__glyph {
	position: absolute;
	top: 8px;
	left: 24px;
	font-family: var(--font-display);
	font-weight: 800;
	font-size: 130px;
	line-height: 1;
	color: rgba(255, 255, 255, 0.12);
	pointer-events: none;
	user-select: none;
}

.testimonial-slide__panel-initial {
	width: 96px;
	height: 96px;
	border-radius: 50%;
	background: rgba(255, 255, 255, 0.1);
	border: 1px solid rgba(255, 255, 255, 0.16);
	display: flex;
	align-items: center;
	justify-content: center;
	font-family: var(--font-display);
	font-weight: 800;
	font-size: 44px;
	color: var(--white);
}

.testimonial-slide__body {
	display: flex;
	flex-direction: column;
	gap: var(--space-sm);
	padding: 28px 24px;
}

.testimonial-slide__title {
	font-family: var(--font-display);
	font-weight: 700;
	font-size: var(--text-h3);
	color: var(--text-dark);
	margin: 0;
}

.testimonial-slide__quote {
	font-family: var(--font-body);
	font-size: var(--text-m);
	line-height: 1.6;
	color: var(--text-mid);
	margin: 0;
}

/* Attribution pinned to the bottom of the body column, left-aligned */
.testimonial-slide__attribution {
	justify-content: flex-start;
	margin-top: auto;
	padding-top: var(--space-lg);
}

@media (min-width: 768px) {
	.testimonial-slide {
		grid-template-columns: minmax(0, 400px) 1fr;
	}

	.testimonial-slide__media {
		aspect-ratio: 1 / 1;
	}

	.testimonial-slide__body {
		padding: 36px 40px;
	}
}

/* ═══════════════════════════════════════════
   Testimonial Wall — masonry review wall
   (Airbnb-style, mixed photo/text heights)
   ═══════════════════════════════════════════ */

.testimonial-wall__columns {
	columns: 1;
	column-gap: 20px;
}

@media (min-width: 640px) {
	.testimonial-wall__columns { columns: 2; }
}

@media (min-width: 960px) {
	.testimonial-wall__columns { columns: 3; }
}

.testimonial-wall__card {
	break-inside: avoid;
	display: flow-root;
	margin-bottom: 20px;
	background: var(--white);
	border-radius: var(--radius-lg);
	padding: 24px;
	border: 1px solid rgba(106, 96, 128, 0.06);
	box-shadow: 0 2px 8px rgba(14, 10, 24, 0.03);
	text-align: left;
	transition: border-color 0.35s cubic-bezier(0.16, 1, 0.3, 1), box-shadow 0.35s cubic-bezier(0.16, 1, 0.3, 1);
}

.testimonial-wall__card:hover {
	border-color: var(--accent-light);
	box-shadow: 0 12px 40px rgba(14, 10, 24, 0.08);
}

/* Photo bleeds to the card edges; natural aspect ratio drives the masonry
   height variance (photo cards taller, text-only cards shorter). */
.testimonial-wall__photo {
	margin: -24px -24px 20px;
	overflow: hidden;
	border-radius: var(--radius-lg) var(--radius-lg) 0 0;
}

.testimonial-wall__photo img {
	width: 100%;
	height: auto;
	display: block;
}

.testimonial-wall__card .testimonial-card__rating {
	margin-bottom: var(--space-sm);
}

.testimonial-wall__title {
	font-family: var(--font-display);
	font-weight: 700;
	font-size: var(--text-h4);
	color: var(--text-dark);
	margin: 0 0 var(--space-sm);
}

.testimonial-wall__quote {
	font-family: var(--font-body);
	font-size: var(--text-body);
	line-height: 1.65;
	color: var(--text-mid);
	margin: 0;
}

/* 10-line clamp — server-rendered, removed reactively by the weoClampQuote
   Alpine component when the reader taps "Read more". */
.testimonial-wall__quote.is-clamped {
	display: -webkit-box;
	-webkit-box-orient: vertical;
	-webkit-line-clamp: 10;
	line-clamp: 10;
	overflow: hidden;
}

.testimonial-wall__readmore {
	background: none;
	border: none;
	padding: 0;
	margin-top: var(--space-sm);
	font-family: var(--font-body);
	font-size: var(--text-s);
	font-weight: 600;
	color: var(--accent);
	text-decoration: underline;
	text-underline-offset: 3px;
	cursor: pointer;
	transition: color 0.15s ease;
}

.testimonial-wall__readmore:hover,
.testimonial-wall__readmore:focus {
	color: var(--text-dark);
}

.testimonial-wall__attribution {
	justify-content: flex-start;
	margin-top: var(--space-md);
	padding-top: var(--space-md);
	border-top: 1px solid rgba(106, 96, 128, 0.08);
}

/* Cards beyond the caps hide until the wall is expanded (server-rendered
   classes, CSS-only toggle — no x-show flash before Alpine boots).
   Two tiers: --overflow = beyond the desktop cap (hidden everywhere),
   --overflow-sm = beyond the mobile cap (hidden ≤639px only). */
.testimonial-wall__card--overflow {
	display: none;
}

@media (max-width: 639px) {
	.testimonial-wall:not(.is-expanded) .testimonial-wall__card--overflow-sm {
		display: none;
	}
}

.testimonial-wall.is-expanded .testimonial-wall__card--overflow {
	display: flow-root;
}

.testimonial-wall__more-wrap {
	display: flex;
	justify-content: center;
	margin-top: var(--space-lg);
}

/* When only the mobile cap is exceeded, the Show-all button is mobile-only */
@media (min-width: 640px) {
	.testimonial-wall__more-wrap--sm-only {
		display: none;
	}
}

/* ═══════════════════════════════════════════
   Step Cards (How It Works)
   ═══════════════════════════════════════════ */

.step-card {
	text-align: center;
	padding: 36px 24px 32px;
	border-radius: var(--radius-lg);
	transition: all 0.35s ease;
	cursor: default;
}

.step-card:hover {
	background: var(--white);
	box-shadow: 0 8px 30px rgba(14, 10, 24, 0.06);
}

.step-card__icon {
	width: 72px;
	height: 72px;
	border-radius: 50%;
	margin: 0 auto var(--space-lg);
	background: var(--white);
	display: flex;
	align-items: center;
	justify-content: center;
	font-size: var(--text-h2);
	box-shadow: 0 2px 8px rgba(14, 10, 24, 0.06);
	border: 2px solid var(--surface);
	transition: all 0.35s ease;
}

.step-card:hover .step-card__icon {
	background: linear-gradient(135deg, var(--accent), #C040D0);
	box-shadow: 0 8px 24px rgba(224, 64, 160, 0.25);
	border-color: transparent;
}

/* Show number on hover, icon by default */
.step-card__icon-number {
	display: none;
	font-family: var(--font-display);
	font-weight: 800;
	font-size: var(--text-h2);
	color: var(--white);
}

.step-card:hover .step-card__icon-emoji {
	display: none;
}

.step-card:hover .step-card__icon-number {
	display: block;
}

.step-card__title {
	color: var(--text-dark);
	margin-bottom: 10px;
}

.step-card__desc {
	font-family: var(--font-body);
	font-size: var(--text-body);
	line-height: 1.6;
	color: var(--text-mid);
	max-width: 260px;
	margin: 0 auto;
}

/* Dashed connecting line between steps */
.steps-connector {
	position: absolute;
	top: 52px;
	left: 18%;
	right: 18%;
	height: 2px;
	background-image: repeating-linear-gradient(
		90deg,
		rgba(224, 64, 160, 0.25) 0,
		rgba(224, 64, 160, 0.25) 8px,
		transparent 8px,
		transparent 16px
	);
	z-index: 0;
}

/* ═══════════════════════════════════════════
   Audience Segment Cards
   ═══════════════════════════════════════════ */

.audience-card {
	display: block;
	text-decoration: none;
	color: inherit;
	text-align: center;
	padding: 36px 20px 30px;
	border-radius: var(--radius-lg);
	cursor: pointer;
	background: var(--white);
	position: relative;
	overflow: hidden;
	border: 2px solid rgba(106, 96, 128, 0.08);
	box-shadow: 0 2px 8px rgba(14, 10, 24, 0.03);
	transition: all 0.35s var(--ease-out-expo);
}

.audience-card:hover {
	transform: translateY(-5px);
}

.audience-card:focus-visible {
	outline: 2px solid var(--accent);
	outline-offset: 2px;
}

/* Radial glow on hover — applied via inline style with audience colour */
.audience-card__glow {
	position: absolute;
	inset: 0;
	opacity: 0;
	transition: opacity 0.35s ease;
	pointer-events: none;
}

.audience-card:hover .audience-card__glow {
	opacity: 1;
}

.audience-card__content {
	position: relative;
	z-index: var(--z-base);
}

.audience-card__icon {
	font-size: var(--text-hero);
	margin-bottom: 14px;
	line-height: 1;
	color: var(--text-dark);
	transition: transform 0.35s var(--ease-bounce), color 0.3s ease;
	display: flex;
	justify-content: center;
}

.audience-card:hover .audience-card__icon {
	transform: scale(1.15);
	color: var(--card-accent, var(--accent));
}

.audience-card__title {
	color: var(--text-dark);
	margin-bottom: 6px;
}

.audience-card__desc {
	font-family: var(--font-body);
	font-size: var(--text-body);
	line-height: 1.5;
	color: var(--text-mid);
}

.audience-card__link {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	margin-top: var(--space-md);
	font-size: var(--text-body);
	font-weight: 700;
	font-family: var(--font-body);
	opacity: 0;
	transform: translateY(6px);
	transition: all 0.3s ease;
}

.audience-card__link svg {
	flex-shrink: 0;
}

.audience-card:hover .audience-card__link {
	opacity: 1;
	transform: translateY(0);
}

/* Section-wide glow — fades in on card hover, tinted with the hovered card's
   accent. `--seg-glow` + the `is-glowing` toggle are set by
   js/scroll-animations.js from the card's `--card-accent-bg`. `isolation`
   keeps the glow's negative z-index above the section bg but behind content. */
.audience-segments {
	isolation: isolate;
}

.audience-segments__glow {
	position: absolute;
	inset: 0;
	z-index: -1;
	opacity: 0;
	pointer-events: none;
	background: radial-gradient(ellipse 70% 55% at 50% 42%, var(--seg-glow, transparent), transparent 72%);
	transition: opacity 0.5s ease;
}

.audience-segments.is-glowing .audience-segments__glow {
	opacity: 1;
}

/* ═══════════════════════════════════════════
   Form Inputs
   ═══════════════════════════════════════════ */

.form-input,
.form-textarea,
.form-select {
	width: 100%;
	padding: 12px;
	font-family: var(--font-body);
	font-size: var(--text-body);
	color: var(--text-dark);
	background-color: var(--white);
	border: 1px solid #e6e6e6;
	border-radius: 8px;
	box-shadow: 0 1px 1px rgba(0, 0, 0, 0.03), 0 3px 6px rgba(0, 0, 0, 0.02);
	transition: background 0.15s ease, border 0.15s ease, box-shadow 0.15s ease, color 0.15s ease;
}

.form-input:focus,
.form-textarea:focus,
.form-select:focus {
	outline: 0;
	border-color: var(--text-dark);
	box-shadow: 0 1px 1px rgba(0, 0, 0, 0.03), 0 3px 6px rgba(0, 0, 0, 0.02), 0 0 0 3px hsla(265, 43%, 11%, 0.25), 0 1px 1px 0 rgba(0, 0, 0, 0.08);
}

.form-input::placeholder,
.form-textarea::placeholder {
	color: var(--text-mid);
	opacity: 0.6;
}

.form-textarea {
	resize: vertical;
	min-height: 120px;
}

.form-select {
	appearance: none;
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8'%3E%3Cpath d='M1 1l5 5 5-5' stroke='%236A6080' stroke-width='1.5' fill='none'/%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-position: right 16px center;
	padding-right: 40px;
}

/* Dark context form inputs */
.dark-context .form-input,
.dark-context .form-textarea,
.dark-context .form-select {
	background: rgba(168, 156, 200, 0.08);
	border-color: rgba(168, 156, 200, 0.15);
	color: var(--muted);
}

.dark-context .form-input::placeholder,
.dark-context .form-textarea::placeholder {
	color: var(--subtle);
}

/* Checkbox */
.form-checkbox {
	appearance: none;
	width: 20px;
	height: 20px;
	border: 1.5px solid rgba(106, 96, 128, 0.2);
	border-radius: 4px;
	background: var(--white);
	cursor: pointer;
	flex-shrink: 0;
	transition: all var(--transition-fast);
}

.form-checkbox:checked {
	background: var(--accent);
	border-color: var(--accent);
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='10'%3E%3Cpath d='M1 5l3 3 7-7' stroke='%23fff' stroke-width='2' fill='none'/%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-position: center;
}

.form-checkbox:focus-visible {
	outline: 2px solid var(--accent);
	outline-offset: 2px;
}

/* Form label */
.form-label {
	display: block;
	font-family: var(--font-body);
	font-size: var(--text-small);
	font-weight: 600;
	color: var(--text-dark);
	margin-bottom: var(--space-xs);
}

/* ═══════════════════════════════════════════
   Contact Form 7 overrides
   Styled bespoke — CF7 default CSS is dequeued.
   ═══════════════════════════════════════════ */

/* Reset CF7 paragraph spacing so its wpautop output flows nicely. */
.wpcf7-form p {
	margin: 0 0 var(--space-md);
}

.wpcf7-form p:last-child {
	margin-bottom: 0;
}

/* CF7 labels — match .form-label when they wrap an input. */
.wpcf7-form label {
	display: block;
	font-family: var(--font-body);
	font-size: var(--text-small);
	font-weight: 600;
	color: var(--text-dark);
	margin-bottom: var(--space-xs);
}

/* CF7 form controls — hook into the existing .form-input treatment. */
.wpcf7-form-control.wpcf7-text,
.wpcf7-form-control.wpcf7-email,
.wpcf7-form-control.wpcf7-tel,
.wpcf7-form-control.wpcf7-url,
.wpcf7-form-control.wpcf7-number,
.wpcf7-form-control.wpcf7-date,
.wpcf7-form-control.wpcf7-textarea,
.wpcf7-form-control.wpcf7-select {
	width: 100%;
	font-family: var(--font-body);
	font-size: var(--text-body);
	padding: 12px var(--space-md);
	border: 1.5px solid rgba(106, 96, 128, 0.15);
	border-radius: var(--radius-md);
	background: var(--white);
	color: var(--text-dark);
	transition: border-color var(--transition-fast), box-shadow var(--transition-fast);
}

.wpcf7-form-control.wpcf7-text:focus,
.wpcf7-form-control.wpcf7-email:focus,
.wpcf7-form-control.wpcf7-tel:focus,
.wpcf7-form-control.wpcf7-url:focus,
.wpcf7-form-control.wpcf7-number:focus,
.wpcf7-form-control.wpcf7-date:focus,
.wpcf7-form-control.wpcf7-textarea:focus,
.wpcf7-form-control.wpcf7-select:focus {
	outline: none;
	border-color: var(--accent);
	box-shadow: 0 0 0 3px var(--accent-light);
}

.wpcf7-form-control.wpcf7-textarea {
	resize: vertical;
	min-height: 140px;
}

.wpcf7-form-control.wpcf7-select {
	appearance: none;
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8'%3E%3Cpath d='M1 1l5 5 5-5' stroke='%236A6080' stroke-width='1.5' fill='none'/%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-position: right 16px center;
	padding-right: 40px;
}

/* Checkbox / radio groups */
.wpcf7-form-control.wpcf7-checkbox,
.wpcf7-form-control.wpcf7-radio {
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-md);
	padding: 0;
	margin: 0;
}

.wpcf7-form-control.wpcf7-checkbox .wpcf7-list-item,
.wpcf7-form-control.wpcf7-radio .wpcf7-list-item {
	margin: 0;
	display: inline-flex;
	align-items: center;
	gap: var(--space-xs);
}

/* CF7 submit — style as if it were .btn.btn--primary.btn--lg. */
.wpcf7-submit {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: var(--space-sm);
	font-family: var(--font-body);
	font-weight: 600;
	font-size: var(--text-body);
	line-height: 1;
	padding: 14px 28px;
	border: none;
	border-radius: var(--radius-md);
	cursor: pointer;
	text-decoration: none;
	white-space: nowrap;
	background: var(--accent);
	color: var(--white);
	transition: all 0.25s var(--ease-out-expo);
}

.wpcf7-submit:hover {
	background: var(--accent-hover);
	transform: translateY(-1px);
	box-shadow: var(--shadow-md);
}

.wpcf7-submit:focus-visible {
	outline: 2px solid var(--accent);
	outline-offset: 2px;
}

.wpcf7 form.submitting .wpcf7-submit {
	opacity: 0.7;
	pointer-events: none;
}

/* Inline field-level error tip. */
.wpcf7-not-valid-tip {
	display: block;
	margin-top: var(--space-xs);
	color: var(--error);
	font-size: var(--text-small);
	font-weight: 500;
}

.wpcf7-form-control.wpcf7-not-valid {
	border-color: var(--error);
}

.wpcf7-form-control.wpcf7-not-valid:focus {
	box-shadow: 0 0 0 3px rgba(232, 80, 64, 0.15);
}

/* Response banner (validation errors / success message). */
.wpcf7-response-output {
	margin: var(--space-lg) 0 0;
	padding: var(--space-md) var(--space-lg);
	border: 1.5px solid rgba(106, 96, 128, 0.2);
	border-radius: var(--radius-md);
	font-size: var(--text-small);
	font-weight: 500;
	line-height: 1.5;
}

.wpcf7 form.invalid .wpcf7-response-output,
.wpcf7 form.unaccepted .wpcf7-response-output,
.wpcf7 form.payment-required .wpcf7-response-output {
	border-color: var(--error);
	background: rgba(232, 80, 64, 0.08);
	color: var(--error);
}

.wpcf7 form.sent .wpcf7-response-output {
	border-color: var(--success);
	background: rgba(48, 184, 112, 0.08);
	color: var(--success);
}

.wpcf7 form.failed .wpcf7-response-output,
.wpcf7 form.aborted .wpcf7-response-output {
	border-color: var(--error);
	background: rgba(232, 80, 64, 0.08);
	color: var(--error);
}

/* Spinner — accent-coloured, subtle. */
.wpcf7-spinner {
	display: inline-block;
	width: 18px;
	height: 18px;
	margin-left: var(--space-sm);
	border: 2px solid var(--accent-light);
	border-top-color: var(--accent);
	border-radius: 50%;
	animation: weo-cf7-spin 0.8s linear infinite;
	background: none;
	vertical-align: middle;
}

@keyframes weo-cf7-spin {
	to {
		transform: rotate(360deg);
	}
}

/* ═══════════════════════════════════════════
   Contact tabs (two-path form toggle)
   ═══════════════════════════════════════════ */

.contact-tabs {
	display: inline-flex;
	gap: var(--space-xs);
	padding: 6px;
	background: rgba(106, 96, 128, 0.08);
	border-radius: var(--radius-full);
	margin: 0 auto var(--space-xl);
	max-width: fit-content;
}

.contact-tab {
	appearance: none;
	font-family: var(--font-body);
	font-size: var(--text-small);
	font-weight: 600;
	color: var(--text-mid);
	background: transparent;
	border: none;
	padding: 10px 22px;
	border-radius: var(--radius-full);
	cursor: pointer;
	transition: all 0.25s var(--ease-out-expo);
	white-space: nowrap;
}

.contact-tab:hover {
	color: var(--text-dark);
}

.contact-tab--active {
	background: var(--accent);
	color: var(--white);
	box-shadow: var(--shadow-sm);
}

.contact-tab--active:hover {
	color: var(--white);
	background: var(--accent-hover);
}

.contact-tab:focus-visible {
	outline: 2px solid var(--accent);
	outline-offset: 2px;
}

/* Contact tab panels */
.contact-panel {
	padding-top: var(--space-xl);
	border-top: 1px solid rgba(106, 96, 128, 0.12);
}

/* ═══════════════════════════════════════════
   Contact info band (email / phone / hours)
   ═══════════════════════════════════════════ */

.contact-info-band {
	display: grid;
	grid-template-columns: 1fr;
	gap: var(--space-md);
	margin: var(--space-xl) 0 var(--space-2xl);
}

@media (min-width: 720px) {
	.contact-info-band {
		grid-template-columns: repeat(3, 1fr);
	}
}

.contact-info__card {
	display: flex;
	flex-direction: column;
	gap: 6px;
	padding: var(--space-lg);
	background: var(--white);
	border: 1px solid rgba(106, 96, 128, 0.12);
	border-radius: var(--radius-md);
	text-decoration: none;
	color: var(--text-dark);
	transition: all 0.25s var(--ease-out-expo);
}

.contact-info__card:not(.contact-info__card--static):hover {
	border-color: var(--accent);
	transform: translateY(-2px);
	box-shadow: var(--shadow-md);
}

.contact-info__icon {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 40px;
	height: 40px;
	border-radius: var(--radius-full);
	background: var(--accent-light);
	color: var(--accent);
	margin-bottom: var(--space-xs);
}

.contact-info__label {
	font-family: var(--font-body);
	font-size: var(--text-xs);
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.08em;
	color: var(--text-mid);
}

.contact-info__value {
	font-family: var(--font-display);
	font-size: var(--text-body);
	font-weight: 600;
	color: var(--text-dark);
	word-break: break-word;
}

/* ═══════════════════════════════════════════
   Contact helpful-links strip
   ═══════════════════════════════════════════ */

.contact-faq-links {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--space-sm) var(--space-md);
	padding: var(--space-md) var(--space-lg);
	margin-bottom: var(--space-2xl);
	background: rgba(224, 64, 160, 0.04);
	border: 1px dashed rgba(224, 64, 160, 0.25);
	border-radius: var(--radius-md);
}

.contact-faq-links__intro {
	font-family: var(--font-body);
	font-size: var(--text-small);
	font-weight: 600;
	color: var(--text-mid);
}

.contact-faq-links__item {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	font-family: var(--font-body);
	font-size: var(--text-small);
	font-weight: 600;
	color: var(--accent);
	text-decoration: none;
	padding: 6px 14px;
	background: var(--white);
	border: 1px solid rgba(224, 64, 160, 0.2);
	border-radius: var(--radius-full);
	transition: all 0.25s var(--ease-out-expo);
}

.contact-faq-links__item:hover {
	background: var(--accent);
	color: var(--white);
	border-color: var(--accent);
	transform: translateY(-1px);
}

.contact-faq-links__item:focus-visible {
	outline: 2px solid var(--accent);
	outline-offset: 2px;
}

/* ═══════════════════════════════════════════
   Search form (shared by search.php + 404.php)
   ═══════════════════════════════════════════ */

.search-form {
	display: flex;
	align-items: stretch;
	gap: var(--space-sm);
	width: 100%;
	max-width: 520px;
	margin: 0 auto;
}

.search-form__field {
	position: relative;
	flex: 1;
	min-width: 0;
}

.search-form__icon {
	position: absolute;
	top: 50%;
	left: var(--space-md);
	transform: translateY(-50%);
	display: inline-flex;
	color: var(--text-mid);
	pointer-events: none;
}

.search-form__input.form-input {
	padding-left: 44px;
}

.search-form__submit {
	flex-shrink: 0;
}

/* Dark context (hero overlays) */
.dark-context .search-form__icon,
.section--dark .search-form__icon {
	color: var(--subtle);
}

@media (max-width: 480px) {
	.search-form {
		flex-direction: column;
	}

	.search-form__submit {
		width: 100%;
		justify-content: center;
	}
}


/* ═══════════════════════════════════════════
   Floating Cart FAB
   Fixed bottom-right pill; renders site-wide
   except on cart/checkout/order-received.
   Hides when empty via `data-cart-count="0"`.
   Lives in components.css (not woocommerce.css)
   because woocommerce.css is conditionally
   enqueued — the FAB needs to render on every
   page in the funnel.
   ═══════════════════════════════════════════ */

.weo-cart-fab {
	position: fixed;
	right: 24px;
	bottom: 24px;
	z-index: 95;
	display: inline-flex;
	align-items: center;
	gap: 10px;
	padding: 14px 20px 14px 18px;
	background: var(--accent);
	color: var(--white);
	border-radius: 999px;
	box-shadow: 0 8px 24px rgba(224, 64, 160, 0.32), 0 2px 6px rgba(26, 16, 40, 0.12);
	font-family: var(--font-body);
	font-weight: 700;
	font-size: var(--text-body);
	text-decoration: none;
	transition: transform 0.18s ease, box-shadow 0.18s ease, background 0.18s ease;
}

.weo-cart-fab:hover,
.weo-cart-fab:focus {
	background: var(--accent-hover);
	color: var(--white);
	transform: translateY(-2px);
	box-shadow: 0 14px 32px rgba(224, 64, 160, 0.38), 0 3px 8px rgba(26, 16, 40, 0.14);
}

.weo-cart-fab:focus-visible {
	outline: 3px solid var(--white);
	outline-offset: 2px;
}

.weo-cart-fab[data-cart-count="0"] {
	display: none;
}

.weo-cart-fab__icon {
	display: inline-flex;
	align-items: center;
	justify-content: center;
}

.weo-cart-fab__count {
	min-width: 22px;
	height: 22px;
	padding: 0 7px;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	background: var(--white);
	color: var(--accent);
	border-radius: 999px;
	font-size: var(--text-xs);
	font-weight: 700;
	line-height: 1;
}

/* ═══════════════════════════════════════════
 * Login prompt banner
 *
 * Used on cart, checkout, and Attendee Registration
 * pages for signed-out visitors. Lives in components.css
 * (always loaded) so all three contexts pick it up
 * without conditional enqueuing.
 * ═══════════════════════════════════════════ */

.weo-login-prompt {
	position: relative;
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 18px;
	background: var(--white);
	border: 3px solid var(--accent);
	border-radius: 14px;
	padding: 16px 22px;
	margin: 0 auto;
	max-width: 1152px;
	box-shadow: 0 1px 3px rgba(0, 0, 0, 0.04);
	box-sizing: border-box;
	/* Entrance: slide-in-from-top + fade. */
	animation: weoLoginPromptIn 0.55s var(--ease-out-expo) 0.15s backwards;
}

/* Pink ripple halo around the banner. A `::before` pseudo expanding
 * via box-shadow keeps the banner's own resting shadow untouched, and
 * `pointer-events: none` prevents the halo from blocking clicks. Two
 * pulses, separated by a brief pause, then quiet — enough to catch
 * the eye without becoming a loop. */
.weo-login-prompt::before {
	content: "";
	position: absolute;
	inset: 0;
	border-radius: 14px;
	box-shadow: 0 0 0 0 rgba(224, 64, 160, 0);
	animation: weoLoginPromptPulse 1.8s var(--ease-out-expo) 0.8s 2 backwards;
	pointer-events: none;
}

@keyframes weoLoginPromptIn {
	from {
		opacity: 0;
		transform: translateY(-12px);
	}
	to {
		opacity: 1;
		transform: translateY(0);
	}
}

@keyframes weoLoginPromptPulse {
	0% {
		box-shadow: 0 0 0 0 rgba(224, 64, 160, 0.55);
	}
	70% {
		box-shadow: 0 0 0 14px rgba(224, 64, 160, 0);
	}
	100% {
		box-shadow: 0 0 0 14px rgba(224, 64, 160, 0);
	}
}

@media (prefers-reduced-motion: reduce) {
	.weo-login-prompt,
	.weo-login-prompt::before {
		animation: none;
	}
}

.weo-login-prompt__copy {
	margin: 0;
	color: var(--text-dark);
	font-size: var(--text-s);
	line-height: 1.4;
	font-weight: 600;
}

.weo-login-prompt__link {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	flex-shrink: 0;
	color: var(--accent);
	font-weight: 600;
	font-size: var(--text-s);
	text-decoration: none;
	transition: color 0.15s ease, transform 0.15s ease;
}

.weo-login-prompt__link:hover {
	color: var(--text-dark);
	transform: translateX(2px);
}

.weo-login-prompt__link:focus-visible {
	outline: 2px solid var(--accent);
	outline-offset: 2px;
	border-radius: 4px;
}

@media (max-width: 1200px) {
	.weo-login-prompt {
		margin-inline: 24px;
	}
}

@media (max-width: 767px) {
	.weo-login-prompt {
		margin-inline: 16px;
	}
}

@media (max-width: 639px) {
	.weo-login-prompt {
		flex-direction: column;
		align-items: flex-start;
		gap: 10px;
		padding: 14px 18px;
		width: auto;
	}
	.weo-cart-fab {
		right: 16px;
		bottom: 16px;
		padding: 12px 16px 12px 14px;
	}
}

/* ─── Promo badge (window.weoPromo / js/promo-badge.js) ──────────────
 * Admin-controlled marketing banner, JS-built from an uncached AJAX
 * config so it stays correct behind the full-page cache. Bottom-right,
 * #F0C840. Sits LEFT of the cart FAB on desktop / ABOVE it on mobile
 * when the FAB is visible — via :has() so it tracks the live cart count
 * (cart-fab.js flips data-cart-count after load); default bottom-right
 * (the FAB's spot) when no FAB or the cart is empty. Must live in this
 * always-loaded sheet — it renders site-wide via wp_footer/JS. */
.weo-promo {
	position: fixed;
	right: 24px;
	bottom: 24px;
	z-index: 94; /* just under the cart FAB's 95 */
	background: var(--violet);
	color: var(--text-dark);
	border-radius: 14px;
	box-shadow: 0 10px 40px rgba(26, 16, 40, 0.28);
	opacity: 0;
	transform: translateY(12px);
	transition: opacity 0.3s var(--ease-out-expo), transform 0.3s var(--ease-out-expo);
}

.weo-promo.is-visible {
	opacity: 1;
	transform: translateY(0);
}

.weo-promo.is-dismissing {
	opacity: 0;
	transform: translateY(12px);
}

.weo-promo:hover {
	box-shadow: 0 14px 48px rgba(26, 16, 40, 0.34);
}

.weo-promo__inner {
	display: block;
	padding: 16px 18px;
	font-family: var(--font-body);
	font-size: var(--text-s);
	font-weight: 600;
	line-height: 1.45;
	color: #fff;
	text-decoration: none;
}

.weo-promo__inner:hover,
.weo-promo__inner:focus-visible {
	color: #fff;
	text-decoration: none;
}

/* Small × outside the box, top-right. */
.weo-promo__dismiss {
	position: absolute;
	top: -8px;
	right: -8px;
	width: 26px;
	height: 26px;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	background: var(--dark);
	color: var(--white);
	border: 2px solid var(--violet);
	border-radius: 999px;
	font-size: 16px;
	line-height: 1;
	cursor: pointer;
	box-shadow: 0 2px 8px rgba(26, 16, 40, 0.3);
	transition: transform 0.15s ease;
}

.weo-promo__dismiss:hover {
	transform: scale(1.08);
}

.weo-promo__dismiss:focus-visible {
	outline: 2px solid var(--dark);
	outline-offset: 2px;
}

/* Desktop: when the FAB is visible, sit to its left. */
@media (min-width: 640px) {
	body:has(.weo-cart-fab:not([data-cart-count="0"])) .weo-promo {
		right: calc(24px + 92px + 16px); /* FAB gutter + ~FAB width + gap */
	}
}

/* Mobile: full-width; when the FAB is visible, stack above it. */
@media (max-width: 639px) {
	.weo-promo {
		right: 16px;
		bottom: 16px;
		left: 16px;
		max-width: none;
	}
	body:has(.weo-cart-fab:not([data-cart-count="0"])) .weo-promo {
		bottom: calc(16px + 52px + 12px); /* FAB gutter + ~FAB height + gap */
	}
}

@media (prefers-reduced-motion: reduce) {
	.weo-promo {
		transition: none;
		opacity: 1;
		transform: none;
	}
	.weo-promo.is-dismissing {
		opacity: 0;
	}
}

/* ─── Global toast service (window.weoToast) ─────────────────────────
 * Stacked, dismissible toasts in the top-right corner (full-width on
 * mobile). Built by js/weo-toast.js; consumed by checkoutCart qty +
 * pre-validation, the WC notice scanner (js/wc-notice-toast.js), and
 * any future caller. Reuses the weoToastIn / weoToastOut /
 * weoToastProgress keyframes from css/animations.css. The booking-
 * sidebar `.booking-toast` (Phase 44) is a SEPARATE pattern — Alpine
 * scoped, single-slot, with the x-for restart-bar trick. */

.weo-toast-stack {
	position: fixed;
	top: calc(var(--nav-height) + 16px);
	right: 24px;
	z-index: 9999;
	display: flex;
	flex-direction: column;
	gap: 10px;
	max-width: 380px;
	pointer-events: none;
}

.weo-toast {
	pointer-events: auto;
	position: relative;
	padding: 14px 40px 16px 46px;
	border-radius: 14px;
	background: var(--dark);
	color: var(--white);
	font-size: var(--text-s);
	font-weight: 500;
	line-height: 1.45;
	box-shadow: 0 10px 40px rgba(14, 10, 24, 0.25);
	overflow: hidden;
	animation: weoToastIn 0.35s var(--ease-out-expo) backwards;
}

/* `role="alert"` makes some browsers auto-focus the toast on insert
 * (visible as a default focus ring around the chrome). The toast
 * itself isn't keyboard-interactive — the × button inside is and
 * keeps its own focus styles — so suppress the wrapper's ring. */
.weo-toast:focus,
.weo-toast:focus-visible {
	outline: none;
}

.weo-toast__message {
	margin: 0;
}

/* Inline links inside notice content — preserve underline + readable
 * colour on the coloured backgrounds. Hover lifts opacity. */
.weo-toast__message a {
	color: inherit;
	text-decoration: underline;
	font-weight: 600;
}

.weo-toast__message a:hover {
	opacity: 0.85;
}

/* Icon — single alert-circle for all toast types (matches the
 * Phase 44 booking-toast + AR-page validation-notice pattern). */
.weo-toast::before {
	content: "";
	position: absolute;
	top: 16px;
	left: 18px;
	width: 20px;
	height: 20px;
	background-repeat: no-repeat;
	background-size: contain;
	background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='20' height='20' viewBox='0 0 24 24' fill='none' stroke='%23ffffff' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><circle cx='12' cy='12' r='10'/><line x1='12' y1='8' x2='12' y2='12'/><line x1='12' y1='16' x2='12.01' y2='16'/></svg>");
	pointer-events: none;
}

.weo-toast__bar {
	position: absolute;
	left: 0;
	bottom: 0;
	height: 3px;
	width: 100%;
	background: var(--accent);
	transform-origin: left center;
	animation: weoToastProgress 5s linear forwards;
	pointer-events: none;
}

.weo-toast__dismiss {
	position: absolute;
	top: 6px;
	right: 8px;
	width: 28px;
	height: 28px;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	background: none;
	border: 0;
	color: inherit;
	font-size: 22px;
	line-height: 1;
	cursor: pointer;
	opacity: 0.7;
	border-radius: 6px;
	transition: opacity 0.15s ease, background 0.15s ease;
}

.weo-toast__dismiss:hover,
.weo-toast__dismiss:focus-visible {
	opacity: 1;
	background: rgba(255, 255, 255, 0.12);
	outline: none;
}

.weo-toast.is-dismissing {
	animation: weoToastOut 0.3s var(--ease-out-expo) forwards;
}

.weo-toast.is-dismissing .weo-toast__bar {
	animation-play-state: paused;
}

/* Action buttons (persistent toasts — confirmation prompts). When the
 * caller supplies `actions`, the countdown bar is suppressed and the
 * toast stays put until a button is clicked. The bottom padding is
 * widened to keep visual breathing room since there's no bar at the
 * very bottom. */
.weo-toast--has-actions {
	padding-bottom: 18px;
}

.weo-toast__actions {
	display: flex;
	gap: 8px;
	margin-top: 14px;
}

.weo-toast__action {
	flex: 1;
	padding: 9px 14px;
	border-radius: 8px;
	border: 1px solid rgba(255, 255, 255, 0.25);
	background: transparent;
	color: inherit;
	font-family: inherit;
	font-size: var(--text-s);
	font-weight: 600;
	line-height: 1.2;
	cursor: pointer;
	transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}

.weo-toast__action:hover,
.weo-toast__action:focus-visible {
	background: rgba(255, 255, 255, 0.12);
	border-color: rgba(255, 255, 255, 0.45);
	outline: none;
}

.weo-toast__action--primary {
	background: var(--accent);
	border-color: var(--accent);
	color: var(--white);
}

.weo-toast__action--primary:hover,
.weo-toast__action--primary:focus-visible {
	background: var(--accent);
	border-color: var(--accent);
	color: var(--white);
	filter: brightness(1.08);
}

@media (max-width: 639px) {
	.weo-toast-stack {
		top: calc(var(--nav-height) + 12px);
		left: 16px;
		right: 16px;
		max-width: none;
	}
}

@media (prefers-reduced-motion: reduce) {
	.weo-toast,
	.weo-toast.is-dismissing,
	.weo-toast__bar {
		animation: none;
	}
}

/* ─── YouTube facade (lite-youtube-embed) ────────────────────────────── */

/* Container — match event-card chrome (radius + shadow). Vendor CSS
   already handles the 16:9 aspect-ratio spacer via ::after. */
lite-youtube {
	border-radius: var(--radius-md);
	overflow: hidden;
	box-shadow: var(--shadow-card);
	max-width: 100%;
	margin: var(--space-md) auto;
}

/* Suppress the vendor's title-gradient strip — our facade doesn't pass
   a title via `data-title`, and the empty gradient bar still paints. */
lite-youtube::before {
	display: none;
}

/* Replace YT's red rounded-rect play button with a dark midnight circle
   that picks up the audience accent on the triangle. Background is set
   here; the triangle is painted by ::after below via mask-image so the
   accent colour swaps cleanly across audience contexts. */
lite-youtube > .lyt-playbtn {
	background-image: none;
	background-color: rgba(14, 10, 24, 0.85);
	width: 78px;
	height: 78px;
	border-radius: 50%;
	top: 50%;
	left: 50%;
	transform: translate(-50%, -50%);
	filter: none;
	transition: transform 0.2s var(--ease-out-expo), background-color 0.2s ease;
}

/* Audience-accent triangle. Using `mask` (not `background-image`)
   because mask + background-color lets `var(--accent)` flow through —
   which means the existing `<body data-audience="...">` system swaps
   the triangle colour per audience automatically with zero JS. */
lite-youtube > .lyt-playbtn::after {
	content: "";
	position: absolute;
	top: 50%;
	left: 53%; /* optical right-shift — right-pointing triangles read centred when geometric centre is slightly right */
	transform: translate(-50%, -50%);
	width: 28px;
	height: 28px;
	background-color: var(--accent);
	-webkit-mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 22 22'><path d='M7 4 L18 11 L7 18 Z'/></svg>") no-repeat center / contain;
	mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 22 22'><path d='M7 4 L18 11 L7 18 Z'/></svg>") no-repeat center / contain;
}

/* Hover / focus — slight scale up, deeper background, keyboard ring. */
lite-youtube:hover > .lyt-playbtn,
lite-youtube > .lyt-playbtn:focus,
lite-youtube > .lyt-playbtn:focus-visible {
	background-color: rgba(14, 10, 24, 0.95);
	transform: translate(-50%, -50%) scale(1.08);
	filter: none;
	outline: 2px solid var(--accent);
	outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
	lite-youtube > .lyt-playbtn {
		transition: none;
	}
}


/* Shared lightbox — used by the event single AND the Gallery FC block (parts/gallery.php).
   Lives here (global components.css) rather than events.css so it works on any page. */
/* ═══════════════════════════════════════════
   Gallery Lightbox Modal
   ═══════════════════════════════════════════ */

body.lightbox-open {
	overflow: hidden;
}

[x-cloak] {
	display: none !important;
}

.gallery-lightbox {
	position: fixed;
	inset: 0;
	z-index: 9999;
	display: flex;
	align-items: center;
	justify-content: center;
}

.gallery-lightbox__backdrop {
	position: absolute;
	inset: 0;
	background: rgba(14, 10, 24, 0.95);
	backdrop-filter: blur(20px);
}

.gallery-lightbox__content {
	position: relative;
	width: 90vw;
	height: 90vh;
	max-width: 1200px;
	display: flex;
	align-items: center;
	justify-content: center;
}

/* Close button — anchored to viewport top-right so it's always findable.
 * Styled to match .gallery-lightbox__arrow (circular dark backdrop, white icon). */
.gallery-lightbox__close {
	position: fixed;
	top: 24px;
	right: 24px;
	width: 44px;
	height: 44px;
	display: flex;
	align-items: center;
	justify-content: center;
	background: rgba(42, 32, 64, 0.6);
	border: 1px solid rgba(168, 156, 200, 0.1);
	border-radius: 50%;
	color: var(--white);
	cursor: pointer;
	transition: background 0.2s ease, transform 0.2s ease;
	z-index: 10;
}

.gallery-lightbox__close:hover {
	background: rgba(42, 32, 64, 0.9);
	transform: scale(1.05);
}

/* Slides */
.gallery-lightbox__stage {
	width: 100%;
	height: 100%;
	display: flex;
	align-items: center;
	justify-content: center;
	position: relative;
}

.gallery-lightbox__slide {
	display: none;
	width: 100%;
	height: 100%;
	align-items: center;
	justify-content: center;
}

.gallery-lightbox__slide.is-active {
	display: flex;
}

.gallery-lightbox__img {
	max-width: 100%;
	max-height: 100%;
	width: auto;
	height: auto;
	object-fit: contain;
	border-radius: var(--radius-md);
}

.gallery-lightbox__video {
	width: 100%;
	max-width: 1200px;
	aspect-ratio: 16 / 9;
	border-radius: var(--radius-md);
	background: var(--midnight);
}

/* Nav arrows */
.gallery-lightbox__arrow {
	position: absolute;
	top: 50%;
	transform: translateY(-50%);
	width: 44px;
	height: 44px;
	display: flex;
	align-items: center;
	justify-content: center;
	background: rgba(42, 32, 64, 0.6);
	border: 1px solid rgba(168, 156, 200, 0.1);
	border-radius: 50%;
	color: var(--muted);
	cursor: pointer;
	transition: all 0.2s;
	z-index: 10;
}

.gallery-lightbox__arrow:hover {
	background: rgba(42, 32, 64, 0.9);
	color: var(--white);
}

.gallery-lightbox__arrow--prev {
	left: -56px;
}

.gallery-lightbox__arrow--next {
	right: -56px;
}

@media (max-width: 959px) {
	.gallery-lightbox__arrow--prev {
		left: 8px;
	}
	.gallery-lightbox__arrow--next {
		right: 8px;
	}
}

/* Counter */
.gallery-lightbox__counter {
	position: absolute;
	bottom: -20px;
	left: 50%;
	transform: translateX(-50%);
	font-family: var(--font-body);
	font-size: var(--text-small);
	color: var(--subtle);
	font-weight: 600;
}

/* ─── End Gallery Lightbox ─── */

/* Native <video> in the lightbox (Gallery FC block uses uploaded files, not
   embeds). Let the clip use its own intrinsic ratio, capped to the viewport. */
.gallery-lightbox__video[controls] {
	/* Keep the base 16:9 stage box (a definite size from width alone, so it
	   never depends on the clip's intrinsic size — which metadata preload
	   defers) and letterbox the clip (and its first-frame still, rendered via
	   the `#t=0.001` source fragment) within it. */
	max-height: 90vh;
	object-fit: contain;
}

/* ═══════════════════════════════════════════
   Gallery FC block — Airbnb-style mosaic
   parts/gallery.php. One large hero tile + a 2×2 grid of the rest, opening the
   shared .gallery-lightbox on click. Mobile-first.
   ═══════════════════════════════════════════ */

/* Shared with the generic FC above/below pattern (.content-above /
   .content-below / .fc-ctas) used by events grid, testimonials, pricing
   table, FAQ, audience segments, team grid, etc. .content-above /
   .content-below also switch off .content-default's default typography
   (see layouts.css) so these rules own the styling. */
.weo-gallery__above, .content-above,
.weo-gallery__below, .content-below,
.weo-gallery__ctas, .fc-ctas {
	text-align: center;
}
.weo-gallery__above, .content-above { margin-bottom: var(--space-2xl); }
.weo-gallery__below, .content-below { margin-top: var(--space-2xl); }
.weo-gallery__above :where(h1, h2, h3, h4), .content-above :where(h1, h2, h3, h4),
.weo-gallery__below :where(h1, h2, h3, h4), .content-below :where(h1, h2, h3, h4) { margin: 0 0 var(--space-sm); }
.weo-gallery__above p, .content-above p,
.weo-gallery__below p, .content-below p { color: var(--text-mid); margin: 0; }

.weo-gallery__ctas, .fc-ctas {
	margin-top: var(--space-xl);
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-sm);
	justify-content: center;
}

/* Mosaic grid — mobile base: big hero tile, then a 2-col grid of the rest. */
.weo-gallery__grid {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 8px;
}

.weo-gallery__tile {
	position: relative;
	overflow: hidden;
	margin: 0;
	padding: 0;
	border: none;
	cursor: pointer;
	border-radius: var(--radius-md);
	background: transparent;
	aspect-ratio: 4 / 3;
	outline: 2px solid transparent;
	outline-offset: 2px;
	transition: padding 0.2s ease-in-out;
}
.weo-gallery__tile:hover { padding: 2px; }
.weo-gallery__tile:focus-visible { outline-color: var(--accent); }

/* First tile is the large hero, full-width on mobile. */
.weo-gallery__tile:first-child {
	grid-column: 1 / -1;
	aspect-ratio: 16 / 9;
}

.weo-gallery__img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	border-radius: inherit;
	transition: filter 0.25s ease-in-out;
}
.weo-gallery__tile:hover .weo-gallery__img { filter: brightness(0.6); }

/* Play overlay on video tiles. */
.weo-gallery__play {
	position: absolute;
	inset: 0;
	display: flex;
	align-items: center;
	justify-content: center;
	pointer-events: none;
	opacity: 0.92;
	filter: drop-shadow(0 8px 32px rgba(224, 64, 160, 0.45));
	animation: weo-gallery-play-pulse 2.5s ease-in-out infinite;
}
@keyframes weo-gallery-play-pulse {
	0%, 100% { transform: scale(1); }
	50%      { transform: scale(0.92); }
}

/* "Show all photos" pill — only when the gallery has more than 5 items. */
.weo-gallery__tile--more .weo-gallery__img { filter: brightness(0.5); }
.weo-gallery__showall {
	position: absolute;
	bottom: 12px;
	right: 12px;
	display: inline-flex;
	align-items: center;
	gap: 6px;
	padding: 8px 14px;
	background: var(--white);
	color: var(--text-dark);
	font-family: var(--font-body);
	font-size: var(--text-s);
	font-weight: 600;
	border-radius: var(--radius-full);
	box-shadow: var(--shadow-md);
	pointer-events: none;
}

/* Mobile odd-remainder fixes so no tile is left stranded half-width. */
.weo-gallery__grid--count-2 .weo-gallery__tile:nth-child(2),
.weo-gallery__grid--count-4 .weo-gallery__tile:nth-child(4) {
	grid-column: 1 / -1;
	aspect-ratio: 16 / 9;
}

/* ── Desktop mosaics (≥ 640px) ── */
@media (min-width: 640px) {

	/* 2 — side by side. */
	.weo-gallery__grid--count-2 .weo-gallery__tile:first-child,
	.weo-gallery__grid--count-2 .weo-gallery__tile:nth-child(2) {
		grid-column: auto;
		aspect-ratio: 4 / 3;
	}

	/* 3 — big left, two stacked right. */
	.weo-gallery__grid--count-3 {
		grid-template-columns: 2fr 1fr;
		grid-template-rows: 1fr 1fr;
		aspect-ratio: 3 / 2;
	}
	.weo-gallery__grid--count-3 > .weo-gallery__tile { aspect-ratio: auto; }
	.weo-gallery__grid--count-3 .weo-gallery__tile:first-child {
		grid-column: 1 / 2;
		grid-row: 1 / 3;
	}

	/* 4 — 2×2. */
	.weo-gallery__grid--count-4 {
		grid-template-columns: 1fr 1fr;
		grid-template-rows: 1fr 1fr;
		aspect-ratio: 3 / 2;
	}
	.weo-gallery__grid--count-4 > .weo-gallery__tile {
		grid-column: auto;
		aspect-ratio: auto;
	}

	/* 5+ — Airbnb hero: big left (square) + 2×2 right. */
	.weo-gallery__grid--count-5plus {
		grid-template-columns: repeat(4, 1fr);
		grid-template-rows: 1fr 1fr;
		aspect-ratio: 2 / 1;
	}
	.weo-gallery__grid--count-5plus > .weo-gallery__tile { aspect-ratio: auto; }
	.weo-gallery__grid--count-5plus .weo-gallery__tile:first-child {
		grid-column: 1 / 3;
		grid-row: 1 / 3;
	}
}

@media (prefers-reduced-motion: reduce) {
	.weo-gallery__play { animation: none; }
}

/* ═══════════════════════════════════════════
   FAQ Accordion — parts/faq-accordion.php
   Lives here (not events.css) because the faq_accordion FC block can render on
   ANY page via page.php's flexible-content loop, while events.css is only
   conditionally enqueued (event templates + Woo/account pages). Site-wide CSS
   for a site-wide component.
   ═══════════════════════════════════════════ */

.faq-accordion {
	display: flex;
	flex-direction: column;
	gap: 2px;
}

.faq-accordion__item {
	border-bottom: 1px solid rgba(106, 96, 128, 0.08);
	overflow: hidden;
	transition: all 0.25s ease;
}

.faq-accordion__trigger {
	width: 100%;
	padding: 16px 0;
	border: none;
	cursor: pointer;
	background: transparent;
	display: flex;
	justify-content: space-between;
	align-items: center;
	gap: 16px;
	text-align: left;
}

.faq-accordion__trigger:focus-visible {
	outline: 2px solid var(--accent);
	outline-offset: -2px;
}

.faq-accordion__question {
	font-family: var(--font-display);
	font-weight: 600;
	color: var(--text-dark);
	transition: color 0.2s;
}

.faq-accordion__item.is-open .faq-accordion__question {
	color: var(--accent);
}

.faq-accordion__chevron {
	flex-shrink: 0;
	display: flex;
	color: var(--text-mid);
	transition: transform 0.3s var(--ease-out-expo), color 0.2s;
}

.faq-accordion__item.is-open .faq-accordion__chevron {
	transform: rotate(180deg);
	color: var(--accent);
}

.faq-accordion__answer {
	padding: 0 0 16px;
	font-family: var(--font-body);
	color: var(--text-mid);
	line-height: 1.7;
}

/* ═══════════════════════════════════════════
   Home-screen app prompt ("Missing the app?")
   Rendered site-wide from wp_footer (inc/app-prompt.php), so its CSS must live
   here - components.css is unconditional, events.css / woocommerce.css are not.
   ═══════════════════════════════════════════ */

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

.weo-app-modal {
	position: fixed;
	inset: 0;
	z-index: 9990; /* above the nav (100), cart FAB (95) and promo badge (94) */
	display: flex;
	align-items: flex-end; /* phones: rises from the bottom like a sheet */
	justify-content: center;
}

.weo-app-modal__backdrop {
	position: absolute;
	inset: 0;
	background: rgba(14, 10, 24, 0.7);
	opacity: 0;
	transition: opacity 0.3s ease;
}

.weo-app-modal.is-open .weo-app-modal__backdrop {
	opacity: 1;
}

/* Edge to edge on phones: a bottom sheet with gaps down the sides reads as a
   mistake. The 420px cap only kicks in at 640px, where it becomes a centred
   card (see the breakpoint at the end of this block). Anything narrower than
   640px is a phone, including the 440px Pro Max. */
.weo-app-modal__dialog {
	position: relative;
	width: 100%;
	max-height: calc(100dvh - 24px);
	overflow-y: auto;
	overscroll-behavior: contain;
	-webkit-overflow-scrolling: touch;
	background: var(--white);
	border-radius: var(--radius-lg) var(--radius-lg) 0 0;
	box-shadow: var(--shadow-lg);
	opacity: 0;
	transform: translateY(28px);
	transition: transform 0.4s var(--ease-out-expo), opacity 0.25s ease;
}

.weo-app-modal.is-open .weo-app-modal__dialog {
	opacity: 1;
	transform: none;
}

/* Media - flush to the top and sides of the dialog, no padding. */
.weo-app-modal__media {
	position: relative;
	aspect-ratio: 4 / 3;
	overflow: hidden;
	background: var(--muted);
}

.weo-app-modal__media-img,
.weo-app-modal__media-video {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* Sits over the media, so it needs its own contrast rather than the page's. */
.weo-app-modal__close {
	position: absolute;
	top: 12px;
	right: 12px;
	z-index: 2;
	width: 34px;
	height: 34px;
	display: flex;
	align-items: center;
	justify-content: center;
	font-size: 22px;
	line-height: 1;
	color: var(--white);
	background: rgba(14, 10, 24, 0.55);
	border-radius: 50%;
	transition: background 0.2s ease;
}

.weo-app-modal__close:hover,
.weo-app-modal__close:focus-visible {
	background: rgba(14, 10, 24, 0.8);
}

/* No image or video: the close button falls on white instead. */
.weo-app-modal--no-media .weo-app-modal__close {
	color: var(--text-mid);
	background: var(--surface);
}

.weo-app-modal--no-media .weo-app-modal__close:hover,
.weo-app-modal--no-media .weo-app-modal__close:focus-visible {
	color: var(--text-dark);
	background: var(--muted);
}

.weo-app-modal__body {
	padding: var(--space-lg);
	/* Flush to the bottom of the screen on phones, so keep the actions clear of
	   the iPhone home indicator. Reset by the shorthand at the 640px
	   breakpoint, where the dialog floats and there's nothing to avoid. */
	padding-bottom: calc(var(--space-lg) + env(safe-area-inset-bottom, 0px));
}

.weo-app-modal__title {
	margin-bottom: var(--space-sm);
}

.weo-app-modal__intro p {
	margin: 0 0 var(--space-sm);
	font-size: var(--text-s);
	line-height: 1.6;
	color: var(--text-mid);
}

.weo-app-modal__intro p:last-child {
	margin-bottom: 0;
}

/* Every browser's copy is in the DOM; js/app-prompt.js adds .is-active to the
   set that matches, and .weo-app-modal__off to anything that context hides. */
.weo-app-modal__off {
	display: none !important;
}

.weo-app-modal__lead {
	margin-top: var(--space-md);
	padding: var(--space-md);
	display: none;
	font-size: var(--text-s);
	line-height: 1.5;
	color: var(--text-dark);
	background: var(--surface);
	border-left: 3px solid var(--accent);
	border-radius: var(--radius-sm);
}

.weo-app-modal__lead.is-active {
	display: block;
}

.weo-app-modal__steps {
	display: none;
	list-style: none;
	margin: var(--space-lg) 0 0;
	padding: 0;
	counter-reset: weo-app-step;
}

.weo-app-modal__steps.is-active {
	display: grid;
	gap: var(--space-md);
}

.weo-app-modal__step {
	counter-increment: weo-app-step;
	display: grid;
	grid-template-columns: 26px 1fr;
	gap: var(--space-md);
	align-items: start;
	font-size: var(--text-s);
	line-height: 1.5;
	color: var(--text-mid);
}

.weo-app-modal__step::before {
	content: counter(weo-app-step);
	width: 26px;
	height: 26px;
	display: flex;
	align-items: center;
	justify-content: center;
	font-family: var(--font-display);
	font-size: var(--text-s);
	font-weight: 700;
	color: var(--accent);
	background: var(--accent-light);
	border-radius: 50%;
}

.weo-app-modal__step strong {
	font-weight: 600;
	color: var(--text-dark);
}

/* Inline UI glyphs (iOS share box, Android ⋮) sit on the text baseline. */
.weo-app-modal__glyph {
	display: inline-block;
	vertical-align: -3px;
	color: var(--text-dark);
}

.weo-app-modal__note {
	margin-top: var(--space-md);
	font-size: var(--text-xs);
	line-height: 1.5;
	color: var(--text-mid);
}

/* Per-browser notes follow the same show/hide rule as the steps. */
.weo-app-modal__note[data-platform] {
	display: none;
}

.weo-app-modal__note[data-platform].is-active {
	display: block;
}

.weo-app-modal__actions {
	margin-top: var(--space-lg);
	display: grid;
	gap: var(--space-xs);
}

.weo-app-modal__cta {
	width: 100%;
	justify-content: center;
}

/* The in-app "Close" button only appears in that one context. */
.weo-app-modal__cta[data-platform] {
	display: none;
}

.weo-app-modal__cta[data-platform].is-active {
	display: inline-flex;
}

.weo-app-modal__secondary {
	padding: var(--space-sm);
	font-size: var(--text-s);
	color: var(--text-mid);
	text-decoration: underline;
	transition: color 0.15s ease;
}

.weo-app-modal__secondary:hover,
.weo-app-modal__secondary:focus-visible {
	color: var(--text-dark);
}

body.weo-app-modal-open {
	overflow: hidden;
}

@media (min-width: 640px) {

	.weo-app-modal {
		align-items: center;
		padding: var(--space-lg);
	}

	.weo-app-modal__dialog {
		max-width: 420px;
		max-height: calc(100dvh - 48px);
		border-radius: var(--radius-lg);
	}

	.weo-app-modal__body {
		padding: var(--space-xl);
	}
}
