/**
 * Wedwebs Envelope Opener
 *
 * Layer order inside .ww-envelope__env (a preserve-3d box), back to front:
 * ground shadow (z -2px), back/liner (0), card (1px), pocket (2px),
 * flap (3px, folds back to -1px), seal (4px). z-index does nothing inside a
 * 3D context, so every layer is placed with translateZ.
 *
 * Stages are classes on .ww-envelope added by the script:
 * is-seal > is-flap > is-card > is-lift > is-reveal > is-revealed.
 * Keep proportions, then expand adds is-expanded along with is-reveal.
 * Travel distances (--ww-rise, --ww-lift-*, --ww-reveal-*) are measured in
 * px by the script so the card always clears the pocket before it moves
 * forward, whatever the card and envelope proportions.
 */

.ww-envelope {
	/* palette (overridden by the Color Preset control) */
	--ww-paper: #2f4a3e;
	--ww-paper-shade: #263d33;
	--ww-paper-img: none;
	/* How the texture sits on the paper, set by the Position, Attachment,
	   Repeat and Display Size controls. Every panel is a full envelope sized
	   box, so one set of values lands the same crop on all of them. */
	--ww-paper-pos: center;
	--ww-paper-size: cover;
	--ww-paper-repeat: repeat;
	--ww-paper-attach: scroll;
	/* How strongly the folds are shaded. Colour alone separates the panels
	   until a texture image covers it, so the shading has to carry the folds. */
	--ww-fold: 0.16;
	/* Paper Type lays a paper from Wedwebs Paper Texture on every panel, and
	   that plugin's stylesheet reads these four there. A Container around the
	   envelope may set them for its own paper, so they are cleared here to
	   keep its settings off the envelope. The Paper Strength and Paper Grain
	   Size controls set two of them again. */
	--ww-paper-strength: initial;
	--ww-paper-scale: initial;
	--ww-paper-cloud: initial;
	--ww-paper-blend: initial;
	--ww-liner: #1f3129;
	--ww-liner-line: #b89a5e;
	--ww-liner-img: none;
	--ww-liner-tile: 160px;
	/* How the liner image sits on the sheet. The vector patterns below repeat
	   at their own scale, so these defaults suit them; the Image liner sets
	   them from the Image Fit control. */
	--ww-liner-size: auto;
	--ww-liner-pos: 0 0;
	--ww-liner-repeat: repeat;
	--ww-seal: #8a2a2e;
	--ww-seal-hi: #b24a4c;
	--ww-frame: rgba(43, 42, 38, 0.28);
	--ww-frame-inset: 12px;
	--ww-ground-shadow: rgba(30, 28, 22, 0.38);
	--ww-hint-dot: var(--ww-seal);
	--ww-hint-gap: 28px;
	--ww-hint-dot-size: 8px;
	--ww-hint-dot-gap: 8px;
	--ww-hint-pad: 16px;
	/* Written as a set by the Position control, for the reason the Size
	   Mode control gives: a device that left one of them alone would take
	   it from the device above and end up with a half flipped hint. */
	--ww-hint-dir: column;
	--ww-hint-top: auto;
	--ww-hint-bottom: calc(var(--ww-hint-gap) + env(safe-area-inset-bottom, 0px));
	--ww-hint-max: none;
	--ww-hint-nudge: 0px;

	/*
	 * geometry
	 *
	 * These match the panel's defaults, so reading this file tells the same
	 * story the controls do. Elementor's generated CSS overrides all of them,
	 * and the size mode writes the three env values below as a set, which is
	 * why they stay at the Keep proportions geometry here.
	 */
	--ww-ratio: 1.7;
	--ww-env-w: 100vw;
	--ww-env-max: min(100%, 400px);
	--ww-env-h: auto;
	--ww-seal-offset: 0%;
	--ww-split: 0;
	/* The pocket follows the flap: side seams meet where the flap ends, and
	   the bottom panel reaches above that line so the two overlap. */
	--ww-pocket-y: var(--ww-flap-depth);
	--ww-pocket-apex: calc(var(--ww-flap-depth) - 14%);
	--ww-card-w: 100%;
	--ww-card-h: 100%;
	--ww-card-r: 2px;
	--ww-card-arch: 28%;
	--ww-tilt: 0deg;
	--ww-forward: 0px;
	--ww-flap-depth: 57%;
	/* How much of each fold is given to the curve at its point. A share, not a
	   length, so the rounding keeps its proportion at every size. */
	--ww-point: 0.2;
	/* Where the unfold card starts before it settles. Never above 1. */
	--ww-unfold-rest: 0.94;

	/* measured by the script */
	--ww-rise: 0px;
	--ww-lift-card: 0px;
	--ww-lift-env: 0px;
	--ww-reveal-card: 0px;
	--ww-reveal-env: 0px;
	--ww-zoom: 1;
	--ww-design-w: 360px;
	--ww-seal-w: 21%;
	--ww-panel-travel: 120%;
	--ww-content-h: 100%;

	/* stage durations in ms, set by the script */
	--ww-d-seal: 380ms;
	--ww-d-flap: 760ms;
	--ww-d-card: 850ms;
	--ww-d-lift: 600ms;
	--ww-d-reveal: 950ms;

	--ww-ease: cubic-bezier(0.62, 0.04, 0.24, 1);
	--ww-noise: none;
	--ww-card-noise: none;

	--ww-liner-pattern: none;

	position: relative;
}

.ww-envelope-grain-yes .ww-envelope,
.ww-envelope-card-grain-yes .ww-envelope {
	--ww-grain: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='180' height='180'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0  0 0 0 0 0  0 0 0 0 0  0 0 0 .11 0'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>");
}
.ww-envelope-grain-yes .ww-envelope { --ww-noise: var(--ww-grain); }
.ww-envelope-card-grain-yes .ww-envelope { --ww-card-noise: var(--ww-grain); }

/* liner presets */
.ww-envelope--liner-diamond {
	--ww-liner-pattern:
		repeating-linear-gradient(45deg, transparent 0 9px, color-mix(in srgb, var(--ww-liner-line) 55%, transparent) 9px 10px),
		repeating-linear-gradient(-45deg, transparent 0 9px, color-mix(in srgb, var(--ww-liner-line) 55%, transparent) 9px 10px);
}
.ww-envelope--liner-stripes {
	--ww-liner-pattern: repeating-linear-gradient(90deg, transparent 0 7px, color-mix(in srgb, var(--ww-liner-line) 50%, transparent) 7px 8px);
}
.ww-envelope--liner-image {
	--ww-liner-pattern: var(--ww-liner-img);
	--ww-liner-pos: center;
}

/*
 * Image Fit, the same three choices a background image gets anywhere else.
 * Written against both liner classes so the vector patterns above keep their
 * own repeat whatever the fit control was last left at.
 */
.ww-envelope--liner-image.ww-envelope--linerfit-cover {
	--ww-liner-size: cover;
	--ww-liner-repeat: no-repeat;
}

.ww-envelope--liner-image.ww-envelope--linerfit-contain {
	--ww-liner-size: contain;
	--ww-liner-repeat: no-repeat;
}

.ww-envelope--liner-image.ww-envelope--linerfit-tile {
	--ww-liner-size: var(--ww-liner-tile);
	--ww-liner-repeat: repeat;
}

/* ---------- scene ---------- */

.ww-envelope__scene {
	position: relative;
	display: flex;
	/* The scene holds the envelope and the hint, so reversing the column is
	   all it takes to move the hint above the envelope. */
	flex-direction: var(--ww-hint-dir, column);
	align-items: center;
	gap: var(--ww-hint-gap);
	width: var(--ww-stage-w, auto);
	min-height: var(--ww-stage-h, 0px);
	justify-content: center;
	/* Clips the full screen paper until the script has switched Fill screen
	   to its own layout (see "fill screen" below). */
	overflow: var(--ww-stage-clip, visible);
	perspective: 1100px;
	perspective-origin: 50% 30%;
	cursor: pointer;
	-webkit-tap-highlight-color: transparent;
	outline: none;
}

.ww-envelope.is-revealed .ww-envelope__scene {
	cursor: auto;
}

