/* ==========================================================================
   OMAR & RAGHDA — CLOSED ENVELOPE OPENING
   The supplied twine animation sits on an envelope cut from the same paper
   colour as the GIF. Pressing the seal unwinds the thread, then the whole
   envelope — flowers included — fades away into the invitation.
   ========================================================================== */

.envelope-page {
  min-height: 100vh;
  min-height: 100svh;
  margin: 0;
  display: grid;
  place-items: center;
  padding: clamp(1.5rem, 5vw, 3.5rem) var(--gutter);
  position: relative;
  overflow: hidden;
  background:
    radial-gradient(120% 90% at 12% 0%, #b8b9a8 0%, transparent 55%),
    radial-gradient(110% 100% at 92% 100%, #7c816e 0%, transparent 62%),
    linear-gradient(135deg, #a9aa9a 0%, #9a9c8b 46%, #8d907e 100%);
}

.envelope-page::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 0;
  background:
    repeating-linear-gradient(114deg, rgba(255, 255, 255, 0.05) 0 2px, transparent 2px 24px),
    var(--texture-paper);
  opacity: 0.55;
  mix-blend-mode: overlay;
  pointer-events: none;
}

.envelope-page.is-leaving .envelope-stage {
  opacity: 0;
  transform: translateY(-10px) scale(0.985);
  transition: opacity 900ms var(--ease-out), transform 900ms var(--ease-out);
}

/* ---------- loading gate ---------- */

html.js .envelope-stage {
  opacity: 0;
  visibility: hidden;
  transform: translateY(8px);
}

html.js.is-ready .envelope-stage {
  opacity: 1;
  visibility: visible;
  transform: none;
  transition:
    opacity 800ms var(--ease-out),
    transform 800ms var(--ease-out),
    visibility 0s;
}

html:not(.js) .envelope-loader { display: none; }

.envelope-loader {
  position: fixed;
  inset: 0;
  z-index: 20;
  display: grid;
  place-content: center;
  justify-items: center;
  gap: 16px;
  text-align: center;
  transition: opacity 500ms var(--ease-out), visibility 0s 500ms;
}

html.is-ready .envelope-loader {
  opacity: 0;
  visibility: hidden;
}

.envelope-loader img {
  width: 46px;
  height: auto;
  opacity: 0.92;
  filter: drop-shadow(0 8px 12px rgba(40, 34, 22, 0.28));
  animation: loader-breathe 1.9s ease-in-out infinite;
}

.envelope-loader p {
  margin: 0;
  font-family: var(--font-serif);
  font-size: clamp(0.58rem, 1.4vw, 0.66rem);
  font-weight: 700;
  letter-spacing: 0.28em;
  text-indent: 0.28em;
  text-transform: uppercase;
  color: rgba(251, 243, 226, 0.78);
}

.envelope-loader__line {
  display: block;
  position: relative;
  width: 124px;
  height: 1px;
  overflow: hidden;
  background: rgba(251, 243, 226, 0.16);
}

.envelope-loader__line::after {
  content: "";
  position: absolute;
  inset-block: 0;
  left: -45%;
  width: 45%;
  background: linear-gradient(90deg, transparent, rgba(251, 243, 226, 0.7), transparent);
  animation: loader-scan 1.5s ease-in-out infinite;
}

@keyframes loader-breathe {
  0%, 100% { transform: scale(1); opacity: 0.92; }
  50% { transform: scale(1.06); opacity: 1; }
}

@keyframes loader-scan {
  to { left: 100%; }
}

.skip-link {
  position: absolute;
  top: 12px;
  left: 12px;
  z-index: 10;
  padding: 10px 14px;
  background: var(--paper-50);
  color: var(--ink-900);
  font-family: var(--font-serif);
  font-size: 0.68rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  text-decoration: none;
  transform: translateY(-160%);
  transition: transform var(--dur-fast) var(--ease-out);
}
.skip-link:focus-visible { transform: none; outline: 2px solid var(--sage-700); outline-offset: 3px; }

.envelope-stage {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: 620px;
  display: grid;
  justify-items: center;
  gap: clamp(1.5rem, 4vw, 2.25rem);
}

/* ---------- envelope ---------- */

.envelope {
  position: relative;
  width: min(420px, 82vw);
  aspect-ratio: 3 / 4;
  /* sampled from the GIF's left and right edges, top to bottom */
  background: linear-gradient(
    180deg,
    #efede5 0%,
    #ece9e4 20%,
    #e7e4dc 40%,
    #e2dfd7 60%,
    #dcd9d1 80%,
    #d6d0c6 100%
  );
  border-radius: 2px;
  border: 1px solid rgba(80, 64, 42, 0.14);
  filter: drop-shadow(0 30px 48px rgba(48, 38, 24, 0.28))
          sepia(0.08) saturate(1.06) brightness(1.01);
  animation: envelope-arrive 1s var(--ease-out) both;
  overflow: hidden;
}

/* the folded flap, seen from the back — drawn as a crease on the same paper */
.envelope__seam {
  position: absolute;
  inset: 0;
  z-index: 3;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

/* ---------- twine animation ---------- */

.envelope__twine {
  position: absolute;
  left: 50%;
  top: 50%;
  z-index: 2;
  height: 100%;
  width: auto;
  max-width: none;
  transform: translate(-50%, -50%);
  pointer-events: none;
  user-select: none;
}

/* the last frame, laid over the GIF so its loop never flashes */
.envelope__end {
  position: absolute;
  left: 50%;
  top: 50%;
  z-index: 3;
  height: 100%;
  width: auto;
  max-width: none;
  transform: translate(-50%, -50%);
  opacity: 0;
  pointer-events: none;
  user-select: none;
  transition: opacity 300ms ease;
}

.envelope__end.is-visible { opacity: 1; }

/* unify the GIF's paper with the envelope's flat paper */
.envelope__grain {
  position: absolute;
  inset: 0;
  z-index: 4;
  background-image:
    repeating-linear-gradient(0deg, rgba(121, 100, 68, 0.035) 0 1px, transparent 1px 5px),
    radial-gradient(120% 80% at 18% 8%, rgba(255, 252, 244, 0.34), transparent 58%),
    var(--texture-paper);
  opacity: 0.24;
  mix-blend-mode: multiply;
  pointer-events: none;
}

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

.envelope__seal {
  display: block;
  position: absolute;
  left: 50%;
  top: 49.5%;
  z-index: 5;
  width: clamp(74px, 23%, 100px);
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  transform: translate(-50%, -50%);
  cursor: pointer;
  filter: drop-shadow(0 14px 16px rgba(40, 43, 32, 0.3));
  transition:
    transform 420ms var(--ease-out),
    opacity 420ms var(--ease-out),
    filter 420ms var(--ease-out);
}

.envelope__seal img {
  display: block;
  width: 100%;
  height: auto;
}

.envelope__seal:hover {
  transform: translate(-50%, -50%) scale(1.035);
  filter: drop-shadow(0 18px 20px rgba(40, 43, 32, 0.34));
}
.envelope__seal:active { transform: translate(-50%, -50%) scale(0.97); }

.envelope__seal:focus-visible {
  outline: 2px solid var(--paper-100);
  outline-offset: 7px;
  border-radius: 50%;
}

.envelope__seal.is-gone {
  opacity: 0;
  transform: translate(-50%, -50%) scale(0.9) rotate(-5deg);
  filter: drop-shadow(0 6px 8px rgba(40, 43, 32, 0.15));
  pointer-events: none;
}

/* ---------- captions ---------- */

.envelope__hint {
  margin: 0;
  font-family: var(--font-serif);
  font-size: clamp(0.6rem, 1.4vw, 0.7rem);
  font-weight: 700;
  letter-spacing: 0.28em;
  text-indent: 0.28em;
  text-transform: uppercase;
  color: rgba(251, 243, 226, 0.9);
}

.envelope__names {
  margin: 0;
  font-family: var(--font-script);
  font-size: clamp(1.35rem, 4vw, 1.8rem);
  line-height: 1.1;
  color: rgba(251, 243, 226, 0.96);
  text-align: center;
}

.envelope__names span {
  display: block;
  margin-top: 0.55rem;
  font-family: var(--font-serif);
  font-size: clamp(0.52rem, 1.2vw, 0.6rem);
  font-weight: 700;
  letter-spacing: 0.3em;
  text-indent: 0.3em;
  text-transform: uppercase;
  color: rgba(251, 243, 226, 0.62);
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

@keyframes envelope-arrive {
  from { opacity: 0; transform: translateY(22px) scale(0.985); }
  to { opacity: 1; transform: none; }
}

@media (max-width: 480px) {
  .envelope-page { align-content: start; padding-top: clamp(3.5rem, 12vh, 6rem); }
  .envelope { width: min(360px, 84vw); }
}

@media (prefers-reduced-motion: reduce) {
  .envelope { animation: none; }
  .envelope,
  .envelope__seal,
  .envelope__twine,
  .envelope-stage { transition-duration: 1ms; }
  .envelope-loader img,
  .envelope-loader__line::after { animation: none; }
}
