/*
 * Janda Events — the wedding landing pages.
 *
 * Figma: Wedding Entertainment 51284:10714 (1440×6030) / mobile 51288:5547,
 *        Wedding Packages (1440×5874).
 *
 * The two pages share four sections — .we-hero, .we-intro, .we-one-team and
 * .we-faq — so they share this stylesheet. The `we-` prefix is where those
 * sections were first built; treat it as "wedding", not "wedding
 * entertainment". Sections unique to one page carry .we-vibes or .wp-*.
 *
 * Every horizontal measurement below is expressed as a fraction of the 1344
 * container the desktop frames use, so the design's proportions hold as
 * --container grows past 1440 (see tokens.css).
 */

/* ==========================================================================
   Hero — Figma "Container" (1440×740)
   ========================================================================== */

.we-hero {
	position: relative;
	display: flex;
	flex-direction: column;
	min-height: 640px; /* the 428 frame; every hero in the design draws 640 here */
	padding-top: 88px; /* the header sits over this section */
	overflow: hidden;
	color: var(--c-white);
	isolation: isolate;
	background-color: var(--c-primary-900);
}

.we-hero__media {
	position: absolute;
	inset: 0;
	z-index: -1;
}

/*
 * The anchor is a property rather than the shorthand so the page's own focal
 * point, which arrives inline, and the crop weighting below, which is a
 * stylesheet rule, can each set one axis without one silently winning.
 */
.we-hero__media img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	/*
	 * --hero-focus-y-page is the page's own vertical anchor and wins outright
	 * where it is set; --hero-focus-y is the stylesheet's default below it, so
	 * the 20% top-weighting past the frame still applies to every page that
	 * leaves the field empty.
	 */
	object-position: var(--hero-focus-x, 50%) var(--hero-focus-y-page, var(--hero-focus-y, 50%));
}

/*
 * Past the 1440 frame the band holds 740 while the photo keeps scaling with the
 * viewport, so a centred crop takes progressively more off the top: 110px at
 * 1440, which is what the frame draws, but 270 at 1920 — enough to cut the
 * performers' heads off. Above the frame the crop is weighted to the top, which
 * holds the frame's headroom as the photo grows: 20% of the overflow is 91px at
 * 1792 and 193 at 2560, against the frame's own 110 scaled to 137 and 195.
 *
 * Only above 1440, so the frame width itself still renders the centred crop the
 * design specifies. A percentage rather than a length, so it stays inside the
 * overflow at every width instead of opening a gap under the photo.
 */
@media (min-width: 90.0625em) {
	.we-hero__media img {
		--hero-focus-y: 20%;
	}
}

/*
 * The Hero focal point deliberately has no reset here.
 *
 * It used to be forced back to 50% below 63.9375em, which left the field inert
 * at every width: at and above the 1440 frame cover scales by width, so the
 * photo exactly fills the band and there is no horizontal overflow for an
 * anchor to move. Narrow is the only place it can bite — which is what its own
 * instructions promise — so the reset was cancelling the one case it exists for.
 *
 * The reset was added because the Celebrants value misframed that page at 600.
 * That is a wrong value, not a wrong mechanism: each page's anchor is now set
 * against the narrow crop it actually governs. A page that leaves the field at
 * 50 is unchanged either way.
 */

/*
 * Below the 428 frame the crop runs sideways instead — the band is taller than
 * the photo is deep — and a band fixed at 640 makes it tighter with every pixel
 * the screen loses: 39% of the photo's width at 375 against the frame's own 45%.
 * That is what cuts a performer standing near the edge out of the picture.
 *
 * The visible fraction is (width / height) x the photo's own aspect, so holding
 * the band's aspect holds the crop: 640/428 of the viewport reproduces the
 * frame's framing at every width below it, whatever the photo. min-height, so a
 * page whose copy needs more still gets it.
 *
 * Where a subject sits so far off centre that even the frame's crop loses it,
 * the page's own Hero focal point field moves the anchor — see we-hero.php.
 */
@media (max-width: 26.75em) {
	.we-hero {
		min-height: 149.53vw; /* 640 / 428 */
	}
}

/*
 * The source photo is dark but not evenly so, and the 80px headline crosses
 * the brightest part of it, so the frames weight the darkening to the top.
 * See --hero-wash for the measurement.
 */
.we-hero__media::after {
	content: "";
	position: absolute;
	inset: 0;
	background-image: var(--hero-wash);
}

