/**
 * Invitely front end.
 *
 * The block inherits the theme's typeface on purpose so an invitation looks
 * like part of the site. Every colour is a custom property, so a theme or
 * child plugin can restyle the whole block by redefining these four values.
 */

.invitely {
	--invitely-accent: #14504a;
	--invitely-accent-soft: #e6efed;
	--invitely-ink: #1d1d1b;
	--invitely-muted: #6f6d67;
	--invitely-line: #e2e0da;
	--invitely-paper: #fbfbf9;
	--invitely-field-bg: #ffffff;
	--invitely-field-ink: #1d1d1b;
	--invitely-placeholder: #8b887f;
	--invitely-radius: 10px;
	--invitely-scale: 1;
	--invitely-font: inherit;

	margin: 2.5rem 0 0;
	color: var(--invitely-ink);
	/* Everything inside sizes from here, so one scale value moves the whole
	   block without touching individual rules. */
	font-family: var(--invitely-font);
	font-size: calc( 1rem * var(--invitely-scale) );
	line-height: 1.55;
}

.invitely-card,
.invitely-card * {
	font-family: inherit;
}

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

/* ---------------------------------------------------------------- Facts */

.invitely-facts {
	display: grid;
	color: var(--invitely-ink);
	gap: 1rem;
	grid-template-columns: repeat( auto-fit, minmax( 220px, 1fr ) );
	margin: 0 0 1.75rem;
	padding: 1.25rem 1.35rem;
	background: var(--invitely-paper);
	border: 1px solid var(--invitely-line);
	border-radius: var(--invitely-radius);
}

/*
 * When and Where are section headings, the same as Payment and Are you coming.
 * They were set as small uppercase labels, which put them in a different visual
 * class from the sections they sit beside.
 */
.invitely-fact dt {
	margin: 0 0 0.4rem;
	font-weight: 600;
	letter-spacing: normal;
	text-transform: none;
}

.invitely-fact dd {
	margin: 0;
	font-size: 1.02rem;
}

.invitely-venue,
.invitely-address,
.invitely-maplink {
	display: block;
}

/*
 * These read as part of the details rather than as separate interface, so they
 * take the body colour. The accent stays for things that are genuinely actions
 * elsewhere in the block.
 */
.invitely-address {
	color: var(--invitely-ink);
	font-size: 0.94rem;
}

.invitely .invitely-maplink {
	margin-top: 0.35rem;
	color: var(--invitely-ink);
	font-size: 0.9rem;
	text-decoration: underline;
	text-underline-offset: 0.15em;
}

.invitely .invitely-maplink:hover,
.invitely .invitely-maplink:focus {
	color: var(--invitely-ink);
	opacity: 0.75;
}

/* ------------------------------------------------------------- Messages */

.invitely-alert {
	margin: 0 0 1.25rem;
	padding: 0.85rem 1.05rem;
	border-radius: 8px;
	border-left: 3px solid var(--invitely-line);
	background: var(--invitely-paper);
	font-size: 0.95rem;
}

.invitely-alert strong {
	display: block;
}

.invitely-alert--ok {
	border-left-color: var(--invitely-accent);
	background: var(--invitely-accent-soft);
}

.invitely-alert--error {
	border-left-color: #a3352a;
	background: #fbeeec;
}

.invitely-alert--muted {
	color: var(--invitely-muted);
}

/* ------------------------------------------------------------ Headcount */

.invitely-headcount {
	margin: 0 0 1.75rem;
}

.invitely-headcount__line {
	margin: 0 0 0.65rem;
	font-size: 1.05rem;
}

.invitely-headcount__line strong {
	font-size: 1.65rem;
	font-variant-numeric: tabular-nums;
	line-height: 1;
}

/*
 * Signature: one mark per seat. The remaining room in the venue is the thing
 * a guest actually wants to know, so the count is drawn rather than stated.
 * Falls back to a plain number above 120 seats, where marks stop being
 * countable at a glance.
 */
.invitely-seats {
	display: flex;
	flex-wrap: wrap;
	gap: 4px;
	margin: 0 0 0.9rem;
	max-width: 30rem;
}

.invitely-seat {
	width: 11px;
	height: 11px;
	border: 1px solid var(--invitely-line);
	border-radius: 2px;
	background: transparent;
}

.invitely-seat.is-taken {
	border-color: var(--invitely-accent);
	background: var(--invitely-accent);
}

.invitely-tally {
	display: flex;
	flex-wrap: wrap;
	gap: 0.35rem 1.15rem;
	margin: 0;
	padding: 0;
	list-style: none;
	color: var(--invitely-muted);
	font-size: 0.88rem;
}

.invitely-tally span {
	color: var(--invitely-ink);
	font-weight: 600;
	font-variant-numeric: tabular-nums;
}

/* ----------------------------------------------------------------- Form */

.invitely-form {
	margin: 0 0 2rem;
	padding: 1.5rem;
	background: var(--invitely-paper);
	border: 1px solid var(--invitely-line);
	border-radius: var(--invitely-radius);
}

.invitely-form__title {
	margin: 0 0 1.1rem;
	font-size: 1.15rem;
}

.invitely-hp {
	position: absolute !important;
	left: -9999px;
	width: 1px;
	height: 1px;
	overflow: hidden;
}

.invitely-choices legend,
.invitely .screen-reader-text {
	position: absolute !important;
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	overflow: hidden;
	clip: rect( 0 0 0 0 );
	clip-path: inset( 50% );
	white-space: nowrap;
	border: 0;
}

.invitely-choices {
	display: flex;
	flex-wrap: wrap;
	gap: 0.55rem;
	margin: 0 0 1.35rem;
	padding: 0;
	border: 0;
}

.invitely-choice {
	position: relative;
	flex: 1 1 8rem;
}

.invitely-choice input {
	position: absolute;
	opacity: 0;
	width: 1px;
	height: 1px;
}

.invitely-choice span {
	display: block;
	padding: 0.7rem 0.9rem;
	background: #fff;
	border: 1px solid var(--invitely-line);
	border-radius: 8px;
	cursor: pointer;
	font-size: 0.95rem;
	text-align: center;
	transition: border-color 0.12s ease, background-color 0.12s ease;
}

.invitely-choice input:checked + span {
	border-color: var(--invitely-accent);
	background: var(--invitely-accent-soft);
	box-shadow: inset 0 0 0 1px var(--invitely-accent);
	font-weight: 600;
}

.invitely-choice input:focus-visible + span {
	outline: 2px solid var(--invitely-accent);
	outline-offset: 2px;
}

.invitely-fields {
	display: grid;
	gap: 0 1rem;
	grid-template-columns: repeat( auto-fit, minmax( 200px, 1fr ) );
}

.invitely-field {
	margin: 0 0 1rem;
}