.ww-envelope__env {
	position: relative;
	width: var(--ww-env-w);
	max-width: var(--ww-env-max);
	height: var(--ww-env-h);
	aspect-ratio: var(--ww-ratio);
	transform-style: preserve-3d;
	-webkit-transform-style: preserve-3d;
	transform: rotateX(var(--ww-tilt));
	transition: transform var(--ww-d-reveal) var(--ww-ease);
}

.ww-envelope__scene:focus-visible .ww-envelope__env {
	outline: 2px dashed currentColor;
	outline-offset: 10px;
}

.ww-envelope__env > * {
	position: absolute;
	inset: 0;
}

/*
 * A spare copy of the layer order, in paint order terms.
 *
 * While the browser keeps the 3D context these do nothing: translateZ decides
 * what is in front, as the note at the top of this file says. They are here
 * for the engines that quietly flatten the context instead, which a filter or
 * a texture image on one of the layers is enough to trigger. A flattened
 * context falls back to document order, and document order puts the flap over
 * the card, so the card would dive under the opened flap on its way out.
 *
 * The opened flap is the one layer whose place changes: it folds back behind
 * the envelope, so it drops behind the card with it. It changes place halfway
 * through the fold, not at the start of it, which is what is-flap-over marks.
 * is-flap goes on while the flap is still standing over the card, so a flap
 * that gave up its place on that class would be swallowed by the card for the
 * rest of the rotation and reappear only once it cleared the envelope's top
 * edge. The faces trade places on the same beat, for the same reason.
 */
.ww-envelope__shadow { z-index: -2; }
.ww-envelope__back { z-index: 0; }
.ww-envelope__card { z-index: 1; }
.ww-envelope__pocket { z-index: 2; }
.ww-envelope__flap { z-index: 3; }
.ww-envelope__seal { z-index: 4; }

.ww-envelope.is-flap-over .ww-envelope__flap { z-index: -1; }

.ww-envelope__face--front { z-index: 1; }
.ww-envelope__face--back { z-index: 0; }
.ww-envelope.is-flap-over .ww-envelope__face--front { z-index: 0; }
.ww-envelope.is-flap-over .ww-envelope__face--back { z-index: 1; }

.ww-envelope__shadow {
	inset: auto 4% -9% 4%;
	height: 22%;
	background: radial-gradient(50% 50% at 50% 50%, var(--ww-ground-shadow), transparent 72%);
	transform: translateY(0) translateZ(-2px);
	filter: blur(6px);
	transition:
		transform var(--ww-d-lift) var(--ww-ease),
		opacity var(--ww-d-lift) var(--ww-ease);
	pointer-events: none;
}

/*
 * The liner is one sheet. A real envelope lines the back panel and carries the
 * lining on across the inside of the flap, so both surfaces are painted from
 * the same background here. They can be: each is a full envelope sized box
 * (the flap and its faces are inset: 0 like everything else, and only a
 * clip-path decides what shows), so one `cover` lands the same crop on both
 * and the halves meet instead of each cropping the image for itself.
 */
.ww-envelope__back,
.ww-envelope__face--back i {
	background: var(--ww-noise), var(--ww-liner-pattern), var(--ww-liner);
	background-size: auto, var(--ww-liner-size), auto;
	background-position: 0 0, var(--ww-liner-pos), 0 0;
	background-repeat: repeat, var(--ww-liner-repeat), repeat;
}

.ww-envelope__back {
	border-radius: 3px;
	box-shadow: inset 0 18px 30px rgba(0, 0, 0, 0.35);
}

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

.ww-envelope__card {
	inset: auto;
	left: calc((100% - var(--ww-card-w)) / 2);
	top: calc((100% - var(--ww-card-h)) / 2);
	width: var(--ww-card-w);
	height: var(--ww-card-h);
	overflow: hidden;
	background-color: #fbf8f1;
	border-radius: var(--ww-card-r);
	box-shadow: 0 1px 2px rgba(0, 0, 0, 0.18), 0 10px 30px rgba(0, 0, 0, 0.12);
	transform: translateY(0) translateZ(1px);
	transition: transform var(--ww-d-card) var(--ww-ease);
}

.ww-envelope__card--arch {
	border-radius:
		50% 50% var(--ww-card-r) var(--ww-card-r) /
		var(--ww-card-arch) var(--ww-card-arch) var(--ww-card-r) var(--ww-card-r);
}

.ww-envelope__card::after {
	content: "";
	position: absolute;
	inset: 0;
	background: var(--ww-card-noise);
	pointer-events: none;
	border-radius: inherit;
}

.ww-envelope__card.has-frame::before {
	content: "";
	position: absolute;
	inset: var(--ww-frame-inset);
	border: 1px solid var(--ww-frame);
	border-radius: inherit;
	pointer-events: none;
	z-index: 1;
}

/*
 * Two ways to size the card content. Responsive (the default) lets it fill
 * the card at the card's real width, like any other section on the page.
 * Scaled lays it out at a fixed design width and zooms it to fit, for a card
 * that must look identical on every screen.
 */
.ww-envelope--fit-natural .ww-envelope__content {
	width: 100%;
	height: 100%;
	zoom: 1;
	transform: none;
}

.ww-envelope__content {
	position: absolute;
	left: 0;
	top: 0;
	width: var(--ww-design-w);
	height: var(--ww-content-h);
	zoom: var(--ww-zoom);
	display: flex;
	flex-direction: column;
	/*
	 * Safe: content taller than the card starts at the top instead of
	 * spilling past both edges, so what is cut off is the end of it, not the
	 * heading.
	 */
	justify-content: center;
	justify-content: safe center;
	pointer-events: none;
}

.ww-envelope.is-no-zoom .ww-envelope__content {
	zoom: 1;
	transform: scale(var(--ww-zoom));
	transform-origin: 0 0;
}

.ww-envelope.is-revealed .ww-envelope__content {
	pointer-events: auto;
}

.ww-envelope__content > * {
	width: 100%;
}

/*
 * The card's height is the single source of truth: the content grows to fill
 * it, so nothing needs a height of its own and the card background never
 * shows through above or below the content.
 *
 * Not in Fill screen, where it is the other way round: the card takes the
 * height of the content, so the content keeps the height it was designed with.
 * It still grows into any room the card has left (see "fill screen" below),
 * but by flex-grow, which leaves its own min-height alone. An expanded card
 * (see "keep proportions, then expand") is sized by its content the same way.
 */
.ww-envelope-stretch-yes .ww-envelope:not(.is-fill):not(.is-expanded) .ww-envelope__content > * {
	flex: 1 0 auto;
	min-height: 100%;
}

.ww-envelope-stretch-yes .ww-envelope.is-fill .ww-envelope__content > *,
.ww-envelope-stretch-yes .ww-envelope.is-expanded .ww-envelope__content > * {
	flex: 1 0 auto;
}

.ww-envelope__placeholder {
	padding: 24px;
	text-align: center;
	font: 13px/1.5 system-ui, -apple-system, "Segoe UI", sans-serif;
	color: #6b665c;
}

/* ---------- pocket ---------- */

.ww-envelope__pocket {
	--ww-layer-z: 2px;
	transform: translateY(0) translateZ(2px);
	filter: drop-shadow(0 -1px 2px rgba(0, 0, 0, calc(var(--ww-fold) * 1.4)));
}

.ww-envelope__pocket i,
.ww-envelope__face i {
	position: absolute;
	inset: 0;
}

.ww-envelope__pocket-left {
	clip-path: polygon(0 0, 54% var(--ww-pocket-y), 0 100%);
	background:
		var(--ww-noise),
		linear-gradient(90deg, rgba(0, 0, 0, 0) 55%, rgba(0, 0, 0, calc(var(--ww-fold) * 0.75))),
		var(--ww-paper-img) var(--ww-paper-pos) / var(--ww-paper-size) var(--ww-paper-repeat) var(--ww-paper-attach),
		var(--ww-paper);
}

.ww-envelope__pocket-right {
	clip-path: polygon(100% 0, 46% var(--ww-pocket-y), 100% 100%);
	background:
		var(--ww-noise),
		linear-gradient(270deg, rgba(0, 0, 0, 0) 55%, rgba(0, 0, 0, calc(var(--ww-fold) * 0.75))),
		var(--ww-paper-img) var(--ww-paper-pos) / var(--ww-paper-size) var(--ww-paper-repeat) var(--ww-paper-attach),
		var(--ww-paper);
}

