/* The envelope that opens in the home page's hero, as
 * docs/redesign/prototype/Envelope.dc.html draws it, at the prototype's own
 * 520 by 560 pixels. The stage keeps those exact numbers and is scaled as a
 * whole to fit its frame, so every offset, the rise of the card and the
 * 180 degree turn of the flap stay identical to the source at any width.
 * A design's paper, lining, wax and card arrive as custom properties from
 * envelope.js.
 */

.ev-frame {
  position: relative;
  width: 100%;
  aspect-ratio: 520 / 560;
  overflow: hidden;
  border-radius: 6px;
  background: #2A211C;
  box-shadow: var(--shadow-lift);
  contain: layout paint;
}

.ev-stage {
  position: absolute;
  left: 0;
  top: 0;
  width: 520px;
  height: 560px;
  overflow: hidden;
  transform-origin: 0 0;
  transform: scale(var(--ev-scale, 1));
  transition: opacity var(--dur-ui) var(--ease-out);
}
.ev-stage.is-leaving { opacity: 0; }
.ev-backdrop { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }

/* Layers, back to front: body, lining, card, pocket, fold shading, wax, flap.
   Once the flap passes ninety degrees it drops behind the card, and once the
   card is clear of the pocket it is lifted in front of everything. */
.ev-rig {
  position: absolute;
  left: 90px;
  top: 292px;
  width: 340px;
  height: 236px;
  animation: ev-settle 1s var(--ease-out) both;
}
@keyframes ev-settle { from { transform: translateY(40px) rotate(-5deg) scale(.96); opacity: 0; } to { transform: none; opacity: 1; } }
.ev-body {
  position: absolute;
  inset: 0;
  border-radius: 4px;
  z-index: 0;
  background: var(--ev-paper-dark);
  box-shadow: 0 4px 5px rgb(0 0 0 / .22), 0 8px 14px rgb(0 0 0 / .12), 0 2px 3px rgb(0 0 0 / .10);
}
.ev-lining {
  position: absolute;
  inset: 0;
  border-radius: 4px;
  z-index: 1;
  clip-path: polygon(0 0, 100% 0, 50% 58%);
  background-image: var(--ev-liner);
  background-size: 150px;
}
.ev-slot { position: absolute; inset: 0; z-index: 2; clip-path: inset(-700px 0 0 0); animation: ev-front .01s linear 3.55s forwards; }
@keyframes ev-front { to { z-index: 8; clip-path: inset(-700px -200px -200px -200px); } }
.ev-card {
  position: absolute;
  left: 70px;
  top: 16px;
  width: 200px;
  height: 284px;
  margin: 0;
  border-radius: 2px;
  overflow: hidden;
  box-shadow: 0 8px 20px -10px rgb(0 0 0 / .4);
  animation: ev-rise 1.05s var(--ease-in-out) 2.45s both, ev-present 1.2s var(--ease-out) 3.6s forwards;
}
.ev-card img { width: 100%; height: 100%; object-fit: cover; object-position: top; }
/* A composed card (site.css) fills the same 200 by 284 slot a plain card
   image would, its own 640 by 900 aspect-ratio overridden so it never gaps
   at the bottom or grows past the figure that clips it. */
.ev-card .card-composed { width: 100%; height: 100%; aspect-ratio: auto; }
@keyframes ev-rise { from { transform: none; } to { transform: translateY(-292px); } }
@keyframes ev-present {
  from { transform: translateY(-292px); }
  to { transform: translateY(-236px) scale(1.14); box-shadow: 0 36px 70px -28px rgb(0 0 0 / .6); }
}
.ev-pocket {
  position: absolute;
  inset: 0;
  border-radius: 4px;
  z-index: 3;
  background: var(--ev-paper);
  clip-path: polygon(0 0, 50% 58%, 100% 0, 100% 100%, 0 100%);
}
.ev-grain {
  position: absolute;
  inset: 0;
  border-radius: 4px;
  z-index: 4;
  opacity: .26;
  mix-blend-mode: multiply;
  background-image: url("/site/img/m-grain.webp");
  background-size: cover;
  clip-path: polygon(0 0, 50% 58%, 100% 0, 100% 100%, 0 100%);
  pointer-events: none;
}
.ev-fold {
  position: absolute;
  inset: 0;
  border-radius: 4px;
  z-index: 4;
  clip-path: polygon(0 0, 50% 58%, 100% 0, 100% 100%, 0 100%);
  background: linear-gradient(160deg, rgb(0 0 0 / .07), rgb(0 0 0 / 0) 34%), linear-gradient(200deg, rgb(0 0 0 / .07), rgb(0 0 0 / 0) 34%);
}