.we-hero__inner {
	display: flex;
	flex-direction: column;
	flex: 1 1 auto;
	justify-content: center;
	width: 100%;
	max-width: calc(var(--container) + (var(--gutter) * 2));
	margin-inline: auto;
	padding-inline: var(--gutter);
	/*
	 * .we-hero carries padding-top:88px because the header overlays the band.
	 * Mirroring it here makes this box symmetric about the *band's* centre
	 * (320 of 640), which is where the 428 frames put the group — without it,
	 * `center` resolves to 364 and everything drops 44px. Reset at 64em.
	 */
	padding-bottom: 88px;
}

/*
 * The 428 frames centre the headline and the copy together, as one block, on
 * the band's own vertical centre, and hold a constant ~24px between them.
 * Measured off the mobile exports (glyph rows → line boxes), the group centre
 * lands at 320.3–321.3 on Gallery, Wedding Entertainment, Wedding Artists,
 * About us, Articles and Resources alike, while the headline *top* is nowhere
 * near constant across them: 225.6 / 142.6 / 198.6 / 223.6 / 196.6 / 169.6.
 *
 * Pinning the headline 52.6 below the header and measuring the copy off the
 * bottom edge reproduces Wedding Entertainment exactly — its 3-line headline
 * and 6-line copy happen to fill the band, so both models agree there — but it
 * makes every pixel the band is taller than its content land *between* the
 * title and the copy. On Gallery's one-line headline that was 194.8px of dead
 * band (ticket 1217634564812693); About us 191.2, Artists/Articles 137.2.
 * Centring the pair puts the surplus above and below the group instead, and
 * still measures Wedding Entertainment's headline top at 140.6.
 *
 * The 1440 frames genuinely do pin: every desktop export puts the headline top
 * at 177 and the copy top at 449 whatever the headline length, so the
 * min-width:64em block below restores the pinned model unchanged.
 */
.we-hero__headline {
	display: flex;
	flex: 0 0 auto;
	align-items: flex-start;
	justify-content: center;
}

/*
 * The 428 frame sets 48px. base.css floors h1 at 40px for the homepage, whose
 * headline is one long unbreakable token; these headlines are short enough to
 * take the design's own floor.
 */
/*
 * The ramp's floor used to be a flat 48 — the 428 frame's size — which is the
 * one width where the longest heading we have only just fits: "Corporate/
 * Private" is a single unbreakable token measuring 379 against that frame's
 * 380 column. One pixel of slack does not survive a narrower phone. At 375 the
 * column is 327 and at 320 it is 272, so the word overhung by 52 and 107 and
 * was clipped rather than scrolled.
 *
 * Below the frame the floor now scales with the column instead of holding
 * still: 48 / 380 of whatever the gutters leave, which reproduces the frame's
 * edge-to-edge line at every narrower width rather than overshooting it. Plain
 * vw would not do — the gutters are a fixed 24 either side, so the column
 * shrinks faster than the viewport and the text would still overhang.
 *
 * min() means this only bites below 428: above it the 3rem term is the smaller
 * of the two and the ramp behaves exactly as it did.
 */
.we-hero__title {
	max-width: 940px;
	margin: 0;
	color: #f6fffe;
	font-size: clamp(
		min(3rem, calc((100vw - var(--gutter) * 2) * 0.12632)),
		1.15rem + 4.6vw,
		var(--fs-display-4xl)
	);
	text-align: center;
}

.we-hero__content {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--space-24);
	max-width: 368px;
	margin-inline: auto;
	margin-top: var(--space-24); /* the frames' constant title-to-copy gap: 23.2–25.2 measured, mean 24.3 */
	text-align: center;
}

.we-hero__text {
	margin: 0;
	color: var(--c-primary-50);
	font-size: var(--fs-body-lg);
	line-height: var(--lh-body);
}

.we-hero__angle {
	position: absolute;
	inset: auto 0 0;
	color: var(--c-ground-dark);
	line-height: 0;
	pointer-events: none;
}

.we-hero__angle .icon {
	display: block;
	width: 100%;
	height: var(--hero-angle-h);
}

@media (min-width: 64em) {
	.we-hero {
		min-height: 740px;
		padding-top: 121px;
	}

	/*
	 * The 1440 frames pin rather than centre — see the note above
	 * .we-hero__headline — so the desktop hero keeps the headline 54.5 below
	 * the 121 header and measures the copy off the bottom edge, unchanged.
	 */
	.we-hero__inner {
		justify-content: flex-start;
		padding-bottom: 0;
	}

	.we-hero__headline {
		flex: 1 1 auto;
		padding-top: 54.5px;
	}

	/* Copy sits 124px from the frame edge; 48px of that is the inner gutter. */
	.we-hero__content {
		align-items: flex-start;
		margin-top: 0;
		margin-inline: 0;
		margin-left: 76px;
		padding-bottom: 183px;
		text-align: left;
	}
}

