/* Covers for every design. Colours come from the design (--cv-*) and card palette variables
   set in the invitation's <style> block. Body classes: is-sealed → is-opening → is-open;
   the cover carries op-<opening> so each opening animates differently. */
.cover { position: fixed; inset: 0; z-index: 5; overflow: hidden; cursor: pointer; -webkit-tap-highlight-color: transparent; touch-action: manipulation; }
.is-open .cover { display: none; }

/* ---------- opening buttons ---------- */
.cover-btn, .tassel { border: 0; background: none; padding: 0; margin: 0; cursor: pointer; color: inherit; font: inherit; -webkit-tap-highlight-color: transparent; }
.cover-btn { position: relative; z-index: 6; display: flex; flex-direction: column; align-items: center; gap: 12px; }
.cover-btn--bottom { position: absolute; left: 50%; bottom: max(9%, calc(env(safe-area-inset-bottom) + 36px)); translate: -50% 0; }
.cover-btn:focus-visible, .tassel:focus-visible { outline: none; }
.cover-btn:focus-visible .btn-label, .tassel:focus-visible .btn-label { box-shadow: 0 0 0 3px var(--orn); }
.btn-label--pill {
  display: inline-flex; align-items: center; gap: 10px; min-width: 200px; justify-content: center;
  padding: 14px 30px 13px calc(30px + .26em); border-radius: 999px; white-space: nowrap;
  border: 1.5px solid color-mix(in srgb, var(--orn) 80%, transparent); background: color-mix(in srgb, var(--paper) 82%, transparent);
  color: var(--accent); box-shadow: inset 0 1px 0 #ffffff59, 0 10px 28px #00000040;
  font: 600 .9rem/1 var(--font-title); letter-spacing: .26em; text-transform: uppercase;
  -webkit-backdrop-filter: blur(9px); backdrop-filter: blur(9px);
}
.btn-label--pill svg { width: 15px; height: 15px; fill: currentColor; }
.cover-btn--pill, .cover-btn--lemon { animation: cta-float 3.6s cubic-bezier(.22, 1, .36, 1) infinite; }
.cta-ornament { display: flex; align-items: center; gap: 10px; color: var(--cv-orn-c); }
.cta-ornament::before, .cta-ornament::after { content: ''; width: 34px; height: 1px; background: linear-gradient(90deg, transparent, currentColor); }
.cta-ornament::after { transform: scaleX(-1); }
.cta-ornament i { width: 5px; height: 5px; rotate: 45deg; background: currentColor; }
/* Gold medallion with a pulsing halo. */
.medallion {
  position: relative; display: grid; place-items: center; width: 92px; height: 92px; border-radius: 50%;
  background: radial-gradient(circle at 34% 28%, #fff3cf, #e2c47f 30%, #b8924c 62%, #8a6a32);
  box-shadow: inset 0 2px 1px #ffffffaa, inset 0 -4px 8px #6a4d1f80, 0 10px 26px #00000080, 0 0 0 1px #f3dfa8;
}
.medallion::before { content: ''; position: absolute; inset: 7px; border-radius: 50%; border: 1px solid #6a4d1f66; }
.medallion::after { content: ''; position: absolute; inset: -4px; border-radius: 50%; border: 2px solid #f3dfa8; animation: halo 2.4s var(--ease) infinite; }
.medallion svg { width: 40px; height: 40px; fill: none; stroke: color-mix(in srgb, var(--accent), #000 25%); stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; animation: tap 2.4s ease-in-out infinite; }
.cover-btn--medallion .btn-label { color: var(--cv-on-dark); font: 600 .85rem/1 var(--font-title); letter-spacing: .32em; padding-left: .32em; text-transform: uppercase; text-shadow: 0 1px 8px #000a; }
.btn-lemon { width: 96px; filter: drop-shadow(0 12px 14px #0000004d); animation: bob 2.8s ease-in-out infinite; transform-origin: 50% 80%; }
.is-opening .cover-btn, .is-opening .tassel .btn-label { animation: fade-out 500ms var(--ease) forwards; }

/* ---------- design ornaments on cover surfaces (inside a positioned parent) ---------- */
.orn { position: absolute; pointer-events: none; }
.orn.is-flipped { transform: scaleX(-1); }
.orn-florals {
  top: 5%; bottom: 5%; right: 9%; aspect-ratio: 233 / 1204; background: var(--cv-orn); filter: var(--cv-orn-shadow);
  -webkit-mask: url('/b/florals.webp') center / 100% 100% no-repeat; mask: url('/b/florals.webp') center / 100% 100% no-repeat;
}
.orn-florals.is-flipped { right: auto; left: 9%; }
.orn-olive { inset: 6% 12%; display: flex; flex-direction: column; justify-content: space-between; align-items: center; }
.orn-olive svg { width: 100%; max-width: 260px; stroke: var(--cv-orn-c); stroke-width: 1.3; fill: none; }
.orn-olive svg:last-child { transform: scale(-1, -1); }
.orn-stars { inset: 0; }
.orn-stars svg { position: absolute; fill: var(--cv-orn-c); }
.orn-stars svg:nth-child(1) { width: 26px; top: 14%; left: 22%; } .orn-stars svg:nth-child(2) { width: 14px; top: 24%; left: 62%; }
.orn-stars svg:nth-child(3) { width: 18px; top: 66%; left: 30%; } .orn-stars svg:nth-child(4) { width: 30px; top: 78%; left: 64%; }
.orn-stars svg:nth-child(5) { width: 12px; top: 40%; left: 16%; }
.orn-deco { inset: 6% 10%; color: var(--cv-orn-c); }
.orn-deco svg { width: 70%; display: block; margin: 0 auto; }
.orn-deco i { position: absolute; top: 22%; bottom: 4%; width: 1px; background: currentColor; opacity: .55; }
.orn-deco i:nth-of-type(1) { right: 6%; } .orn-deco i:nth-of-type(2) { right: 10%; opacity: .3; } .orn-deco i:nth-of-type(3) { right: 14%; opacity: .18; }
.orn-deco.is-flipped i:nth-of-type(1) { right: 6%; }
.orn-bokeh { inset: 0; }
.orn-bokeh i { position: absolute; border-radius: 50%; background: radial-gradient(circle, color-mix(in srgb, var(--cv-orn-c) 45%, transparent), transparent 70%); }
.orn-bokeh i:nth-child(1) { width: 90px; height: 90px; top: 12%; left: 20%; } .orn-bokeh i:nth-child(2) { width: 50px; height: 50px; top: 30%; left: 60%; }
.orn-bokeh i:nth-child(3) { width: 120px; height: 120px; top: 58%; left: 10%; } .orn-bokeh i:nth-child(4) { width: 40px; height: 40px; top: 74%; left: 56%; }
.orn-bokeh i:nth-child(5) { width: 70px; height: 70px; top: 86%; left: 30%; } .orn-bokeh i:nth-child(6) { width: 30px; height: 30px; top: 46%; left: 40%; }
.orn-corners { inset: 5%; color: var(--cv-orn-c); }
.orn-corners svg { position: absolute; width: 34%; max-width: 130px; }
.orn-corners svg:nth-child(1) { top: 0; left: 0; } .orn-corners svg:nth-child(2) { bottom: 0; left: 0; transform: scaleY(-1); }
.orn-lines { top: 6%; bottom: 6%; right: 9%; width: 12px; }
.orn-lines i { position: absolute; top: 0; bottom: 0; width: 1px; background: var(--cv-orn-c); opacity: .7; }
.orn-lines i:last-child { left: 8px; opacity: .35; }
.orn-lines.is-flipped { right: auto; left: 9%; }

/* ================= DOORS ================= */
.cover--doors { perspective: 1600px; perspective-origin: 50% 45%; background: var(--cv-dark); }
.door { position: absolute; top: 0; bottom: 0; width: 50%; transform-style: preserve-3d; }
.door--left { left: 0; transform-origin: left center; }
.door--right { right: 0; transform-origin: right center; }
.door-face { position: absolute; inset: 0; overflow: hidden; backface-visibility: hidden; -webkit-backface-visibility: hidden; background: var(--cv-surface); }
.door-back { transform: rotateY(180deg); background: var(--cv-back); }
.door--left .door-front { background: var(--cv-surface-l); }
.door-face::before, .door-face::after { content: ''; position: absolute; pointer-events: none; }
.door-face::before { inset: 14px; border: 1px solid var(--cv-line); }
.door-face::after { inset: 22px; border: 1px solid color-mix(in srgb, var(--cv-line) 55%, transparent); }
.door--left .door-front::before { right: 7px; } .door--left .door-front::after { right: 15px; }
.door--right .door-front::before { left: 7px; } .door--right .door-front::after { left: 15px; }
.door--left .door-front { box-shadow: inset -1px 0 0 #0000002e, inset -6px 0 10px -6px #00000040; }
.door--right .door-front { box-shadow: inset 1px 0 0 #ffffff59, inset 6px 0 10px -6px #00000033; }
.door .seal { position: absolute; z-index: 2; top: 46%; width: clamp(124px, 35vw, 158px); aspect-ratio: 1; translate: 0 -50%; }
.door--left .seal { right: calc(clamp(124px, 35vw, 158px) / -2); }
.door--right .seal { left: calc(clamp(124px, 35vw, 158px) / -2); }
.door-shade { position: absolute; inset: 0; z-index: 3; opacity: 0; pointer-events: none; }
.door--left .door-front .door-shade { background: linear-gradient(90deg, transparent, #0000005e); }
.door--right .door-front .door-shade { background: linear-gradient(270deg, transparent, #0000005e); }
.door-back .door-shade { opacity: 1; background: linear-gradient(90deg, #00000026, transparent 40%); }
/* swing: the seal lights up, light runs down the seam to the button, the button glows, then the
   doors swing away on their hinges while gold sparks fall out of the gap. */
.door-light { position: absolute; inset: 0; z-index: 4; pointer-events: none; --seal: clamp(124px, 35vw, 158px); }
.dl-up, .dl-down { position: absolute; left: 50%; width: 3px; margin-left: -1.5px; opacity: 0; border-radius: 3px;
  background: linear-gradient(#fffaf0, #ffe1a0); box-shadow: 0 0 3px 1px #ffd77f, 0 0 12px 2px #f5b941, 0 0 30px 6px #f2a93380; }
.dl-up { top: 0; height: calc(46% - var(--seal) / 2 + 6px); background: linear-gradient(transparent, #ffe9b8); }
.dl-down { top: calc(46% + var(--seal) / 2 - 6px); bottom: 0; clip-path: inset(0 -40px 100% -40px); background: linear-gradient(#fff6dc, #ffe2a0 80%, transparent); }
.dl-sparks i { position: absolute; left: 50%; width: 5px; height: 5px; margin-left: -2.5px; border-radius: 50%; opacity: 0; scale: var(--s);
  background: radial-gradient(circle, #fffbea, #ffd27a 55%, transparent 70%); box-shadow: 0 0 6px 1px #f5b941; }
.is-opening .op-swing .door .seal { animation: dr-seal 1700ms var(--ease) forwards; }
.is-opening .op-swing .dl-up { animation: dr-up 2100ms 250ms ease-out forwards; }
.is-opening .op-swing .dl-down { animation: dr-down 2000ms 300ms cubic-bezier(.45, 0, .35, 1) forwards; }
.is-opening .op-swing .dl-sparks i { animation: dr-spark 1500ms calc(1500ms + var(--d)) ease-out forwards; }
.is-opening .op-swing .cover-btn { animation: dr-btn 1500ms 1150ms ease-out forwards; }
.is-opening .op-swing .door--left { animation: swing-left 2300ms 1600ms cubic-bezier(.55, 0, .25, 1) forwards; }
.is-opening .op-swing .door--right { animation: swing-right 2300ms 1600ms cubic-bezier(.55, 0, .25, 1) forwards; }
.is-opening .op-swing .door-front .door-shade { animation: shade-in 2300ms 1600ms forwards; }
.is-opening .cover--doors.op-swing { animation: fade-out 500ms 3500ms forwards; }
/* The doors' backdrop goes as soon as they start to move, so the card shows through the gap. */
.is-opening .cover--doors { background: transparent; }
/* slide: the doors part sideways like sliding panels */
.is-opening .op-slide .door--left { animation: slide-left 1500ms 250ms cubic-bezier(.65, 0, .25, 1) forwards; }
.is-opening .op-slide .door--right { animation: slide-right 1500ms 250ms cubic-bezier(.65, 0, .25, 1) forwards; }

/* ================= ENVELOPE ================= */
.cover--envelope {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: clamp(22px, 5vh, 40px); padding: 24px 16px;
  background: radial-gradient(ellipse at 50% 30%, color-mix(in srgb, var(--cv-dark), #fff 14%), var(--cv-dark) 62%, color-mix(in srgb, var(--cv-dark), #000 40%));
}
.env-names { margin: 0; font-family: var(--font-names); font-size: clamp(34px, 10vw, 56px); line-height: 1.1; color: var(--cv-on-dark); text-align: center; text-shadow: 0 2px 12px #0000004d; }
.env-names span { font-family: var(--font-title); font-style: italic; font-size: .7em; }
.envelope { --w: min(84vw, 400px, 52vh * 1.42); position: relative; width: var(--w); aspect-ratio: 1.42; perspective: 1400px; filter: drop-shadow(0 28px 34px #0000008c); }
.envelope > span { position: absolute; display: block; }
.env-back { inset: 0; border-radius: 3px; background: var(--cv-back); }
.env-letter {
  z-index: 2; left: 5%; right: 5%; top: 5%; height: 90%; padding-top: 9%;
  display: flex; flex-direction: column; align-items: center; gap: 4%; background: var(--paper); color: var(--accent); text-align: center;
}
.letter-title { font-family: var(--font-title); font-size: calc(var(--w) * .034); font-weight: 600; letter-spacing: .3em; padding-left: .3em; text-transform: uppercase; }
.letter-names { font-family: var(--font-names); font-size: calc(var(--w) * .085); line-height: 1.1; }
.env-side, .env-bottom { inset: 0; }
.env-side--left { z-index: 3; clip-path: polygon(0 0, 52% 54%, 0 100%); background: linear-gradient(100deg, #ffffff1f, #0000000f), var(--cv-surface); }
.env-side--right { z-index: 3; clip-path: polygon(100% 0, 48% 54%, 100% 100%); background: linear-gradient(260deg, #ffffff14, #0000001a), var(--cv-surface); }
.env-bottom { z-index: 4; clip-path: polygon(0 100%, 50% 47%, 100% 100%); background: linear-gradient(#0000000d, #ffffff26 60%), var(--cv-surface); }
.env-flap { z-index: 5; left: 0; right: 0; top: 0; height: 58%; transform-origin: 50% 0; clip-path: polygon(0 0, 100% 0, 50% 100%); background: linear-gradient(#ffffff26, #00000014), var(--cv-surface); }
.envelope .seal { z-index: 6; top: 56%; left: 50%; width: 26%; aspect-ratio: 1; translate: -50% -50%; }
.is-opening .op-flap .envelope .seal { animation: seal-off 600ms var(--ease) forwards; }
.is-opening .op-flap .env-flap { animation: flap-open 900ms 350ms cubic-bezier(.5, 0, .3, 1) both; }
.is-opening .op-flap .env-letter { animation: letter-out 1000ms 1150ms cubic-bezier(.3, 0, .2, 1) both; }
.is-opening .op-flap .env-names { animation: fade-out 500ms var(--ease) forwards; }
.is-opening .cover--envelope.op-flap { animation: fade-out 650ms 2150ms var(--ease) forwards; }

/* ================= BALLOONS ================= */
/* A wall of glossy latex balloons over the page colour; they float up (float) or pop (pop). */
.cover--balloons { background: radial-gradient(ellipse at 50% 30%, color-mix(in srgb, var(--cv-dark), #fff 30%), var(--cv-dark)); }
.balloon-wall { position: absolute; inset: -4% -8% 0; }
.balloon-wall i {
  position: absolute; width: 30%; aspect-ratio: .84; scale: var(--s); border-radius: 50% 50% 47% 47% / 55% 55% 45% 45%;
  background:
    radial-gradient(ellipse 22% 16% at 33% 24%, #fffffff0, #ffffff00 70%),
    radial-gradient(ellipse 60% 55% at 40% 38%, color-mix(in srgb, var(--c), #fff 28%), var(--c) 55%, color-mix(in srgb, var(--c), #000 32%) 100%);
  box-shadow: inset -6px -10px 18px #0000002e, 0 14px 22px -8px #00000059;
  animation: balloon-bob 4.5s ease-in-out infinite alternate; animation-delay: calc(var(--d) * -3);
}
.balloon-wall i::after { content: ''; position: absolute; left: 50%; bottom: -5%; width: 9%; aspect-ratio: 1.3; translate: -50% 0; border-radius: 30% 30% 50% 50%; background: color-mix(in srgb, var(--c), #000 25%); }
.balloon-plaque { top: 44%; }
.is-opening .op-float .balloon-wall i { animation: balloon-float 1900ms cubic-bezier(.45, 0, .7, .4) var(--d) forwards; }
.is-opening .op-pop .balloon-wall i { animation: balloon-pop 260ms ease-in calc(var(--d) * .9) forwards; }
.is-opening .balloon-plaque { animation: pop-out 500ms var(--ease) forwards; }
.is-opening .cover--balloons { background: transparent; transition: background-color .4s; }
@keyframes balloon-bob { to { translate: 0 -10px; rotate: 3deg; } }
@keyframes balloon-float { to { translate: var(--sway) -130vh; rotate: 8deg; } }
@keyframes balloon-pop { 60% { scale: calc(var(--s) * 1.25); opacity: 1; } to { scale: calc(var(--s) * 1.5); opacity: 0; } }

/* ================= LETTER (a tall envelope whose seal lights up) ================= */
/* Two flaps meet under the seal (top and bottom), the side pockets show between them. On tap the
   seal glows, light leaks out along the seams, the flaps swing open and the light floods the screen. */
.cover--letter {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: clamp(16px, 3.5vh, 30px); padding: 24px 16px 120px;
  background: radial-gradient(ellipse at 50% 42%, color-mix(in srgb, var(--cv-dark), #fff 22%), var(--cv-dark) 70%);
}
.lt-names { margin: 0; font-family: var(--font-names); font-size: clamp(30px, 8.5vw, 48px); line-height: 1.1; color: var(--cv-on-dark); text-align: center; }
.lt-names span { font-family: var(--font-title); font-style: italic; font-size: .65em; }
.letter {
  --lw: min(76vw, 44vh, 360px); position: relative; width: var(--lw); aspect-ratio: .6; perspective: 1800px;
  background: var(--cv-surface); background-size: cover; border-radius: 4px;
  box-shadow: inset 0 0 0 1px #ffffff40, 0 30px 60px -18px #0000008c, 0 8px 18px -8px #0000004d;
}
.letter > span { position: absolute; display: block; }
/* Warm light behind the flaps. */
.lt-light {
  inset: 0; opacity: 0; border-radius: inherit;
  background: radial-gradient(closest-side, #fffdf5, #fff1cf 30%, #ffe2a666 62%, #ffe2a600);
}
.lt-flap { left: 0; right: 0; height: 50.5%; background: var(--cv-surface); background-size: cover; backface-visibility: visible; }
.lt-flap--top { top: 0; transform-origin: 50% 0; clip-path: polygon(0 0, 100% 0, 50% 100%); background-image: linear-gradient(#ffffff26, #0000001a), var(--cv-surface); }
.lt-flap--bottom { bottom: 0; transform-origin: 50% 100%; clip-path: polygon(0 100%, 100% 100%, 50% 0); background-image: linear-gradient(#0000000f, #ffffff1f), var(--cv-surface); }
/* The seams: the envelope's two diagonals, a faint crease that turns to light when it opens. */
.lt-seam {
  inset: 0; pointer-events: none;
  background:
    linear-gradient(to bottom right, transparent calc(50% - .8px), #00000030 50%, transparent calc(50% + .8px)),
    linear-gradient(to bottom left, transparent calc(50% - .8px), #00000030 50%, transparent calc(50% + .8px));
}
.lt-seam::after {
  content: ''; position: absolute; inset: 0; opacity: 0; filter: blur(2.5px) drop-shadow(0 0 8px #ffcf70);
  background:
    linear-gradient(to bottom right, transparent calc(50% - 2px), #fff3c8 50%, transparent calc(50% + 2px)),
    linear-gradient(to bottom left, transparent calc(50% - 2px), #fff3c8 50%, transparent calc(50% + 2px));
}
.lt-halo { left: 50%; top: 50%; width: 70%; aspect-ratio: 1; translate: -50% -50%; border-radius: 50%; opacity: 0; background: radial-gradient(circle, #ffe9b0cc, #ffcf7055 40%, transparent 70%); }
.letter .seal { z-index: 2; left: 50%; top: 50%; width: 30%; aspect-ratio: 1; translate: -50% -50%; }

.is-opening .op-glow .lt-halo { animation: lt-halo 900ms ease-out forwards; }
.is-opening .op-glow .letter .seal { animation: lt-seal 1300ms var(--ease) forwards; }
.is-opening .op-glow .lt-seam::after { animation: lt-leak 900ms 350ms ease-in forwards; }
.is-opening .op-glow .lt-light { animation: lt-light 2200ms 900ms ease-in forwards; }
.is-opening .op-glow .lt-flap--top { animation: lt-top 1400ms 1000ms cubic-bezier(.5, 0, .25, 1) forwards; }
.is-opening .op-glow .lt-flap--bottom { animation: lt-bottom 1400ms 1000ms cubic-bezier(.5, 0, .25, 1) forwards; }
.is-opening .op-glow .lt-seam { animation: fade-out 400ms 1100ms forwards; }
.is-opening .op-glow .lt-names { animation: fade-out 500ms var(--ease) forwards; }
.cover--letter::after { content: ''; position: absolute; inset: 0; z-index: 7; opacity: 0; pointer-events: none; background: radial-gradient(circle at 50% 45%, #fffdf6, #fff3dc); }
.is-opening .cover--letter.op-glow::after { animation: lt-wash 700ms 1900ms ease-in forwards; }
.is-opening .cover--letter.op-glow { animation: lt-out 800ms 2600ms ease-out forwards; }
@keyframes lt-halo { 40% { opacity: 1; scale: 1.25; } 100% { opacity: .9; scale: 1.6; } }
@keyframes lt-seal { 0% { filter: drop-shadow(0 1px 1px #4a32187a); } 45% { filter: brightness(1.35) drop-shadow(0 0 14px #ffd27a) drop-shadow(0 0 30px #ffc04d); scale: 1.06; opacity: 1; } 100% { filter: brightness(1.6) drop-shadow(0 0 30px #ffd27a); scale: 1.25; opacity: 0; } }
@keyframes lt-leak { to { opacity: 1; } }
@keyframes lt-light { 0% { opacity: 0; } 35% { opacity: 1; } 100% { opacity: 1; scale: 3.2; } }
@keyframes lt-top { to { transform: rotateX(178deg); filter: brightness(.7); } }
@keyframes lt-bottom { to { transform: rotateX(-178deg); filter: brightness(.7); } }
/* The light becomes a warm white wash over everything, then clears to the invitation. */
@keyframes lt-wash { to { opacity: .96; } }
@keyframes lt-out { to { opacity: 0; } }

/* ================= CURTAINS ================= */
.cover--curtains { background: var(--cv-f1); }
.curtain {
  position: absolute; top: 0; bottom: 0; width: 51%;
  background:
    linear-gradient(180deg, #0000008c, transparent 26%, transparent 80%, #00000055),
    repeating-linear-gradient(90deg, var(--cv-f1) 0, var(--cv-f2) 3.2vw, var(--cv-f3) 4.6vw, var(--cv-f2) 6vw, var(--cv-f1) 9vw);
  box-shadow: inset 0 -26px 0 -16px var(--cv-orn-c), inset 0 -30px 0 -16px #6b4f1f;
}
.curtain--left { left: 0; transform-origin: 0 50%; }
.curtain--right { right: 0; transform-origin: 100% 50%; }
.valance {
  position: absolute; top: 0; left: 0; right: 0; height: 15vh; z-index: 1;
  background: linear-gradient(180deg, #00000066, transparent 70%), repeating-linear-gradient(90deg, var(--cv-f1) 0, var(--cv-f2) 5vw, var(--cv-f1) 10vw);
  box-shadow: 0 10px 24px #00000066;
}
.valance::after {
  content: ''; position: absolute; left: 0; right: 0; top: 100%; height: 5vw; margin-top: -1px;
  background: radial-gradient(circle at 50% 0, var(--cv-f1) 64%, var(--cv-orn-c) 65%, var(--cv-orn-c) 72%, transparent 73%) 0 0 / 10vw 10vw repeat-x;
}
.plaque {
  position: absolute; z-index: 3; left: 50%; top: 40%; translate: -50% -50%; width: min(78vw, 360px); padding: 26px 20px 24px;
  display: flex; flex-direction: column; align-items: center; gap: 8px; text-align: center;
  background: var(--paper); border: 1px solid var(--cv-orn-c); outline: 1px solid color-mix(in srgb, var(--cv-orn-c) 55%, transparent); outline-offset: 5px;
  box-shadow: 0 24px 50px #0000008c;
}
.plaque-title { font-family: var(--font-title); font-size: 12px; letter-spacing: .34em; padding-left: .34em; text-transform: uppercase; color: var(--muted); }
.plaque-names { font-family: var(--font-names); font-size: clamp(30px, 9vw, 42px); line-height: 1.15; color: var(--accent); }
.plaque-date { font-family: var(--font-title); font-size: 13px; letter-spacing: .2em; text-transform: uppercase; color: var(--muted); }
/* The tassel hangs on a cord behind the plaque; tap or pull it. */
.tassel {
  position: absolute; z-index: 2; top: 0; left: 50%; width: 140px; height: calc(40% + 270px); margin-left: -70px;
  display: flex; flex-direction: column; align-items: center; justify-content: flex-end; transform-origin: 50% 0;
  animation: sway 3.6s ease-in-out infinite;
}
.cord { flex: 1; width: 3px; background: repeating-linear-gradient(170deg, #f2dca0 0 3px, #8c6a2c 3px 6px); }
.knot { width: 30px; height: 30px; border-radius: 50%; background: radial-gradient(circle at 35% 30%, #fff1c4, #c9a45c 55%, #8c6a2c); box-shadow: 0 4px 8px #0006; }
.skirt { width: 46px; height: 74px; margin-top: -6px; clip-path: polygon(30% 0, 70% 0, 100% 100%, 0 100%); background: repeating-linear-gradient(90deg, #8c6a2c 0 2px, #c9a45c 2px 4px, #f2dca0 4px 5px); filter: drop-shadow(0 6px 6px #0008); }
.tassel .btn-label { margin-top: 16px; min-width: 0; }
.is-opening .cover--curtains .tassel { animation: pull 700ms var(--ease) forwards; }
.is-opening .cover--curtains .plaque { animation: fade-out 500ms var(--ease) forwards; }
.is-opening .cover--curtains { background: transparent; }
/* draw: the fabric bunches to the sides */
.is-opening .op-draw .curtain--left { animation: gather-left 1900ms 350ms cubic-bezier(.6, 0, .25, 1) forwards; }
.is-opening .op-draw .curtain--right { animation: gather-right 1900ms 350ms cubic-bezier(.6, 0, .25, 1) forwards; }
.is-opening .op-draw .valance { animation: fly-up 900ms 1700ms var(--ease) forwards; }
/* rise: the whole curtain flies up into the rigging */
.is-opening .op-rise .curtain, .is-opening .op-rise .valance { animation: fly-up 1500ms 400ms cubic-bezier(.6, 0, .3, 1) forwards; }

/* ================= BOOK ================= */
.cover--book {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: clamp(46px, 8vh, 70px); padding: 24px 16px;
  background: repeating-linear-gradient(0deg, #ffffff1f 0 1px, transparent 1px 4px), repeating-linear-gradient(90deg, #0000000a 0 1px, transparent 1px 4px), radial-gradient(ellipse at 50% 30%, color-mix(in srgb, var(--cv-dark), #fff 18%), var(--cv-dark) 70%);
}
.book { --bw: min(74vw, 340px, 46vh); position: relative; width: var(--bw); aspect-ratio: 1 / 1.38; perspective: 2200px; }
.book > span { position: absolute; }
.ribbon { z-index: 0; left: 70%; bottom: -54px; width: 20px; height: 90px; background: linear-gradient(90deg, color-mix(in srgb, var(--cv-orn-c), #000 35%), var(--cv-orn-c) 45%, color-mix(in srgb, var(--cv-orn-c), #fff 35%) 55%, color-mix(in srgb, var(--cv-orn-c), #000 20%)); clip-path: polygon(0 0, 100% 0, 100% 100%, 50% 84%, 0 100%); transform-origin: 50% 0; animation: flutter 3.4s ease-in-out infinite; }
.page-right {
  z-index: 1; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6%; text-align: center;
  border-radius: 2px 6px 6px 2px; background: var(--paper); color: var(--accent);
  box-shadow: 2px 1px 0 #e8e2d4, 4px 2px 0 #f6f1e6, 6px 3px 0 #e2dccd, 8px 4px 0 #f3eee2, 10px 5px 0 #d8d1c0, 14px 18px 30px -10px #0006;
}
.page-names { font-family: var(--font-names); font-size: calc(var(--bw) * .15); line-height: 1; }
.page-names i { font-family: var(--font-title); font-size: .5em; color: var(--orn); }
.page-date { font-family: var(--font-title); font-size: calc(var(--bw) * .045); letter-spacing: .24em; text-transform: uppercase; color: var(--muted); }
.book-cover { z-index: 2; inset: 0; transform-origin: 0 50%; transform-style: preserve-3d; }
.book-front, .book-back {
  position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4.5%; text-align: center;
  backface-visibility: hidden; -webkit-backface-visibility: hidden; border-radius: 2px 7px 7px 2px; overflow: hidden;
}
.book-front { background: linear-gradient(90deg, #00000040, #0000 6%, #ffffff1a 7.5%, #0000 9%), var(--cv-surface); box-shadow: inset 0 0 0 1px #00000022, 0 26px 50px -20px #000a; }
.book-front::before { content: ''; position: absolute; inset: 7% 8% 7% 12%; border: 1px solid var(--cv-line); border-radius: 2px; }
.book-front .orn { opacity: .8; }
.foil { position: relative; z-index: 1; background: var(--cv-orn); -webkit-background-clip: text; background-clip: text; color: transparent; padding: 0 .1em; }
.book-title { font-family: var(--font-title); font-size: calc(var(--bw) * .04); letter-spacing: .34em; padding-left: .34em; text-transform: uppercase; }
.book-mono { font-family: var(--font-title); font-size: calc(var(--bw) * .2); line-height: 1; }
.book-mono i { font-family: var(--font-names); font-style: normal; font-size: .7em; margin: 0 .05em; }
.book-names { font-family: var(--font-names); font-size: calc(var(--bw) * .11); line-height: 1.1; }
.book-back { transform: rotateY(180deg); padding: 14%; background: linear-gradient(90deg, color-mix(in srgb, var(--paper), #000 6%), var(--paper) 20%); color: var(--muted); }
.inside-intro { font-family: var(--font-body); font-style: italic; font-size: calc(var(--bw) * .055); line-height: 1.5; }
.is-opening .op-open .book-cover { animation: open-cover 1400ms cubic-bezier(.55, 0, .25, 1) forwards; }
.is-opening .op-open .book { animation: centre-spread 1400ms cubic-bezier(.55, 0, .25, 1) forwards; }
.is-opening .op-open .ribbon { animation: none; }
.is-opening .cover--book.op-open { animation: grow-out 700ms 1550ms var(--ease) forwards; }

/* ================= TILE WALL ================= */
.cover--tiles { background: var(--cv-tile); background-size: 20vw 20vw; }
.is-opening .cover--tiles { background: none; }
.tiles { position: absolute; inset: 0; display: grid; grid-template-columns: repeat(var(--cols, 5), 1fr); grid-auto-rows: var(--size, 20vw); perspective: 900px; }
.tiles i { position: relative; display: block; background: var(--cv-tile); backface-visibility: hidden; -webkit-backface-visibility: hidden; box-shadow: inset 0 0 0 1px var(--cv-line); }
/* Plain designs get a small ornament on every tile; the Mediterranean tile is already patterned. */
.tiles i::after { content: ''; position: absolute; left: 50%; top: 50%; width: 14%; aspect-ratio: 1; translate: -50% -50%; rotate: 45deg; background: var(--cv-orn-c); opacity: .55; }
.design-mesdhe .tiles i::after { display: none; }
.design-mesdhe .tiles i { box-shadow: inset 0 0 0 .5px #1f4e9c22; }
.tile-plaque {
  position: absolute; z-index: 3; left: 50%; top: 42%; translate: -50% -50%; width: min(76vw, 330px); aspect-ratio: 1; border-radius: 50%;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px; text-align: center; padding: 30px;
  background: var(--paper); border: 3px solid var(--cv-orn-c); outline: 1px solid var(--cv-orn-c); outline-offset: 7px;
  box-shadow: 0 0 0 12px var(--paper), 0 30px 60px #0000004d;
}
.tile-plaque .plaque-names i { font-family: var(--font-title); font-style: normal; font-size: .5em; color: var(--orn); }
.is-opening .tile-plaque { animation: pop-out 500ms var(--ease) forwards; }
.is-opening .op-wave .tiles i, .is-opening .op-cascade .tiles i { animation: tile-flip 760ms cubic-bezier(.5, 0, .3, 1) var(--delay, 0ms) forwards; }

/* ================= ROSES (a filmed envelope) ================= */
/* The video fills the screen; invite.js keeps the monogram on the video's blank seal (position,
   size and strength per frame) and plays it on tap. The video ends in white light, then the
   cover fades into the card (rv-end). */
.cover--roses { background: radial-gradient(ellipse at 50% 45%, #7a2333, #4a1019 75%); }
.rv-video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; pointer-events: none; }
/* Wide screens: show the whole (portrait) film rather than a close-up of the seal. */
@media (min-aspect-ratio: 3/4) { .rv-video { object-fit: contain; } }
.rv-mono {
  position: absolute; left: 0; top: 0; z-index: 1; opacity: 0; white-space: nowrap; pointer-events: none; will-change: transform, opacity;
  font: 400 20px/1 "Great Vibes", cursive; padding: .1em .12em;
  background: linear-gradient(165deg, #e2c893, #b38d4f 50%, #85632f); -webkit-background-clip: text; background-clip: text; color: transparent;
  filter: drop-shadow(0 .03em 0 #fffc) drop-shadow(0 -.02em .01em #6d4f2366);
}
.rv-mono i { font-style: normal; font-size: .6em; margin: 0 .03em; }
.cover--roses.rv-end { animation: fade-out 450ms var(--ease) forwards; }

/* ================= UNIVERSAL OPENINGS (any cover) ================= */
.is-opening .cover.op-fade { animation: u-fade 1000ms var(--ease) forwards; }
.is-opening .cover.op-zoom { animation: u-zoom 1200ms cubic-bezier(.5, 0, .75, .3) forwards; }
.is-opening .cover.op-dissolve { animation: u-dissolve 1300ms ease-in forwards; }

@keyframes cta-float { 50% { translate: -50% -6px; } }
.cover--envelope .cover-btn--pill, .cover--book .cover-btn--pill, .cover--envelope .cover-btn--lemon, .cover--book .cover-btn--lemon { animation-name: cta-float-inline; }
@keyframes cta-float-inline { 50% { translate: 0 -6px; } }
@keyframes halo { 0% { scale: 1; opacity: .9; } 80%, 100% { scale: 1.55; opacity: 0; } }
@keyframes tap { 0%, 60%, 100% { translate: 0 0; } 70% { translate: 0 3px; } }
@keyframes bob { 0%, 100% { rotate: -6deg; } 50% { rotate: 6deg; translate: 0 -6px; } }
@keyframes fade-out { to { opacity: 0; } }
@keyframes swing-left { to { transform: rotateY(86deg); } }
@keyframes swing-right { to { transform: rotateY(-86deg); } }
@keyframes shade-in { to { opacity: .55; } }
@keyframes dr-seal { 35% { filter: brightness(1.2) drop-shadow(0 0 10px #ffd98a) drop-shadow(0 0 22px #ffc04d); } 100% { filter: brightness(1.12) drop-shadow(0 0 6px #ffd98a); } }
@keyframes dr-up { 20% { opacity: .75; } 70% { opacity: .75; } 100% { opacity: 0; } }
@keyframes dr-down { 0% { opacity: 1; clip-path: inset(0 -40px 100% -40px); } 50% { clip-path: inset(0 -40px 0 -40px); } 70% { opacity: 1; } 100% { opacity: 0; clip-path: inset(0 -40px 0 -40px); } }
@keyframes dr-spark { 15% { opacity: 1; } 100% { opacity: 0; translate: var(--x) var(--y); } }
@keyframes dr-btn {
  30%, 65% { opacity: 1; filter: brightness(1.08) drop-shadow(0 0 6px #ffe3a3) drop-shadow(0 0 18px #ffc65a); }
  100% { opacity: 0; filter: brightness(1.08) drop-shadow(0 0 6px #ffe3a3) drop-shadow(0 0 18px #ffc65a); }
}
@keyframes slide-left { to { transform: translateX(-102%); } }
@keyframes slide-right { to { transform: translateX(102%); } }
@keyframes seal-off { 40% { scale: 1.12; opacity: 1; } to { scale: .7; opacity: 0; } }
@keyframes flap-open { 0% { transform: rotateX(0); z-index: 5; } 55% { z-index: 5; } 56% { z-index: 1; } 100% { transform: rotateX(180deg); z-index: 1; } }
@keyframes letter-out { to { translate: 0 -58%; } }
@keyframes sway { 0%, 100% { rotate: -2.5deg; } 50% { rotate: 2.5deg; } }
@keyframes pull { 35% { translate: 0 26px; } 100% { translate: 0 -100%; opacity: 0; } }
@keyframes gather-left { 55% { transform: scaleX(.42) skewY(1.5deg); } 100% { transform: translateX(-100%) scaleX(.28); } }
@keyframes gather-right { 55% { transform: scaleX(.42) skewY(-1.5deg); } 100% { transform: translateX(100%) scaleX(.28); } }
@keyframes fly-up { 20% { transform: scaleY(1.03); } 100% { transform: translateY(-115%) scaleY(.9); } }
@keyframes flutter { 0%, 100% { rotate: -3deg; } 50% { rotate: 3deg; } }
@keyframes open-cover { to { transform: rotateY(-178deg); } }
/* The open spread is two books wide: scale it to fit (--spread from invite.js), then centre it. */
@keyframes centre-spread { to { transform: scale(var(--spread, 1)) translateX(50%); } }
@keyframes grow-out { to { opacity: 0; transform: scale(1.06); } }
@keyframes pop-out { to { opacity: 0; scale: .85; } }
@keyframes tile-flip { to { transform: rotateY(180deg) scale(.7); } }
@keyframes u-fade { to { opacity: 0; transform: scale(1.04); } }
@keyframes u-zoom { to { opacity: 0; transform: scale(2.6); } }
@keyframes u-dissolve { 0% { filter: blur(0) brightness(1); } 60% { opacity: .8; } 100% { opacity: 0; filter: blur(16px) brightness(1.7); } }

/* A patterned (tile) surface would swallow the foil lettering: give the book a plain label panel. */
.design-mesdhe .book-front { background: var(--cv-surface); }
.design-mesdhe .book-front::before { inset: 16% 14%; border: 3px solid var(--cv-orn-c); background: var(--paper); outline: 1px solid var(--cv-orn-c); outline-offset: 5px; }
