/* ═══════════════════════════════════════════════════════════════════════
   Premium opening stage library — shared by dynamic-json-canvas.html and
   main-edit-wedding.html. Everything is namespaced .po-*. The HOST overlay
   provides the positioning context (inset 0) and its own exit fade; the JS
   (premium-openings.js) builds the stage DOM, sets --po-accent/--po-dur and
   the per-design stage delays (--po-s1…--po-s5, absolute ms) so every
   choreography scales uniformly with the chosen duration.

   Stage conventions (every design): s1 arrival · s2 first object beat ·
   s3 second object beat · s4 content presentation · s5 fill/clear.
   ═══════════════════════════════════════════════════════════════════════ */

/* Local Ge'ez display faces so monograms/names render offline in exported
   bundles (the dynamic template otherwise relies on the Google Fonts link). */
@font-face {
  font-family: "PO Geez Display";
  src: url("../fonts/WaldbaYebse-Regular.woff2") format("woff2");
  font-display: swap;
}
@font-face {
  font-family: "PO Geez Serif";
  src: url("../fonts/EthiopicLeTewahedo-Regular.woff2") format("woff2");
  font-display: swap;
}

/* ───────────────────────── stage + shared primitives ───────────────────── */

.po-stage {
  position: absolute;
  inset: 0;
  overflow: hidden;
  display: grid;
  place-items: center;
  perspective: 1500px;
  perspective-origin: 50% 40%;
  --po-ink: #16110b;
  --po-paper: #f3ecdd;
  --po-paper-deep: #e7ddc8;
  --po-card: #fbf7ee;
  --po-text-ink: #3a2f1f;
  --po-obj-w: min(74vmin, 470px);
  font-family: var(--po-font-display, "Playfair Display", "Cormorant Garamond", Georgia, serif);
}

.po-backdrop {
  position: absolute;
  inset: -2%;
  background:
    radial-gradient(120% 100% at 50% 30%,
      color-mix(in srgb, var(--po-accent) 24%, var(--po-ink)) 0%,
      var(--po-ink) 64%);
  opacity: 0;
  animation: poFadeIn calc(var(--po-dur) * 0.14) ease var(--po-s1, 0ms) both;
}
.po-vignette {
  position: absolute;
  inset: 0;
  background: radial-gradient(120% 120% at 50% 50%, transparent 55%, rgba(0, 0, 0, 0.42) 100%);
  pointer-events: none;
  z-index: 20;
}
@keyframes poFadeIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes poFadeUp {
  from { opacity: 0; transform: translateY(12px); }
  to { opacity: 1; transform: translateY(0); }
}
@keyframes poDim { to { opacity: 0; } }

/* drifting golden motes (count/placement randomized by JS) */
.po-mote {
  position: absolute;
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: color-mix(in srgb, var(--po-accent) 85%, #fff);
  filter: blur(0.5px);
  opacity: 0;
  animation: poMote var(--mote-dur, 6s) linear var(--mote-delay, 0s) infinite;
}
@keyframes poMote {
  0% { opacity: 0; transform: translateY(12px) translateX(0); }
  18% { opacity: var(--mote-peak, 0.55); }
  82% { opacity: var(--mote-peak, 0.55); }
  100% { opacity: 0; transform: translateY(-46px) translateX(var(--mote-sway, 8px)); }
}

/* the JS-driven WAAPI zoom wrapper (FLIP "card fills the screen") */
.po-zoom {
  position: relative;
  transform-style: preserve-3d;
  will-change: transform;
}
/* WAAPI failed → approximate fill with a plain CSS scale */
.po-fill-fallback .po-zoom {
  animation: poZoomFallback calc(var(--po-dur) * 0.2) cubic-bezier(.55,.06,.25,1) var(--po-s5, 0ms) forwards;
}
@keyframes poZoomFallback { to { transform: scale(5.2); } }

/* ── the shared "mini invitation card" face (envelope/box/gatefold/ribbon/
     floral). Positioning + motion are per-design; type scales with
     --po-obj-w so any stage size keeps the proportions. ── */
.po-mini-card {
  position: absolute;
  border-radius: 4px;
  background:
    linear-gradient(168deg, rgba(255, 255, 255, 0.65), transparent 46%),
    var(--po-card);
  box-shadow: 0 10px 34px rgba(0, 0, 0, 0.35);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  will-change: transform;
}
.po-card-frame {
  position: absolute;
  inset: 5.5%;
  border: 1px solid color-mix(in srgb, var(--po-accent) 65%, transparent);
  border-radius: 2px;
  pointer-events: none;
}
.po-card-frame::before {
  content: "";
  position: absolute;
  inset: 4px;
  border: 1px solid color-mix(in srgb, var(--po-accent) 30%, transparent);
  border-radius: 1px;
}
.po-card-eyebrow {
  font-size: calc(var(--po-obj-w) * 0.0235);
  letter-spacing: 0.4em;
  text-transform: uppercase;
  color: color-mix(in srgb, var(--po-accent) 75%, var(--po-text-ink));
  opacity: 0;
  animation: poFadeUp calc(var(--po-dur) * 0.18) ease calc(var(--po-s4) + var(--po-dur) * 0.05) forwards;
}
.po-card-monogram {
  margin-top: calc(var(--po-obj-w) * 0.028);
  font-size: calc(var(--po-obj-w) * 0.105);
  line-height: 1.1;
  color: var(--po-accent);
  letter-spacing: 0.08em;
  opacity: 0;
  animation: poFadeUp calc(var(--po-dur) * 0.18) ease calc(var(--po-s4) + var(--po-dur) * 0.09) forwards;
}
.po-card-names {
  margin-top: calc(var(--po-obj-w) * 0.02);
  max-width: 86%;
  font-size: calc(var(--po-obj-w) * 0.043);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--po-text-ink);
  opacity: 0;
  animation: poFadeUp calc(var(--po-dur) * 0.18) ease calc(var(--po-s4) + var(--po-dur) * 0.13) forwards;
}
.po-card-rule {
  width: 34%;
  height: 1px;
  margin-top: calc(var(--po-obj-w) * 0.03);
  background: linear-gradient(90deg, transparent, var(--po-accent), transparent);
  opacity: 0;
  animation: poFadeIn calc(var(--po-dur) * 0.18) ease calc(var(--po-s4) + var(--po-dur) * 0.16) forwards;
}
.po-card-date {
  margin-top: calc(var(--po-obj-w) * 0.024);
  font-size: calc(var(--po-obj-w) * 0.026);
  letter-spacing: 0.32em;
  text-transform: uppercase;
  color: color-mix(in srgb, var(--po-text-ink) 70%, transparent);
  opacity: 0;
  animation: poFadeUp calc(var(--po-dur) * 0.18) ease calc(var(--po-s4) + var(--po-dur) * 0.19) forwards;
}