/* ==========================================================================
   Intro — Figma "Frame 97" (1440×568)
   ========================================================================== */

.we-intro {
	padding-block: var(--space-64);
	background-color: var(--c-ground-dark);
	color: var(--c-text-on-dark);
}

.we-intro__inner {
	display: grid;
	gap: var(--space-40);
	width: 100%;
	max-width: calc(var(--container) + (var(--gutter) * 2));
	margin-inline: auto;
	padding-inline: var(--gutter);
}

.we-intro__copy {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: var(--space-24);
}

.we-intro__head {
	display: flex;
	flex-direction: column;
	gap: var(--space-12);
}

.we-intro__title {
	margin: 0;
	color: #f2efea;
}

.we-intro__text {
	margin: 0;
	font-size: var(--fs-body-lg);
}

/* The Experience page's intro runs to two paragraphs; every other page sets a
   single one, so this leaves them looking exactly as they did. */
.we-intro__text p {
	margin: 0;
}

.we-intro__text p + p {
	margin-top: 1em;
}

/*
 * Special Offers only — the bulleted "what goes wrong with separate vendors"
 * list between the copy and the button. The disc is drawn from the font, so
 * the body face at 600 gives it the weight the frame has; same construction as
 * the split band's list.
 */
.we-intro__list {
	display: flex;
	flex-direction: column;
	gap: var(--space-8);
	margin: 0;
	padding-left: 1.5em;
	font-size: var(--fs-body-lg);
	list-style: disc outside;
}

.we-intro__list li::marker {
	font-family: var(--font-body);
	font-weight: 600;
}

/* position for the play button; the media box itself is identical whether it
   holds a photo or a video poster. */
.we-intro__media {
	position: relative;
	margin: 0;
}

/* Portrait on the 428 frame, landscape on the 1440 one. Measured off the
   Wedding Artists frames: 380×440 at 428, 600×440 at 1440 — the same box the
   photo uses, so the video needs no separate ratio. */
.we-intro__media :is(img, video) {
	display: block;
	width: 100%;
	height: auto;
	aspect-ratio: 380 / 440;
	object-fit: cover;
}

/*
 * Click-to-play overlay — Figma 51284:8961. A 72px translucent white disc with
 * a solid triangle, centred on the poster. It is a real <button>, so it is
 * focusable and announces itself; JS swaps it for the native controls on play.
 */
.we-intro__play {
	position: absolute;
	top: 50%;
	left: 50%;
	translate: -50% -50%;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 72px;
	height: 72px;
	padding: 0;
	border: 0;
	border-radius: var(--radius-circle);
	background-color: rgba(255, 255, 255, 0.35);
	color: var(--c-white);
	cursor: pointer;
	transition: background-color var(--dur-fast) var(--ease), scale var(--dur-fast) var(--ease);
}

.we-intro__play .icon {
	width: 28px;
	height: 28px;
	/* The glyph's own mass sits right of centre, so nudge it back into the disc. */
	margin-left: 3px;
}

.we-intro__play:hover,
.we-intro__play:focus-visible {
	background-color: rgba(255, 255, 255, 0.55);
	scale: 1.06;
}

/* Once it is playing the poster is gone and the native controls take over. */
.we-intro__media.is-playing .we-intro__play {
	display: none;
}

@media (prefers-reduced-motion: reduce) {
	.we-intro__play {
		transition: none;
	}

	.we-intro__play:hover,
	.we-intro__play:focus-visible {
		scale: 1;
	}
}

@media (min-width: 64em) {
	/* Photo is 600 of the 1344 container and sits flush to its right edge. */
	.we-intro__inner {
		grid-template-columns: minmax(0, 1fr) 44.64%;
		align-items: center;
		column-gap: var(--space-48);
	}

	.we-intro__copy {
		max-width: 578px;
	}

	/*
	 * 600x440 in the frame, and it stops there. The copy column is already
	 * capped at the frame's 578, so letting the media keep taking 44.64% of a
	 * container that goes on scaling past 1440 pulled the row out of the
	 * frame's proportions — 733 wide against a 578 copy at 2000, where the
	 * frame draws 600 against 578. Flush right, as the frame has it.
	 */
	.we-intro__media {
		max-width: 600px;
		margin-left: auto;
	}

	.we-intro__media :is(img, video) {
		aspect-ratio: 600 / 440;
	}

	/*
	 * With the list in place the copy column is 656 of the 1344 container and
	 * the photo fills whatever height the copy sets (600×549 in the frame)
	 * rather than holding a ratio of its own.
	 */
	.we-intro--list .we-intro__inner {
		align-items: stretch;
	}

	.we-intro--list .we-intro__copy {
		max-width: 656px;
		justify-content: center;
	}

	.we-intro--list .we-intro__media :is(img, video) {
		aspect-ratio: auto;
		height: 100%;
		min-height: 440px;
	}
}

