:root {
  --blush: #FAE6EB;
  --rose-soft: #EDB9C8;
  --rose: #D8869F;
  --rose-deep: #A8405F;
  --sage: #9DB59A;
  --sage-deep: #4D6B49;
  --ink: #3A2F33;
  --muted: #6C5C62;
  --line: #DFCBA5;
  --gold: #C2A063;
  --card: #FFFBF4;
}

* { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: #DDB6B9 linear-gradient(180deg, #EEDAD3 0, #E3C2C3 55%, #DDB6B9 100%) no-repeat;
  color: var(--ink);
  font-family: "Nunito Sans", system-ui, -apple-system, "Segoe UI", sans-serif;
  font-size: 19px;
  line-height: 1.5;
}

.hero { padding: 0; }

.frame {
  position: relative;
  width: 100%;
  max-width: 520px;
  margin: 0 auto;
  aspect-ratio: 9 / 16;
  container-type: inline-size;
  border-radius: 0;
  overflow: hidden;
  background: #F3E3DF;
  box-shadow: 0 10px 26px rgba(110, 50, 65, .28);
}
@media (min-width: 521px) {
  .hero { padding: 16px 14px 0; }
  .frame { max-width: 440px; border-radius: 26px; }
}
/* the animated card: a looping video, with a still picture shown until it loads */
.frame .art { position: absolute; inset: 0; width: 100%; height: 100%; display: block; object-fit: cover; pointer-events: none; }

/* the words sit on the plain panel inside the arch, above the couple */
.frame .text {
  position: absolute;
  left: 26%;
  right: 26%;
  top: 19.8%;
  text-align: center;
}

.eyebrow {
  margin: 0 0 1.2cqw;
  font-size: 10px;
  font-size: max(10px, 2.75cqw);
  line-height: 1.3;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--sage-deep);
  font-weight: 700;
}

.names {
  margin: 0;
  font-family: "Pinyon Script", "Snell Roundhand", cursive;
  font-weight: 400;
  font-size: 38px;
  font-size: 10.6cqw;
  line-height: 1;
  white-space: nowrap;
  color: var(--rose-deep);
}
.names .n1, .names .n2, .names .amp { display: block; }
.names .n1, .names .n2 { padding: .08em 0; }
.names .amp {
  font-family: "Playfair Display", Georgia, serif;
  font-style: italic;
  font-size: .42em;
  line-height: 1;
  color: var(--sage-deep);
}

.lead { margin: 1.4cqw 0 0; color: var(--muted); font-size: 12px; font-size: max(11.5px, 3.3cqw); white-space: nowrap; }

.occasion {
  margin: 0;
  font-family: "Lora", Georgia, serif;
  font-weight: 600;
  font-size: 29px;
  font-size: 8cqw;
  line-height: 1.25;
  letter-spacing: .05em;
  color: var(--sage-deep);
}

/* a guest's own invitation greets them by name */
.eyebrow.is-name {
  font-family: "Playfair Display", Georgia, serif;
  font-style: italic;
  font-weight: 400;
  font-size: 12px;
  font-size: max(11.5px, 3.2cqw);
  line-height: 1.25;
  letter-spacing: 0;
  text-transform: none;
  color: var(--rose-deep);
  max-width: 33cqw;
  margin-left: auto;
  margin-right: auto;
  text-wrap: balance;
}
.frame.has-name .text { top: 19.8%; }
.frame.has-name .names { font-size: 36px; font-size: 10cqw; }
.frame.has-name .lead { line-height: 1.3; }

.when { margin: .6cqw 0 0; font-weight: 700; line-height: 1.3; white-space: nowrap; font-size: 13px; font-size: max(12.5px, 3.35cqw); }

main { max-width: 560px; margin: 0 auto; padding: 8px 18px 8px; }

/* each panel is an ivory card with a fine double gold edge and roses at two corners */
.card {
  position: relative;
  background: var(--card);
  border: 1px solid var(--gold);
  border-radius: 22px;
  padding: 34px 22px 60px;
  margin: 26px 0;
  box-shadow: inset 0 0 0 5px var(--card), inset 0 0 0 6px rgba(194, 160, 99, .6), 0 10px 28px rgba(110, 50, 65, .18);
}
.card::before, .card::after {
  content: "";
  position: absolute;
  width: 84px;
  height: 73px;
  background: url("roses.webp?v=8") left bottom / cover no-repeat;
  pointer-events: none;
}
.card::after { left: 0; bottom: 0; border-bottom-left-radius: 21px; }
.card::before { right: 0; top: 0; border-bottom-left-radius: 21px; transform: rotate(180deg); }

