/* ================= 第十一幕 生日夜 ================= */
.nt-stage { --wind: 0; }
.nt-lights { position: absolute; left: 0; right: 0; top: calc(0px + var(--st)); width: 100%; height: 14%; z-index: 2; overflow: visible; opacity: 0; transform: translateY(-100%); will-change: transform, opacity; }
.nt-wire { fill: none; stroke: #2a1a12; stroke-width: 2; vector-effect: non-scaling-stroke; }
.nt-bulb { fill: #5a4a6a; stroke: #2a1a12; stroke-width: 1.5; vector-effect: non-scaling-stroke; transition: fill .4s, filter .4s; }
.nt-bulb.on.b0 { fill: #ffd36b; filter: drop-shadow(0 0 6px #ffd36b); }
.nt-bulb.on.b1 { fill: #ff9ec4; filter: drop-shadow(0 0 6px #ff9ec4); }
.nt-bulb.on.b2 { fill: #9cc6ff; filter: drop-shadow(0 0 6px #9cc6ff); }
.nt-bulb.on.b3 { fill: #fff1c4; filter: drop-shadow(0 0 6px #fff1c4); }
.st-dark .nt-bulb.on { fill: #5a4a6a; filter: none; }
.st-party .nt-bulb.on { animation: bulbs 1s steps(2) infinite; }
@keyframes bulbs { 50% { opacity: .35; } }
.nt-fw { position: absolute; inset: 0; width: 100%; height: 100%; z-index: 5; pointer-events: none; }
.nt-head { position: absolute; top: calc(13% + var(--st)); left: 0; right: 0; z-index: 3; display: flex; flex-direction: column; align-items: center; gap: 10px; text-align: center; pointer-events: none; }
.nt-intro { font-size: clamp(16px, 4.6vw, 21px); }
.nt-cake { position: absolute; left: 50%; bottom: calc(21% + var(--sb)); width: min(74vw, 380px); aspect-ratio: 640 / 620; z-index: 3; opacity: 0; touch-action: pan-y; transition: filter 1.4s ease; }
.st-dark .nt-cake { filter: brightness(.45) saturate(.75); }
.st-party .nt-cake { filter: brightness(.8) saturate(.9); }
@media (max-height: 700px) { .nt-cake { width: min(62vw, 330px); } }
.nt-cakeimg { position: absolute; inset: 0; width: 100%; height: 100%; }
.nt-cakeglow { position: absolute; left: 50%; top: 34%; width: 130%; aspect-ratio: 1; transform: translate(-50%, -50%); border-radius: 50%; background: radial-gradient(circle, rgba(255, 210, 140, .45), rgba(255, 170, 120, .15) 40%, rgba(255, 150, 120, 0) 66%); transition: opacity .8s; }
.st-dark .nt-cakeglow { opacity: 0; }
.cdl { position: absolute; width: 5.4%; transform: translate(-50%, -96%); cursor: pointer; }
.cdl img { width: 100%; aspect-ratio: 40 / 150; }
.flame { position: absolute; left: 50%; top: 4%; width: 125%; aspect-ratio: .52; margin-left: -62.5%; transform-origin: 50% 100%; transform: translateY(-88%) skewX(calc(var(--wind) * -30deg)) scaleY(calc(1 - var(--wind) * .25));
  border-radius: 50% 50% 45% 45% / 62% 62% 38% 38%; background: radial-gradient(ellipse at 50% 72%, #fff 0 16%, #fff0b0 26%, #ffc45a 48%, rgba(255, 130, 60, .55) 62%, rgba(255, 110, 50, 0) 74%);
  filter: drop-shadow(0 0 4px rgba(255, 190, 90, .8)); transition: transform .25s, opacity .25s; }
.flame::after { content: ''; position: absolute; left: 50%; top: 50%; width: 260%; aspect-ratio: 1; transform: translate(-50%, -40%); border-radius: 50%; background: radial-gradient(circle, rgba(255, 200, 110, .18), rgba(255, 200, 110, 0) 60%); pointer-events: none; }
.cdl:not(.out) .flame { animation: flick 1.1s ease-in-out infinite alternate; animation-delay: calc(var(--fd) * -1); }
@keyframes flick { 0% { rotate: -3deg; scale: 1 1; } 40% { rotate: 2deg; scale: .94 1.06; } 70% { rotate: -1deg; scale: 1.03 .96; } 100% { rotate: 3deg; scale: .98 1.03; } }
.cdl.out .flame { opacity: 0; transform: translateY(-88%) scale(.1); }
.smoke { position: absolute; left: 50%; top: -10%; width: 220%; aspect-ratio: 1; margin-left: -110%; border-radius: 50%; background: radial-gradient(circle, rgba(220, 220, 235, .6), rgba(220, 220, 235, 0) 70%); opacity: 0; pointer-events: none; }
.cdl.out .smoke { animation: smoke 2.4s ease-out forwards; }
@keyframes smoke { 0% { opacity: .9; transform: translateY(0) scale(.6); } 100% { opacity: 0; transform: translate(10px, -80px) scale(2.4); } }
.nt-pet { position: absolute; bottom: -2%; width: 30%; aspect-ratio: 1; z-index: 700; }
.nt-pet .puppet { width: 100%; height: 100%; }
.nt-dog { left: -14%; } .nt-cat { right: -14%; }
.st-party .nt-head, .st-dark .nt-head, .wishing .nt-head { opacity: 0 !important; transition: opacity .8s; }
.wishing .nt-ctrl { opacity: 0; pointer-events: none; }
.nt-ctrl { transition: opacity .8s; }
.nt-happy { position: absolute; left: 0; right: 0; top: 30%; z-index: 6; text-align: center; pointer-events: none; padding: 0 16px; }
.nt-happy b { display: inline-block; font-weight: normal; line-height: 1.3; font-size: clamp(36px, 10.5vw, 66px); color: #fff2c4; opacity: 0; transform: scale(.3); transition: all .8s var(--ease-pop); }
.st-party .nt-happy b { opacity: 1; transform: none; }
.st-done .nt-happy b { opacity: 0; transform: scale(.9) translateY(-20px); transition-duration: 1s; }
.nt-ctrl { position: absolute; left: 0; right: 0; bottom: calc(5% + var(--sb)); z-index: 7; display: flex; justify-content: center; pointer-events: none; }
.nc-step { position: absolute; bottom: 0; left: 16px; right: 16px; display: flex; flex-direction: column; align-items: center; gap: 10px; text-align: center; opacity: 0; transform: translateY(16px); transition: all .5s var(--ease-pop); pointer-events: none; }
.nc-step p { font-size: 17px; }
.nt-ctrl.ready .nc-step { pointer-events: none; }
.st-wish .nt-ctrl.ready .s1, .st-blow .nt-ctrl.ready .s2, .st-done .nt-ctrl.ready .s3 { opacity: 1; transform: none; pointer-events: auto; }
.nc-alt { font-size: 13px !important; color: var(--txt2); }
.nc-meter { width: 160px; height: 10px; border-radius: 99px; border: 2px solid var(--ink); background: rgba(255, 255, 255, .2); overflow: hidden; opacity: 0; transition: opacity .3s; }
.listening .nc-meter { opacity: 1; }
.nc-meter i { display: block; height: 100%; width: 0; background: linear-gradient(90deg, #9cc6ff, #ffffff); transition: width .08s; }
.nt-wishing { position: absolute; inset: 0; z-index: 9; display: flex; align-items: flex-start; justify-content: center; padding-top: calc(17% + var(--st)); opacity: 0; pointer-events: none; transition: opacity 1.2s ease;
  background: radial-gradient(ellipse 80% 30% at 50% 22%, rgba(6, 4, 26, .45), rgba(6, 4, 26, .18) 60%, rgba(6, 4, 26, 0) 100%); }
.wishing .nt-wishing { opacity: 1; }
.nt-wishing p { font-size: clamp(26px, 8vw, 44px); color: #fff2c4; text-align: center; padding: 0 20px; text-shadow: 0 0 30px rgba(255, 200, 120, .8); }
.nt-wishing p.pop { animation: wishpop .9s var(--ease-pop); }
@keyframes wishpop { 0% { transform: scale(.5); opacity: 0; } 100% { transform: none; opacity: 1; } }

/* letter overlay */
.letter-ov { position: fixed; inset: 0; z-index: 130; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 18px; opacity: 0; transition: opacity .45s; }
.letter-ov.on { opacity: 1; }
.lt-back { position: absolute; inset: 0; background: rgba(14, 8, 46, .82); }
.lt-env { position: relative; width: min(78vw, 380px); aspect-ratio: 620 / 440; cursor: pointer; transition: opacity .6s, transform .6s; animation: envfloat 2.4s ease-in-out infinite; }
@keyframes envfloat { 0%, 100% { transform: translateY(0) rotate(-2deg); } 50% { transform: translateY(-10px) rotate(2deg); } }
.lt-env img { position: absolute; inset: 0; width: 100%; height: 100%; }
.le-back { z-index: 0; } .le-paper { z-index: 1; } .le-front { z-index: 3; } .le-flap { z-index: 4; transform-origin: 50% 17%; transition: transform .7s ease-in-out; } .le-seal { z-index: 5; transition: transform .4s var(--ease-pop), opacity .4s; }
.le-paper { position: absolute; left: 12%; right: 12%; top: 20%; height: 66%; background: #fff6e8 repeating-linear-gradient(transparent 0 14px, rgba(255, 150, 190, .35) 14px 15px); border: 2.5px solid var(--ink); border-radius: 6px; transition: transform .9s cubic-bezier(.3, 1.3, .5, 1); }
.seal-off .le-seal { transform: scale(0) rotate(90deg); opacity: 0; }
.flap-open .le-flap { transform: perspective(700px) rotateX(180deg); z-index: 0; }
.paper-up .le-paper { transform: translateY(-62%); }
.reading .lt-env { opacity: 0; transform: scale(.8) translateY(40px); pointer-events: none; animation: none; }
.lt-tap { position: relative; font-size: 16px; color: var(--gold3); animation: tapb 1.6s ease-in-out infinite; }
.flap-open .lt-tap { opacity: 0; }
.lt-sheet { position: absolute; left: 50%; top: 50%; width: min(92vw, 540px); max-height: calc(var(--vh) * 88); overflow-y: auto; padding: 30px 24px 26px; transform: translate(-50%, -46%) scale(.7); opacity: 0; pointer-events: none; transition: all .7s var(--ease-pop);
  background: #fff6e8 url(../assets/art/paper.webp) center / 380px; }
.reading .lt-sheet { opacity: 1; transform: translate(-50%, -50%); pointer-events: auto; }
.lt-text { min-height: 300px; font-size: 18px; line-height: 2.05; color: #3a2418; background: repeating-linear-gradient(transparent 0 calc(2.05em - 1px), rgba(255, 140, 180, .3) calc(2.05em - 1px) 2.05em); }
.lt-text p { text-indent: 2em; margin: 0; text-wrap: wrap; text-wrap: pretty; }
.lt-text p.lt-greet { text-indent: 0; font-family: var(--f-cute); font-size: 20px; color: var(--rose); }
.lt-sign { display: flex; flex-direction: column; align-items: flex-end; margin-top: 14px; opacity: 0; transition: opacity 1s; }
.lt-sign b { font-weight: normal; font-size: 20px; }
.lt-sign span { font-size: 14px; color: var(--ink2); }
.lt-btns { display: flex; flex-direction: column; align-items: center; gap: 10px; margin-top: 22px; opacity: 0; transform: translateY(10px); transition: all .7s; pointer-events: none; }
.typed .lt-sign { opacity: 1; }
.typed .lt-btns { opacity: 1; transform: none; pointer-events: auto; }
/* the two of them sit at the very end of the letter, on either side of the buttons (in the flow, so they never cover a line) */
.lt-pets { display: flex; justify-content: space-between; margin: -62px -10px -12px; pointer-events: none; opacity: 0; transition: opacity 1s; }
.typed .lt-pets { opacity: 1; }
.lt-dog, .lt-cat { width: 62px; height: 62px; background: center / contain no-repeat; opacity: .95; }
.lt-dog { background-image: url(../assets/art/dog/full.webp); } .lt-cat { background-image: url(../assets/art/cat/full.webp); }

/* letter section + poster */
#ch-letter { padding: calc(var(--vh) * 8) 0 calc(var(--vh) * 4); }
.lr-wrap { display: flex; flex-direction: column; align-items: center; gap: 16px; text-align: center; }
.lr-env { position: relative; width: 210px; aspect-ratio: 620 / 440; }
.lr-env img { position: absolute; inset: 0; width: 100%; height: 100%; }
#ch-letter.locked .lr-env { filter: grayscale(.7) brightness(.8); }
.lr-msg { font-size: 17px; }
.lr-btns { display: flex; flex-wrap: wrap; justify-content: center; gap: 12px; }
.m-poster .modal-box { width: min(100%, 420px); text-align: center; padding: 18px 16px 18px; }
.poster { display: flex; flex-direction: column; align-items: center; gap: 12px; }
.po-img { width: 100%; aspect-ratio: 9 / 16; max-height: calc(var(--vh) * 58); display: flex; align-items: center; justify-content: center; border-radius: 12px; overflow: hidden; border: 3px solid var(--ink); background: #2a2380; }
.po-img img { width: 100%; height: 100%; object-fit: contain; -webkit-touch-callout: default; user-select: auto; -webkit-user-select: auto; }
.po-img.busy img { opacity: .5; }
.po-loading { color: #fff2c4; font-size: 15px; padding: 20px; }
.po-opts { display: flex; flex-wrap: wrap; justify-content: center; align-items: center; gap: 10px; }
.po-row { display: flex; gap: 6px; }
.po-st { font-size: 14px; padding: 4px 12px; border: 2.5px solid var(--ink); border-radius: 99px; background: var(--cream); color: var(--ink); }
.po-st.on { background: var(--pink); }

.modal.m-poster, .modal.m-save { z-index: 140; }