/* ==========================================================================
   The Vibes To Match Your Freak — Figma "Frame 1984078277" (1440×1842)
   ========================================================================== */

.we-vibes {
	padding-block: var(--space-32) var(--space-64);
	background-color: var(--c-ground-mist);
}

.we-vibes__inner {
	width: 100%;
	max-width: calc(var(--container) + (var(--gutter) * 2));
	margin-inline: auto;
	padding-inline: var(--gutter);
}

/* Wide enough to hold "The Vibes To Match Your" on one line, as designed. */
.we-vibes__title {
	max-width: 760px;
	margin: 0 auto var(--space-48);
	color: var(--c-primary-500);
	text-align: center;
}

/* 1440 frame: 48 above the rule and 48 below. 428 frame: 56 above, 24 below. */
.we-vibes__row + .we-vibes__row {
	margin-top: var(--space-56);
	padding-top: var(--space-24);
	border-top: 1px solid #e6e6e6;
}

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

.card-entertainment {
	display: grid;
	gap: var(--space-24);
}

.card-entertainment__media {
	margin: 0;
}

/* The 428 frame crops these much squarer than the 1440 one does. */
.card-entertainment__media img {
	width: 100%;
	height: auto;
	aspect-ratio: 380 / 340;
	object-fit: cover;
	border-radius: var(--radius-lg);
}

/* Inset from the photo, which runs the full width of the container. */
.card-entertainment__copy {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: var(--space-24);
	padding-inline: var(--space-24);
}

.card-entertainment__head {
	display: flex;
	flex-direction: column;
	gap: var(--space-24);
}

/* The design sets these titles in black rather than the usual heading teal. */
.card-entertainment__title {
	margin: 0;
	color: var(--c-black);
}

.card-entertainment__text {
	margin: 0;
	font-size: var(--fs-body-lg);
}

.card-entertainment__text p {
	margin: 0;
}

.card-entertainment__text p + p {
	margin-top: 1em;
}

/*
 * A serif text link, not the sans .link-arrow used elsewhere. The padding is
 * cancelled by the matching negative margin: it buys a 45px tap target without
 * changing where the link sits.
 */
.card-entertainment__link {
	display: inline-flex;
	align-items: center;
	gap: var(--space-8);
	padding-block: 11px;
	margin-block: -11px;
	color: var(--c-primary-500);
	font-family: var(--font-display);
	font-size: var(--fs-body-lg);
	line-height: 1.3;
	text-decoration: none;
}

.card-entertainment__link .icon {
	width: 20px;
	height: 20px;
	transition: transform var(--dur-fast) var(--ease);
}

.card-entertainment__link:hover {
	color: var(--c-primary-800);
}

.card-entertainment__link:hover .icon {
	transform: translateX(2px);
}

@media (min-width: 64em) {
	/*
	 * 672 photo + 62 gutter + 560 copy = 1294 of the 1344 container. The 50px
	 * remainder is what makes the rows read as alternating: odd rows sit against
	 * the container's left edge, even rows against its right.
	 */
	.card-entertainment {
		grid-template-columns: 50% 41.667%;
		column-gap: 4.613%;
		align-items: center;
		justify-content: start;
	}

	.card-entertainment__media img {
		aspect-ratio: 672 / 440;
	}

	.we-vibes {
		padding-block: var(--space-64);
	}

	.card-entertainment__copy {
		padding-inline: 0;
	}

	.we-vibes__row + .we-vibes__row {
		margin-top: var(--space-48);
		padding-top: var(--space-48);
	}

	/*
	 * Reversed rows mirror the whole thing: the copy takes the narrow track on
	 * the left, the photo keeps its 672 on the right. Placing both explicitly
	 * (rather than reordering) is what keeps the photo the wider of the two.
	 * The DOM order stays photo-then-copy for screen readers either way.
	 */
	.we-vibes__row:nth-child(even) .card-entertainment {
		grid-template-columns: 41.667% 50%;
		justify-content: end;
	}

	.we-vibes__row:nth-child(even) .card-entertainment__media {
		grid-area: 1 / 2;
	}

	.we-vibes__row:nth-child(even) .card-entertainment__copy {
		grid-area: 1 / 1;
	}
}

