:root {
  --ink: #3a1a12;
  --gold: #b98a3e;
  --gold-light: #e8c987;
  --ivory: #fbf3e4;
}

* { box-sizing: border-box; margin: 0; }

html, body {
  height: 100%;
  overflow: hidden;
  background: #16040a;
}

#stage {
  position: fixed;
  inset: 0;
  overflow: hidden;
  background: linear-gradient(#22040c, #4a0a1a 50%, #1a0208);
  cursor: pointer;
  outline: none;
  -webkit-tap-highlight-color: transparent;
  user-select: none;
}

/* Sits above the canvas: the card only appears once the curtains have gone */
.backdrop {
  position: absolute;
  inset: 0;
  z-index: 2;
  display: grid;
  place-items: center;
  padding: 21vh 0 5vh;
  padding: 21dvh 0 5dvh;
}

/* A phone on its side is too short for the card, so the card scrolls */
@media (orientation: landscape) and (max-height: 500px) {
  .backdrop { place-items: start center; }
  .is-open .backdrop { overflow-y: auto; }
  #stage .hanging { z-index: 1; }
}

.card {
  position: relative;
  z-index: 1;
  --card-width: min(74vw, 330px);
  width: var(--card-width);
  padding: 74px 14px 44px;
  text-align: center;
  color: var(--gold-light);
  font-family: "Cormorant Garamond", Georgia, serif;
  text-shadow: 0 2px 10px rgba(0, 0, 0, .6);
}

.arch {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
  fill: none;
  stroke: var(--gold-light);
  opacity: .75;
}

.arch path {
  stroke-width: 1px;
  vector-effect: non-scaling-stroke;
}

.arch path + path { opacity: .45; }

/* Spreads from the top of the arch down both sides */
.arch { clip-path: circle(0 at 50% 0); }
.is-open .arch { animation: trace 2.8s cubic-bezier(.5, 0, .2, 1) forwards; }

@keyframes trace {
  to { clip-path: circle(150% at 50% 0); }
}

.card-inner > * { opacity: 0; }

.is-open .card-small,
.is-open .card-line,
.is-open .card-date,
.is-open .card-venue {
  animation: settle 1.1s cubic-bezier(.2, .7, .2, 1) forwards;
}

.is-open .card-small { animation-delay: .5s; }
.is-open .card-line { animation-delay: 2.1s; }
.is-open .card-date { animation-delay: 2.7s; }
.is-open .card-venue { animation-delay: 2.95s; }
.is-open .sample { animation: settle 1.1s ease 3.2s forwards; }

@keyframes settle {
  from { opacity: 0; transform: translateY(14px); letter-spacing: .24em; filter: blur(4px); }
  to { opacity: 1; transform: none; filter: none; }
}

.card-small,
.card-venue {
  font-size: 11px;
  letter-spacing: .06em;
  text-transform: uppercase;
}

.card-names {
  margin: 18px 0;
  font-family: "Great Vibes", "Snell Roundhand", cursive;
  /* --chars is the longer name's length: long names shrink to stay inside the arch */
  font-size: min(clamp(42px, 12.5vw, 54px), calc(var(--card-width) * .84 / (var(--chars) * .38 + .4)));
  font-weight: 400;
  line-height: 1.15;
}

.is-open .card-names { opacity: 1; }

/* Gold foil: each name is unveiled left to right, then light runs across it */
.name {
  display: block;
  width: fit-content;
  margin: 0 auto;
  padding: 0 .2em;
  color: transparent;
  background: linear-gradient(100deg, #b4853a 20%, #f4dfae 42%, #fff8e3 50%, #f4dfae 58%, #b4853a 80%) 100% 0 / 280% 100%;
  -webkit-background-clip: text;
  background-clip: text;
  text-shadow: none;
  filter: drop-shadow(0 2px 6px rgba(0, 0, 0, .55));
  clip-path: inset(-20% 100% -20% 0);
}

.is-open .name {
  animation:
    unveil 1.3s cubic-bezier(.6, 0, .2, 1) .8s forwards,
    foil 2.4s ease-in-out 1.5s forwards;
}

.is-open .name.second { animation-delay: 1.45s, 2.15s; }

@keyframes unveil {
  to { clip-path: inset(-20% -5% -20% -5%); }
}

@keyframes foil {
  to { background-position: 0 0; }
}

.amp {
  display: block;
  font-size: .62em;
  color: var(--gold-light);
  opacity: 0;
}

.is-open .amp { animation: bloom .9s cubic-bezier(.2, 1.5, .4, 1) 1.2s forwards; }

@keyframes bloom {
  from { opacity: 0; transform: scale(.3) rotate(-30deg); }
  to { opacity: 1; transform: none; }
}

.card-line {
  font-size: 17px;
  line-height: 1.35;
}

.card-rule {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 18px 22px;
  color: var(--gold-light);
  font-size: 12px;
}

.is-open .card-rule { animation: open-rule 1s cubic-bezier(.2, .7, .2, 1) 2.4s forwards; }

@keyframes open-rule {
  from { opacity: 0; transform: scaleX(.1); }
  to { opacity: 1; transform: none; }
}

.card-rule::before,
.card-rule::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--gold-light);
}

