/* ============================================================
   Thiệp cưới — Ngọc Lâm & Minh Phương
   Bảng màu: kem / gold-nâu / hồng phấn / đỏ tim
   ============================================================ */
:root{
  --cream:      #fdf7f1;
  --cream-2:    #f6ece2;
  --gold:       #b0916e;
  --gold-soft:  #c9b299;
  --wine:       #8f5b52;
  --pink:       #e7a7ad;
  --pink-soft:  #f4d7d9;
  --ink:        #4a3f39;
  --ink-soft:   #7a6a60;
  --white:      #fffdfb;
  --shadow:     0 18px 45px rgba(120, 90, 70, .16);
  --serif:      "Cormorant Garamond", "Playfair Display", serif;
  --body:       "Be Vietnam Pro", system-ui, sans-serif;
  --script:     "Dancing Script", cursive;
  --signature:  "Sacramento", "Dancing Script", cursive;
  --maxw:       460px;   /* khung giống điện thoại */
}

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

html{
  scroll-behavior:smooth;
  scrollbar-gutter:stable;   /* luôn chừa chỗ cho thanh cuộn -> không nhảy ngang khi mở khoá cuộn lúc mở thiệp */
}

body{
  font-family:var(--body);
  color:var(--ink);
  background:#e9ded3;   /* nền ngoài khung */
  line-height:1.65;
  -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
}

img{ max-width:100%; display:block; }