/* ==========================================================================
   One Team — Figma "Frame 1984078271" (1440×677)
   ========================================================================== */

.we-one-team {
	padding-block: var(--space-64) var(--space-32);
	overflow: hidden;
	background-color: var(--c-ground-light);
}

.we-one-team__inner {
	display: grid;
	gap: var(--space-40);
	width: 100%;
	max-width: calc(var(--container) + (var(--gutter) * 2));
	margin-inline: auto;
	padding-inline: var(--gutter);
}

.we-one-team__copy {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: var(--space-24);
	padding-right: var(--space-24);
}

/* Set larger than the other 48px display headings on the 428 frame. */
.we-one-team__title {
	margin: 0;
	color: var(--c-primary-500);
	font-size: 2.5rem;
}

/* 18/27, same as the other body copy on these pages. */
.we-one-team__text {
	margin: 0;
	font-size: var(--fs-body-lg);
}

.we-one-team__text p {
	margin: 0;
}

.we-one-team__text p + p {
	margin-top: 1em;
}

/*
 * Three photo columns that run to the viewport edge rather than stopping at the
 * container gutter. On mobile they bleed both ways and scroll.
 */
.we-one-team__gallery {
	display: grid;
	grid-auto-flow: column;
	/* Three across the viewport, as the 428 frame shows them. */
	grid-auto-columns: calc((100% - (var(--space-8) * 2)) / 3);
	gap: var(--space-8);
	margin-inline: calc(var(--gutter) * -1);
	overflow-x: auto;
	scroll-snap-type: x mandatory;
	scrollbar-width: none;
}

.we-one-team__gallery::-webkit-scrollbar {
	display: none;
}

.we-one-team__gallery > li {
	scroll-snap-align: start;
}

.we-one-team__gallery img {
	width: 100%;
	height: auto;
	aspect-ratio: 140 / 340;
	object-fit: cover;
}

@media (min-width: 64em) {
	.we-one-team {
		padding-block: var(--space-64);
	}

	/* Copy occupies the first 524px of the container, the gallery the rest. */
	.we-one-team__inner {
		grid-template-columns: 39% minmax(0, 1fr);
		align-items: center;
		column-gap: 0;
	}

	/* 42px inside the container's own gutter, so the copy starts 90px in. */
	.we-one-team__copy {
		max-width: 420px;
		padding-left: 8%;
		padding-right: 0;
	}

	.we-one-team__gallery {
		grid-auto-columns: 1fr;
		margin-inline: 0 calc(var(--gutter) * -1);
		overflow: visible;
	}

	.we-one-team__gallery img {
		aspect-ratio: 284 / 548;
	}

	.we-one-team__title {
		font-size: var(--fs-display-2xl);
	}

	/*
	 * The package frames and the Special Offers "One Line of Communication"
	 * band mirror this one — photos in the left column running off the LEFT
	 * edge, copy on the right. Everything else about it is the same, so it is a
	 * flip rather than a second section.
	 */
	.we-one-team--reverse .we-one-team__inner {
		grid-template-columns: minmax(0, 1fr) 39%;
	}

	.we-one-team--reverse .we-one-team__copy {
		grid-column: 2;
		padding-left: 8%;
		padding-right: 0;
	}

	.we-one-team--reverse .we-one-team__gallery {
		grid-row: 1;
		grid-column: 1;
		margin-inline: calc(var(--gutter) * -1) 0;
	}
}

/* Stacked, the Special Offers frame leads with the photo row and puts the copy
   under it — the reverse of what the other pages running this band do. */
@media (max-width: 63.999em) {
	.page-template-template-special-offers .we-one-team__gallery {
		order: -1;
	}
}

/*
 * The Special Offers frame gives this band a wider copy column than the
 * package frames do (462 of 1344 against 420) and 82px of air above and below
 * the photo columns rather than 64.
 */
@media (min-width: 64em) {
	.page-template-template-special-offers .we-one-team {
		padding-block: 82px;
	}

	.page-template-template-special-offers .we-one-team__copy {
		max-width: 462px;
	}
}

/* ==========================================================================
   FAQ — Figma "Frame 1984078278" (1440×1061)
   ========================================================================== */