/* ─────────────────────────── envelopeSeal ───────────────────────────────
   A wax-sealed envelope arrives, the monogrammed seal cracks and falls, the
   flap opens in 3D spilling light, the invitation card slides out and
   swells to fill the screen as the envelope dims away. */

.po-envelopeSeal .po-env-wrap {
  position: relative;
  width: var(--po-obj-w);
  height: calc(var(--po-obj-w) * 0.66);
  transform-style: preserve-3d;
  animation:
    poEnvArrive calc(var(--po-dur) * 0.18) cubic-bezier(.18,.8,.26,1) var(--po-s1) both,
    poEnvLevel calc(var(--po-dur) * 0.16) ease var(--po-s4) forwards;
}
@keyframes poEnvArrive {
  0% { opacity: 0; transform: translateY(16vh) rotateX(34deg) scale(0.9); }
  100% { opacity: 1; transform: translateY(0) rotateX(10deg) scale(1); }
}
@keyframes poEnvLevel {
  from { transform: translateY(0) rotateX(10deg) scale(1); }
  to { transform: translateY(1.5%) rotateX(0deg) scale(1); }
}

.po-env-shadow {
  position: absolute;
  left: 50%;
  bottom: -9%;
  width: 96%;
  height: 12%;
  transform: translateX(-50%);
  border-radius: 50%;
  background: radial-gradient(50% 50% at 50% 50%, rgba(0, 0, 0, 0.5), transparent 70%);
  animation:
    poShadowSettle calc(var(--po-dur) * 0.18) cubic-bezier(.18,.8,.26,1) var(--po-s1) both,
    poDim calc(var(--po-dur) * 0.1) ease var(--po-s5) forwards;
}
@keyframes poShadowSettle {
  0% { opacity: 0; transform: translateX(-50%) scaleX(1.5); filter: blur(14px); }
  100% { opacity: 1; transform: translateX(-50%) scaleX(1); filter: blur(6px); }
}

