/* =========================================================
   Preview & Share — envelope opening experience
   ========================================================= */

.preview-shell{ max-width: 900px; margin: 0 auto; padding: 40px clamp(16px,4vw,48px) 90px; text-align:center; }

.reveal-stage{
  position:relative; border-radius: var(--radius-l); overflow:hidden;
  min-height: 640px; box-shadow: var(--shadow-deep);
  display:flex; align-items:center; justify-content:center;
}
.reveal-fx{ position:absolute; inset:0; pointer-events:none; overflow:hidden; }

/* --- envelope --- */
.envelope{
  position:relative; width: 300px; height: 200px; cursor:pointer;
  filter: drop-shadow(0 18px 30px rgba(0,0,0,.25));
  transition: transform .4s var(--ease);
}
.envelope:hover{ transform: translateY(-4px) scale(1.02); }
.envelope-body{ position:absolute; inset:0; border-radius: 8px; }
.envelope-flap{
  position:absolute; top:0; left:0; width:100%; height:100%;
  clip-path: polygon(0 0, 50% 55%, 100% 0);
  transform-origin: top center; transition: transform 1s var(--ease);
  border-radius: 8px 8px 0 0;
}
.envelope.open .envelope-flap{ transform: rotateX(180deg); }
.envelope-seal{
  position:absolute; top: 46%; left:50%; transform: translate(-50%,-50%);
  width:44px; height:44px; border-radius:50%; display:flex; align-items:center; justify-content:center;
  font-size:1.2rem; color:#fff; box-shadow: 0 4px 10px rgba(0,0,0,.25); z-index:3;
  transition: opacity .4s var(--ease), transform .4s var(--ease);
}
.envelope.open .envelope-seal{ opacity:0; transform: translate(-50%,-50%) scale(0.4); }
.click-hint{
  position:absolute; bottom:-38px; left:0; right:0; text-align:center;
  font-size:0.85rem; color: var(--plum-quiet); animation: gentlePulse 2s ease-in-out infinite;
}
.envelope.open .click-hint{ display:none; }

/* --- side-by-side reveal: letter and bouquet appear together, at the
   same height, instead of two separately-floating absolute elements
   that used to overlap each other (the bouquet was literally rendering
   on top of the letter). --- */
.reveal-result{
  position:absolute; inset:0; z-index:5;
  display:flex; flex-wrap:wrap; align-items:stretch; justify-content:center;
  gap:28px; padding: 36px; box-sizing:border-box;
  opacity:0; pointer-events:none; transition: opacity .7s var(--ease);
}
.reveal-result.show{ opacity:1; pointer-events:auto; }

.pulled-letter{
  position:relative; flex:1 1 320px; max-width:400px;
  display:flex; align-items:center; justify-content:center;
}
.pulled-letter .paper-sheet{ width:100%; margin:0; align-self:center; }

/* the paper appears first; the words themselves fade up a beat later,
   so reading it feels like a small unfolding moment rather than a flat
   block of text appearing all at once */
#previewPaperText{ opacity:0; transform: translateY(10px); transition: opacity .7s var(--ease) .3s, transform .7s var(--ease) .3s; }
#previewPaperText.reveal-text{ opacity:1; transform: translateY(0); }

#previewPaperSheet{ cursor: pointer; }
.tap-heart{
  position:absolute; font-size:1.1rem; pointer-events:none; z-index:20;
  transform: translate(-50%,-50%);
  animation: tapHeartFloat 1.1s ease-out forwards;
}
@keyframes tapHeartFloat{
  0%{ opacity:0; transform: translate(-50%,-50%) scale(.5); }
  15%{ opacity:1; transform: translate(-50%,-50%) scale(1.1); }
  100%{ opacity:0; transform: translate(calc(-50% + var(--tx,0px)), -160%) scale(.9); }
}