.we-faq {
	position: relative;
	padding-block: var(--space-32);
	overflow: hidden;
	background-color: var(--c-ground-frost);
}

/*
 * The "I do and Yewww" lockup, decorative background rather than content. It is
 * positioned against the container, not the viewport: anchoring to the viewport
 * instead would let its offset grow every pixel past 1440. Offsets are measured
 * from .we-faq__inner's border box, which includes its gutter.
 *
 * This replaced a full-bleed filigree watermark at 20%. A logo cannot be run
 * behind copy the way that watermark was, so below the desktop breakpoint —
 * where the accordion is full width and there is no column to sit in — it stays
 * small, corners itself, and drops back far enough to keep the text readable.
 */
/*
 * Below the desktop breakpoint the accordion runs full width, so there is no
 * column for the mark to sit in and nothing to absolutely position it against
 * without landing on the heading. It stays in the flow there — mark, heading,
 * accordion — and only becomes a watermark once there is a column for it.
 */
.we-faq__doodles {
	position: static;
	width: 112px;
	margin: 0 auto var(--space-24);
	pointer-events: none;
}

.we-faq__art {
	display: block;
	width: 100%;
	height: auto;
}

.we-faq__inner {
	position: relative;
	display: flex;
	flex-direction: column;
	width: 100%;
	max-width: calc(var(--container) + (var(--gutter) * 2));
	margin-inline: auto;
	padding-inline: var(--gutter);
}

.we-faq__title {
	margin: 0 0 var(--space-48);
	color: var(--c-primary-500);
}

.we-faq__item {
	border-top: 1px solid #e6e6e6;
}

.we-faq__question {
	display: grid;
	grid-template-columns: 2.375rem minmax(0, 1fr) 1.5rem;
	align-items: start;
	gap: var(--space-8);
	padding-block: var(--space-24);
	cursor: pointer;
	list-style: none;
}

/* Safari still paints its own triangle without this. */
.we-faq__question::-webkit-details-marker {
	display: none;
}

.we-faq__number {
	font-family: var(--font-display);
	font-style: italic;
	font-size: var(--fs-body-lg);
	letter-spacing: 0.02em;
	line-height: 1.6;
	color: var(--c-black);
}

.we-faq__label {
	padding-right: var(--space-16);
	font-family: var(--font-display);
	font-size: 1.75rem;
	line-height: var(--lh-display);
	color: var(--c-black);
}

.we-faq__chevron {
	width: 1.5rem;
	height: 1.5rem;
	margin-top: 0.35em;
	color: var(--c-black);
	transform: rotate(180deg);
	transition: transform var(--dur) var(--ease);
}

.we-faq__item[open] .we-faq__chevron {
	transform: rotate(0deg);
}

/*
 * While app.js slides an answer shut the item is still [open], so the chevron
 * has to follow the intent rather than the attribute or it flips a beat late.
 */
.we-faq__item[data-closing] .we-faq__chevron {
	transform: rotate(180deg);
}

/*
 * This is the element app.js animates, so it carries no padding of its own.
 * Under border-box a height animation is clamped to at least its padding, so
 * padding here would stop the slide at 24px instead of 0 — leaving the section
 * 24px too tall for the whole transition and jogging the band below it. The
 * spacing sits on the inner element instead, which nothing animates.
 */
.we-faq__answer {
	color: var(--c-body);
}

.we-faq__answer-inner {
	padding: 0 var(--space-40) var(--space-24) 2.875rem;
}

.we-faq__answer p {
	margin: 0;
}

.we-faq__answer p + p {
	margin-top: 1em;
}

/*
 * Keep the FAQ in its centred, stacked treatment through tablet landscape
 * (including 1024px Tablet Pro). The two-column composition needs enough
 * horizontal room for the artwork and accordion to remain visually balanced.
 */