.invitely-field label {
	display: block;
	margin: 0 0 0.3rem;
	color: var(--invitely-muted);
	font-size: 0.8rem;
	font-weight: 600;
	letter-spacing: 0.045em;
	text-transform: uppercase;
}

/*
 * One rule for every control. Listing input types individually meant url,
 * tel, datetime-local, password, and select inherited whatever the theme
 * did, so a single form rendered in two different styles.
 */
.invitely input:not([type="checkbox"]):not([type="radio"]):not([type="submit"]):not([type="button"]),
.invitely textarea,
.invitely select {
	width: 100%;
	max-width: 100%;
	padding: 0.6rem 0.7rem;
	/*
	 * These two carry !important, which is not a habit but a decision. This
	 * block renders inside somebody else's theme, and page builders emit
	 * high-specificity control styling from their global kit. Losing that
	 * race makes the form unreadable rather than merely off-brand, so these
	 * two properties are held. Everything else here stays overridable.
	 */
	background: var(--invitely-input-bg, var(--invitely-field-bg)) !important;
	color: var(--invitely-input-ink, var(--invitely-field-ink)) !important;
	border: 1px solid var(--invitely-input-border, var(--invitely-line));
	border-radius: 7px;
	font: inherit;
	font-size: 0.98rem;
	line-height: 1.4;
}

.invitely input::placeholder,
.invitely textarea::placeholder {
	color: var(--invitely-placeholder);
	opacity: 1;
}

.invitely input:focus,
.invitely textarea:focus,
.invitely select:focus {
	border-color: var(--invitely-accent);
	outline: 2px solid var(--invitely-accent);
	outline-offset: 1px;
}

/*
 * Links. Themes style content anchors freely, and a link colour close to the
 * page background makes controls vanish rather than merely look wrong, so
 * these are set rather than inherited.
 */
.invitely a {
	color: var(--invitely-accent);
	text-decoration: underline;
	text-underline-offset: 0.15em;
}

.invitely a:hover,
.invitely a:focus {
	color: var(--invitely-accent);
	text-decoration: underline;
}

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

/* Buttons that happen to be anchors keep their own colour. */
.invitely a.invitely-btn {
	color: #fff;
	text-decoration: none;
}

.invitely a.invitely-btn--ghost {
	color: var(--invitely-ink);
}

/* Some themes force a colour onto every heading and label inside content. */
.invitely label,
.invitely legend,
.invitely dt,
.invitely dd,
.invitely h2,
.invitely h3 {
	color: var(--invitely-ink);
}

.invitely-field label {
	color: var(--invitely-muted);
}

.invitely-field--party select {
	max-width: 8rem;
}

/* Sits with the reply buttons, not with the contact details below. */
.invitely-field--party {
	margin-top: -0.4rem;
	margin-bottom: 1.25rem;
}

.invitely-field--party[hidden] {
	display: none;
}

.invitely-hint {
	display: inline-block;
	margin-left: 0.6rem;
	color: var(--invitely-muted);
	font-size: 0.85rem;
}

.invitely-submit {
	margin: 0.5rem 0 0;
}

.invitely-btn {
	display: inline-block;
	padding: 0.75rem 1.5rem;
	background: var(--invitely-accent);
	border: 0;
	border-radius: 7px;
	color: #fff;
	cursor: pointer;
	font: inherit;
	font-size: 0.98rem;
	font-weight: 600;
	text-decoration: none;
}

.invitely-btn:hover,
.invitely-btn:focus {
	color: #fff;
	filter: brightness( 1.12 );
}

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

/* -------------------------------------------------------------- Payment */

.invitely-pay {
	margin: 0 0 1.75rem;
	padding: 1.25rem 1.35rem;
	background: #fff;
	border: 1px solid var(--invitely-line);
	border-radius: var(--invitely-radius);
}

.invitely-pay__ref {
	margin: 0 0 0.75rem;
	color: var(--invitely-muted);
	font-size: 0.78rem;
	font-weight: 600;
	letter-spacing: 0.08em;
	text-transform: uppercase;
}

.invitely-pay__ref code {
	display: inline-block;
	margin-left: 0.5rem;
	padding: 0.15rem 0.45rem;
	background: var(--invitely-accent-soft);
	border-radius: 4px;
	color: var(--invitely-ink);
	font-size: 0.95rem;
	letter-spacing: 0.04em;
	text-transform: none;
}

.invitely-pay__note {
	margin: 0 0 1rem;
	font-size: 0.96rem;
}

/* ----------------------------------------------------------- Guest list */

.invitely-guestlist__title {
	margin: 0 0 0.9rem;
	font-size: 1.05rem;
}

.invitely-guests {
	display: grid;
	gap: 0.4rem 1.25rem;
	grid-template-columns: repeat( auto-fill, minmax( 180px, 1fr ) );
	margin: 0;
	padding: 0;
	list-style: none;
}

.invitely-guest {
	display: flex;
	align-items: baseline;
	gap: 0.4rem;
	padding: 0.35rem 0;
	border-bottom: 1px solid var(--invitely-line);
	font-size: 0.95rem;
}

.invitely-guest__party,
.invitely-guest__tag {
	color: var(--invitely-muted);
	font-size: 0.8rem;
}

.invitely-guest__tag {
	padding: 0.05rem 0.4rem;
	background: var(--invitely-paper);
	border: 1px solid var(--invitely-line);
	border-radius: 20px;
}

.invitely-guest.is-maybe .invitely-guest__name {
	color: var(--invitely-muted);
}

.invitely-empty {
	color: var(--invitely-muted);
	font-size: 0.95rem;
}

/* --------------------------------------------------------------- Detail */

@media ( max-width: 600px ) {
	.invitely-form {
		padding: 1.15rem;
	}

	.invitely-choice {
		flex-basis: 100%;
	}
}

@media ( prefers-reduced-motion: reduce ) {
	.invitely *,
	.invitely *::before,
	.invitely *::after {
		transition-duration: 0.01ms !important;
	}
}

/*
 * Dark surfaces are opt-in, never automatic. Add data-invitely-theme="dark"
 * to a wrapper (or <body>) on a dark theme. Keying this off the OS setting
 * instead inverted the text on light themes and made the forms unreadable.
 */
[data-invitely-theme="dark"] .invitely,
.invitely[data-invitely-theme="dark"] {
	--invitely-ink: #f2f1ec;
	--invitely-muted: #a4a19a;
	--invitely-line: #3a3833;
	--invitely-paper: #211f1c;
	--invitely-field-bg: #191714;
	--invitely-field-ink: #f2f1ec;
	--invitely-placeholder: #7d7a72;
	--invitely-accent: #59b3a3;
	--invitely-accent-soft: #1d3733;
}

[data-invitely-theme="dark"] .invitely-choice span {
	background: #191714;
}

[data-invitely-theme="dark"] .invitely-btn {
	color: #10201d;
}