/* Khung nội dung căn giữa như màn hình điện thoại */
.invitation{
  max-width:var(--maxw);
  margin:0 auto;
  background:
    radial-gradient(120% 60% at 50% 0%, #fffdfb 0%, var(--cream) 45%, var(--cream-2) 100%);
  position:relative;
  overflow:hidden;
  box-shadow:0 0 60px rgba(120,90,70,.18);
  min-height:100vh;
}

/* ============================================================
   Section chung
   ============================================================ */
.section{
  position:relative;
  padding:78px 26px;
  text-align:center;
}

.pre{
  font-family:var(--serif);
  font-style:italic;
  letter-spacing:.32em;
  text-transform:uppercase;
  font-size:.72rem;
  color:var(--gold);
  margin-bottom:14px;
}

.script-accent{
  font-family:var(--script);
  font-size:2rem;
  color:var(--pink);
  line-height:1;
  margin-bottom:6px;
}

.heading{
  font-family:var(--serif);
  font-weight:600;
  font-size:1.9rem;
  color:var(--wine);
  letter-spacing:.01em;
  margin-bottom:18px;
}
.heading.light{ color:var(--gold); }

.body-text{
  font-weight:300;
  color:var(--ink-soft);
  font-size:.98rem;
  max-width:34ch;
  margin:0 auto 12px;
}
.body-text.en{ font-family:var(--serif); font-style:italic; color:var(--gold); }

.divider{
  width:190px;
  margin:14px auto 20px;
  opacity:.8;
}

.card{
  background:rgba(255,255,255,.72);
  border:1px solid rgba(176,145,110,.28);
  border-radius:22px;
  padding:38px 26px;
  box-shadow:var(--shadow);
  backdrop-filter:blur(2px);
}

/* ============================================================
   HERO
   ============================================================ */
.hero{ padding-top:64px; padding-bottom:56px; }
.hero-inner{ position:relative; z-index:2; }

.hero-title{
  width:230px;
  margin:6px auto 22px;
}

.hero-photo-wrap{
  width:min(78%, 320px);
  margin:0 auto 22px;
  border-radius:400px 400px 18px 18px;
  overflow:hidden;
  padding:10px;
  background:linear-gradient(#fff, #fbeee3);
  box-shadow:var(--shadow);
  border:1px solid rgba(176,145,110,.3);
}
.hero-photo{
  width:100%;
  border-radius:390px 390px 12px 12px;
  aspect-ratio:3/4;
  object-fit:cover;
}

.couple-names{
  font-family:var(--serif);
  font-weight:600;
  color:var(--wine);
  line-height:1.15;
  font-size:2.5rem;
  margin-bottom:12px;
}
.couple-names .amp{
  display:block;
  font-family:var(--script);
  color:var(--pink);
  font-size:1.7rem;
  margin:2px 0;
}

.hero-date{
  font-family:var(--serif);
  letter-spacing:.18em;
  color:var(--gold);
  font-size:.95rem;
}

/* Hoa trang trí góc */
.deco-rose, .deco-daisy{
  position:absolute;
  z-index:1;
  opacity:.9;
  pointer-events:none;
}
.deco-rose--tl{ width:150px; top:-24px; left:-38px; transform:rotate(45deg); }   /* nghiêng ~45° vào tâm */
.deco-daisy--br{ width:120px; bottom:-10px; right:-26px; transform:rotate(-45deg); }

/* ============================================================
   Hoa góc cho MỌI section nội dung (trừ hero đã có ảnh riêng)
   - nghiêng ~45° hướng vào trung tâm, tự cắt gọn nhờ .invitation{overflow:hidden}
   - mỗi section 1 góc xen kẽ cho thoáng; Hero & Footer giữ cả 2 góc làm điểm nhấn
   ============================================================ */
.invitation .section:not(.hero) > *{ position:relative; z-index:1; }   /* nội dung nổi trên hoa */
.invitation .section:not(.hero)::before,
.invitation .section:not(.hero)::after{
  content:"";
  position:absolute;
  z-index:0;
  width:104px; height:104px;
  background-size:contain;
  background-repeat:no-repeat;
  opacity:.75;
  pointer-events:none;
}
.invitation .section:not(.hero)::before{        /* góc trên-trái — hoa cúc */
  top:-18px; left:-30px;
  background-image:url("../publics/images/gm7mq3ru5s7k4o1dt5ymhp.png");
  transform:rotate(45deg);
}
.invitation .section:not(.hero)::after{         /* góc dưới-phải — hoa hồng */
  bottom:-18px; right:-30px;
  background-image:url("../publics/images/unri8axa4zmlj5408kc4ko.png");
  transform:rotate(-45deg);
}
/* Mỗi section chỉ 1 góc, xen kẽ tạo nhịp: lẻ = trên-trái, chẵn = dưới-phải */
.invitation .section:not(.hero):nth-of-type(odd)::after{ display:none; }
.invitation .section:not(.hero):nth-of-type(even)::before{ display:none; }
/* Footer: giữ cả 2 góc làm điểm nhấn kết */
.invitation .footer::before,
.invitation .footer::after{ display:block !important; }

/* ============================================================
   QUOTE
   ============================================================ */
.quote-love{ width:220px; margin:0 auto 26px; }
.quote-photo-frame{
  width:82%;
  margin:0 auto 24px;
  padding:12px;
  background:#fff;
  border-radius:16px;
  box-shadow:var(--shadow);
  transform:rotate(-2deg);
  border:1px solid rgba(176,145,110,.25);
}
.quote-photo-frame img{ border-radius:10px; width:100%; }
.quote-text{
  font-family:var(--serif);
  font-style:italic;
  color:var(--wine);
  font-size:1.05rem;
  line-height:1.9;
  max-width:32ch;
  margin:0 auto;
}

/* ============================================================
   ĐẾM NGƯỢC
   ============================================================ */
.countdown{
  background:linear-gradient(160deg, #f3ddd9, #f8ece2);
}
.countdown-grid{
  display:flex;
  justify-content:center;
  gap:12px;
  margin-top:26px;
}
.cd-item{
  background:rgba(255,255,255,.85);
  border:1px solid rgba(176,145,110,.28);
  border-radius:16px;
  width:70px;
  padding:16px 6px;
  box-shadow:0 10px 24px rgba(143,91,82,.14);
}
.cd-num{
  display:block;
  font-family:var(--serif);
  font-size:1.9rem;
  color:var(--wine);
  line-height:1;
}
.cd-label{
  display:block;
  margin-top:8px;
  font-size:.7rem;
  letter-spacing:.14em;
  text-transform:uppercase;
  color:var(--gold);
}
.cd-done{
  font-family:var(--serif);
  color:var(--wine);
  font-size:1.2rem;
  line-height:1.7;
  animation:slideInFadeIn .8s ease-in-out;
}
.cd-done span{
  display:block;
  font-family:var(--body);
  font-weight:300;
  font-size:.85rem;
  color:var(--ink-soft);
  margin-top:6px;
}

/* ============================================================
   LỊCH
   ============================================================ */
.calendar-card{
  background:rgba(255,255,255,.8);
  border:1px solid rgba(176,145,110,.28);
  border-radius:22px;
  padding:24px 18px 20px;
  box-shadow:var(--shadow);
  max-width:340px;
  margin:16px auto 0;
}
.cal-weekdays, .cal-days{
  display:grid;
  grid-template-columns:repeat(7,1fr);
  gap:4px;
}
.cal-weekdays span{
  font-size:.72rem;
  font-weight:600;
  color:var(--gold);
  padding:6px 0;
}
.cal-days span{
  aspect-ratio:1;
  display:flex;
  align-items:center;
  justify-content:center;
  font-size:.85rem;
  color:var(--ink-soft);
  border-radius:50%;
  position:relative;
}
.cal-days span.empty{ visibility:hidden; }
.cal-days span.wed{
  color:#fff;
  font-weight:700;
  background:url("../publics/images/calen_heart_1.png") center center / 132% auto no-repeat;
  animation:heartScale 1.4s ease-in-out infinite;
  text-shadow:0 1px 2px rgba(0,0,0,.25);
}
.cal-note{
  margin-top:16px;
  font-size:.78rem;
  color:var(--ink-soft);
}

/* ============================================================
   THÔNG TIN LỄ
   ============================================================ */
.event{ background:linear-gradient(#fbeee3, #fdf7f1); }
.event-photo{
  width:200px;
  margin:0 auto 22px;
}
.event-photo.film{
  padding:14px 12px;
  background:#1c1a19;
  border-radius:6px;
  box-shadow:var(--shadow);
}
.event-photo.film img{
  aspect-ratio:3/4;
  object-fit:cover;
  border-radius:2px;
}
.event-title{
  font-family:var(--serif);
  color:var(--wine);
  font-size:1.5rem;
  margin-bottom:8px;
}
.event-time{ color:var(--gold); letter-spacing:.08em; margin-bottom:6px; }
.event-place{ font-weight:500; color:var(--ink); }
.event-addr{ font-weight:300; color:var(--ink-soft); font-size:.9rem; }

/* ============================================================
   ALBUM
   ============================================================ */
.gallery-grid{
  display:grid;
  grid-template-columns:1fr 1fr;
  gap:16px;
  margin-top:24px;
}
.g-item.polaroid{
  background:#fff;
  padding:10px 10px 30px;
  border-radius:4px;
  box-shadow:var(--shadow);
  transition:transform .4s ease;
}
.g-item.polaroid:nth-child(odd){ transform:rotate(-2.5deg); }
.g-item.polaroid:nth-child(even){ transform:rotate(2.5deg); }
.g-item.polaroid:hover{ transform:rotate(0) scale(1.03); z-index:3; }
.g-item.polaroid img{
  aspect-ratio:3/4;
  object-fit:cover;
  border-radius:2px;
}

/* ============================================================
   HỘP QUÀ
   ============================================================ */
.gift-box{
  width:96px;
  margin:0 auto 14px;
  animation:animation-bounce 2.4s ease-in-out infinite;
}
.gift-bank{
  margin-top:18px;
  background:linear-gradient(#fff, #fbeee3);
  border:1px dashed var(--gold-soft);
  border-radius:14px;
  padding:18px;
  font-size:.9rem;
}
.gift-bank p{ margin:4px 0; color:var(--ink-soft); }
.gift-bank strong{ color:var(--wine); }

/* ============================================================
   RSVP
   ============================================================ */
.rsvp{ background:linear-gradient(160deg,#f7e6df,#fdf7f1); }
.rsvp-illus{ width:160px; margin:0 auto 10px; }
.rsvp-form{
  max-width:340px;
  margin:22px auto 0;
  text-align:left;
  display:flex;
  flex-direction:column;
  gap:14px;
}
.rsvp-form label{ display:flex; flex-direction:column; gap:6px; }
.rsvp-form label span{
  font-size:.8rem;
  font-weight:500;
  color:var(--wine);
  letter-spacing:.04em;
}
.rsvp-form input,
.rsvp-form select{
  font-family:var(--body);
  font-size:.95rem;
  padding:12px 14px;
  border:1px solid var(--gold-soft);
  border-radius:12px;
  background:#fff;
  color:var(--ink);
  outline:none;
  transition:border-color .25s, box-shadow .25s;
}
.rsvp-form input:focus,
.rsvp-form select:focus{
  border-color:var(--pink);
  box-shadow:0 0 0 3px var(--pink-soft);
}
.rsvp-submit{
  margin-top:6px;
  padding:14px;
  border:none;
  border-radius:40px;
  background:linear-gradient(120deg,var(--wine),var(--pink));
  color:#fff;
  font-family:var(--body);
  font-weight:600;
  letter-spacing:.06em;
  font-size:.98rem;
  cursor:pointer;
  box-shadow:0 12px 26px rgba(143,91,82,.3);
  transition:transform .2s, box-shadow .2s;
}
.rsvp-submit:hover{ transform:translateY(-2px); box-shadow:0 16px 30px rgba(143,91,82,.36); }
.rsvp-submit:active{ transform:translateY(0); }
.rsvp-thanks{
  text-align:center;
  color:var(--wine);
  font-family:var(--serif);
  font-style:italic;
  font-size:1rem;
  margin-top:6px;
  animation:slideInFadeIn .7s ease-in-out;
}

/* ============================================================
   BẢN ĐỒ
   ============================================================ */
.map-wrap{
  max-width:360px;
  margin:16px auto 20px;
  border-radius:18px;
  overflow:hidden;
  box-shadow:var(--shadow);
  border:6px solid #fff;
}
.map-wrap iframe{ width:100%; height:240px; border:0; display:block; }
.map-btn{
  display:inline-block;
  padding:12px 28px;
  border-radius:40px;
  background:#fff;
  color:var(--wine);
  font-weight:600;
  text-decoration:none;
  border:1px solid var(--gold-soft);
  box-shadow:0 10px 22px rgba(143,91,82,.14);
  transition:transform .2s;
}
.map-btn:hover{ transform:translateY(-2px); }

/* ============================================================
   FOOTER
   ============================================================ */
.footer{
  padding-bottom:70px;
  background:linear-gradient(#fdf7f1,#f3ddd9);
}
.footer-thanks{ width:210px; margin:0 auto 14px; }
.footer-names{
  font-family:var(--serif);
  color:var(--wine);
  font-size:1.3rem;
  margin-bottom:6px;
}
.footer-note{ color:var(--ink-soft); font-size:.9rem; }

/* ============================================================
   MÀN MỞ THIỆP
   ============================================================ */
.open-overlay{
  position:relative;
  z-index:2;
  background:#e9ded3;                 /* ngoài khung điện thoại — cùng nền với .invitation */
}
/* Màn phong thư nằm liền mạch phía trên thiệp — cuộn liên tục xuống nội dung */
.open-inner{
  position:relative;
  max-width:var(--maxw);
  margin:0 auto;
  min-height:100vh;                   /* cùng khung điện thoại như .invitation */
  /* Bán kính dọc ĐỂ THEO PIXEL, không để 60% như .invitation.
     Cùng một dòng gradient nhưng "60%" là 60% chiều cao CỦA CHÍNH NÓ: .invitation cao vài nghìn px
     nên cả màn hình đầu vẫn nằm ở đoạn --cream (#fdf7f1); còn .open-inner chỉ cao ~830px nên
     gradient chạy hết ngay trong 1 màn, từ khoảng giữa trở xuống là --cream-2 (#f6ece2) — chính
     là cái "hơi vàng hơn". Ghim theo px thì màn bìa không còn phụ thuộc chiều cao của chính nó. */
  background:radial-gradient(120% 2200px at 50% 0%, #fffdfb 0%, var(--cream) 45%, var(--cream-2) 100%);
  box-shadow:0 0 60px rgba(120,90,70,.18);
  text-align:center;
  /* padding-top 72 (không phải 46): nút nhạc position:fixed chiếm y 16→60 ở mép phải,
     mà .open-top trải hết bề ngang nên chữ "MY LIFE" chui xuống dưới nút. Đẩy cả hàng
     xuống dưới đáy nút là hết chồng, đồng thời hạ tiêu đề xuống cho đỡ sát mép. */
  padding:72px 28px 40px;
  /* Flex column để phần trống thừa được CHIA cho các .open-gap, thay vì dồn hết xuống đáy.
     Hoa .open-daisy/.open-roses là position:absolute nên không bị flex đụng tới. */
  display:flex;
  flex-direction:column;
  overflow:hidden;                    /* ẩn phần hoa trờm ra ngoài khung */
}

/* Khoảng đệm co giãn: nở ra khi màn hình cao, tự thu về 0 khi nội dung đã kín.
   Dùng phần tử riêng thay vì margin:auto để KHÔNG phá margin sẵn có của các khối.
   Có 3 cái, chia đều chỗ thừa thành 3 chặng: trên tiêu đề — trên phong thư — dưới phong thư.
   KHÔNG thay bằng margin-top cứng cho .env-float: màn 360×780 vốn đã không đủ chỗ, cộng thêm
   margin là tràn mất cái divider ở chân; còn .open-gap thì tự co về 0 đúng lúc hết chỗ. */
.open-gap{ flex:1 1 0; min-height:0; }
/* Dồn chỗ trống về phía TRÊN phong thư để nó tụt xuống sát khối tên hơn.
   TỔNG flex-grow vẫn đúng bằng 3 (1 + 2 + 0) nên chặng đầu vẫn chiếm đúng 1/3 như cũ
   → tiêu đề "Wedding Invitation" đứng nguyên chỗ, chỉ phong thư dịch xuống.
   Đo thực tế: giảm margin cứng gần như VÔ ÍCH ở đây (51→49px) — khung cao cố định 100vh nên
   tổng chiều cao được bảo toàn, cắt margin bao nhiêu thì các đệm nở ra bấy nhiêu. Muốn thu hẹp
   thật sự chỉ có cách đổi TỈ LỆ chia, nên chặng dưới cho hẳn về 0. */
.open-gap--push { flex-grow:2; }   /* chặng giữa tiêu đề và phong thư */
.open-gap--tight{ flex-grow:0; }   /* chặng dưới phong thư — dồn hết lên trên */

/* Hoa góc */
/* top 224 (không phải 124): bố cục mới đẩy tiêu đề xuống, chữ "Wedding" trải tới x=56 còn
   cụm cúc dại cao tận 214px và với sang x=132 → chữ "W" nằm đè lên hoa, rất khó đọc.
   Hạ cụm hoa xuống ngang thân phong thư thì hết đè chữ, hoa lại nấp sau phong bì rất tự nhiên. */
.open-daisy{
  position:absolute; width:112px; top:224px; left:-38px; z-index:0;
  opacity:.96; pointer-events:none; transform-origin:50% 50%;
  --tilt:32deg;                       /* nghiêng ~45° vào trung tâm (góc trên-trái) */
  animation:animation-float 5s ease-in-out infinite;
}
/* bottom 172: khối ngày giờ đã dời xuống, mép dưới cụm hồng (b=686) cắt ngang chữ
   "20.09.2026" (ink t=675) — chữ vàng trên cánh hoa hồng nhạt gần như không đọc được.
   Nâng lên cho mép dưới hoa nằm trên đầu dòng chữ, đẩy thêm sang phải cho chắc. */
.open-roses{
  position:absolute; width:126px; bottom:172px; right:-48px; z-index:0;
  opacity:.96; pointer-events:none; transform-origin:50% 50%;
  --tilt:-71deg;                      /* nghiêng ~45° vào trung tâm (góc dưới-phải) */
  animation:animation-float 6s ease-in-out infinite;
}

/* Header 3 cột */
.open-top{
  position:relative; z-index:2;
  display:flex;
  justify-content:space-between;
  align-items:center;
  font-size:.62rem;
  font-weight:600;
  letter-spacing:.16em;
  margin-bottom:30px;
  padding:0 2px;
}
.open-top .ot-1{ color:var(--wine); }
.open-top .ot-2{ color:var(--gold); }
.open-top .ot-3{ color:#7f93a3; }

.open-script{
  position:relative; z-index:2;
  font-family:var(--signature);
  font-weight:400;
  /* Đo được: ở 3.4rem dòng "Wedding Invitation" rộng 377px, khung chỉ rộng 404px (460 - 2×28).
     Máy 390px thì khung còn 334px → chữ vắt thành 2 dòng, đội trang cao thêm ~55px.
     Cho co theo bề ngang màn, chặn trên 3.4rem để máy rộng vẫn y như thiết kế gốc. */
  font-size:clamp(2.6rem, 11.5vw, 3.4rem);
  color:var(--ink);
  line-height:1;
  margin-bottom:28px;
}
.open-hint{
  position:relative; z-index:2;
  font-size:.9rem;
  color:var(--ink-soft);
  margin-bottom:26px;
}
/* Mở thiệp rồi thì câu nhắc hết nhiệm vụ → nắp thư lật lên "quét" nó đi.
   Phải THAY animation (không dùng transition/opacity thường): .open-hint mang .reveal-now
   với `animation:slideInFadeIn ... forwards`, animation đang fill sẽ đè mọi khai báo thường.
   Dùng fill `both` để trong 0.4s delay chữ vẫn giữ opacity:1 — nếu để `forwards` thì suốt
   thời gian delay nó rơi về opacity:0 của .reveal-now → chữ tắt phụt ngay lúc bấm.
   Delay .4s để khớp lúc nắp vừa qua phương thẳng đứng và trùm lên vùng chữ. */
.open-overlay:has(.envelope.is-opening) .open-hint{
  animation:hintWipe .35s ease .4s both;
}
@keyframes hintWipe{
  from{ opacity:1; }
  to  { opacity:0; }
}

/* ---- Phong thư có ảnh — 4 nắp gấp, nắp trên mở ra, ảnh trượt lên ---- */
/* Khung bọc — chịu trách nhiệm hiệu ứng NẢY LÊN XUỐNG của phong thư,
   tách khỏi entrance (reveal-now) và hover scale của nút bên trong */
.env-float{
  position:relative;
  /* Cao hơn .open-script/.open-hint (z-index:2): nắp thư lật ngược lên trên cao hơn cạnh
     phong bì ~89px, phải ĐÈ LÊN chữ "Chạm để mở thiệp". Nếu để mặc định, .env-float có
     transform (envelopeFloat) nên tự tạo stacking context ở mức 0 → chữ vẽ đè lên nắp. */
  z-index:3;
  /* 22 chứ không phải 34: đệm co giãn dưới phong thư đã siết còn ~9px rồi, phần hở còn lại
     chủ yếu là margin cứng này. Giảm nó mới kéo được phong thư sát khối tên trên MỌI cỡ màn,
     kể cả màn nhỏ (nơi các .open-gap đã co về 0 nên chỉnh flex-grow không còn tác dụng). */
  margin:0 auto 22px;
  animation:envelopeFloat 3.2s ease-in-out infinite;
  will-change:transform;
}
/* Đang mở thư → dừng nảy.
   PHẢI dùng animation-play-state, KHÔNG dùng `animation:none` + transform:translateY(0):
   cú bấm rơi vào thời điểm bất kỳ của chu kỳ nảy, nên xoá animation làm phong thư
   NHẢY GIẬT tối đa 16px xuống trong đúng 1 frame. Pause thì đứng yên tại chỗ, không giật. */
.env-float:has(.envelope.is-opening){
  animation-play-state:paused;
}

.envelope{
  position:relative; z-index:2;
  --ew: min(280px, 76vw);
  --eh: calc(var(--ew) * 0.6667);
  width:var(--ew);
  height:var(--eh);
  margin:0 auto;
  background:none; border:none; padding:0;
  cursor:pointer;
  perspective:1000px;
  filter:drop-shadow(0 20px 34px rgba(120,90,60,.24));
  transition:transform .35s ease;
}
.envelope:hover{ transform:translateY(-4px) scale(1.02); }
.envelope.is-opening{ transform:none; cursor:default; }
.envelope > *{ position:absolute; }

/* Phong thư nảy lên rồi hạ xuống, lặp vô hạn */
@keyframes envelopeFloat{
  0%,100%{ transform:translateY(0); }
  50%{ transform:translateY(-16px); }
}

/* đáy trong của phong thư */
.env-back{
  inset:0;
  background:linear-gradient(#f3ecdd,#e8ddc8);
  border-radius:10px;
  box-shadow:inset 0 0 22px rgba(150,120,90,.18);
  z-index:0;
}

/* ảnh cưới nằm trong thư — trượt lên khi mở (không lên hết) */
.env-photo{
  left:50%; bottom:4px;
  width:84%;                 /* rộng gần bằng chiều ngang phong bì */
  transform:translateX(-50%);
  z-index:2;
  border-radius:5px;
  overflow:hidden;
  background:#fff;
  padding:4px 4px 6px;
  box-shadow:0 6px 16px rgba(80,60,45,.28);
  transition:transform 1.6s cubic-bezier(.22,1,.36,1) .75s;  /* đợi nắp lật xong mới trồi lên */
}
.env-photo img{
  width:100%;
  aspect-ratio:4/3;          /* ngang → chiều cao lọt trong thư, không ló mép khi đóng */
  object-fit:cover;
  border-radius:4px;
}
.envelope.is-opening .env-photo{
  transform:translateX(-50%) translateY(-30%);   /* nhô nhẹ khỏi miệng thư, không đâm lên tiêu đề */
}

/* Túi thư LIỀN KHỐI (1 mảnh, không có khe ghép) — che kín ảnh, chừa miệng chữ V ở trên */
.env-pocket{
  inset:0;
  background:linear-gradient(155deg,#efe7d6 0%, #e9dec9 55%, #e2d6bf 100%);
  /* bỏ tam giác miệng thư ở giữa-trên (đỉnh V chạm 46% chiều cao) */
  clip-path:polygon(0 0, 0 100%, 100% 100%, 100% 0, 50% 46%);
  z-index:3;
  border-radius:0 0 10px 10px;
  box-shadow:inset 0 5px 9px -6px rgba(120,90,60,.3);
}
/* nếp gấp đáy chữ V — chỉ là đường mờ trang trí, vẽ trên mảnh liền nên không hở */
.env-pocket::after{
  content:"";
  position:absolute; inset:0;
  background:
    linear-gradient(to top right, transparent calc(50% - .6px), rgba(150,120,90,.22) 50%, transparent calc(50% + .6px)) left / 50% 100% no-repeat,
    linear-gradient(to top left,  transparent calc(50% - .6px), rgba(150,120,90,.22) 50%, transparent calc(50% + .6px)) right / 50% 100% no-repeat;
  clip-path:polygon(0 100%, 50% 46%, 100% 100%);
}

/* nắp trên — tam giác đặc, đè CHỒNG lên miệng túi (không hở), lật NGƯỢC RA SAU khi bấm.
   Dùng hộp thật + clip-path (không dùng border-triangle): border-triangle có content-box 0×0
   nên rất khó suy luận transform-origin, còn hộp thật thì bản lề nằm đúng cạnh trên. */
.env-flap{
  top:0; left:0;
  width:100%; height:50%;
  background:linear-gradient(#f4ecdb,#e8dec8);
  clip-path:polygon(0 0, 100% 0, 50% 100%);
  transform-origin:top center;
  transform:rotateX(0deg);
  z-index:5;
  will-change:transform;
}
/* Nắp phải LẬT HẲN QUA 90° rồi dựng ngược ra sau lưng thư — đó mới là "mở nắp".
   Bản cũ chỉ xoay tới 82° rồi fade: tam giác bị NÉN DẸP TẠI CHỖ (93px → 20px) chứ không
   đi đâu cả, mắt chỉ thấy "nắp biến mất". Tệ hơn, khi nén dẹp thì nắp hẹp lại NHANH HƠN
   miệng chữ V của túi (nắp cụt ở 50%·cos θ, còn khe V cố định ở 46%), nên từ ~23° trở đi
   nắp không lấp kín khe nữa: ảnh lòi ra thành 2 vệt chéo mỏng, chừa đúng 1 tam giác kem
   nằm giữa — nhìn y như đang ĐÓNG thư lại. Cho nắp lật tiếp qua 90° và chui ra sau
   (z-index âm) thì mắt bám được cả hành trình, hết cả 2 lỗi. */
.envelope.is-opening .env-flap{
  animation:flapOpen 1s cubic-bezier(.45,.05,.25,1) forwards;
}
@keyframes flapOpen{
  0%  { transform:rotateX(0deg);    z-index:5; }
  48% { z-index:5; }                    /* còn ngả về phía trước → nằm trên túi thư */
  52% { z-index:-1; }                   /* vừa qua phương thẳng đứng → lùi ra sau thân thư */
  100%{ transform:rotateX(-168deg); z-index:-1; }
}

/* dấu sáp giữa nắp */
.env-seal{
  left:50%; top:50%;
  transform:translate(-50%,-50%);
  width:20%;
  z-index:6;
  animation:sealPulse 2.2s ease-in-out infinite;
  transition:transform .75s ease, opacity .75s ease;
}
.envelope:hover .env-seal{
  animation:none;
  transform:translate(-50%,-50%) scale(1.08) rotate(6deg);
}
/* Phải THAY animation bằng animation khác, không được `animation:none` + transition:
   transform "trước đó" của dấu sáp do sealPulse sinh ra; xoá animation trong cùng 1 frame
   thì transition transform không chạy (chỉ opacity chạy) → dấu sáp GIẬT PHỰT từ scale(1.06)
   xuống scale(.4) tức thì. Nối bằng keyframes thì nó teo lại mượt. */
.envelope.is-opening .env-seal{
  animation:sealDrop .45s cubic-bezier(.4,0,.6,1) forwards;
}
@keyframes sealDrop{
  from{ transform:translate(-50%,-50%) scale(1); opacity:1; }
  to  { transform:translate(-50%,-50%) scale(.4) rotate(24deg); opacity:0; }
}
/* Gộp translate căn giữa vào animation để không mất căn giữa */
@keyframes sealPulse{
  0%,100%{ transform:translate(-50%,-50%) scale(1); }
  50%{ transform:translate(-50%,-50%) scale(1.06); }
}

/* tim nhẹ bay ra khi mở thư */
.open-heart{
  position:absolute;
  z-index:8;
  color:var(--pink);
  pointer-events:none;
  will-change:transform, opacity;
  text-shadow:0 2px 6px rgba(180,120,120,.3);
  animation:openHeartFloat 3.6s ease-out forwards;   /* chậm ~50% */
}
@keyframes openHeartFloat{
  0%{ transform:translateY(0) scale(.5); opacity:0; }
  20%{ opacity:1; }
  100%{ transform:translateY(-180px) scale(1.1); opacity:0; }
}

/* TRÂN TRỌNG KÍNH MỜI */
/* ---- Tên cô dâu chú rể — lấp khoảng giữa phong thư và khối thông tin lễ ---- */
.open-couple{
  position:relative; z-index:2;
  display:flex;
  align-items:center;
  justify-content:center;
  gap:14px;
  margin:6px 0 2px;
}
.open-couple .cn{
  font-family:var(--script);
  font-weight:600;
  font-size:2.1rem;
  line-height:1.25;
  color:var(--wine);
  /* Sacramento/Dancing Script có phần đuôi chữ thò xuống; thêm chút đệm để dấu
     tiếng Việt (Lâm, Phương) không bị cắt bởi line-height. */
  padding:2px 0;
}
.open-couple .cn-amp{
  font-family:var(--signature);
  font-style:normal;
  font-size:1.5rem;
  color:var(--pink);
  transform:translateY(-2px);
}
/* hai nét kẻ mảnh loe dần ra hai bên cho cân với divider phía dưới */
.open-couple::before,
.open-couple::after{
  content:"";
  height:1px;
  width:clamp(20px, 9vw, 46px);
  background:linear-gradient(90deg, transparent, var(--gold-soft));
}
.open-couple::after{ background:linear-gradient(90deg, var(--gold-soft), transparent); }

.open-invite-label{
  position:relative; z-index:2;
  margin:14px 0 24px;
}
.open-invite-label span{
  position:relative; z-index:1;
  display:inline-block;          /* để bóng bám theo bề rộng của chữ */
  font-family:var(--serif);
  letter-spacing:.14em;
  font-size:.94rem;
  color:#3a2e26;                 /* đậm hơn --ink để nổi rõ trên nền kem */
  padding:0 16px;
  /* chỉ 1 lớp mờ nhẹ, KHÔNG tạo viền sáng lóe quanh chữ */
  text-shadow:0 1px 1px rgba(253,249,244,.7);
}
/* Bóng đổ mềm của phong thư — hình elip, LUÔN rộng hơn phần chữ, nằm HẲN DƯỚI
   chân chữ như bóng trên nền để không đè lên nét chữ; nảy ĐỒNG BỘ với thư */
.open-invite-label span::before{
  content:""; position:absolute; z-index:-1;
  left:50%; top:112%;
  width:132%; height:22px;       /* rộng hơn chữ ~1/3 mỗi bên */
  transform:translate(-50%,-50%) scaleX(1);
  background:radial-gradient(ellipse at center,
              rgba(120,90,60,.50) 0%,
              rgba(120,90,60,.30) 46%,
              rgba(120,90,60,.10) 70%,
              transparent 84%);
  border-radius:50%;
  filter:blur(2px);
  animation:inviteShadow 3.2s ease-in-out infinite;
}
/* khớp pha với envelopeFloat: mốc 50% (thư cao nhất) → bóng nhỏ & mờ nhất */
@keyframes inviteShadow{
  0%,100%{ transform:translate(-50%,-50%) scaleX(1);   opacity:1; }
  50%    { transform:translate(-50%,-50%) scaleX(.72); opacity:.5; }
}
/* Đang mở thư → bóng ngừng nảy. Pause thay vì xoá animation, cùng lý do với .env-float:
   xoá thì bóng nhảy cóc về scaleX(1)/opacity 1 ngay giữa chu kỳ, lệch pha với phong thư. */
.open-overlay:has(.envelope.is-opening) .open-invite-label span::before{
  animation-play-state:paused;
}

.open-event-lead{
  position:relative; z-index:2;
  font-family:var(--serif);
  color:var(--ink);
  font-size:.96rem;
  line-height:1.85;
  margin-bottom:16px;
}
.open-event-time{
  position:relative; z-index:2;
  font-family:var(--serif);
  color:var(--gold);
  /* Cùng lý do với .open-script: ở 1.5rem dòng này rộng 375px, máy 390px chỉ còn 334px
     → nó rớt dòng ngay sau dấu "|" thứ hai, để lại một gạch đứng lơ lửng cuối dòng. */
  font-size:clamp(1.05rem, 4.9vw, 1.5rem);
  letter-spacing:.01em;
  margin-bottom:8px;
}
.open-event-time i{ color:var(--gold-soft); font-style:normal; margin:0 5px; }
.open-event-lunar{
  position:relative; z-index:2;
  color:var(--ink-soft);
  font-size:.85rem;
  margin-bottom:20px;
}
/* File SVG có viewBox 1024×1024 nhưng hoạ tiết chỉ là một dải mảnh ở CHÍNH GIỮA.
   Để nguyên thì thẻ img cao đúng 150px → tự sinh ~120px trống trắng quanh đường kẻ
   (đây mới là thủ phạm chính của khoảng trống ở đáy, không phải padding).
   Ép chiều cao + object-fit:cover = cắt lấy đúng dải hoạ tiết ở giữa. */
.open-divider{
  width:150px; height:30px;
  object-fit:cover; object-position:center;
  margin:0 auto; opacity:.7; position:relative; z-index:2;
}

/* ============================================================
   NÚT NHẠC
   ============================================================ */
.music-toggle{
  position:fixed;
  top:16px;
  right:16px;
  z-index:120;
  width:44px;
  height:44px;
  border-radius:50%;
  border:1px solid rgba(176,145,110,.4);
  background:rgba(255,255,255,.85);
  color:var(--wine);
  display:flex;
  align-items:center;
  justify-content:center;
  cursor:pointer;
  box-shadow:0 8px 20px rgba(143,91,82,.2);
  backdrop-filter:blur(4px);
}
.music-toggle.playing svg{ animation:spin 4s linear infinite; }
.music-toggle.paused{ opacity:.75; }

/* ============================================================
   HIỆU ỨNG HOA / TIM RƠI
   ============================================================ */
.petals{
  position:absolute;
  inset:0;
  overflow:hidden;
  pointer-events:none;
  z-index:5;
}
.petal{
  position:absolute;
  top:-40px;
  will-change:transform;
  opacity:.85;
  animation:fall linear infinite, snowflakes-shake ease-in-out infinite;
}

.floating-hearts{
  position:fixed;
  inset:0;
  pointer-events:none;
  z-index:90;
  overflow:hidden;
}
.f-heart{
  position:absolute;
  bottom:-30px;
  color:var(--pink);
  animation:heartFloat linear forwards;
  will-change:transform, opacity;
}

/* ============================================================
   REVEAL khi cuộn — slideInFadeIn (giống bản gốc)
   ============================================================ */
.reveal{
  opacity:0;
  transform:translateY(34px);
  transition:opacity .8s ease, transform .8s ease;
}
.reveal.in{
  opacity:1;
  transform:none;
}
.reveal-now{
  opacity:0;
  animation:slideInFadeIn .8s ease-in-out forwards;
}
.reveal-now:nth-child(2){ animation-delay:.15s; }
.reveal-now:nth-child(3){ animation-delay:.3s; }
.reveal-now:nth-child(4){ animation-delay:.45s; }

/* ============================================================
   KEYFRAMES (tái tạo từ bản gốc)
   ============================================================ */
@keyframes slideInFadeIn{
  from{ opacity:0; transform:translateY(30px); }
  to{ opacity:1; transform:translateY(0); }
}
@keyframes fall{
  to{ transform:translateY(115vh); }
}
@keyframes snowflakes-shake{
  0%,100%{ margin-left:0; }
  50%{ margin-left:24px; }
}
@keyframes heartFloat{
  0%{ transform:translateY(0) scale(.6); opacity:0; }
  15%{ opacity:.9; }
  100%{ transform:translateY(-105vh) scale(1); opacity:0; }
}
@keyframes heartScale{
  0%,100%{ transform:scale(1); }
  50%{ transform:scale(1.12); }
}
@keyframes animation-float{
  0%,100%{ transform:translateY(0) rotate(var(--tilt,0deg)); }
  50%{ transform:translateY(-14px) rotate(var(--tilt,0deg)); }
}
@keyframes animation-bounce{
  0%,100%{ transform:translateY(0); }
  50%{ transform:translateY(-10px); }
}
@keyframes animation-pulse{
  0%,100%{ transform:scale(1); }
  50%{ transform:scale(1.06); }
}
@keyframes backdropPulse{
  0%,100%{ background-position:50% 30%; }
  50%{ background-position:50% 40%; }
}
@keyframes spin{
  to{ transform:rotate(360deg); }
}

/* Máy hẹp: khung co lại nhưng cụm hoa vẫn giữ nguyên cỡ nên nó lấn vào cột chữ.
   Thu nhỏ + đẩy ra mép cho mép dưới cụm hồng nằm TRÊN dòng "17 GIỜ 00 | CHỦ NHẬT | 20.09.2026",
   vì đây là dòng dài nhất, chữ vàng nhạt đè lên cánh hồng thì gần như không đọc được. */
@media (max-width:430px){
  .open-roses{ width:108px; right:-52px; bottom:200px; }
  .open-daisy{ width:96px;  left:-34px; }
}

/* Tôn trọng người dùng tắt hiệu ứng */
@media (prefers-reduced-motion: reduce){
  *{ animation:none !important; transition:none !important; }
  .reveal{ opacity:1; transform:none; }
  .reveal-now{ opacity:1; }
}

/* Màn rộng: bo góc khung điện thoại cho đẹp — CẢ màn mở thiệp lẫn thiệp dùng chung 1 khung */
@media (min-width:520px){
  .invitation{ margin:24px auto; border-radius:26px; min-height:auto; }
  /* Màn mở thiệp là "bìa" — vẫn nên phủ kín màn hình để .open-gap có chỗ mà giãn,
     nếu để min-height:auto thì khung co lại bằng nội dung và bố cục dồn cục lên trên. */
  .open-inner{ margin:24px auto; border-radius:26px; min-height:calc(100vh - 48px); }
  body{ padding:0; }
  /* nút nhạc bám theo mép phải khung điện thoại, không dính mép màn hình */
  .music-toggle{ right:calc(50% - 214px); top:40px; }
}

/* ============================================================
   CUỘN PHIM KODAK
   ============================================================ */
.filmstrip{
  position:relative;
  max-width:300px;
  margin:26px auto 6px;
  background:#141210;
  border-radius:8px;
  padding:22px 34px;
  box-shadow:var(--shadow);
}
.filmstrip::before, .filmstrip::after{
  content:"";
  position:absolute; top:14px; bottom:14px; width:14px;
  background-image:repeating-linear-gradient(to bottom, #efe9da 0 11px, transparent 11px 22px);
  border-radius:3px; opacity:.9;
}
.filmstrip::before{ left:11px; }
.filmstrip::after{ right:11px; }
.film-label{
  position:absolute; top:0; bottom:0;
  writing-mode:vertical-rl;
  display:flex; align-items:center; justify-content:center;
  font-family:"Courier New", monospace;
  font-size:.5rem; letter-spacing:.28em;
  color:#cfc6b2; opacity:.85;
  z-index:3; pointer-events:none;
}
.film-label.l{ left:28px; }
.film-label.r{ right:28px; transform:rotate(180deg); }
.film-frame{
  position:relative;
  margin:0 0 8px;
}
.film-frame:last-child{ margin-bottom:0; }
.film-frame img{
  width:100%;
  aspect-ratio:5/6;
  object-fit:cover;
  display:block;
}
.film-cap{
  position:absolute; left:0; right:0; bottom:0;
  padding:20px 12px 12px;
  color:#fff;
  font-family:var(--serif);
  font-style:italic;
  font-size:1.05rem;
  line-height:1.4;
  text-align:center;
  text-shadow:0 1px 6px rgba(0,0,0,.8);
  background:linear-gradient(transparent, rgba(0,0,0,.5));
}

/* ============================================================
   RSVP RADIO
   ============================================================ */
.rsvp-radio{
  border:none; padding:0; margin:0;
  display:flex; flex-direction:column; gap:10px;
}
.rsvp-radio legend{
  font-size:.8rem; font-weight:500; color:var(--wine);
  letter-spacing:.04em; margin-bottom:4px; padding:0;
}
.rsvp-radio .radio{
  display:flex; align-items:center; gap:10px;
  padding:11px 14px;
  border:1px solid var(--gold-soft);
  border-radius:12px;
  background:#fff;
  cursor:pointer;
  transition:border-color .2s, box-shadow .2s;
  font-size:.9rem; color:var(--ink);
}
.rsvp-radio .radio input{ accent-color:var(--wine); width:16px; height:16px; flex:none; }
.rsvp-radio .radio:has(input:checked){
  border-color:var(--pink);
  box-shadow:0 0 0 3px var(--pink-soft);
}

/* ============================================================
   THANH LIVESTREAM
   ============================================================ */
.live-bar{
  position:fixed;
  left:50%; bottom:0;
  width:100%;
  max-width:var(--maxw);   /* bám đúng bề ngang khung thiệp */
  padding:0 14px 14px;
  /* z-index 100: nằm trên lớp tim bay (90) nhưng dưới nút nhạc (120) */
  z-index:100;
  /* Cả thanh không ăn chạm để còn cuộn/chạm xuyên qua vùng lời chúc;
     riêng .live-actions bật lại pointer-events:auto cho 3 nút
     (mở popup lời chúc, tim, like) */
  pointer-events:none;
  transform:translateX(-50%) translateY(120%);   /* ẩn dưới đáy màn hình */
  transition:transform .8s cubic-bezier(.22,.61,.36,1);
  background: linear-gradient(to top, rgba(233,222,211,0.98) 55%, rgba(233,222,211,0) 100%);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
.live-bar.show{ transform:translateX(-50%) translateY(0); }

/* Tay nắm thu/mở, kiểu bottom-sheet.
   .live-bar dựng pointer-events:none nên phải bật lại ở đây, y như
   .live-actions — quên là nút nhìn thấy mà bấm không được. */
.wish-grab{
  display:block;
  width:64px; height:22px;      /* vùng chạm rộng hơn vạch nhìn thấy */
  margin:0 auto 4px;
  padding:0;
  border:none; background:none;
  cursor:pointer;
  pointer-events:auto;
  touch-action:none;            /* để vuốt dọc trên tay nắm không cuộn trang */
}
.wish-grab::before{
  content:"";
  display:block;
  width:46px; height:5px;
  margin:8px auto 0;
  border-radius:3px;
  /* Tay nắm nằm ở mép trên thanh, chỗ nền gradient đã tan hết thành trong
     suốt — nó đứng trên ảnh cưới chứ không phải trên nền kem. Quầng sáng
     trắng là thứ giữ cho nó nhìn thấy được trên cả ảnh sáng lẫn ảnh tối. */
  background:rgba(120,90,70,.45);
  box-shadow:0 0 6px 2px rgba(255,255,255,.6);
  transition:background .2s;
}
.wish-grab:active::before{ background:rgba(120,90,70,.7); }

/* Vùng thu gọn được. Bọc cả băng lẫn dòng "chưa có lời chúc" để hai thứ
   cùng thu cùng mở, và để .wish-empty có gốc toạ độ mà bám đáy. */
.wish-strip{
  position:relative;
  height:136px;
  overflow:hidden;
  margin-bottom:10px;
  transition:height .35s cubic-bezier(.22,.61,.36,1),
             margin-bottom .35s cubic-bezier(.22,.61,.36,1),
             opacity .25s ease;
}
.wish-strip.collapsed{ height:0; margin-bottom:0; opacity:0; }

/* Nằm đè lên đáy vùng băng chứ không đẩy chiều cao — băng phải giữ nguyên
   136px, kẻo lúc lời chúc đầu tiên về thì cả thanh giật lên một nhịp. */
.wish-empty{
  position:absolute;
  left:4px; right:4px; bottom:0;
  margin:0;
  padding:6px 12px;
  font-size:.78rem; line-height:1.35;
  color:var(--ink-soft);
  font-style:italic;
  text-align:center;
}
.wish-empty[hidden]{ display:none; }

.wishes{
  height:136px;
  display:flex; flex-direction:column; justify-content:flex-end;
  gap:5px;
  overflow:hidden;
  padding:0 4px;
  -webkit-mask-image:linear-gradient(transparent 0, #000 58%);
  mask-image:linear-gradient(transparent 0, #000 58%);
}
.wish{
  align-self:flex-start;
  max-width:90%;
  padding:6px 12px;
  border-radius:15px;
  background:rgba(255,255,255,.86);
  box-shadow:0 3px 12px rgba(120,90,70,.16);
  font-size:.78rem; line-height:1.35;
  color:var(--ink);
  backdrop-filter:blur(2px);
  animation:slideInFadeIn .5s ease-out;
}
.wish b{ color:var(--wine); font-weight:600; }
.live-actions{
  display:flex; align-items:center; gap:8px;
  pointer-events:auto;
}
.live-btn{
  flex:none;
  border:none;
  border-radius:40px;
  padding:11px 14px;
  font-family:var(--body); font-size:.78rem; font-weight:600;
  cursor:pointer;
  display:flex; align-items:center; gap:5px;
  box-shadow:0 5px 16px rgba(120,90,70,.18);
  transition:transform .15s;
  white-space:nowrap;
}
.live-btn.heart{ background:linear-gradient(120deg,var(--wine),var(--pink)); color:#fff; }
.live-btn.like{ background:rgba(255,255,255,.92); color:var(--wine); }
.live-btn:active{ transform:scale(.93); }
.live-btn.pop{ animation:animation-bounce .45s ease; }

/* Nút mở popup — trông y hệt ô nhập cũ để khách không thấy khác gì */
.wish-open{
  flex:1; min-width:0;
  border:none;
  border-radius:40px;
  padding:12px 16px;
  font-family:var(--body); font-size:.85rem;
  text-align:left;
  background:rgba(255,255,255,.92);
  box-shadow:0 5px 16px rgba(120,90,70,.18);
  color:var(--ink-soft);
  cursor:pointer;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
  transition:transform .15s;
}
.wish-open:active{ transform:scale(.98); }

/* Nút đã thả tim / đã like: mờ đi, hết vẻ bấm được */
.live-btn.reacted{ opacity:.7; cursor:default; }

/* ============================================================
   POPUP GỬI LỜI CHÚC
   ============================================================ */
.wish-modal{
  position:fixed; inset:0;
  z-index:200;                  /* trên live-bar (100) và nút nhạc (120) */
  display:flex; align-items:center; justify-content:center;
  padding:20px;
  overflow-y:auto;              /* bàn phím điện thoại co viewport => vẫn cuộn tới nút Gửi */
}
/* BẮT BUỘC: display:flex ở trên thắng thuộc tính hidden của trình duyệt,
   thiếu dòng này thì popup hiện ngay lúc mở trang. */
.wish-modal[hidden]{ display:none; }

.wish-modal-bg{
  position:absolute; inset:0;
  background:rgba(60,40,35,.45);
  backdrop-filter:blur(3px);
  -webkit-backdrop-filter:blur(3px);
  animation:wishFade .25s ease;
}
.wish-card{
  position:relative;
  margin:auto;
  width:100%; max-width:360px;
  background:var(--cream);
  border-radius:20px;
  padding:26px 22px 22px;
  box-shadow:0 18px 50px rgba(90,60,50,.32);
  animation:wishPop .3s cubic-bezier(.22,.61,.36,1);
}
@keyframes wishFade{ from{ opacity:0; } to{ opacity:1; } }
@keyframes wishPop{
  from{ opacity:0; transform:translateY(14px) scale(.96); }
  to{ opacity:1; transform:none; }
}
.wish-x{
  position:absolute; top:9px; right:11px;
  border:none; background:none;
  padding:6px;
  font-size:.95rem; line-height:1;
  color:var(--ink-soft);
  cursor:pointer;
}
.wish-title{
  margin:0 0 18px;
  font-family:var(--serif); font-weight:500; font-size:1.45rem;
  color:var(--wine); text-align:center;
}
.wish-label{
  display:block;
  margin-bottom:5px;
  font-family:var(--body); font-size:.7rem; font-weight:600;
  letter-spacing:.05em; text-transform:uppercase;
  color:var(--ink-soft);
}
.wish-field{
  display:block; width:100%;
  box-sizing:border-box;
  margin-bottom:15px;
  border:1px solid rgba(140,110,95,.24);
  border-radius:12px;
  padding:11px 13px;
  font-family:var(--body); font-size:.88rem;
  color:var(--ink); background:var(--white);
  outline:none; resize:none;
}
.wish-field:focus{ border-color:var(--pink); box-shadow:0 0 0 3px var(--pink-soft); }
.wish-error{
  margin:0 0 12px;
  font-family:var(--body); font-size:.78rem; line-height:1.4;
  color:#b3261e;
}
.wish-error[hidden]{ display:none; }
.wish-submit{
  width:100%;
  border:none; border-radius:40px;
  padding:13px;
  font-family:var(--body); font-size:.88rem; font-weight:600;
  color:#fff;
  background:linear-gradient(120deg,var(--wine),var(--pink));
  box-shadow:0 8px 22px rgba(143,91,82,.3);
  cursor:pointer;
  transition:transform .15s;
}
.wish-submit:active{ transform:scale(.97); }

.f-heart.burst{
  bottom:88px;
  animation-name:heartBurst;
  animation-timing-function:ease-out;
  animation-fill-mode:forwards;
}
@keyframes heartBurst{
  0%{ transform:translateY(0) scale(.4); opacity:0; }
  15%{ opacity:1; }
  100%{ transform:translateY(-280px) scale(1.15); opacity:0; }
}

/* Chừa chỗ cho thanh live không che nội dung cuối */
.footer{ padding-bottom:130px; }

#live-bar.show{
  transition-delay: .9s !important;
}

/* Báo lỗi gửi RSVP */
.rsvp-error {
  margin-top: 10px;
  color: #c0392b;
  font-size: 0.92rem;
  text-align: center;
}