@media (min-width: 75em) {
	.we-faq {
		padding-block: var(--space-64);
	}

	.we-faq__label {
		padding-right: 0;
	}

	/*
	 * The accordion starts at 34%, so the lockup gets the column to its left to
	 * itself and can draw at full strength, centred in that space.
	 */
	.we-faq__doodles {
		position: absolute;
		top: 50%;
		/*
		 * The FAQ list begins 34% into the inner content box. Its left edge
		 * includes the inner gutter, while an absolutely-positioned child uses
		 * the inner padding box for percentage offsets. Account for that small
		 * difference so the artwork is centred in the complete left column,
		 * rather than a few pixels left of centre on wide screens.
		 */
		left: calc(17% + (var(--gutter) * 0.16));
		width: 200px;
		margin: 0;
		transform: translate(-50%, -50%);
	}

	/*
	 * Heading and accordion start at the same 34% offset, leaving the doodles
	 * the space beside them. The accordion runs the rest of the container; the
	 * heading is capped short of it so it breaks after "Asked", as designed.
	 */
	.we-faq__list {
		width: 66%;
		margin-left: 34%;
	}

	.we-faq__title {
		max-width: 600px;
		margin-left: 34%;
	}

	.we-faq__question {
		grid-template-columns: 3.125rem minmax(0, 1fr) 1.5rem;
		gap: var(--space-16);
	}

	.we-faq__label {
		font-size: 2rem;
	}

	.we-faq__answer-inner {
		padding-left: calc(3.125rem + var(--space-16));
		padding-right: 3.5rem;
	}
}

/* ==========================================================================
   Our Signature Wedding Packages — Wedding Packages page
   ========================================================================== */

.wp-signature {
	padding-block: var(--space-64);
	background-color: var(--c-ground-mist);
}

.wp-signature__inner {
	width: 100%;
	max-width: calc(var(--container) + (var(--gutter) * 2));
	margin-inline: auto;
	padding-inline: var(--gutter);
}

/* Narrow enough to break after "Our Signature", as designed. */
.wp-signature__title {
	max-width: 600px;
	margin: 0 auto var(--space-48);
	color: var(--c-primary-500);
	text-align: center;
}

/*
 * A centred rail rather than a container-aligned one: the design puts the
 * active card in the middle of the frame and lets its neighbours run off both
 * edges. The padding is a percentage of the section — not vw — so a scrollbar
 * cannot push the page sideways.
 */
.wp-signature__rail {
	--wp-card: 840px;

	gap: 25px;
	padding-inline: max(var(--gutter), calc(50% - (var(--wp-card) / 2)));
	scroll-padding-inline: 0;
}

.wp-signature__rail > li {
	flex-basis: min(var(--wp-card), 100%);
	scroll-snap-align: center;
}

.card-package-detail {
	position: relative;
	display: grid;
	gap: var(--space-16);
	height: 100%;
	padding: 10px;
	overflow: hidden;
	isolation: isolate;
	border: 1px solid var(--c-border);
	border-radius: var(--radius-lg);
	background-color: var(--c-white);
}

/*
 * Hover: the photo grows out of its column to fill the card and the copy
 * inverts on top of it. Done with a background layer that cross-fades rather
 * than by animating the real image out of its grid cell — grid placement is
 * not animatable, and this way the resting layout is untouched.
 */
.card-package-detail__cover {
	position: absolute;
	inset: 0;
	z-index: 0;
	background-position: center;
	background-size: cover;
	opacity: 0;
	scale: 1.08;
	pointer-events: none;
}

.card-package-detail__cover::after {
	content: "";
	position: absolute;
	inset: 0;
	background-image: linear-gradient(to top, rgba(0, 0, 0, 0.82), rgba(0, 0, 0, 0.45));
}

.card-package-detail--monochrome .card-package-detail__media img,
.card-package-detail--monochrome .card-package-detail__cover {
	filter: grayscale(1);
}

.card-package-detail__media,
.card-package-detail__body {
	position: relative;
	z-index: 1;
}

/* A grid item defaults to min-width: auto, which would hold the photo column
   open at its intrinsic width and stop the hover collapse. */
.card-package-detail__media {
	min-width: 0;
	overflow: hidden;
}

@media (hover: hover) and (pointer: fine) {
	.card-package-detail__cover {
		transition: opacity 420ms var(--ease), scale 700ms cubic-bezier(0.22, 1, 0.36, 1);
	}

	.card-package-detail__media {
		transition: opacity 320ms var(--ease);
	}

	.card-package-detail :is(.card-package-detail__title, .card-package-detail__text, .card-package-detail__link),
	.card-package-detail__specs :is(dt, dd) {
		transition: color 320ms var(--ease);
	}

	.card-package-detail:hover .card-package-detail__cover,
	.card-package-detail:focus-within .card-package-detail__cover {
		opacity: 1;
		scale: 1;
	}

	/* The column photo steps aside so the full-card one reads cleanly. */
	.card-package-detail:hover .card-package-detail__media,
	.card-package-detail:focus-within .card-package-detail__media {
		opacity: 0;
	}

	.card-package-detail:hover :is(.card-package-detail__title, .card-package-detail__text, .card-package-detail__link),
	.card-package-detail:hover .card-package-detail__specs :is(dt, dd),
	.card-package-detail:focus-within :is(.card-package-detail__title, .card-package-detail__text, .card-package-detail__link),
	.card-package-detail:focus-within .card-package-detail__specs :is(dt, dd) {
		color: var(--c-white);
	}

	@media (prefers-reduced-motion: reduce) {
		.card-package-detail__cover {
			scale: 1;
			transition: opacity 420ms linear;
		}
	}
}