[data-invitely-theme="dark"] .invitely-alert--error {
	background: #3a201d;
}

/*
 * Hero variant of the facts block, used when the host chose to show the photo
 * behind the text. Same scrim approach as the card: a photo of unknown
 * brightness sitting behind text needs a guaranteed contrast floor.
 */
.invitely-facts--hero {
	position: relative;
	overflow: hidden;
	border-color: transparent;
	background-color: #1a1a17;
	color: #fff;
	padding: 2.25rem 1.5rem;
}

.invitely-facts--hero::before {
	content: "";
	position: absolute;
	inset: 0;
	background-image: var(--invitely-card-bg);
	background-size: cover;
	background-position: center;
}

.invitely-facts--hero::after {
	content: "";
	position: absolute;
	inset: 0;
	background: linear-gradient( to top, rgba( 0, 0, 0, 0.78 ) 0%, rgba( 0, 0, 0, 0.45 ) 60%, rgba( 0, 0, 0, 0.2 ) 100% );
}

.invitely-facts--hero .invitely-fact {
	position: relative;
	z-index: 2;
	text-shadow: 0 1px 2px rgba( 0, 0, 0, 0.45 );
}

.invitely-facts--hero .invitely-fact dt {
	color: #fff;
}

.invitely-facts--hero .invitely-fact dd,
.invitely-facts--hero .invitely-address {
	color: #fff;
}

.invitely-facts--hero .invitely-maplink {
	color: #fff;
}

.invitely-card__deadline {
	margin: 1rem 0 0;
	padding-top: 0.75rem;
	border-top: 1px solid var(--invitely-line);
	color: var(--invitely-ink);
	font-size: 0.88rem;
}

.invitely-card__deadline[hidden] {
	display: none;
}

.invitely-card.is-background .invitely-card__deadline {
	border-top-color: rgba( 255, 255, 255, 0.25 );
	color: rgba( 255, 255, 255, 0.85 );
}

.invitely-form__deadline {
	margin: -0.6rem 0 1.1rem;
	color: var(--invitely-ink);
	font-size: 0.9rem;
}

/*
 * Banner on the public invitation, drawn only when the theme did not print the
 * featured image itself.
 */
.invitely-banner {
	margin: 0 0 1.75rem;
	border-radius: var(--invitely-radius);
	overflow: hidden;
	line-height: 0;
}

.invitely-banner__image,
.invitely-banner img {
	display: block;
	width: 100%;
	height: auto;
	max-height: 26rem;
	object-fit: cover;
}

/* -------------------------------------------------- Framed photo + overlays */

.invitely-frame {
	position: relative;
	height: var(--invitely-frame-h, 320px);
	overflow: hidden;
	background: #10100e;
}

.invitely-frame > img {
	display: block;
	width: 100%;
	height: 100%;
	max-height: none;
	object-fit: var(--invitely-frame-fit, cover);
	object-position: var(--invitely-frame-x, 50%) var(--invitely-frame-y, 50%);
	transform: scale( var(--invitely-frame-zoom, 1) );
	transform-origin: var(--invitely-frame-x, 50%) var(--invitely-frame-y, 50%);
}

.invitely-overlays {
	position: absolute;
	inset: 0;
	pointer-events: none;
}

.invitely-overlay {
	position: absolute;
	max-width: 92%;
	margin: 0;
	line-height: 1.15;
	white-space: pre-wrap;
	overflow-wrap: anywhere;
}

.invitely-overlay.has-shadow {
	text-shadow: 0 2px 6px rgba( 0, 0, 0, 0.55 ), 0 1px 2px rgba( 0, 0, 0, 0.45 );
}

.invitely-banner .invitely-frame {
	border-radius: var(--invitely-radius);
}

/* Guests never drag anything; only the builder enables this. */
.invitely-overlay.is-draggable {
	pointer-events: auto;
	cursor: grab;
	outline: 1px dashed rgba( 255, 255, 255, 0.5 );
	outline-offset: 4px;
}

.invitely-overlay.is-draggable:focus-visible,
.invitely-overlay.is-dragging {
	cursor: grabbing;
	outline: 2px solid #fff;
}

/* ------------------------------------------------------------ Embedded map */

.invitely-map {
	margin: 0 0 1.75rem;
	border: 1px solid var(--invitely-line);
	border-radius: var(--invitely-radius);
	overflow: hidden;
}

.invitely-map iframe {
	display: block;
	width: 100%;
	height: var(--invitely-map-h, 300px);
	border: 0;
}

.invitely-maplinks {
	display: flex;
	gap: 0.9rem;
	margin-top: 0.35rem;
}

/* ------------------------------------------------ Responsive frame + text */

.invitely-frame {
	container-type: inline-size;
	max-height: 80vh;
}

/* "Match the photo": height follows the image's own proportions, so nothing
   is cropped and no letterbox bars appear either. */
.invitely-frame.is-auto {
	height: auto;
	aspect-ratio: var(--invitely-frame-ar, 16 / 9);
}

.invitely-frame.is-auto > img {
	height: 100%;
}

.invitely-frame.is-contain {
	background: var(--invitely-paper);
}

.invitely-overlay {
	font-size: calc( var(--invitely-o-size, 32) * 1px );
}

/*
 * Scale overlay text against the frame width rather than the viewport, so the
 * same invitation reads the same at 1200px and at 360px. Falls back to the
 * plain pixel size above where container units are unsupported.
 */
@supports ( font-size: 1cqw ) {
	.invitely-overlay {
		font-size: max( 11px, calc( var(--invitely-o-size, 32) * 0.125cqw ) );
	}
}

.invitely-overlay.is-italic {
	font-style: italic;
}

/* ------------------------------------------------------ Greeting-card shell */

/*
 * Two layers. The greeting is the backdrop — colour or image — and the mat
 * inside it carries the photo, inset by the backdrop padding. The photo used to
 * be the greeting's own background, which left nowhere for a backdrop to show.
 */
.invitely-greeting {
	position: relative;
	aspect-ratio: var(--invitely-card-ar, 2 / 3);
	max-height: 88vh;
	margin: 0 auto 1.75rem;
	container-type: inline-size;
	background-color: #14120f;
	background-size: cover;
	background-position: center;
	border-radius: var(--invitely-radius);
	overflow: hidden;
}

.is-layout-portrait .invitely-greeting {
	max-width: 34rem;
}