h2 {
  margin: 0 0 6px;
  padding: 0 22px;
  text-align: center;
  font-family: "Lora", Georgia, serif;
  font-weight: 600;
  font-size: 26px;
  line-height: 1.25;
  color: var(--rose-deep);
}
h2:focus { outline: none; }
/* a small gold flourish under each heading */
h2::after {
  content: "";
  display: block;
  width: 120px;
  height: 11px;
  margin: 12px auto 14px;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 120 11'%3E%3Cpath d='M2 5.5h46M72 5.5h46' stroke='%23C2A063' stroke-width='1' stroke-linecap='round'/%3E%3Cpath d='M60 1l4.5 4.5L60 10l-4.5-4.5z' fill='%23C2A063'/%3E%3Ccircle cx='51.500' cy='5.5' r='1.2' fill='%23C2A063'/%3E%3Ccircle cx='68.500' cy='5.5' r='1.2' fill='%23C2A063'/%3E%3C/svg%3E") center / contain no-repeat;
}

h3 {
  margin: 0 0 8px;
  font-family: "Lora", Georgia, serif;
  font-weight: 600;
  font-size: 23px;
  color: var(--sage-deep);
}

.help { margin: 0 0 18px; color: var(--muted); text-align: center; }

label, .q {
  display: block;
  margin: 18px 0 8px;
  font-weight: 700;
  font-size: 19px;
}

input[type="text"], textarea {
  width: 100%;
  min-height: 58px;
  padding: 14px 16px;
  font: inherit;
  color: var(--ink);
  background: #fff;
  border: 2px solid var(--line);
  border-radius: 14px;
}
textarea { min-height: 120px; resize: vertical; }
input[type="text"]:focus, textarea:focus, button:focus-visible, summary:focus-visible, a:focus-visible {
  outline: 3px solid var(--sage);
  outline-offset: 2px;
  border-color: var(--sage-deep);
}