/* --- bloom stage --- */
.bloom-stage{
  position:relative; flex:1 1 320px; max-width:420px; min-height:420px;
  display:flex; align-items:flex-end; justify-content:center;
}
.bloom-stage .bouquet-area{ position:absolute; inset:0; }
.grass-layer{
  position:absolute; left:50%; bottom:9%; transform:translateX(-50%);
  width: min(78%, 380px); z-index:8; pointer-events:none;
  opacity:0; animation: fadeIn 1s var(--ease) forwards; animation-delay:.3s;
}
.bloom-stage .stem-item{
  position:absolute; left:50%; bottom:9%; margin-left:-70px; opacity:0; transform: scale(.5);
  animation: bloomIn 0.9s var(--ease) forwards;
  cursor: pointer; pointer-events: auto; z-index:20;
}
.bloom-stage .stem-item svg{ width:140px; }
/* the fan angle + size are set once as CSS custom properties (--base-rot,
   --base-scale) by preview.js; the sway/wiggle keyframes below read them
   through calc() so the bouquet keeps its shape while still moving —
   this avoids fighting with the static inline transform that would
   otherwise be needed just to hold the fan angle in place. */
.bloom-stage .stem-item > div{
  transform-origin: bottom center;
  animation: stemSway 4.5s ease-in-out infinite;
  animation-delay: 0.9s;
  animation-fill-mode: backwards; /* shows the fanned angle immediately, not just after the delay */
}
@keyframes stemSway{
  0%,100%{ transform: rotate(calc(var(--base-rot) - 1.5deg)) scale(var(--base-scale)); }
  50%{ transform: rotate(calc(var(--base-rot) + 1.5deg)) scale(var(--base-scale)); }
}
.bloom-stage .stem-item.wiggle > div{ animation: stemWiggle 0.5s ease-in-out; }
@keyframes stemWiggle{
  0%,100%{ transform: rotate(var(--base-rot)) scale(var(--base-scale)); }
  25%{ transform: rotate(calc(var(--base-rot) - 8deg)) scale(var(--base-scale)); }
  75%{ transform: rotate(calc(var(--base-rot) + 8deg)) scale(var(--base-scale)); }
}
.bloom-stage .wrap-shape{ position:absolute; left:50%; bottom:0; transform: translateX(-50%); width:56%; height:27%; border-radius: 40% 40% 12px 12px / 60% 60% 12px 12px; }
.bloom-stage .ribbon-bow{ position:absolute; left:50%; bottom:10%; transform: translateX(-50%); width:88px; z-index:900; filter: drop-shadow(0 3px 5px rgba(0,0,0,.25)); }

@media (max-width: 680px){
  .reveal-result{ padding:20px; gap:16px; }
  .bloom-stage{ min-height:320px; }
}

.music-controls{
  position:absolute; top:18px; right:18px; z-index:10; display:flex; gap:8px;
}
.music-toggle, .music-add{
  width:44px; height:44px; border-radius:50%; background: rgba(255,255,255,.85);
  display:flex; align-items:center; justify-content:center; box-shadow: var(--shadow-soft);
  font-size: 0.95rem; transition: transform .2s var(--ease);
}
.music-toggle:hover, .music-add:hover{ transform: scale(1.06); }
.music-toggle[disabled]{ opacity:.45; pointer-events:none; }
.music-add.has-track{ background: var(--sage); color: #fff; }

/* --- post reveal actions --- */
.reveal-actions{ margin-top: 30px; display:flex; justify-content:center; gap:14px; flex-wrap:wrap; }

.share-panel{ margin-top: 56px; text-align:left; }
.share-link-row{ display:flex; gap:10px; margin: 16px 0 26px; flex-wrap:wrap; }
.support-nudge{
  text-align:center; margin-top: 34px; padding-top: 22px;
  border-top: 1px solid rgba(62,44,63,0.08);
  font-size: 0.9rem; color: var(--plum-quiet);
}
.support-nudge a{ color: var(--gold); font-weight: 600; }
.support-nudge a:hover{ text-decoration: underline; }
.share-link-row input{
  flex:1; min-width:220px; padding:14px 18px; border-radius:999px; border:1.5px solid rgba(62,44,63,.14);
  background: var(--white); font-size:0.88rem; color: var(--plum-quiet);
}
.share-icons{ display:grid; grid-template-columns: repeat(6,1fr); gap:12px; }
.share-icon{
  padding: 16px 10px; border-radius: var(--radius-m); text-align:center; font-size:0.78rem; color: var(--plum-quiet);
}
.share-icon .ic{ width:38px; height:38px; margin: 0 auto 8px; display:flex; align-items:center; justify-content:center; border-radius:50%; color:#fff; }

.save-actions{ display:flex; gap:12px; flex-wrap:wrap; margin-top:30px; }