.has-backdrop-photo .invitely-greeting {
	background-color: var(--invitely-backdrop, #14120f);
	background-image: var(--invitely-backdrop-image, none);
	background-size: var(--invitely-backdrop-size, cover);
	background-repeat: var(--invitely-backdrop-repeat, no-repeat);
}

.invitely-greeting__mat {
	position: absolute;
	inset: 0;
	display: flex;
	align-items: flex-end;
	overflow: hidden;
}

/* The photo frame fills the mat, so framing behaves the same here as it does
   in the down-the-page banner. */
.invitely-greeting__mat > .invitely-frame {
	position: absolute;
	inset: 0;
	height: 100%;
	max-height: none;
	aspect-ratio: auto;
	background: transparent;
}

/*
 * A scrim over the photo rather than a tint mixed into it: the wording has to
 * stay readable over a photo whose brightness the plugin cannot know.
 */
/*
 * The fallbacks are the two defaults: a gradient when the wording sits on the
 * photo, a light wash when it sits on a panel. A host who sets the control
 * replaces both with one value; a host who leaves it alone keeps each.
 */
.invitely-greeting__scrim {
	position: absolute;
	inset: 0;
	pointer-events: none;
	background: var(--invitely-scrim, linear-gradient( to top, rgba( 0, 0, 0, 0.84 ) 0%, rgba( 0, 0, 0, 0.5 ) 40%, rgba( 0, 0, 0, 0.08 ) 100% ));
}

.invitely-greeting__inner {
	position: relative;
	z-index: 3;
	width: 100%;
	padding: 8cqw;
	color: #fff;
	text-shadow: 0 1px 3px rgba( 0, 0, 0, 0.5 );
}

.invitely-greeting__inner .invitely-card__eyebrow {
	color: rgba( 255, 255, 255, 0.85 );
	font-size: 3cqw;
}

.invitely-greeting__inner .invitely-card__title {
	margin: 0 0 0.4em;
	color: #fff;
	font-size: 8cqw;
	line-height: 1.1;
}

.invitely-greeting__inner .invitely-card__when {
	margin: 0 0 0.15em;
	color: #fff;
	font-size: 4cqw;
}

.invitely-greeting__inner .invitely-card__where {
	margin: 0;
	color: rgba( 255, 255, 255, 0.85 );
	font-size: 3.4cqw;
}

@media ( max-width: 520px ) {
	.invitely-greeting {
		max-height: 70vh;
	}

	.invitely-facts {
		padding: 1rem;
	}

	.invitely-frame {
		max-height: 60vh;
	}
}

/* ------------------------------------------------------ One surface, not many */

/*
 * With a host-chosen background the whole block takes that colour and the
 * inner panels stop drawing their own. Separate backgrounds and radii on each
 * panel read as a stack of unrelated boxes; hairline rules keep the grouping
 * without the boxing.
 */
.invitely.has-custom-bg {
	padding: 1.75rem;
	background: var(--invitely-paper);
	border-radius: var(--invitely-radius);
}

.invitely.has-custom-bg .invitely-facts,
.invitely.has-custom-bg .invitely-form,
.invitely.has-custom-bg .invitely-pay {
	padding-left: 0;
	padding-right: 0;
	background: transparent;
	border: 0;
	border-top: 1px solid var(--invitely-line);
	border-radius: 0;
}

.invitely.has-custom-bg .invitely-facts {
	border-top: 0;
}

/*
 * Form fields go transparent so the block reads as one surface. The !important
 * is needed only to beat the base control rule, which carries its own.
 */
.invitely.has-custom-bg .invitely-field input,
.invitely.has-custom-bg .invitely-field textarea,
.invitely.has-custom-bg .invitely-field select {
	background: var(--invitely-input-bg, transparent) !important;
	border-color: var(--invitely-input-border, var(--invitely-line));
}

/*
 * Reply buttons keep their own colours here. This rule used to sweep them into
 * transparent along with the fields, which silently beat every button colour a
 * host chose. The variable chain gives the same transparent default without
 * overriding an explicit choice.
 */
.invitely.has-custom-bg .invitely-choice span {
	background: var(--invitely-btn-bg, transparent);
	border-color: var(--invitely-btn-border, var(--invitely-line));
}

.invitely.has-custom-bg .invitely-choice--yes span {
	background: var(--invitely-btn-yes-bg, var(--invitely-btn-bg, transparent));
}

.invitely.has-custom-bg .invitely-choice--maybe span {
	background: var(--invitely-btn-maybe-bg, var(--invitely-btn-bg, transparent));
}

.invitely.has-custom-bg .invitely-choice--no span {
	background: var(--invitely-btn-no-bg, var(--invitely-btn-bg, transparent));
}

.invitely.has-custom-bg .invitely-choice input:checked + span {
	background: var(--invitely-btn-on-bg, var(--invitely-accent-soft));
}

.invitely.has-custom-bg .invitely-choice input:checked + span {
	background: var(--invitely-accent-soft) !important;
}

/* --------------------------------------------------------- Preview wrapper */

.invitely-preview {
	margin: 0;
	padding: 1.25rem;
	border: 1px solid var(--invitely-line);
	border-radius: var(--invitely-radius);
	background: var(--invitely-paper);
}

.invitely-preview__title {
	margin: 0 0 0.6rem;
	font-size: 1.5rem;
	line-height: 1.2;
	overflow-wrap: anywhere;
}

.invitely-preview__body {
	margin: 0 0 1.25rem;
	font-size: 0.98rem;
}

.invitely-preview__body p {
	margin: 0 0 0.7rem;
}

.invitely-preview__body p:last-child {
	margin-bottom: 0;
}

.invitely-preview .invitely-banner[hidden] {
	display: none;
}

.invitely-preview .invitely-facts {
	grid-template-columns: minmax( 0, 1fr );
}

/* --------------------------------------------- Card floating on a backdrop */

/*
 * With a panel, the photo stops being the invitation and becomes the setting
 * it sits in, which is how a printed card actually reads. The scrim drops away
 * because the wording no longer sits on the photo.
 */
.invitely-greeting.has-panel .invitely-greeting__mat {
	align-items: center;
	justify-content: center;
	padding: 4cqw;
}

/* A far lighter wash with a panel: the wording is on the card, not on the
   photo, so the photo does not need dimming to stay readable. */
.invitely-greeting.has-panel .invitely-greeting__scrim {
	background: var(--invitely-scrim, rgba( 0, 0, 0, 0.18 ));
}

.invitely-panel-card {
	position: relative;
	z-index: 3;
	width: var(--invitely-panel-w, 74%);
	max-width: 100%;
	max-height: 100%;
	overflow: auto;
	background: var(--invitely-panel-bg, #a51f23);
	color: var(--invitely-panel-ink, #fff);
	box-shadow: 0 1.5cqw 4cqw rgba( 0, 0, 0, 0.35 );
	text-align: center;
}

.invitely-panel-card__inner {
	padding: 7cqw 6cqw;
}

/* Border treatments, all drawn rather than imaged so they scale with the card
   and follow the chosen colour. */
.invitely-panel-card.is-border-line {
	border: 0.35cqw solid var(--invitely-panel-accent, #e0b970);
}

.invitely-panel-card.is-border-double {
	border: 0.35cqw solid var(--invitely-panel-accent, #e0b970);
	box-shadow:
		inset 0 0 0 0.8cqw var(--invitely-panel-bg, #a51f23),
		inset 0 0 0 1.1cqw var(--invitely-panel-accent, #e0b970),
		0 1.5cqw 4cqw rgba( 0, 0, 0, 0.35 );
}

.invitely-panel-card.is-border-ornate {
	border: 0.5cqw solid var(--invitely-panel-accent, #e0b970);
	box-shadow:
		inset 0 0 0 1.2cqw var(--invitely-panel-bg, #a51f23),
		inset 0 0 0 1.35cqw var(--invitely-panel-accent, #e0b970),
		inset 0 0 0 2cqw var(--invitely-panel-bg, #a51f23),
		inset 0 0 0 2.15cqw color-mix( in srgb, var(--invitely-panel-accent, #e0b970) 55%, transparent ),
		0 1.5cqw 4cqw rgba( 0, 0, 0, 0.35 );
}

.invitely-panel-card .invitely-card__eyebrow {
	margin: 0 0 1.5cqw;
	color: var(--invitely-panel-accent, #e0b970);
	font-size: 2.4cqw;
	letter-spacing: 0.28em;
}

.invitely-panel-card .invitely-card__title {
	margin: 0 0 2.5cqw;
	color: var(--invitely-panel-ink, #fff);
	font-size: 9cqw;
	line-height: 1.05;
}

.invitely-panel-card .invitely-card__when {
	margin: 0 0 1cqw;
	padding: 1.6cqw 0;
	border-top: 0.15cqw solid color-mix( in srgb, var(--invitely-panel-accent, #e0b970) 70%, transparent );
	border-bottom: 0.15cqw solid color-mix( in srgb, var(--invitely-panel-accent, #e0b970) 70%, transparent );
	color: var(--invitely-panel-accent, #e0b970);
	font-size: 3.4cqw;
	font-weight: 600;
	letter-spacing: 0.06em;
}

.invitely-panel-card .invitely-card__where {
	margin: 2cqw 0 0;
	color: var(--invitely-panel-ink, #fff);
	font-size: 2.9cqw;
	line-height: 1.5;
}

.invitely-panel-card .invitely-card__body {
	margin: 2.5cqw 0 0;
	color: var(--invitely-panel-ink, #fff);
	font-size: 2.7cqw;
	line-height: 1.6;
	opacity: 0.94;
}

.invitely-panel-card .invitely-card__body p {
	margin: 0 0 0.6em;
}

.invitely-panel-card [hidden] {
	display: none;
}

/* On a narrow screen the card takes the width it needs; a 74% panel inside a
   360px phone would leave the wording unreadable. */
@media ( max-width: 560px ) {
	.invitely-panel-card {
		width: 88%;
	}

	.invitely-greeting.has-panel .invitely-greeting__mat {
		padding: 3cqw;
	}
}

/*
 * In the builder both arrangements are in the DOM and CSS picks one, so
 * switching shape is instant. Rebuilding the markup in JavaScript would mean
 * maintaining the card structure twice in two languages, which is exactly the
 * drift that merging the two renderers was meant to end.
 */
.invitely-preview.is-layout-plain .invitely-greeting,
.invitely-preview:not( .is-layout-plain ) .invitely-preview__plain {
	display: none;
}

.invitely-greeting:not( .has-panel ) .invitely-panel-card,
.invitely-greeting.has-panel .invitely-greeting__inner {
	display: none;
}

/* ------------------------------------------------------- Backdrop and parts */

.invitely {
	--invitely-heading-ink: var(--invitely-ink);
	--invitely-heading-font: var(--invitely-font);
	--invitely-heading-scale: 1;
	--invitely-label-ink: var(--invitely-muted);
	--invitely-label-font: var(--invitely-font);
	--invitely-label-scale: 1;
	--invitely-body-ink: var(--invitely-ink);
	--invitely-body-font: var(--invitely-font);
	--invitely-body-scale: 1;
	--invitely-info-ink: var(--invitely-body-ink);
	--invitely-info-font: var(--invitely-body-font);
	--invitely-info-scale: 1;

	/* Base sizes, so a narrow screen can retune the whole scale in one place
	   rather than overriding a dozen rules. */
	--invitely-size-title: 1.6rem;
	--invitely-size-heading: 1.15rem;
	--invitely-size-label: 0.8rem;
	--invitely-size-body: 1rem;
	--invitely-size-info: 1.02rem;
	--invitely-btn-radius: 7px;
	--invitely-btn-scale: 1;
	--invitely-submit-scale: 1;
	--invitely-backdrop-pad: 0px;
}

/* The photo sits inset in a backdrop, like a mount around a print. Padding is
   zero by default so nothing changes until a host asks for it. */
/*
 * The backdrop is painted where its scope says, not everywhere it is defined.
 * "Behind the photo" mounts the picture; "behind the whole invitation" frames
 * the lot. Both are the same colour and image, so the variables stay global and
 * only the classes decide which layers use them.
 */
.has-backdrop-photo .invitely-banner {
	padding: min( var(--invitely-backdrop-pad-photo, var(--invitely-backdrop-pad, 0px)), 4vw );
	background-color: var(--invitely-backdrop, transparent);
	background-image: var(--invitely-backdrop-image, none);
	background-size: var(--invitely-backdrop-size, cover);
	background-repeat: var(--invitely-backdrop-repeat, no-repeat);
	background-position: center;
}

/*
 * Section headings and labels carry their own colour, face and size so the
 * invitation is not one uniform block of type.
 *
 * The block class is doubled here on purpose. Themes style headings with
 * selectors like `.entry-content h3`, which ties with `.invitely h3` and then
 * wins or loses on load order — so a host could set the same typeface for
 * headings and labels and watch only the labels change. Doubling the class
 * settles it without reaching for !important.
 */
.invitely.invitely h2,
.invitely.invitely h3,
.invitely.invitely .invitely-card__title,
.invitely.invitely .invitely-form__title,
.invitely.invitely .invitely-gifts__title,
.invitely.invitely .invitely-pay__title,
.invitely.invitely .invitely-guestlist__title,
.invitely.invitely .invitely-fact dt,
.invitely.invitely .invitely-headcount__line strong {
	color: var(--invitely-heading-ink);
	font-family: var(--invitely-heading-font);
}

/*
 * Themes set a top margin on headings through `.entry-content h3`, which
 * outranks a single class. That margin is what still pushed the reply column
 * below the details column: the form's own padding was already zeroed, but the
 * heading inside it kept a margin of its own.
 */
.invitely.invitely .invitely-form__title,
.invitely.invitely .invitely-gifts__title,
.invitely.invitely .invitely-pay__title,
.invitely.invitely .invitely-guestlist__title,
.invitely.invitely .invitely-card__title,
.invitely.invitely .invitely-preview__title {
	margin-top: 0;
}

.invitely-split__col > :first-child > :first-child {
	margin-top: 0;
}

.invitely.invitely .invitely-card__title,
.invitely.invitely .invitely-form__title,
.invitely.invitely .invitely-gifts__title,
.invitely.invitely .invitely-pay__title,
.invitely.invitely .invitely-guestlist__title,
.invitely.invitely .invitely-fact dt {
	font-size: calc( var(--invitely-size-heading) * var(--invitely-heading-scale) );
}

.invitely .invitely-preview__title {
	font-size: calc( var(--invitely-size-title) * 0.94 * var(--invitely-heading-scale) );
}

/* Labels: the small When, Where and field captions, sized and set apart from
   both the headings and the body. */
.invitely.invitely .invitely-field label,
.invitely.invitely .invitely-card__eyebrow {
	color: var(--invitely-label-ink);
	font-family: var(--invitely-label-font);
}

.invitely.invitely .invitely-field label {
	font-size: calc( var(--invitely-size-label) * var(--invitely-label-scale) );
}

.invitely.invitely .invitely-card__eyebrow {
	font-size: calc( var(--invitely-size-label) * 0.88 * var(--invitely-label-scale) );
}

/*
 * The values beside each label — the date, the venue, the address — follow the
 * details typeface rather than the base one. They are the invitation's own
 * words, and leaving them on the base face was the other half of why a host
 * setting one typeface still saw two.
 */
/*
 * Information text: the value under each heading, the reply-by line, and the
 * payment and gift notes. These are neither headings nor the invitation's own
 * wording, and sizing them with either meant moving something else to adjust
 * them.
 */
.invitely.invitely .invitely-fact dd,
.invitely.invitely .invitely-address,
.invitely.invitely .invitely-card__when,
.invitely.invitely .invitely-card__where,
.invitely.invitely .invitely-form__deadline,
.invitely.invitely .invitely-card__deadline,
.invitely.invitely .invitely-pay__note,
.invitely.invitely .invitely-pay__ref,
.invitely.invitely .invitely-gifts__note {
	color: var(--invitely-info-ink);
	font-family: var(--invitely-info-font);
}

.invitely.invitely .invitely-fact dd {
	font-size: calc( var(--invitely-size-info) * var(--invitely-info-scale) );
}

.invitely.invitely .invitely-address {
	font-size: calc( var(--invitely-size-info) * 0.92 * var(--invitely-info-scale) );
}

.invitely.invitely .invitely-form__deadline {
	font-size: calc( var(--invitely-size-info) * 0.88 * var(--invitely-info-scale) );
}

.invitely.invitely .invitely-card__deadline {
	font-size: calc( var(--invitely-size-info) * 0.86 * var(--invitely-info-scale) );
}

.invitely.invitely .invitely-pay__note {
	font-size: calc( var(--invitely-size-info) * 0.94 * var(--invitely-info-scale) );
}

.invitely.invitely .invitely-gifts__note {
	font-size: calc( var(--invitely-size-info) * 0.95 * var(--invitely-info-scale) );
}

/* Reply buttons. */
.invitely .invitely-choice span {
	background: var(--invitely-btn-bg, #fff);
	border-color: var(--invitely-btn-border, var(--invitely-line));
	border-radius: var(--invitely-btn-radius);
	color: var(--invitely-btn-ink, var(--invitely-ink));
	font-size: calc( var(--invitely-size-body) * 0.95 * var(--invitely-btn-scale) );
}

.invitely .invitely-choice input:checked + span {
	box-shadow: inset 0 0 0 2px var(--invitely-accent);
}

.invitely .invitely-btn {
	border-radius: var(--invitely-btn-radius);
}

/* Each answer can carry its own colour, falling back to the shared one. */
.invitely .invitely-choice--yes span {
	background: var(--invitely-btn-yes-bg, var(--invitely-btn-bg, #fff));
}

.invitely .invitely-choice--maybe span {
	background: var(--invitely-btn-maybe-bg, var(--invitely-btn-bg, #fff));
}

.invitely .invitely-choice--no span {
	background: var(--invitely-btn-no-bg, var(--invitely-btn-bg, #fff));
}

.invitely .invitely-choice input:checked + span {
	background: var(--invitely-btn-on-bg, var(--invitely-accent-soft));
}

/*
 * Break out of the theme's content column.
 *
 * The white card and the grey surround on an invitation page belong to the
 * theme, not this plugin, and a plugin cannot reach up and restyle a container
 * it does not own. This spans the block to the viewport instead, which covers
 * the theme's box rather than removing it. The proper fix is a full-width page
 * template in the theme or Elementor Canvas; this is the version that works
 * without touching either.
 */
.invitely.is-fullwidth {
	width: 100vw;
	max-width: 100vw;
	margin-left: calc( 50% - 50vw );
	margin-right: calc( 50% - 50vw );
	border-radius: 0;
}

/*
 * Full width and a whole-invitation backdrop are independent choices, so the
 * backdrop is restated at the combined specificity. Relying on source order for
 * two optional classes is the kind of thing that breaks the next time a rule is
 * appended below.
 */
.invitely.is-fullwidth.has-backdrop-page {
	padding: min( var(--invitely-backdrop-pad, 24px), 5vw );
	background-color: var(--invitely-backdrop, transparent);
	background-image: var(--invitely-backdrop-image, none);
	background-size: var(--invitely-backdrop-size, cover);
	background-repeat: var(--invitely-backdrop-repeat, no-repeat);
	background-position: center;
}

.invitely.is-fullwidth.has-custom-bg {
	padding-left: max( 1.5rem, calc( 50vw - 36rem ) );
	padding-right: max( 1.5rem, calc( 50vw - 36rem ) );
}

/* A horizontal scrollbar would otherwise appear when 100vw includes it. */
@supports ( width: 100dvw ) {
	.invitely.is-fullwidth {
		width: 100dvw;
		max-width: 100dvw;
	}
}

/* The takeover has no gap above it: the invitation is the page. */
.invitely.is-fullwidth {
	margin-top: 0;
}

.invitely-pay--upfront {
	margin: 0 0 1.75rem;
}

.invitely-pay__title {
	margin: 0 0 0.6rem;
	font-size: calc( var(--invitely-size-heading) * 0.91 * var(--invitely-heading-scale) );
}

.invitely-pay--upfront .invitely-hint {
	display: block;
	margin: 0.75rem 0 0;
}

/* Whole-invitation scope: the backdrop frames everything, not just the photo. */
.invitely.has-backdrop-page {
	padding: min( var(--invitely-backdrop-pad, 24px), 5vw );
	background-color: var(--invitely-backdrop, transparent);
	background-image: var(--invitely-backdrop-image, none);
	background-size: var(--invitely-backdrop-size, cover);
	background-repeat: var(--invitely-backdrop-repeat, no-repeat);
	background-position: center;
	border-radius: var(--invitely-radius);
}

.has-backdrop-photo .invitely-greeting__mat {
	inset: min( var(--invitely-backdrop-pad-photo, var(--invitely-backdrop-pad, 0px)), 4vw );
}


/* The send button styles independently of the answer buttons. */
.invitely .invitely-btn--submit {
	font-size: calc( var(--invitely-size-body) * 0.98 * var(--invitely-submit-scale) );
	background: var(--invitely-submit-bg, var(--invitely-accent));
	border: 1px solid var(--invitely-submit-border, transparent);
	border-radius: var(--invitely-submit-radius, var(--invitely-btn-radius));
	color: var(--invitely-submit-ink, #fff);
}

.invitely .invitely-btn--submit:hover,
.invitely .invitely-btn--submit:focus {
	color: var(--invitely-submit-ink, #fff);
}

/* ------------------------------------------------------------------ Gifts */

.invitely-gifts {
	margin: 0 0 1.75rem;
}

.invitely-gifts__title {
	margin: 0 0 0.5rem;
	font-size: calc( var(--invitely-size-heading) * 0.91 * var(--invitely-heading-scale) );
}

.invitely-gifts__note {
	margin: 0 0 0.9rem;
	font-size: 0.97rem;
}

.invitely-gifts__links {
	display: flex;
	flex-wrap: wrap;
	gap: 0.5rem;
	margin: 0;
	padding: 0;
	list-style: none;
}

.invitely-gifts__links li {
	margin: 0;
}

/* ------------------------------------------------------- Side-by-side view */

/*
 * Two columns only where there is room for both to stay readable. Below that
 * they stack in the same order they read in: what the event is, then how to
 * reply to it.
 */
.invitely-split {
	display: grid;
	gap: var(--invitely-split-gap, 1.5rem);
	grid-template-columns: minmax( 0, 1fr );
	align-items: start;
}

.invitely-split__col {
	padding: min( var(--invitely-split-pad, 0px), 4vw );
	min-width: 0;
}

@media ( min-width: 56rem ) {
	.invitely-split {
		grid-template-columns: var(--invitely-split-cols, minmax( 0, 1fr ) minmax( 0, 1fr ));
	}

	/* The details column holds a map and can run long; the reply form should
	   stay in view beside it rather than float against a wall of whitespace. */
	.invitely-split__col--reply {
		position: sticky;
		top: 1.5rem;
	}
}

.invitely-split .invitely-facts {
	grid-template-columns: minmax( 0, 1fr );
}

.invitely-split .invitely-fields {
	grid-template-columns: minmax( 0, 1fr );
}



/* ---------------------------------------------------- Content panel layer */

/*
 * Three layers: the backdrop, this panel, and the wording. Without it the text
 * sits straight on a patterned backdrop, which no amount of colour picking
 * makes readable. Transparent by default, so nothing changes until a host asks.
 */
.invitely-content {
	max-width: var(--invitely-content-w, 100%);
	margin-inline: auto;
	padding: min( var(--invitely-content-pad, 0px), 6vw );
	background: var(--invitely-content-bg, transparent);
	border-radius: var(--invitely-radius);
}

/* With a panel behind it the inner sections stop drawing their own boxes, for
   the same reason a custom background collapses them: one surface, not five. */
.invitely.has-content-panel .invitely-facts,
.invitely.has-content-panel .invitely-form,
.invitely.has-content-panel .invitely-pay {
	background: transparent;
	border-color: var(--invitely-line);
}

/* ------------------------------------------------------------------ Print */

/*
 * Paper cards. The site header, navigation, footer and admin bar are screen
 * furniture; on paper they are wasted ink and a wasted first page. The reply
 * form goes too by default, since nobody fills in a text box with a pen — the
 * host can keep it with the "leave room to reply" setting for a card people
 * post back.
 */
@media print {
	body.invitely-print-plain #wpadminbar,
	body.invitely-print-plain .site-header,
	body.invitely-print-plain #masthead,
	body.invitely-print-plain .site-footer,
	body.invitely-print-plain #colophon,
	body.invitely-print-plain .site-navigation,
	body.invitely-print-plain nav,
	body.invitely-print-plain .skip-link,
	body.invitely-print-plain .invitely-nav {
		display: none !important;
	}

	body.invitely-print-plain {
		margin: 0 !important;
		padding: 0 !important;
		background: #fff !important;
	}

	/* Without this the browser drops backgrounds and a red invitation prints
	   as white paper with red text. */
	.invitely,
	.invitely * {
		-webkit-print-color-adjust: exact;
		print-color-adjust: exact;
	}

	.invitely {
		margin: 0 !important;
	}

	.invitely-map,
	.invitely-headcount,
	.invitely-guestlist {
		display: none !important;
	}

	body:not( .invitely-print-reply ) .invitely-form {
		display: none !important;
	}

	/* A reply card people post back keeps the fields but loses the button. */
	body.invitely-print-reply .invitely-submit,
	body.invitely-print-reply .invitely-hp {
		display: none !important;
	}

	.invitely-greeting,
	.invitely-frame,
	.invitely-content {
		break-inside: avoid;
	}

	.invitely a[href]::after {
		content: "";
	}
}

/* The invitation text, when a card layout has replaced the theme's copy. */
/* The invitation text, with its own colour, face and size. */
.invitely.invitely .invitely-body,
.invitely.invitely .invitely-preview__body,
.invitely.invitely .invitely-card__body {
	color: var(--invitely-body-ink);
	font-family: var(--invitely-body-font);
}

.invitely-body {
	margin: 0 0 1.5rem;
	font-size: calc( var(--invitely-size-body) * var(--invitely-body-scale) );
}

.invitely-preview__body {
	font-size: calc( var(--invitely-size-body) * 0.98 * var(--invitely-body-scale) );
}

.invitely-body p {
	margin: 0 0 0.8rem;
}

.invitely-body p:last-child {
	margin-bottom: 0;
}

/* Letterboxing inside a card shows the backdrop behind, not a flat panel. */
.invitely-greeting__mat > .invitely-frame.is-contain,
.invitely-greeting__mat > .invitely-frame.is-auto {
	background: transparent;
}

/*
 * Column tops.
 *
 * The details column opens with the facts block and the reply column with the
 * form, and the two carry different top padding, so the first line in each
 * started at a different height. Whatever leads a column starts flush with it.
 */
.invitely-split__col > :first-child {
	margin-top: 0;
	padding-top: 0;
}

.invitely-split .invitely-facts,
.invitely-split .invitely-form {
	margin-top: 0;
}

/* A panel that starts the column keeps its side padding but not its top. */
.invitely-split__col > .invitely-form:first-child,
.invitely-split__col > .invitely-facts:first-child {
	border-top: 0;
}

/*
 * Flipped columns: the reply form on the left, the details on the right.
 *
 * Applied only where the two columns actually exist. Stacked on a narrow
 * screen the order stays what it reads as — the event first, then how to reply
 * to it — because "left" and "right" have stopped meaning anything there.
 */
@media ( min-width: 56rem ) {
	.invitely-split.is-flipped .invitely-split__col--reply {
		order: 1;
	}

	.invitely-split.is-flipped .invitely-split__col--details {
		order: 2;
	}
}

/*
 * The map fills whatever the details column has left.
 *
 * Only the details column stretches; the reply column keeps `align-self: start`
 * so it can stay sticky. Stretching both would make the row as tall as the
 * taller one and leave nothing for sticky to move within.
 */
@media ( min-width: 56rem ) {
	.invitely-split__col--details {
		align-self: stretch;
		display: flex;
		flex-direction: column;
	}

	.invitely-split__col--details .invitely-map {
		flex: 1 1 auto;
		display: flex;
		min-height: var(--invitely-map-h, 300px);
	}

	.invitely-split__col--details .invitely-map iframe {
		height: 100%;
		min-height: 0;
	}
}

/* The invitation title, when a card shape is not printing it over the photo. */
.invitely-title {
	margin: 0 0 0.9rem;
	font-size: calc( var(--invitely-size-title) * var(--invitely-heading-scale) );
	line-height: 1.15;
	overflow-wrap: anywhere;
}

/* ------------------------------------------------------------ Narrow screens */

/*
 * One retune of the base sizes, rather than a media query per rule. Every
 * font-size in the block is a multiple of one of these five, so a phone gets a
 * proportionally smaller invitation with the host's own choices intact: a
 * heading set to 140% is still 140% of a heading, just a smaller heading.
 */
@media ( max-width: 640px ) {
	.invitely {
		--invitely-size-title: calc( 1.6rem * var(--invitely-mobile-scale, 0.85) );
		--invitely-size-heading: calc( 1.15rem * var(--invitely-mobile-scale, 0.88) );
		--invitely-size-label: calc( 0.8rem * var(--invitely-mobile-scale, 0.95) );
		--invitely-size-body: calc( 1rem * var(--invitely-mobile-scale, 0.95) );
		--invitely-size-info: calc( 1.02rem * var(--invitely-mobile-scale, 0.93) );
	}

	/* A panel inset from a backdrop leaves too little room for words on a
	   phone, so it takes the width and the backdrop shows as a border. */
	.invitely-content {
		max-width: 100%;
	}

	.invitely-panel-card {
		width: 92%;
	}

	.invitely-greeting {
		max-height: none;
	}

	.invitely-facts {
		gap: 1rem;
	}
}

/*
 * A fixed background is unreliable on mobile browsers: iOS ignores it and
 * Android jitters or scales it oddly against a resizing viewport. It scrolls
 * with the page there instead.
 */
@media ( max-width: 900px ) {
	body.invitely-takeover {
		background-attachment: scroll !important;
	}
}

/* Long words in a title must not push the card wider than the screen. */
.invitely-title,
.invitely .invitely-card__title,
.invitely-preview__title {
	overflow-wrap: anywhere;
	hyphens: auto;
}

/*
 * A cover backdrop on a phone.
 *
 * `cover` on a 400 by 900 viewport scales a wide decorative frame until only a
 * fragment of it is visible — the pattern reads as a blur rather than a border.
 * Below 640px a cover backdrop fits the width and repeats down instead, which
 * keeps the artwork at its intended scale.
 *
 * This overrides the host's choice, deliberately. The setting says "fill the
 * space"; on a tall narrow screen filling it by cropping destroys the thing
 * being filled with.
 */
@media ( max-width: 640px ) {
	.invitely.has-backdrop-page,
	.invitely.is-fullwidth.has-backdrop-page,
	.has-backdrop-photo .invitely-banner,
	.has-backdrop-photo .invitely-greeting {
		background-size: var(--invitely-backdrop-size-mobile, 100% auto);
		background-repeat: var(--invitely-backdrop-repeat-mobile, repeat-y);
	}

	body.invitely-takeover {
		background-size: 100% auto !important;
		background-repeat: repeat-y !important;
	}
}

/* ------------------------------------------------- Payment, price and how */

/*
 * The amount sits beside the instructions rather than above them: a guest
 * checking what they owe and a guest looking up where to send it are doing two
 * different things, and neither should have to read past the other.
 */
.invitely-pay__grid {
	display: grid;
	gap: 1rem;
	grid-template-columns: minmax( 0, 1fr );
	align-items: start;
}

@media ( min-width: 34rem ) {
	.invitely-pay__grid:has( .invitely-pay__amount ) {
		grid-template-columns: auto minmax( 0, 1fr );
		gap: 1.5rem;
	}
}

.invitely-pay__amount {
	display: flex;
	flex-direction: column;
	padding-right: 1.25rem;
	border-right: 1px solid var(--invitely-line);
}

.invitely-pay__figure {
	color: var(--invitely-heading-ink);
	font-family: var(--invitely-heading-font);
	font-size: calc( var(--invitely-size-title) * var(--invitely-heading-scale) );
	font-weight: 700;
	line-height: 1.1;
	white-space: nowrap;
}

.invitely-pay__per {
	color: var(--invitely-info-ink);
	font-family: var(--invitely-info-font);
	font-size: calc( var(--invitely-size-info) * 0.86 * var(--invitely-info-scale) );
}

.invitely-pay__how > :first-child {
	margin-top: 0;
}

/* Stacked, the rule reads as a divider in the wrong direction. */
@media ( max-width: 34rem ) {
	.invitely-pay__amount {
		padding-right: 0;
		padding-bottom: 0.75rem;
		border-right: 0;
		border-bottom: 1px solid var(--invitely-line);
	}
}

/* Payment inside the reply form, directly beneath the party size. */
.invitely-form .invitely-pay--upfront {
	margin: 0 0 1.4rem;
	padding: 0.9rem 1rem;
	background: var(--invitely-accent-soft);
	border-radius: var(--invitely-radius);
}

.invitely-form .invitely-pay--upfront .invitely-pay__title {
	font-size: calc( var(--invitely-size-heading) * 0.86 * var(--invitely-heading-scale) );
}

/* ---------------------------------------------------------- Add to calendar */

.invitely-calendar {
	margin: 0 0 1.75rem;
}

.invitely-calendar__title {
	margin: 0 0 0.6rem;
	font-size: calc( var(--invitely-size-heading) * 0.91 * var(--invitely-heading-scale) );
}

.invitely-calendar__links {
	display: flex;
	flex-wrap: wrap;
	gap: 0.5rem;
	margin: 0;
}