/* ==========================================================================
   Add To The Experience — Wedding Packages page
   ========================================================================== */

.wp-experience {
	padding-block: var(--space-64);
	overflow: hidden;
	background-color: var(--c-ground-light);
}

.wp-experience__inner {
	width: 100%;
	max-width: calc(var(--container) + (var(--gutter) * 2));
	margin-inline: auto;
	padding-inline: var(--gutter);
}

.wp-experience__head {
	max-width: 640px;
	margin: 0 auto var(--space-48);
	text-align: center;
}

.wp-experience__title {
	margin: 0 0 var(--space-16);
	color: var(--c-primary-500);
}

.wp-experience__text {
	margin: 0;
}

/*
 * Anchored to the container on the left and run off the right edge of the
 * screen, which is how the design's frame cuts the fifth card.
 *
 * The right margin is pulled out to the viewport rather than stopping at the
 * container. Stopping there left the cut card floating with a gap beside it
 * that grew with the screen — 121px at 1990, 361px at 2560 — space the design
 * does not have. min() picks whichever pull is larger, so below the container
 * width the rule falls back to the plain -gutter and nothing changes.
 *
 * 100vw includes the scrollbar, so this overshoots by its width; the section's
 * own overflow: hidden clips that off.
 */
.wp-experience__rail {
	gap: 17px;
	margin-left: calc(var(--gutter) * -1);
	margin-right: min(
		calc(var(--gutter) * -1),
		calc((var(--container) + (var(--gutter) * 2) - 100vw) / 2 - var(--gutter))
	);
	padding-inline: var(--gutter);
}

.wp-experience__rail > li {
	flex-basis: min(323px, 78%);
}

.wp-experience__nav,
.wp-signature__nav {
	display: flex;
	justify-content: center;
	gap: var(--space-8);
	margin-top: var(--space-24);
}

.wp-experience__nav .rail-btn:first-child .icon {
	transform: rotate(180deg);
}

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

/*
 * The card itself now lives in components.css: the homepage's Why Us rail
 * draws the same card for the service posts, and this sheet is not loaded
 * there. Only the rail's own column sizing stays here.
 */



@media (min-width: 64em) {
	/* Four cards across the container, 17px apart. Measured against the
	   container and not the rail's own 100% — the rail now runs wider than the
	   container, so a percentage would let the cards grow with the bleed.
	   min() keeps the old behaviour where the rail is the narrower of the two:
	   --container is derived from vw, which counts the scrollbar, so at 1440
	   with one showing the container is 15px wider than the space the cards
	   actually have and four of them would push the fifth off the sliver. */
	.wp-experience__rail > li {
		flex-basis: calc((min(100%, var(--container)) - 51px) / 4);
	}

	/*
	 * Three cards fill the container in thirds rather than sitting as three
	 * quarters with a gap on the right — Frame 1984078309 draws them edge to
	 * edge. A quantity query rather than a class, so the rail follows whatever
	 * the page picks: the Wedding Packages page drops the Wedding Package card
	 * because that is the page you are already on, and other pages showing all
	 * four keep the 4-across above. 34px is the two gaps between three cards.
	 */
	.wp-experience__rail > li:first-child:nth-last-child(3),
	.wp-experience__rail > li:first-child:nth-last-child(3) ~ li {
		flex-basis: calc((min(100%, var(--container)) - 34px) / 3);
	}
}


/* Client revision helpers. */
.we-hero__kicker {
	margin: 0 0 var(--space-12);
	color: var(--c-primary-50);
	font-size: var(--fs-body-md);
	font-weight: var(--fw-medium);
	letter-spacing: .08em;
	text-align: center;
	text-transform: uppercase;
}
.wp-signature__subtitle {
	max-width: 680px;
	margin: calc(var(--space-48) * -1 + var(--space-16)) auto var(--space-48);
	color: var(--c-body);
	font-size: var(--fs-body-lg);
	line-height: var(--lh-body);
	text-align: center;
}
@media (min-width: 64em) {
	.we-hero__kicker { text-align: center; }
}