.sample {
  margin-top: 10px;
  font-size: 10px;
  letter-spacing: .08em;
  opacity: 0;
}

.card-date {
  font-size: 22px;
  font-weight: 500;
}

.card-venue {
  margin-top: 6px;
}

.hanging {
  position: absolute;
  z-index: 2;
  transform-origin: 50% 0;
  animation: sway 7s ease-in-out infinite;
  pointer-events: none;
}

.hanging[hidden] { display: none; }

.hanging img {
  position: relative;
  display: block;
  width: 100%;
  height: 100%;
}

.hanging-glow {
  position: absolute;
  inset: -55%;
  background: radial-gradient(closest-side, rgba(255, 200, 130, .5), transparent 72%);
  animation: flicker 3.1s ease-in-out infinite;
}

@keyframes sway {
  0%, 100% { transform: rotate(0); }
  25% { transform: rotate(1.3deg); }
  75% { transform: rotate(-1.3deg); }
}

@keyframes flicker {
  0%, 100% { opacity: .75; }
  30% { opacity: 1; }
  55% { opacity: .68; }
  80% { opacity: .92; }
}

#curtain {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

.prompt {
  position: absolute;
  left: 50%;
  top: 56%;
  display: grid;
  justify-items: center;
  gap: 16px;
  transform: translateX(-50%);
  color: var(--gold-light);
  font-family: "Cormorant Garamond", Georgia, serif;
  font-size: 30px;
  text-shadow: 0 2px 10px rgba(0, 0, 0, .7);
  white-space: nowrap;
  pointer-events: none;
  transition: opacity .4s ease;
}

.prompt-label {
  display: flex;
  align-items: center;
  gap: 12px;
}

.prompt-label::before,
.prompt-label::after {
  content: "";
  width: 34px;
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--gold-light));
}

.prompt-label::after { transform: scaleX(-1); }

.ring {
  width: 34px;
  height: 34px;
  border: 1px solid var(--gold-light);
  border-radius: 50%;
  animation: pulse 2s ease-out infinite;
}

@keyframes pulse {
  0% { transform: scale(.7); opacity: 1; }
  100% { transform: scale(1.5); opacity: 0; }
}

.is-tapped .prompt { opacity: 0; }

/* CSS fallback */
/* Two halves of the closed-curtain frame: the first paint, the loading state,
   and the opening itself when WebGL isn't available */
.fallback-curtain {
  display: none;
  position: absolute;
  top: 0;
  bottom: 0;
  width: 50.5%;
  background: url(assets/poster.webp) no-repeat 0 0 / 198% 100%;
  transition: transform 2.2s cubic-bezier(.65, 0, .35, 1);
}

.fallback-curtain.left { left: 0; }
.fallback-curtain.right { right: 0; background-position: 100% 0; }

.use-fallback .fallback-curtain { display: block; }
.use-fallback #curtain { display: none; }
#stage.use-fallback.is-tapped {
  background: #16040a url(assets/final.webp) center / cover no-repeat;
}
/* final.webp is phone-shaped: past that, keep all of it and let velvet carry on either side */
@media (min-aspect-ratio: 2 / 3) {
  #stage.use-fallback.is-tapped {
    background: url(assets/final.webp) center / auto 100% no-repeat, #2a0509 url(assets/velvet.webp) center / 100% auto;
  }
}
.use-fallback.is-tapped .fallback-curtain.left { transform: translateX(-102%); }
.use-fallback.is-tapped .fallback-curtain.right { transform: translateX(102%); }

@media (prefers-reduced-motion: reduce) {
  .fallback-curtain { transition-duration: .01s; }
  .ring, .hanging, .hanging-glow { animation: none; }
  .is-open .arch,
  .is-open .card-inner *,
  .is-open .name,
  .is-open .amp {
    animation-duration: .01s;
    animation-delay: 0s;
  }
}

#stats {
  position: absolute;
  left: 8px;
  bottom: 8px;
  padding: 4px 8px;
  background: rgba(0, 0, 0, .7);
  color: #9f9;
  font: 12px/1.3 ui-monospace, monospace;
}

.fallback-curtain { z-index: 3; }
.prompt, #stats { z-index: 4; }

/* The card grows with the room it has. zoom keeps its px text and arch in step. */
@media (min-width: 700px) and (min-height: 860px) {
  .card { zoom: 1.2; }
}

@media (min-width: 700px) and (min-height: 1000px) {
  .card { zoom: 1.4; }
}

/* Once the opening is over the stage becomes the first screen of a normal page.
   svh, not dvh: the address bar hiding during a scroll must not move the card. */
.is-page,
.is-page body {
  height: auto;
  overflow: visible;
}

.is-page #stage {
  position: relative;
  height: 100vh;
  height: 100svh;
  cursor: auto;
  user-select: auto;
}

.is-page .backdrop {
  padding: 21vh 0 5vh;
  padding: 21svh 0 5svh;
}

.is-away .hanging,
.is-away .hanging-glow { animation-play-state: paused; }

/* Short laptops: lift the card clear of the bottom edge */
@media (min-width: 900px) and (max-height: 760px) {
  .card { zoom: .88; }
  .backdrop, .is-page .backdrop { padding-top: 15vh; }
}
