﻿/* ===== 字体 ===== */
@font-face{font-family:'FZSiLTJW';src:url('assets/fonts/FZSiLTJW.woff2') format('woff2');font-display:swap;}

*{margin:0;padding:0;box-sizing:border-box;}

/* ===== 鼠标指针光标（全站强制统一）=====
   用户提供蓝色像素箭头，32x32，热点在箭头尖端 */
*,*::before,*::after{
  cursor:url("assets/img/cursor.webp?v=5") 0 0, auto !important;
}
/* 星星棒点击迸发的小星星粒子 */
.wand-spark{position:fixed;z-index:99999;pointer-events:none;
  font-size:16px;line-height:1;opacity:0;will-change:transform,opacity;
  text-shadow:0 0 6px rgba(180,210,255,.9);}
.wand-spark.go{animation:wandSpark .7s ease-out forwards;}
@keyframes wandSpark{
  0%{opacity:1;transform:translate(-50%,-50%) scale(.4) rotate(0deg);}
  100%{opacity:0;transform:translate(calc(-50% + var(--wx,0px)),calc(-50% + var(--wy,-40px))) scale(1) rotate(var(--wr,90deg));}
}
@media (prefers-reduced-motion:reduce){.wand-spark{display:none;}}

/* ===== 首屏 Loading 遮罩 ===== */
.loader{
  position:fixed;inset:0;z-index:9999;
  display:flex;align-items:center;justify-content:center;
  background:radial-gradient(ellipse 120% 120% at center,#243456 0%,#1a2748 55%,#131e39 100%);
  transition:opacity .8s ease,visibility .8s ease;
}
.loader.done{opacity:0;visibility:hidden;pointer-events:none;}
.loader-inner{display:flex;flex-direction:column;align-items:center;gap:26px;}
.loader-disc{
  width:132px;height:132px;position:relative;
  filter:drop-shadow(0 8px 22px rgba(0,0,0,.45));
  animation:loaderSpin 2.2s linear infinite;
}
.loader-disc img{width:100%;height:100%;display:block;}
@keyframes loaderSpin{from{transform:rotate(0);}to{transform:rotate(360deg);}}
.loader-title{
  font-family:'FZSiLTJW',serif;font-size:22px;letter-spacing:.32em;
  color:#eaf0ff;text-indent:.32em;opacity:.92;
}
.loader-bar{
  width:220px;height:4px;border-radius:4px;overflow:hidden;
  background:rgba(255,255,255,.14);
}
.loader-bar span{
  display:block;height:100%;width:0;border-radius:4px;
  background:linear-gradient(90deg,#8fb0ff,#dfe9ff);
  box-shadow:0 0 10px rgba(160,200,255,.7);
  transition:width .35s ease;
}
.loader-tip{font-family:'FZSiLTJW',serif;font-size:13px;color:#a9bce6;letter-spacing:.04em;}
.loader-tip b{color:#e9f1ff;font-weight:700;}
/* 加载中隐藏主内容，加载完由 .ready 触发整站淡入 */
body.is-loading .screen{opacity:0;}
.screen{transition:opacity .9s ease;}
body.ready .screen{opacity:1;}

/* 留边：用牛仔底图本身放大模糊铺满全屏，与画布同纹理 → 接缝消失 */
html,body{width:100%;height:100%;background:#1c2a4d;overflow:hidden;}
body{display:flex;justify-content:center;align-items:center;min-height:100vh;}
/* 全屏背景层：与画面同一张牛仔星空图，cover 铺满、放大模糊压暗，作为所有屏幕的统一底 */
body::before{
  content:"";position:fixed;inset:-30px;z-index:-1;
  background:#1c2a4d url('assets/img/bg-denim-stars.webp') center center / cover no-repeat;
  filter:blur(10px) brightness(.9) saturate(.95);
  transform:scale(1.06);
}

/* ===== 缩放容器：1440x900 固定画布等比缩放 ===== */
.scaler{position:relative;width:1800px;height:900px;flex:0 0 auto;transform-origin:center center;transform:scale(var(--s,1));}
.stage{position:absolute;inset:0;width:1800px;height:900px;overflow:hidden;background:#7F90B6;user-select:none;}

/* ===== 鼠标视差：给带 data-depth 的元素外层套 .plx 包裹层，只平移包裹层，
   内部元素原有动画/transform 完全不受影响（分层，绝不冲突）===== */
.plx{
  position:absolute;
  transition:transform .5s cubic-bezier(.22,.61,.36,1);
  transform:translate3d(var(--px,0px),var(--py,0px),0);
  will-change:transform;
  pointer-events:none;   /* 视差包裹层不拦鼠标，事件穿透到底下可交互元素（如字母）*/
}
/* 包裹层内需要交互的元素（照片/夹子等）自行恢复点击 */
.plx > .ab-photo,.plx > .ab-spin{pointer-events:auto;}
@media (prefers-reduced-motion:reduce){.plx{transform:none!important;}}

/* ===== 单页应用：每屏铺满，切屏 = 显示/隐藏 + 上划覆盖（无跳转→音乐不断、动画必现） ===== */
body.app{display:block;overflow:hidden;background:transparent;}
.screen{
  position:fixed;inset:0;display:none;overflow:hidden;
  justify-content:center;align-items:center;background:transparent;
}
/* 整屏背景层：脱离固定舞台，直接 cover 整个视口；舞台透明后底图从舞台区到四周连续透出，消除两侧/上下色条 */
.bg-cover{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;z-index:0;pointer-events:none;}
/* 长图横向无限滚动：双份图片无缝衔接，整体向左移动 */
.bg-scroll{position:absolute;inset:0;z-index:0;pointer-events:none;display:flex;height:100%;width:max-content;}
.bg-scroll img{height:100%;width:auto;flex-shrink:0;object-fit:cover;}
@keyframes bgScrollLeft{from{transform:translateX(0);}to{transform:translateX(-50%);}}
.about-bg-scroll{animation:bgScrollLeft 40s linear infinite;}
.screen.is-active{display:flex;z-index:1;}
/* Home 页舞台必须叠在撕纸背景之上，确保所有前景素材在 bg-torn-paper.webp 上方 */
.screen[data-screen="home"] .scaler{position:relative;z-index:2;}
/* Home 舞台允许溢出：CD 左侧不裁切，仍保留旋转/抖动动画 */
.screen[data-screen="home"] .stage{overflow:visible;}
/* 目标屏：位于上层，初始藏屏幕下方，滑入覆盖当前屏 */
.screen.is-incoming{
  z-index:2;transform:translateY(100%);
  transition:transform .6s cubic-bezier(.22,.61,.36,1);
}
.screen.is-incoming.slide-in{transform:translateY(0);}
@media (prefers-reduced-motion:reduce){
  .screen.is-incoming{transition:none;transform:none;}
}
.page-transition{display:none;}

/* ===== 通用元素：左上角锚点 ===== */
.el{position:absolute;display:block;}
.bg-denim,.bg-torn{object-fit:cover;pointer-events:none;}

/* 直接嵌入 Figma 矢量 SVG 作为整页底图（1:1 还原） */
.svg-base{position:absolute;left:0;top:0;width:1800px;height:900px;z-index:1;pointer-events:none;}
/* CSS 导航覆盖在 SVG 底图上，字号与首页一致 */
.nav-css .nav-item{color:#f4f6fb;}
/* Ending 页导航文字为黑色 */
.nav-dark.nav-css .nav-item{color:#111;text-shadow:0 1px 3px rgba(255,255,255,.3);}
.nav-dark .nav-item::after{background:#fff;}
/* 星星底图缓慢漂移，营造星空移动感（放大留余量，避免露出边缘） */
.bg-denim{
  transform-origin:center center;
  animation:starDrift 20s ease-in-out infinite;
}
@keyframes starDrift{
  0%{transform:scale(1.14) translate(-34px,-20px);}
  25%{transform:scale(1.14) translate(30px,-30px);}
  50%{transform:scale(1.14) translate(38px,26px);}
  75%{transform:scale(1.14) translate(-28px,32px);}
  100%{transform:scale(1.14) translate(-34px,-20px);}
}

/* ===== 导航（FZSiLTJW；left 为文字中心 x） ===== */
.nav{position:absolute;z-index:30;inset:0;pointer-events:none;}
.nav-item{
  position:absolute;top:47px;transform:translateX(-50%);
  pointer-events:auto;
  font-family:'FZSiLTJW',serif;
  font-size:21px;color:#f4f6fb;text-decoration:none;
  letter-spacing:.03em;white-space:nowrap;
  transition:transform .2s ease,color .2s ease;
  text-shadow:0 1px 4px rgba(0,0,0,.45);
}
.nav-item::after{
  content:"";
  position:absolute;left:0;right:0;bottom:-7px;
  height:2px;background:#fff;border-radius:2px;
  transform:scaleX(0);transform-origin:left center;
  transition:transform .35s cubic-bezier(.65,0,.35,1);
}
.nav-item:hover{transform:translateX(-50%) translateY(-2px) scale(1.06);color:#fff;}
.nav-item:hover::after{transform:scaleX(1);}
.nav-item.active::after{transform:scaleX(1);transition:transform 0s;}

/* ===== 音符：左右摆动（定格动画感，节奏更快） ===== */
.note-wrap{position:absolute;}
.note{
  display:block;width:100%;height:100%;
  transform-origin:50% 15%;
  animation:noteSwing .7s steps(3,end) infinite alternate;
}
@keyframes noteSwing{
  0%{transform:rotate(-15deg);}
  100%{transform:rotate(15deg);}
}

/* ===== PORTFOLIO 剪字（摆动在外层 wrapper，hover 放大在内层 img，互不冲突）===== */
.portfolio-group{position:absolute;transform:scale(1.13);transform-origin:center center;}
.letter{
  position:absolute;
  transform-origin:50% 90%;
  animation:letterSwing 1s steps(4,end) infinite alternate;
  animation-delay:var(--d,0s);
}
.letter img{
  display:block;width:100%;height:100%;
  filter:drop-shadow(2px 4px 5px rgba(0,0,0,.3));
  transition:transform .25s cubic-bezier(.34,1.56,.64,1);
  cursor:pointer;
}
.letter:hover{z-index:30;animation-play-state:paused;}
.letter:hover img{transform:scale(1.18);}
@keyframes letterSwing{
  0%{transform:rotate(-5deg);}
  100%{transform:rotate(5deg);}
}
/* ===== 首页入场动画：首次进入网页播放一次（正常速度，--spd=1）；切页回到首页时由 go() 再次播放，
   整体快 1.5 倍（--spd=1/1.5≈.667）。入场时长/延迟统一乘 --spd，由 .screen[data-screen="home"] 上的变量控制。
   批次1（最先）：bg-torn-paper-bottom-1 → bg-torn-paper-top-1 两张背景纸先后滑入
   批次2：portfolio 字母掉落（dropIn）+ CD 从右滑入（introFromRight）
   批次3（随后）：其余纸 / 星 / 音符 / 唱臂 按 from-top / from-bottom 方向入场 */
@keyframes dropIn{
  0%{opacity:0;transform:translateY(-1000px) rotate(-5deg);}
  70%{opacity:1;}
  90%{transform:translateY(16px) rotate(-5deg);}        /* 下落途中越过落点（向下）过冲 */
  100%{opacity:1;transform:translateY(0) rotate(-5deg);}  /* 弹回落点 */
}
/* 从画外（上方）往下落入，落点带轻微回弹（先越过落点再弹回） */
@keyframes introFromTop{
  0%{opacity:0;transform:translateY(-115%);}
  65%{opacity:1;transform:translateY(30px);}
  100%{opacity:1;transform:translateY(0);}
}
/* 从画外（下方）往上浮入，落点带轻微回弹 */
@keyframes introFromBottom{
  0%{opacity:0;transform:translateY(115%);}
  65%{opacity:1;transform:translateY(-30px);}
  100%{opacity:1;transform:translateY(0);}
}
/* 从画外（左侧外）往右滑入，越过落点再回弹到自己位置 */
@keyframes introFromRight{
  0%{opacity:0;transform:translateX(-120%);}
  65%{opacity:1;transform:translateX(48px);}
  100%{opacity:1;transform:translateX(0);}
}
/* 唱臂掉落：从画外上方落下，落定在「未播放」待机位（rotate(-30deg) 抬起），回弹中等力度 */
@keyframes tonearmDrop{
  0%{opacity:0;transform:translateY(-115%) rotate(-30deg);}
  65%{opacity:1;transform:translateY(28px) rotate(-30deg);}
  100%{opacity:1;transform:translateY(0) rotate(-30deg);}
}
/* 批次2：portfolio 字母按序掉落（dropIn 单独跑，绝不与 letterSwing 同元素叠加，否则后者抢占 transform 只剩渐隐） */
.screen[data-screen="home"].is-intro .portfolio-group .letter{
  animation:dropIn calc(.9s * var(--spd,1)) cubic-bezier(.2,.75,.25,1) calc((.4s + var(--d,0s)) * var(--spd,1)) both;
}
/* 每个字母一落定（JS 在 dropIn 结束时刻加 .idle）即开始常驻摆动，不必等全局 is-intro 移除；
   用单独 class 触发，保证同一时刻元素上只有一个动画，彻底消除「渐隐」 */
.screen[data-screen="home"].is-intro .portfolio-group .letter.idle{
  animation:letterSwing 1s steps(4,end) infinite alternate;
}
/* 批次1+3：背景纸（无常驻动画，落定后静态保留；is-intro 期间用 both 填充隐藏初始态） */
.screen[data-screen="home"].is-intro .paper-intro{animation:introFromTop calc(.9s * var(--spd,1)) cubic-bezier(.2,.75,.25,1) calc(var(--in-delay,0s) * var(--spd,1)) both;}
.screen[data-screen="home"].is-intro .paper-intro.from-bottom{animation-name:introFromBottom;}
/* 批次3：星 / 音符 —— 入场动画作用于 wrapper，不影响内部常驻摆动（starSwing/noteSwing） */
.screen[data-screen="home"].is-intro .star-wrap.intro-el,
.screen[data-screen="home"].is-intro .note-wrap.intro-el{
  opacity:0;
  animation:introFromTop calc(.85s * var(--spd,1)) cubic-bezier(.2,.75,.25,1) calc(var(--in-delay,0s) * var(--spd,1)) both;
}
.screen[data-screen="home"].is-intro .note-wrap.from-bottom{
  animation-name:introFromBottom;
}
/* 唱臂：从画外掉落，落定在「未播放」待机位（rotate(-30deg) 抬起 + 轻微摇摆），带回弹 */
.screen[data-screen="home"].is-intro .tonearm-btn.intro-el{
  opacity:0;
  animation:tonearmDrop calc(.95s * var(--spd,1)) cubic-bezier(.3,1.2,.6,1) calc(var(--in-delay,0s) * var(--spd,1)) both;
}
/* 批次2：CD 从右滑入（introFromRight 单独跑，绝不与 cdHintSpin 同元素叠加，否则后者抢占 transform 只剩渐隐） */
.screen[data-screen="home"].is-intro .cd.intro-right{
  animation:introFromRight calc(1s * var(--spd,1)) cubic-bezier(.2,.75,.25,1) calc(var(--in-delay,0s) * var(--spd,1)) both;
}
/* CD 一落定（JS 在 introFromRight 结束时刻加 .idle）即开始小幅旋转待机 */
.screen[data-screen="home"].is-intro .cd.intro-right.idle{
  animation:cdHintSpin 4s ease-in-out infinite;
}
/* 音乐播放时：PORTFOLIO 字母跟节奏上下轻跳（作用在内层 img，与外层摆动分层；hover 时暂停让位放大）*/
.screen[data-screen="home"].bgm-on .letter img{animation:letterBeat .5s ease-in-out infinite alternate;animation-delay:var(--d,0s);}
.screen[data-screen="home"].bgm-on .letter:hover img{animation-play-state:paused;}
@keyframes letterBeat{
  0%{transform:translateY(0) scale(1);}
  100%{transform:translateY(-7px) scale(1.04);}
}
@media (prefers-reduced-motion:reduce){.screen[data-screen="home"].bgm-on .letter img{animation:none;}}

/* 鱼群（在标题之上，缓慢上下浮动） */
.fish{
  pointer-events:none;opacity:.97;
  transform-origin:50% 50%;
  animation:fishFloat 6.5s ease-in-out infinite;
}
@keyframes fishFloat{
  0%,100%{transform:translateY(0) rotate(0deg);}
  50%{transform:translateY(-14px) rotate(-1.2deg);}
}

/* ===== 星星（右上，轻轻摆动） ===== */
.star-wrap{position:absolute;}
.star-wrap img{
  display:block;width:100%;height:100%;
  transform-origin:50% 50%;
  animation:starSwing 2.4s ease-in-out infinite alternate;
  animation-delay:var(--d,0s);
  filter:drop-shadow(2px 3px 4px rgba(0,0,0,.3));
}
@keyframes starSwing{
  0%{transform:rotate(-16deg) scale(.95);}
  100%{transform:rotate(16deg) scale(1.05);}
}

/* ===== CD 唱片 ===== */
.cd{transform-origin:50% 50%;filter:drop-shadow(4px 6px 12px rgba(0,0,0,.35));}
.cd.playing{animation:cdSpin 3.4s linear infinite;}
.cd:not(.playing){animation:cdHintSpin 4s ease-in-out infinite;}   /* 空闲时小幅来回旋转，暗示可播放 */

/* ===== 唱臂：初始抬高远离 CD/音符 ===== */
.tonearm-shadow{opacity:.16;pointer-events:none;transition:opacity .5s ease;}
.tonearm-btn{
  position:absolute;z-index:12;
  background:none;border:none;padding:0;cursor:pointer;
  transform-origin:50% 14%;
  transform:rotate(-30deg);                  /* 默认抬起，远离 CD */
  transition:transform 1s cubic-bezier(.4,0,.2,1);   /* 点击落到 CD 上的过渡（约 1s） */
}
.tonearm-btn:not(.playing) .tonearm{display:block;width:100%;height:100%;filter:drop-shadow(2px 3px 5px rgba(0,0,0,.4));animation:tonearmHint 4.5s ease-in-out infinite alternate;}  /* 空闲时轻轻摇摆，暗示可点击 */
.tonearm-btn.playing .tonearm{animation:none;}   /* 播放时唱臂保持静止，不再晃动 */
.tonearm-btn.playing{transform:rotate(0deg);}         /* 落到 CD 上 */

/* ===== 署名 ===== */
.signature{opacity:.95;}

/* ===== Productions 页：作品贴纸卡片 + 勺叉摆动 ===== */
.prod-stage{background:transparent;width:1800px;height:900px;}
.prod-scaler{width:1800px;height:900px;}
.prod-content{position:absolute;inset:0;transform:scale(0.952381);transform-origin:center center;}

/* 勺子/叉子：钟摆式左右摆动（顶部为支点） */
.cutlery{position:absolute;}
.cutlery img{
  display:block;width:100%;height:100%;
  transform-origin:50% 8%;
  animation:cutlerySwing 3s ease-in-out infinite alternate;
  animation-delay:var(--d,0s);
  filter:drop-shadow(2px 4px 6px rgba(0,0,0,.35));
}
@keyframes cutlerySwing{
  0%{transform:rotate(-2.5deg);}
  100%{transform:rotate(2.5deg);}
}

/* 盘中作品贴纸：链接到作品页；外层持续微摆 + 内层 hover 抬起放大（分层避免 transform 冲突） */
.card-link{
  position:absolute;display:block;cursor:pointer;
  transform-origin:50% 90%;
  animation:cardSwing 2.6s ease-in-out infinite alternate;
  animation-delay:var(--sw,0s);
}
.card-link img{
  display:block;width:100%;height:100%;
  transition:transform .3s cubic-bezier(.34,1.4,.64,1),filter .3s ease;
  filter:drop-shadow(3px 6px 10px rgba(0,0,0,.35));
}
.card-link:hover{z-index:30;animation-play-state:paused;}
.card-link:hover img{
  transform:translateY(-12px) scale(1.06) rotate(-1deg);
  filter:drop-shadow(6px 16px 22px rgba(0,0,0,.5));
}
@keyframes cardSwing{
  0%{transform:rotate(-1.6deg);}
  100%{transform:rotate(1.6deg);}
}
/* 鲨鱼按键整体左倾 5°：旋转内层图（父级 cardSwing 仍在轻轻摇摆 + hover 上浮保留） */
.card-link[data-go="work-shark"] img{transform:rotate(-5deg);}
.card-link[data-go="work-shark"]:hover img{transform:translateY(-12px) scale(1.06) rotate(-5deg);}

/* Productions 四个作品键：进入页面时的快速进场（切页即播，落定后由 cardSwing 接管）。
   进场期用 .is-intro 覆盖 .card-link 的 cardSwing（同一元素不同时跑两个 transform 动画），
   移除 is-intro 后 cardSwing 自然恢复。错峰间隔 0.25s（--in-delay）；进场前元素 opacity:0 且离场（both 反向填充），故不在场。
   回弹用分段缓动：下落加速(ease-in)→越过落点下沉→缓回(ease-out)，比单段 cubic-bezier 更自然。 */
@keyframes prodDrop{            /* 上排：从上方掉落，越过落点下 15px 自然回弹 */
  0%{opacity:0;transform:translateY(-700px);animation-timing-function:ease-in;}
  60%{opacity:1;}
  78%{transform:translateY(0);animation-timing-function:ease-in;}      /* 触底（砸下加速） */
  85%{transform:translateY(15px);animation-timing-function:ease-out;} /* 越过落点下沉 */
  100%{opacity:1;transform:translateY(0);}                            /* 缓慢回弹归位（占比更大、更慢） */
}
@keyframes prodRise{            /* 下排：从下方上升，越过落点上 15px 自然回弹 */
  0%{opacity:0;transform:translateY(700px);animation-timing-function:ease-in;}
  60%{opacity:1;}
  78%{transform:translateY(0);animation-timing-function:ease-in;}
  85%{transform:translateY(-15px);animation-timing-function:ease-out;}
  100%{opacity:1;transform:translateY(0);}
}
.screen[data-screen="productions"].is-intro .card-link.intro-top{
  animation:prodDrop .85s ease-in-out var(--in-delay,0s) both;
}
.screen[data-screen="productions"].is-intro .card-link.intro-bottom{
  animation:prodRise .85s ease-in-out var(--in-delay,0s) both;
}
/* 每个键自身入场结束后由 JS 加 .idle：立刻开始 cardSwing 待机摆动（比 .intro 规则更具体，故覆盖进场动画） */
.screen[data-screen="productions"].is-intro .card-link.intro-top.idle,
.screen[data-screen="productions"].is-intro .card-link.intro-bottom.idle{
  animation:cardSwing 2.6s ease-in-out infinite alternate;
}
/* 勺子/叉子（cutlery）：不做入场动画，始终以常驻钟摆摆动呈现（见上方 .cutlery img 的 cutlerySwing） */

/* ===== 作品卡片「待填充」锁定状态 ===== */
/* 悬停时复制一层该图片、明度拉到最低 + 50% 透明作为遮罩，叠加居中锁图标；
   点击不进详情，改为左右抖动。解锁方法见 app.js 顶部 LOCKED_WORKS。 */
.card-link.locked{cursor:not-allowed;}
.card-link.locked .card-ghost{        /* 复制一层图片：明度最低 + 50% 透明，作为遮罩 */
  position:absolute;inset:0;z-index:2;
  width:100%;height:100%;
  filter:brightness(0) opacity(.5);
  opacity:0;transition:opacity .2s ease;pointer-events:none;
}
.card-link.locked::after{             /* 居中锁图标 */
  content:"";position:absolute;inset:0;z-index:3;
  background:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23ffffff'%3E%3Cpath d='M12 1a5 5 0 0 0-5 5v3H6a2 2 0 0 0-2 2v9a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-9a2 2 0 0 0-2-2h-1V6a5 5 0 0 0-5-5zm3 8H9V6a3 3 0 0 1 6 0v3z'/%3E%3C/svg%3E") center/42px no-repeat;
  opacity:0;transition:opacity .2s ease;pointer-events:none;
}
.card-link.locked:hover .card-ghost{opacity:1;}
.card-link.locked:hover::after{opacity:.8;}
.card-link.locked.shake{animation:cardShake .42s ease;}
@keyframes cardShake{
  0%,100%{transform:translateX(0);}
  15%{transform:translateX(-9px);}
  30%{transform:translateX(9px);}
  45%{transform:translateX(-7px);}
  60%{transform:translateX(7px);}
  75%{transform:translateX(-4px);}
  90%{transform:translateX(4px);}
}

/* ===== 作品详情占位页 ===== */
.ph-wrap{
  position:absolute;inset:0;z-index:10;
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:18px;
}
.ph-title{font-family:'FZSiLTJW',serif;font-size:40px;color:#eef1f8;letter-spacing:.04em;}
.ph-sub{font-family:'FZSiLTJW',serif;font-size:18px;color:#9fb0d6;}
.ph-back{
  margin-top:14px;font-family:'FZSiLTJW',serif;font-size:16px;color:#cfe;
  text-decoration:none;border:1px solid rgba(255,255,255,.4);
  padding:8px 22px;border-radius:24px;transition:all .25s ease;
}
.ph-back:hover{background:rgba(255,255,255,.12);transform:translateY(-2px);}

/* ===== 作品长图块（CD 页封面下方保留的 3 张长图）===== */
.work-long{
  display:block;
  width:100%;max-width:1440px;height:auto;
  margin:0 auto;
}
/* 左上角返回键（固定不随滚动，始终可点） */
.work-back{
  position:absolute;left:26px;top:22px;z-index:50;
  width:58px;height:auto;cursor:pointer;
  filter:drop-shadow(0 3px 8px rgba(0,0,0,.4));
  transition:transform .2s ease;
}
.work-back img{display:block;width:100%;height:auto;}
.work-back:hover{transform:translateX(-3px) scale(1.06);}

/* ===== 作品开头页（鲨鱼/蝴蝶/猫咪 三个，结构同 CD 长图页）=====
   整页块级可滚动：上方封面(背景星空+标题+说明) + 下方黑色区域(留作以后放作品) + 左上返回键 */
.screen.work-cover{display:none;}
.screen.work-cover.is-active{display:block;}   /* 覆盖 flex，改块级以便滚动 */
.wc-scroll{position:absolute;inset:0;overflow-y:auto;overflow-x:hidden;background:#000;-webkit-overflow-scrolling:touch;}
/* 封面区：固定 16:10 比例的背景，铺满上方一屏 */
.wc-cover{position:relative;width:100%;max-width:1440px;margin:0 auto;
  aspect-ratio:1440/900;overflow:hidden;background:#0b1430;}
.wc-cover .wc-bg{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block;}
/* 各页背景微调：蝴蝶上移10px、猫上移7px */
[data-screen="work-butterfly"] .wc-bg{transform:translateY(-10px);}
[data-screen="work-cat"] .wc-bg{transform:translateY(-7px);}
/* 封面底部渐变过渡：星空封面 → 黑色，柔化与下方作品的衔接 */
.wc-cover::after{content:"";position:absolute;left:0;right:0;bottom:0;height:22%;z-index:2;
  pointer-events:none;background:linear-gradient(to bottom,rgba(0,0,0,0) 0%,rgba(2,6,20,.55) 55%,#000 100%);}
/* 标题（手写体图，居中偏上，进入时浮现）
   四张标题图字形密度不同(单字墨迹宽 p1=107 p2=94 p3=90 p4=85)，若统一行高会让"单字"看起来大小不一。
   以蝴蝶 p2 的单字大小为基准，给每页单独设显示高度 --th，使各标题"单个字"视觉一致。 */
.wc-title{position:absolute;left:50%;top:31%;transform:translateX(-50%) translateY(12px);
  width:auto;height:var(--th,14.45%);opacity:0;z-index:3;
  filter:drop-shadow(0 4px 14px rgba(0,0,0,.4));}
.wc-desc{position:absolute;left:50%;top:48%;transform:translateX(-50%) translateY(12px);
  width:auto;height:3.4%;max-height:31px;opacity:0;z-index:3;
  filter:drop-shadow(0 2px 8px rgba(0,0,0,.4));}
/* 作品封面页 Tianyishi 白色水印（往上移，保证点进来首屏就能看到）*/
.wc-sign{position:absolute;left:50%;bottom:12%;transform:translateX(-50%);
  width:140px;height:auto;opacity:0;z-index:4;filter:drop-shadow(0 1px 4px rgba(0,0,0,.4));}
.work-cover.is-active .wc-title{animation:wcIn .8s cubic-bezier(.22,.61,.36,1) .25s both;}
.work-cover.is-active .wc-desc{animation:wcIn .8s cubic-bezier(.22,.61,.36,1) .5s both;}
.work-cover.is-active .wc-sign{animation:wcIn .8s cubic-bezier(.22,.61,.36,1) .7s both;}
@keyframes wcIn{0%{opacity:0;transform:translateX(-50%) translateY(12px);}100%{opacity:1;transform:translateX(-50%) translateY(0);}}
/* 下方作品内容区：长图由 JS 按 assets/works/<作品>/NN 自动加载（NN=01,02,03…）*/
.wc-works{width:100%;max-width:1440px;margin:0 auto;min-height:900px;background:#000;
  display:flex;flex-direction:column;align-items:center;}
.wc-works-empty{margin-top:60px;font-family:'FZSiLTJW',serif;font-size:15px;color:#33405e;letter-spacing:.08em;}
@media (prefers-reduced-motion:reduce){.work-cover .wc-title,.work-cover .wc-desc,.work-cover .wc-sign{animation:none!important;opacity:1!important;transform:translateX(-50%)!important;}}

/* ===== 作品详情页（鲨鱼/猫咪/CD/蝴蝶）整体缩放（80%），四周留白、画面不占满；返回键不缩小 ===== */
[data-screen="work-shark"] .wc-cover,
[data-screen="work-cat"] .wc-cover,
[data-screen="work-record"] .wc-cover,
[data-screen="work-butterfly"] .wc-cover{
  width:80%;
  margin:4% auto 0;
}
[data-screen="work-shark"] .work-long,
[data-screen="work-cat"] .work-long,
[data-screen="work-record"] .work-long,
[data-screen="work-butterfly"] .work-long{
  width:80%;
}

/* ===== About me 页：轻微摆动装饰 & 照片 ===== */
.deco-sway{transform-origin:50% 20%;animation:decoSway 3.2s ease-in-out infinite alternate;}
@keyframes decoSway{0%{transform:rotate(-4deg);}100%{transform:rotate(4deg);}}
.photo{border-radius:14px;transition:transform .3s ease,box-shadow .3s ease;box-shadow:0 6px 16px rgba(0,0,0,.3);}
.photo:hover{transform:scale(1.04) rotate(-1deg);box-shadow:0 10px 24px rgba(0,0,0,.4);}

/* About me 拼贴底层：分离的 PNG 素材（纸张/卡片/图标），静态定位、不拦截鼠标 */
.ab-layer{position:absolute;display:block;pointer-events:none;user-select:none;}

/* ===== About me 页：圈出的 4 个图案转动摆动 =====
   持续旋转放在 img 子元素上，避免与 .ab-in 的进场动画或 .about-done 的
   animation:none 冲突，进场结束后图案仍保持摆动。 */
.ab-spin{position:absolute;transform-origin:50% 50%;}
.ab-spin img{display:block;width:100%;height:100%;filter:drop-shadow(2px 4px 6px rgba(0,0,0,.28));transform-origin:50% 50%;animation:abSpin 3s ease-in-out infinite alternate;animation-delay:var(--sp,0s);}
@keyframes abSpin{0%{transform:rotate(-8deg);}100%{transform:rotate(8deg);}}
/* 右上星群在原图带 32.27° 基础旋转，摆动叠加在其上 */
.ab-spin-rot img{animation:abSpinRot 3s ease-in-out infinite alternate;animation-delay:var(--sp,0s);}
@keyframes abSpinRot{0%{transform:rotate(24deg);}100%{transform:rotate(40deg);}}

/* About me 人物照片：叠加图严格贴合底图那张（同 24.5 圆角、无独立描边/阴影，避免与底图照片叠出双层边框）；
   悬停时轻微抬升放大端详 */
.ab-photo{position:absolute;border-radius:24.5px;cursor:pointer;
  transform-origin:50% 50%;
  transition:transform .35s cubic-bezier(.34,1.4,.5,1),filter .35s ease;}
.ab-photo:hover{
  transform:scale(1.05) rotate(-2deg);
  filter:drop-shadow(0 12px 24px rgba(0,0,0,.4));z-index:20;}

/* ===== About me 进场：切到该页时，卡片/图案像被一张张贴上剪贴板 ===== */
/* 初始隐藏（缩小+下移+旋转+透明）；加 .go 后弹回原位。用独立包裹思路：
   直接作用在元素外层 transform，通过 CSS 变量与自身动画分层避免冲突 */
.about .ab-in{opacity:0;}
.about.about-play .ab-in{
  animation:abStick .62s cubic-bezier(.22,1.35,.5,1) both;
  animation-delay:var(--in,0s);
}
@keyframes abStick{
  0%{opacity:0;transform:translateY(26px) scale(.82) rotate(-6deg);}
  60%{opacity:1;}
  100%{opacity:1;transform:translateY(0) scale(1) rotate(0deg);}
}
/* 进场结束后清掉 transform，交还给各自的摆动/hover（避免残留 transform 冲突） */
.about.about-done .ab-in{animation:none;opacity:1;}
@media (prefers-reduced-motion:reduce){
  .about .ab-in{opacity:1!important;animation:none!important;}
}

/* 人物照片专用进场：原位"从无到有"淡入 + 极轻微放大浮现（不位移不弹跳，
   避免与相邻狗狗照片的弹跳动作叠在一起打架）*/
.about .ab-fade{opacity:0;}
.about.about-play .ab-fade{
  animation:abFadeIn .9s ease both;
  animation-delay:var(--in,0s);
}
@keyframes abFadeIn{
  0%{opacity:0;transform:scale(.94);}
  100%{opacity:1;transform:scale(1);}
}
.about.about-done .ab-fade{animation:none;opacity:1;}
@media (prefers-reduced-motion:reduce){
  .about .ab-fade{opacity:1!important;animation:none!important;}
}

/* ===== About me 软件图标 hover：弹跳 + 名称气泡 ===== */
.ab-soft{position:absolute!important;z-index:14;cursor:pointer;display:block!important;
  border-radius:12px;transition:transform .28s cubic-bezier(.34,1.6,.5,1);}
.ab-soft::after{
  content:attr(title);
  position:absolute;left:50%;bottom:calc(100% + 8px);transform:translateX(-50%) translateY(4px);
  padding:3px 10px;border-radius:12px;white-space:nowrap;
  font-family:'FZSiLTJW',serif;font-size:12px;color:#26355f;
  background:rgba(255,255,255,.92);box-shadow:0 4px 12px rgba(0,0,0,.22);
  opacity:0;pointer-events:none;transition:opacity .25s ease,transform .25s ease;
}
.ab-soft:hover{transform:translateY(-7px) scale(1.14);}
.ab-soft:hover::after{opacity:1;transform:translateX(-50%) translateY(0);}

/* ===== About me 彩蛋 1：法斗犬照片点击抖动 + 冒爱心 ===== */
.ab-pug{position:absolute;display:block;cursor:pointer;
  transform-origin:50% 60%;
  transition:transform .3s cubic-bezier(.34,1.5,.6,1),filter .3s ease;}
.ab-pug img{display:block;width:100%;height:100%;object-fit:contain;pointer-events:none;}
.ab-pug:hover{transform:scale(1.07) rotate(-2deg);
  filter:drop-shadow(0 10px 22px rgba(0,0,0,.4));z-index:20;}
/* 进场结束后 .ab-in 的 animation:none 会盖掉 wiggle，这里用更高优先级保住点击彩蛋 */
.ab-pug.wiggle{animation:pugWiggle .5s ease !important;}
@keyframes pugWiggle{
  0%,100%{transform:rotate(0) scale(1);}
  15%{transform:rotate(-4deg) scale(1.04);}
  40%{transform:rotate(3.5deg) scale(1.05);}
  65%{transform:rotate(-2.5deg) scale(1.03);}
  85%{transform:rotate(1.5deg) scale(1.02);}
}
/* 爱心/爪印粒子 */
.heart-particle{position:absolute;z-index:60;pointer-events:none;font-size:22px;
  opacity:0;will-change:transform,opacity;}
.heart-particle.go{animation:heartParticle 1s ease-out forwards;}
@keyframes heartParticle{
  0%{opacity:0;transform:translate(0,0) scale(.5) rotate(0);}
  20%{opacity:1;}
  100%{opacity:0;transform:translate(var(--hx,0),var(--hy,-60px)) scale(1.2) rotate(var(--hr,0deg));}
}

/* ===== About me 质感 3：背景改为 bg-stars.png 星空，不再对底图做纸张呼吸动画 ===== */
.about .svg-base{animation:none;}
@keyframes paperBreath{
  0%,100%{transform:scale(1) rotate(0deg);}
  50%{transform:scale(1.006) rotate(.12deg);}
}
@media (prefers-reduced-motion:reduce){.about .svg-base{animation:none;}}
/* About me 手写标题：保留底图原样，不叠加、不放大 */
.ab-title,.ab-title-cover{display:none;}

/* ===== Ending 页：星星闪烁摆动 + Thanks 浮动 ===== */
.star-tw{
  transform-origin:50% 50%;
  animation:starTwinkle 3.4s ease-in-out infinite alternate;
  animation-delay:var(--d,0s);
}
@keyframes starTwinkle{
  0%{transform:rotate(-10deg) scale(.94);opacity:.85;}
  100%{transform:rotate(10deg) scale(1.06);opacity:1;}
}
.t-thanks-float{animation:thanksFloat 4s ease-in-out infinite;}
@keyframes thanksFloat{0%,100%{transform:translateY(0) rotate(-1deg);}50%{transform:translateY(-8px) rotate(-1deg);}}
.tbc{animation:tbcNudge 1.4s ease-in-out infinite;}
/* tbc 同时是 end-seq：浮现阶段先不跑 nudge，避免 transform 打架；seq-done 后再跑 */
.end-stage .tbc.end-seq{animation:none;}
.end-stage.seq-done .tbc.end-seq{animation:tbcNudge 1.4s ease-in-out infinite;}
@keyframes tbcNudge{0%,100%{transform:translateX(0);}50%{transform:translateX(8px);}}

/* ===== Ending 页：可拖拽 + 摆动的星星，Thanks 悬停放大 ===== */
.end-stage{background:transparent;}
.star-drag{position:absolute;cursor:grab;touch-action:none;
  transform-origin:50% 50%;}
/* 扩大隐形点击/抓取范围（150%），星星更好选中；命中框随容器一起 transform，始终跟着可见星星 */
.star-drag::before{content:"";position:absolute;left:50%;top:50%;
  width:150%;height:150%;transform:translate(-50%,-50%);}
.star-drag img{
  display:block;width:100%;height:100%;pointer-events:none;
  transform-origin:50% 50%;
  filter:drop-shadow(2px 3px 5px rgba(0,0,0,.25));
  transition:filter .25s ease, transform .25s ease;
}
/* 悬停：轻微放大 + 柔光（与拖拽发光一致的蓝调） */
.star-drag:hover img{
  transform:scale(1.16);
  filter:drop-shadow(0 0 8px rgba(130,185,255,.85)) drop-shadow(0 0 20px rgba(120,170,255,.45));
}
/* 自由漂浮时的柔和轮询发光（JS 按顺序切换 .glow，每颗星轮流亮一下） */
.star-drag.glow img{
  filter:drop-shadow(0 0 6px rgba(130,185,255,.75)) drop-shadow(0 0 14px rgba(120,170,255,.35));
}
.star-drag.dragging{cursor:grabbing;z-index:50!important;}
/* 拖拽选中时：发光 + 轻微放大（柔和，不夸张） */
.star-drag.dragging img{
  transform:scale(1.08);
  filter:drop-shadow(0 0 10px rgba(130,185,255,.95)) drop-shadow(0 0 24px rgba(120,170,255,.55));
}
/* 拖拽拖尾：沿路径留下的小碎星（克制的星屑，不夸张） */
.star-trail{position:absolute;z-index:45;pointer-events:none;
  font-size:13px;line-height:1;color:#dcebff;
  text-shadow:0 0 6px rgba(150,200,255,.9);
  transform:translate(-50%,-50%) rotate(var(--r,0deg)) scale(.3);opacity:0;}
.star-trail.go{animation:starTrail .6s ease-out forwards;}
@keyframes starTrail{
  0%{opacity:0;transform:translate(-50%,-50%) rotate(var(--r,0deg)) scale(.3);}
  30%{opacity:.76;}
  100%{opacity:0;transform:translate(calc(-50% + var(--dx,0px)),calc(-50% + var(--dy,0px))) rotate(var(--r,0deg)) scale(1);}
}
.t-thanks{cursor:pointer;}
.t-thanks img,.t-thanks svg{display:block;width:100%;height:100%;object-fit:contain;transition:transform .4s cubic-bezier(.34,1.4,.64,1);transform-origin:50% 50%;}

/* Ending 页：二维码 + 三个联系方式按钮 */
.end-qr{position:absolute;left:835px;top:488px;width:129px;height:131px;z-index:10;}
.end-qr img,.end-qr svg{display:block;width:100%;height:100%;object-fit:contain;}

.end-contact-row{position:absolute;left:789px;top:641px;width:223px;height:46px;z-index:12;}
.end-contact-btn{
  position:absolute;top:0;width:46px;height:46px;padding:0;border:none;background:transparent;
  cursor:pointer;display:flex;align-items:center;justify-content:center;
  transition:transform .2s ease,background .2s ease;
}
.end-contact-btn:nth-child(1){left:0;}
.end-contact-btn:nth-child(2){left:89px;}
.end-contact-btn:nth-child(3){left:177px;}
.end-contact-btn img{display:block;width:100%;height:100%;object-fit:contain;pointer-events:none;}
.end-contact-btn:hover{transform:scale(1.14);z-index:13;}
.end-contact-btn::before{
  content:attr(data-tip);position:absolute;left:50%;bottom:100%;
  transform:translateX(-50%) translateY(6px);margin-bottom:10px;
  padding:4px 10px;border-radius:6px;background:rgba(0,0,0,.75);
  color:#fff;font-size:12px;white-space:nowrap;letter-spacing:.4px;
  opacity:0;visibility:hidden;transition:opacity .2s ease,transform .2s ease,visibility .2s;
  pointer-events:none;
}
.end-contact-btn:hover::before{opacity:1;visibility:visible;transform:translateX(-50%) translateY(0);}
.end-contact-btn.copied{background:#5aa3f5;border-radius:10px;}
.end-contact-btn.show-toast::after{
  content:"Copied!";position:absolute;left:50%;bottom:100%;
  transform:translateX(-50%) translateY(0);margin-bottom:10px;
  padding:4px 9px;border-radius:5px;background:#5aa3f5;color:#fff;
  font-size:11px;white-space:nowrap;pointer-events:none;
  animation:endCopiedToast 1.5s ease forwards;
}
/* 复制成功提示期间隐藏悬停标签（Email/Wechat 等），1.5s 后随 .show-toast 移除自动恢复 */
.end-contact-btn.show-toast::before{opacity:0;visibility:hidden;}
@keyframes endCopiedToast{
  0%{opacity:1;transform:translateX(-50%) translateY(0);}
  75%{opacity:1;transform:translateX(-50%) translateY(-4px);}
  100%{opacity:0;transform:translateX(-50%) translateY(-10px);}
}
.t-thanks:hover img{transform:scale(1.06) rotate(-1deg);}
.t-thanks img{clip-path:inset(0 100% 0 0);}
/* 笔尖光点：书写时跟随 reveal 右边缘 */
.t-thanks .th-nib{
  position:absolute;left:0;top:50%;width:10px;height:10px;border-radius:50%;
  background:#0a3fb0;opacity:0;transform:translate(-50%,-50%);
  box-shadow:0 0 8px rgba(60,120,255,.9);pointer-events:none;z-index:2;
}
.end-stage.th-writing #tThanks img{animation:thClipReveal 1.2s ease-out forwards;}
.end-stage.th-writing #tThanks .th-nib{opacity:1;animation:thNibMove 1.2s ease-out forwards;}
@keyframes thClipReveal{to{clip-path:inset(0 0 0 0);}}
@keyframes thNibMove{to{left:100%;}}
/* Thanks 写完的 Q 弹 */
.t-thanks.th-pop{animation:thPop .6s cubic-bezier(.34,1.7,.5,1);}
@keyframes thPop{0%{transform:scale(1);}35%{transform:scale(1.08) rotate(-1.5deg);}70%{transform:scale(.99);}100%{transform:scale(1);}}
/* Thanks 写完迸发的星光粒子 */
.th-spark{position:absolute;z-index:40;pointer-events:none;width:12px;height:12px;
  background:radial-gradient(circle,#fff 0%,#bcd8ff 45%,rgba(150,190,255,0) 72%);
  border-radius:50%;opacity:0;}
.th-spark.go{animation:thSpark .85s ease-out forwards;}
@keyframes thSpark{0%{opacity:1;transform:translate(0,0) scale(1);}100%{opacity:0;transform:translate(var(--sx),var(--sy)) scale(.2);}}

/* Ending 落款接力浮现：Thanks 写完后依次淡入上移 */.end-seq{opacity:0;}
.end-stage.seq-in .end-seq{
  animation:endSeqIn .7s cubic-bezier(.22,.61,.36,1) both;
  animation-delay:var(--sq,0s);
}
@keyframes endSeqIn{0%{opacity:0;transform:translateY(16px);}100%{opacity:1;transform:translateY(0);}}
/* tbc 有自己的 tbcNudge 循环动画，浮现完成后交还 */
.end-stage.seq-done .end-seq{opacity:1;}
@media (prefers-reduced-motion:reduce){.end-seq{opacity:1!important;animation:none!important;}}

/* ===== 播放提示（居中，偏下） ===== */
.hint{
  position:absolute;z-index:30;left:900px;bottom:74px;transform:translateX(-50%);
  font-family:'FZSiLTJW',serif;font-size:14px;color:#eef1f8;
  background:rgba(40,52,82,.5);padding:5px 16px;border-radius:20px;
  white-space:nowrap;transition:opacity .6s ease,transform .6s ease;backdrop-filter:blur(2px);
}
.hint.hide{opacity:0;transform:translateX(-50%) translateY(8px);pointer-events:none;}

/* ===== Home 提示词：Roll down + 向下滑动态图标（手机/电脑一致） ===== */
.hint.roll-hint{
  display:flex;align-items:center;gap:18px;
  font-size:18px;font-family:'FZSiLTJW',serif;color:#eef1f8;   /* 英文视觉偏小，故略大于 Ending 提示 */
}
.hint.roll-hint .roll-icon{
  position:relative;display:inline-block;width:16px;height:16px;
  animation:rollBounce 1.5s ease-in-out infinite;
}
/* 双层向下 V 形：通用“下滑/上滑切换”指示 */
.hint.roll-hint .roll-icon::before,
.hint.roll-hint .roll-icon::after{
  content:'';position:absolute;left:1px;width:14px;height:14px;
  border-left:2px solid #eef1f8;border-bottom:2px solid #eef1f8;
  transform:rotate(-45deg);   /* 在现有图标基础上旋转 -90° → 向下 V 形 */
}
.hint.roll-hint .roll-icon::before{top:-3px;opacity:1;}
.hint.roll-hint .roll-icon::after{top:3px;opacity:.5;}
@keyframes rollBounce{0%,100%{transform:translateY(-8px);opacity:.55;}50%{transform:translateY(-3px);opacity:1;}}

/* ===== 动画 ===== */
@keyframes cdSpin{from{transform:rotate(0deg);}to{transform:rotate(360deg);}}
@keyframes cdHintSpin{0%,100%{transform:rotate(-6deg);}50%{transform:rotate(6deg);}}
@keyframes tonearmHint{from{transform:rotate(-3deg);}to{transform:rotate(3deg);}}
@media (prefers-reduced-motion:reduce){.letter,.note,.fish,.star-wrap img,.star-drag,.bg-denim,.cd:not(.playing),.ab-gamer,.ab-ground-wrap,.ab-obs,.ab-clouds{animation:none;}}

/* ================= About 页小游戏 ================= */
.about-game{position:absolute;inset:0;z-index:5;pointer-events:auto;overflow:hidden;}
/* 导航 z-index 更高，签名 z-index 更高，仍会优先接收点击 */
/* Start 按钮：画面中心最右侧 */
.ab-start{position:absolute;left:1650px;top:436px;width:113px;height:28px;z-index:10;cursor:pointer;
  filter:drop-shadow(0 2px 4px rgba(0,0,0,.35));transition:transform .2s ease,filter .2s ease;}
.ab-start:hover{transform:scale(1.10);}
.ab-start:active{transform:scale(.96);}
.ab-start img{display:block;width:100%;height:100%;}
.about-game.playing .ab-start{opacity:0;pointer-events:none;transition:opacity .3s ease;}
/* 体力心：按 txt 坐标 (201,655) 摆放（3 颗间隔 19px，与 txt 一致） */
.ab-hearts{position:absolute;left:201px;top:655px;z-index:10;display:flex;gap:4px;pointer-events:none;}
.ab-heart{width:15px;height:14px;transition:transform .25s ease,opacity .25s ease;}
.ab-heart.lost{transform:scale(.2) rotate(-30deg);opacity:0;}
.ab-hearts.healing .ab-heart.lost{animation:heartHeal .45s ease forwards;}
@keyframes heartHeal{0%{transform:scale(.2) rotate(-30deg);opacity:0;}70%{transform:scale(1.2) rotate(8deg);opacity:1;}100%{transform:scale(1) rotate(0);opacity:1;}}
/* 角色 */
.ab-gamer{position:absolute;left:379px;top:685px;width:75px;height:60px;z-index:8;will-change:top,transform;}
.about-game:not(.playing) .ab-gamer{animation:gamerIdle 2.6s ease-in-out infinite;}
@keyframes gamerIdle{0%,100%{transform:translateY(0);}50%{transform:translateY(-7px);}}
.ab-gamer.hurt{animation:gamerHurt .35s ease-out;}
@keyframes gamerHurt{0%,100%{filter:none;}25%{filter:brightness(1.6) saturate(0);transform:translateX(-3px);}50%{filter:brightness(1.6) saturate(0);transform:translateX(3px);}75%{filter:brightness(1.6) saturate(0);transform:translateX(-3px);}}
.ab-gamer.falling{transition:top .25s cubic-bezier(.55,.06,.68,.19);transform:none;}
.ab-gamer.returning{transition:top .6s ease-out,left .6s ease-out;transform:none;}
.ab-gamer.resetting{transition:top .3s ease-out,left .3s ease-out;transform:none;}
/* 完全失败后，Start 与体力心在同一时机恢复，动画一致 */
.ab-start.returning,
.ab-hearts.returning .ab-heart{opacity:0;animation:uiReturn .45s ease forwards;}
@keyframes uiReturn{to{opacity:1;}}
/* 地面 */
.ab-ground-wrap{position:absolute;left:0;top:794px;width:3600px;height:10px;z-index:6;display:flex;}
.ab-ground{display:block;width:1800px;height:10px;flex-shrink:0;}
/* 全屏铺底地面：与 .ab-ground-wrap 同一张图、同一高度；定位到舞台地面在视口中的实际 Y，
   宽度铺满整个视口。超宽屏舞台两侧留白处由它补齐，使地面线两端始终贴画面两侧。
   z-index:0 → 位于 .bg-scroll(0) 之上、透明舞台(.scaler)之下：舞台内地面盖在它上面，
   两侧留白处只剩它，视觉无缝衔接。top/height/background-size/position 由 JS 每帧同步。 */
.ab-ground-bleed{position:absolute;left:0;top:0;width:100%;height:10px;z-index:0;pointer-events:none;
  background:url('assets/about/ground.webp') repeat-x left top;background-size:1800px 10px;}
/* 地面滚动由 JS 驱动，与障碍物/云朵速度严格同步 */
/* 障碍物 */
.ab-obs{position:absolute;inset:0;z-index:7;pointer-events:none;}
.ab-obs > *{position:absolute;pointer-events:none;}
.ab-obs .obs-ground{bottom:106px;} /* 900-794=106，即底部对齐地面 top=794 */
/* 云朵 */
.ab-clouds{position:absolute;inset:0;z-index:6;pointer-events:none;}
.ab-game-tip{position:absolute;left:900px;top:818px;transform:translateX(-50%);z-index:9;pointer-events:none;text-align:center;font-family:'FZSiLTJW',serif;font-size:14px;line-height:1.45;color:#eef1f8;opacity:1;letter-spacing:1px;background:rgba(40,52,82,.5);padding:5px 16px;border-radius:20px;backdrop-filter:blur(2px);transition:opacity .3s ease;}
.about-game.playing .ab-game-tip{opacity:0;pointer-events:none;}
.about-game.played  .ab-game-tip{opacity:0;pointer-events:none;}
.ab-clouds > *{position:absolute;pointer-events:none;opacity:.9;}
.about-game:not(.playing) .ab-clouds > *{animation:cloudBob 3.2s ease-in-out infinite;}
@keyframes cloudBob{0%,100%{transform:translateY(0);}50%{transform:translateY(-5px);}}


/* ================= 手机竖屏横屏提示遮罩 ================= */
#rotateHint{position:fixed;inset:0;z-index:99999;display:none;
  background:linear-gradient(160deg,#1c2a4d 0%,#26355f 100%);
  align-items:center;justify-content:center;flex-direction:column;
  -webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);}
#rotateHint .rotate-hint-inner{display:flex;flex-direction:column;align-items:center;gap:22px;}
#rotateHint .rotate-phone{animation:rotateNudge 1.8s ease-in-out infinite;}
#rotateHint .rotate-tip{margin:0;color:#fff;
  font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,'Helvetica Neue',Arial,'Noto Sans SC','PingFang SC','Microsoft YaHei',sans-serif;
  font-size:19px;line-height:1.7;text-align:center;letter-spacing:1px;
  text-shadow:0 1px 10px rgba(0,0,0,.4);}
@keyframes rotateNudge{0%,100%{transform:rotate(0)}50%{transform:rotate(-90deg)}}
/* 横屏提示：默认隐藏，由 JS 在首屏 Loading 结束后按需弹出（仅竖屏窄触屏）；横屏时强制隐藏，即可浏览内容 */
.show-rotate #rotateHint{display:flex;}
@media (orientation:landscape){#rotateHint{display:none !important;}}

/* ================= About 页：静态中文整页（无中英切换） ================= */

/* ===== About me 钥匙扣页：左侧分类导航 ===== */
.key-nav{
  position:absolute;left:37px;top:50%;transform:translateY(-50%);z-index:20;
  display:flex;flex-direction:column;gap:28px;pointer-events:none;
}
.key-nav-item{
  pointer-events:auto;background:none;border:none;padding:0;
  font-family:'FZSiLTJW',serif;font-size:20px;color:#f4f6fb;
  letter-spacing:.06em;text-align:left;white-space:nowrap;
  text-shadow:0 1px 4px rgba(0,0,0,.45);
  transform-origin:left center;
  transition:transform .22s cubic-bezier(.22,.61,.36,1),color .22s ease;
  cursor:pointer;position:relative;
}
/* 悬停/选中时直接显示为 "- Label -"：短横与文字之间各一个空格，
   - 作为文字流的一部分紧贴文字左右边缘（内联伪元素，不受 flex 拉伸影响，无定位间隙） */
.key-nav-item::before{content:"";font-size:20px;color:#f4f6fb;}
.key-nav-item::after{content:"";font-size:20px;color:#f4f6fb;}
.key-nav-item:hover::before,
.key-nav-item.active::before{content:"- ";}
.key-nav-item:hover::after,
.key-nav-item.active::after{content:" -";}
.key-nav-item:hover,
.key-nav-item.active,
.key-nav-item.nav-hover{
  transform:scale(1.18);color:#fff;
}
.key-nav-item.nav-hover::before{content:"- ";}
.key-nav-item.nav-hover::after{content:" -";}
@media (prefers-reduced-motion:reduce){
  .key-nav-item{transition:none;}
}

/* ===== About me 中心钥匙扣串 ===== */
.keychain-cluster{
  position:absolute;inset:0;z-index:12;pointer-events:none;
}
.kc-pivot{
  position:absolute;inset:0;
  transform-origin:888px 412px;
  pointer-events:none;
}

.kc-charm{position:absolute;display:block;pointer-events:auto;transition:transform .45s cubic-bezier(.22,.61,.36,1);transform-origin:50% 0;}
.kc-charm img{display:block;width:100%;height:100%;object-fit:contain;transform-origin:50% 0;}

/* 主钥匙扣：完全固定不动；x 由 943.97 左移至 796，使中心≈舞台中线(900)，不再偏右；坐标严格按 ABOUTME.txt 1800×900 画布 */
.kc-main{
  --kx:806px;--ky:68px;
  left:0;top:0;width:208px;height:270px;
  transform:translate(calc(var(--kx) + var(--ox,0px)), calc(var(--ky) + var(--oy,0px))) rotate(var(--gr,0deg));
  z-index:10;
}

/* 挂件默认位置：严格按 ABOUTME.txt 1800×900 画布坐标（line27-32 原值，未做任何平移）；
   舞台 .scaler(1800×900) 已居中缩放，txt 坐标直接生效；尺寸=SVG 自然尺寸，不旋转不翻转。
   层级：按左侧导航栏从上到下（Profile→Works→Showcase→Skills→Personal），越靠上 z-index 越高，
   故 Profile 在最上层；主钥匙扣(10)在挂件之下，作为连接中枢。 */
.kc-profile{--kx:594px;--ky:246px;left:0;top:0;width:365px;height:362px;transform:translate(calc(var(--kx) + var(--ox,0px)), calc(var(--ky) + var(--oy,0px))) rotate(var(--gr,0deg));transform-origin:76% 12%;z-index:15;}
.kc-works{--kx:683px;--ky:301px;left:0;top:0;width:243px;height:461px;transform:translate(calc(var(--kx) + var(--ox,0px)), calc(var(--ky) + var(--oy,0px))) rotate(var(--gr,0deg));transform-origin:83% 0%;z-index:14;}
.kc-showcase{--kx:742px;--ky:310px;left:0;top:0;width:301px;height:365px;transform:translate(calc(var(--kx) + var(--ox,0px)), calc(var(--ky) + var(--oy,0px))) rotate(var(--gr,0deg));transform-origin:55% 0%;z-index:13;}
.kc-skills{--kx:864px;--ky:305px;left:0;top:0;width:271px;height:430px;transform:translate(calc(var(--kx) + var(--ox,0px)), calc(var(--ky) + var(--oy,0px))) rotate(var(--gr,0deg));transform-origin:21% 0%;z-index:12;}
.kc-personal{--kx:868px;--ky:269px;left:0;top:0;width:315px;height:331px;transform:translate(calc(var(--kx) + var(--ox,0px)), calc(var(--ky) + var(--oy,0px))) rotate(var(--gr,0deg));transform-origin:21% 7%;z-index:11;}

/* 悬停时微微下移（约 12px，模拟重力响应） */
.kc-profile[data-hover-target="1"]{--ky:251px;}
.kc-works[data-hover-target="1"]{--ky:306px;}
.kc-showcase[data-hover-target="1"]{--ky:315px;}
.kc-skills[data-hover-target="1"]{--ky:310px;}
.kc-personal[data-hover-target="1"]{--ky:274px;}

/* 摆动改为以素材顶端"环扣/连线"为支点（脚本逐像素实测每颗连接线的位置）：
   支点=每颗钥匙扣连到主钥匙扣的那根细线的最高点，绕此点旋转 →
   顶端环扣固定不动，仅下方像钟摆一样荡。
   Profile 线在右上(76%,12%) / Works 线在右上(83%,0%) / Showcase 线在中上(55%,0%)
   / Skills 线在左上(21%,0%) / Personal 线在左上(21%,7%) */
.kc-profile img{animation:swayProfile 4.4s ease-in-out infinite alternate;transform-origin:76% 12%;}
.kc-works img{animation:swayWorks 4.1s ease-in-out infinite alternate;animation-delay:-1.7s;transform-origin:83% 0%;}
.kc-showcase img{animation:swayShowcase 4.0s ease-in-out infinite alternate;transform-origin:55% 0%;}
.kc-skills img{animation:swaySkills 4.8s ease-in-out infinite alternate;transform-origin:21% 0%;}
.kc-personal img{animation:swayPersonal 5.5s ease-in-out infinite alternate;transform-origin:21% 7%;}

@keyframes swayProfile{0%{transform:rotate(-4deg);}100%{transform:rotate(4deg);}}
@keyframes swayWorks{0%{transform:rotate(-3deg);}100%{transform:rotate(3deg);}}
@keyframes swayShowcase{0%{transform:rotate(-5deg);}100%{transform:rotate(5deg);}}
@keyframes swaySkills{0%{transform:rotate(-2.5deg);}100%{transform:rotate(2.5deg);}}
@keyframes swayPersonal{0%{transform:rotate(-4.5deg);}100%{transform:rotate(4.5deg);}}

@media (prefers-reduced-motion:reduce){
  .kc-charm img{animation:none;}
}

/* 待机（无悬停）时：各钥匙扣按导航层级堆叠——Profile 最上 → Works → Showcase → Skills → Personal → 主钥匙扣最下（z-index 15→10）；
   仅当某颗被悬停时：被悬停者跳到最上层(z-index:20)，其余下沉(z-index:5)，实现「悬停到最前」；
   打开详情页(data-active)时整串下沉，让位给详情遮罩。位置(translate)一律不变。 */
/* 悬停：仅被悬停的钥匙扣跳到最前(z-index:20)，其余保持待机相对层级
   (Profile15 > Works14 > Showcase13 > Skills12 > Personal11 > Main10)，
   不再统一压平到 z5 —— 否则 Personal 会借 DOM 顺序反超 Skills。 */
.keychain-cluster .kc-charm[data-hover-target="1"]{z-index:20;}
/* 打开详情页：整串回到待机相对层级（自然 z-index），不压平，层级关系与待机一致 */

/* ===== 悬停让位（摆动版）：被悬停者置顶(z20)并微沉，其余钥匙扣以各自"顶端环扣点"为支点
   (transform-origin 已与各挂件 img 的环扣点一致)像钟摆一样向远离被悬停者的一侧摆开，
   给被悬停者让出全貌；环扣点不动 → 摆开后仍钉在主钥匙扣的圆环上，不偏离。
   同侧按离被悬停者的距离逐级加大摆角，避免互相重叠。纯 rotate（无平移），
   沿用 .kc-charm 的 transform 过渡(.45s)平滑摆动；左组摆左(正角)、右组摆右(负角)，越远摆越大。 */
/* 悬停 Profile（最左）：右侧四颗全部往右摆(负角)，越靠右摆越大（幅度加大，更高让位） */
.keychain-cluster[data-hover="profile"]   .kc-works   {--gr:-22deg;}
.keychain-cluster[data-hover="profile"]   .kc-showcase{--gr:-24deg;}
.keychain-cluster[data-hover="profile"]   .kc-skills  {--gr:-32deg;}
.keychain-cluster[data-hover="profile"]   .kc-personal{--gr:-34deg;}

/* 悬停 Works：Profile 往左摆(正角，最大)，右侧三颗往右摆 */
.keychain-cluster[data-hover="works"]     .kc-profile {--gr:26deg;}
.keychain-cluster[data-hover="works"]     .kc-showcase{--gr:-22deg;}
.keychain-cluster[data-hover="works"]     .kc-skills  {--gr:-24deg;}
.keychain-cluster[data-hover="works"]     .kc-personal{--gr:-32deg;}

/* 悬停 Showcase（居中）：左组往左摆、右组往右摆，两端摆最大（幅度加大，明显抬高让位） */
.keychain-cluster[data-hover="showcase"]  .kc-profile {--gr:26deg;}
.keychain-cluster[data-hover="showcase"]  .kc-works   {--gr:16deg;}
.keychain-cluster[data-hover="showcase"]  .kc-skills  {--gr:-16deg;}
.keychain-cluster[data-hover="showcase"]  .kc-personal{--gr:-26deg;}

/* 悬停 Skills：左侧三颗往左摆、Personal 往右摆(最小) */
.keychain-cluster[data-hover="skills"]    .kc-profile {--gr:40deg;}
.keychain-cluster[data-hover="skills"]    .kc-works   {--gr:32deg;}
.keychain-cluster[data-hover="skills"]    .kc-showcase{--gr:30deg;}
.keychain-cluster[data-hover="skills"]    .kc-personal{--gr:-16deg;}

/* 悬停 Personal（最右）：左侧四颗全部往左摆(正角)，越靠左摆越大 */
.keychain-cluster[data-hover="personal"]  .kc-skills  {--gr:33deg;}
.keychain-cluster[data-hover="personal"]  .kc-showcase{--gr:24deg;z-index:11;}
.keychain-cluster[data-hover="personal"]  .kc-works   {--gr:32deg;}
.keychain-cluster[data-hover="personal"]  .kc-profile {--gr:40deg;}

/* ===== About me 详情页遮罩（与其他页面一致：从底部上划覆盖） ===== */
.about-detail{
  position:fixed;inset:0;z-index:100;
  transform:translateY(100%);
  visibility:hidden;pointer-events:none;
  transition:transform .6s cubic-bezier(.22,.61,.36,1), visibility .6s;
}
.about-detail.is-open{
  visibility:visible;pointer-events:auto;
  transform:translateY(0);
}
.about-detail-bg{position:absolute;inset:0;background:rgba(0,0,0,.85);}
.about-detail-body{position:absolute;inset:0;overflow-y:auto;overflow-x:hidden;-webkit-overflow-scrolling:touch;}
.about-detail-content{min-height:100%;padding:120px 120px 100px;}
.about-detail-watermark{
  position:absolute;left:50%;bottom:16px;transform:translateX(-50%);
  width:166px;height:33px;pointer-events:none;z-index:2;opacity:.6;
}
/* Skills 详情页：Skill Set 标题图（静态，无待机动画）；画面中心底部、水印上方 25px */
.skill-set-img{
  position:absolute;left:50%;bottom:99px;transform:translateX(-50%);
  width:200px;height:auto;display:none;z-index:3;pointer-events:none;
  animation:skillSetFloat 3.6s ease-in-out infinite;
}
@keyframes skillSetFloat{
  0%,100%{transform:translate(-50%,0);}
  50%{transform:translate(-50%,-6px);}
}
.about-detail[data-active="skills"] .skill-set-img{display:block;}
/* Skills 页：椭圆弧线（1800×169），已移入 .skills-canvas 内部，
   用 1800×900 画板设计空间坐标定位，随 --sk-s 与卡牌同步缩放，大屏不再错位。
   弧线视觉中心 ≈ 画板 y=219（卡牌夹子线），图片高 169 → 顶边 top=219-169/2≈135 */
.ellipse-arc-img{
  position:absolute;left:0;top:105px;
  width:1800px;height:auto;display:none;z-index:1;pointer-events:none;
}
.about-detail[data-active="skills"] .ellipse-arc-img{display:block;}
/* === Skills 详情页：卡牌弧线轨道 + 语言切换 === */
.skills-canvas{
  position:absolute;left:50%;top:50%;
  width:1800px;height:900px;
  transform:translate(-50%,-50%) scale(var(--sk-s,1));
  transform-origin:center center;z-index:4;
  pointer-events:none;
  user-select:none;-webkit-user-select:none;
}
.about-detail[data-active="skills"] .skills-canvas{pointer-events:auto;}
.skill-card{
  position:absolute;width:254px;height:409px;z-index:2;
  transform-origin:50% 0%; /* 挂绳点（夹子）在卡片顶部中心 */
  /* 平时（非 skills 页）完全不接收鼠标，避免隐形的 opacity:0 卡牌跨页拦截工卡等其他内容的拖拽 */
  pointer-events:none;cursor:grab;
  will-change:transform;backface-visibility:hidden;
  opacity:0;
  user-select:none;-webkit-user-select:none; /* 拖拽时不被当成文本/图片选中 */
  -webkit-user-drag:none;user-drag:none;     /* 禁用浏览器原生图片拖拽 */
}
/* 仅当在 Skills 页激活时，卡牌才接收鼠标（拖拽/悬停） */
.about-detail[data-active="skills"] .skill-card{pointer-events:auto;}
.skill-card.dragging{cursor:grabbing;z-index:10;}
.about-detail-back{position:absolute;left:26px;top:22px;z-index:50;width:58px;height:auto;cursor:pointer;filter:drop-shadow(0 3px 8px rgba(0,0,0,.4));transition:transform .2s ease;}
.about-detail-back img{display:block;width:100%;height:auto;}
.about-detail-back:hover{transform:translateX(-3px) scale(1.06);}

/* === Works detail page (aboutDetail#worksCanvas) === */
.about-detail-content{position:relative;width:100%;height:100%;min-height:100%;padding:0;overflow:hidden;}
.works-canvas{
  position:absolute;left:50%;top:50%;
  width:1800px;height:900px;
  transform:translate(-50%,-50%) scale(var(--wk-s,1));
  transform-origin:center center;z-index:1;
}
.works-canvas .wk{position:absolute;display:block;pointer-events:none;user-select:none;-webkit-user-drag:none;}
.works-canvas .paper1{left:808px;top:51px;width:798px;height:780px;z-index:2;}
.works-canvas .paper2{left:829px;top:106px;width:784px;height:676px;z-index:1;
                    transform-origin:50% 50%;animation:p2Sway 4.8s ease-in-out infinite;}
.works-canvas .env-back{left:264px;top:175px;width:434px;height:502px;z-index:3;}
.works-canvas .env-front{left:264px;top:385px;width:435px;height:341px;z-index:5;}
.works-canvas .letter-wrap{left:257px;top:196px;width:449px;height:334px;z-index:4;animation:wkLetterFloat 3.5s ease-in-out infinite;pointer-events:auto;cursor:pointer;}
@keyframes wkLetterFloat{
  0%,100%{transform:translateY(-6px);}
  50%{transform:translateY(6px);}
}
.works-canvas .letter-img{display:block;width:100%;height:100%;transform-origin:center center;transition:transform .45s cubic-bezier(.22,.61,.36,1);}
.works-canvas .letter-wrap:hover .letter-img{transform:translateY(-30px) rotate(4deg);}
.works-canvas .en-text{left:1031px;top:267px;width:402px;height:356px;z-index:6;}
.works-canvas #enTextCn{width:396px;height:326px;}
.works-canvas .star{left:1345px;top:509px;width:285px;height:239px;z-index:7;animation:worksStarTwirl 6s ease-in-out infinite;}
@keyframes worksStarTwirl{
  0%,100%{transform:rotate(-6deg);}
  50%{transform:rotate(6deg);}
}
/* Translate 切换键：移到 .about-detail 层级，right:26px 与返回键 left:26px 对称 */
.translate-btn{
  position:absolute;right:26px;top:22px;width:48px;height:48px;z-index:50;
  background:transparent;border:0;padding:0;margin:0;
  display:none;align-items:center;justify-content:center;
  cursor:pointer;pointer-events:auto;border-radius:50%;
  transition:transform .25s ease,filter .25s ease;
  filter:drop-shadow(0 3px 6px rgba(0,0,0,.4));
}
.about-detail[data-active="works"] .translate-btn,
.about-detail[data-active="profile"] .translate-btn,
.about-detail[data-active="skills"] .translate-btn{display:flex;}
.translate-btn:hover{transform:scale(1.15);filter:drop-shadow(0 5px 10px rgba(0,0,0,.55));}
.translate-btn:active{transform:scale(.95);}
.translate-btn img{width:100%;height:100%;display:block;pointer-events:none;user-select:none;}
/* About 详情页占位：角色上下漂浮 + Still building ... */
.about-placeholder{
  position:absolute;inset:0;
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:20px;
  user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;
}
.ab-build-gamer{
  position:relative;top:10px;
  width:88.6px;height:auto;
  animation:buildGamerFloat 2.4s ease-in-out infinite;
  filter:drop-shadow(0 10px 20px rgba(0,0,0,.35));
  -webkit-user-drag:none;user-select:none;
}
@keyframes buildGamerFloat{
  0%,100%{transform:translateY(0);}
  50%{transform:translateY(-18px);}
}
.ab-build-text{
  font-family:'FZSiLTJW',serif;font-size:22px;color:#fff;
  letter-spacing:.04em;text-shadow:0 2px 8px rgba(0,0,0,.45);
}
.loading-dots i{
  display:inline-block;font-style:normal;
  animation:dotBlink 1.2s ease-in-out infinite;
}
.loading-dots i:nth-child(1){animation-delay:0s;}
.loading-dots i:nth-child(2){animation-delay:.2s;}
.loading-dots i:nth-child(3){animation-delay:.4s;}
@keyframes dotBlink{
  0%,100%{opacity:.2;transform:translateY(0);}
  50%{opacity:1;transform:translateY(-4px);}
}

/* === Profile detail page (aboutDetail#profileCanvas) === */
/* 与 works-canvas 同样的居中 1800×900 缩放画板；CSS 变量 --pf-s 由 JS 写入 */
.profile-canvas{
  position:absolute;left:50%;top:50%;
  width:1800px;height:900px;
  transform:translate(-50%,-50%) scale(var(--pf-s,1));
  transform-origin:center center;z-index:1;
}
/* 工卡：按用户要求「不缩放、直接拉进画面、超出部分裁切」。
   用 card.webp 原生 422×940（1:1 不缩放）。绳子在图内 y=0~573、卡身 y=575~931。
   把卡片顶部（绳子根部）推到画板上方之外（top:-303px），绳子被 .about-detail-content
   的 overflow:hidden 裁掉，卡身（575~931）完整可见、垂直居中；left:282.67 保持左侧定位。
   transform-origin 设顶部中心——旋转/位移都像"从吊绳根部（画板外）"摆动。 */
.profile-card{
  position:absolute;left:232.67px;top:-288px;
  width:422px;height:940px;
  z-index:5;
  pointer-events:auto;cursor:grab;
  user-select:none;-webkit-user-drag:none;
  transform-origin:50% 0%;
  will-change:transform;
  touch-action:none;
}
.profile-card.dragging{cursor:grabbing;}
.profile-card .card-img{
  display:block;width:100%;height:100%;
  pointer-events:none;user-select:none;-webkit-user-drag:none;
  -webkit-user-drag:none;
}

/* === Profile 各图层坐标（按 profile_coords.json 解析的 Figma SVG） ===
   全部绝对定位在 1800×900 画板内；z-index 从底到顶递增。
   transform-origin:0 0 让旋转支点在元素自身左上角，与 Figma 一致。 */
.profile-layer{
  position:absolute;display:block;
  user-select:none;-webkit-user-drag:none;
  pointer-events:none;            /* 装饰元素不挡鼠标，让工卡可拖 */
}
/* slot1: 底层堆叠纸张 */
.profile-p2{left:779.24px;top:101.94px;width:827px;height:703px;z-index:1;
        transform-origin:50% 50%;animation:p2Sway 4.8s ease-in-out infinite;}
@keyframes p2Sway{
  0%,100%{transform:rotate(-1deg);}
  50%   {transform:rotate( 1deg);}
}
/* slot2: 蓝色花边纸（覆盖在 p2 之上） */
.profile-p1{left:794px;top:139px;width:795px;height:608px;z-index:2;}
/* En 英文文案（无损 WebP；viewBox 原生 621×403，原尺寸不缩放）
   叠在 p1 纸张左半区（纸张 x:794–1589, y:139–747），不挡右侧头像。
   用户微调：下移 40px、右移 30px → left:860 top:250；再右移 20px → 880；再右移 15px → 895；再左移 5px → 890 */
.profile-en{left:890px;top:250px;width:621px;height:403px;z-index:3;}
/* Cn 中文文案（无损 WebP）：与 En 同尺寸、同位置（left:890 top:250 621×403）。
   画布内容已在 Pillow 中右移 24px，使 Cn 内容中心(612)与 En 内容中心(612)重合 → 横向完全对齐 */
.profile-cn{left:890px;top:250px;width:621px;height:403px;z-index:3;}
/* slot3: Archive 燕尾夹
   外层 .profile-cut-wrap 负责位置 + 微微左右摆动（绕顶端支点 ±1.5°，3.6s 周期），
   内层 .profile-cut 保持 Figma 原解析的 4.417° 旋转不变。 */
.profile-cut-wrap{left:957.1px;top:37px;width:243.03px;height:223.75px;z-index:4;
                  transform-origin:50% 0%;pointer-events:none;
                  animation:cutSway 3.6s ease-in-out infinite;}
.profile-cut{display:block;width:100%;height:100%;
             transform-origin:0 0;transform:rotate(4.417deg);}
@keyframes cutSway{
  0%,100%{transform:rotate(-2deg);}
  50%   {transform:rotate( 2deg);}
}
/* slot5: 个人照片（右侧） */
.profile-photo{left:1299.74px;top:228.44px;width:172px;height:172px;z-index:5;}
/* slot4: 图钉（最右边缘，z 最高；微微上下浮动 ±2.5px，2.8s 周期） */
.profile-ding{left:1554.24px;top:257.94px;width:70px;height:74px;z-index:6;
              animation:dingFloat 2.8s ease-in-out infinite;}
@keyframes dingFloat{
  0%,100%{transform:translateY( 0px);}
  50%   {transform:translateY(-6px);}
}

/* 详情页内容按 key 切换：works=作品画板，profile=Profile 工卡画板，其余 3 个=占位（保持原样） */
.about-detail-content .works-canvas,
.about-detail-content .profile-canvas,
.about-detail-content .about-placeholder{display:none;}
.about-detail[data-active="works"] .works-canvas{display:block;}
.about-detail[data-active="profile"] .profile-canvas{display:block;}
/* Skills 提示词只在 Skills 页显示：skills-canvas 默认不 display:none（仅切 pointer-events），
   里面的 .hint 若不按 data-active 隐藏会串到 Profile 页。这里兜底隐藏，与 Profile 提示词同 .hint 样式/高度 */
.about-detail:not([data-active="skills"]) .skills-canvas .hint{display:none;}
.about-detail:not([data-active="works"]):not([data-active="profile"]):not([data-active="skills"]) .about-placeholder{display:flex;}

/* 打开详情时暂停并隐藏钥匙扣悬停动效，避免与遮罩冲突 */
.about-detail.is-open ~ .scaler .keychain-cluster,
.about-detail.is-open ~ .scaler .key-nav{pointer-events:none;}

/* ===== 钥匙扣手动微调（拖拽模式，keychain-finetune.js 配套） ===== */
#kcFinetunePanel{
  position:fixed;top:14px;right:14px;z-index:99999;
  width:236px;padding:12px 14px;border-radius:12px;
  background:rgba(18,18,26,.88);color:#eee;
  font:13px/1.5 -apple-system,"Segoe UI",Roboto,"PingFang SC","Microsoft YaHei",sans-serif;
  box-shadow:0 8px 30px rgba(0,0,0,.45);backdrop-filter:blur(6px);
  display:none;user-select:none;
}
#kcFinetunePanel .kc-ft-head{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-bottom:4px;}
#kcFinetunePanel .kc-ft-head strong{font-size:13px;font-weight:600;}
#kcFinetunePanel button{cursor:pointer;border:0;border-radius:8px;padding:5px 9px;background:#5b6cff;color:#fff;font-size:12px;transition:filter .15s;}
#kcFinetunePanel button:hover{filter:brightness(1.12);}
#kcFinetunePanel .kc-ft-tip{margin:8px 0;color:#9aa0b5;font-size:11px;line-height:1.45;}
#kcFinetunePanel .kc-ft-list{list-style:none;margin:0 0 10px;padding:0;}
#kcFinetunePanel .kc-ft-list li{display:flex;justify-content:space-between;padding:2px 0;}
#kcFinetunePanel .kc-ft-k{color:#9fb0ff;text-transform:capitalize;}
#kcFinetunePanel .kc-ft-v{font-variant-numeric:tabular-nums;color:#fff;}
#kcFinetunePanel .kc-ft-actions{display:flex;gap:6px;}
#kcFinetunePanel .kc-ft-actions button{flex:1;background:#3a3f52;}
#kcFinetunePanel .kc-ft-actions #kcFtCopy{background:#5b6cff;}
body.kc-finetune-on .kc-charm{cursor:grab;transition:none;}
body.kc-finetune-on .kc-charm.kc-dragging{cursor:grabbing;}
body.kc-finetune-on .kc-charm:hover{outline:1px dashed rgba(123,148,255,.7);outline-offset:2px;}