.ww-envelope__pocket-bottom {
	clip-path: polygon(0 100%, 50% var(--ww-pocket-apex), 100% 100%);
	/*
	 * Flat tone, not a gradient. A gradient this wide reads as haze over a
	 * light texture instead of as a fold; what makes the flap above read as
	 * paper is its edge, so the bottom panel gets the same treatment: an even
	 * tone barely apart from the sides, and a real shadow along its fold.
	 */
	background:
		var(--ww-noise),
		linear-gradient(rgba(0, 0, 0, calc(var(--ww-fold) * 0.35)) 0 0),
		var(--ww-paper-img) var(--ww-paper-pos) / var(--ww-paper-size) var(--ww-paper-repeat) var(--ww-paper-attach),
		var(--ww-paper-shade);
	filter:
		drop-shadow(0 -1px 0 rgba(0, 0, 0, calc(var(--ww-fold) * 1.6)))
		drop-shadow(0 -3px 7px rgba(0, 0, 0, calc(var(--ww-fold) * 1.1)));
}

/* ---------- flap ---------- */

.ww-envelope__flap {
	transform-origin: 50% 0;
	transform-style: preserve-3d;
	-webkit-transform-style: preserve-3d;
	transform: translateY(0) translateZ(3px) rotateX(0deg);
	transition: transform var(--ww-d-flap) var(--ww-ease);
}

/*
 * Each face is half a millimetre of paper in front of its own side of the
 * flap, so whichever side is turned towards the viewer is also the nearer of
 * the two. backface-visibility alone would do it, but a face carrying a filter
 * or a texture image is rendered as a group on some engines, and a grouped
 * face can lose its backface test and print the front of the flap, mirrored,
 * on the inside. The offset settles the order without that test.
 */
.ww-envelope__face {
	position: absolute;
	inset: 0;
	backface-visibility: hidden;
	-webkit-backface-visibility: hidden;
	transform: translateZ(0.5px);
}

.ww-envelope__face--front {
	filter: drop-shadow(0 2px 3px rgba(0, 0, 0, calc(var(--ww-fold) * 2)));
}

.ww-envelope__face--front i {
	clip-path: var(--ww-flap-clip-front, none);
	-webkit-mask: var(--ww-flap-mask-front, none) 0 0 / 100% 100% no-repeat;
	mask: var(--ww-flap-mask-front, none) 0 0 / 100% 100% no-repeat;
	background:
		var(--ww-noise),
		linear-gradient(180deg, rgba(255, 255, 255, calc(var(--ww-fold) * 0.5)), rgba(0, 0, 0, 0) 70%),
		var(--ww-paper-img) var(--ww-paper-pos) / var(--ww-paper-size) var(--ww-paper-repeat) var(--ww-paper-attach),
		var(--ww-paper);
}

.ww-envelope__face--back {
	transform: rotateX(180deg) translateZ(0.5px);
}

/* Background: the shared liner rule above paints this face. */
.ww-envelope__face--back i {
	clip-path: var(--ww-flap-clip-back, none);
	-webkit-mask: var(--ww-flap-mask-back, none) 0 0 / 100% 100% no-repeat;
	mask: var(--ww-flap-mask-back, none) 0 0 / 100% 100% no-repeat;
}

/* ---------- rounded points ---------- */

/*
 * A polygon() corner is always a cut, and real paper never folds to a knife
 * point. shape() draws the same outlines with a curve at each point, and it
 * accepts percentages, so the rounding stays proportional the way the rest of
 * the geometry does. Every point is trimmed by --ww-point of its own two
 * edges, which puts the cut on the edge itself and keeps the curve tangent.
 *
 * Browsers without shape() keep the polygons above, sharp as before.
 */
@supports (clip-path: shape(from 0 0, line to 100% 0)) {

	.ww-envelope--flap-pointed .ww-envelope__face--front i {
		clip-path: var(
			--ww-flap-shape-front,
			shape(
				from 0 0,
				line to 100% 0,
				line to
					calc(50% + var(--ww-point) * 50%)
					calc(var(--ww-flap-depth) - var(--ww-point) * var(--ww-flap-depth)),
				curve to
					calc(50% - var(--ww-point) * 50%)
					calc(var(--ww-flap-depth) - var(--ww-point) * var(--ww-flap-depth))
					with 50% var(--ww-flap-depth),
				close
			)
		);
	}

	.ww-envelope--flap-pointed .ww-envelope__face--back i {
		clip-path: var(
			--ww-flap-shape-back,
			shape(
				from 0 100%,
				line to 100% 100%,
				line to
					calc(50% + var(--ww-point) * 50%)
					calc(100% - var(--ww-flap-depth) + var(--ww-point) * var(--ww-flap-depth)),
				curve to
					calc(50% - var(--ww-point) * 50%)
					calc(100% - var(--ww-flap-depth) + var(--ww-point) * var(--ww-flap-depth))
					with 50% calc(100% - var(--ww-flap-depth)),
				close
			)
		);
	}

	.ww-envelope__pocket-left {
		clip-path: shape(
			from 0 0,
			line to
				calc(54% - var(--ww-point) * 54%)
				calc(var(--ww-pocket-y) - var(--ww-point) * var(--ww-pocket-y)),
			curve to
				calc(54% - var(--ww-point) * 54%)
				calc(var(--ww-pocket-y) + var(--ww-point) * (100% - var(--ww-pocket-y)))
				with 54% var(--ww-pocket-y),
			line to 0 100%,
			close
		);
	}

	.ww-envelope__pocket-right {
		clip-path: shape(
			from 100% 0,
			line to
				calc(46% + var(--ww-point) * 54%)
				calc(var(--ww-pocket-y) - var(--ww-point) * var(--ww-pocket-y)),
			curve to
				calc(46% + var(--ww-point) * 54%)
				calc(var(--ww-pocket-y) + var(--ww-point) * (100% - var(--ww-pocket-y)))
				with 46% var(--ww-pocket-y),
			line to 100% 100%,
			close
		);
	}

	.ww-envelope__pocket-bottom {
		clip-path: shape(
			from 0 100%,
			line to
				calc(50% - var(--ww-point) * 50%)
				calc(var(--ww-pocket-apex) + var(--ww-point) * (100% - var(--ww-pocket-apex))),
			curve to
				calc(50% + var(--ww-point) * 50%)
				calc(var(--ww-pocket-apex) + var(--ww-point) * (100% - var(--ww-pocket-apex)))
				with 50% var(--ww-pocket-apex),
			line to 100% 100%,
			close
		);
	}
}

/* ---------- seal ---------- */

.ww-envelope__seal {
	inset: auto;
	left: 50%;
	top: calc(var(--ww-flap-depth) + var(--ww-seal-offset));
	width: var(--ww-seal-w);
	aspect-ratio: 1;
	transform: translate(-50%, -50%) translateZ(4px);
	display: grid;
	place-items: center;
	container-type: inline-size;
	transition:
		transform var(--ww-d-seal) var(--ww-ease),
		opacity calc(var(--ww-d-seal) * 0.85) ease-out;
}

