/* ==========================================================
   致 庚欣 · 一封生日信    （全部图形由 SVG 绘制）
   色调：炉火琥珀
   ========================================================== */

:root{
  --paper:      #f2ead6;
  --paper-hi:   #f8f2e2;
  --ink:        #2b241c;
  --ink-2:      #4c453a;
  --ink-3:      #6f6656;
  --red:        #9e2b1f;
  --gold:       #b08d4a;
  --gold-deep:  #8a6a2f;
  --cream:      #f0e2c6;
  --night:      #140d07;
  --night-2:    #22150c;

  --f-brush: 'Ma Shan Zheng','KaiTi','STKaiti','Kaiti SC','AR PL UKai CN',cursive;
  --f-serif: 'Noto Serif SC','Songti SC','STSong','SimSun','Noto Serif CJK SC',serif;
  --f-latin: 'Cormorant Garamond',Georgia,'Times New Roman',serif;
}

*{box-sizing:border-box}
html{height:100%;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}
body{
  margin:0;min-height:100%;
  background:var(--night);
  color:var(--ink);
  font-family:var(--f-serif);
  -webkit-font-smoothing:antialiased;
  text-rendering:optimizeLegibility;
  overflow-x:hidden;
  overscroll-behavior-y:contain;
}
body.locked{overflow:hidden;height:100vh;height:100dvh}
body.unlocked{background:#eadcc0}
::selection{background:rgba(176,141,74,.28)}
button{touch-action:manipulation;-webkit-tap-highlight-color:transparent}
.gate,.envelope,.stamp-cluster,.ornament,.candle-sec,.finale .hb,.hb-flourish,.signature,.player,.dust,.verse{-webkit-user-select:none;user-select:none}

.svg-defs{position:absolute;width:0;height:0;overflow:hidden}
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
.brush{font-family:var(--f-brush);font-weight:400}
.latin{font-family:var(--f-latin);letter-spacing:.28em;text-transform:uppercase}

/* ---------- 全局图层 ---------- */
.layer{position:fixed;inset:0;pointer-events:none}
.layer svg{display:block;width:100%;height:100%}
.layer-grain{z-index:30}
.grain-mult{mix-blend-mode:multiply;opacity:.42}
.grain-screen{mix-blend-mode:screen;opacity:.05}
.layer-leaves{z-index:31;overflow:hidden}
.layer-ripples{z-index:33;overflow:hidden}
.layer-pointerglow{z-index:29;opacity:0;transition:opacity 1.2s}
body:not(.unlocked) .layer-pointerglow{opacity:.6}
@media (hover:none){.layer-pointerglow{display:none}}
#glowCircle{transform-box:fill-box;transform-origin:center;opacity:.3}

.leaf-fall{animation:leafFall linear infinite}
@keyframes leafFall{from{transform:translateY(-10vh)}to{transform:translateY(112vh)}}
.leaf-sway{animation:leafSway ease-in-out infinite alternate}
@keyframes leafSway{from{transform:translateX(-16px)}to{transform:translateX(16px)}}
.leaf-rot{animation:leafRot linear infinite}
@keyframes leafRot{to{transform:rotate(360deg)}}

.ripple{fill:none;stroke:rgba(158,43,31,.45);transform-box:fill-box;transform-origin:center;animation:rip .8s ease-out both}
@keyframes rip{from{opacity:.5;transform:scale(.12)}to{opacity:0;transform:scale(1)}}

.mote{transform-box:fill-box;transform-origin:center;animation:moteRise ease-in-out infinite alternate,moteFade ease-in-out infinite alternate}
@keyframes moteRise{from{transform:translateY(0)}to{transform:translateY(-46px)}}
@keyframes moteFade{from{opacity:.06}to{opacity:.42}}

/* ==========================================================
   场景一 · 书房来信
   ========================================================== */
.gate{
  position:fixed;inset:0;z-index:50;
  background:var(--night);
  overflow-y:auto;overflow-x:hidden;
  transition:opacity .8s ease,transform 1.1s cubic-bezier(.3,.6,.3,1);
}
.gate.done{opacity:0;transform:scale(1.06);pointer-events:none}
.gate-bg{position:fixed;inset:0}
.gate-bg svg{display:block}
.bg-room{position:absolute;inset:0;width:100%;height:100%}
.bg-moon{position:absolute;top:7%;right:8%;width:clamp(58px,9.5vw,110px);height:auto}
.bg-candle{
  position:absolute;
  left:clamp(6px,4.6vw,96px);
  bottom:clamp(44px,9vh,104px);
  width:clamp(56px,8vw,104px);height:auto;
  opacity:.95;
}
.bg-candle .dc-glow{opacity:.85;animation:glowPulse 3.6s ease-in-out infinite}
.bg-candle .dc-flame{transform-box:fill-box;transform-origin:50% 100%;animation:flick1 1.15s ease-in-out infinite alternate}
.bg-candle .dc-flame path:nth-child(2){transform-box:fill-box;transform-origin:50% 100%;animation:flick2 1.9s ease-in-out infinite alternate}
@keyframes flick1{from{transform:scaleY(1) scaleX(1)}to{transform:scaleY(1.08) scaleX(.95)}}
@keyframes flick2{from{transform:scaleY(.95) scaleX(1.05)}to{transform:scaleY(1.06) scaleX(.96)}}
@keyframes glowPulse{0%,100%{opacity:.7}50%{opacity:.95}}

.gate-inner{
  position:relative;z-index:2;
  width:100%;max-width:880px;margin:0 auto;
  min-height:100vh;min-height:100dvh;
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:clamp(.9rem,3.2vh,1.9rem);
  padding:clamp(1.4rem,4.5vh,2.8rem) clamp(1rem,4vw,2rem) calc(clamp(3.4rem,7.5vh,5rem) + env(safe-area-inset-bottom));
}
.gate-head{text-align:center;transition:opacity .7s ease,transform .7s ease}
.gate.risen .gate-head{opacity:0;transform:translateY(-12px)}
.gate-title{
  margin:0;color:#f3e6cb;
  font-size:clamp(2.05rem,7.4vw,3.5rem);
  letter-spacing:.16em;text-indent:.16em;
  text-shadow:0 0 40px rgba(244,170,84,.34),0 2px 0 rgba(0,0,0,.25);
}
.gate-sub{
  margin:.7rem 0 0;color:rgba(240,226,198,.6);
  font-size:clamp(.78rem,2.7vw,.92rem);
  letter-spacing:.24em;text-indent:.24em;
}
.gate.intro .gate-head{animation:fadeDown 1.3s ease both}
.gate.intro .env-group{animation:fadeUp 1.4s ease .15s both}
@keyframes fadeDown{from{opacity:0;transform:translateY(-14px)}to{opacity:1;transform:none}}
@keyframes fadeUp{from{opacity:0;transform:translateY(16px)}to{opacity:1;transform:none}}

/* 信封与表单作为一个整体 */
.env-group{
  display:flex;flex-direction:column;align-items:center;
  gap:clamp(.85rem,2.4vh,1.35rem);
  width:100%;
}
.env-wrap{width:min(88vw,500px);margin-top:calc(-1 * clamp(2rem,4vw,3.4rem))}
.envelope{width:100%;height:auto;display:block}
.gate.intro .envelope{animation:envIn 1.5s ease .1s both,envFloat 7s ease-in-out 1.6s infinite}
@keyframes envIn{from{opacity:0;transform:translateY(18px) scale(.97)}to{opacity:1;transform:none}}
@keyframes envFloat{0%,100%{transform:translateY(0) rotate(-.25deg)}50%{transform:translateY(-6px) rotate(.25deg)}}
.env-wrap.sealing .envelope{animation:none}
.env-wrap.shake{animation:envShake .52s ease}
@keyframes envShake{
  10%,90%{transform:translateX(-3px)}
  20%,80%{transform:translateX(5px)}
  30%,50%,70%{transform:translateX(-8px) rotate(-.4deg)}
  40%,60%{transform:translateX(8px) rotate(.4deg)}
}

/* --- 名址书写 & 墨迹被退回 --- */
#envName{transform-box:fill-box;transform-origin:50% 100%}
#envName.blot{animation:blot .9s cubic-bezier(.4,0,.7,1) forwards}
@keyframes blot{
  0%{opacity:1;filter:blur(0);transform:none}
  40%{opacity:.75;filter:blur(2.6px);transform:translateY(2px) scaleY(.95)}
  100%{opacity:0;filter:blur(9px);transform:translateY(8px) scaleY(.78)}
}

/* --- 信封开启动画 --- */
#flapClosed{transform-box:fill-box;transform-origin:50% 0%;transition:transform .42s cubic-bezier(.55,0,.75,.5)}
.gate.open #flapClosed{transform:scaleY(0)}
#flapOpen{transform-box:fill-box;transform-origin:50% 100%;transform:scaleY(0);transition:transform .5s cubic-bezier(.2,.75,.3,1)}
.gate.open #flapOpen{transform:scaleY(1)}
#envInside{transition:opacity .55s ease}
.gate.open #envInside{opacity:1}
#envInsideShade{transition:opacity .7s ease .15s}
.gate.open #envInsideShade{opacity:1}
#letterSheet{opacity:0;transform:translateY(150px);transition:transform 1.05s cubic-bezier(.2,.78,.25,1),opacity .45s ease}
.gate.risen #letterSheet{opacity:1;transform:translateY(-172px)}

#seal{transform-box:fill-box;transform-origin:center;transition:opacity .45s ease .05s,transform .5s ease}
.gate.open #seal{opacity:0;transform:translateY(-7px) scale(.94)}
.crack{stroke-dasharray:70;stroke-dashoffset:70;transition:stroke-dashoffset .3s ease-out}
.gate.cracked #sealCracks{opacity:1}
.gate.cracked .crack{stroke-dashoffset:0}
#sealPing{transform-box:fill-box;transform-origin:center}
.gate.cracked #sealPing{animation:pingOut 1.05s ease-out .12s both}
@keyframes pingOut{from{opacity:.8;transform:scale(1)}to{opacity:0;transform:scale(2.3)}}
.crumb{transform-box:fill-box;transform-origin:center;transition:transform .95s cubic-bezier(.18,.7,.3,1),opacity .95s ease}
.crumb.fly{transform:translate(var(--tx),var(--ty)) rotate(var(--rot)) scale(.45);opacity:0}

/* --- 名字输入 --- */
.gate-form{
  width:min(86vw,400px);
  display:flex;flex-direction:column;align-items:center;gap:.8rem;
  transition:opacity .6s ease,transform .6s ease;
}
.gate.sealing .gate-form,.gate.sealing .hint{opacity:0;transform:translateY(10px);pointer-events:none}
.field{
  width:100%;
  border-bottom:1.5px solid rgba(240,226,198,.28);
  transition:border-color .35s ease;
}
.field:focus-within{border-color:rgba(240,226,198,.68)}
.field.err{border-color:#d4604a;animation:envShake .45s ease}
#nameInput{
  width:100%;background:none;border:0;outline:0;
  color:#f6ecd8;text-align:center;
  font-family:var(--f-brush);font-size:clamp(1.15rem,4.3vw,1.38rem);
  letter-spacing:.14em;text-indent:.14em;
  padding:.48rem .3rem .52rem;
  caret-color:#f0a44f;border-radius:0;appearance:none;
}
#nameInput::placeholder{color:rgba(240,226,198,.32);font-family:var(--f-brush);letter-spacing:.26em}
.seal-btn{
  font-size:1.08rem;letter-spacing:.42em;text-indent:.42em;
  color:#fbeadb;
  background:linear-gradient(180deg,#b03a2a,#8d2318);
  border:1px solid rgba(240,214,150,.34);border-radius:9px;
  padding:.58rem 1.5rem;cursor:pointer;
  box-shadow:0 8px 22px rgba(130,35,18,.42),inset 0 1px 0 rgba(255,205,170,.28);
  transition:transform .18s ease,box-shadow .2s ease,filter .2s ease;
}
.seal-btn:hover{filter:brightness(1.08);transform:translateY(-1px)}
.seal-btn:active{transform:translateY(1px) scale(.985)}
.seal-btn:focus-visible,.again-btn:focus-visible,.disc-btn:focus-visible,.candle-btn:focus-visible{outline:2px solid rgba(201,161,90,.9);outline-offset:3px}
.hint{
  margin:0;min-height:1.5em;
  color:rgba(240,226,198,.55);font-size:.82rem;letter-spacing:.16em;
  text-align:center;transition:color .4s ease,opacity .6s ease,transform .6s ease;
}
.hint.flash{color:#f0b45c}
.gate-foot{position:fixed;left:0;right:0;bottom:max(12px,env(safe-area-inset-bottom));text-align:center;z-index:3}
.gate-foot .latin{font-size:.62rem;color:rgba(240,226,198,.32)}

/* ==========================================================
   场景二 · 展开的信
   ========================================================== */
.letter{
  position:relative;z-index:1;
  opacity:0;pointer-events:none;
  min-height:100vh;min-height:100dvh;
  background:radial-gradient(120% 80% at 50% 0%,#f8f2e2 0%,#f2ead6 46%,#eadcc0 100%);
}
body.unlocked .letter{opacity:1;pointer-events:auto;transition:opacity .9s ease .1s}
.letter::after{
  content:'';position:fixed;inset:0;z-index:-1;pointer-events:none;
  background:radial-gradient(62% 52% at 50% 58%,rgba(242,178,92,.17),transparent 72%);
  opacity:0;transition:opacity 1.8s ease;
}
body.candlelit .letter::after{opacity:1}
.letter.revealed .letter-inner{animation:unfold 1.15s cubic-bezier(.2,.75,.25,1) both}
@keyframes unfold{from{opacity:0;transform:translateY(16px) scaleY(.975);filter:blur(5px)}to{opacity:1;transform:none;filter:blur(0)}}

.letter-inner{
  position:relative;
  max-width:43rem;margin:0 auto;
  padding:clamp(2.6rem,7.5vh,4.6rem) calc(clamp(1.35rem,5vw,3rem) + env(safe-area-inset-right)) 0 calc(clamp(1.35rem,5vw,3rem) + env(safe-area-inset-left));
}
.crease{position:absolute;left:0;right:0;height:3px;pointer-events:none;background:linear-gradient(180deg,rgba(160,140,105,.15),rgba(160,140,105,0) 70%)}
.crease::after{content:'';position:absolute;left:0;right:0;top:-1px;height:1px;background:rgba(255,255,255,.45)}
.c1{top:30%}.c2{top:63%}

.l-head{position:relative;margin-bottom:2.4rem}
.stamp-cluster{width:min(300px,66vw);margin:0 0 1.5rem auto;transform:rotate(-2.2deg);filter:drop-shadow(0 3px 6px rgba(80,60,30,.18))}
.stamp-cluster svg{width:100%;height:auto;display:block}
.salutation{margin:0 0 .45rem;font-size:clamp(1.9rem,7vw,2.6rem);letter-spacing:.1em;color:var(--ink)}
.sub{font-size:.7rem;letter-spacing:.2em;color:rgba(76,69,58,.6);margin:0 0 2rem}
.opening{margin:0;font-size:clamp(1.25rem,4.6vw,1.5rem);letter-spacing:.12em;color:var(--ink-2)}

.verse{display:none}
@media (min-width:1120px){
  .verse{display:flex;position:absolute;right:calc(-1 * clamp(2.6rem,7vw,6rem));top:24%}
  .v-text{
    writing-mode:vertical-rl;
    font-size:.74rem;letter-spacing:.52em;color:rgba(76,69,58,.62);
    border-right:1px solid rgba(111,102,86,.3);padding-right:.75rem;
  }
  .v-leaf{width:20px;height:34px;margin-top:1rem;transform:rotate(92deg);opacity:.8}
}

.l-body p{
  margin:0 0 1.45rem;
  font-size:clamp(1.02rem,3.6vw,1.13rem);
  line-height:2.15;letter-spacing:.02em;
  color:var(--ink);text-indent:2em;text-align:justify;
}
.wishes{margin:.4rem 0 1.9rem}
.wishes .wish{margin-bottom:.7rem}
.ornament{width:min(240px,60vw);margin:2.3rem auto;opacity:.9}
.ornament.small{width:min(200px,52vw);margin:0 auto 1.5rem}
.ornament svg{width:100%;height:auto;display:block}

.l-body-end{margin-top:2.5rem}
.l-ps{text-indent:0;color:var(--ink-2)}
.ps-label{font-size:.72rem;margin-right:.6em;color:rgba(76,69,58,.62)}
.l-last{
  margin:2.4rem 0 0;text-indent:0;
  font-size:clamp(1.5rem,5.6vw,1.95rem);letter-spacing:.14em;color:var(--ink);
}

.ink-in{opacity:0;transform:translateY(15px);filter:blur(7px)}
.ink-in.in{
  opacity:1;transform:none;filter:blur(0);
  transition:opacity 1.1s ease var(--d,0s),transform 1.25s cubic-bezier(.16,.84,.24,1) var(--d,0s),filter 1.25s ease var(--d,0s);
}

/* ---------- 点烛许愿 ---------- */
.candle-sec{position:relative;margin:3.1rem 0 0;text-align:center}
.candle-cue{margin:0 0 1.4rem;font-size:1.02rem;letter-spacing:.14em;color:var(--ink-2);text-indent:0}
.candle-btn{
  position:relative;display:inline-block;padding:0;border:0;background:none;cursor:pointer;
  filter:drop-shadow(0 10px 22px rgba(90,70,40,.14));
}
.candle{width:clamp(132px,35vw,168px);height:auto;display:block;margin:0 auto}
.candle-tap{
  display:inline-flex;align-items:center;gap:.45em;
  margin-top:.5rem;font-size:.78rem;letter-spacing:.24em;color:#8a6a2f;
  transition:opacity .6s ease;
}
.candle-tap svg{width:14px;height:14px}
.lit .candle-tap{opacity:0}
.cflame{transition:opacity .9s ease}
.cflame .f1,.cflame .f2{transform-box:fill-box;transform-origin:50% 100%}
.lit .cflame{opacity:1}
.lit .cflame .f1{animation:flick1 1.15s ease-in-out infinite alternate}
.lit .cflame .f2{animation:flick2 1.9s ease-in-out infinite alternate}
.cglow{transition:opacity 1.4s ease}
.lit .cglow{opacity:.85;animation:glowPulse 3.6s ease-in-out infinite}
.candle-wish{
  min-height:2.4em;margin:1.4rem 0 0;
  font-size:clamp(1.05rem,3.9vw,1.22rem);letter-spacing:.18em;color:#7c5a24;
  opacity:0;transform:translateY(10px);filter:blur(6px);
  transition:opacity 1.1s ease,transform 1.2s cubic-bezier(.16,.84,.24,1),filter 1.2s ease;
}
.candle-wish.in{opacity:1;transform:none;filter:blur(0)}
.candle-wish .w2{display:block;margin-top:.55em;font-size:.82em;letter-spacing:.14em;color:rgba(124,90,36,.72)}

.flight-wrap{
  position:absolute;right:-3%;top:-34%;
  width:clamp(180px,46vw,258px);
  pointer-events:none;opacity:0;transition:opacity .5s ease;
}
.flight-wrap.fly{opacity:1}
.flight-wrap.fly .trail{opacity:.75;transition:opacity 1.4s ease .4s}
.plane-fly{transform-box:fill-box;transform-origin:center}
.flight-wrap.fly .plane-fly{animation:planeFly 2.7s cubic-bezier(.4,.06,.6,.96) forwards}
@keyframes planeFly{
  0%{transform:translate(0,0) rotate(0);opacity:1}
  40%{transform:translate(-46px,-58px) rotate(-16deg);opacity:1}
  88%{transform:translate(58px,-106px) rotate(6deg);opacity:1}
  100%{transform:translate(64px,-114px) rotate(8deg);opacity:0}
}

/* ---------- 尾声 ---------- */
.finale{position:relative;margin:4.2rem 0 2.6rem;text-align:center;padding:1.2rem 0}
.dust{position:absolute;left:0;right:0;top:-34px;height:calc(100% + 68px);width:100%;pointer-events:none}
.dust circle{opacity:0}
.finale.go .dust circle{animation:dustRise var(--dur,7s) ease-in-out infinite;animation-delay:var(--dly,0s)}
@keyframes dustRise{
  0%{opacity:0;transform:translateY(24px)}
  22%{opacity:.55}
  70%{opacity:.32}
  100%{opacity:0;transform:translateY(-142px)}
}
.fin-latin{margin:0 0 1.1rem;font-size:.78rem;letter-spacing:.52em;text-indent:.52em;color:rgba(176,141,74,.9)}
.hb{
  margin:0;line-height:1.24;
  font-family:var(--f-brush);font-weight:400;
  font-size:clamp(2.9rem,15.5vw,5.4rem);letter-spacing:.06em;
  color:var(--ink);
}
.hb span{display:inline-block;opacity:0}
.finale.go .hb span{animation:charIn 1.2s cubic-bezier(.16,.84,.24,1) both}
.finale.go .hb span:nth-child(1){animation-delay:.05s}
.finale.go .hb span:nth-child(2){animation-delay:.22s}
.finale.go .hb span:nth-child(3){animation-delay:.39s}
.finale.go .hb span:nth-child(4){animation-delay:.56s}
@keyframes charIn{
  from{opacity:0;filter:blur(16px);transform:translateY(15px) scale(1.07)}
  60%{opacity:1}
  to{opacity:1;filter:blur(0);transform:none}
}
.hb-flourish{width:min(300px,72vw);margin:.55rem auto 1.5rem}
.hb-flourish svg{width:100%;height:auto;display:block}
.flo{stroke-dasharray:320;stroke-dashoffset:320}
.finale.go .flo{animation:floDraw 1.7s ease-out .95s forwards}
@keyframes floDraw{to{stroke-dashoffset:0}}
.flo-leaf{opacity:0}
.finale.go .flo-leaf{animation:leafIn .9s ease 2.1s forwards}
@keyframes leafIn{to{opacity:.75}}
.fin-line{margin:0;font-size:1.06rem;letter-spacing:.22em;text-indent:0;color:var(--ink-2)}

.signature{
  display:flex;justify-content:flex-end;align-items:center;
  gap:clamp(1rem,4vw,2rem);
  margin-top:2.9rem;padding-right:clamp(0rem,4vw,2rem);
}
.sig-text{text-align:right}
.sig-name{margin:0;font-size:clamp(1.7rem,6vw,2.2rem);letter-spacing:.1em}
.sig-date{margin:.45rem 0 0;font-size:.84rem;letter-spacing:.2em;color:var(--ink-3)}
.sig-latin{margin:.4rem 0 0;font-size:.64rem;color:rgba(111,102,86,.75)}
.sig-seal{width:clamp(64px,17vw,86px);height:auto;mix-blend-mode:multiply;opacity:.94;transform:rotate(2deg)}

.l-foot{
  margin-top:3.2rem;
  padding:2rem 0 calc(5.4rem + env(safe-area-inset-bottom));
  border-top:1px solid rgba(111,102,86,.18);
  display:flex;flex-direction:column;align-items:center;gap:1.05rem;
}
.again-btn{
  font-family:var(--f-serif);font-size:.85rem;letter-spacing:.32em;text-indent:.32em;
  color:var(--ink-2);background:none;border:1px solid rgba(76,69,58,.38);
  border-radius:999px;padding:.68rem 1.55rem;cursor:pointer;transition:.25s ease;
}
.again-btn:hover{background:rgba(76,69,58,.06);border-color:rgba(76,69,58,.62)}
.l-foot .latin{font-size:.6rem;color:rgba(111,102,86,.6)}

/* ==========================================================
   桌面：信纸 = 深色书桌上的一张纸（补足空旷感）
   ========================================================== */
@media (min-width:860px){
  .env-wrap{margin-top:calc(-1 * clamp(3.4rem,4.6vw,5.2rem))}
  body.unlocked{background:#150e07}
  .letter{background:radial-gradient(95% 55% at 50% 0%,#261910 0%,#180f08 55%,#120b06 100%)}
  .letter-inner{
    max-width:47rem;
    margin:clamp(18px,3.2vh,42px) auto clamp(36px,6.5vh,74px);
    padding:clamp(3rem,4.6vw,4.1rem) clamp(3rem,4.6vw,4.4rem) 0;
    background:radial-gradient(120% 70% at 50% 0%,#f8f2e2 0%,#f2ead6 46%,#e9dbbc 100%);
    border:1px solid rgba(132,102,62,.3);
    border-radius:2px;
    box-shadow:0 1px 0 rgba(255,255,255,.55) inset,0 30px 70px rgba(0,0,0,.55),0 8px 22px rgba(0,0,0,.4);
  }
  .l-foot{padding-bottom:4rem}
}

/* ==========================================================
   唱片播放器
   ========================================================== */
.player{
  position:fixed;z-index:60;
  right:max(16px,env(safe-area-inset-right));
  bottom:max(16px,env(safe-area-inset-bottom));
  display:flex;align-items:center;justify-content:flex-end;gap:.7rem;
  opacity:0;transform:translateY(10px);
  transition:opacity .9s ease,transform .9s ease;
}
.player.on{opacity:1;transform:none}
.player[hidden]{display:none}
.disc-btn{
  position:relative;width:70px;height:70px;padding:0;border:0;background:none;cursor:pointer;
  filter:drop-shadow(0 5px 12px rgba(40,26,10,.35));
  transition:transform .25s ease;
}
.disc-btn:hover{transform:scale(1.06)}
.disc-btn:active{transform:scale(.97)}
.disc-btn .ring,.disc-btn .disc{position:absolute;inset:0;width:100%;height:100%}
.disc-btn .disc{inset:7px;width:calc(100% - 14px);height:calc(100% - 14px)}
.player.playing .disc{animation:spin 3.4s linear infinite}
@keyframes spin{to{transform:rotate(360deg)}}
.disc-17{font-family:var(--f-latin);font-size:11px;font-weight:600;fill:#3a2f1c;letter-spacing:0}
#ringFg{transition:stroke-dashoffset .35s linear}
.player-title{
  font-family:var(--f-latin);font-size:.7rem;letter-spacing:.2em;text-transform:uppercase;
  color:var(--ink-3);background:rgba(248,242,226,.92);
  border:1px solid rgba(111,102,86,.28);border-radius:999px;
  padding:.32rem .75rem;white-space:nowrap;
  opacity:0;transform:translateX(6px);transition:.3s ease;pointer-events:none;
}
.player:hover .player-title{opacity:1;transform:none}
.player-title[hidden]{display:none}
/* 触屏没有 hover：歌名常显，不然看不到放的是什么 */
@media (hover:none){
  .player-title{opacity:.95;transform:none;font-size:.62rem;letter-spacing:.14em;padding:.26rem .62rem}
}
/* 歌词 */
.lyric{
  position:absolute;right:2px;bottom:calc(100% + 10px);
  margin:0;max-width:min(74vw,340px);text-align:right;
  font-size:.82rem;letter-spacing:.1em;line-height:1.7;
  color:rgba(76,69,58,.92);
  background:rgba(248,242,226,.9);
  border:1px solid rgba(111,102,86,.22);
  border-radius:12px;padding:.4rem .8rem;
  box-shadow:0 4px 14px rgba(60,42,18,.12);
  opacity:0;transform:translateY(6px);
  transition:opacity .6s ease,transform .6s ease;
  pointer-events:none;
}
.lyric:empty{display:none}
.lyric.on{opacity:1;transform:none}

/* ==========================================================
   响应式 & 可访问性
   ========================================================== */
@media (max-width:640px){
  .gate-inner{
    justify-content:flex-start;
    padding-top:clamp(1.5rem,5.5vh,3rem);
    gap:clamp(.85rem,2.4vh,1.3rem);
    padding-bottom:calc(4rem + env(safe-area-inset-bottom));
    padding-left:max(1rem,env(safe-area-inset-left));
    padding-right:max(1rem,env(safe-area-inset-right));
  }
  .gate-title{font-size:clamp(1.95rem,10.4vw,2.6rem)}
  .gate-sub{letter-spacing:.16em;text-indent:.16em;line-height:1.9}
  .env-wrap{width:min(94vw,460px);margin-top:calc(-1 * clamp(2.6rem,7.5vw,3.3rem))}
  .gate-form{width:min(88vw,380px)}
  .hint{font-size:.78rem;letter-spacing:.1em;line-height:1.9}
  .gate-foot{bottom:max(9px,env(safe-area-inset-bottom))}
  .bg-candle{bottom:40px;left:4px;width:52px;opacity:.8}
  .bg-moon{top:3.6%;right:5.5%;width:clamp(50px,12.5vw,74px)}

  .letter-inner{padding-top:2.4rem}
  .stamp-cluster{width:min(250px,72vw);margin-bottom:1.2rem}
  .l-body p{line-height:2.05}
  .candle{width:clamp(126px,38vw,152px)}
  .flight-wrap{width:min(200px,52vw);right:-4%;top:-32%}
  .candle-wish{letter-spacing:.12em}
  .hb{letter-spacing:.02em}
  .fin-latin{letter-spacing:.4em;text-indent:.4em}
  .signature{justify-content:center;padding-right:0;gap:1.15rem}

  .player{right:12px;bottom:calc(12px + env(safe-area-inset-bottom));gap:.5rem}
  .disc-btn{width:64px;height:64px}
  .lyric{max-width:74vw;font-size:.76rem}
  .grain-screen{display:none}
}
@media (max-width:374px){
  .gate-title{font-size:1.8rem;letter-spacing:.1em}
  .env-wrap{width:96vw}
  .stamp-cluster{width:min(228px,76vw)}
}
@media (max-height:700px){
  .gate-inner{justify-content:flex-start;padding-top:1.2rem}
}
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{
    animation-duration:.001s !important;
    animation-iteration-count:1 !important;
    transition-duration:.2s !important;
  }
  .leaf-fall,.mote,.dust circle{display:none}
  .envelope{animation:none !important}
  .gate.intro .gate-head,.gate.intro .env-group{animation:none}
  .ink-in{opacity:1;transform:none;filter:none}
}

/* dev 冻结模式（仅本地 ?dev= 时挂载，用于截图终态） */
.freeze *, .freeze *::before, .freeze *::after{transition:none !important;animation:none !important}
.freeze .dust circle{animation:dustRise 7s ease-in-out -3.4s infinite paused !important}
.freeze .plane-fly{animation:planeFly 2.7s linear paused !important}
.freeze .leaf-fall{animation:leafFall 16s linear infinite paused !important}
.freeze .leaf-sway{animation:leafSway 4s ease-in-out infinite alternate paused !important}
.freeze .leaf-rot{animation:leafRot 11s linear infinite paused !important}
.freeze .mote{animation:moteRise 9s ease-in-out -4s infinite alternate paused !important}
.freeze .trail{opacity:.75 !important}