.btn {
  display: block;
  width: 100%;
  min-height: 58px;
  margin-top: 16px;
  padding: 14px 18px;
  font: inherit;
  font-weight: 700;
  text-align: center;
  text-decoration: none;
  border-radius: 14px;
  border: 2px solid transparent;
  cursor: pointer;
}
.btn.primary { background: var(--sage-deep); color: #fff; }
.btn.primary:active { background: #3C5639; }
.btn.primary[disabled] { opacity: .65; cursor: progress; }
.btn.secondary { background: #FFFDF9; color: var(--rose-deep); border-color: var(--gold); }
.btn.link { background: none; color: var(--muted); text-decoration: underline; min-height: 48px; margin-top: 8px; }

.deadline { margin: 18px 0 0; text-align: center; color: var(--muted); font-size: 17px; }

.error {
  margin: 14px 0 0;
  padding: 12px 14px;
  background: #FCE6EA;
  border-left: 5px solid var(--rose-deep);
  border-radius: 8px;
  color: #6E2237;
}

.demo-note {
  margin: 12px 0 0;
  padding: 10px 14px;
  background: #EEF3EC;
  border: 1px dashed var(--sage);
  border-radius: 10px;
  font-size: 16px;
  color: var(--sage-deep);
}

.demo-note a { color: var(--sage-deep); font-weight: 700; }

.pick-list { list-style: none; margin: 0; padding: 0; }
.pick-list .btn { margin-top: 12px; background: #fff; color: var(--ink); border-color: var(--line); font-size: 20px; }
.pick-list .btn:active { border-color: var(--sage-deep); }

.event {
  margin: 18px 0 8px;
  padding: 18px 16px 20px;
  background: #FBF3E6;
  border: 1px solid var(--line);
  border-radius: 16px;
  text-align: center;
}
.event .q, .event .limit-note { text-align: left; }
.event .when-line { margin: 0; font-weight: 700; }
.event .where { margin: 6px 0 0; }
.event .where small { display: block; color: var(--muted); font-size: 17px; }

.actions { display: grid; gap: 10px; margin: 14px 0 4px; }
.actions .btn { margin: 0; min-height: 52px; font-size: 18px; }

details.cal summary {
  list-style: none;
  display: block;
  min-height: 52px;
  padding: 12px 18px;
  text-align: center;
  font-weight: 700;
  font-size: 18px;
  background: #FFFDF9;
  color: var(--rose-deep);
  border: 2px solid var(--gold);
  border-radius: 14px;
  cursor: pointer;
}
details.cal summary::-webkit-details-marker { display: none; }
details.cal[open] summary { border-color: var(--sage-deep); color: var(--sage-deep); }
details.cal .cal-links { display: grid; gap: 10px; margin-top: 10px; }
details.cal .cal-links a {
  display: block;
  min-height: 50px;
  padding: 12px 16px;
  text-align: center;
  color: var(--sage-deep);
  font-weight: 700;
  text-decoration: none;
  background: #EEF1E6;
  border-radius: 12px;
}

.choice { display: grid; grid-template-columns: 1fr; gap: 10px; }
.choice .btn { margin: 0; min-height: 60px; background: #fff; color: var(--ink); border-color: var(--line); line-height: 1.25; }
.choice .btn[aria-pressed="true"].yes { background: var(--sage-deep); color: #fff; border-color: var(--sage-deep); }
.choice .btn[aria-pressed="true"].no { background: var(--rose-deep); color: #fff; border-color: var(--rose-deep); }

.count-wrap { margin-top: 6px; }
.counts { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; }
.counts button {
  min-height: 58px;
  font: inherit;
  font-weight: 700;
  font-size: 22px;
  color: var(--ink);
  background: #fff;
  border: 2px solid var(--line);
  border-radius: 14px;
  cursor: pointer;
}
.counts button[aria-pressed="true"] { background: var(--sage-deep); color: #fff; border-color: var(--sage-deep); }
.limit-note { margin: 8px 0 0; color: var(--muted); font-size: 17px; }

.heart { text-align: center; font-size: 34px; color: var(--rose); line-height: 1; margin-bottom: 8px; }
#view-done h2 { text-align: center; }
#view-done .summary { text-align: center; margin: 10px 0 4px; }
#view-done .summary p { margin: 4px 0; }
#view-done .summary strong { color: var(--sage-deep); }

footer { text-align: center; padding: 26px 20px 60px; }
.sign { margin: 0; font-family: "Pinyon Script", cursive; font-size: 38px; line-height: 1.3; color: #7E2944; }
.sign .amp { font-family: "Playfair Display", Georgia, serif; font-style: italic; font-size: .66em; color: var(--sage-deep); padding: 0 .08em; }

@media (min-width: 640px) {
  body { font-size: 20px; }
}

@media (prefers-reduced-motion: no-preference) {
  .card { animation: rise .35s ease-out; }
  @keyframes rise { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
}

/* ---------- the invitation film ---------- */
/* Scene one (the opening) plays once on top of the invitation. The camera then moves up to
   the gateway and the opening melts into the invitation, which is the same gateway up close. */
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes fadeUp { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
@keyframes wipe { from { clip-path: inset(-20% 100% -20% -8%); } to { clip-path: inset(-20% -8% -20% -8%); } }
@keyframes textPop { from { opacity: 0; transform: scale(.85); } to { opacity: 1; transform: none; } }
@keyframes nudge { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(3px); } }

.opening {
  position: absolute; inset: 0; z-index: 3;
  background: #4A2F36;
  opacity: 0; visibility: hidden;
  transition: opacity 1.9s ease-in-out .1s, visibility 0s linear 2.1s;
}
.frame.is-opening .opening { opacity: 1; visibility: visible; transition: none; }

/* the camera glides slowly toward the gateway, then eases right up to it */
.scene-open { transform-origin: 50% 62%; transition: transform 7s cubic-bezier(.3, 0, .8, 1); }
.frame.is-pushing .scene-open { transform: scale(1.05); }
/* (the couple stay where they are on screen while the gateway grows behind them) */
.frame.is-through .scene-open { transform: translateY(9%) scale(1.04); transition: transform 2.4s cubic-bezier(.4, 0, .3, 1); }

/* a soft glow behind the initials so they read over the scene */
.opening::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(ellipse 62% 17% at 50% 30%, rgba(255, 247, 236, .55), transparent 100%);
  opacity: 0;
}
.frame.is-opening .opening::after { animation: fadeIn 1.2s ease-out .5s both; }

/* the couple's initials write themselves over the opening scene */
.monogram {
  position: absolute; left: 0; right: 0; top: 22%; z-index: 1;
  margin: 0; text-align: center; white-space: nowrap;
  font-family: "Pinyon Script", "Snell Roundhand", cursive;
  font-size: 30cqw; line-height: 1.1;
  color: #8C2B4C;
  text-shadow: 0 0 14px rgba(255, 248, 238, .95), 0 0 3px rgba(255, 248, 238, .8);
  transition: opacity .5s ease;
}
.frame.is-through .monogram { opacity: 0; }
.mono-i, .mono-a, .mono-amp { display: inline-block; opacity: 0; }
.mono-i, .mono-a { padding: 0 .06em; }
.mono-amp {
  font-family: "Playfair Display", Georgia, serif; font-style: italic;
  font-size: .36em; padding: 0 .2em; color: #A8782C; vertical-align: .5em;
}
.frame.is-opening .mono-i { opacity: 1; animation: wipe 1.3s cubic-bezier(.4, 0, .2, 1) .9s both; }
.frame.is-opening .mono-amp { animation: fadeIn .8s ease-out 1.9s both; }
.frame.is-opening .mono-a { opacity: 1; animation: wipe 1.3s cubic-bezier(.4, 0, .2, 1) 2.2s both; }

/* candlelight: a warm glow over each lantern that flickers, and a slow shimmer across the scene */
.glows { position: absolute; inset: 0; z-index: 1; overflow: hidden; pointer-events: none; opacity: 0; transition: opacity 1.6s ease; }
.frame.is-card .glows { opacity: 1; }
.frame.is-through .glows { transition-delay: 1.8s; }
.glows i {
  position: absolute; left: var(--x); top: var(--y);
  width: 20cqw; height: 20cqw; margin: -10cqw 0 0 -10cqw; border-radius: 50%;
  background: radial-gradient(circle, rgba(255, 232, 170, .8) 0, rgba(255, 205, 125, .34) 30%, rgba(255, 190, 110, 0) 68%);
  mix-blend-mode: screen;
  animation: candle var(--t) ease-in-out var(--dl) infinite;
}
@keyframes candle {
  0%, 100% { opacity: .5; transform: scale(.9); }
  11% { opacity: .95; transform: scale(1.05); }
  24% { opacity: .58; transform: scale(.94); }
  39% { opacity: 1; transform: scale(1.1); }
  55% { opacity: .66; transform: scale(.97); }
  71% { opacity: .96; transform: scale(1.04); }
  86% { opacity: .56; transform: scale(.92); }
}
/* the light in the gateway slowly brightens and dims */
.glows::before {
  content: ""; position: absolute; left: 14%; right: 14%; top: 10%; height: 62%; border-radius: 50%;
  background: radial-gradient(ellipse, rgba(255, 250, 235, .6) 0, rgba(255, 246, 225, .25) 45%, rgba(255, 244, 220, 0) 72%);
  animation: breathe 7s ease-in-out infinite;
}
@keyframes breathe { 0%, 100% { opacity: .15; } 50% { opacity: 1; } }
.glows::after {
  content: ""; position: absolute; top: -20%; left: 0; width: 46%; height: 140%;
  background: linear-gradient(90deg, rgba(255, 244, 220, 0), rgba(255, 244, 220, .34) 50%, rgba(255, 244, 220, 0));
  mix-blend-mode: soft-light;
  transform: translateX(-140%) skewX(-14deg);
  animation: shimmer 11s ease-in-out 4s infinite;
}
@keyframes shimmer { 0% { transform: translateX(-140%) skewX(-14deg); } 38%, 100% { transform: translateX(340%) skewX(-14deg); } }

/* rose petals drift down, and tiny lights twinkle among the flowers */
.petals { position: absolute; inset: 0; z-index: 1; overflow: hidden; pointer-events: none; opacity: 0; transition: opacity 1.6s ease; }
.frame.is-card .petals { opacity: 1; }
.frame.is-through .petals { transition-delay: 1.2s; }
.petals b {
  position: absolute; left: var(--x); top: -6cqw;
  width: var(--s); height: calc(var(--s) * .76);
  border-radius: 85% 12% 85% 12%;
  background: linear-gradient(135deg, #F6C3CC, #D7738C);
  box-shadow: inset -.3cqw -.2cqw .5cqw rgba(150, 50, 80, .25);
  animation: fall var(--t) linear var(--dl) infinite;
}
@keyframes fall {
  0% { transform: translate(0, 0) rotate(0); }
  25% { transform: translate(var(--w), 48cqw) rotate(130deg); }
  50% { transform: translate(calc(var(--w) * -.6), 96cqw) rotate(230deg); }
  75% { transform: translate(var(--w), 144cqw) rotate(340deg); }
  100% { transform: translate(calc(var(--w) * .3), 192cqw) rotate(440deg); }
}
.petals u {
  position: absolute; left: var(--x); top: var(--y);
  width: 2.2cqw; height: 2.2cqw; margin: -1.1cqw 0 0 -1.1cqw; border-radius: 50%;
  background: radial-gradient(circle, #FFFDF2 0, rgba(255, 236, 170, .85) 28%, rgba(255, 220, 140, 0) 70%);
  animation: twinkle var(--t) ease-in-out var(--dl) infinite;
}
@keyframes twinkle { 0%, 100% { opacity: 0; transform: scale(.3); } 50% { opacity: 1; transform: scale(1); } }

/* the words of the invitation appear line by line once the invitation is showing */
.frame .text { z-index: 2; }
.frame.is-through { --d0: 1s; }
.frame.is-opening .text > *, .frame.is-opening .cue { opacity: 0; }
.frame.is-card .eyebrow { animation: fadeUp .9s ease-out calc(var(--d0, 0s) + .9s) both; }
.frame.is-card .names .n1 { animation: wipe 1.2s cubic-bezier(.4, 0, .2, 1) calc(var(--d0, 0s) + 1.5s) both; }
.frame.is-card .names .amp { animation: fadeIn .7s ease-out calc(var(--d0, 0s) + 2.4s) both; }
.frame.is-card .names .n2 { animation: wipe 1.2s cubic-bezier(.4, 0, .2, 1) calc(var(--d0, 0s) + 2.7s) both; }
.frame.is-card .lead { animation: fadeUp .8s ease-out calc(var(--d0, 0s) + 3.9s) both; }
.frame.is-card .occasion { animation: textPop 1s cubic-bezier(.2, .9, .3, 1.2) calc(var(--d0, 0s) + 4.3s) both; }
.frame.is-card .when { animation: fadeUp .8s ease-out calc(var(--d0, 0s) + 4.9s) both; }

/* a small pointer to the reply form further down */
.cue {
  position: absolute; left: 50%; bottom: 2.4%; z-index: 2;
  margin: 0; padding: .3em 1em; transform: translateX(-50%);
  border-radius: 999px;
  background: rgba(255, 250, 244, .88);
  box-shadow: 0 2px 10px rgba(80, 30, 45, .2);
  color: var(--rose-deep); font-weight: 700; letter-spacing: .03em; white-space: nowrap;
  font-size: 14px; font-size: max(14px, 3.8cqw);
  opacity: 0;
}
.cue::after { content: "\2193"; display: inline-block; margin-left: .45em; animation: nudge 1.6s ease-in-out infinite; }
.frame.is-card .cue { animation: fadeIn .9s ease-out calc(var(--d0, 0s) + 6.3s) both; }

/* a small button to watch the opening again */
.replay {
  position: absolute; right: 3%; top: 1.6%; z-index: 2;
  min-height: 40px; padding: 0 1em;
  border: 0; border-radius: 999px;
  background: rgba(255, 250, 244, .72);
  box-shadow: 0 2px 8px rgba(80, 30, 45, .16);
  color: var(--rose-deep); font: inherit; font-weight: 700; white-space: nowrap; cursor: pointer;
  font-size: 12px; font-size: max(12px, 3.1cqw);
  opacity: 0; visibility: hidden;
}
.replay::before { content: "\21BB"; margin-right: .4em; }
.frame.is-card .replay { opacity: 1; visibility: visible; transition: opacity .9s ease; }
.frame.is-through .replay { transition-delay: 8.6s; }

/* people who have seen the opening before, or who ask their phone for less motion,
   get the finished invitation straight away */
.frame.is-seen .text *, .frame.is-still .text *,
.frame.is-seen .cue, .frame.is-still .cue { animation: none !important; opacity: 1; }
.frame.is-still .cue::after, .frame.is-still .glows i, .frame.is-still .glows::before, .frame.is-still .glows::after { animation: none !important; }
.frame.is-still .petals { display: none; }
.frame.is-still .replay { display: none; }

/* used for an instant while the opening is put back to its start */
.frame.no-move, .frame.no-move * { transition: none !important; }

/* save battery: stop the endless motion while the artwork is off screen */
.frame.is-offscreen *, .frame.is-offscreen *::before, .frame.is-offscreen *::after { animation-play-state: paused !important; }

@media (prefers-reduced-motion: reduce) {
  .frame *, .frame *::after { animation: none !important; transition: none !important; }
  .frame .text > *, .frame .cue { opacity: 1; }
  .opening, .replay, .petals { display: none; }
}