/* The flap turns toward the reader about its top edge through 180 degrees,
   on a long lens as in frontend/invite/stationery.css, so the point lifts
   without the near edge sagging at the camera. The drop shadow flattens the
   flap, which is why its faces and the wax are swapped by opacity at the
   moment it is edge on. */
.ev-flap {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  height: 60%;
  z-index: 6;
  transform-origin: 50% 0;
  filter: drop-shadow(0 2px 3px rgb(0 0 0 / .18));
  animation: ev-open 1.2s cubic-bezier(.34, .02, .22, 1) 1.3s both;
}
@keyframes ev-open {
  0% { transform: perspective(5000px) rotateX(0deg); z-index: 6; }
  32.6% { z-index: 6; }
  33.4% { z-index: 1; }
  100% { transform: perspective(5000px) rotateX(180deg); z-index: 1; }
}
.ev-flap-out, .ev-flap-in { position: absolute; inset: 0; clip-path: polygon(0 0, 100% 0, 50% 100%); }
.ev-flap-out { background: var(--ev-paper-flap); animation: ev-face-off 1.2s linear 1.3s both; }
.ev-flap-in {
  opacity: 0;
  background-image: var(--ev-liner);
  background-size: 150px;
  filter: brightness(.94);
  animation: ev-face-on 1.2s linear 1.3s both;
}
/* The flap's curve reaches ninety degrees at 33 percent of its time, not
   halfway, so the faces and the wax swap there. */
@keyframes ev-face-off { 0%, 32.6% { opacity: 1; } 33.4%, 100% { opacity: 0; } }
@keyframes ev-face-on { 0%, 32.6% { opacity: 0; } 33.4%, 100% { opacity: 1; } }

/* The wax sits on the flap's point and goes where the point goes. Once the
   flap is past ninety degrees its outer face, and the pressed side of the
   wax, face away from the reader. What is still seen is the wax around the
   point, from behind: plain, a little darker, and cut by the flap's own two
   edges, which meet at the point with a slope of 1.2 across to 1 down. */
.ev-seal {
  position: absolute;
  left: 50%;
  top: 100%;
  width: 66px;
  height: 66px;
  transform: translate(-50%, -50%);
  animation: ev-press .5s var(--ease-out) .8s both;
}
@keyframes ev-press {
  0% { transform: translate(-50%, -50%) scale(1); }
  40% { transform: translate(-50%, -50%) scale(1.06); }
  100% { transform: translate(-50%, -50%) scale(1); }
}
.ev-seal-a, .ev-seal-b { position: absolute; inset: 0; }
.ev-seal-a { animation: ev-face-off 1.2s linear 1.3s both; }
.ev-seal-b {
  opacity: 0;
  clip-path: polygon(0 5.5%, 50% 50%, 100% 5.5%, 100% 100%, 0 100%);
  filter: brightness(.78) saturate(.85);
  animation: ev-face-on 1.2s linear 1.3s both;
}
.ev-wax {
  position: absolute;
  inset: 0;
  background-image: var(--ev-seal);
  background-size: 100% 100%;
  filter: drop-shadow(0 3px 3px rgb(0 0 0 / .32));
}
.ev-mono {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-display);
  font-style: italic;
  font-size: 16px;
  color: var(--ev-mono-ink, rgb(255 238 232 / .82));
  text-shadow: 0 -1px 0 rgb(0 0 0 / .35);
}
.ev-sweep {
  position: absolute;
  inset: 0;
  background: linear-gradient(115deg, rgb(255 255 255 / 0) 38%, rgb(255 255 255 / .5) 50%, rgb(255 255 255 / 0) 62%);
  background-size: 260% 100%;
  background-position: 120% 0;
  animation: ev-sweep 1.4s var(--ease-in-out) 4.9s both;
}
@keyframes ev-sweep { to { background-position: -120% 0; } }

/* Under reduced motion the envelope is shown already open, with the card
   presented, which is the state the animation ends in. */
@media (prefers-reduced-motion: reduce) {
  .ev-stage * { animation: none !important; }
  .ev-stage { transition: none; }
  .ev-flap { transform: perspective(5000px) rotateX(180deg); z-index: 1; }
  .ev-seal-a, .ev-flap-out { opacity: 0; }
  .ev-seal-b, .ev-flap-in { opacity: 1; }
  .ev-slot { z-index: 8; clip-path: none; }
  .ev-card { transform: translateY(-236px) scale(1.14); }
}
