/* ==========================================================================
   宠物立体形象 · 动画层 + 宠物空间场景   pet-anim.css   v2.0.0
   依赖：无。必须在 style.css 之后引入。
   --------------------------------------------------------------------------
   结构约定（三层 transform 互不打架）—— 完全沿用 pet-motion.js，零改动：
     .pet-scene                       庭院场景卡片（5 层叠加 + HUD）
      ├ .ps-sky   z=1                 远景天空（渐变 + 太阳 + 云）
      ├ .ps-far   z=2                 远景（远山 / 远树 / 棚架）
      ├ .ps-mid   z=3                 中景（草坪 / 石板路 / 小屋 / 栅栏 / 风车）
      ├ .pet-stage z=50               宠物活动层（唯一接收点击的装饰层）
      │   └ .pet-actor                位移层，rAF 写 translate3d + 纵深 scale
      │       ├ .pet-flip             朝向层 scaleX(var(--fx))，带 .24s 过渡
      │       │   └ svg.pet-svg       ★ 唯一被翻转的元素
      │       ├ .pet-bubble           ★ 状态气泡（必须在 .pet-flip 之外，否则文字镜像）
      │       ├ .pet-fx / .pet-dust / .pet-tear / .pet-zzz / .pet-emote
      ├ .ps-near  z=95                前景遮挡（花丛 / 草莓丛）
      └ .ps-hud   z=100               HUD（状态胶囊 + 等级徽章）
   --------------------------------------------------------------------------
   命名：部件 .pt-{部件}（与美术规格 pet-art-spec-v1.0 完全一致；旧 .p-* 已全部废弃）
         状态 .is-{状态}（挂在 .pet-actor 上；美术规格的 pt-anim-* 不实现）
         关键帧 kf-{部件}-{动作}（名字不动）
   ========================================================================== */

/* ---------- 0. 场景与三层容器 ---------- */
.pet-stage{ position:relative; overflow:hidden; touch-action:manipulation; -webkit-tap-highlight-color:transparent; }
.pet-stage.is-shake{ animation:kf-stage-shake .14s linear; }

.pet-actor{
  /* ★ 尺寸由 JS 下发 --pet-size（设计案 §3.4 渲染框尺寸表），不能写死 */
  width:var(--pet-size,96px); height:var(--pet-size,96px);
  position:absolute; left:0; top:0;
  transform-origin:50% 100%;
  pointer-events:none;            /* 点击由 .pet-stage 统一接管 */
}
.pet-actor.is-moving{ will-change:transform; }   /* 只在移动期挂 will-change */

.pet-flip{
  position:absolute; inset:0;
  transform-origin:50% 100%;
  /* --pet-lift：跨形态「脚底对齐」补偿。PetMotion 把 .pet-actor 的**盒子底边**钉在 y×H，
     而地面线 GY=104 在盒内 104/120 处 → 脚底 = y×H − 0.1333×boxH。
     美术规格每阶段框尺寸不同（S2 133 → S6 172），不补偿的话换形态脚底会上下跳最多 5px。
     故由程序按 (boxH − 基准H) × 0.13333 下发 --pet-lift，把内容反向推回同一条地面线。 */
  transform:translateY(var(--pet-lift,0px)) scaleX(var(--fx,1));
  transition:transform .24s cubic-bezier(.34,0,.64,1);
}
.pet-svg{ display:block; overflow:visible; }
.pet-flip > .pet-svg{ width:100%; height:100%; }

/* ---------- 1. SVG 部件：transform-origin 由美术规格内联写死，CSS 不覆盖 ----------
   注意：带内联 style="transform-origin:Xpx Ypx" 的部件（pt-root / pt-body / pt-head /
   pt-tail / pt-leg-* / pt-acc）使用 SVG 默认 transform-box:view-box，单位是 viewBox 用户
   单位（120×120）。这里**绝不能**给它们加 transform-box:fill-box —— 否则内联原点会被
   重新解释成「自身包围盒百分比」，所有旋转/缩放轴心全部错位。
   只有没有内联原点的叶子部件（眼 / 嘴 / 耳 / 角 / 腮红）才用 fill-box + 百分比。        */
.pet-svg .pt-eye-l,.pet-svg .pt-eye-r,
.pet-svg .pt-mouth,
.pet-svg .pt-ear-f,.pet-svg .pt-ear-n,
.pet-svg .pt-horn-f,.pet-svg .pt-horn-n,
.pet-svg .pt-blush-l,.pet-svg .pt-blush-r,
.pet-svg .pt-skull,.pet-svg .pt-hl{ transform-box:fill-box; transform-origin:50% 50%; }

