/* Lov3ly · Mẫu 03 — Sinh Nhật Dưới Ánh Nến (đêm tím, nến vàng) */
:root{
  --bg1:#2a0e20; --bg2:#1d0b16; --ink:#f7ead9; --muted:rgba(247,234,217,.62);
  --pink:#f2a7c3; --rose:#e88bb0; --gold:#ffc46b; --gold2:#ffdf9e;
  --serif:"Playfair Display",Georgia,serif; --script:"Dancing Script",cursive; --sans:"Be Vietnam Pro",system-ui,sans-serif;
  --ease:cubic-bezier(.22,1,.36,1);
}
*{margin:0;padding:0;box-sizing:border-box}
html,body{height:100%}
body{
  font-family:var(--sans); color:var(--ink); overflow-x:hidden;
  background:
    radial-gradient(120% 70% at 50% -10%, #4a1730 0%, transparent 55%),
    radial-gradient(90% 55% at 85% 110%, #33102a 0%, transparent 60%),
    linear-gradient(180deg, var(--bg1), var(--bg2));
  background-attachment:fixed;
}
#fx{position:fixed; inset:0; z-index:30; pointer-events:none}
#dim{position:fixed; inset:0; z-index:20; background:#000; opacity:0; pointer-events:none; transition:opacity .3s linear}
.script{font-family:var(--script)}
.hidden{display:none !important}

.screen{display:none; min-height:100svh; flex-direction:column; align-items:center; justify-content:center;
  text-align:center; padding:34px 20px calc(38px + env(safe-area-inset-bottom)); position:relative; z-index:5}
.screen.active{display:flex; animation:fadeUp .65s cubic-bezier(.22,1,.36,1) both}
@keyframes fadeUp{from{opacity:0; transform:translateY(14px); filter:blur(6px)} to{opacity:1; transform:none; filter:blur(0)}}

.s-label{letter-spacing:.18em; text-transform:uppercase; font-size:11px; color:var(--gold); font-weight:600}
.big-script{font-size:clamp(52px,13vw,84px); line-height:1.15; margin-top:14px;
  background:linear-gradient(120deg,#fff, var(--pink) 55%, var(--gold2)); -webkit-background-clip:text; background-clip:text; color:transparent;
  filter:drop-shadow(0 6px 24px rgba(232,139,176,.35))}
.date-sub{margin-top:10px; font-weight:400; color:var(--muted); font-size:15px; max-width:420px}

/* — Vòng quay ngày/tháng — */
.wheels{position:relative; display:flex; align-items:center; gap:6px; margin-top:30px; height:190px}
.wheel{height:190px; width:86px; overflow-y:auto; scroll-snap-type:y mandatory; scrollbar-width:none;
  -webkit-mask-image:linear-gradient(180deg, transparent, #000 30%, #000 70%, transparent);
  mask-image:linear-gradient(180deg, transparent, #000 30%, #000 70%, transparent)}
.wheel::-webkit-scrollbar{display:none}
.wheel .pad{height:76px}
.wheel .num{height:38px; display:flex; align-items:center; justify-content:center; scroll-snap-align:center;
  font-family:var(--serif); font-size:21px; color:rgba(247,234,217,.35); transition:all .2s}
.wheel .num.sel{color:var(--ink); font-size:29px; font-weight:700}
.wheel-sep{font-size:26px; color:var(--gold); padding-bottom:2px}
.wheel-frame{position:absolute; left:50%; top:50%; transform:translate(-50%,-50%); width:196px; height:46px;
  border:1.5px solid rgba(255,196,107,.45); border-radius:14px; pointer-events:none;
  background:radial-gradient(60% 100% at 50% 50%, rgba(255,196,107,.14), transparent)}
.date-echo{margin-top:18px; font-family:var(--serif); font-style:italic; font-size:19px; color:var(--pink); min-height:28px}

/* — Nút — */
.btn-glow{margin-top:24px; font-family:var(--sans); font-weight:600; font-size:15.5px; color:#33160f;
  background:linear-gradient(180deg, var(--gold2), var(--gold)); border:none; border-radius:999px; padding:14px 32px; cursor:pointer;
  box-shadow:0 12px 32px rgba(255,196,107,.35), inset 0 1px 0 rgba(255,255,255,.5); transition:transform .3s var(--ease), box-shadow .3s var(--ease)}
.btn-glow:hover{transform:translateY(-2px); box-shadow:0 16px 38px rgba(255,196,107,.45), inset 0 1px 0 rgba(255,255,255,.5)}
.btn-glow:active{transform:scale(.97)}
.btn-glow.gold{margin-top:26px}
.btn-ghost-l{margin-top:24px; font-family:var(--sans); font-weight:500; font-size:14.5px; color:var(--ink);
  background:rgba(255,255,255,.06); border:1px solid rgba(255,255,255,.35); border-radius:999px; padding:12px 26px; cursor:pointer;
  backdrop-filter:blur(14px); -webkit-backdrop-filter:blur(14px); box-shadow:0 10px 24px rgba(0,0,0,.28), inset 0 1px 0 rgba(255,255,255,.14);
  transition:transform .3s var(--ease), background .3s var(--ease)}
.btn-ghost-l:hover{background:rgba(255,255,255,.12)}
.btn-ghost-l:active{transform:scale(.97)}
.link-btn{margin-top:16px; background:none; border:none; color:var(--muted); font-family:var(--sans); font-size:13.5px; cursor:pointer; text-decoration:underline; text-underline-offset:4px}

/* — Bánh & nến — */
.bunting{position:absolute; top:0; left:50%; transform:translateX(-50%); width:min(96vw,430px); opacity:.95}
.cake-wrap{position:relative; margin-top:5.5vh}
.cake{width:min(74vw,300px); display:block; margin:34px auto 0; filter:drop-shadow(0 24px 34px rgba(0,0,0,.5))}
#candle-zone{position:absolute; left:50%; top:-14px; transform:translateX(-50%); width:76px; height:76px; z-index:6; cursor:pointer; touch-action:none}
#progress-ring{position:absolute; inset:0; width:100%; height:100%}
#flame{position:absolute; left:50%; top:16px; transform:translateX(-50%); width:17px; height:27px;
  background:radial-gradient(50% 62% at 50% 68%, #fff6d8 0%, #ffd76e 38%, #ff9a3c 72%, rgba(255,120,40,0) 100%);
  border-radius:50% 50% 50% 50% / 62% 62% 38% 38%; transform-origin:50% 100%;
  animation:flick .18s ease-in-out infinite alternate; filter:drop-shadow(0 0 14px rgba(255,170,60,.95)) drop-shadow(0 0 42px rgba(255,140,50,.5))}
.flame-core{position:absolute; left:50%; bottom:3px; transform:translateX(-50%); width:6px; height:10px; border-radius:50%; background:#fff8e1; opacity:.9}
@keyframes flick{from{transform:translateX(-50%) scale(1) rotate(-2deg)} to{transform:translateX(-52%) scale(1.07,1.13) rotate(2.5deg)}}
#smoke{position:absolute; left:50%; top:2px; width:8px; height:8px; border-radius:50%; background:rgba(230,225,225,.75);
  filter:blur(3px); opacity:0; transform:translateX(-50%)}
#smoke.puff{animation:smokeUp 2.4s ease-out forwards}
@keyframes smokeUp{0%{opacity:.85; transform:translate(-50%,0) scale(1)}100%{opacity:0; transform:translate(-30%,-64px) scale(3.4)}}
.cake-texts{margin-top:26px; max-width:440px}
.cake-line{font-family:var(--serif); font-size:19.5px; line-height:1.55}
.cake-line.dim-text{color:var(--muted); font-size:16.5px; margin-top:5px; font-style:italic}
.cake-hint{margin-top:18px; font-size:13.5px; color:var(--gold2); letter-spacing:.02em}
#after-blow{margin-top:8px; max-width:460px}
.blow-line{font-family:var(--serif); font-size:20px; line-height:1.6; opacity:0; transform:translateY(10px); transition:opacity .9s ease, transform .9s ease; margin-top:8px}
.blow-line.show{opacity:1; transform:none}
.confetti{position:fixed; top:-4vh; z-index:40; border-radius:2px; pointer-events:none; animation:confFall linear forwards}
@keyframes confFall{to{transform:translateY(112vh) rotate(720deg)}}

/* — Thẻ điều ước — */
.wish-title{font-family:var(--serif); font-size:clamp(21px,5.6vw,28px); line-height:1.45; max-width:480px; margin-top:14px}
.tags{display:flex; flex-wrap:wrap; gap:16px; justify-content:center; margin-top:38px; max-width:430px}
.tag{position:relative; width:128px; padding:30px 12px 18px; background:linear-gradient(180deg,#fdf6ec,#f7e8d8); color:#5b3a2e;
  border-radius:6px 6px 14px 14px; cursor:pointer; box-shadow:0 16px 32px rgba(0,0,0,.4); font-family:var(--serif); font-weight:600; font-size:15.5px; line-height:1.4;
  transition:transform .35s var(--ease), opacity .5s var(--ease), filter .5s var(--ease); animation:sway 3.6s ease-in-out infinite}
.tag::before{content:""; position:absolute; top:-16px; left:50%; transform:translateX(-50%); width:2px; height:16px; background:rgba(247,234,217,.5)}
.tag::after{content:""; position:absolute; top:7px; left:50%; transform:translateX(-50%) rotate(45deg); width:10px; height:10px;
  border-radius:2.5px; background:linear-gradient(135deg,#f9d3e2,#e88bb0); box-shadow:0 1px 4px rgba(160,60,100,.35)}
.tag .fl{position:absolute; bottom:8px; right:10px; opacity:.75; line-height:0}
.tag .fl svg{width:13px; height:13px; display:block}
.tag:hover{transform:translateY(-5px) rotate(-1.4deg)}
.tag.gone{opacity:0; transform:translateY(26px) rotate(5deg); pointer-events:none}
.tag.picked{animation:none; transform:scale(1.1); box-shadow:0 0 0 2px var(--gold), 0 20px 44px rgba(255,196,107,.4)}
@keyframes sway{0%,100%{transform:rotate(-1.6deg)}50%{transform:rotate(1.6deg)}}
.wish-confirm{margin-top:30px; font-family:var(--serif); font-style:italic; font-size:17.5px; color:var(--gold2); opacity:0; transition:opacity .8s; max-width:440px}
.wish-confirm.show{opacity:1}

/* — Trái tim ghép ảnh — */
#mosaic{display:grid; gap:3px; margin-top:8px; cursor:pointer; filter:drop-shadow(0 18px 40px rgba(232,139,176,.35))}
#mosaic .cell{width:100%; aspect-ratio:1; border-radius:3px; overflow:hidden; opacity:0; transform:scale(.4)}
#mosaic .cell.in{animation:cellIn .5s ease forwards}
#mosaic .cell img{width:100%; height:100%; object-fit:cover; display:block}
@keyframes cellIn{to{opacity:1; transform:scale(1)}}
.heart-line{margin-top:30px; font-weight:400; color:var(--muted); font-size:15px}
.heart-title{font-family:var(--serif); font-size:clamp(27px,7vw,37px); margin-top:7px}
.heart-hint{margin-top:10px; font-size:13px; color:rgba(247,234,217,.45)}
.heart-actions{display:flex; gap:12px; flex-wrap:wrap; justify-content:center}
.heart-actions .btn-glow, .heart-actions .btn-ghost-l{margin-top:22px}

/* — Xem ảnh — */
.viewer-card{background:#fdfaf4; padding:12px 12px 14px; border-radius:8px; width:min(84vw,340px);
  border:1px solid rgba(255,255,255,.35);
  box-shadow:0 26px 54px rgba(0,0,0,.55), 0 10px 22px rgba(0,0,0,.35), 0 2px 6px rgba(0,0,0,.25); transform:rotate(-1.4deg)}
.viewer-card img{width:100%; height:min(52svh,430px); object-fit:cover; border-radius:4px; display:block; background:#eadfd2}
.viewer-card figcaption{font-family:var(--script); font-size:21px; color:#7a4a5e; padding-top:10px; min-height:34px}
.viewer-nav{display:flex; align-items:center; gap:16px; margin-top:22px}
.v-btn{width:44px; height:44px; border-radius:50%; border:1px solid rgba(255,255,255,.35); background:rgba(255,255,255,.06); color:var(--ink); font-size:24px; cursor:pointer; line-height:1;
  backdrop-filter:blur(14px); -webkit-backdrop-filter:blur(14px); transition:transform .3s var(--ease), background .3s var(--ease)}
.v-btn:active{transform:scale(.97)}
.v-dots{display:flex; gap:7px}
.v-dots span{width:7px; height:7px; border-radius:50%; background:rgba(247,234,217,.3); transition:all .25s}
.v-dots span.on{background:var(--gold); transform:scale(1.35)}

/* — Lá thư — */
.paper{position:relative; margin-top:26px; width:min(88vw,430px); background:linear-gradient(180deg,#fffdf6,#fdf3e3); color:#5b4232;
  border-radius:4px; padding:38px 30px 30px; text-align:left; transform:rotate(-.7deg);
  box-shadow:0 30px 60px rgba(0,0,0,.5);
  -webkit-mask-image:radial-gradient(circle 5px at 8px 8px, transparent 4.5px, #000 5.5px); -webkit-mask-size:16px 16px; -webkit-mask-position:-8px -8px; -webkit-mask-composite:destination-out;
  mask-image:radial-gradient(circle 5px at 8px 8px, transparent 4.5px, #000 5.5px); mask-size:16px 16px; mask-position:-8px -8px; mask-composite:intersect}
.paper-photo{position:absolute; top:-20px; right:-10px; width:64px; height:78px; object-fit:cover; border:4px solid #fff; border-bottom-width:13px;
  border-radius:3px; transform:rotate(7deg); box-shadow:0 10px 22px rgba(0,0,0,.35); background:#fff}
#letter-body p{font-family:var(--script); font-size:20.5px; line-height:1.75; margin-bottom:13px; opacity:0; transform:translateY(8px); transition:opacity .8s ease, transform .8s ease}
#letter-body p.show{opacity:1; transform:none}
.paper-sign{font-family:var(--script); font-size:22px; text-align:right; color:#8a5a44; opacity:0; transition:opacity .8s}
.paper-sign.show{opacity:1}

/* — Thiệp cuối & trời sao — */
.final-card{border:1px solid rgba(255,255,255,.35); border-radius:14px; padding:38px 30px; max-width:470px;
  background:rgba(255,255,255,.05); backdrop-filter:blur(14px); -webkit-backdrop-filter:blur(14px);
  box-shadow:0 30px 64px rgba(0,0,0,.45), 0 10px 24px rgba(0,0,0,.3), inset 0 0 0 5px rgba(29,11,22,.35), inset 0 0 0 6px rgba(255,196,107,.28), inset 0 1px 0 rgba(255,255,255,.18)}
.final-title{font-family:var(--serif); font-size:clamp(24px,6.4vw,32px); margin-top:12px; line-height:1.35}
.final-rule{width:54px; height:1.5px; background:var(--gold); margin:18px auto; opacity:.8}
.final-msg{font-weight:400; font-size:15.5px; line-height:1.75; color:rgba(247,234,217,.85)}
.final-name{font-size:27px; color:var(--pink); margin-top:16px}
#big-star{margin-top:34px; cursor:pointer; line-height:0;
  filter:drop-shadow(0 0 22px rgba(255,212,110,.95)) drop-shadow(0 0 60px rgba(255,190,80,.55));
  animation:starPulse 1.7s ease-in-out infinite; transition:opacity .5s var(--ease), transform .5s var(--ease)}
#big-star svg{width:76px; height:76px; display:block}
@keyframes starPulse{0%,100%{transform:scale(1) rotate(0deg)}50%{transform:scale(1.14) rotate(8deg)}}
#big-star.sent{opacity:0; transform:scale(2.2); pointer-events:none}
.sent-title{font-size:clamp(34px,9vw,46px); margin-top:16px; color:var(--gold2)}
#sky-done .final-msg{max-width:440px; margin:10px auto 0}
.meteor{position:fixed; z-index:31; width:3px; height:3px; border-radius:50%; background:#fff; pointer-events:none;
  box-shadow:0 0 8px 2px rgba(255,240,200,.9)}
.meteor::after{content:""; position:absolute; right:0; top:50%; transform:translateY(-50%); width:110px; height:1.6px;
  background:linear-gradient(90deg, rgba(255,240,200,.95), transparent)}
.petal{position:fixed; top:-4vh; z-index:29; pointer-events:none; opacity:.85; animation:petalFall linear forwards}
.petal svg{width:100%; height:100%; display:block}
@keyframes petalFall{to{transform:translateY(112vh) rotate(320deg)}}
/* Lớp hạt mịn (noise) phủ cố định — chiều sâu bề mặt kiểu bản in cao cấp */
body::after{content:""; position:fixed; inset:0; z-index:90; pointer-events:none; opacity:.035;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)' opacity='0.55'/%3E%3C/svg%3E");
  background-size:160px 160px}
@media (prefers-reduced-motion: reduce){
  #flame, .tag, #big-star{animation:none}
  .screen.active{animation:none}
  .btn-glow, .btn-ghost-l, .v-btn, .tag{transition:none}
}

/* ===== Lov3ly ambient: cánh hoa rơi + mở trang mượt ===== */
.lv-ambient{position:fixed; inset:0; pointer-events:none; z-index:4; overflow:hidden}
.lv-ambient span{position:absolute; top:-6vh; opacity:0; animation-name:lvFall; animation-timing-function:linear; animation-iteration-count:infinite; will-change:transform,opacity}
@keyframes lvFall{0%{transform:translate3d(0,-6vh,0) rotate(0deg); opacity:0} 8%{opacity:.5} 50%{transform:translate3d(2.6vw,52vh,0) rotate(170deg)} 92%{opacity:.42} 100%{transform:translate3d(-1.6vw,108vh,0) rotate(330deg); opacity:0}}
body{animation:lvPageIn .55s ease both}
@keyframes lvPageIn{from{opacity:0} to{opacity:1}}
@media (prefers-reduced-motion: reduce){ .lv-ambient{display:none} body{animation:none} }

/* Lửa nến lập lòe */
#flame{animation:flameFlicker 1.7s ease-in-out infinite}
@keyframes flameFlicker{0%,100%{filter:brightness(1)} 28%{filter:brightness(1.22)} 52%{filter:brightness(.93)} 76%{filter:brightness(1.12)}}

/* ===== Nâng cấp nến: gộp animation lửa + halo đồng bộ + khói + confetti + thư =====
   Trước đây rule flameFlicker ở cuối file ghi đè mất animation "flick" (đung đưa)
   và nuốt luôn drop-shadow phát sáng của lửa. Khối này hợp nhất cả ba:
   đung đưa (transform có var --bsx/--bsy do applyBlow điều khiển khi thổi),
   lập lòe sáng (filter brightness + drop-shadow), quầng halo cùng nhịp 1.7s. */
#flame{animation:flick2 .19s ease-in-out infinite alternate, flameGlow 1.7s ease-in-out infinite}
@keyframes flick2{
  from{transform:translateX(-50%) scale(var(--bsx,1),var(--bsy,1)) rotate(-2deg)}
  to{transform:translateX(-52%) scale(calc(var(--bsx,1)*1.07),calc(var(--bsy,1)*1.13)) rotate(2.5deg)}
}
@keyframes flameGlow{
  0%,100%{filter:brightness(1) drop-shadow(0 0 14px rgba(255,170,60,.95)) drop-shadow(0 0 42px rgba(255,140,50,.5))}
  28%{filter:brightness(1.22) drop-shadow(0 0 18px rgba(255,180,70,1)) drop-shadow(0 0 54px rgba(255,150,55,.62))}
  52%{filter:brightness(.93) drop-shadow(0 0 11px rgba(255,160,55,.85)) drop-shadow(0 0 34px rgba(255,130,45,.42))}
  76%{filter:brightness(1.12) drop-shadow(0 0 16px rgba(255,175,65,.98)) drop-shadow(0 0 48px rgba(255,145,50,.55))}
}
#flame::before{content:""; position:absolute; left:50%; top:46%; width:118px; height:118px; z-index:-1;
  transform:translate(-50%,-50%); border-radius:50%; pointer-events:none;
  background:radial-gradient(circle, rgba(255,196,107,.5) 0%, rgba(255,150,60,.22) 42%, rgba(255,130,50,0) 70%);
  animation:haloPulse 1.7s ease-in-out infinite}
@keyframes haloPulse{
  0%,100%{opacity:.55; transform:translate(-50%,-50%) scale(1)}
  28%{opacity:.85; transform:translate(-50%,-50%) scale(1.07)}
  52%{opacity:.45; transform:translate(-50%,-50%) scale(.96)}
  76%{opacity:.72; transform:translate(-50%,-50%) scale(1.04)}
}
/* Làn khói mỏng sau khi thổi tắt: nhiều vệt nhỏ bay lên, loang và tan dần */
.smoke-wisp{position:absolute; left:50%; top:0; border-radius:50%; pointer-events:none; z-index:5; opacity:0;
  background:radial-gradient(circle, rgba(235,230,230,.5) 0%, rgba(235,230,230,0) 70%); filter:blur(2px);
  animation:smokeRise var(--sd,2.8s) ease-out var(--sdel,0s) forwards}
@keyframes smokeRise{
  0%{opacity:0; transform:translate(-50%,6px) scale(.5)}
  14%{opacity:.75}
  55%{opacity:.36}
  100%{opacity:0; transform:translate(calc(-50% + var(--dx,10px)),-104px) scale(2.6)}
}
/* Confetti vàng có vật lý: đung đưa hai bên giảm dần, lật 3D, xoay theo --rot */
.confetti{animation-name:confFall2; animation-timing-function:cubic-bezier(.25,.45,.45,1)}
@keyframes confFall2{
  0%{transform:translate3d(0,-5vh,0) rotate(0deg) rotateX(0deg); opacity:0}
  6%{opacity:1}
  22%{transform:translate3d(var(--sway,14px),24vh,0) rotate(calc(var(--rot,540deg)*.28)) rotateX(160deg)}
  48%{transform:translate3d(calc(var(--sway,14px)*-.7),52vh,0) rotate(calc(var(--rot,540deg)*.55)) rotateX(340deg)}
  74%{transform:translate3d(calc(var(--sway,14px)*.55),78vh,0) rotate(calc(var(--rot,540deg)*.8)) rotateX(500deg)}
  100%{transform:translate3d(calc(var(--sway,14px)*-.3),110vh,0) rotate(var(--rot,540deg)) rotateX(680deg); opacity:.92}
}
/* Thư tay: từng dòng hết mờ thành nét như mực thấm giấy */
#letter-body p{filter:blur(3px); transition:opacity .9s ease, transform .9s ease, filter .9s ease}
#letter-body p.show{filter:blur(0)}
@media (prefers-reduced-motion: reduce){
  #flame, #flame::before{animation:none}
  .smoke-wisp{display:none}
}
