    :root {
      --sage:       #7D9B76;
      --sage-dark:  #5C7A55;
      --sage-light: #A8C4A2;
      --sage-pale:  #E8F0E6;
      --cream:      #FAF6EF;
      --gold:       #C8A96E;
      --shadow:     rgba(80,100,78,0.28);
    }


/*

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html, body { width: 100%; height: 100%; overflow: hidden; background: #18160F; }

*/

#outer-wrap {/*
  position: fixed; inset: 0; z-index: 5;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  text-align: center; /* padding: 2rem; */
  /* Start tiny (letter-sized) and invisible */
  transform-origin: center center;
  transform: scale(0.18);
  opacity: 0;
  pointer-events: none;
  /* Zoom transition — runs after letter is out */
  transition: transform 0s, opacity 0s;
}
#outer-wrap::before {
  content: ''; position: absolute; inset: 0; pointer-events: none;/*
  background:
    radial-gradient(ellipse 70% 60% at 50% 50%, transparent 55%, rgba(139,152,120,.07) 100%),
    radial-gradient(ellipse 40% 35% at 50% 50%, transparent 70%, rgba(139,152,120,.05) 100%);*/
}
#outer-wrap.zoom-in {
  transition: transform 0.7s cubic-bezier(0.22, 1, 0.36, 1), opacity 0.4s ease;
  transform: scale(1) translateY(0);
  opacity: 1;
  pointer-events: auto;
}

    .ws-title {
      font-family: 'Great Vibes', cursive;
      font-size: clamp(2rem,10vw,10rem);
      color: var(--sage-dark); line-height: 2.2;
    }

    .ws-divider {
      width: 180px; height: 2px;
      background: linear-gradient(to right, transparent, var(--gold), transparent);
      margin: .8rem auto;
    }
    .ws-sub {
      font-family: 'Cormorant Garamond', serif;
      font-size: clamp(1.7rem,3.2vw,2.2rem);
      letter-spacing: .5em; color: var(--sage); text-transform: uppercase;
    }
    .ws-date {
      font-family: 'Great Vibes', cursive;
      font-size: clamp(3.6rem,8vw,6rem); color: var(--gold); margin-top: .6rem;
    }
    .ws-note {
      font-family: 'Cormorant Garamond', serif;
      font-size: clamp(2rem,2.4vw,3rem);
      color: #aaa; letter-spacing: .15em; text-transform: uppercase; margin-top: 2rem;
    }

/* ══════════════════════════════════════
   OVERLAY
══════════════════════════════════════ */
#overlay {
  position: fixed; inset: 0; z-index: 20;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  background: radial-gradient(ellipse at 50% 45%, #2B2820 0%, #18160F 100%);
  cursor: pointer;
  transition: opacity 0.9s ease;
  z-index: 999999999999;
}
#overlay.fade-out { opacity: 0; pointer-events: none; }
#overlay::before {
  content:''; position:absolute; inset:0; pointer-events:none;
  background-image:url("data:image/svg+xml,%3Csvg width='4' height='4' viewBox='0 0 4 4' xmlns='http://www.w3.org/2000/svg'%3E%3Crect x='0' y='0' width='1' height='1' fill='%23ffffff05'/%3E%3C/svg%3E");
}

#hint {
  position:absolute; bottom:8%; left:0; right:0; text-align:center;
  font-family:'Cormorant Garamond',serif; font-style:italic;
  font-size:30px; letter-spacing:.14em; color:rgba(181,168,130,.45);
  animation:breathe 3s ease-in-out infinite; transition:opacity .4s;
}
#hint.hide { opacity:0 !important; animation:none; }
@keyframes breathe {
  0%,100% { opacity:.35; transform:translateY(0); }
  50%      { opacity:.85; transform:translateY(-5px); }
}

/* ══════════════════════════════════════
   ENVELOPE
   Shadow on a static wrapper — never
   repaints during animation.
══════════════════════════════════════ */
#env-wrap {
  position: relative;
  width: min(82vw, 520px);
}

#env-svg {
  width: 100%; height: auto;
  display: block; overflow: visible;
  /* Shadow on static element — not repainted per frame */
  filter: drop-shadow(0 18px 50px rgba(0,0,0,.8)) drop-shadow(0 4px 12px rgba(0,0,0,.5));
}

#env-svg>rect, #env-svg>polygon, #env-svg>line, #env-svg>g {
  -webkit-transition: -webkit-transform .75s ease;
  -moz-transition:    -moz-transform .75s ease;
  -o-transition:      -o-transform .75s ease;
  -ms-transition:     -ms-transform .75s ease;
  transition:         transform .75s ease;
  transform-origin: 30% 30%;
}

#env-svg.move>rect, #env-svg.move>polygon, #env-svg.move>line, #env-svg.move>g {
  transform: translateY(30px) rotate(10deg) ;
}



/* ══════════════════════════════════════
   LETTER CARD (real site div, miniaturized)
   Sits inside the SVG coordinate space via
   a foreignObject, clipped to envelope interior.
   On open: clip removed, letter rises, then zooms.
══════════════════════════════════════ */

#letter-card {
  width: 100%; height: 100%;
  background: #F5EEE2;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  text-align: center;
  padding: 8%;
  overflow: hidden;
  /* transition for the rise — applied by JS */
  will-change: transform;
}

/* Scaled-down typography inside the letter card */
    #letter-card .ws-title {
      font-size: clamp(1.2rem,8vw,4rem);
      line-height: 1.76;
    }

    #letter-card .ws-divider {
      width: 180px; height: 2px;
      margin: .8rem auto;
    }
    #letter-card .ws-sub {
      font-size: clamp(1.36rem,1.4vw,1.4rem);
      letter-spacing: .2em;
    }
    #letter-card .ws-date {
      font-size: clamp(3rem,3.4vw,3rem);
      margin-top: .6rem;
    }
    #letter-card .ws-note {
      font-size: clamp(1.2rem,1.8vw,1.8rem);
      color: #aaa; letter-spacing: .15em;
      margin-top: 2rem;
    }


/* ══════════════════════════════════════
   FLAP GROUP — animated via JS setAttribute
   on SVG polygon points. Drop-shadow is on
   the static #env-wrap, so this is cheap.
   (No CSS scaleY — broken on mobile Safari)
══════════════════════════════════════ */

/* ══ Particles ══ */
.particle {
  position:fixed; border-radius:50%; pointer-events:none; opacity:0;
  will-change: transform, opacity;
  animation:float-up linear infinite;
}
@keyframes float-up {
  0%   { transform:translateY(0) translateX(0); opacity:0; }
  12%  { opacity:.5; }
  88%  { opacity:.12; }
  100% { transform:translateY(-100vh) translateX(calc(var(--drift)*1px)); opacity:0; }
}