/* back panel + liner sliver that shows above the pocket once the flap opens */
.po-env-back {
  position: absolute;
  inset: 0;
  border-radius: 7px;
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.12), transparent 36%),
    linear-gradient(180deg, var(--po-paper-deep), var(--po-paper));
  box-shadow: 0 22px 60px rgba(0, 0, 0, 0.45);
  z-index: 1;
  animation: poDim calc(var(--po-dur) * 0.1) ease var(--po-s5) forwards;
}
.po-env-liner {
  position: absolute;
  inset: 1.5% 1.5% 55% 1.5%;
  border-radius: 5px 5px 0 0;
  overflow: hidden;
  color: color-mix(in srgb, var(--po-accent) 92%, #38260c);
  background:
    linear-gradient(180deg, rgba(0, 0, 0, 0.18), transparent 30%),
    color-mix(in srgb, var(--po-accent) 36%, #f0e3c8);
}
.po-env-liner svg, .po-flap-face.back svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

.po-envelopeSeal { --po-obj-w: min(64vmin, 440px); }
.po-envelopeSeal .po-mini-card {
  left: 7%;
  top: 5%;
  width: 86%;
  height: 90%;
  z-index: 3;
  animation: poCardRise calc(var(--po-dur) * 0.2) cubic-bezier(.16,.8,.24,1.06) var(--po-s4) forwards;
}
@keyframes poCardRise {
  0% { transform: translateY(0); }
  100% { transform: translateY(-64%); }
}

/* front pocket: classic V-notch envelope face with diagonal fold shading */
.po-env-pocket {
  position: absolute;
  inset: 0;
  border-radius: 7px;
  clip-path: polygon(0 0, 50% 40%, 100% 0, 100% 100%, 0 100%);
  background:
    linear-gradient(115deg, rgba(255, 255, 255, 0.32), transparent 46%),
    linear-gradient(245deg, rgba(255, 255, 255, 0.2), transparent 46%),
    linear-gradient(0deg, rgba(0, 0, 0, 0.07), transparent 40%),
    var(--po-paper);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.5);
  z-index: 4;
  animation: poDim calc(var(--po-dur) * 0.1) ease var(--po-s5) forwards;
}
.po-env-pocket::before,
.po-env-pocket::after {
  content: "";
  position: absolute;
  top: 0;
  width: 58%;
  height: 46%;
  background: linear-gradient(to bottom, rgba(0, 0, 0, 0.14), transparent 70%);
}
.po-env-pocket::before { left: -8%; transform: skewY(20deg); transform-origin: top left; }
.po-env-pocket::after { right: -8%; transform: skewY(-20deg); transform-origin: top right; }

/* flap: rotates up & over in 3D; front face = paper, back face = liner.
   z-index drops once it passes vertical so the rising card clears it. */
.po-env-flap {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 46%;
  transform-origin: top center;
  transform-style: preserve-3d;
  z-index: 6;
  animation:
    poFlapOpen calc(var(--po-dur) * 0.22) cubic-bezier(.6,.05,.3,1) var(--po-s3) forwards,
    poDim calc(var(--po-dur) * 0.1) ease var(--po-s5) forwards;
  will-change: transform;
}
@keyframes poFlapOpen {
  0% { transform: rotateX(0deg); z-index: 6; }
  49% { z-index: 6; }
  50% { z-index: 2; }
  100% { transform: rotateX(-178deg); z-index: 2; }
}
.po-flap-face {
  position: absolute;
  inset: 0;
  clip-path: polygon(0 0, 100% 0, 50% 96%);
  backface-visibility: hidden;
}
.po-flap-face.front {
  transform: translateZ(0.4px);
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.3), transparent 46%),
    linear-gradient(180deg, var(--po-paper), color-mix(in srgb, var(--po-paper-deep) 88%, #c9b896));
  border-radius: 7px 7px 0 0;
  filter: drop-shadow(0 2px 3px rgba(0, 0, 0, 0.16));
}
.po-flap-face.back {
  transform: rotateX(180deg) translateZ(0.4px);
  overflow: hidden;
  color: color-mix(in srgb, var(--po-accent) 92%, #38260c);
  background:
    linear-gradient(0deg, rgba(0, 0, 0, 0.14), transparent 40%),
    color-mix(in srgb, var(--po-accent) 36%, #f0e3c8);
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.08);
}

/* light spilling out of the opened envelope (positioned at the fold line,
   inside the envelope wrap so it tracks the object) */
.po-light-spill {
  position: absolute;
  left: 50%;
  top: 8%;
  width: 170%;
  height: 120%;
  transform: translate(-50%, -50%) scale(0.5);
  border-radius: 50%;
  background: radial-gradient(50% 50% at 50% 50%,
    color-mix(in srgb, var(--po-accent) 62%, #fff6dd) 0%,
    color-mix(in srgb, var(--po-accent) 30%, rgba(255, 244, 214, 0.4)) 34%,
    transparent 68%);
  filter: blur(14px);
  opacity: 0;
  z-index: 5;
  pointer-events: none;
  animation: poSpill calc(var(--po-dur) * 0.34) ease var(--po-s3) both;
}
@keyframes poSpill {
  0% { opacity: 0; transform: translate(-50%, -50%) scale(0.5); }
  35% { opacity: 0.85; transform: translate(-50%, -50%) scale(1.06); }
  100% { opacity: 0; transform: translate(-50%, -50%) scale(1.3); }
}

/* wax seal (inline SVG, two clip-path halves that crack apart and fall) */
.po-seal {
  position: absolute;
  left: 50%;
  top: 44%;
  width: clamp(58px, calc(var(--po-obj-w) * 0.21), 104px);
  height: clamp(58px, calc(var(--po-obj-w) * 0.21), 104px);
  transform: translate(-50%, -50%);
  z-index: 7;
  animation:
    poSealGlow calc(var(--po-dur) * 0.14) ease var(--po-s2) both,
    poSealPress calc(var(--po-dur) * 0.05) cubic-bezier(.4,0,.6,1) calc(var(--po-s3) - var(--po-dur) * 0.13) both,
    poDim calc(var(--po-dur) * 0.06) ease var(--po-s3) forwards;
}
@keyframes poSealGlow {
  0% { filter: drop-shadow(0 2px 6px rgba(0, 0, 0, 0.4)); }
  55% { filter: drop-shadow(0 0 18px color-mix(in srgb, var(--po-accent) 80%, #fff)) drop-shadow(0 2px 6px rgba(0, 0, 0, 0.4)); }
  100% { filter: drop-shadow(0 2px 6px rgba(0, 0, 0, 0.4)); }
}
@keyframes poSealPress {
  0% { transform: translate(-50%, -50%) scale(1); }
  55% { transform: translate(-50%, -50%) scale(1.08); }
  100% { transform: translate(-50%, -50%) scale(1); }
}
.po-seal svg { width: 100%; height: 100%; overflow: visible; }
.po-seal-half {
  animation-duration: calc(var(--po-dur) * 0.16);
  animation-timing-function: cubic-bezier(.3, 0, .7, .2);
  animation-delay: calc(var(--po-s3) - var(--po-dur) * 0.08);
  animation-fill-mode: forwards;
  transform-box: fill-box;
  transform-origin: center;
  will-change: transform, opacity;
}
.po-seal-half.l { animation-name: poSealFallL; }
.po-seal-half.r { animation-name: poSealFallR; }
@keyframes poSealFallL {
  0% { transform: translate(0, 0) rotate(0deg); opacity: 1; }
  100% { transform: translate(-34%, 150%) rotate(-22deg); opacity: 0; }
}
@keyframes poSealFallR {
  0% { transform: translate(0, 0) rotate(0deg); opacity: 1; }
  100% { transform: translate(30%, 160%) rotate(18deg); opacity: 0; }
}

/* ─────────────────────────── keepsakeBox ────────────────────────────────
   A velvet keepsake box rises; the lid lifts away with a shaft of light and
   drifting dust; the invitation rises out of the box and fills the screen. */

.po-keepsakeBox { --po-obj-w: min(64vmin, 420px); }
.po-keepsakeBox .po-backdrop {
  background:
    radial-gradient(120% 100% at 50% 26%,
      color-mix(in srgb, var(--po-accent) 18%, #120b10) 0%,
      #0e090d 66%);
}
.po-box-wrap {
  position: relative;
  width: var(--po-obj-w);
  height: calc(var(--po-obj-w) * 0.78);
  transform-style: preserve-3d;
  animation: poBoxArrive calc(var(--po-dur) * 0.18) cubic-bezier(.18,.8,.26,1) var(--po-s1) both;
}
@keyframes poBoxArrive {
  0% { opacity: 0; transform: translateY(14vh) scale(0.92); }
  100% { opacity: 1; transform: translateY(0) scale(1); }
}
.po-box-shadow {
  position: absolute;
  left: 50%;
  bottom: -7%;
  width: 110%;
  height: 12%;
  transform: translateX(-50%);
  border-radius: 50%;
  background: radial-gradient(50% 50% at 50% 50%, rgba(0, 0, 0, 0.55), transparent 70%);
  filter: blur(8px);
  animation: poDim calc(var(--po-dur) * 0.1) ease var(--po-s5) forwards;
}
.po-box-body {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 62%;
  border-radius: 6px 6px 10px 10px;
  background:
    linear-gradient(100deg, rgba(255, 255, 255, 0.14), transparent 30%),
    linear-gradient(180deg,
      color-mix(in srgb, var(--po-accent) 34%, #221018),
      color-mix(in srgb, var(--po-accent) 16%, #140a10) 80%);
  box-shadow: inset 0 6px 14px rgba(0, 0, 0, 0.5), 0 18px 50px rgba(0, 0, 0, 0.5);
  z-index: 4;
  animation: poDim calc(var(--po-dur) * 0.1) ease var(--po-s5) forwards;
}
.po-box-body::after {
  content: "";
  position: absolute;
  left: 6%;
  right: 6%;
  top: 14%;
  height: 1px;
  background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--po-accent) 80%, #ffe9b8), transparent);
  opacity: 0.8;
}
.po-box-mouth {
  position: absolute;
  left: 2.5%;
  right: 2.5%;
  bottom: 56%;
  height: 7%;
  border-radius: 4px;
  background: linear-gradient(180deg, #06030a, rgba(6, 3, 10, 0));
  z-index: 2;
}
.po-keepsakeBox .po-mini-card {
  left: 9%;
  width: 82%;
  height: 76%;
  bottom: 10%;
  z-index: 3;
  transform: translateY(28%);
  animation: poBoxCardRise calc(var(--po-dur) * 0.2) cubic-bezier(.16,.8,.24,1.05) var(--po-s4) forwards;
}
@keyframes poBoxCardRise {
  0% { transform: translateY(28%); }
  100% { transform: translateY(-74%); }
}
.po-box-lid {
  position: absolute;
  left: -2.5%;
  right: -2.5%;
  bottom: 58%;
  height: 17%;
  border-radius: 8px;
  background:
    linear-gradient(100deg, rgba(255, 255, 255, 0.2), transparent 36%),
    linear-gradient(180deg,
      color-mix(in srgb, var(--po-accent) 42%, #2b1620),
      color-mix(in srgb, var(--po-accent) 22%, #1a0d14));
  box-shadow: 0 10px 26px rgba(0, 0, 0, 0.5), inset 0 1px 0 rgba(255, 255, 255, 0.22);
  z-index: 6;
  transform-origin: 50% 120%;
  animation:
    poLidLift calc(var(--po-dur) * 0.26) cubic-bezier(.5,.05,.3,1) var(--po-s2) forwards,
    poDim calc(var(--po-dur) * 0.1) ease var(--po-s5) forwards;
  will-change: transform;
}
.po-box-lid::after {
  content: "";
  position: absolute;
  left: 8%;
  right: 8%;
  top: 46%;
  height: 1px;
  background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--po-accent) 85%, #ffe9b8), transparent);
}
@keyframes poLidLift {
  0% { transform: translateY(0) rotateX(0) rotateZ(0); }
  100% { transform: translateY(-240%) translateZ(-130px) rotateX(54deg) rotateZ(-6deg); opacity: 0.85; }
}
.po-box-shaft {
  position: absolute;
  left: 50%;
  bottom: 56%;
  width: 76%;
  height: 120%;
  transform: translateX(-50%);
  clip-path: polygon(18% 100%, 82% 100%, 100% 0, 0 0);
  background: linear-gradient(to top,
    color-mix(in srgb, var(--po-accent) 52%, #fff3d8) 0%,
    transparent 80%);
  filter: blur(10px);
  opacity: 0;
  z-index: 1;
  animation: poShaft calc(var(--po-dur) * 0.4) ease var(--po-s3) both;
}
@keyframes poShaft {
  0% { opacity: 0; transform: translateX(-50%) scaleY(0.4); transform-origin: bottom; }
  35% { opacity: 0.7; }
  100% { opacity: 0; transform: translateX(-50%) scaleY(1.06); }
}

/* ─────────────────────────── gatefold ───────────────────────────────────
   A wide gatefold invitation: both decorated outer panels hinge open in 3D
   revealing the centre card, then glide aside as the card fills the view. */

.po-gatefold { --po-obj-w: min(80vmin, 540px); }
.po-gf-wrap {
  position: relative;
  width: var(--po-obj-w);
  height: calc(var(--po-obj-w) * 0.7);
  transform-style: preserve-3d;
  animation: poBoxArrive calc(var(--po-dur) * 0.16) cubic-bezier(.18,.8,.26,1) var(--po-s1) both;
}
.po-gatefold .po-mini-card {
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 1;
}
.po-gf-panel {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 50.5%;
  transform-style: preserve-3d;
  z-index: 5;
  will-change: transform;
}
.po-gf-panel.left  { left: 0;  transform-origin: left center; }
.po-gf-panel.right { right: 0; transform-origin: right center; }
.po-gf-panel.left {
  animation:
    poGfOpenL calc(var(--po-dur) * 0.26) cubic-bezier(.6,.05,.3,1) var(--po-s2) forwards,
    poGfAwayL calc(var(--po-dur) * 0.16) cubic-bezier(.5,.05,.5,1) var(--po-s4) forwards;
}
.po-gf-panel.right {
  animation:
    poGfOpenR calc(var(--po-dur) * 0.26) cubic-bezier(.6,.05,.3,1) var(--po-s3) forwards,
    poGfAwayR calc(var(--po-dur) * 0.16) cubic-bezier(.5,.05,.5,1) var(--po-s4) forwards;
}
@keyframes poGfOpenL { to { transform: rotateY(-148deg); } }
@keyframes poGfOpenR { to { transform: rotateY(148deg); } }
@keyframes poGfAwayL { to { transform: rotateY(-148deg) translateX(34vw); opacity: 0; } }
@keyframes poGfAwayR { to { transform: rotateY(148deg) translateX(-34vw); opacity: 0; } }
.po-gf-face {
  position: absolute;
  inset: 0;
  backface-visibility: hidden;
}
.po-gf-face.front {
  /* the tiny translateZ forces real 3D rendering so backface-visibility
     is honored and the faces don't z-fight mid-swing */
  transform: translateZ(0.4px);
  background:
    linear-gradient(135deg, rgba(255, 255, 255, 0.26), transparent 42%),
    linear-gradient(180deg, var(--po-paper), var(--po-paper-deep));
  box-shadow: 0 16px 44px rgba(0, 0, 0, 0.4);
}
.po-gf-panel.left  .po-gf-face.front { border-radius: 6px 0 0 6px; }
.po-gf-panel.right .po-gf-face.front { border-radius: 0 6px 6px 0; }
.po-gf-face.front::before {
  content: "";
  position: absolute;
  inset: 7%;
  border: 1px solid color-mix(in srgb, var(--po-accent) 55%, transparent);
}
/* a split diamond emblem on the closed seam */
.po-gf-face.front::after {
  content: "";
  position: absolute;
  top: 50%;
  width: calc(var(--po-obj-w) * 0.055);
  height: calc(var(--po-obj-w) * 0.055);
  background: color-mix(in srgb, var(--po-accent) 85%, #f4e3b8);
  transform: translateY(-50%) rotate(45deg);
}
.po-gf-panel.left  .po-gf-face.front::after { right: calc(var(--po-obj-w) * -0.0275); }
.po-gf-panel.right .po-gf-face.front::after { left: calc(var(--po-obj-w) * -0.0275); }
.po-gf-face.back {
  transform: rotateY(180deg) translateZ(0.4px);
  overflow: hidden;
  color: color-mix(in srgb, var(--po-accent) 92%, #38260c);
  background:
    linear-gradient(90deg, rgba(0, 0, 0, 0.12), transparent 30%),
    color-mix(in srgb, var(--po-accent) 34%, #f0e3c8);
}
.po-gf-face.back svg { position: absolute; inset: 0; width: 100%; height: 100%; }
/* moving fold shade while panels swing */
.po-gf-shade {
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, rgba(0, 0, 0, 0.3), transparent 60%);
  opacity: 0.5;
  animation: poDim calc(var(--po-dur) * 0.26) ease var(--po-s2) forwards;
  pointer-events: none;
}

/* ─────────────────────────── silkRibbon ─────────────────────────────────
   The card is bound in satin ribbon with a bow. The bow unties, the bands
   slip off with a cloth flutter, and the card breathes up to full view. */

.po-silkRibbon { --po-obj-w: min(58vmin, 380px); }
.po-silkRibbon .po-backdrop {
  background:
    radial-gradient(120% 100% at 50% 28%,
      color-mix(in srgb, var(--po-accent) 16%, #1a1412) 0%,
      #14100e 66%);
}
.po-rb-wrap {
  position: relative;
  width: var(--po-obj-w);
  height: calc(var(--po-obj-w) * 1.32);
  animation: poBoxArrive calc(var(--po-dur) * 0.16) cubic-bezier(.18,.8,.26,1) var(--po-s1) both;
}
.po-silkRibbon .po-mini-card {
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 1;
  animation: poRbBreathe calc(var(--po-dur) * 0.18) cubic-bezier(.2,.8,.3,1.04) var(--po-s4) forwards;
}
@keyframes poRbBreathe {
  0% { transform: scale(0.985); }
  100% { transform: scale(1.01); }
}
.po-ribbon {
  position: absolute;
  z-index: 5;
  background:
    linear-gradient(var(--rb-angle, 90deg),
      color-mix(in srgb, var(--po-accent) 88%, #2c0d12) 0%,
      color-mix(in srgb, var(--po-accent) 70%, #fff) 26%,
      color-mix(in srgb, var(--po-accent) 92%, #1d080c) 52%,
      color-mix(in srgb, var(--po-accent) 72%, #fff) 78%,
      color-mix(in srgb, var(--po-accent) 86%, #2c0d12) 100%);
  background-size: 240% 240%;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
  animation: poRbSheen calc(var(--po-dur) * 0.5) linear var(--po-s1) both;
  will-change: transform;
}
@keyframes poRbSheen {
  0% { background-position: 0% 0%; }
  100% { background-position: 100% 100%; }
}
.po-ribbon.v {
  left: 50%;
  top: -3%;
  bottom: -3%;
  width: calc(var(--po-obj-w) * 0.115);
  margin-left: calc(var(--po-obj-w) * -0.0575);
  --rb-angle: 90deg;
  animation:
    poRbSheen calc(var(--po-dur) * 0.5) linear var(--po-s1) both,
    poRbSlipV calc(var(--po-dur) * 0.2) cubic-bezier(.55,.05,.6,1) var(--po-s3) forwards;
}
.po-ribbon.h {
  top: 38%;
  left: -4%;
  right: -4%;
  height: calc(var(--po-obj-w) * 0.105);
  --rb-angle: 0deg;
  animation:
    poRbSheen calc(var(--po-dur) * 0.5) linear var(--po-s1) both,
    poRbSlipH calc(var(--po-dur) * 0.22) cubic-bezier(.55,.05,.6,1) calc(var(--po-s3) + var(--po-dur) * 0.05) forwards;
}
@keyframes poRbSlipV {
  0% { transform: translateY(0) skewX(0); opacity: 1; }
  45% { transform: translateY(34%) skewX(-7deg); }
  100% { transform: translateY(130%) skewX(-13deg); opacity: 0; }
}
@keyframes poRbSlipH {
  0% { transform: translateX(0) skewY(0); opacity: 1; }
  45% { transform: translateX(-32%) skewY(5deg); }
  100% { transform: translateX(-128%) skewY(10deg); opacity: 0; }
}
.po-bow {
  position: absolute;
  left: 50%;
  top: 38%;
  width: calc(var(--po-obj-w) * 0.46);
  height: calc(var(--po-obj-w) * 0.34);
  transform: translate(-50%, -34%);
  z-index: 6;
  filter: drop-shadow(0 4px 10px rgba(0, 0, 0, 0.35));
  animation: poBowFall calc(var(--po-dur) * 0.2) cubic-bezier(.4,0,.8,.3) calc(var(--po-s2) + var(--po-dur) * 0.12) forwards;
}
@keyframes poBowFall {
  0% { transform: translate(-50%, -34%) rotate(0); opacity: 1; }
  100% { transform: translate(-44%, 80%) rotate(26deg); opacity: 0; }
}
.po-bow svg { width: 100%; height: 100%; overflow: visible; }
.po-bow .bw-base { fill: color-mix(in srgb, var(--po-accent) 86%, #471018); }
.po-bow .bw-lite { fill: color-mix(in srgb, var(--po-accent) 55%, #fff); opacity: 0.4; }
.po-bow .po-bow-knot .bw-base { fill: color-mix(in srgb, var(--po-accent) 88%, #2c080d); }
.po-bow-loop, .po-bow-tail, .po-bow-knot {
  transform-box: fill-box;
  transform-origin: center;
}
.po-bow-loop.l {
  transform-origin: right center;
  animation: poLoopL calc(var(--po-dur) * 0.12) cubic-bezier(.6,.05,.4,1) var(--po-s2) forwards;
}
.po-bow-loop.r {
  transform-origin: left center;
  animation: poLoopR calc(var(--po-dur) * 0.12) cubic-bezier(.6,.05,.4,1) var(--po-s2) forwards;
}
@keyframes poLoopL { to { transform: scaleX(0.12) rotate(-8deg); } }
@keyframes poLoopR { to { transform: scaleX(0.12) rotate(8deg); } }
.po-bow-tail.l { animation: poTailL calc(var(--po-dur) * 0.14) ease calc(var(--po-s2) + var(--po-dur) * 0.04) forwards; }
.po-bow-tail.r { animation: poTailR calc(var(--po-dur) * 0.14) ease calc(var(--po-s2) + var(--po-dur) * 0.04) forwards; }
@keyframes poTailL { to { transform: rotate(-16deg) translateY(8%); } }
@keyframes poTailR { to { transform: rotate(14deg) translateY(10%); } }

/* ─────────────────────────── floralBloom ────────────────────────────────
   Layered botanical clusters cover the screen, then part along soft arcs
   with depth blur while stray petals keep falling through the reveal. */

.po-floralBloom { --po-obj-w: min(58vmin, 380px); }
.po-floralBloom .po-backdrop {
  background:
    radial-gradient(130% 110% at 50% 24%, #f4efe3 0%, #e9e0cd 58%, #ded2b9 100%);
}
.po-floralBloom .po-vignette {
  background: radial-gradient(120% 120% at 50% 50%, transparent 60%, rgba(86, 70, 40, 0.28) 100%);
}
.po-fb-side {
  position: absolute;
  top: -6%;
  bottom: -6%;
  width: 64%;
  z-index: 5;
  will-change: transform, filter;
}
.po-fb-side svg { position: absolute; width: 100%; height: 100%; overflow: visible; }
.po-fb-side.l { left: -8%; }
.po-fb-side.r { right: -8%; transform: scaleX(-1); }
.po-fb-side.back  { z-index: 4; filter: blur(3px) saturate(0.9); opacity: 0.85; }
.po-fb-side.front { z-index: 6; }
.po-fb-side.l.front { animation: poFbPartL calc(var(--po-dur) * 0.34) cubic-bezier(.5,.05,.3,1) var(--po-s2) forwards; }
.po-fb-side.r.front { animation: poFbPartRMir calc(var(--po-dur) * 0.34) cubic-bezier(.5,.05,.3,1) var(--po-s2) forwards; }
.po-fb-side.l.back  { animation: poFbPartLSoft calc(var(--po-dur) * 0.4) cubic-bezier(.5,.05,.3,1) calc(var(--po-s2) + var(--po-dur) * 0.05) forwards; }
.po-fb-side.r.back  { animation: poFbPartRSoftMir calc(var(--po-dur) * 0.4) cubic-bezier(.5,.05,.3,1) calc(var(--po-s2) + var(--po-dur) * 0.05) forwards; }
@keyframes poFbPartL {
  to { transform: translateX(-74%) rotate(-13deg); filter: blur(5px); opacity: 0; }
}
@keyframes poFbPartRMir {
  to { transform: scaleX(-1) translateX(-74%) rotate(-13deg); filter: blur(5px); opacity: 0; }
}
@keyframes poFbPartLSoft {
  to { transform: translateX(-60%) rotate(-8deg); filter: blur(8px); opacity: 0; }
}
@keyframes poFbPartRSoftMir {
  to { transform: scaleX(-1) translateX(-60%) rotate(-8deg); filter: blur(8px); opacity: 0; }
}
.po-floralBloom .po-mini-card {
  position: relative;
  width: var(--po-obj-w);
  height: calc(var(--po-obj-w) * 1.3);
  z-index: 3;
  opacity: 0;
  animation: poFbCard calc(var(--po-dur) * 0.24) cubic-bezier(.2,.8,.3,1) calc(var(--po-s2) + var(--po-dur) * 0.08) forwards;
}
@keyframes poFbCard {
  0% { opacity: 0; transform: translateY(20px) scale(0.96); filter: blur(4px); }
  100% { opacity: 1; transform: translateY(0) scale(1); filter: blur(0); }
}
.po-petal {
  position: absolute;
  width: 10px;
  height: 14px;
  border-radius: 60% 40% 60% 40%;
  background: color-mix(in srgb, var(--po-accent) 36%, #fdf3ef);
  opacity: 0;
  z-index: 7;
  animation: poPetalFall var(--petal-dur, 7s) linear var(--petal-delay, 0s) infinite;
}
@keyframes poPetalFall {
  0% { opacity: 0; transform: translate3d(0, -6vh, 0) rotate(0); }
  12% { opacity: 0.85; }
  100% { opacity: 0; transform: translate3d(var(--petal-sway, 40px), 105vh, 0) rotate(var(--petal-spin, 240deg)); }
}

/* ─────────────────────────── goldDust ───────────────────────────────────
   Gold particles swirl in and converge into the couple's monogram, which
   ignites, then bursts into falling sparks as the page comes through. */

.po-goldDust .po-backdrop {
  background:
    radial-gradient(120% 100% at 50% 34%,
      color-mix(in srgb, var(--po-accent) 14%, #0c0905) 0%,
      #080604 66%);
}
.po-gd-center {
  position: relative;
  z-index: 8;
  text-align: center;
}
.po-gd-ring {
  position: absolute;
  left: 50%;
  top: 42%;
  width: min(46vmin, 320px);
  height: min(46vmin, 320px);
  transform: translate(-50%, -50%);
  border-radius: 50%;
  border: 1px solid color-mix(in srgb, var(--po-accent) 45%, transparent);
  opacity: 0;
  z-index: 7;
  animation: poGdRing calc(var(--po-dur) * 0.3) ease var(--po-s2) both;
}
.po-gd-ring::before {
  content: "";
  position: absolute;
  inset: 10px;
  border-radius: 50%;
  border: 1px dashed color-mix(in srgb, var(--po-accent) 35%, transparent);
  animation: poGdSpin 14s linear infinite;
}
@keyframes poGdSpin { to { transform: rotate(360deg); } }
@keyframes poGdRing {
  0% { opacity: 0; transform: translate(-50%, -50%) scale(1.3); }
  100% { opacity: 1; transform: translate(-50%, -50%) scale(1); }
}
.po-gd-monogram {
  font-size: min(30vmin, 210px);
  line-height: 1;
  letter-spacing: 0.04em;
  background: linear-gradient(160deg,
    #f9e8b8 0%,
    color-mix(in srgb, var(--po-accent) 86%, #ffdf9a) 38%,
    #8a5d20 62%,
    color-mix(in srgb, var(--po-accent) 90%, #f3cf86) 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  opacity: 0;
  animation:
    poGdIgnite calc(var(--po-dur) * 0.2) cubic-bezier(.2,.8,.3,1) var(--po-s3) forwards,
    poGdDissolve calc(var(--po-dur) * 0.16) ease var(--po-s5) forwards;
}
@keyframes poGdIgnite {
  0% { opacity: 0; transform: scale(0.86); filter: blur(10px) brightness(2.4); }
  60% { opacity: 1; filter: blur(0) brightness(1.65); }
  100% { opacity: 1; transform: scale(1); filter: blur(0) brightness(1); }
}
@keyframes poGdDissolve {
  to { opacity: 0; transform: scale(1.12); filter: blur(14px) brightness(2); }
}
.po-gd-names {
  margin-top: 2vmin;
  font-size: min(4vmin, 26px);
  letter-spacing: 0.34em;
  text-transform: uppercase;
  color: #f3ead6;
  opacity: 0;
  animation:
    poFadeUp calc(var(--po-dur) * 0.2) ease var(--po-s4) forwards,
    poDim calc(var(--po-dur) * 0.14) ease var(--po-s5) forwards;
}
.po-gd-date {
  margin-top: 1.2vmin;
  font-size: min(2.1vmin, 13px);
  letter-spacing: 0.4em;
  text-transform: uppercase;
  color: color-mix(in srgb, var(--po-accent) 75%, #fff);
  opacity: 0;
  animation:
    poFadeUp calc(var(--po-dur) * 0.2) ease calc(var(--po-s4) + var(--po-dur) * 0.05) forwards,
    poDim calc(var(--po-dur) * 0.14) ease var(--po-s5) forwards;
}
.po-gd-field { position: absolute; inset: 0; z-index: 6; pointer-events: none; }
.po-gd-p {
  position: absolute;
  left: 0;
  top: 0;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: radial-gradient(circle at 36% 32%,
    #fff7df 0%,
    color-mix(in srgb, var(--po-accent) 88%, #ffd98c) 55%,
    rgba(122, 82, 26, 0) 100%);
  opacity: 0;
  will-change: transform, opacity;
}

/* ─────────────────────────── inkReveal ──────────────────────────────────
   A field of dark ink with organic, turbulent edges recedes diagonally like
   water drawing back, uncovering paper grain and the couple's names. */

.po-inkReveal .po-backdrop {
  background:
    repeating-linear-gradient(2deg, rgba(64, 50, 28, 0.025) 0 2px, transparent 2px 5px),
    repeating-linear-gradient(92deg, rgba(64, 50, 28, 0.02) 0 3px, transparent 3px 7px),
    radial-gradient(120% 110% at 50% 30%, #f6f1e4 0%, #ece4d0 70%, #e2d7bd 100%);
}
.po-ink-center {
  position: relative;
  z-index: 3;
  text-align: center;
  color: #232733;
}
.po-ink-eyebrow {
  font-size: min(2vmin, 12px);
  letter-spacing: 0.44em;
  text-transform: uppercase;
  color: #5c5743;
  opacity: 0;
  animation: poFadeUp calc(var(--po-dur) * 0.2) ease calc(var(--po-s3) + var(--po-dur) * 0.1) forwards;
}
.po-ink-names {
  margin-top: 1.6vmin;
  font-size: min(8.6vmin, 64px);
  line-height: 1.12;
  color: #20242e;
  font-style: italic;
  opacity: 0;
  animation: poInkNames calc(var(--po-dur) * 0.26) cubic-bezier(.2,.8,.3,1) calc(var(--po-s3) + var(--po-dur) * 0.14) forwards;
}
@keyframes poInkNames {
  0% { opacity: 0; filter: blur(8px); transform: translateY(10px); }
  100% { opacity: 1; filter: blur(0); transform: translateY(0); }
}
.po-ink-rule {
  width: min(30vmin, 200px);
  height: 1px;
  margin: 2vmin auto 0;
  background: linear-gradient(90deg, transparent, #2b2f3a, transparent);
  opacity: 0;
  animation: poFadeIn calc(var(--po-dur) * 0.2) ease calc(var(--po-s3) + var(--po-dur) * 0.2) forwards;
}
.po-ink-date {
  margin-top: 1.6vmin;
  font-size: min(2.2vmin, 13px);
  letter-spacing: 0.4em;
  text-transform: uppercase;
  color: #555a48;
  opacity: 0;
  animation: poFadeUp calc(var(--po-dur) * 0.2) ease calc(var(--po-s3) + var(--po-dur) * 0.24) forwards;
}
.po-ink-wash {
  position: absolute;
  inset: -22%;
  z-index: 5;
  background:
    radial-gradient(70% 60% at 30% 36%, rgba(16, 19, 28, 0.98) 0%, rgba(16, 19, 28, 0.94) 55%, rgba(16, 19, 28, 0) 78%),
    radial-gradient(80% 72% at 72% 62%, rgba(22, 26, 36, 0.98) 0%, rgba(22, 26, 36, 0.9) 52%, rgba(22, 26, 36, 0) 80%),
    radial-gradient(120% 110% at 50% 50%, rgba(13, 16, 24, 0.99) 0%, rgba(13, 16, 24, 0.95) 60%, rgba(13, 16, 24, 0.6) 82%, rgba(13, 16, 24, 0) 96%);
  will-change: transform, opacity;
  animation: poInkRecede calc(var(--po-dur) * 0.42) cubic-bezier(.55,.04,.3,1) var(--po-s3) forwards;
}
.po-ink-wash.second {
  z-index: 4;
  opacity: 0.55;
  animation-delay: calc(var(--po-s3) + var(--po-dur) * 0.06);
  animation-duration: calc(var(--po-dur) * 0.46);
}
@keyframes poInkRecede {
  0% { transform: translate3d(0, 0, 0) scale(1); opacity: 1; }
  60% { opacity: 0.96; }
  100% { transform: translate3d(26%, -18%, 0) scale(1.12) rotate(2deg); opacity: 0; }
}
.po-ink-sheen {
  position: absolute;
  inset: 0;
  z-index: 6;
  background: linear-gradient(115deg, transparent 30%, rgba(255, 255, 255, 0.1) 46%, transparent 62%);
  background-size: 240% 240%;
  mix-blend-mode: screen;
  pointer-events: none;
  animation: poRbSheen calc(var(--po-dur) * 0.6) linear var(--po-s1) both;
}

/* ─────────────────────────── teletWeave ─────────────────────────────────
   Woven telet ribbon bands (habesha-kemis border geometry, colorways drawn
   from the project accent) sweep in from alternating sides, weave across the
   screen, then settle into a top/bottom frame as meskel daisies bloom in the
   corners and the couple's Ge'ez-set monogram rises in the centre. */

.po-teletWeave .po-backdrop {
  background:
    radial-gradient(120% 100% at 50% 30%,
      color-mix(in srgb, var(--po-accent) 20%, #1b120a) 0%,
      #140d07 66%);
}
.po-tl-band {
  position: absolute;
  left: -4%;
  right: -4%;
  top: var(--tb-top, 50%);
  height: clamp(30px, 6.6vmin, 58px);
  z-index: 5;
  box-shadow: 0 7px 20px rgba(0, 0, 0, 0.4);
  will-change: transform, opacity;
  animation: poTlSweepL calc(var(--po-dur) * 0.3) cubic-bezier(.2,.8,.25,1) var(--tb-delay, var(--po-s2)) both;
}
.po-tl-band.from-r { animation-name: poTlSweepR; }
.po-tl-band.mid {
  animation:
    poTlSweepL calc(var(--po-dur) * 0.3) cubic-bezier(.2,.8,.25,1) var(--tb-delay, var(--po-s2)) both,
    poTlPass calc(var(--po-dur) * 0.2) ease var(--po-s5) forwards;
}
.po-tl-band.mid.from-r {
  animation:
    poTlSweepR calc(var(--po-dur) * 0.3) cubic-bezier(.2,.8,.25,1) var(--tb-delay, var(--po-s2)) both,
    poTlPass calc(var(--po-dur) * 0.2) ease var(--po-s5) forwards;
}
@keyframes poTlSweepL {
  0% { transform: translateX(-112%) skewX(-7deg); opacity: 0; }
  18% { opacity: 1; }
  100% { transform: translateX(0) skewX(0); opacity: 1; }
}
@keyframes poTlSweepR {
  0% { transform: translateX(112%) skewX(7deg); opacity: 0; }
  18% { opacity: 1; }
  100% { transform: translateX(0) skewX(0); opacity: 1; }
}
@keyframes poTlPass { to { opacity: 0; transform: scaleY(0.6); } }
.po-tl-band svg { width: 100%; height: 100%; display: block; }

.po-tl-daisy {
  position: absolute;
  width: clamp(40px, 9vmin, 76px);
  height: clamp(40px, 9vmin, 76px);
  z-index: 6;
  opacity: 0;
  animation: poTlDaisy calc(var(--po-dur) * 0.2) cubic-bezier(.2,.9,.3,1.3) var(--td-delay, var(--po-s3)) forwards;
  filter: drop-shadow(0 3px 8px rgba(0, 0, 0, 0.35));
}
@keyframes poTlDaisy {
  0% { opacity: 0; transform: scale(0.2) rotate(-80deg); }
  100% { opacity: 1; transform: scale(1) rotate(0); }
}
.po-tl-daisy svg { width: 100%; height: 100%; }

.po-tl-center {
  position: relative;
  z-index: 4;
  text-align: center;
  color: #f6efe0;
}
.po-tl-ornament {
  width: clamp(30px, 6vmin, 50px);
  height: clamp(30px, 6vmin, 50px);
  margin: 0 auto;
  opacity: 0;
  animation: poTlDaisy calc(var(--po-dur) * 0.18) cubic-bezier(.2,.9,.3,1.2) calc(var(--po-s4) - var(--po-dur) * 0.04) forwards;
}
.po-tl-ornament svg { width: 100%; height: 100%; }
.po-tl-monogram {
  margin-top: 1.6vmin;
  font-size: min(16vmin, 120px);
  line-height: 1.05;
  color: color-mix(in srgb, var(--po-accent) 55%, #f3d9a0);
  opacity: 0;
  animation: poFadeUp calc(var(--po-dur) * 0.2) cubic-bezier(.2,.8,.3,1) var(--po-s4) forwards;
}
.po-tl-names {
  margin-top: 1.4vmin;
  font-size: min(4.6vmin, 30px);
  letter-spacing: 0.26em;
  text-transform: uppercase;
  opacity: 0;
  animation: poFadeUp calc(var(--po-dur) * 0.2) ease calc(var(--po-s4) + var(--po-dur) * 0.06) forwards;
}
.po-tl-date {
  margin-top: 1.4vmin;
  font-size: min(2.2vmin, 13px);
  letter-spacing: 0.4em;
  text-transform: uppercase;
  color: color-mix(in srgb, var(--po-accent) 65%, #e8d9b8);
  opacity: 0;
  animation: poFadeUp calc(var(--po-dur) * 0.2) ease calc(var(--po-s4) + var(--po-dur) * 0.11) forwards;
}

/* ─────────────────────────── netelaVeil ─────────────────────────────────
   A white netela — sheer cotton gauze with a woven tilet border along the
   centre seam — sways gently, the names glowing through the fabric, then the
   two halves part like a lifted veil. */

.po-netelaVeil .po-backdrop {
  background:
    radial-gradient(130% 110% at 50% 20%, #faf6ec 0%, #efe7d4 56%, #e2d6bc 100%);
}
.po-netelaVeil .po-vignette {
  background: radial-gradient(120% 120% at 50% 50%, transparent 58%, rgba(96, 78, 44, 0.26) 100%);
}
.po-nv-center {
  position: relative;
  z-index: 2;
  text-align: center;
  color: #33302a;
  animation: poNvClear calc(var(--po-dur) * 0.3) ease calc(var(--po-s3) + var(--po-dur) * 0.06) both;
}
@keyframes poNvClear {
  0% { filter: blur(5px); opacity: 0.62; }
  100% { filter: blur(0); opacity: 1; }
}
.po-nv-eyebrow {
  font-size: min(2vmin, 12px);
  letter-spacing: 0.44em;
  text-transform: uppercase;
  color: #7a6f55;
  opacity: 0;
  animation: poFadeUp calc(var(--po-dur) * 0.24) ease var(--po-s2) forwards;
}
.po-nv-names {
  margin-top: 1.8vmin;
  font-size: min(9vmin, 66px);
  line-height: 1.14;
  color: #2e2b24;
  opacity: 0;
  animation: poFadeUp calc(var(--po-dur) * 0.26) ease calc(var(--po-s2) + var(--po-dur) * 0.05) forwards;
}
.po-nv-rule {
  width: min(26vmin, 180px);
  height: 1px;
  margin: 2vmin auto 0;
  background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--po-accent) 80%, #6b5328), transparent);
  opacity: 0;
  animation: poFadeIn calc(var(--po-dur) * 0.24) ease calc(var(--po-s2) + var(--po-dur) * 0.1) forwards;
}
.po-nv-date {
  margin-top: 1.8vmin;
  font-size: min(2.2vmin, 13px);
  letter-spacing: 0.4em;
  text-transform: uppercase;
  color: #6e6446;
  opacity: 0;
  animation: poFadeUp calc(var(--po-dur) * 0.24) ease calc(var(--po-s2) + var(--po-dur) * 0.14) forwards;
}
.po-nv-half {
  position: absolute;
  top: -4%;
  bottom: -4%;
  width: 57%;
  z-index: 5;
  will-change: transform;
}
.po-nv-half.l {
  left: -3%;
  animation: poNvPartL calc(var(--po-dur) * 0.4) cubic-bezier(.45,.05,.3,1) var(--po-s3) forwards;
}
.po-nv-half.r {
  right: -3%;
  animation: poNvPartR calc(var(--po-dur) * 0.4) cubic-bezier(.45,.05,.3,1) var(--po-s3) forwards;
}
@keyframes poNvPartL {
  0% { transform: translateX(0) rotate(0); }
  45% { transform: translateX(-32%) rotate(-1.6deg); }
  100% { transform: translateX(-122%) rotate(-4.5deg); }
}
@keyframes poNvPartR {
  0% { transform: translateX(0) rotate(0); }
  45% { transform: translateX(32%) rotate(1.6deg); }
  100% { transform: translateX(122%) rotate(4.5deg); }
}
/* the cloth itself sways on a nested node so the part + sway compose */
.po-nv-cloth {
  position: absolute;
  inset: 0;
  background:
    repeating-linear-gradient(90deg, rgba(255, 255, 255, 0.5) 0 1px, transparent 1px 7px),
    repeating-linear-gradient(0deg, rgba(214, 203, 178, 0.16) 0 1px, transparent 1px 9px),
    linear-gradient(180deg, rgba(252, 250, 245, 0.93), rgba(248, 244, 234, 0.88));
  box-shadow: 0 0 40px rgba(120, 100, 60, 0.12) inset;
  animation: poNvSway 5.2s ease-in-out infinite alternate;
  transform-origin: top center;
}
.po-nv-half.r .po-nv-cloth { animation-delay: -2.6s; }
@keyframes poNvSway {
  0% { transform: skewX(0.4deg) translateX(-0.4%); }
  100% { transform: skewX(-0.5deg) translateX(0.5%); }
}
/* woven tilet border along the centre seam of each half + a fringe */
.po-nv-hem {
  position: absolute;
  top: 0;
  bottom: 0;
  width: clamp(26px, 5.4vmin, 46px);
  z-index: 2;
  box-shadow: 0 0 16px rgba(0, 0, 0, 0.14);
}
.po-nv-half.l .po-nv-hem { right: 0; }
.po-nv-half.r .po-nv-hem { left: 0; }
.po-nv-hem svg { width: 100%; height: 100%; display: block; }
.po-nv-fringe {
  position: absolute;
  top: 0;
  bottom: 0;
  width: clamp(10px, 2vmin, 18px);
  background: repeating-linear-gradient(0deg,
    rgba(240, 233, 216, 0.95) 0 6px, rgba(214, 201, 172, 0.9) 6px 8px, transparent 8px 12px);
}
.po-nv-half.l .po-nv-fringe { right: calc(clamp(26px, 5.4vmin, 46px) * -0.38); }
.po-nv-half.r .po-nv-fringe { left: calc(clamp(26px, 5.4vmin, 46px) * -0.38); }
.po-nv-light {
  position: absolute;
  inset: 0;
  z-index: 6;
  background: linear-gradient(112deg, transparent 34%, rgba(255, 252, 240, 0.5) 48%, transparent 60%);
  background-size: 230% 230%;
  mix-blend-mode: screen;
  pointer-events: none;
  animation: poRbSheen calc(var(--po-dur) * 0.7) linear var(--po-s1) both;
}

/* ─────────────────────────── reduced motion ───────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  .po-stage * { animation: none !important; }
  .po-stage { display: none !important; }
}