.ww-envelope__seal--wax {
	border-radius: 47% 53% 50% 50% / 52% 46% 54% 48%;
	background:
		radial-gradient(60% 60% at 38% 32%, var(--ww-seal-hi), transparent 62%),
		radial-gradient(circle at 50% 50%, var(--ww-seal) 58%, color-mix(in srgb, var(--ww-seal) 70%, #000) 72%, var(--ww-seal) 76%);
	box-shadow: 0 3px 6px rgba(0, 0, 0, 0.35), inset 0 -3px 5px rgba(0, 0, 0, 0.3);
}

.ww-envelope__seal-mark {
	width: 70%;
	aspect-ratio: 1;
	border-radius: 50%;
	display: grid;
	place-items: center;
	box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.45), 0 1px 0 rgba(255, 255, 255, 0.18);
	font-family: "Bodoni Moda", "Didot", "Bodoni 72", Georgia, serif;
	font-style: italic;
	font-size: 26cqi;
	line-height: 1;
	white-space: nowrap;
	color: color-mix(in srgb, var(--ww-seal) 60%, #000);
	text-shadow: 0 1px 0 rgba(255, 255, 255, 0.22);
}

.ww-envelope__seal--image img {
	width: 100%;
	height: 100%;
	object-fit: contain;
	filter: drop-shadow(0 3px 4px rgba(0, 0, 0, 0.35));
}

/* ---------- hint ---------- */

.ww-envelope__hint {
	margin: 0;
	position: var(--ww-hint-abs, static);
	left: 0;
	right: 0;
	top: var(--ww-hint-top, auto);
	bottom: var(--ww-hint-bottom, calc(var(--ww-hint-gap) + env(safe-area-inset-bottom, 0px)));
	padding: 0 var(--ww-hint-pad);
	font-size: 13px;
	letter-spacing: 0.04em;
	text-align: center;
	color: #6b665c;
	transition: opacity 300ms ease;
}

/*
 * The words get their own box so the dot can sit outside it. A dot that rides
 * in the line pushes the words along by its own width, and a line centred as
 * a whole then reads as off-centre by half that much, which is the illusion
 * the Dot Placement control is really choosing about. Every placement below
 * takes the dot out of flow and, where it needs the room, reserves it with
 * padding on this box instead.
 */
.ww-envelope__hint-text {
	position: relative;
	display: inline-block;
	max-width: var(--ww-hint-max, none);
	margin-left: var(--ww-hint-nudge, 0px);
	margin-right: calc(var(--ww-hint-nudge, 0px) * -1);
}

/*
 * The pulse animates transform, so the dot is placed with offsets and margins
 * only. top is set against the first line rather than the box, so a hint that
 * wraps keeps the dot beside its opening words.
 */
.ww-envelope__hint-text::before {
	content: "";
	position: absolute;
	/* Half a line down, so the dot meets the middle of the first line.
	   The em value is the guess a browser without lh falls back to. */
	top: 0.75em;
	top: calc(0.5lh);
	right: 100%;
	width: var(--ww-hint-dot-size);
	height: var(--ww-hint-dot-size);
	margin: calc(var(--ww-hint-dot-size) / -2) var(--ww-hint-dot-gap) 0 0;
	border-radius: 50%;
	background: var(--ww-hint-dot);
	animation: ww-envelope-pulse 1.6s ease-in-out infinite;
}

/* Dot inside the line: the old behaviour, kept for anyone who wants it. */
.ww-envelope--hint-dot-inline .ww-envelope__hint-text {
	padding-left: calc(var(--ww-hint-dot-size) + var(--ww-hint-dot-gap));
}

.ww-envelope--hint-dot-inline .ww-envelope__hint-text::before {
	right: auto;
	left: 0;
	margin-right: 0;
}

.ww-envelope--hint-dot-after .ww-envelope__hint-text::before {
	right: auto;
	left: 100%;
	margin-right: 0;
	margin-left: var(--ww-hint-dot-gap);
}

.ww-envelope--hint-dot-above .ww-envelope__hint-text {
	padding-top: calc(var(--ww-hint-dot-size) + var(--ww-hint-dot-gap));
}

.ww-envelope--hint-dot-above .ww-envelope__hint-text::before {
	top: 0;
	right: auto;
	left: 50%;
	margin: 0 0 0 calc(var(--ww-hint-dot-size) / -2);
}

.ww-envelope--hint-dot-none .ww-envelope__hint-text::before,
.ww-envelope--hint-still .ww-envelope__hint-text::before {
	animation: none;
}

.ww-envelope--hint-dot-none .ww-envelope__hint-text::before {
	display: none;
}

@keyframes ww-envelope-pulse {
	50% {
		transform: scale(1.7);
		opacity: 0.35;
	}
}

/* ---------- stages ---------- */

.ww-envelope.is-seal .ww-envelope__seal {
	transform: translate(-50%, -50%) translateZ(40px) scale(1.12) rotate(-8deg);
	opacity: 0;
}

.ww-envelope.is-seal .ww-envelope__hint {
	opacity: 0;
}

.ww-envelope.is-flap .ww-envelope__flap {
	transform: translateY(0) translateZ(-1px) rotateX(180deg);
}

.ww-envelope.is-card .ww-envelope__card {
	transform: translateY(var(--ww-rise)) translateZ(1px);
}

/*
 * Pull apart: the card keeps rising while the envelope drops until the
 * card's bottom edge is above the envelope's top edge. The card stays behind
 * the pocket (1px < 2px) until then, so it never passes through the paper.
 */
.ww-envelope.is-lift .ww-envelope__card {
	transform: translateY(var(--ww-lift-card)) translateZ(1px);
	transition-duration: var(--ww-d-lift);
}

.ww-envelope.is-lift .ww-envelope__back,
.ww-envelope.is-lift .ww-envelope__pocket {
	transform: translateY(var(--ww-lift-env)) translateZ(var(--ww-layer-z, 0px));
}

.ww-envelope.is-lift .ww-envelope__flap {
	transform: translateY(var(--ww-lift-env)) translateZ(-1px) rotateX(180deg);
}

.ww-envelope.is-lift .ww-envelope__back,
.ww-envelope.is-lift .ww-envelope__pocket,
.ww-envelope.is-lift .ww-envelope__flap {
	transition:
		transform var(--ww-d-lift) var(--ww-ease),
		opacity var(--ww-d-lift) var(--ww-ease);
}

.ww-envelope.is-lift .ww-envelope__shadow {
	transform: translateY(160%) translateZ(-2px);
	opacity: 0.6;
}

/*
 * Only now does the card come forward. The envelope falls further than the
 * card settles (the script guarantees it), and both use the same easing, so
 * the gap between them only grows.
 */
.ww-envelope.is-reveal .ww-envelope__env {
	transform: rotateX(0deg);
}

/*
 * Forward is drawn as a 2D scale about the vanishing point, not translateZ.
 * On a flat card facing the viewer the two land on the same picture, but a
 * translateZ grows the card through the perspective divide, which the browser
 * cannot size ahead of time: it keeps re-rasterising the card at each new
 * scale on the way, and the text and frame visibly snap from one pixel grid
 * to the next. A scale is known end to end, so the card is rasterised once
 * and glides. The script measures --ww-forward-scale from --ww-forward and
 * --ww-forward-origin from the perspective origin.
 */
.ww-envelope.is-reveal .ww-envelope__card {
	transform: translateY(var(--ww-reveal-card)) translateZ(1px) scale(var(--ww-forward-scale, 1));
	transform-origin: var(--ww-forward-origin, 50% 50%);
	transition-duration: var(--ww-d-reveal);
}

.ww-envelope.is-reveal .ww-envelope__back,
.ww-envelope.is-reveal .ww-envelope__pocket {
	transform: translateY(var(--ww-reveal-env)) translateZ(var(--ww-layer-z, 0px));
	opacity: 0;
}

.ww-envelope.is-reveal .ww-envelope__flap {
	transform: translateY(var(--ww-reveal-env)) translateZ(-1px) rotateX(180deg);
	opacity: 0;
}

.ww-envelope.is-reveal .ww-envelope__back,
.ww-envelope.is-reveal .ww-envelope__pocket,
.ww-envelope.is-reveal .ww-envelope__flap {
	transition:
		transform var(--ww-d-reveal) var(--ww-ease),
		opacity calc(var(--ww-d-reveal) * 0.55) ease-in calc(var(--ww-d-reveal) * 0.19);
}

.ww-envelope.is-reveal .ww-envelope__shadow {
	opacity: 0;
}

.ww-envelope.is-revealed .ww-envelope__back,
.ww-envelope.is-revealed .ww-envelope__pocket,
.ww-envelope.is-revealed .ww-envelope__flap,
.ww-envelope.is-revealed .ww-envelope__seal,
.ww-envelope.is-revealed .ww-envelope__shadow,
.ww-envelope.is-revealed .ww-envelope__hint {
	visibility: hidden;
}

/* The dot is out of sight by now, but a composited animation left running is
   still work the compositor repeats forever. */
.ww-envelope.is-revealed .ww-envelope__hint-text::before {
	animation: none;
}

/* ---------- unfold style ----------
 *
 * The card is not inside the envelope here: it lies behind the paper at the
 * full envelope size, so the opening flap reveals it through the hole, and
 * the panels then fold away to clear it. Stages read as:
 * seal > flap opens onto the card > card settles > panels fold away > reveal.
 */

.ww-envelope--unfold .ww-envelope__back {
	display: none;
}

.ww-envelope--unfold .ww-envelope__card {
	left: 0;
	top: 0;
	width: 100%;
	height: 100%;
	/*
	 * The card settles out of a slight zoom. It has to zoom *in* to its place,
	 * never out of a larger one: the card is exactly envelope sized here, so a
	 * resting scale above 1 hangs outside the paper on every side, which the
	 * closed envelope shows as a rim wherever the envelope does not fill the
	 * screen.
	 */
	transform: translateZ(0) scale(var(--ww-unfold-rest));
	box-shadow: none;
	transition:
		transform var(--ww-d-card) var(--ww-ease),
		opacity var(--ww-d-card) var(--ww-ease);
}

.ww-envelope--unfold .ww-envelope__pocket i,
.ww-envelope--unfold .ww-envelope__flap {
	transition:
		transform var(--ww-d-lift) var(--ww-ease),
		opacity var(--ww-d-lift) var(--ww-ease);
}

/* The card is already in place; it only settles out of its slight zoom. */
.ww-envelope--unfold.is-card .ww-envelope__card {
	transform: translateZ(0) scale(1);
}

/* The card never travels in this style, so hold it against the draw rules. */
.ww-envelope--unfold.is-lift .ww-envelope__card {
	transform: translateZ(0) scale(1);
}

/* Panels fold away: sides outward, bottom down, flap further up and out. */
.ww-envelope--unfold.is-lift .ww-envelope__pocket-left {
	transform: translateX(calc(var(--ww-panel-travel) * -1)) rotate(-4deg);
}

.ww-envelope--unfold.is-lift .ww-envelope__pocket-right {
	transform: translateX(var(--ww-panel-travel)) rotate(4deg);
}

.ww-envelope--unfold.is-lift .ww-envelope__pocket-bottom {
	transform: translateY(var(--ww-panel-travel));
}

.ww-envelope--unfold.is-lift .ww-envelope__pocket {
	transform: translateZ(2px);
}

.ww-envelope--unfold.is-lift .ww-envelope__flap {
	transform: translateY(calc(var(--ww-panel-travel) * -1)) translateZ(-1px) rotateX(180deg);
}

.ww-envelope--unfold.is-lift .ww-envelope__shadow {
	opacity: 0;
	transform: translateY(0) translateZ(-2px);
}

/* Nothing is drawn forward at the end: the card is the page. */
.ww-envelope--unfold.is-reveal .ww-envelope__card {
	transform: translateZ(0) scale(1);
	transition-duration: var(--ww-d-reveal);
}

.ww-envelope--unfold.is-reveal .ww-envelope__pocket,
.ww-envelope--unfold.is-reveal .ww-envelope__flap {
	opacity: 0;
	transition:
		transform var(--ww-d-reveal) var(--ww-ease),
		opacity calc(var(--ww-d-reveal) * 0.6) ease-in;
}

.ww-envelope--unfold.is-reveal .ww-envelope__env {
	transform: rotateX(0deg);
}

/* ---------- holding the content ----------
 *
 * Elementor starts an entrance animation when its element comes into view,
 * and behind a cover every element is in view from the first frame, so its
 * animations play and their delays expire before the guest opens anything.
 * Pausing the animation is not enough, because the delay is a setTimeout, not
 * animation-delay.
 *
 * Taking the content out of the layout solves both at once: an element that
 * is display: none never comes into view, so Elementor starts nothing at all
 * for it. When it is put back, its observers fire for the first time and
 * every delay counts from that moment. The class is printed server side, so
 * this holds from the first painted frame.
 */

.ww-envelope--content-hidden .ww-envelope__content,
.ww-envelope-content-hidden {
	display: none !important;
}

/* ---------- slot source ----------
 *
 * A container marked as a card slot is hidden until the script moves it into
 * the envelope, so it never flashes in its original place. In the editor it
 * stays visible and editable where the author put it. Elementor swaps
 * elementor-editor-active for elementor-editor-preview while previewing and
 * while the colour sampler is picking, and the script moves nothing in either.
 */

body:not(.elementor-editor-active):not(.elementor-editor-preview) .ww-envelope-slot {
	visibility: hidden;
}

/* ---------- cover overlays ----------
 *
 * Anything the author floats above the envelope inside the cover (a guest
 * name, the couple's names, a wedding title) is a sibling of the envelope,
 * not a part of it, so it would sit still while the envelope opens and then
 * stay on top of the card underneath. Give the widget the class
 * ww-cover-fade in Elementor (Advanced > CSS Classes) and it leaves with the
 * envelope instead: the script marks the cover on the lift, one stage before
 * the envelope falls away.
 *
 * The easing is written out rather than read from --ww-ease, because the
 * cover is the envelope's ancestor and inherits nothing from it. The script
 * copies --ww-d-lift up, so the fade still follows the panel's Speed.
 */

.ww-cover-fade {
	transition:
		opacity var(--ww-d-lift, 600ms) ease,
		transform var(--ww-d-lift, 600ms) cubic-bezier(0.62, 0.04, 0.24, 1);
}

.ww-cover--opening .ww-cover-fade {
	opacity: 0;
	transform: translateY(-0.75rem);
	/* Cleared straight away: a faded overlay would still swallow taps meant
	   for the card underneath for the length of the transition. */
	pointer-events: none;
}

/*
 * Held hidden once the transition is over. Visibility rather than display, so
 * the overlay keeps its place and nothing around it reflows as it goes.
 */
.ww-cover--revealed .ww-cover-fade {
	opacity: 0;
	pointer-events: none;
	visibility: hidden;
}

/*
 * For an overlay that sits in the cover's flow rather than over it. With
 * After Opening set to keep the card as the first screen, the cover becomes
 * the top of the page, and a hidden widget still in the flow would leave a
 * blank gap there.
 */
.ww-cover--revealed .ww-cover-fade.ww-cover-fade-flow {
	display: none;
}

/*
 * Only while the timeline runs. Each panel carries a clip-path and a
 * drop-shadow, so without its own compositor layer the browser re-rasterises
 * that work on every frame of the opening. Promoting them for good would keep
 * the memory for a page that has finished moving, so the class is added when
 * the envelope opens and dropped when it settles.
 */
.ww-envelope.is-running .ww-envelope__card,
.ww-envelope.is-running .ww-envelope__pocket,
.ww-envelope.is-running .ww-envelope__pocket i,
.ww-envelope.is-running .ww-envelope__shadow {
	will-change: transform, opacity;
}

/*
 * Transform only for the two boxes that hold a 3D context. A hint for
 * opacity makes the browser treat the box as a group, as real opacity would,
 * and a group is flattened: the flap then loses its inside face and shows
 * the outside of the paper, mirrored, where the liner should be.
 */
.ww-envelope.is-running .ww-envelope__env,
.ww-envelope.is-running .ww-envelope__flap {
	will-change: transform;
}

/* ---------- fill screen ----------
 *
 * The card is the page from the first frame. It sits in the normal flow at
 * whatever height its content gives it, and nothing about it changes when
 * the envelope opens: no travel, no clipping to the screen, no swap at the
 * end. The paper is laid over the screen instead, fixed to the viewport, and
 * opening it is a split. The seal lifts, then the flap leaves through the
 * top of the screen while the pocket leaves through the bottom, and the card
 * is simply there underneath. There is no back panel: the flap and the
 * pocket cover the screen between them, and the lining would only show over
 * the card as they part.
 *
 * Nothing on the card's side is sized to the viewport, so the address bar
 * sliding in and out cannot resize it either. The script adds is-fill
 * wherever Size Mode is Fill screen, which it reads from --ww-fill because
 * the mode is set per device.
 *
 * Fixed paper needs every ancestor between it and the page to leave
 * position: fixed alone, so the 3D setup (perspective, preserve-3d, the
 * resting tilt, will-change) is dropped here. The split is flat and needs
 * none of it.
 */

/*
 * A definite width on Elementor's wrapper for the widget. Without one, a
 * cover container that wraps its items (Elementor's default on phones)
 * measures the widget before the card's 100% width means anything, gets a
 * height for a card laid out at some other width, and keeps it: the cover
 * then centres a widget shorter than the card, which shows the cover's own
 * background in a strip above the card and lets the card hang over the
 * section below.
 */
.elementor-widget:has(.ww-envelope.is-fill) {
	width: 100%;
}

.ww-envelope.is-fill .ww-envelope__scene {
	width: 100%;
	min-height: 0;
	overflow: visible;
	perspective: none;
}

.ww-envelope.is-fill .ww-envelope__env,
.ww-envelope.is-fill.is-running .ww-envelope__env {
	width: 100%;
	max-width: none;
	height: auto;
	aspect-ratio: auto;
	transform: none;
	transform-style: flat;
	-webkit-transform-style: flat;
	transition: none;
	will-change: auto;
}

/*
 * At least one screen tall, so a card designed a little shorter than the
 * screen (a container at 95vh, say) still covers it. A cover that centres
 * its content would otherwise show its own background in a strip above and
 * below the card. svh, not dvh: it is the screen with the address bar
 * showing, and it does not change as the bar slides in and out, so neither
 * does the card. The content grows into the room (see Fill the Card above).
 */
.ww-envelope.is-fill .ww-envelope__card,
.ww-envelope.is-fill.is-running .ww-envelope__card {
	position: relative;
	inset: auto;
	display: flex;
	flex-direction: column;
	width: 100%;
	height: auto;
	min-height: 100vh;
	min-height: 100svh;
	z-index: auto;
	overflow: hidden;
	overflow: clip;
	box-shadow: none;
	transform: none;
	transition: none;
	will-change: auto;
}

/*
 * Keeps whatever the card content stacks with its own z-index under the
 * paper while the envelope is shut. Dropped once it is open, so the content
 * stacks against the rest of the page like any other section, and a card
 * container at z-index 8 is not trapped under a fixed header at 6.
 */
.ww-envelope.is-fill:not(.is-revealed) .ww-envelope__card {
	isolation: isolate;
}

.ww-envelope.is-fill .ww-envelope__content {
	position: relative;
	flex: 1 0 auto;
	height: auto;
}

.ww-envelope.is-fill .ww-envelope__shadow,
.ww-envelope.is-fill .ww-envelope__back {
	display: none;
}

.ww-envelope.is-fill .ww-envelope__pocket,
.ww-envelope.is-fill .ww-envelope__flap {
	position: fixed;
	inset: 0;
	opacity: 1;
	transform: none;
	transition: transform var(--ww-d-flap) var(--ww-ease);
}

.ww-envelope.is-fill .ww-envelope__seal,
.ww-envelope.is-fill .ww-envelope__hint {
	position: fixed;
}

/* Document order, as z-index, so it holds against the isolated card. */
.ww-envelope.is-fill .ww-envelope__pocket { z-index: 2; }
.ww-envelope.is-fill .ww-envelope__flap { z-index: 3; }
.ww-envelope.is-fill .ww-envelope__seal { z-index: 4; }
.ww-envelope.is-fill .ww-envelope__hint { z-index: 5; }

.ww-envelope.is-fill.is-flap .ww-envelope__flap {
	transform: translateY(-100%);
}

.ww-envelope.is-fill.is-flap .ww-envelope__pocket {
	transform: translateY(100%);
}

/* Out of the way for good. Nothing here is in the flow, so nothing moves. */
.ww-envelope.is-fill.is-revealed .ww-envelope__pocket,
.ww-envelope.is-fill.is-revealed .ww-envelope__flap,
.ww-envelope.is-fill.is-revealed .ww-envelope__seal,
.ww-envelope.is-fill.is-revealed .ww-envelope__hint {
	display: none;
}

/*
 * In the editor a paper fixed to the screen would cover every section below
 * it, so the paper covers one screen at the top of the envelope instead.
 */
body.elementor-editor-active .ww-envelope.is-fill:not(.is-revealed) .ww-envelope__env {
	min-height: var(--ww-stage-h, 100vh);
}

body.elementor-editor-active .ww-envelope.is-fill .ww-envelope__pocket,
body.elementor-editor-active .ww-envelope.is-fill .ww-envelope__flap,
body.elementor-editor-active .ww-envelope.is-fill .ww-envelope__seal,
body.elementor-editor-active .ww-envelope.is-fill .ww-envelope__hint {
	position: absolute;
}

/* ---------- keep proportions, then expand ----------
 *
 * An ordinary envelope up to the reveal. There the card stops being a part
 * of the envelope and becomes the page: it sits in the normal flow at the
 * full width and at the height its content was designed with, the way an
 * opened Fill screen card does, and the script draws it growing there from
 * the place the envelope had brought it to (see expandCard() in the script).
 * The script adds is-expanded on that beat.
 *
 * The size is the content's own. There is no one screen minimum, because
 * nothing was covering the screen to begin with, and the card is a section
 * of the page now, so it loses the rounded corners and the arch it had as a
 * piece of stationery.
 *
 * The 3D setup goes on the same beat. The card is drawn growing in screen
 * pixels, which a perspective or a tilt above it would bend, and the paper
 * that is still falling away keeps its order from the z-index copy of the
 * layer order above.
 */

.elementor-widget:has(.ww-envelope.is-expanded) {
	width: 100%;
}

.ww-envelope.is-expanded .ww-envelope__scene {
	width: 100%;
	min-height: 0;
	perspective: none;
}

.ww-envelope.is-expanded .ww-envelope__env {
	width: 100%;
	max-width: none;
	height: auto;
	aspect-ratio: auto;
	transform: none;
	transform-style: flat;
	-webkit-transform-style: flat;
	transition: none;
}

.ww-envelope.is-expanded .ww-envelope__card {
	position: relative;
	inset: auto;
	display: flex;
	flex-direction: column;
	width: 100%;
	height: auto;
	z-index: auto;
	overflow: hidden;
	overflow: clip;
	border-radius: 0;
	box-shadow: none;
	transform: none;
	/* The growth is measured from the card's own corner. */
	transform-origin: 0 0;
	transition: none;
}

/* Over the paper while it grows, so the card covers the envelope it left
   instead of passing behind it. Not after: see the Fill screen card. */
.ww-envelope.is-expanded:not(.is-revealed) .ww-envelope__card {
	z-index: 5;
}

.ww-envelope.is-expanded .ww-envelope__content {
	position: relative;
	flex: 1 0 auto;
	height: auto;
}

/*
 * The paper is placed against the envelope box, which is now as large as the
 * card. These hold it in the box it had, so it finishes falling away from
 * where it was. The script measures them; unset, they are the box itself.
 */
.ww-envelope.is-expanded .ww-envelope__back,
.ww-envelope.is-expanded .ww-envelope__pocket,
.ww-envelope.is-expanded .ww-envelope__flap {
	inset: auto;
	left: var(--ww-pin-x, 0px);
	top: var(--ww-pin-y, 0px);
	width: var(--ww-pin-w, 100%);
	height: var(--ww-pin-h, 100%);
}

/* All three are out of sight by the reveal, and the hint would hold room. */
.ww-envelope.is-expanded .ww-envelope__shadow,
.ww-envelope.is-expanded .ww-envelope__seal,
.ww-envelope.is-expanded .ww-envelope__hint,
.ww-envelope.is-expanded.is-revealed .ww-envelope__back,
.ww-envelope.is-expanded.is-revealed .ww-envelope__pocket,
.ww-envelope.is-expanded.is-revealed .ww-envelope__flap {
	display: none;
}

/*
 * Spacing around the envelope is room for an envelope. Around a card that
 * has become the page it is a frame, showing the background of whatever
 * holds the card: the widget, a Container, the cover. The script marks every
 * box from the widget up to the cover while the card is expanded (see
 * setFlush() in the script), and the spacing is back as soon as the mark is
 * gone. Important, because Elementor writes padding and margin from the
 * panel with the weight of an element id.
 *
 * Two sizes go with the spacing, for the same reason. A boxed Container
 * holds its content to the Content Width, which leaves the cover showing
 * down both sides of the card, and a Min Height taller than the card leaves
 * it showing above or below.
 */
.ww-envelope-flush {
	padding: 0 !important;
	max-width: none !important;
	min-height: 0 !important;
}

/* A boxed Container centres its inner box with auto margins. */
.ww-envelope-flush:not(.e-con-inner) {
	margin: 0 !important;
}

/* ---------- more opening styles ----------
 *
 * Every style is the same parts on the same stages (see openings() in
 * class-envelope-shapes.php). A flap carries its hinge side as a modifier,
 * and a style is free to render several of them.
 *
 * These rules come after Fill screen on purpose: several of them have to win
 * over its flap rules at equal weight.
 */

/*
 * A flap hinged on the left or right turns about the vertical axis, so its
 * inside face is the outside mirrored left to right, not top to bottom.
 */
.ww-envelope__flap--left .ww-envelope__face--back,
.ww-envelope__flap--right .ww-envelope__face--back {
	transform: rotateY(180deg) translateZ(0.5px);
}

/* ---------- side flap ----------
 *
 * The ordinary envelope turned a quarter: the flap is on the right hand short
 * edge, the pocket's three panels meet where it ends, and the envelope slides
 * off the card to the left instead of dropping away. The card itself does
 * what it does when Release Split is 0: it stays put, then comes forward.
 * The script holds the split at 0 for this style, since a card travelling
 * sideways would leave the screen on a phone.
 */
.ww-envelope--style-side {
	--ww-side-x: calc(100% - var(--ww-pocket-y));
	--ww-side-apex: calc(100% - var(--ww-pocket-apex));
	/* Shares of the envelope's own width. Past 100 the card is clear. */
	--ww-side-lift: -112%;
	--ww-side-reveal: -175%;
}

.ww-envelope--style-side .ww-envelope__seal {
	left: var(--ww-side-x);
	top: calc(50% + var(--ww-seal-offset));
}

.ww-envelope--style-side .ww-envelope__pocket {
	filter: drop-shadow(1px 0 2px rgba(0, 0, 0, calc(var(--ww-fold) * 1.4)));
}

.ww-envelope--style-side .ww-envelope__pocket-left {
	clip-path: polygon(0 0, 100% 0, var(--ww-side-x) 54%);
	background:
		var(--ww-noise),
		linear-gradient(180deg, rgba(0, 0, 0, 0) 55%, rgba(0, 0, 0, calc(var(--ww-fold) * 0.75))),
		var(--ww-paper-img) var(--ww-paper-pos) / var(--ww-paper-size) var(--ww-paper-repeat) var(--ww-paper-attach),
		var(--ww-paper);
}

.ww-envelope--style-side .ww-envelope__pocket-right {
	clip-path: polygon(0 100%, 100% 100%, var(--ww-side-x) 46%);
	background:
		var(--ww-noise),
		linear-gradient(0deg, rgba(0, 0, 0, 0) 55%, rgba(0, 0, 0, calc(var(--ww-fold) * 0.75))),
		var(--ww-paper-img) var(--ww-paper-pos) / var(--ww-paper-size) var(--ww-paper-repeat) var(--ww-paper-attach),
		var(--ww-paper);
}

.ww-envelope--style-side .ww-envelope__pocket-bottom {
	clip-path: polygon(0 0, var(--ww-side-apex) 50%, 0 100%);
	filter:
		drop-shadow(1px 0 0 rgba(0, 0, 0, calc(var(--ww-fold) * 1.6)))
		drop-shadow(3px 0 7px rgba(0, 0, 0, calc(var(--ww-fold) * 1.1)));
}

.ww-envelope--style-side .ww-envelope__face--front {
	filter: drop-shadow(-2px 0 3px rgba(0, 0, 0, calc(var(--ww-fold) * 2)));
}

.ww-envelope--style-side .ww-envelope__face--front i {
	clip-path: polygon(100% 0, 100% 100%, var(--ww-side-x) 50%);
	background:
		var(--ww-noise),
		linear-gradient(270deg, rgba(255, 255, 255, calc(var(--ww-fold) * 0.5)), rgba(0, 0, 0, 0) 70%),
		var(--ww-paper-img) var(--ww-paper-pos) / var(--ww-paper-size) var(--ww-paper-repeat) var(--ww-paper-attach),
		var(--ww-paper);
}

.ww-envelope--style-side .ww-envelope__face--back i {
	clip-path: polygon(0 0, 0 100%, var(--ww-flap-depth) 50%);
}

/* The same outlines with Point Softness, as for the upright envelope. */
@supports (clip-path: shape(from 0 0, line to 100% 0)) {
	.ww-envelope--style-side .ww-envelope__pocket-left {
		clip-path: shape(
			from 0 0,
			line to
				calc(var(--ww-side-x) - var(--ww-point) * var(--ww-side-x))
				calc(54% - var(--ww-point) * 54%),
			curve to
				calc(var(--ww-side-x) + var(--ww-point) * (100% - var(--ww-side-x)))
				calc(54% - var(--ww-point) * 54%)
				with var(--ww-side-x) 54%,
			line to 100% 0,
			close
		);
	}

	.ww-envelope--style-side .ww-envelope__pocket-right {
		clip-path: shape(
			from 0 100%,
			line to
				calc(var(--ww-side-x) - var(--ww-point) * var(--ww-side-x))
				calc(46% + var(--ww-point) * 54%),
			curve to
				calc(var(--ww-side-x) + var(--ww-point) * (100% - var(--ww-side-x)))
				calc(46% + var(--ww-point) * 54%)
				with var(--ww-side-x) 46%,
			line to 100% 100%,
			close
		);
	}

	.ww-envelope--style-side .ww-envelope__pocket-bottom {
		clip-path: shape(
			from 0 0,
			line to
				calc(var(--ww-side-apex) - var(--ww-point) * var(--ww-side-apex))
				calc(50% - var(--ww-point) * 50%),
			curve to
				calc(var(--ww-side-apex) - var(--ww-point) * var(--ww-side-apex))
				calc(50% + var(--ww-point) * 50%)
				with var(--ww-side-apex) 50%,
			line to 0 100%,
			close
		);
	}

	.ww-envelope--style-side .ww-envelope__face--front i {
		clip-path: shape(
			from 100% 0,
			line to
				calc(var(--ww-side-x) + var(--ww-point) * (100% - var(--ww-side-x)))
				calc(50% - var(--ww-point) * 50%),
			curve to
				calc(var(--ww-side-x) + var(--ww-point) * (100% - var(--ww-side-x)))
				calc(50% + var(--ww-point) * 50%)
				with var(--ww-side-x) 50%,
			line to 100% 100%,
			close
		);
	}

	.ww-envelope--style-side .ww-envelope__face--back i {
		clip-path: shape(
			from 0 0,
			line to
				calc(var(--ww-flap-depth) - var(--ww-point) * var(--ww-flap-depth))
				calc(50% - var(--ww-point) * 50%),
			curve to
				calc(var(--ww-flap-depth) - var(--ww-point) * var(--ww-flap-depth))
				calc(50% + var(--ww-point) * 50%)
				with var(--ww-flap-depth) 50%,
			line to 0 100%,
			close
		);
	}
}

.ww-envelope--style-side .ww-envelope__flap {
	transform-origin: 100% 50%;
	transform: translateX(0) translateZ(3px) rotateY(0deg);
}

.ww-envelope--style-side.is-flap .ww-envelope__flap {
	transform: translateX(0) translateZ(-1px) rotateY(180deg);
}

.ww-envelope--style-side.is-lift .ww-envelope__back,
.ww-envelope--style-side.is-lift .ww-envelope__pocket {
	transform: translateX(var(--ww-side-lift)) translateZ(var(--ww-layer-z, 0px));
}

.ww-envelope--style-side.is-lift .ww-envelope__flap {
	transform: translateX(var(--ww-side-lift)) translateZ(-1px) rotateY(180deg);
}

.ww-envelope--style-side.is-lift .ww-envelope__shadow {
	transform: translateX(var(--ww-side-lift)) translateZ(-2px);
}

.ww-envelope--style-side.is-reveal .ww-envelope__back,
.ww-envelope--style-side.is-reveal .ww-envelope__pocket {
	transform: translateX(var(--ww-side-reveal)) translateZ(var(--ww-layer-z, 0px));
}

.ww-envelope--style-side.is-reveal .ww-envelope__flap {
	transform: translateX(var(--ww-side-reveal)) translateZ(-1px) rotateY(180deg);
}

/* Fill screen: the paper parts sideways, flap to the right, pocket to the left. */
.ww-envelope.ww-envelope--style-side.is-fill.is-flap .ww-envelope__flap {
	transform: translateX(100%);
}

.ww-envelope.ww-envelope--style-side.is-fill.is-flap .ww-envelope__pocket {
	transform: translateX(-100%);
}

/* ---------- leaves: double doors, book cover, four petals ----------
 *
 * Here the flaps are all the paper there is. The card lies behind them as it
 * does in the unfold style, whose card rules these styles share, and each
 * flap opens about its own hinge, towards the viewer, with the liner on its
 * inside face. Stages read as:
 * seal > leaves open onto the card > card settles > leaves slide away > reveal.
 *
 * Each leaf's transform is one fixed list of functions fed by two variables,
 * its turn (--ww-leaf-r) and its slide (--ww-leaf-t). The stages only change
 * the variables, so every move between them is interpolated function by
 * function and a leaf never takes a short cut through a matrix.
 *
 * The paper texture image is laid on the envelope box, not on each leaf, so
 * one picture of a pair of doors is split down the seam with no extra setup.
 */
.ww-envelope--leaves {
	/* How far a petal reaches towards the middle. Past 50 so they overlap. */
	--ww-petal: 53%;
	/* Fill screen has no scene perspective, so each leaf brings its own. It
	   has to stay well clear of a leaf as wide as the screen. */
	--ww-leaf-p: max(1100px, 220vmax);
}

.ww-envelope--style-gatefold,
.ww-envelope--style-book {
	--ww-leaf-open: var(--ww-door-swing, 120deg);
}

.ww-envelope--leaves .ww-envelope__seal {
	left: 50%;
	top: calc(50% + var(--ww-seal-offset));
}

.ww-envelope.ww-envelope--leaves .ww-envelope__flap {
	--ww-leaf-r: 0deg;
	--ww-leaf-t: 0%;
	/* Leaves open towards the viewer and never fold behind the envelope. */
	z-index: 3;
	transition: transform var(--ww-leaf-d, var(--ww-d-flap)) var(--ww-ease) var(--ww-leaf-delay, 0ms);
}

.ww-envelope.ww-envelope--leaves.is-flap .ww-envelope__flap {
	--ww-leaf-r: var(--ww-leaf-open, 180deg);
}

.ww-envelope.ww-envelope--leaves.is-lift .ww-envelope__flap {
	--ww-leaf-t: var(--ww-panel-travel);
	transition: transform var(--ww-d-lift) var(--ww-ease);
}

/*
 * The faces fade, not the leaf. Opacity flattens the box it is set on, and a
 * flattened leaf drops its inside face, so a leaf fading as a whole would
 * turn from liner to paper on its way out.
 */
.ww-envelope.ww-envelope--leaves.is-reveal .ww-envelope__flap {
	opacity: 1;
	transition: transform var(--ww-d-reveal) var(--ww-ease);
}

.ww-envelope--leaves .ww-envelope__face {
	transition: opacity calc(var(--ww-d-reveal) * 0.6) ease-in;
}

.ww-envelope--leaves.is-reveal .ww-envelope__face {
	opacity: 0;
}

/* Closed, the later leaf lies over the earlier one, as in the markup. The
   steps are small so the top face (0.5px proud) stays under the seal at 4px. */
.ww-envelope.ww-envelope--leaves .ww-envelope__flap.ww-envelope__flap--bottom {
	transform-origin: 50% 100%;
	transform: translateY(var(--ww-leaf-t)) translateZ(3px) rotateX(calc(var(--ww-leaf-r) * -1));
}

.ww-envelope.ww-envelope--leaves .ww-envelope__flap.ww-envelope__flap--left {
	transform-origin: 0 50%;
	transform: translateX(calc(var(--ww-leaf-t) * -1)) translateZ(3.1px) rotateY(calc(var(--ww-leaf-r) * -1));
}

.ww-envelope.ww-envelope--leaves .ww-envelope__flap.ww-envelope__flap--right {
	transform-origin: 100% 50%;
	transform: translateX(var(--ww-leaf-t)) translateZ(3.2px) rotateY(var(--ww-leaf-r));
}

.ww-envelope.ww-envelope--leaves .ww-envelope__flap.ww-envelope__flap--top {
	transform-origin: 50% 0;
	transform: translateY(calc(var(--ww-leaf-t) * -1)) translateZ(3.3px) rotateX(var(--ww-leaf-r));
}

/*
 * Fill screen: the same turn, flat on the screen with the leaf's own
 * perspective. A leaf is off screen once it passes a quarter turn, so there
 * is nothing left to slide away.
 */
.ww-envelope.ww-envelope--leaves.is-fill .ww-envelope__flap.ww-envelope__flap--bottom {
	transform: perspective(var(--ww-leaf-p)) rotateX(calc(var(--ww-leaf-r) * -1));
}

.ww-envelope.ww-envelope--leaves.is-fill .ww-envelope__flap.ww-envelope__flap--left {
	transform: perspective(var(--ww-leaf-p)) rotateY(calc(var(--ww-leaf-r) * -1));
}

.ww-envelope.ww-envelope--leaves.is-fill .ww-envelope__flap.ww-envelope__flap--right {
	transform: perspective(var(--ww-leaf-p)) rotateY(var(--ww-leaf-r));
}

.ww-envelope.ww-envelope--leaves.is-fill .ww-envelope__flap.ww-envelope__flap--top {
	transform: perspective(var(--ww-leaf-p)) rotateX(var(--ww-leaf-r));
}

/* Double doors: each leaf is its half of the envelope. */
.ww-envelope--style-gatefold .ww-envelope__flap--left .ww-envelope__face--front i,
.ww-envelope--style-gatefold .ww-envelope__flap--right .ww-envelope__face--back i {
	clip-path: inset(0 50% 0 0);
}

.ww-envelope--style-gatefold .ww-envelope__flap--right .ww-envelope__face--front i,
.ww-envelope--style-gatefold .ww-envelope__flap--left .ww-envelope__face--back i {
	clip-path: inset(0 0 0 50%);
}

/*
 * Four petals: a triangle from each edge. The top one closes last, so it
 * reaches a little further and covers the point where the others meet. They
 * open in the reverse of the order they were closed in, each starting before
 * the one ahead of it has finished.
 */
.ww-envelope--style-petal .ww-envelope__flap {
	--ww-leaf-d: calc(var(--ww-d-flap) * 0.55);
}

.ww-envelope--style-petal .ww-envelope__flap--top {
	--ww-petal: 58%;
}

.ww-envelope--style-petal .ww-envelope__flap--right {
	--ww-leaf-delay: calc(var(--ww-d-flap) * 0.15);
}

.ww-envelope--style-petal .ww-envelope__flap--left {
	--ww-leaf-delay: calc(var(--ww-d-flap) * 0.3);
}

.ww-envelope--style-petal .ww-envelope__flap--bottom {
	--ww-leaf-delay: calc(var(--ww-d-flap) * 0.45);
}

.ww-envelope--style-petal .ww-envelope__flap--top .ww-envelope__face--front i,
.ww-envelope--style-petal .ww-envelope__flap--bottom .ww-envelope__face--back i {
	clip-path: polygon(0 0, 100% 0, 50% var(--ww-petal));
}

.ww-envelope--style-petal .ww-envelope__flap--bottom .ww-envelope__face--front i,
.ww-envelope--style-petal .ww-envelope__flap--top .ww-envelope__face--back i {
	clip-path: polygon(0 100%, 100% 100%, 50% calc(100% - var(--ww-petal)));
}

.ww-envelope--style-petal .ww-envelope__flap--left .ww-envelope__face--front i,
.ww-envelope--style-petal .ww-envelope__flap--right .ww-envelope__face--back i {
	clip-path: polygon(0 0, var(--ww-petal) 50%, 0 100%);
}

.ww-envelope--style-petal .ww-envelope__flap--right .ww-envelope__face--front i,
.ww-envelope--style-petal .ww-envelope__flap--left .ww-envelope__face--back i {
	clip-path: polygon(100% 0, calc(100% - var(--ww-petal)) 50%, 100% 100%);
}

/* Jump to a stage without animating (reset, editor preview, reduced motion). */
.ww-envelope.is-instant,
.ww-envelope.is-instant * {
	transition: none !important;
}

@media (prefers-reduced-motion: reduce) {
	.ww-envelope__hint-text::before {
		animation: none;
	}
}