/* 地面投影：三层同心椭圆，bbox 中心即 (60,104)，用 view-box 绝对单位更稳 */
.pet-svg .pt-shadow{ transform-origin:60px 104px; }
.pet-svg .pt-shadow{ fill:#c9a99b; }
.pet-svg .pt-shadow > *{ fill:inherit; }

/* 美术规格缺口兜底：sheep S2–S6 的 pt-body 羊毛圆**未声明 fill**（SVG 缺省 = 黑），
   直接渲染小羊会黑成一团。给组补默认色 = 规格 pt-body 底椭圆同款奶油白 #FFF6EE；
   组内已显式声明 fill 的（底椭圆 / pt-wool2 / 高光）不受影响。pig 全部自带 fill，无需处理。 */
.pet-svg.pet-sheep .pt-body{ fill:#FFF6EE; }

/* will-change 名额只给根节点与四条腿（美术规格 §7.4：≤8） */
.pet-svg .pt-root,
.pet-svg .pt-leg-fn,.pet-svg .pt-leg-hn,
.pet-svg .pt-leg-ff,.pet-svg .pt-leg-hf{ will-change:transform; }

/* ---------- 2. 默认待机：常驻循环 ---------- */
.pet-actor .pt-body  { animation:kf-breathe    var(--breathDur,2.8s) ease-in-out infinite; }
.pet-actor .pt-head  { animation:kf-head-idle  var(--breathDur,2.8s) ease-in-out infinite; }
.pet-actor .pt-tail  { animation:kf-tail-idle  1.9s ease-in-out infinite; }
.pet-actor .pt-shadow{ animation:kf-shadow-idle var(--breathDur,2.8s) ease-in-out infinite; }

/* ---------- 3. 步行 is-walk（四足对角步态） ---------- */
.pet-actor.is-walk .pt-body { animation:kf-walk-body calc(var(--stepDur,.46s)/2) linear infinite; }
.pet-actor.is-walk .pt-head { animation:kf-walk-head var(--stepDur,.46s) ease-in-out infinite; }
.pet-actor.is-walk .pt-tail { animation:kf-tail-wag  calc(var(--stepDur,.46s)*2) ease-in-out infinite; }
.pet-actor.is-walk .pt-leg-fn{ animation:kf-walk-leg     var(--stepDur,.46s) ease-in-out infinite; }
.pet-actor.is-walk .pt-leg-hf{ animation:kf-walk-leg     var(--stepDur,.46s) ease-in-out infinite; }
.pet-actor.is-walk .pt-leg-hn{ animation:kf-walk-leg     var(--stepDur,.46s) ease-in-out infinite;
                               animation-delay:calc(var(--stepDur,.46s) * -.5); }
.pet-actor.is-walk .pt-leg-ff{ animation:kf-walk-leg-far var(--stepDur,.46s) ease-in-out infinite;
                               animation-delay:calc(var(--stepDur,.46s) * -.5); }
.pet-actor.is-walk .pt-ear-n { animation:kf-ear-flap calc(var(--stepDur,.46s)*1.5) ease-in-out infinite; }
.pet-actor.is-walk .pt-shadow{ animation:none; transform:scale(.96); opacity:.85; }

/* ---------- 4. 奔跑 is-run ---------- */
.pet-actor.is-run .pt-body { animation:kf-run-body var(--stepDur,.26s) ease-out infinite; }
.pet-actor.is-run .pt-head { animation:kf-run-head var(--stepDur,.26s) ease-in-out infinite; }
.pet-actor.is-run .pt-tail { animation:kf-tail-wag calc(var(--stepDur,.26s)*2) ease-in-out infinite; }
.pet-actor.is-run .pt-leg-fn{ animation:kf-run-leg     var(--stepDur,.26s) ease-in-out infinite; }
.pet-actor.is-run .pt-leg-hf{ animation:kf-run-leg     var(--stepDur,.26s) ease-in-out infinite; }
.pet-actor.is-run .pt-leg-hn{ animation:kf-run-leg     var(--stepDur,.26s) ease-in-out infinite;
                              animation-delay:calc(var(--stepDur,.26s) * -.5); }
.pet-actor.is-run .pt-leg-ff{ animation:kf-run-leg-far var(--stepDur,.26s) ease-in-out infinite;
                              animation-delay:calc(var(--stepDur,.26s) * -.5); }
.pet-actor.is-run .pt-ear-n { animation:kf-ear-back calc(var(--stepDur,.26s)*1.5) ease-out infinite; }
.pet-actor.is-run .pt-shadow{ animation:none; transform:scale(.9); opacity:.7; }
.pet-actor.is-run .pet-dust{ animation:kf-dust .5s ease-out infinite; }
.pet-actor.is-run .pet-dust:nth-child(2){ animation-delay:.18s; }

/* ---------- 4b. PNG 双足模式：躯干起伏（biped 立绘无 .pt-* 部件，§3/§4 的部件 keyframes 全部空转） ----------
   ★ 双足接入后立绘换成 PNG（app.js petImgHTML/.pet-img），页面上不存在 .pt-body/.pt-leg-* 等元素，
     故 §3 walk / §4 run 的部件动画对其无效 → 只剩 PetMotion 的 translate3d 平移（=用户说的"滑动"）。
   这里补 PNG 模式躯干起伏：作用在 .pet-layers（含本体 + 全部配饰 + 妆面，整体一起动，
   与 theme-v2.css §9.8 的 is-tap/is-happy/is-evolve 同目标同规范；只动 img 会让配饰脱离）。
   帧交替（本体帧 ↔ walk2 迈步帧）由 pet-motion.js 在 PNG 模式按 --stepDur/2 做，非 CSS。
   pet-png 标记类由 pet-motion.js 检测到 img.pet-img 时挂上。 */
.pet-actor.pet-png.is-walk .pet-layers{ animation:kf-png-bob var(--stepDur,.46s) ease-in-out infinite; }
.pet-actor.pet-png.is-run  .pet-layers{ animation:kf-png-bob-run var(--stepDur,.26s) ease-in-out infinite; }
@keyframes kf-png-bob{     0%,100%{ transform:translateY(0) }            50%{ transform:translateY(-2.2%) } }
@keyframes kf-png-bob-run{ 0%,100%{ transform:translateY(0) scaleY(1) }  50%{ transform:translateY(-4.5%) scaleY(1.025) } }
/* 降级门闩：reduced-motion / perf-low → 全关（不占合成层） */
@media (prefers-reduced-motion: reduce){
  .pet-actor.pet-png.is-walk .pet-layers,
  .pet-actor.pet-png.is-run  .pet-layers{ animation:none; }
}
.pet-actor.pet-png.perf-low .pet-layers{ animation:none !important; }


/* ---------- 4b. ★B2：PNG（双足）步态 —— 帧交替 + 躯干起伏 ----------
   帧交替由 pet-motion.js 驱动（移动中 img.pet-img 的 src 在 本体帧 ↔ walk2/ 迈步帧 间按
   --stepDur/2 交替；停下回本体帧）。此处补 PNG 模式的躯干 bob（is-run 幅度更大）。
   选择器仅命中 .pet-base img.pet-img —— SVG 模式无此元素故不受影响；
   作用元素是 img.pet-img（非 .pet-flip），与 --pet-lift 不冲突。
   降级门闩：prefers-reduced-motion / <html>.perf-low 下关闭 bob（帧交替在 JS 侧同步关闭）。 */
@keyframes kf-png-step {
  0%,100%{ transform:translateY(0) scaleY(1); }
  50%    { transform:translateY(-1.8%) scaleY(1.012); }
}
@keyframes kf-png-step-run {
  0%,100%{ transform:translateY(0) scaleY(1); }
  45%    { transform:translateY(-3.2%) scaleY(1.024); }
}
.pet-actor.is-walk .pet-base img.pet-img{
  transform-origin:50% 100%; animation:kf-png-step calc(var(--stepDur,.46s)) ease-in-out infinite; }
.pet-actor.is-run  .pet-base img.pet-img{
  transform-origin:50% 100%; animation:kf-png-step-run calc(var(--stepDur,.26s)) ease-out infinite; }
@media (prefers-reduced-motion: reduce){
  .pet-actor.is-walk .pet-base img.pet-img,
  .pet-actor.is-run  .pet-base img.pet-img{ animation:none !important; }
}
.perf-low .pet-actor.is-walk .pet-base img.pet-img,
.perf-low .pet-actor.is-run  .pet-base img.pet-img{ animation:none !important; }

/* ---------- 5. 转身（不瞬间镜像） ---------- */
.pet-actor.is-turn .pet-svg{ animation:kf-turn-squash .24s cubic-bezier(.34,0,.64,1); }

/* ---------- 6. 单次行为：状态 class 一律挂在 .pet-actor ---------- */
/* 四处观察 */
.pet-actor.is-look  .pt-head{ animation:kf-look-around var(--lookDur,2.2s) ease-in-out; }
.pet-actor.is-look  .pt-ear-n{ animation:kf-ear-flap 1.1s ease-in-out; }
/* 点击回应：先转头看 0.25s，再动身 */
.pet-actor.is-tap   .pt-head{ animation:kf-tap-look .42s cubic-bezier(.34,1.4,.64,1); }
.pet-actor.is-tap   .pt-body{ animation:kf-tap-body .42s cubic-bezier(.34,1.4,.64,1); }
/* 进食 */
.pet-actor.is-eat   .pt-body { animation:kf-eat-body  1.1s ease-in-out infinite; }
.pet-actor.is-eat   .pt-head { animation:kf-eat-head  1.1s ease-in-out infinite; }
.pet-actor.is-eat   .pt-mouth{ animation:kf-chew      .42s ease-in-out infinite; }
.pet-actor.is-eat   .pt-tail { animation:kf-tail-wag  .9s  ease-in-out infinite; }
/* 开心 */
.pet-actor.is-happy .pt-root { animation:kf-happy-jump .72s cubic-bezier(.28,.9,.32,1) both; }
.pet-actor.is-happy .pt-ear-n{ animation:kf-ear-flap .36s ease-in-out 2; }
.pet-actor.is-happy .pt-tail { animation:kf-tail-wag .3s ease-in-out infinite; }
.pet-actor.is-happy .pt-shadow{ animation:kf-shadow-hop .72s ease-out both; }
/* 鼓励·答错 */
.pet-actor.is-encourage .pt-head{ animation:kf-encourage-head .9s ease-in-out; }
.pet-actor.is-encourage .pt-body{ animation:kf-encourage-body .9s ease-in-out; }
.pet-actor.is-encourage .pt-tail{ animation:kf-tail-wag 1.2s ease-in-out infinite; animation-direction:reverse; }
/* 难过 */
.pet-actor.is-sad .pt-body{ animation:kf-sad-body 2.4s ease-in-out infinite; }
.pet-actor.is-sad .pt-head{ animation:kf-sad-head 2.4s ease-in-out infinite; }
.pet-actor.is-sad .pt-ear-n,.pet-actor.is-sad .pt-ear-f{ animation:kf-sad-ear 2.4s ease-in-out infinite; }
.pet-actor.is-sad .pt-tail{ animation:kf-sad-tail 2.4s ease-in-out infinite; }
/* 饥饿 */
.pet-actor.is-hungry .pt-body{ animation:kf-hungry-body 1.6s ease-in-out infinite; }
.pet-actor.is-hungry .pt-head{ animation:kf-hungry-head 1.6s ease-in-out infinite; }
.pet-actor.is-hungry .pt-tail{ animation:kf-hungry-tail 2.2s ease-in-out infinite; }
/* 疲惫（10 ≤ ⚡ < 30）：呼吸变慢 + 步子拖沓 */
.pet-actor.is-tired{ --breathDur:4.2s; }
.pet-actor.is-tired.is-walk .pt-leg-fn,.pet-actor.is-tired.is-walk .pt-leg-hf,
.pet-actor.is-tired.is-walk .pt-leg-hn,.pet-actor.is-tired.is-walk .pt-leg-ff{ animation-duration:.62s; }
/* 困倦 */
.pet-actor.is-sleepy .pt-head{ animation:kf-sleepy-nod 2.6s ease-in-out infinite; }
.pet-actor.is-sleepy .pt-eye-l,.pet-actor.is-sleepy .pt-eye-r{ animation:kf-sleepy-eye 2.6s ease-in-out infinite; }
/* 坐下（低能量替代奔跑） */
.pet-actor.is-sit  .pt-body{ animation:kf-sit-body .45s cubic-bezier(.3,.9,.3,1) forwards; }
.pet-actor.is-sit  .pt-leg-hn,.pet-actor.is-sit .pt-leg-hf{ animation:kf-sit-leg .45s ease-out forwards; }
/* 睡觉 */
.pet-actor.is-sleep .pt-body{ animation:kf-sleep-body 4.2s ease-in-out infinite; }
.pet-actor.is-sleep .pt-head{ animation:kf-sleep-head 4.2s ease-in-out infinite; }
.pet-actor.is-sleep .pt-eye-l,.pet-actor.is-sleep .pt-eye-r{ animation:kf-sleepy-eye 999s linear forwards; animation-delay:-1s; }
/* 任务完成庆祝 */
.pet-actor.is-celebrate .pt-root{ animation:kf-celebrate 1.9s cubic-bezier(.3,.85,.35,1) both; }
.pet-actor.is-celebrate .pt-tail{ animation:kf-tail-wag .28s ease-in-out infinite; }
.pet-actor.is-celebrate .pt-shadow{ animation:kf-shadow-hop .63s ease-out 3; }
/* 阶段进化：★ 现有 5.5s 太长（孩子会以为卡住），设计案 §5.4 覆盖为 2.4s */
.pet-actor.is-evolve .pt-root{ animation:kf-evolve-body 2.4s cubic-bezier(.32,.8,.3,1) both; }
.pet-actor.is-evolve .pet-fx-ring{ animation:kf-evolve-ring .8s ease-out; }
.pet-actor.is-evolve .pet-fx-ring:nth-child(2){ animation-delay:.24s; }
.pet-actor.is-evolve .pet-fx-ring:nth-child(3){ animation-delay:.48s; }
.pet-actor.is-evolve .pet-fx-flash{ animation:kf-evolve-flash .9s ease-out 2; animation-delay:1.4s; }

/* 眨眼（JS 每 3–6s 加 .is-blink 120ms 后移除） */
.pet-actor.is-blink .pt-eye-l,.pet-actor.is-blink .pt-eye-r{ animation:kf-blink .12s linear; }

/* 小尺寸兜底：size ≤ 48 关掉细节，避免糊成一团（美术规格 §1.3）
   类名用 pt-mini 而非 pet-mini —— pet-mini 已被 style.css 的「全页悬浮宠物小窗」占用 */
.pt-mini .pt-brow-l,.pt-mini .pt-brow-r,
.pt-mini .pt-blush-l,.pt-mini .pt-blush-r,
.pt-mini .pt-mark,.pt-mini .pt-mark2,
.pt-mini .pt-chest,.pt-mini .pt-hl,.pt-mini .pt-acc{ display:none; }

/* ---------- 7. FX 层（DOM，不占 SVG 重绘） ---------- */
.pet-fx{ position:absolute; inset:0; pointer-events:none; }
.pet-fx-ring{
  position:absolute; left:50%; bottom:6px; width:72px; height:20px; margin-left:-36px;
  border:3px solid #ffd24a; border-radius:50%; opacity:0;
}
.pet-fx-flash{ position:absolute; inset:-20% -20%; border-radius:50%;
  background:radial-gradient(circle,#fff 0%,rgba(255,255,255,.7) 45%,rgba(255,255,255,0) 72%); opacity:0; }
.pet-dust{
  position:absolute; left:8%; bottom:2px; width:9px; height:9px; border-radius:50%;
  background:#e8c7d6; opacity:0;
}
.pet-dust:nth-child(2){ left:20%; width:7px; height:7px; }
.pet-emote{
  position:absolute; left:50%; top:-6px; transform:translate(-50%,0);
  font-size:16px; line-height:1; padding:2px 6px; border-radius:10px;
  background:#fff; border:2px solid var(--brand-soft,#ffd7e8); box-shadow:0 4px 10px rgba(0,0,0,.08);
  animation:kf-emote-pop .3s cubic-bezier(.34,1.5,.64,1) forwards;
}
.pet-zzz{ position:absolute; right:-4px; top:-2px; font-size:13px; font-weight:800; color:#ff7fa0;
  opacity:0; animation:none; }
.pet-actor.is-sleepy .pet-zzz{ animation:kf-zzz 2.1s ease-out infinite; }
.pet-actor.is-sleepy .pet-zzz:nth-child(2){ animation-delay:.7s; }
.pet-actor.is-sleepy .pet-zzz:nth-child(3){ animation-delay:1.4s; }
.pet-tear{ position:absolute; left:62%; top:34%; width:6px; height:8px; border-radius:50%;
  background:#7fc4ff; opacity:0; animation:none; }
.pet-actor.is-sad .pet-tear{ animation:kf-tear 1.6s ease-out infinite; }   /* §6.1：💗<25 才落泪 */

/* 状态气泡：★ 必须挂在 .pet-actor（.pet-flip 之外），否则文字被 scaleX(-1) 镜像 */
.pet-bubble{
  position:absolute; left:50%; bottom:100%; margin-bottom:-2px; z-index:6;
  transform:translateX(-50%);
  white-space:nowrap; font-size:12px; font-weight:800; line-height:1.35;
  color:var(--ink,#3a3f55);
  background:rgba(255,255,255,.96);
  border:2px solid var(--brand-soft,#ffd7e8);
  border-radius:12px; padding:5px 10px;
  box-shadow:0 4px 10px rgba(0,0,0,.08);
  opacity:0; pointer-events:none;
  transition:opacity .22s ease, transform .22s ease;
}
.pet-bubble.on{ opacity:1; transform:translateX(-50%) translateY(-5px); }
.pet-bubble::after{
  content:''; position:absolute; left:50%; top:100%; margin-left:-5px;
  width:0; height:0; border:5px solid transparent; border-top-color:var(--brand-soft,#ffd7e8);
}

/* ==========================================================================
   8. 宠物空间场景（P1 · 五层庭院 + 双身份主题）
   ========================================================================== */
.pet-scene{
  position:relative; width:100%;
  aspect-ratio:1/0.78; min-height:240px; max-height:360px;
  border-radius:18px; overflow:hidden;
  background:var(--sky-bot,#FFF9F2);
  box-shadow:0 6px 18px rgba(120,90,110,.10);
  user-select:none; -webkit-user-select:none;
}
.pet-scene > *{ position:absolute; }

/* --- 主题色板：姐姐 = 云朵花园（小羊） --- */
.pet-scene.th-sheep{
  --sky-top:#DCEEFF; --sky-bot:#FFF9F2;
  --hill:#C9E4D6; --tree:#A8C98A; --tree2:#87A96C;
  --lawn-far:#E4F3D4; --lawn-near:#CDE9B8;
  --path:#E8DFD2; --wood:#B98A5E; --wood2:#96694A;
  --roof:#FF8FB1; --flower:#FFFFFF; --flower2:#FFD9E6;
  --berry:#FF8FB1; --leaf:#A8D5BA;
}
/* --- 主题色板：妹妹 = 草莓果园（小猪） --- */
.pet-scene.th-pig{
  --sky-top:#FFE3EF; --sky-bot:#FFF9F2;
  --hill:#CFE8D8; --tree:#A8C98A; --tree2:#87A96C;
  --lawn-far:#E1F2CE; --lawn-near:#C8E6A8;
  --path:#E8DFD2; --wood:#B98A5E; --wood2:#96694A;
  --roof:#FF6F91; --flower:#FFB3C8; --flower2:#FF8FA8;
  --berry:#FF6F91; --leaf:#A8D5BA;
}

/* 8.1 远景天空 z=1 */
.ps-sky{ inset:0; z-index:1; background:linear-gradient(180deg,var(--sky-top) 0%,var(--sky-bot) 72%); }
.ps-sun{
  position:absolute; right:12%; top:9%; width:40px; height:40px; border-radius:50%;
  background:radial-gradient(circle at 40% 38%,#FFFCEC,#FFE49B 60%,#FFD06B);
  box-shadow:0 0 0 9px rgba(255,216,130,.28), 0 0 22px rgba(255,206,110,.35);
}
.ps-cloud{
  position:absolute; width:56px; height:18px; border-radius:9px;
  background:rgba(255,255,255,.92);
  animation:kf-cloud-drift linear infinite;
}
.ps-cloud::before,.ps-cloud::after{
  content:''; position:absolute; border-radius:50%; background:inherit;
}
.ps-cloud::before{ width:26px; height:26px; left:8px;  top:-13px; }
.ps-cloud::after { width:20px; height:20px; right:9px; top:-9px;  }
.ps-cloud.c1{ top:16%; left:-70px; transform:scale(.9);  animation-duration:62s; }
.ps-cloud.c2{ top:30%; left:-70px; transform:scale(1.15);animation-duration:48s; animation-delay:-18s; }
.ps-cloud.c3{ top:8%;  left:-70px; transform:scale(.7);  animation-duration:74s; animation-delay:-40s; }

/* 8.2 远景 / 中景 / 前景：SVG 铺满，viewBox 300×234 与场景 1:0.78 同比例 */
.ps-far { inset:0; z-index:2;  pointer-events:none; }
.ps-mid { inset:0; z-index:3;  pointer-events:none; }
.ps-near{ left:0; right:0; bottom:0; height:19%; z-index:95; pointer-events:none; }
.ps-far svg,.ps-mid svg,.ps-near svg{ display:block; width:100%; height:100%; }
.ps-wind{ animation:kf-windmill 12s linear infinite; }
.ps-bush{ animation:kf-bush-sway 6s ease-in-out infinite; }

/* 8.3 宠物活动层 z=50（前景 z=95 之下） */
.pet-scene > .pet-stage{ inset:0; z-index:50; }

/* 8.4 HUD z=100（禁用 backdrop-filter，移动端太贵，用近实色） */
.ps-hud{
  top:10px; left:10px; right:10px; z-index:100;
  display:flex; gap:6px; align-items:center;
  pointer-events:none;
}
.ps-stat{
  flex:1 1 0; min-width:0; height:30px; border-radius:15px;
  display:flex; align-items:center; justify-content:center; gap:3px;
  background:rgba(255,255,255,.88); border:1.5px solid rgba(255,255,255,.95);
  box-shadow:0 2px 6px rgba(90,70,80,.08);
  font-size:12px; font-weight:800; color:#4a4453; white-space:nowrap; overflow:hidden;
}
.ps-stat .ic{ font-size:12px; line-height:1; }
.ps-stat .v { font-size:13px; }
.ps-stat.warn{ background:rgba(255,244,228,.95); border-color:#FFD79A; color:#8a6316; }
.ps-stat.bad { background:rgba(255,236,236,.95); border-color:#FFB3B3; color:#a33b3b; }
/* ⭐ 经验胶囊内容最长（⭐ + 10/405），不参与等分 —— 按内容自适应，杜绝小屏裁字 */
.ps-stat.exp { flex:0 0 auto; padding:0 9px; }
.ps-lv{
  left:12px; bottom:12px; z-index:100;
  height:28px; padding:0 12px; border-radius:14px;
  display:flex; align-items:center; gap:6px;
  background:rgba(255,255,255,.9); border:2px solid var(--brand-soft,#ffe3ee);
  box-shadow:0 2px 6px rgba(90,70,80,.08);
  font-size:12px; font-weight:800; color:#4a4453;
}
.ps-lv b{ color:var(--brand,#ff5b8a); }

/* 8.5 点位提示（点地面跑过去） */
.ps-tip{
  right:12px; bottom:12px; z-index:100;
  font-size:11px; font-weight:700; color:#8a8296;
  background:rgba(255,255,255,.72); border-radius:10px; padding:4px 8px;
}

/* 8.6 互动菜单（点宠物弹出） */
.pet-menu{
  left:50%; bottom:46px; z-index:101; transform:translateX(-50%);
  display:flex; gap:6px; padding:6px; border-radius:14px;
  background:rgba(255,255,255,.96); border:2px solid var(--brand-soft,#ffe3ee);
  box-shadow:0 6px 18px rgba(90,70,80,.16);
  animation:kf-menu-in .2s cubic-bezier(.34,1.4,.64,1) both;
}
.pet-menu.hide{ display:none; }
.pet-menu button{
  border:none; background:var(--brand-soft,#ffe3ee); color:#c1316b;
  font-size:12px; font-weight:800; padding:8px 10px; border-radius:10px;
  white-space:nowrap; cursor:pointer;
}
.pet-menu button:active{ transform:scale(.94); }
.pet-menu button:disabled{ opacity:.45; }
.pet-menu button small{ display:block; font-size:10px; font-weight:700; opacity:.75; margin-top:1px; }

/* 8.7 场景外：经验细条 + 照顾按钮行 */
.ps-expbar{ position:relative; height:8px; border-radius:4px; background:#EDF1F8; overflow:hidden; margin:10px 2px 4px; }
.ps-expbar > i{ display:block; height:100%; border-radius:4px;
  background:linear-gradient(90deg,#FFD24A,var(--gold,#f5b301)); transition:width .4s ease; }
.ps-expnote{ font-size:11px; color:#8a8296; font-weight:700; text-align:right; margin:0 2px 10px; }
.ps-expnote.full{ color:#c98a00; }
.ps-care{ display:grid; grid-template-columns:1fr 1fr; gap:10px; margin-bottom:6px; }
.ps-care .btn{ margin:0; padding:13px 8px; font-size:14px; }
.ps-care .btn.wide{ grid-column:span 2; }
.ps-care .btn:disabled,.ps-care .btn[disabled]{ opacity:.45; box-shadow:none; }
.ps-care .btn small{ display:block; font-size:11px; font-weight:700; opacity:.85; margin-top:2px; }

/* ==========================================================================
   9. @keyframes 全表（名字保持 kf-* 不动）
   ========================================================================== */

/* --- 呼吸 / 待机 --- */
@keyframes kf-breathe{
  0%,100%{ transform:scale(1,1)      translateY(0); }
  50%    { transform:scale(1.025,.975) translateY(-1.2%); }
}
@keyframes kf-head-idle{
  0%,100%{ transform:rotate(0deg)    translateY(0); }
  50%    { transform:rotate(1.2deg)  translateY(-1.5%); }
}
@keyframes kf-tail-idle{
  0%,100%{ transform:rotate(-6deg); }
  50%    { transform:rotate(8deg); }
}
@keyframes kf-shadow-idle{
  0%,100%{ transform:scale(1);   opacity:.2; }
  50%    { transform:scale(.96); opacity:.17; }
}
@keyframes kf-blink{ 0%,100%{ transform:scaleY(1); } 50%{ transform:scaleY(.1); } }

/* --- 步行步态（四足对角步态：近前+远后 同相） --- */
@keyframes kf-walk-leg{
  0%  { transform:rotate(16deg)  translateY(0); }
  25% { transform:rotate(4deg)   translateY(-4%); }
  50% { transform:rotate(-16deg) translateY(0); }
  75% { transform:rotate(-6deg)  translateY(-2%); }
  100%{ transform:rotate(16deg)  translateY(0); }
}
@keyframes kf-walk-leg-far{
  0%  { transform:rotate(11deg)  translateY(0); }
  50% { transform:rotate(-11deg) translateY(0); }
  100%{ transform:rotate(11deg)  translateY(0); }
}
@keyframes kf-walk-body{
  0%,100%{ transform:translateY(0)     rotate(0deg); }
  50%    { transform:translateY(-2.4%) rotate(-.8deg); }
}
@keyframes kf-walk-head{
  0%,100%{ transform:rotate(1.5deg)  translateY(0); }
  50%    { transform:rotate(-1.5deg) translateY(-1%); }
}

/* --- 奔跑 --- */
@keyframes kf-run-leg{
  0%  { transform:rotate(30deg)  translateY(0)    scaleY(1); }
  30% { transform:rotate(6deg)   translateY(-9%)  scaleY(1.05); }
  55% { transform:rotate(-26deg) translateY(0)    scaleY(1); }
  80% { transform:rotate(-4deg)  translateY(-4%); }
  100%{ transform:rotate(30deg)  translateY(0); }
}
@keyframes kf-run-leg-far{
  0%  { transform:rotate(22deg)  translateY(0); }
  45% { transform:rotate(-20deg) translateY(-3%); }
  100%{ transform:rotate(22deg)  translateY(0); }
}
@keyframes kf-run-body{
  0%  { transform:translateY(0)     scale(1,1)       rotate(-3deg); }
  35% { transform:translateY(-7%)   scale(1.04,.96)  rotate(-6deg); }
  55% { transform:translateY(0)     scale(.98,1.02)  rotate(-2deg); }
  100%{ transform:translateY(0)     scale(1,1)       rotate(-3deg); }
}
@keyframes kf-run-head{ 0%,100%{ transform:rotate(-4deg); } 50%{ transform:rotate(3deg); } }
@keyframes kf-dust{
  0%  { transform:translate(0,0) scale(.4); opacity:.5; }
  100%{ transform:translate(var(--dx,-20px),-14px) scale(1.15); opacity:0; }
}

/* --- 尾巴 / 耳朵 --- */
@keyframes kf-tail-wag{ 0%,100%{ transform:rotate(-12deg); } 50%{ transform:rotate(16deg); } }
@keyframes kf-ear-flap{ 0%,100%{ transform:rotate(-9deg); }  50%{ transform:rotate(8deg); } }
@keyframes kf-ear-back{ 0%,100%{ transform:rotate(-16deg); } 50%{ transform:rotate(-26deg); } }

/* --- 转身 / 镜头震 --- */
@keyframes kf-turn-squash{
  0%  { transform:scaleX(1); }
  45% { transform:scaleX(.6) scaleY(1.07); }
  100%{ transform:scaleX(1); }
}
@keyframes kf-stage-shake{
  0%,100%{ transform:translate(0,0); }
  25%    { transform:translate(-3px,1px); }
  50%    { transform:translate(3px,-1px); }
  75%    { transform:translate(-1px,0); }
}

/* --- 观察 / 点击 --- */
@keyframes kf-look-around{
  0%  { transform:rotate(0deg); }
  20% { transform:rotate(-7deg); }
  45% { transform:rotate(-6deg); }
  70% { transform:rotate(7deg); }
  90% { transform:rotate(5deg); }
  100%{ transform:rotate(0deg); }
}
@keyframes kf-tap-look{
  0%  { transform:rotate(0deg) scale(1); }
  35% { transform:rotate(-7deg) scale(1.04); }
  100%{ transform:rotate(0deg) scale(1); }
}
@keyframes kf-tap-body{
  0%  { transform:translateY(0)      scale(1,1); }
  30% { transform:translateY(-4%)    scale(.97,1.03); }
  100%{ transform:translateY(0)      scale(1,1); }
}

/* --- 进食 --- */
@keyframes kf-eat-body{ 0%,100%{ transform:translateY(0); }  50%{ transform:translateY(1.5%); } }
@keyframes kf-eat-head{ 0%,100%{ transform:rotate(7deg)  translateY(2%); }
                        50%    { transform:rotate(15deg) translateY(4%); } }
@keyframes kf-chew{ 0%,100%{ transform:scaleY(1); } 32%{ transform:scaleY(.42); } 66%{ transform:scaleY(1.1); } }

/* --- 开心 / 庆祝 --- */
@keyframes kf-happy-jump{
  0%  { transform:translateY(0)      scale(1,1); }
  12% { transform:translateY(2%)     scale(1.09,.88); }   /* 预备下蹲 */
  38% { transform:translateY(-16%)   scale(.94,1.09); }   /* 腾空拉伸 */
  62% { transform:translateY(0)      scale(1.08,.9); }    /* 落地压缩(hit) */
  80% { transform:translateY(-5%)    scale(.98,1.02); }
  100%{ transform:translateY(0)      scale(1,1); }
}
@keyframes kf-shadow-hop{
  0%,100%{ transform:scale(1);   opacity:.2; }
  38%    { transform:scale(.82); opacity:.1; }
  62%    { transform:scale(1.06);opacity:.24; }
}
@keyframes kf-celebrate{
  0%  { transform:translateY(0)     rotate(0deg)    scale(1,1); }
  10% { transform:translateY(3%)    rotate(0deg)    scale(1.1,.88); }
  28% { transform:translateY(-18%)  rotate(-8deg)   scale(.94,1.09); }
  46% { transform:translateY(0)     rotate(0deg)    scale(1.09,.9); }
  62% { transform:translateY(-14%)  rotate(8deg)    scale(.95,1.07); }
  80% { transform:translateY(0)     rotate(0deg)    scale(1.05,.94); }
  100%{ transform:translateY(0)     rotate(0deg)    scale(1,1); }
}
@keyframes kf-confetti{
  0%  { transform:translate(0,0) rotate(0deg); opacity:1; }
  100%{ transform:translate(var(--dx,0px),var(--dy,-72px)) rotate(var(--rr,320deg)); opacity:0; }
}

/* --- 鼓励 / 难过 / 饥饿 / 困倦 / 坐 / 睡 --- */
@keyframes kf-encourage-head{
  0%{ transform:rotate(0deg); } 30%{ transform:rotate(-9deg); }
  60%{ transform:rotate(6deg); } 100%{ transform:rotate(0deg); }
}
@keyframes kf-encourage-body{
  0%,100%{ transform:translateY(0) scale(1,1); }
  40%    { transform:translateY(-2%) scale(1.02,.98); }
}
@keyframes kf-sad-body{ 0%,100%{ transform:translateY(0) scale(1,1); } 50%{ transform:translateY(1.5%) scale(.98,.97); } }
@keyframes kf-sad-head{ 0%,100%{ transform:rotate(10deg) translateY(2%); } 50%{ transform:rotate(13deg) translateY(3%); } }
@keyframes kf-sad-ear { 0%,100%{ transform:rotate(16deg); } 50%{ transform:rotate(21deg); } }
@keyframes kf-sad-tail{ 0%,100%{ transform:rotate(12deg); } 50%{ transform:rotate(16deg); } }
@keyframes kf-tear{
  0%  { transform:translate(0,0) scale(.6); opacity:0; }
  20% { opacity:.9; }
  100%{ transform:translate(2px,18px) scale(1); opacity:0; }
}
@keyframes kf-hungry-body{ 0%,100%{ transform:scale(1,1) translateY(0); } 45%{ transform:scale(1.02,.97) translateY(1%); } }
@keyframes kf-hungry-head{ 0%,100%{ transform:rotate(5deg); }  50%{ transform:rotate(-2deg) translateY(1%); } }
@keyframes kf-hungry-tail{ 0%,100%{ transform:rotate(-4deg); } 50%{ transform:rotate(2deg); } }
@keyframes kf-sleepy-nod{
  0%{ transform:rotate(0deg); }  20%{ transform:rotate(10deg); }
  45%{ transform:rotate(-3deg); } 70%{ transform:rotate(7deg); } 100%{ transform:rotate(0deg); }
}
@keyframes kf-sleepy-eye{ 0%,40%{ transform:scaleY(1); } 60%,100%{ transform:scaleY(.12); } }
@keyframes kf-sit-body{ from{ transform:translateY(0) scale(1,1); } to{ transform:translateY(4%) scale(1.03,.9); } }
@keyframes kf-sit-leg { from{ transform:rotate(0deg) translateY(0); } to{ transform:rotate(58deg) translateY(6%); } }
@keyframes kf-sleep-body{
  0%,100%{ transform:scale(1.05,.9)  translateY(3%); }
  50%    { transform:scale(1.07,.88) translateY(3.6%); }
}
@keyframes kf-sleep-head{
  0%,100%{ transform:rotate(12deg) translateY(3%); }
  50%    { transform:rotate(13deg) translateY(3.6%); }
}
@keyframes kf-zzz{
  0%  { transform:translate(0,0) scale(.5); opacity:0; }
  25% { opacity:1; }
  100%{ transform:translate(11px,-26px) scale(1.15); opacity:0; }
}

/* --- 进化 --- */
@keyframes kf-evolve-body{
  0%  { transform:scale(1)      translateY(0); }
  15% { transform:scale(.92,1.09) translateY(-2%); }   /* 蓄力压缩 */
  40% { transform:scale(1.12,.9) translateY(0); }      /* 第一波扩张 */
  55% { transform:scale(.96,1.05) translateY(-4%); }   /* 回弹 */
  70% { transform:scale(1.06,.96) translateY(0); }     /* 定形 */
  85% { transform:scale(.99,1.01) translateY(0); }
  100%{ transform:scale(1)      translateY(0); }
}
@keyframes kf-evolve-ring{
  0%  { transform:scale(.3);  opacity:0; }
  25% { opacity:.95; }
  100%{ transform:scale(2.6); opacity:0; }
}
@keyframes kf-evolve-flash{ 0%,60%{ opacity:0; } 72%{ opacity:.95; } 100%{ opacity:0; } }

/* --- 气泡 / 菜单 --- */
@keyframes kf-emote-pop{
  0%  { transform:translate(-50%,0)     scale(.5);  opacity:0; }
  55% { transform:translate(-50%,-7px)  scale(1.08);opacity:1; }
  100%{ transform:translate(-50%,-2px)  scale(1);   opacity:1; }
}
@keyframes kf-menu-in{
  0%  { transform:translateX(-50%) translateY(8px) scale(.9); opacity:0; }
  100%{ transform:translateX(-50%) translateY(0)   scale(1);  opacity:1; }
}

/* --- 场景装饰动效（只动 transform/opacity） --- */
@keyframes kf-cloud-drift{ from{ transform:translateX(0); } to{ transform:translateX(calc(100% + 460px)); } }
@keyframes kf-windmill{ from{ transform:rotate(0deg); } to{ transform:rotate(360deg); } }
@keyframes kf-bush-sway{ 0%,100%{ transform:translateY(0); } 50%{ transform:translateY(-2px); } }

/* ==========================================================================
   10. 性能与降级
   ========================================================================== */

/* 低性能模式：JS 采样 fps<45 连续 3 次 或 hardwareConcurrency<=4 时，
   给 <html> 或 .pet-scene 挂 .perf-low */
.perf-low .pet-dust,
.perf-low .pet-tear,
.perf-low .pet-fx-ring:nth-child(3){ display:none; }
.perf-low .pet-actor .pt-ear-n,
.perf-low .pet-actor .pt-acc{ animation:none !important; }
.perf-low .pet-actor .pt-shadow{ animation:none !important; opacity:.7; }
.perf-low .pet-actor .pt-leg-ff,
.perf-low .pet-actor .pt-leg-hf{ animation:none !important; }   /* 远侧两腿停摆，只留近侧 */
.perf-low .pet-actor.is-evolve .pet-fx-ring:nth-child(2){ display:none; }
.perf-low .pet-stage.is-shake{ animation:none; }
.perf-low .ps-cloud,.perf-low .ps-wind,.perf-low .ps-bush{ animation:none !important; }

/* 无障碍：尊重系统减弱动效 */
@media (prefers-reduced-motion: reduce){
  .pet-actor .pt-body,
  .pet-actor .pt-head,
  .pet-actor .pt-tail,
  .pet-actor .pt-shadow,
  .pet-actor .pt-ear-n,.pet-actor .pt-ear-f,
  .pet-actor .pt-leg-fn,.pet-actor .pt-leg-hn,
  .pet-actor .pt-leg-ff,.pet-actor .pt-leg-hf,
  .pet-actor .pt-mouth,
  .pet-actor .pt-eye-l,.pet-actor .pt-eye-r,
  .pet-dust,.pet-tear,.pet-zzz,.pet-fx-ring,
  .ps-cloud,.ps-wind,.ps-bush{ animation:none !important; }
  .pet-actor.is-happy   .pt-root,
  .pet-actor.is-celebrate .pt-root,
  .pet-actor.is-evolve .pt-root{ animation:kf-emote-pop .3s ease-out both; } /* 只留一次轻微缩放 */
  .pet-flip{ transition:transform .12s linear; }
  .pet-stage.is-shake{ animation:none; }
  /* 位移降级：由 JS 改用 0.35s CSS transition 一次性跳到锚点，步态关闭 */
  .pet-actor{ transition:transform .35s ease-out; }
}

/* ---------- ★ P1 睡觉（ux-iteration-v1.0 §2.1）：ZZZ 触发从 is-sleepy 扩到 is-sleep ----------
   is-sleep 本体 kf（.pt-* 三组）已在 :150-158 现成；此处补两块：
   ① .pet-zzz 三枚 ZZZ 与 is-sleepy 同款（选择器并列，一行级改动）；
   ② imgMode（庭院 PNG 立绘无 .pt-* 部件）→ 给 .pet-flip 一组轻睡姿摇摆，保证入睡可见。 */
.pet-actor.is-sleep .pet-zzz,
.pet-actor.is-sleepy .pet-zzz{ animation:kf-zzz 2.1s ease-out infinite; }
.pet-actor.is-sleep .pet-zzz:nth-child(2),
.pet-actor.is-sleepy .pet-zzz:nth-child(2){ animation-delay:.7s; }
.pet-actor.is-sleep .pet-zzz:nth-child(3),
.pet-actor.is-sleepy .pet-zzz:nth-child(3){ animation-delay:1.4s; }
.pet-actor.is-sleep .pet-flip{ animation:kf-sleep-img 4.2s ease-in-out infinite; transform-origin:50% 100%; }
@keyframes kf-sleep-img{
  0%,100%{ transform:rotate(0deg); }
  50%    { transform:rotate(-2.6deg) translateY(1.5%); }
}
@media (prefers-reduced-motion: reduce){ .pet-actor.is-sleep .pet-flip{ animation:none; } }
