/* ============================================================
   像素耶耶花园 — 全屏像素农场
   舞台固定 2:3 比例、手动 cover 居中；farm-bg.png 实际是
   1254x1254 方图，100%/100% 拉伸到 2:3（实测形变不明显，
   且百分比坐标可与原图直接对应）
   ============================================================ */
:root {
  --pink-100:#fff1f6; --pink-200:#ffd9e8; --pink-300:#ffb8d2;
  --pink-400:#ff8fb6; --pink-500:#ff6f9f;
  --cream:#fff8f2; --cocoa:#7c4a4a; --ink-soft:#b56c82;
  --grass-a:#8fc86a; --grass-b:#83bd5e;
  --soil:#c99a76; --soil-dark:#a97a58;
  --gold:#f5b301; --violet:#a78bfa;
  --leaf:#5c9c3e;
  --px-font: "Courier New", ui-monospace, "PingFang SC", monospace;
}

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }

html, body {
  margin: 0; padding: 0;
  height: 100%;
  overflow: hidden;
  overscroll-behavior: none;
}
body {
  background: #7fb95a;
  color: var(--cocoa);
  font-family: system-ui, -apple-system, "PingFang SC", "Microsoft YaHei", sans-serif;
  -webkit-user-select: none; user-select: none;
}

img, .sprite { image-rendering: pixelated; image-rendering: crisp-edges; -webkit-touch-callout: none; /* iOS长按图片会弹"存储图像"菜单，抢掉长按聊天 */ }

/* ============================================================
   舞台（固定 2:3 比例，手动 cover：短边贴满、长边裁切、居中）
   ============================================================ */
.stage-wrap {
  position: fixed; inset: 0;
  overflow: hidden;
  background: #7fb95a;
}
.stage {
  position: absolute; left: 50%; top: 50%;
  transform: translate(-50%, -50%);
  width:  max(100vw, 66.67vh);
  height: max(150vw, 100vh);
  width:  max(100vw, 66.67dvh);
  height: max(150vw, 100dvh);
  /* 背景 = JS 算出的 主题×时段 图（--bg-url），没算出来时退回默认绿野图；
     再下层是像素草地格兜底。63 张组合不写 63 条规则，全靠这一个变量 */
  background-image:
    var(--bg-url, var(--bg-fallback, url('sprites/farm/farm-bg.png?v=8'))),
    repeating-conic-gradient(var(--grass-a) 0% 25%, var(--grass-b) 0% 50%);
  background-size: 100% 100%, 28px 28px;
  background-repeat: no-repeat, repeat;
  image-rendering: pixelated;
}
/* ---------- 主题皮肤：只换背景图，布局坐标系与原版完全一致 ----------
   JS 预加载完成后才挂 class（防闪白）；下层像素草地格兜底照旧 */
.stage.theme-sakura {
  /* 时段图由 JS 设 --bg-url；这里是它没算出来时的单图兜底 */
  --bg-fallback: url('sprites/farm/farm-bg-sakura.png?v=8');
}
.stage.theme-autumn {
  /* 时段图由 JS 设 --bg-url；这里是它没算出来时的单图兜底 */
  --bg-fallback: url('sprites/farm/farm-bg-autumn.png?v=8');
}
.stage.theme-snow {
  /* 时段图由 JS 设 --bg-url；这里是它没算出来时的单图兜底 */
  --bg-fallback: url('sprites/farm/farm-bg-snow.png?v=8');
}
.stage.theme-candy {
  /* 时段图由 JS 设 --bg-url；这里是它没算出来时的单图兜底 */
  --bg-fallback: url('sprites/farm/farm-bg-candy.png?v=8');
}
.stage.theme-dusk {
  /* 时段图由 JS 设 --bg-url；这里是它没算出来时的单图兜底 */
  --bg-fallback: url('sprites/farm/farm-bg-dusk.png?v=8');
}
.stage.theme-dream {
  /* 时段图由 JS 设 --bg-url；这里是它没算出来时的单图兜底 */
  --bg-fallback: url('sprites/farm/farm-bg-dream.png?v=8');
}
/* v39 神秘装扮主题（收获掉落解锁，菜单按 unlocks 过滤）：夜色系/暖光系，is-night 叠加照常 */
.stage.theme-aurora {
  /* 时段图由 JS 设 --bg-url；这里是它没算出来时的单图兜底 */
  --bg-fallback: url('sprites/farm/farm-bg-aurora.png?v=8');
}
.stage.theme-cloudsea {
  /* 时段图由 JS 设 --bg-url；这里是它没算出来时的单图兜底 */
  --bg-fallback: url('sprites/farm/farm-bg-cloudsea.png?v=8');
}

/* ---------- 主题氛围粒子（纯 CSS，同云/星星做法；默认绿野无粒子） ---------- */
.ambient {
  /* v59 图层修正：z2 时花瓣从土垄'后面'飘过（用户实锤樱花落在土地图层下）。
     提 7 与耶耶同层、DOM 在末尾=飘在整个世界前（下雪天雪片从镜头前过），
     仍在 todveil(8) 之下被时段色调罩住 */
  position: absolute; inset: 0; z-index: 7;
  pointer-events: none; overflow: hidden;
}
.stage.is-night .ambient { opacity: .55; } /* 夜里粒子跟着收敛，夜幕/调光体系不受影响 */
.amb { position: absolute; }
/* 樱花：粉花瓣飘落（圆一角的小方块，旋着往下漂） */
.amb-sakura {
  width: 7px; height: 7px;
  background: var(--pink-300);
  border-radius: 70% 0 70% 0;
  box-shadow: inset -1px -1px 0 var(--pink-400);
  animation: amb-fall linear infinite;
}
/* 金秋：橙色小方块枫叶旋转落 */
.amb-autumn {
  width: 7px; height: 7px;
  background: #e08a2e;
  box-shadow: inset -2px -2px 0 #c26a18;
  animation: amb-fall-spin linear infinite;
}
/* 落雪：白色小雪点，慢慢飘 */
.amb-snow {
  width: 5px; height: 5px;
  background: rgba(255,255,255,.95);
  border-radius: 50%;
  box-shadow: 0 0 3px rgba(255,255,255,.8);
  animation: amb-fall linear infinite;
}
/* 糖果：偶尔上浮的小心心（原地起浮，top 由 JS 撒点） */
.amb-candy {
  font-size: 12px; line-height: 1;
  color: var(--pink-500);
  text-shadow: 1px 1px 0 rgba(255,255,255,.6);
  animation: amb-rise ease-in-out infinite;
  opacity: 0;
}
.amb-candy::before { content: "♥"; }
/* 黄昏：金色光尘/萤火虫——原地缓浮 + 忽明忽暗（top 由 JS 撒点，少而精） */
.amb-dusk {
  width: 5px; height: 5px;
  background: #ffc35e;
  border-radius: 50%;
  box-shadow: 0 0 5px 1px rgba(255,166,66,.75);
  animation: amb-dusk-drift ease-in-out infinite;
  opacity: 0;
}
/* 梦幻：淡紫小四角星缓缓上浮旋转淡出（top 由 JS 撒点） */
.amb-dream {
  font-size: 11px; line-height: 1;
  color: #c9a2ee;
  text-shadow: 0 0 4px rgba(214,178,255,.8);
  animation: amb-dream-rise ease-in-out infinite;
  opacity: 0;
}
.amb-dream.alt { color: #f2a8ce; text-shadow: 0 0 4px rgba(255,190,224,.8); } /* 淡粉款隔个混色 */
.amb-dream::before { content: "✦"; display: block; }
/* 偶尔混一个小圆泡：盖掉星星字形，换成描边泡泡 */
.amb-dream.amb-bubble::before {
  content: "";
  display: block; width: 9px; height: 9px;
  border: 2px solid rgba(210,178,255,.85);
  border-radius: 50%;
  background: rgba(255,255,255,.14);
  box-shadow: inset 2px -2px 0 rgba(255,255,255,.5);
}
/* v39 极光之夜：青紫极光光点，缓慢飘动 + 微光晕（duration 由 JS 给到 10-18s 的慢档） */
.amb-aurora {
  width: 6px; height: 6px;
  background: #7fe8d8;
  border-radius: 50%;
  box-shadow: 0 0 6px 2px rgba(110,230,214,.55);
  animation: amb-aurora-drift ease-in-out infinite;
  opacity: 0;
}
.amb-aurora.alt { background: #b89af0; box-shadow: 0 0 6px 2px rgba(167,139,250,.55); } /* 紫款隔个混色 */
@keyframes amb-aurora-drift {
  0%   { transform: translate(0, 0) scale(.85); opacity: 0; }
  22%  { opacity: .85; }
  52%  { transform: translate(var(--dx, 12px), -16px) scale(1.05); opacity: .5; }
  76%  { opacity: .8; }
  100% { transform: translate(calc(var(--dx, 12px) * .4), -30px) scale(.9); opacity: 0; }
}
/* v39 云海仙境：金色流光尘，斜斜掠过淡出 */
.amb-cloudsea {
  width: 4px; height: 4px;
  background: #ffd97a;
  border-radius: 50%;
  box-shadow: 0 0 5px 1px rgba(255,201,94,.65);
  animation: amb-cloudsea-flow ease-in-out infinite;
  opacity: 0;
}
@keyframes amb-cloudsea-flow {
  0%   { transform: translate(0, 0) scale(.8); opacity: 0; }
  16%  { opacity: .9; }
  62%  { opacity: .6; }
  100% { transform: translate(var(--dx, 26px), -24px) scale(1.15); opacity: 0; }
}
@keyframes amb-dusk-drift {
  0%   { transform: translateY(0) translateX(0); opacity: 0; }
  18%  { opacity: .9; }
  36%  { opacity: .22; }  /* 忽明 */
  54%  { transform: translateY(-14px) translateX(var(--dx, 8px)); opacity: .85; } /* 忽暗再亮 */
  74%  { opacity: .28; }
  100% { transform: translateY(3px) translateX(0); opacity: 0; }
}
@keyframes amb-dream-rise {
  0%   { transform: translateY(0) rotate(0deg) scale(.7); opacity: 0; }
  16%  { opacity: .9; }
  70%  { opacity: .7; }
  100% { transform: translateY(-72px) rotate(180deg) scale(1.05); opacity: 0; }
}
@keyframes amb-fall {
  0%   { top: -4%; transform: translateX(0) rotate(0deg); opacity: 0; }
  8%   { opacity: .95; }
  100% { top: 103%; transform: translateX(var(--dx, 16px)) rotate(160deg); opacity: .75; }
}
@keyframes amb-fall-spin {
  0%   { top: -4%; transform: translateX(0) rotate(0deg); opacity: 0; }
  8%   { opacity: .95; }
  100% { top: 103%; transform: translateX(var(--dx, 16px)) rotate(420deg); opacity: .75; }
}
@keyframes amb-rise {
  0%   { transform: translateY(0) scale(.8); opacity: 0; }
  18%  { opacity: .85; }
  55%  { opacity: .85; }
  100% { transform: translateY(-60px) scale(1.2); opacity: 0; }
}

.stage-loading {
  position: absolute; left: 50%; top: 42%;
  transform: translate(-50%, -50%);
  z-index: 12; /* v53：时段色调层抬到 z8 后，loading 提示上移保持罩外 */
  font-size: 14px; color: var(--cocoa);
  background: rgba(255,248,242,.94);
  border: 3px solid var(--cocoa);
  box-shadow: 3px 3px 0 rgba(94,53,53,.4);
  padding: 14px 18px; white-space: nowrap;
}

/* ---------- 白天的云 ----------
   z6：飘过建筑(z3)/地块(z3)上空更有层次，但压不住耶耶(z7)——主角永远在云前；
   pointer-events:none，抬层不挡建筑/旋涡点击 */
.sky { position: absolute; inset: 0; z-index: 8; pointer-events: none; overflow: hidden; } /* v59: 6→8 俯视图的云影盖一切（曾被耶耶 z7 踩）；DOM 在 todveil 前=仍被罩色 */
.cloud {
  position: absolute;
  width: 64px; height: 16px;
  background: rgba(255,255,255,.92);
  box-shadow:
    16px -10px 0 rgba(255,255,255,.92),
    36px -8px 0 rgba(255,255,255,.88),
    -6px 4px 0 rgba(255,255,255,.75),
    52px 2px 0 rgba(255,255,255,.75);
  opacity: .9;
  animation: cloud-drift linear infinite;
  /* 可点爆破彩蛋：容器 .sky 保持 pointer-events:none，只有云本身接点击 */
  pointer-events: auto;
  cursor: pointer;
}
.cloud.c1 { top: 6%;  animation-duration: 65s; animation-delay: -12s; }
.cloud.c2 { top: 13%; animation-duration: 90s; animation-delay: -48s; transform: scale(.7); }
.cloud.c3 { top: 21%; animation-duration: 78s; animation-delay: -30s; transform: scale(1.25); opacity: .65; }
@keyframes cloud-drift {
  from { left: -22%; }
  to   { left: 108%; }
}
.stage.is-night .cloud { display: none; }
/* 主题云染色：filter 打在 .cloud 上，CSS 影子云和 sprite 云(img)整块一起染 */
.stage.theme-dusk .cloud  { filter: sepia(.6) saturate(1.7) hue-rotate(-18deg) brightness(.97); } /* 黄昏暖橙 */
.stage.theme-dream .cloud { filter: sepia(.35) saturate(1.4) hue-rotate(215deg) brightness(1.03); } /* 梦幻淡紫 */
.stage.theme-aurora .cloud   { filter: saturate(.7) hue-rotate(165deg) brightness(.82); }  /* 极光青蓝夜云 */
.stage.theme-cloudsea .cloud { filter: sepia(.4) saturate(1.55) hue-rotate(-10deg) brightness(1.06); } /* 云海暖金 */
/* GPT sprite 云模式（JS 预加载 cloud-N.png 成功后挂 .cloud-img 注入 img）：
   关掉 box-shadow 手画和 scale，尺寸直接给 img 定宽错落；drift 关键帧照旧复用 */
.cloud.cloud-img {
  background: none; box-shadow: none;
  width: auto; height: auto;
  transform: none;
}
.cloud.cloud-img img { display: block; height: auto; }
.cloud.c1.cloud-img img { width: 96px; }
.cloud.c2.cloud-img img { width: 64px; }
.cloud.c3.cloud-img img { width: 110px; }
/* 点云爆破：JS 先冻结 left/关掉 drift，再用内联 animation 播 cloud-pop（放大变淡），
   爆完 display:none，8-15s 后重置 drift 从左侧重新飘入 */
@keyframes cloud-pop {
  from { transform: scale(1);   opacity: .95; }
  to   { transform: scale(1.3); opacity: 0; }
}
/* 爆破迸出的小白像素粒：一次性四散飘出淡出（--bx/--by 由 JS 随机） */
.cloud-bit {
  position: absolute;
  width: 6px; height: 6px;
  background: rgba(255,255,255,.95);
  pointer-events: none;
  animation: cloud-bit-fly .6s ease-out forwards;
}
@keyframes cloud-bit-fly {
  from { transform: translate(0, 0);               opacity: 1; }
  to   { transform: translate(var(--bx), var(--by)); opacity: 0; }
}

/* ============================================================
   功能建筑：故事馆 & 藏品馆
   ※ 与地块同层 z3，DOM 在 .plots 之前（同 z 时地块画在上面）；
   耶耶 z7 走到跟前会盖住建筑底部，前后关系合理
   ============================================================ */
.bld {
  position: absolute;
  z-index: 3;
  transform: translate(-50%, -100%); /* 底边中心锚定：y 即建筑落地线 */
  background: none; border: 0; padding: 0;
  cursor: pointer; touch-action: manipulation;
}
.bld-story  { width: 19%; } /* 245x320 */
.bld-clock  { width: 10%; } /* v30 钟楼（专注页入口）：111x256 高塔，窄身 */
/* .bld-museum 已撤：藏品馆入口改为池塘神秘旋涡（.vortex），bld-museum.png 素材留档 */
.bld img { display: block; width: 100%; height: auto; }
/* hover/按下轻微下压，同 .plot:active 手感 */
.bld:hover  { transform: translate(-50%, calc(-100% + 1px)); }
.bld:active { transform: translate(-50%, calc(-100% + 2px)); }

/* 建筑接地影：椭圆软影贴落地线（同 .walker-shadow 做法；
   建筑块头大，暗度比耶耶影子淡一档，不然显脏） */
.bld::before {
  content: "";
  position: absolute;
  left: 50%; bottom: 0;    /* .bld 底边即落地线（translate -100% 锚定） */
  width: 85%;
  aspect-ratio: 5;         /* 扁椭圆贴地 */
  transform: translate(-50%, 50%);
  background: radial-gradient(closest-side, rgba(34,54,22,.22), rgba(34,54,22,.12) 55%, transparent 74%);
  pointer-events: none;
  z-index: -1;             /* .bld 自身有 z-index（层叠上下文）：只垫到建筑 img 之下，穿不到舞台背景后 */
}
/* hover/按下建筑下压时影子反向补偿：影子贴地不动才真实 */
.bld:hover::before  { transform: translate(-50%, calc(50% - 1px)); }
.bld:active::before { transform: translate(-50%, calc(50% - 2px)); }
/* 夜间影子透明度减半（同耶耶影子惯例） */
.stage.is-night .bld::before { opacity: .85; } /* 同盆：夜背景近黑，减半即隐形 */
/* 钟楼是高塔细底座（底部接触面仅占宽 37%，故事馆是 80%）：
   套通用 85% 宽椭圆影会显得虚浮，收窄到贴合塔基 */
.bld-clock::before { width: 44%; aspect-ratio: 3.4; }

/* 图挂了：emoji 兜底（牌匾照常显示） */
.bld-fb {
  display: flex; align-items: flex-end; justify-content: center;
  width: 100%; aspect-ratio: .78;
  font-size: 54px; line-height: 1.1;
}

/* 门牌：复用 plant-sign / plot-label 的像素牌风格，常显、微微压住墙脚 */
.bld-sign {
  position: absolute; left: 50%; top: 100%;
  transform: translate(-50%, -60%);
  font-family: var(--px-font); font-weight: 800; font-size: 11px;
  color: #4c2f2f; background: rgba(255,248,242,.92);
  border: 2px solid var(--cocoa);
  box-shadow: 2px 2px 0 rgba(94,53,53,.35);
  padding: 1px 7px; white-space: nowrap;
  pointer-events: none;
}

/* 故事馆烟囱的烟：2-3 个像素小方点向上飘散淡出（纯 CSS） */
.bld-smoke {
  position: absolute;
  left: 79%; top: 4%;
  width: 5px; height: 5px;
  background: rgba(255,255,255,.85);
  box-shadow: 0 0 2px rgba(255,255,255,.5);
  opacity: 0;
  pointer-events: none;
  animation: smoke-rise 2.7s ease-out infinite;
}
@keyframes smoke-rise {
  0%   { transform: translate(0, 0) scale(1); opacity: 0; }
  18%  { opacity: .85; }
  100% { transform: translate(var(--sx, 3px), -26px) scale(1.9); opacity: 0; }
}

/* ============================================================
   池塘神秘旋涡：藏品馆传送门
   压在左上池塘(bg ~x4-30/y6-22)水面上，中心约 x16,y14；
   首选 GPT 四帧星河旋涡 sprite（.vx-sprite 模式，JS 探测 ≥2 帧就位才挂），
   sprite 本身已是扁椭圆透视，水平放置不加 scaleY/rotate；
   探测不过降级回下面的 CSS 手画旋涡（.vx-swirl conic 渐变那套，保留勿删）
   ============================================================ */
.vortex {
  position: absolute;
  /* 池塘真实中心实测 (20%,12.5%)：对竖版新 bg 蓝色水体求包围盒中心（水面 x6.5~33.4 y4.7~20.8）。
     竖版重建前旧值 (23,15)——每换底图必须重测，这个数没法猜 */
  left: 20%; top: 12.5%;
  width: 15%; aspect-ratio: 1; /* 点击区盖住整个旋涡 */
  transform: translate(-50%, -50%);
  z-index: 3; /* 与建筑同层：耶耶(z7)路过会压在旋涡上 */
  background: none; border: 0; padding: 0;
  cursor: pointer; touch-action: manipulation;
}
.vortex:hover .vx-swirl  { filter: brightness(1.12); }
.vortex:active .vx-swirl { filter: brightness(.92); }
/* sprite 模式（v2 低调水纹版）：宽 16%，中心随 .vortex 实测坐标 (23,15)；
   img 完全水平居中放置——严禁任何 rotate/scaleY/margin 偏移 */
.vortex.vx-sprite { width: 16%; }
.vortex.vx-sprite .vx-swirl { display: none; } /* CSS 手画旋涡整套熄灯 */
.vx-anim {
  position: absolute; inset: 0;
  pointer-events: none;
  /* 融进池塘：整体半透明 + 极轻微缩放呼吸像活水；不用 drop-shadow（浮夸）、
     不用 mix-blend-mode（像素风会糊） */
  opacity: .85;
  animation: vx-breathe 4s ease-in-out infinite;
}
.vx-anim img { display: block; width: 100%; height: auto; }
@keyframes vx-breathe {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.03); }
}
.vortex:hover .vx-anim img  { filter: brightness(1.12); }
.vortex:active .vx-anim img { filter: brightness(.92); }
/* 夜间：旋涡自己发光，调光别压太狠 */
.stage.is-night .vx-anim img { filter: brightness(.8); }
.vx-swirl {
  position: absolute; inset: 0;
  transform: scaleY(.55); /* 水面透视压扁 */
  pointer-events: none;
}
/* 水色暗底盘：把旋涡和池水接起来（深蓝紫） */
.vx-swirl::before {
  content: '';
  position: absolute; inset: -8%;
  border-radius: 50%;
  background: radial-gradient(closest-side,
    rgba(24, 28, 82, .62), rgba(30, 38, 104, .38) 60%, transparent 78%);
}
/* 旋臂：conic 渐变双层反向旋转（steps 走像素顿挫感），~6s/圈 */
.vx-ring {
  position: absolute; inset: 4%;
  border-radius: 50%;
  background: conic-gradient(from 0deg,
    rgba(118, 140, 255, 0)    0 12%,
    rgba(132, 152, 255, .78) 16% 25%,
    rgba(40, 46, 130, 0)     30% 46%,
    rgba(96, 208, 255, .62)  51% 60%,
    rgba(40, 46, 130, 0)     65% 80%,
    rgba(158, 122, 255, .72) 85% 93%,
    rgba(118, 140, 255, 0)   97%);
  -webkit-mask: radial-gradient(closest-side, transparent 16%, #000 28% 90%, transparent 100%);
  mask: radial-gradient(closest-side, transparent 16%, #000 28% 90%, transparent 100%);
  animation: vx-spin 6s steps(24) infinite;
}
.vx-ring2 {
  inset: 22%;
  animation: vx-spin 4.2s steps(18) infinite reverse;
  filter: hue-rotate(24deg) brightness(1.15);
}
@keyframes vx-spin { to { transform: rotate(360deg); } }
/* 中心微光：脉动发亮 */
.vx-core {
  position: absolute; left: 50%; top: 50%;
  width: 24%; aspect-ratio: 1;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background: radial-gradient(closest-side, #d6e8ff, #86a0ff 55%, rgba(90, 100, 230, 0));
  box-shadow: 0 0 10px 3px rgba(150, 178, 255, .6);
  animation: vx-pulse 2.6s ease-in-out infinite;
}
@keyframes vx-pulse {
  0%, 100% { opacity: .72; transform: translate(-50%, -50%) scale(.88); }
  50%      { opacity: 1;   transform: translate(-50%, -50%) scale(1.1); }
}
/* 星光点：3 颗错峰闪烁的像素小方点 */
.vx-star {
  position: absolute;
  width: 3px; height: 3px;
  background: #eaf4ff;
  box-shadow: 0 0 4px rgba(190, 220, 255, .9);
  animation: vx-twinkle 1.8s ease-in-out infinite;
}
.vs1 { left: 24%; top: 30%; }
.vs2 { left: 68%; top: 20%; animation-delay: .6s; }
.vs3 { left: 58%; top: 72%; animation-delay: 1.1s; }
@keyframes vx-twinkle {
  0%, 100% { opacity: .15; transform: scale(.7); }
  50%      { opacity: 1;   transform: scale(1.25); }
}
/* 门牌：照 .bld-sign 风格，收到压扁旋涡的下缘 */
.vx-sign { top: 82%; transform: translate(-50%, 0); }
/* 夜间：旋臂水色吃调光，中心微光和星光点保留不灭 */
.stage.is-night .vx-swirl::before { background: radial-gradient(closest-side,
  rgba(16, 18, 56, .7), rgba(20, 26, 76, .42) 60%, transparent 78%); }
.stage.is-night .vx-ring  { filter: brightness(.68) saturate(.82); }
.stage.is-night .vx-ring2 { filter: hue-rotate(24deg) brightness(.78); }

/* 穿越过渡：0.5s 全屏旋涡渐暗（JS 挂 .vortex-warp 后 520ms 跳转） */
.vortex-warp {
  position: fixed; inset: 0;
  z-index: 99;
  pointer-events: auto; /* 过渡期吞掉一切点击 */
  /* 纯净渐暗：全屏放大的旋臂条带旋转会糊成一片，弃用 */
  background: radial-gradient(circle at 50% 45%, rgba(42, 46, 116, .95) 0%, #090918 70%);
  animation: vx-warp-in .45s ease-in forwards;
}
@keyframes vx-warp-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* ============================================================
   地块（绝对定位在舞台百分比坐标上）
   ============================================================ */
.plots { position: absolute; inset: 0; z-index: 3; pointer-events: none; /* 透明满屏容器会吞掉同层建筑/旋涡的点击（v13-v33的建筑不可点真凶） */ }
.plot { pointer-events: auto; }

.plot {
  position: absolute;
  width: 24%;
  transform: translate(-50%, -50%);
  cursor: pointer;
  touch-action: manipulation;
}
.plot:active .soil-base { transform: translateY(1px); }

/* 土垄：soil.png，挂了就用 CSS 像素土垄兜底 */
.soil-base { position: relative; width: 100%; }
.soil-base img.soil { display: block; width: 100%; height: auto; }
.plot.no-soil .soil-base {
  height: 0; padding-bottom: 80%;
  background: var(--soil);
  background-image:
    radial-gradient(circle at 24% 32%, var(--soil-dark) 0 4%, transparent 6%),
    radial-gradient(circle at 72% 58%, var(--soil-dark) 0 4%, transparent 6%),
    radial-gradient(circle at 46% 80%, var(--soil-dark) 0 4%, transparent 6%);
  border: 3px solid var(--cocoa);
  box-shadow: inset 0 -6px 0 rgba(124,74,74,.3);
}

/* 作物 sprite 叠在土垄上
   ※ v7 起挂在 .soil-base 内：百分比只参照土垄本身，
   不再被下方 px 定高的进度条/标签稀释（原先随屏宽漂移、整体偏高） */
.stage-box {
  position: absolute;
  left: 50%; bottom: 24%;
  width: 58%;
  transform: translateX(-50%);
  display: flex; align-items: flex-end; justify-content: center;
  pointer-events: none;
}
.stage-box .sprite { width: 100%; height: auto; }
/* per-stage 垂直校准：seed/sprout 画布内底部留白 ~26%，bud/bloom 只有 ~11%，
   统一让内容底沿落在土垄 ~32% 高度处；bud 画面整体左偏 1.8% 顺手扶正 */
.stage-box.st-seed, .stage-box.st-sprout { bottom: 13%; }
.stage-box.st-bud { left: 51%; }
.sprite-fallback { font-size: 34px; line-height: 1.2; }

/* 空地：小小的播种牌 */
.plant-sign {
  position: absolute; left: 50%; bottom: 30%;
  transform: translateX(-50%);
  font-family: var(--px-font); font-weight: 800; font-size: 12px;
  color: var(--cocoa); background: rgba(255,248,242,.92);
  border: 2px solid var(--cocoa);
  box-shadow: 2px 2px 0 rgba(94,53,53,.35);
  padding: 2px 6px; white-space: nowrap;
  pointer-events: none;
  animation: sign-bob 2.2s steps(2) infinite;
}
@keyframes sign-bob { 50% { transform: translateX(-50%) translateY(-3px); } }

/* bloom 发光脉动 */
.plot.is-bloom .stage-box .sprite {
  animation: bloom-glow 1.5s ease-in-out infinite;
}
@keyframes bloom-glow {
  0%, 100% { filter: drop-shadow(0 0 3px rgba(245,179,1,.7)); transform: translateY(0); }
  50%      { filter: drop-shadow(0 0 10px rgba(255,220,90,.95)); transform: translateY(-4%); }
}

/* 杂草 / 虫子（可直接点它一步清除）
   ※ 同 .stage-box：v7 起挂在 .soil-base 内，按各自画布底部留白校准
   （weed 底部留白 ~16%，bug ~23%） */
.evt {
  position: absolute;
  right: 2%; bottom: 14%;
  width: 44%;
  cursor: pointer;
  z-index: 2;
  animation: evt-bounce 1s steps(3) infinite;
  touch-action: manipulation;
  background: none; border: 0; padding: 0;
}
.evt.evt-bug { bottom: 10%; }
/* 多帧就位（anim-weed/bug-fN）：帧动画自带摇摆/蠕动，关掉 evt-bounce 免双重运动 */
.evt.evt-multi { animation: none; }
.evt img { display: block; width: 100%; height: auto; }
.evt .sprite-fallback { display: block; font-size: 30px; text-align: center; }
@keyframes evt-bounce {
  0%, 100% { transform: translateY(0) rotate(0deg); }
  40%      { transform: translateY(-10%) rotate(-5deg); }
  70%      { transform: translateY(-4%) rotate(4deg); }
}
.evt-mark {
  position: absolute; top: -14px; right: -4px;
  font-family: var(--px-font); font-weight: 800; font-size: 14px;
  color: #fff; background: #e5533d;
  border: 2px solid var(--cocoa);
  padding: 0 5px; line-height: 1.35;
  animation: mark-blink .7s steps(2) infinite;
}
@keyframes mark-blink { 50% { background: var(--gold); color: #6b4b00; } }
/* 警示牌图标模式（icon-alert 自带红底感叹号）：卸掉文字底色边框，闪烁改轻微跳动；
   图挂了 JS 摘掉此 class 回落成上面的文字"!"红牌 */
.evt-mark.evt-mark-img {
  background: none; border: 0; padding: 0;
  animation: mark-hop .7s steps(2) infinite;
}
.evt-mark.evt-mark-img img { display: block; width: 18px; height: 18px; }
@keyframes mark-hop { 50% { transform: translateY(-2px); } }

/* 浇过水角标 */
.badge-water {
  position: absolute; top: -6%; left: 0;
  font-size: 14px; line-height: 1;
  background: var(--cream); border: 2px solid var(--cocoa);
  padding: 2px 3px;
  box-shadow: 2px 2px 0 rgba(94,53,53,.3);
  z-index: 2;
}
.badge-water img { display: block; width: 14px; height: 14px; }

/* 可收获横幅 */
.badge-ready {
  position: absolute; top: -14%; left: 50%;
  transform: translateX(-50%);
  font-family: var(--px-font); font-weight: 800; font-size: 11px;
  color: #fff; background: var(--pink-500);
  border: 2px solid var(--cocoa); padding: 2px 6px;
  animation: ready-blink 1s steps(2) infinite;
  white-space: nowrap; z-index: 2;
}
@keyframes ready-blink { 50% { background: var(--gold); color: #6b4b00; } }

/* 地块下方：迷你进度条 + 状态字 */
.plot-meta {
  margin-top: 2px;
  display: flex; flex-direction: column; align-items: center; gap: 3px;
  pointer-events: none;
}
.pbar {
  display: flex; gap: 2px;
  width: 84%; max-width: 130px;
  padding: 2px; background: rgba(255,248,242,.95);
  border: 2px solid var(--cocoa);
}
.pbar i { flex: 1; height: 6px; background: var(--pink-200); }
.pbar i.on { background: var(--pink-500); }
.plot.is-bloom .pbar i.on { background: var(--gold); }
.plot.has-evt .pbar i.on { background: #b8a8a0; }

.plot-label {
  font-family: var(--px-font); font-weight: 800;
  font-size: 11px; line-height: 1.3; text-align: center;
  color: #4c2f2f;
  background: rgba(255,248,242,.88);
  border: 2px solid rgba(124,74,74,.85);
  padding: 1px 6px;
  white-space: nowrap;
  max-width: 130%;
}
.plot-label.warn { color: #a0331f; background: #ffe9c9; }

/* 浇水弹跳 */
.plot.bounce { animation: plot-bounce .55s cubic-bezier(.3,1.6,.5,1); }
@keyframes plot-bounce {
  0%   { transform: translate(-50%,-50%) scale(1,1); }
  30%  { transform: translate(-50%,-54%) scale(.95,1.06); }
  60%  { transform: translate(-50%,-50%) scale(1.06,.92); }
  100% { transform: translate(-50%,-50%) scale(1,1); }
}
/* 收获前抖动 */
.plot.harvesting .stage-box { animation: harvest-shake .6s steps(6) infinite; }
@keyframes harvest-shake {
  0%,100% { transform: translateX(-50%) scale(1.05) rotate(0deg); }
  25%     { transform: translateX(-50%) scale(1.12) rotate(-6deg); }
  75%     { transform: translateX(-50%) scale(1.12) rotate(6deg); }
}

/* ============================================================
   溜达的耶耶
   ============================================================ */
.walker {
  position: absolute;
  width: 14%;
  z-index: 7; /* 舞台内最高：耶耶永远压在地块(z3)和场景元素之上 */
  transform: translate(-50%, -100%);
  cursor: pointer;
  touch-action: none; /* 拖拽拎起需要：pointermove 期间彻底不让页面滚/缩 */
}
.walker.held { z-index: 10; cursor: grabbing; } /* 拎起时压过食物菜单(z9)等一切舞台层 */

/* ---------- 脚下椭圆软影子（独立元素挂舞台，拎起时留在地面） ---------- */
.walker-shadow {
  position: absolute;
  width: 10%;              /* ≈ 耶耶身宽(14%)的 70% */
  aspect-ratio: 4.2;       /* 扁椭圆贴底 */
  z-index: 6;              /* 耶耶(z7)之下、场景道具(z4-5)之上 */
  transform: translate(-50%, -50%);
  background: radial-gradient(closest-side, rgba(34,54,22,.36), rgba(34,54,22,.2) 55%, transparent 74%);
  pointer-events: none;
  opacity: calc(var(--sh-op, .9) * var(--sh-night, 1));
  transition: transform .16s ease, opacity .16s ease;
}
/* 走路 bob 上浮相位：影子略缩小变淡，配合起跳感（stepTick 按帧 1/4 相位挂） */
.walker-shadow.bob { transform: translate(-50%, -50%) scale(.88); --sh-op: .62; }
/* 拎起：影子留地面投影位，缩到 ~40% 变淡；松手落地自动恢复 */
.walker-shadow.lifted { transform: translate(-50%, -50%) scale(.4); --sh-op: .45; }
/* 夜间影子透明度减半 */
.stage.is-night .walker-shadow { --sh-night: .5; }

/* ---------- 拖拽拎起：降级挣扎 & 落地弹跳 ---------- */
/* held 帧不足 2 帧：sit 单帧 + 左右小幅摇摆挣扎 */
.walker.held-fallback .walker-body { animation: held-sway .55s ease-in-out infinite; }
@keyframes held-sway {
  0%, 100% { transform: rotate(-6deg); }
  50%      { transform: rotate(6deg); }
}
/* 落地小弹跳（一次性挂 .land-bounce，动画完 JS 摘掉） */
.walker.land-bounce .walker-body { animation: land-squash .45s cubic-bezier(.3,1.6,.5,1); }
@keyframes land-squash {
  0%   { transform: scale(1.08, .82) translateY(0); }
  45%  { transform: scale(.94, 1.07) translateY(-8%); }
  100% { transform: scale(1, 1) translateY(0); }
}
.walker-body { width: 100%; }
.walker-body img { display: block; width: 100%; height: auto; transition: transform .1s ease; /* 颠簸缓动，去瞬移感 */ -webkit-user-drag: none; user-drag: none; /* 禁桌面端原生拖图，否则鼠标拖不动耶耶 */ }
/* 站定待机：轻微呼吸起伏 */
.walker.standing .walker-body { animation: stand-breathe 2.8s ease-in-out infinite; }
.walker.standing.flip .walker-body { animation: stand-breathe-flip 2.8s ease-in-out infinite; }
@keyframes stand-breathe { 50% { transform: scale(1.015, .985); } }
@keyframes stand-breathe-flip { 0%,100% { transform: scaleX(-1); } 50% { transform: scale(-1.015, .985); } }
.walker-body .walker-emoji { display: block; font-size: 40px; text-align: center; }
.walker.flip .walker-body { transform: scaleX(-1); }
.walker.walking .walker-body { animation: walk-hop .45s steps(2) infinite; }
@keyframes walk-hop { 50% { margin-top: -5%; } }
.walker.sleeping .walker-body { animation: sleep-breathe 2.4s ease-in-out infinite; }
@keyframes sleep-breathe { 50% { transform: scale(1.04, .96); } }
.walker.sleeping.flip .walker-body { animation: sleep-breathe-flip 2.4s ease-in-out infinite; }
@keyframes sleep-breathe-flip { 0%,100% { transform: scaleX(-1); } 50% { transform: scale(-1.04, .96); } }

/* 刨土：小幅前倾抖动 */
.walker.digging .walker-body { animation: dig-shake .4s steps(2) infinite; }
@keyframes dig-shake {
  0%,100% { transform: translateY(0) rotate(-3deg); }
  50%     { transform: translateY(4%) rotate(3deg); }
}
.walker.digging.flip .walker-body { animation: dig-shake-flip .4s steps(2) infinite; }
@keyframes dig-shake-flip {
  0%,100% { transform: scaleX(-1) translateY(0) rotate(3deg); }
  50%     { transform: scaleX(-1) translateY(4%) rotate(-3deg); }
}
/* 坐下歪头：慢慢左右歪 */
.walker.sitting .walker-body { animation: sit-tilt 2.8s ease-in-out infinite; }
@keyframes sit-tilt {
  0%,100% { transform: rotate(-4deg); }
  50%     { transform: rotate(5deg); }
}
.walker.sitting.flip .walker-body { animation: sit-tilt-flip 2.8s ease-in-out infinite; }
@keyframes sit-tilt-flip {
  0%,100% { transform: scaleX(-1) rotate(4deg); }
  50%     { transform: scaleX(-1) rotate(-5deg); }
}
/* 打滚：左右摇晃 */
.walker.rolling .walker-body { animation: roll-wiggle .6s ease-in-out infinite; }
@keyframes roll-wiggle {
  0%,100% { transform: rotate(-10deg) translateX(-6%); }
  50%     { transform: rotate(10deg) translateX(6%); }
}
.walker.rolling.flip .walker-body { animation: roll-wiggle .6s ease-in-out infinite; } /* 打滚不区分朝向，动画 transform 盖掉 flip */
/* 嗅一嗅：身体小幅前倾两下（步态引擎停步时挂 .sniffing） */
.walker.sniffing .walker-body { animation: sniff-bow .7s ease-in-out 2; }
@keyframes sniff-bow {
  0%,100% { transform: rotate(0) translateY(0); }
  55%     { transform: rotate(7deg) translateY(3%); }
}
.walker.sniffing.flip .walker-body { animation: sniff-bow-flip .7s ease-in-out 2; }
@keyframes sniff-bow-flip {
  0%,100% { transform: scaleX(-1) rotate(0) translateY(0); }
  55%     { transform: scaleX(-1) rotate(-7deg) translateY(3%); }
}
/* 吃饭：埋头小啄 */
.walker.eating .walker-body { animation: eat-bob .5s steps(2) infinite; }
@keyframes eat-bob { 50% { transform: translateY(5%) rotate(2deg); } }

/* 刨出来的小土粒 */
.dirt-bit {
  position: absolute;
  bottom: 4%;
  width: 5px; height: 5px;
  background: var(--soil-dark);
  pointer-events: none;
  animation: dirt-pop .8s ease-out both;
}
@keyframes dirt-pop {
  0%   { transform: translate(0, 0); opacity: 1; }
  60%  { transform: translate(var(--dx, 12px), -20px); opacity: 1; }
  100% { transform: translate(var(--dx, 12px), -2px); opacity: 0; }
}

.zzz {
  position: absolute; top: -14px; right: -4px;
  font-family: var(--px-font); font-weight: 800; font-size: 13px;
  color: #5a6fae; text-shadow: 1px 1px 0 #fff;
  animation: zzz-float 2s ease-in-out infinite;
  pointer-events: none;
}
@keyframes zzz-float {
  0%   { transform: translateY(0); opacity: 0; }
  30%  { opacity: 1; }
  100% { transform: translateY(-14px); opacity: 0; }
}
/* v30 逻辑睡眠时段点不醒：zzZ 短暂加大表示"睡得正香" */
.zzz.zzz-big { font-size: 20px; }

/* 台词气泡 */
.bubble {
  position: absolute;
  bottom: calc(100% + 8px); left: 50%;
  transform: translateX(-50%);
  width: max-content; max-width: 190px;
  font-size: 12px; line-height: 1.55; text-align: center;
  color: var(--cocoa); background: var(--cream);
  border: 2px solid var(--cocoa);
  box-shadow: 3px 3px 0 rgba(94,53,53,.35);
  padding: 6px 9px;
  z-index: 6;
  animation: bubble-in .18s ease-out;
  white-space: normal;
  pointer-events: none;
}
.bubble::after {
  content: ""; position: absolute;
  bottom: -8px; left: 50%; transform: translateX(-50%);
  border: 4px solid transparent; border-top-color: var(--cocoa);
}
@keyframes bubble-in { from { transform: translateX(-50%) scale(.7); opacity: 0; } }
.walker.flip .bubble { transform: translateX(-50%); }

/* v29 内心独白气泡（环境沉思系统）：比台词更淡、无粗描边、小一号、斜体感 */
.bubble.mono {
  color: rgba(94,53,53,.72);
  background: rgba(255,252,247,.86);
  border: 1px solid rgba(124,74,74,.42);
  box-shadow: none;
  font-size: 11px;
  font-style: italic;
}
.bubble.mono::after { border-top-color: rgba(124,74,74,.42); }

/* v30 AI 回复气泡（投喂点评/摸头反应等长文案）：最多 3 行截断，点开全文浮层 */
.bubble.reply {
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
  max-width: 215px;
  text-align: left;
  pointer-events: auto; /* 基类是 none：回复气泡要接点击展开 */
  cursor: pointer;
}

/* 全文浮层正文（复用通用弹窗） */
.reply-full {
  text-align: left;
  line-height: 1.75;
  white-space: pre-wrap;
  max-height: 50vh;
  overflow-y: auto;
}

/* ============================================================
   v26 环境生态：蝴蝶 / 小鸟（纯氛围生物，不可点击）
   位移/切帧全由 JS 驱动；这里只管尺寸、层级、朝向翻面和小鸟的
   降落（top+opacity 过渡）；v33 起退场一律 JS 连续位移飞出边界
   （移动出画面 > 原地淡出），旧 .fly-off/.fly-up/.fade 淡出样式已清理
   ============================================================ */
.critter {
  position: absolute;
  z-index: 4; /* 生物层：地块(z3)之上、耶耶(z7)/影子(z6)之下 */
  pointer-events: none;
}
.critter img { display: block; width: 100%; height: auto; }
.critter.flip img { transform: scaleX(-1); }
/* 蝴蝶 64px 居中锚（同耶耶 192px→14% 比例换算） */
.critter-butterfly {
  width: 4.7%;
  transform: translate(-50%, -50%);
}
/* 小鸟 80px 底边中心锚（站在草地上）；出场透明，落地过渡见 .landed */
.critter-bird {
  width: 5.8%;
  transform: translate(-50%, -100%);
  opacity: 0;
  transition: top .55s ease-out, opacity .4s ease;
}
.critter-bird.landed { opacity: 1; }

/* ---------- v29 生态四兄弟：青蛙 / 蜗牛 / 蜻蜓 / 瓢虫 ----------
   尺寸按素材像素 × 耶耶 192px→14% 同比例换算；全部居中锚定 */
.critter-frog      { width: 5.8%; transform: translate(-50%, -50%); } /* 80px */
.critter-snail     { width: 4.1%; transform: translate(-50%, -50%); } /* 56px */
.critter-dragonfly { width: 5.3%; transform: translate(-50%, -50%); } /* 72px */
.critter-ladybug   { width: 3.5%; transform: translate(-50%, -50%); } /* 48px */
/* 青蛙跳水入池：快速位移到池塘中心（v33 不再缩小淡出，入水点 JS 瞬间摘节点） */
.critter-frog.dive {
  transition: left .35s ease-in, top .35s ease-in;
}
/* 入水涟漪：水面荡开一圈的一次性像素椭圆（演完 JS 摘掉） */
.pond-ripple {
  position: absolute;
  z-index: 4;              /* 同生物层 */
  width: 3.2%;
  aspect-ratio: 2.4;       /* 俯视水面：压扁的椭圆 */
  border: 2px solid rgba(240, 250, 255, .9);
  border-radius: 50%;
  transform: translate(-50%, -50%);
  pointer-events: none;
  animation: ripple-out .6s ease-out forwards;
}
@keyframes ripple-out {
  from { transform: translate(-50%, -50%) scale(.35); opacity: .95; }
  to   { transform: translate(-50%, -50%) scale(2.3); opacity: 0; }
}

/* ============================================================
   狗粮盆 & 吃饭氛围粒子
   ============================================================ */
.foodbowl {
  position: absolute;
  width: 11%;
  z-index: 4; /* 场景道具：地块之上、耶耶(z7)之下 */
  transform: translate(-50%, -50%);
  background: none; border: 0; padding: 0;
  cursor: pointer; touch-action: manipulation;
}
.foodbowl img { display: block; width: 100%; height: auto; }
.foodbowl:active { transform: translate(-50%, calc(-50% + 2px)); }
/* 盆接地影（v55 双层，codex 会诊定案）：
   悬浮真凶=渐变从透明外沿去"碰"盆底，碰上的永远是透明区，中间隔一线亮草。
   接触影(::after)：窄而极扁、整条实色、上缘钻进盆底后——"咬合"本体；
   外层投影(::before)：宽过盆身、很淡、垂在下方——环境光遮蔽 */
.foodbowl::after {
  content: "";
  position: absolute;
  left: 50%; bottom: 22%;  /* 22% = 归一化后全体变体统一的画布底留白（真盆底线） */
  width: 79%;              /* 打标定值：底边直径实测72.7%容器宽，两侧各延伸~3%（codex 图上标注 y413/x157-337） */
  height: 35%;             /* 高椭圆：水平直径线才能升到底边直径高度（扁椭圆无论怎么挪都只能'相切'——用户四轮纠偏的几何本质） */
  border-radius: 50%;
  transform: translate(-50%, 3%); /* 椭圆中心=底边直径线：上半藏盆身后，两侧从直径处长出，下缘垂到最低点下~4px */
  background: rgba(30,46,18,.30); /* 实色：接触影不打渐变，最暗处贴着轮廓 */
  opacity: var(--ground-op, 1); /* 定向光时段退成淡AO，斜影当主——双影同台=两个太阳（用户实锤） */
  pointer-events: none;
  z-index: -1;             /* .foodbowl 有 z-index：影子只垫到盆 img 之下 */
}
.foodbowl::before {
  content: "";
  position: absolute;
  left: 50%; bottom: 22%;
  width: 84%;              /* 比接触影再宽一圈的淡投影 */
  aspect-ratio: 7.8;       /* 压扁：外影只负责扩散，承重交给接触影 */
  transform: translate(-50%, 72%); /* 大半垂在盆底之下 */
  background: radial-gradient(closest-side, rgba(30,46,18,.11), rgba(30,46,18,.06) 60%, transparent 85%);
  opacity: var(--ground-op, 1);
  pointer-events: none;
  z-index: -1;
}
/* 按下盆下压 2px 时影子反向补偿贴地不动 */
.foodbowl:active::after { transform: translate(-50%, calc(3% - 2px)); }
.foodbowl:active::before { transform: translate(-50%, calc(72% - 2px)); }
/* 夜间接触影：原生夜背景近黑（亮度~34），减半的影子彻底隐形=失去接地锚点。
   保持 .85——月光下影子仍在，物才立得住 */
/* 夜间强度并入 --ground-op（tod-night .85），不再单列防覆盖 */
/* v44 粮量层：通用棕粮堆叠在盆口凹陷处（kibble-full/half/few.png，配任何主题盆）。
   锚点（部署前人工核对）：盆图画布底部 22% 透明留白 → 盆口凹陷约在画布纵向 28-43% 带，
   粮堆中心定 top 35%；视觉盆宽 ≈74% 画布，粮堆取 57%（≈盆宽的 77% 画布口径、盆口内 ~58%） */
.foodbowl .kibble-layer {
  position: absolute;
  left: 50%; top: 35%;
  width: 57%; height: auto;
  transform: translate(-50%, -50%);
  opacity: 0;                      /* 默认空盆：updateKibble 加 .on 淡入 */
  transition: opacity .3s ease;    /* 换档淡切，别闪 */
  pointer-events: none;
}
.foodbowl .kibble-layer.on { opacity: 1; }
.foodbowl .kibble-layer.lv-few { width: 42%; top: 37%; } /* 少粮档：几颗散粒别撑满盆口 */
.foodbowl .kibble-layer.lv-half { width: 52%; }
/* 盆空小气泡：「盆空啦…」（v44，盆旁偶尔冒一句） */
.bowl-tip {
  position: absolute;
  z-index: 8;
  transform: translate(-50%, -100%);
  font-family: var(--px-font); font-size: 11px; font-weight: 700;
  color: var(--cocoa); background: var(--cream);
  border: 2px solid var(--cocoa);
  padding: 3px 8px;
  box-shadow: 2px 2px 0 rgba(94,53,53,.35);
  white-space: nowrap;
  pointer-events: none;
  animation: bowl-tip-in .2s cubic-bezier(.3,1.6,.5,1);
}
@keyframes bowl-tip-in { from { transform: translate(-50%, -100%) scale(.6); opacity: 0; } }
.foodbowl-fb {
  display: flex; align-items: center; justify-content: center;
  width: 100%; aspect-ratio: 1.6;
  font-size: 26px;
  background: #d9b28c;
  border: 3px solid var(--cocoa);
  border-radius: 0 0 10px 10px;
  box-shadow: inset 0 -5px 0 rgba(124,74,74,.3), 2px 2px 0 rgba(94,53,53,.35);
}

/* ---------- 露天小窝：盆旁常驻家具（v42，耶耶午睡/夜眠专属床位） ---------- */
.dogbed {
  position: absolute;
  width: 11%;
  z-index: 4; /* 同盆：场景道具层，耶耶(z7)趴进来时天然压在窝上 */
  transform: translate(-50%, -50%);
  background: none; border: 0; padding: 0;
  cursor: pointer; touch-action: manipulation;
}
.dogbed img { display: block; width: 100%; height: auto; }
/* 窝接地影（v55 双层，同盆）：接触带咬住篮底弧 + 外层淡投影 */
.dogbed::after {
  content: "";
  position: absolute;
  left: 50%; bottom: 0;    /* dogbed.png bbox 紧裁：底沿即贴地线 */
  width: 98%;              /* 打标定值：篮底直径实测89.7%容器宽+两侧延伸（codex 标注 y229/x111-333） */
  height: 43%;
  border-radius: 50%;
  transform: translate(-50%, 4%); /* 椭圆中心=篮底直径线 */
  background: rgba(30,46,18,.32);
  opacity: var(--ground-op, 1);
  pointer-events: none;
  z-index: -1;
}
.dogbed::before {
  content: "";
  position: absolute;
  left: 50%; bottom: 0;
  width: 101%;
  aspect-ratio: 7.2;
  transform: translate(-50%, 70%);
  background: radial-gradient(closest-side, rgba(30,46,18,.11), rgba(30,46,18,.06) 60%, transparent 85%);
  opacity: var(--ground-op, 1);
  pointer-events: none;
  z-index: -1;
}
/* 夜间影子透明度减半（同耶耶/盆惯例） */


/* ---------- 投喂菜单：贴着盆弹出的迷你气泡菜单 ---------- */
.food-menu {
  position: absolute;
  right: 18.5%; top: 30%; /* v44 盆回 (64%,25%)：菜单弹在盆正下方（尾巴在菜单 right 38% → 18.5+46*0.38≈35.98 → 指向 ≈64%） */
  width: 46%;
  z-index: 9;
  background: var(--cream);
  border: 3px solid var(--cocoa);
  box-shadow: 4px 4px 0 rgba(94,53,53,.4);
  padding: 8px;
  transform-origin: 60% 0;
  animation: menu-pop .18s cubic-bezier(.3,1.6,.5,1);
}
@keyframes menu-pop { from { transform: scale(.6); opacity: 0; } }
.food-menu::before {
  /* 指向盆的小尾巴 */
  content: ""; position: absolute;
  top: -13px; right: 38%;
  border: 6px solid transparent; border-bottom-color: var(--cocoa);
}
.food-menu-title {
  font-family: var(--px-font); font-weight: 800; font-size: 12px;
  text-align: center; color: var(--cocoa);
  margin-bottom: 6px;
}
.food-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; }
.food-item {
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  padding: 5px 2px 4px;
  background: #fff; border: 2px solid var(--cocoa);
  box-shadow: 2px 2px 0 rgba(124,74,74,.25);
  cursor: pointer; touch-action: manipulation;
  font-family: inherit;
}
.food-item:active { transform: translate(1px,1px); box-shadow: 0 0 0; }
.food-item .sprite { display: block; width: 72%; height: auto; }
.food-item .sprite-fallback { font-size: 22px; text-align: center; }
.food-name { font-size: 10px; font-weight: 700; color: var(--cocoa); white-space: nowrap; }

/* v47 拍照投喂格：六格后整行虚线瓦片（cocoa 虚线边框 + 大加号） */
.food-item-upload {
  grid-column: 1 / -1;
  flex-direction: row; justify-content: center; gap: 6px;
  padding: 6px 2px;
  background: rgba(255,255,255,.55);
  border: 2px dashed var(--cocoa);
  box-shadow: none;
}
.food-upload-plus {
  font-size: 18px; line-height: 1; font-weight: 800; color: var(--cocoa);
}
/* 冷却中：六样预设灰显禁点，拍照格不受影响（服务端冷却自会拒绝并有文案） */
.food-menu.cooling .food-item:not(.food-item-upload) {
  opacity: .45; pointer-events: none;
}

/* 选中的食物落在盆上方 */
.bowl-food {
  position: absolute;
  width: 8%;
  z-index: 5; /* 盆(z4)之上、耶耶(z7)之下 */
  transform: translate(-50%, -50%);
  pointer-events: none;
  animation: food-drop .35s cubic-bezier(.3,1.6,.5,1);
}
@keyframes food-drop { from { transform: translate(-50%, -110%); opacity: 0; } }
.bowl-food img { display: block; width: 100%; height: auto; }
.bowl-food .sprite-fallback { display: block; font-size: 24px; text-align: center; }

/* v47 拍照投喂：用户照片缩略图落盆——真实照片圆角小方图，不吃全局像素滤镜 */
.bowl-food-photo { width: 7%; }
.bowl-food-photo img {
  width: 100%; aspect-ratio: 1 / 1; object-fit: cover;
  border: 2px solid var(--cocoa); border-radius: 6px;
  box-shadow: 2px 2px 0 rgba(94,53,53,.35);
  image-rendering: auto;
}

/* 蹦出来的粮粒 */
.kibble {
  position: absolute;
  width: 6px; height: 6px;
  background: #b5772f;
  box-shadow: inset -2px -2px 0 #8f5a1e;
  z-index: 6;
  pointer-events: none;
  animation: kibble-hop 1.1s ease-out both;
}
@keyframes kibble-hop {
  0%   { transform: translate(0, 0) rotate(0deg); opacity: 1; }
  55%  { transform: translate(8px, -16px) rotate(120deg); opacity: 1; }
  100% { transform: translate(14px, 2px) rotate(240deg); opacity: 0; }
}
/* 嗷呜嗷呜小字 */
.munch-txt {
  position: absolute;
  z-index: 8;
  font-family: var(--px-font); font-weight: 800; font-size: 11px;
  color: var(--cocoa); text-shadow: 1px 1px 0 #fff;
  pointer-events: none;
  animation: munch-float 2.4s ease-out both;
  white-space: nowrap;
}
@keyframes munch-float {
  0%   { transform: translateY(0); opacity: 0; }
  20%  { opacity: 1; }
  100% { transform: translateY(-22px); opacity: 0; }
}

/* ============================================================
   夜色 & 星星萤火虫
   ============================================================ */
.night {
  /* v53 起降级回"星星萤火容器"：色调职责移交 .todveil（见下）。
     必须留在 z2——星星要在建筑/耶耶身后闪（在天上），跟着 --night-fx-op 昼隐夜现 */
  position: absolute; inset: 0; z-index: 2;
  pointer-events: none;
  opacity: var(--night-fx-op, 0);
  transition: opacity 4s ease;
}
.todveil {
  /* v53 时段色调层：从 z2 抬到 z8（世界层之上、食物菜单 z9 之下）。
     z2 时代只染背景不染精灵——耶耶/植物/虫鸟/静物大白天亮度浮在夜色上，
     "不在同一图层"（用户三连点名：植物/耶耶/小动物）。现在一层有色光罩住全体
     世界居民，颜色物理正确（粉盆在夜里是暗粉，不像 hue-rotate 会转色相）。
     拎起的耶耶(z10)/菜单(z9)在罩外：拿出世界=变亮，是提示不是穿帮。
     强度 = 时段基准 × 主题系数（--tod-scale）——自带时刻的主题少刷一遍色 */
  position: absolute; inset: 0; z-index: 8;
  pointer-events: none;
  background: var(--tod-bg, transparent);
  opacity: calc(var(--tod-op, 0) * var(--tod-scale, 1));
  transition: opacity 4s ease, background 4s ease;
}
/* ── 七时段（北京时间）──────────────────────────────────
   v52 起时段光照由背景图本身承担（63 张原生图：9 主题 × 7 时段，
   每张都是照着"太阳在哪、影子往哪倒、色温多少"重绘的）。
   这层遮罩因此从"造夜"降级为"统一色调"——只负责把浮在背景之上的精灵
   染进当前光线里，别让白天的耶耶贴在夜空上。留 0 会穿帮，留满会黑成一团：
   实测原生夜图平均亮度 27（旧版白天图+满遮罩才 99），再叠满就没法玩了。 */
.stage.tod-dawn {
  --tod-bg: linear-gradient(rgba(122,138,196,.42), rgba(238,178,150,.30) 70%, rgba(246,198,160,.24));
  --tod-op: .18;  --sprite-dim: .82; --ground-dim: .78; --sprite-sat: .92; --sign-dim: .88;
  --night-fx-op: .25;  /* 黎明残星 */
  --ground-op: .9;
}
.stage.tod-morning {
  --tod-bg: linear-gradient(rgba(255,240,205,.26), rgba(255,246,220,.14));
  --tod-op: .12;
  --ground-op: .3;
}
.stage.tod-noon { --tod-bg: transparent; --tod-op: 0; }
.stage.tod-afternoon {
  --tod-bg: linear-gradient(rgba(255,214,140,.20), rgba(255,196,120,.26));
  --tod-op: .16;
  --ground-op: .3;
}
.stage.tod-dusk {
  --tod-bg: linear-gradient(rgba(255,150,80,.30), rgba(232,104,86,.34) 60%, rgba(150,80,110,.30));
  --tod-op: .22;  --sprite-dim: .88; --ground-dim: .85; --sprite-sat: 1; --sign-dim: .93;
  --ground-op: .25;
}
.stage.tod-evening {
  --tod-bg: linear-gradient(rgba(70,64,140,.40), rgba(44,44,104,.44));
  --tod-op: .15;  --sprite-dim: .72; --ground-dim: .66; --sprite-sat: .9; --sign-dim: .8;
  --night-fx-op: .8;
  --ground-op: .85;
}
.stage.tod-night {
  --tod-bg: linear-gradient(rgba(24,32,84,.34), rgba(18,24,66,.42));
  --tod-op: .25;  --sprite-dim: .62; --ground-dim: .55; --sprite-sat: .85; --sign-dim: .72;
  --night-fx-op: 1;
  --ground-op: .85;
}
/* 主题时段系数：本身自带时刻的主题少刷一点，别把黄昏画成正午、把极光夜刷成白天 */
.stage.theme-dusk     { --tod-scale: .35; }
.stage.theme-cloudsea { --tod-scale: .4; }
.stage.theme-dream    { --tod-scale: .6; }
.stage.theme-aurora   { --tod-scale: .15; }

/* ---------- 时段调光：压暗场景实体，文字标签/进度条保持原亮度 ----------
   作物(.stage-box)和杂草虫子(.evt)挂在 .soil-base 内，随土垄一起压暗；
   .plot-meta / .plant-sign / 气泡在 soil-base 外，可读性不受影响。
   v52：由 is-night 二值跳变（19:00 整个农场"啪"地暗一档）改为跟七时段同源的
   变量，逐档过渡。地面实体比耶耶多压一点——耶耶是白萨摩，夜里本就该是最亮的那团。
   白昼三档（清晨/正午/午后）不进 .is-dim，完全不挂 filter——挂了哪怕是
   brightness(1) 也会把这些元素永久提升成合成层，白白吃移动端的显存 */
.foodbowl, .bowl-food, .soil-base, .walker-body, .bld, .dogbed, .critter {
  transition: filter 2s ease;
}
.stage.is-dim .foodbowl,
.stage.is-dim .bowl-food,
.stage.is-dim .dogbed,
.stage.is-dim .soil-base,
.stage.is-dim .critter,   /* 蝴蝶/小鸟/青蛙/蜗牛/蜻蜓/瓢虫也是世界里的居民，一起入夜 */
.stage.is-dim .bld  { filter: brightness(var(--ground-dim, 1)) saturate(var(--sprite-sat, 1)); }
/* v54 时段重打光就位的静物（native-lit）：贴图本身已是该时段的光，CSS 再压一道会黑穿。
   贴图外的通用部件（粮堆/招牌）不在重打光里，单独补齐调光别让它们浮出来 */
.stage.is-dim .foodbowl.native-lit,
.stage.is-dim .dogbed.native-lit,
.stage.is-dim .bld.native-lit { filter: none; }
.stage.is-dim .foodbowl.native-lit .kibble-layer,
.stage.is-dim .bld.native-lit .bld-sign { filter: brightness(var(--sign-dim, 1)) saturate(var(--sprite-sat, 1)); }
.stage.is-dim .walker-body { filter: brightness(var(--sprite-dim, 1)) saturate(var(--sprite-sat, 1)); }
/* 世界内的牌子文字也得吃光照——不然农场入夜了，"故事馆/专注"的白底招牌、地块
   标签、植物牌还是正午亮度，像刚贴上去的贴纸浮在夜色外（用户原话"不在同一个
   图层"）。比场景实体压得轻（--sign-dim 下限 .72），奶油底上的深字仍可读。
   对话气泡也进名单（用户："不然晚上很亮，出戏"）——奶油底光靠 .25 罩压不住，
   和牌子同吃 --sign-dim，夜里 .72 仍可读但不再是白天亮度。
   bld-sign 不在列表里：它钉在 .bld 内，已随建筑一起吃 --ground-dim，再单列会双重压暗 */
.away-sign, .plant-sign, .plot-meta, .vx-sign, .bubble {
  transition: filter 2s ease;
}
.stage.is-dim .away-sign,
.stage.is-dim .plant-sign,
.stage.is-dim .plot-meta,
.stage.is-dim .vx-sign,
.stage.is-dim .bubble { filter: brightness(var(--sign-dim, 1)) saturate(var(--sprite-sat, 1)); }

/* ---------- 静物剪影投影：影子方向随太阳走 ----------
   背景已是"真光照"（树影晨右/午收/暮左），静物脚下再摆一坨永恒正椭圆就穿帮。
   .cast = JS 克隆的本体贴图（addCastShadow，src 自动跟随换肤），在这里压成贴地剪影：
   scaleY(-len) 倒向地面、skewX 定方向——参数与各时段背景里画的树影对齐。
   原椭圆软影保留当接触暗部（AO），剪影负责方向叙事，两层各干各的 */
.cast {
  position: absolute;
  left: 0; bottom: 0;
  width: 100%; height: auto;
  transform-origin: 50% 100%;
  /* 右到左先 scaleY 倒地压扁，再 skewX 斜切定方向 */
  transform: skewX(var(--cast-skew, 0deg)) scaleY(calc(-1 * var(--cast-len, .2)));
  opacity: var(--cast-op, 0);
  /* blur 必不可少：不模糊的倒立剪影会被读成"镜面倒影"=全场悬浮（上过一次线，用户笑死） */
  filter: brightness(0) blur(2px);
  image-rendering: pixelated;
  pointer-events: none;
  transition: transform 2s ease, opacity 2s ease;
}
/* 剪影的根 = 底边接触直径线（用户定案：斜影必须与底边直径同轴同宽，从那条线伸出去）。
   锚定值来自打标坐标：盆直径线距容器底 38%、直径宽 73%；窝 20% / 90%。
   width 收窄到直径宽后 left 按 (100-w)/2 居中；transform-origin 在根部中心，skew 时根线不动 */
.foodbowl .cast { bottom: 38%; left: 13.5%; width: 73%; }
.dogbed .cast   { bottom: 20%; left: 5%;    width: 90%; }
/* 时段参数：与背景树影同向同长。剪影只在太阳斜射时出现（晨/下午/黄昏）——
   正午顶光/夜晚月光/晨昏无直射一律 op 0，交还给椭圆接触影；
   skew=0 的垂直倒影读起来是水面反射不是影子，绝不能上 */
/* len 控制影子的"下垂"量——俯视视角里必须小（背景树影只微微向下），
   方向感全靠 skew 的水平甩出：tan(58 deg)≈1.6 → 影尖横甩 1.6×len 的物高。
   len .45 那版影子下坠半个物高=用户"影子很靠下"实锤 */
.stage.tod-dawn      { --cast-op: 0; }
.stage.tod-morning   { --cast-skew: 55deg;  --cast-len: .2;  --cast-op: .15; }
.stage.tod-noon      { --cast-op: 0; }
.stage.tod-afternoon { --cast-skew: -58deg; --cast-len: .2;  --cast-op: .15; }
.stage.tod-dusk      { --cast-skew: -64deg; --cast-len: .26; --cast-op: .13; }
.stage.tod-evening   { --cast-op: 0; }
.stage.tod-night     { --cast-op: 0; }
.night .star {
  position: absolute;
  width: 4px; height: 4px; background: #fff8d8;
  box-shadow: 0 0 4px rgba(255,248,216,.9);
  animation: star-twinkle 2.4s steps(2) infinite;
}
@keyframes star-twinkle { 50% { opacity: .25; } }
.fireflies {
  /* v59：从 .night(z2) 拆出——萤火虫在草地间飞该在物体前，星星留天幕层 */
  position: absolute; inset: 0; z-index: 7;
  pointer-events: none;
  opacity: var(--night-fx-op, 0);
  transition: opacity 4s ease;
}
.fireflies .firefly {
  position: absolute;
  width: 5px; height: 5px; background: #ffe98a;
  border-radius: 0;
  box-shadow: 0 0 6px 2px rgba(255,233,138,.75);
  animation: firefly-drift 6s ease-in-out infinite alternate;
}
@keyframes firefly-drift {
  0%   { transform: translate(0, 0); opacity: .25; }
  40%  { opacity: 1; }
  100% { transform: translate(18px, -26px); opacity: .35; }
}

/* ============================================================
   HUD
   ============================================================ */
.hud {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 20;
  display: flex; align-items: center; gap: 8px;
  padding: calc(8px + env(safe-area-inset-top)) 12px 8px;
  pointer-events: none;
}
.hud > * { pointer-events: auto; }
.hud-back {
  display: flex; align-items: center; justify-content: center;
  width: 38px; height: 38px;
  font-family: var(--px-font); font-weight: 800; font-size: 18px;
  color: var(--cocoa); text-decoration: none;
  background: var(--cream);
  border: 3px solid var(--cocoa);
  box-shadow: 2px 2px 0 rgba(94,53,53,.4);
}
.hud-back:active { transform: translate(1px,1px); box-shadow: 1px 1px 0 rgba(94,53,53,.4); }
.hud-title {
  font-family: var(--px-font); font-weight: 800; font-size: 15px;
  letter-spacing: .08em;
  color: var(--cocoa);
  background: var(--pink-200);
  border: 3px solid var(--cocoa);
  box-shadow: 2px 2px 0 rgba(94,53,53,.4);
  padding: 6px 10px;
  text-shadow: 1px 1px 0 #fff;
  /* HUD 多了主题按钮：窄屏时标题让位，省略号收尾 */
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.wallet-chip {
  margin-left: auto;
  display: inline-flex; align-items: center; gap: 4px;
  font-family: var(--px-font); font-weight: 800; font-size: 15px;
  color: var(--cocoa);
  background: var(--cream);
  border: 3px solid var(--cocoa);
  box-shadow: 2px 2px 0 rgba(94,53,53,.4);
  padding: 6px 10px; min-height: 38px;
}
.wallet-chip.pop { animation: wallet-pop .45s cubic-bezier(.3,1.7,.5,1); }
@keyframes wallet-pop { 40% { transform: scale(1.16); } }
.wallet-chip img { display: block; width: 18px; height: 18px; }

/* 主题切换小按钮：钱包旁边的 38px 像素方块（同 hud-back 手感） */
.theme-btn {
  display: flex; align-items: center; justify-content: center;
  width: 38px; height: 38px; flex: none;
  font-size: 17px; line-height: 1;
  background: var(--cream);
  border: 3px solid var(--cocoa);
  box-shadow: 2px 2px 0 rgba(94,53,53,.4);
  cursor: pointer; touch-action: manipulation;
  padding: 0;
}
.theme-btn:active { transform: translate(1px,1px); box-shadow: 1px 1px 0 rgba(94,53,53,.4); }
.theme-btn img { display: block; width: 22px; height: 22px; }

/* 弹窗/文案里的内联小图标（骨头币等）：随文字基线走 */
.icon-inline { display: inline-block; width: 14px; height: 14px; vertical-align: -2px; }

/* 主题菜单选项（复用像素弹窗，条目同 seed-card 风格收窄版） */
.theme-list { display: flex; flex-direction: column; gap: 8px; margin: 10px 0 2px; }
.theme-item {
  width: 100%; min-height: 44px; text-align: left;
  padding: 8px 12px;
  font-family: var(--px-font); font-weight: 800; font-size: 13px;
  color: var(--cocoa); background: #fff;
  border: 3px solid var(--cocoa);
  box-shadow: 2px 2px 0 rgba(124,74,74,.3);
  cursor: pointer; touch-action: manipulation;
}
.theme-item:active { transform: translate(1px,1px); box-shadow: 1px 1px 0 rgba(124,74,74,.3); }
.theme-item.sel { background: var(--pink-200); box-shadow: 0 0 0 2px var(--pink-500), 2px 2px 0 rgba(124,74,74,.3); }
.theme-item:disabled { opacity: .6; }

/* ============================================================
   图鉴入口 & 底部抽屉
   ============================================================ */
.dex-btn {
  position: fixed;
  left: 50%; bottom: calc(10px + env(safe-area-inset-bottom));
  transform: translateX(-50%);
  z-index: 20;
  font-family: var(--px-font); font-weight: 800; font-size: 14px;
  color: var(--cocoa); background: var(--cream);
  border: 3px solid var(--cocoa);
  box-shadow: 3px 3px 0 rgba(94,53,53,.4);
  padding: 9px 16px;
  cursor: pointer; touch-action: manipulation;
}
.dex-btn:active { transform: translate(calc(-50% + 2px), 2px); box-shadow: 1px 1px 0 rgba(94,53,53,.4); }
.dex-count { font-size: 11px; color: var(--ink-soft); font-weight: 800; }

.drawer-mask {
  position: fixed; inset: 0; z-index: 30;
  background: rgba(60,40,40,.35);
}
.drawer {
  position: fixed; left: 0; right: 0; bottom: 0;
  z-index: 31;
  max-height: 76vh; max-height: 76dvh;
  display: flex; flex-direction: column;
  background: var(--cream);
  border-top: 3px solid var(--cocoa);
  box-shadow: 0 -4px 0 rgba(94,53,53,.3);
  transform: translateY(100%);
  transition: transform .28s cubic-bezier(.3,1.2,.4,1);
}
.drawer.open { transform: translateY(0); }
.drawer-handle {
  flex: none;
  width: 100%;
  font-family: var(--px-font); font-weight: 800; font-size: 15px;
  color: var(--cocoa); background: var(--pink-200);
  border: 0; border-bottom: 3px solid var(--cocoa);
  padding: 12px 10px;
  cursor: pointer; touch-action: manipulation;
}
.drawer-body {
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  padding: 14px 14px calc(16px + env(safe-area-inset-bottom));
}

.dex-grid {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px;
  max-width: 520px; margin: 0 auto 16px;
}
.dex-cell {
  position: relative;
  display: flex; flex-direction: column; align-items: center; gap: 3px;
  padding: 10px 4px 8px; min-height: 96px;
  background: #fff;
  border: 2px solid var(--cocoa);
  box-shadow: 2px 2px 0 rgba(124,74,74,.25);
}
.dex-cell .sprite { width: 48px; height: 48px; object-fit: contain; }
.dex-cell.locked { background: #e9dcd4; }
.dex-name { font-size: 11px; font-weight: 700; line-height: 1.2; text-align: center; }
.dex-cell.locked .dex-name { color: #b39d92; }
.dex-num { font-family: var(--px-font); font-size: 10px; font-weight: 800; color: var(--ink-soft); }
.dex-q {
  width: 48px; height: 48px; display: flex; align-items: center; justify-content: center;
  font-family: var(--px-font); font-size: 26px; font-weight: 800; color: #b39d92;
}
.rar-tag {
  position: absolute; top: -2px; right: -2px;
  font-family: var(--px-font); font-size: 9px; font-weight: 800;
  padding: 1px 4px; border: 2px solid var(--cocoa); color: #fff; line-height: 1.3;
}
.rar-tag.r-common { background: #b8a8a0; }
.rar-tag.r-rare { background: var(--violet); }
.rar-tag.r-legendary { background: var(--gold); color: #6b4b00; }

.dex-story-link {
  margin: 0 0 12px;
  text-align: center;
  font-size: 11px; color: var(--ink-soft);
}
.dex-story-link a { color: #6b4bb3; font-weight: 800; }

/* ----- v36 抽屉双 tab：像素卡册（默认）/ 耶耶纪念页 ----- */
.dex-tabs {
  flex: none;
  display: flex;
  border-bottom: 3px solid var(--cocoa);
  background: var(--cream);
}
.dex-tab {
  flex: 1;
  font-family: var(--px-font); font-weight: 800; font-size: 13px;
  color: var(--ink-soft); background: #efe3da;
  border: 0; border-right: 2px solid var(--cocoa);
  padding: 10px 6px;
  cursor: pointer; touch-action: manipulation;
}
.dex-tab:last-child { border-right: 0; }
.dex-tab.sel { color: var(--cocoa); background: #fff; box-shadow: inset 0 -3px 0 var(--pink-500); }

.dex-frozen-note {
  margin: 0 0 10px;
  text-align: center;
  font-size: 11px; color: #b39d92;
}

/* ----- v36 像素卡册：153 格紧凑网格 ----- */
.pixel-progress {
  display: flex; align-items: center; gap: 10px;
  max-width: 520px; margin: 0 auto 10px;
  font-family: var(--px-font); font-size: 12px; font-weight: 800; color: var(--cocoa);
  white-space: nowrap;
}
.pixel-progress-bar {
  flex: 1; height: 10px;
  background: #e9dcd4;
  border: 2px solid var(--cocoa);
  overflow: hidden;
}
.pixel-progress-bar i {
  display: block; height: 100%; width: 0;
  background: linear-gradient(90deg, var(--pink-400), var(--violet));
  transition: width .4s ease;
}
.pixel-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(52px, 1fr));
  gap: 6px;
  max-width: 520px; margin: 0 auto 14px;
}
.px-cell {
  position: relative;
  aspect-ratio: 1;
  display: flex; align-items: center; justify-content: center;
  padding: 0;
  background: #fff;
  border: 2px solid var(--cocoa);
  box-shadow: 2px 2px 0 rgba(124,74,74,.2);
  cursor: pointer; touch-action: manipulation;
  overflow: hidden;
}
.px-cell:active { transform: translate(1px,1px); box-shadow: 1px 1px 0 rgba(124,74,74,.2); }
.px-cell img { width: 100%; height: 100%; object-fit: cover; }
.px-cell.locked { background: #e9dcd4; cursor: default; }
.px-cell.locked:active { transform: none; }
/* （v45 一体两面：orig-only 半透明中间态与「原版」小标废除，样式一并清掉） */
.px-emoji { font-size: 24px; line-height: 1; }
.px-q {
  font-family: var(--px-font); font-size: 18px; font-weight: 800; color: #b39d92;
}
/* v45 稀有度角标：z 提到卡框内线（z3）之上 + 内缩 3px——铜/银框双内线、金框 3px 粗边下都完整可读 */
.px-rar {
  position: absolute; top: 3px; right: 3px; z-index: 4;
  font-family: var(--px-font); font-size: 8px; font-weight: 800;
  padding: 0 3px; line-height: 1.5;
  border: 1px solid var(--cocoa); color: #fff;
}
.px-rar.pr-R   { background: #b8a8a0; }
.px-rar.pr-SR  { background: var(--violet); }
.px-rar.pr-SSR { background: var(--gold); color: #6b4b00; }
.px-rar.pr-UR  { background: linear-gradient(90deg, var(--gold), var(--pink-400), var(--violet)); }
/* 大图弹窗里的卡面放大一号 */
.pxd-art { width: 190px; height: 190px; }

.back-link {
  display: block; width: fit-content; margin: 0 auto;
  min-height: 44px; line-height: 38px;
  padding: 0 18px;
  font-family: var(--px-font); font-weight: 800; font-size: 14px;
  color: var(--cocoa); text-decoration: none;
  background: var(--pink-200); border: 3px solid var(--cocoa);
  box-shadow: 3px 3px 0 rgba(124,74,74,.3);
}
.back-link:active { transform: translate(2px,2px); box-shadow: 1px 1px 0 rgba(124,74,74,.3); }

/* ============================================================
   弹窗
   ============================================================ */
.overlay {
  position: fixed; inset: 0; z-index: 40;
  background: rgba(124,74,74,.4);
  display: flex; align-items: center; justify-content: center;
  padding: 24px 20px;
}
.modal {
  width: 100%; max-width: 340px;
  max-height: 82vh; max-height: 82dvh;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  background: var(--cream);
  border: 3px solid var(--cocoa);
  box-shadow: 5px 5px 0 rgba(124,74,74,.4);
  padding: 18px 16px 16px;
  text-align: center;
  animation: modal-in .18s ease-out;
}
@keyframes modal-in { from { transform: scale(.85); opacity: 0; } }
.modal h3 {
  margin: 0 0 8px; font-family: var(--px-font);
  font-size: 17px; font-weight: 800; letter-spacing: .06em;
}
.modal p { margin: 0 0 6px; font-size: 13px; line-height: 1.7; color: var(--cocoa); }
.modal .muted { font-size: 11px; color: var(--ink-soft); }
.modal .m-sprite { width: 72px; height: 72px; object-fit: contain; margin: 4px auto 6px; display: block; }
.modal .pbar { margin: 8px auto 10px; max-width: 180px; width: 100%; }
.m-btns { display: flex; gap: 10px; margin-top: 14px; }
.px-btn {
  flex: 1; min-height: 46px;
  font-family: var(--px-font); font-weight: 800; font-size: 14px;
  color: var(--cocoa); background: var(--pink-200);
  border: 3px solid var(--cocoa);
  box-shadow: 2px 2px 0 rgba(124,74,74,.35);
  cursor: pointer; touch-action: manipulation;
}
.px-btn.primary { background: var(--pink-400); color: #fff; text-shadow: 1px 1px 0 rgba(124,74,74,.4); }
.px-btn.ghost { background: var(--cream); }
.px-btn.leaf { background: #9ccf6d; }
.px-btn:active { transform: translate(2px,2px); box-shadow: 0 0 0; }
.px-btn:disabled { opacity: .55; transform: none; }

/* 种子商店卡片 */
.seed-list { display: flex; flex-direction: column; gap: 8px; margin: 10px 0 2px; }
.seed-card {
  display: flex; align-items: center; gap: 10px;
  width: 100%; text-align: left;
  padding: 8px 10px;
  background: #fff;
  border: 3px solid var(--cocoa);
  box-shadow: 2px 2px 0 rgba(124,74,74,.3);
  cursor: pointer; touch-action: manipulation;
  font-family: inherit; color: var(--cocoa);
}
.seed-card:active { transform: translate(1px,1px); box-shadow: 1px 1px 0 rgba(124,74,74,.3); }
.seed-card.sel { background: var(--pink-200); box-shadow: 0 0 0 2px var(--pink-500), 2px 2px 0 rgba(124,74,74,.3); }
.seed-card:disabled { opacity: .5; cursor: default; }
.seed-card:disabled:active { transform: none; }
.seed-icon { flex: none; width: 44px; height: 44px; object-fit: contain; }
.seed-icon-fb { flex: none; width: 44px; font-size: 30px; text-align: center; }
.seed-info { flex: 1; min-width: 0; }
.seed-name-row {
  display: flex; align-items: baseline; gap: 6px;
  font-weight: 800; font-size: 13px;
}
.seed-cost { margin-left: auto; font-family: var(--px-font); font-weight: 800; font-size: 13px; color: var(--pink-500); white-space: nowrap; }
.seed-card:disabled .seed-cost { color: #b39d92; }
.seed-grow { font-family: var(--px-font); font-size: 10px; font-weight: 800; color: var(--ink-soft); }
.seed-desc { margin-top: 2px; font-size: 11px; line-height: 1.5; color: var(--ink-soft); }

/* story 档暂无专属种子袋图：starlight 图换个调色（v36 后仅存的故事档特殊处理） */
.seed-icon-story { filter: hue-rotate(300deg) saturate(1.3) brightness(1.05); }
/* v36 每档概率行：像素小字，UR 段金色 */
.seed-rates {
  margin-top: 3px;
  display: flex; gap: 8px;
  font-family: var(--px-font); font-size: 9px; font-weight: 800;
  color: #6b4bb3;
  white-space: nowrap;
}
.rate-seg.rate-ur { color: #b8860b; text-shadow: 0 0 4px rgba(245,179,1,.55); }

/* ============================================================
   收获特效
   ============================================================ */
.fx-layer {
  position: fixed; inset: 0; z-index: 50;
  display: flex; align-items: center; justify-content: center;
  padding: 24px 20px;
  background: rgba(124,74,74,.45);
}
.fx-glow { position: absolute; inset: 0; pointer-events: none; }
.fx-layer.r-common .fx-glow {
  background: radial-gradient(circle at 50% 44%, rgba(255,255,255,.85), rgba(255,255,255,.25) 34%, transparent 62%);
  animation: glow-in .5s ease-out;
}
.fx-layer.r-rare .fx-glow {
  background: radial-gradient(circle at 50% 44%, rgba(196,181,253,.95), rgba(167,139,250,.4) 38%, transparent 68%);
  animation: glow-pulse 1.4s ease-in-out infinite;
}
.fx-layer.r-legendary .fx-glow {
  background:
    radial-gradient(circle at 50% 44%, rgba(255,236,170,.98), rgba(245,179,1,.5) 42%, rgba(245,179,1,.18) 75%),
    linear-gradient(rgba(245,179,1,.14), rgba(245,179,1,.14));
  animation: glow-pulse 1s ease-in-out infinite;
}
@keyframes glow-in { from { opacity: 0; } }
@keyframes glow-pulse { 0%,100% { opacity: .8; } 50% { opacity: 1; } }

.fx-spark {
  position: absolute; font-size: 18px; pointer-events: none;
  animation: spark-float 1.5s ease-in-out infinite;
}
@keyframes spark-float {
  0%,100% { transform: translateY(0) scale(1); opacity: .9; }
  50% { transform: translateY(-12px) scale(1.25); opacity: 1; }
}

.fx-card {
  position: relative; width: 100%; max-width: 300px;
  background: var(--cream);
  border: 3px solid var(--cocoa);
  box-shadow: 6px 6px 0 rgba(124,74,74,.45);
  padding: 22px 16px 16px; text-align: center;
  animation: card-pop .4s cubic-bezier(.3,1.6,.5,1);
}
@keyframes card-pop { from { transform: scale(.4); opacity: 0; } }
.fx-card .m-sprite {
  width: 110px; height: 110px; object-fit: contain; margin: 2px auto 8px; display: block;
  animation: sprite-pop .55s cubic-bezier(.3,1.8,.5,1);
}
@keyframes sprite-pop { 0% { transform: scale(0); } 70% { transform: scale(1.18); } 100% { transform: scale(1); } }
.fx-title { font-size: 12px; color: var(--ink-soft); margin: 0 0 4px; }
.fx-name { font-family: var(--px-font); font-size: 20px; font-weight: 800; margin: 0 0 8px; }
.fx-new {
  position: absolute; top: -12px; left: -10px; transform: rotate(-8deg);
  font-family: var(--px-font); font-size: 13px; font-weight: 800;
  background: var(--gold); color: #6b4b00;
  border: 3px solid var(--cocoa); padding: 3px 8px;
  box-shadow: 2px 2px 0 rgba(124,74,74,.4);
  animation: new-blink .8s steps(2) infinite;
}
@keyframes new-blink { 50% { background: #ffd95e; } }
.fx-rar { display: inline-block; font-family: var(--px-font); font-size: 11px; font-weight: 800;
  padding: 2px 8px; border: 2px solid var(--cocoa); color: #fff; margin-bottom: 6px; }
.fx-rar.r-common { background: #b8a8a0; }
.fx-rar.r-rare { background: var(--violet); }
.fx-rar.r-legendary { background: var(--gold); color: #6b4b00; }

/* ----- 故事卡揭晓 ----- */
.fx-card-story { max-width: 320px; }
.fx-card-art {
  width: 150px; height: 150px;
  margin: 4px auto 10px;
  display: flex; align-items: center; justify-content: center;
  background: #fff;
  border: 3px solid var(--cocoa);
  box-shadow: 3px 3px 0 rgba(124,74,74,.35);
  overflow: hidden;
  animation: sprite-pop .55s cubic-bezier(.3,1.8,.5,1);
}
.fx-card-art img { display: block; width: 100%; height: 100%; object-fit: cover; }
.fx-card-art.r-rare { box-shadow: 0 0 0 2px var(--violet), 3px 3px 0 rgba(124,74,74,.35); }
.fx-card-art.r-legendary { box-shadow: 0 0 0 2px var(--gold), 0 0 12px rgba(245,179,1,.7), 3px 3px 0 rgba(124,74,74,.35); }
.fx-card-emoji { font-size: 72px; line-height: 1; }
.fx-flavor {
  margin: 4px 0 8px;
  font-size: 12px; line-height: 1.7; color: var(--cocoa);
  font-style: italic;
}
.fx-rar-card.rc-R   { background: #b8a8a0; }
.fx-rar-card.rc-SR  { background: var(--violet); }
.fx-rar-card.rc-SSR { background: var(--gold); color: #6b4b00; }
.fx-rar-card.rc-UR  {
  background: linear-gradient(90deg, var(--gold), var(--pink-400), var(--violet));
  color: #fff; text-shadow: 1px 1px 0 rgba(94,53,53,.5);
}

/* ----- v36 UR 三色流光揭晓 ----- */
.fx-layer.r-ur .fx-glow {
  background:
    radial-gradient(circle at 50% 44%, rgba(255,236,170,.95), rgba(244,114,182,.42) 36%, rgba(167,139,250,.28) 58%, transparent 78%),
    linear-gradient(rgba(245,179,1,.1), rgba(167,139,250,.12));
  animation: glow-ur 2.4s linear infinite;
}
@keyframes glow-ur {
  0%, 100% { filter: hue-rotate(0deg); opacity: .9; }
  33% { filter: hue-rotate(25deg); opacity: 1; }
  66% { filter: hue-rotate(-25deg); opacity: 1; }
}
.fx-card-art.r-ur {
  box-shadow: 0 0 0 2px var(--gold), 0 0 6px rgba(244,114,182,.8), 0 0 14px rgba(167,139,250,.8), 3px 3px 0 rgba(124,74,74,.35);
}

/* ----- v36 揭晓卡加料：像素版角标 + 图鉴新卡行 ----- */
.fx-card-art { position: relative; }
.fx-pixel-tag {
  position: absolute; left: -2px; bottom: -2px; z-index: 4; /* v45 同稀有度角标：压过卡框内线 */
  font-family: var(--px-font); font-size: 9px; font-weight: 800;
  color: #fff; background: var(--cocoa);
  border: 2px solid var(--cocoa);
  padding: 1px 5px; line-height: 1.3;
  image-rendering: pixelated;
}
.fx-newcard {
  margin: 0 0 6px;
  font-family: var(--px-font); font-size: 13px; font-weight: 800;
  color: #b8860b;
  animation: newcard-blink .8s steps(2) infinite;
}
@keyframes newcard-blink { 50% { opacity: .55; } }
/* 像素画风缩略/大图统一硬边缩放 */
.fx-card-art img, .px-cell img { image-rendering: pixelated; }
/* 降级链落到原版画时不硬边（原版是高清画） */
img.art-orig { image-rendering: auto; }

/* ----- v39 神秘揭晓：卡片收下之后追加的一幕，全屏柔白微光 ----- */
.fx-layer.fx-mystery .fx-glow {
  background: radial-gradient(circle at 50% 46%,
    rgba(255,255,255,.95), rgba(214,196,255,.5) 40%, rgba(140,120,200,.18) 68%, transparent 86%);
  animation: glow-pulse 1.6s ease-in-out infinite;
}
.fx-card-mystery { max-width: 300px; padding-top: 26px; }
.fx-mystery-name { color: #6b4bb3; }

/* ----- v39 收获揭晓「边框升级！」行 ----- */
.fx-frameup {
  margin: 0 0 6px;
  font-family: var(--px-font); font-size: 13px; font-weight: 800;
  color: #8a5732;
  animation: newcard-blink .8s steps(2) infinite;
}

/* ============================================================
   v39 像素卡框（frameLevel 1-4 = 铜/银/彩/金；0 素框走现有 cocoa 细边）
   全部像素风直角：双线用 ::after 叠内线（img 在背景上方，inset shadow 会被盖住）
   放在 fx-card-art 稀有度描边之后，同权重靠后者胜出，框一律压过稀有度光圈
   ============================================================ */
/* 铜框：#b87b4a 双线 */
.px-cell.fl-1, .fx-card-art.fl-1 { border-color: #b87b4a; }
.px-cell.fl-1 { box-shadow: 2px 2px 0 rgba(124,74,74,.2); }
.fx-card-art.fl-1 { box-shadow: 3px 3px 0 rgba(124,74,74,.35); }
.px-cell.fl-1::after, .fx-card-art.fl-1::after {
  content: ""; position: absolute; inset: 2px; pointer-events: none; z-index: 3;
  box-shadow: inset 0 0 0 2px #b87b4a;
}
/* 银框：#c8d4e0 双线微光 */
.px-cell.fl-2, .fx-card-art.fl-2 { border-color: #9fb2c4; }
.px-cell.fl-2 { box-shadow: 0 0 6px rgba(200,212,224,.85), 2px 2px 0 rgba(124,74,74,.2); }
.fx-card-art.fl-2 { box-shadow: 0 0 6px rgba(200,212,224,.85), 3px 3px 0 rgba(124,74,74,.35); }
.px-cell.fl-2::after, .fx-card-art.fl-2::after {
  content: ""; position: absolute; inset: 2px; pointer-events: none; z-index: 3;
  box-shadow: inset 0 0 0 2px #c8d4e0;
}
/* 彩框：四色渐变描边（border-image，直角不圆润） */
.px-cell.fl-3, .fx-card-art.fl-3 {
  border-color: transparent;
  border-image: linear-gradient(135deg, #f5b301, #f472b6, #a78bfa, #6ec6ff) 1;
}
.px-cell.fl-3 { box-shadow: 2px 2px 0 rgba(124,74,74,.2); }
.fx-card-art.fl-3 { box-shadow: 3px 3px 0 rgba(124,74,74,.35); }
/* 金框：#f5b301 粗边 + 微光呼吸（收敛档，不做大特效） */
.px-cell.fl-4 { border: 3px solid #f5b301; animation: frame-gold-breathe 2.2s ease-in-out infinite; }
.fx-card-art.fl-4 { border: 4px solid #f5b301; animation: frame-gold-breathe-lg 2.2s ease-in-out infinite; }
@keyframes frame-gold-breathe {
  0%, 100% { box-shadow: 0 0 3px rgba(245,179,1,.4), 2px 2px 0 rgba(124,74,74,.2); }
  50%      { box-shadow: 0 0 8px rgba(245,179,1,.8), 2px 2px 0 rgba(124,74,74,.2); }
}
@keyframes frame-gold-breathe-lg {
  0%, 100% { box-shadow: 0 0 3px rgba(245,179,1,.4), 3px 3px 0 rgba(124,74,74,.35); }
  50%      { box-shadow: 0 0 9px rgba(245,179,1,.85), 3px 3px 0 rgba(124,74,74,.35); }
}

/* ============================================================
   toast
   ============================================================ */
.toast {
  position: fixed; left: 50%; bottom: calc(64px + env(safe-area-inset-bottom));
  transform: translateX(-50%);
  z-index: 60; max-width: 86vw;
  background: var(--cocoa); color: #fff;
  font-size: 13px; line-height: 1.6; text-align: center;
  border: 2px solid #5e3535;
  box-shadow: 3px 3px 0 rgba(94,53,53,.5);
  padding: 9px 14px;
  animation: toast-in .2s ease-out;
}
@keyframes toast-in { from { transform: translate(-50%, 10px); opacity: 0; } }

/* ============ v32 拖放互动系统 ============ */
/* 拖拽悬停在可投放目标上方：目标轻微高亮（放下前的预告，纯 class 切换） */
.drop-hint {
  filter: brightness(1.28) drop-shadow(0 0 6px rgba(255, 250, 190, 0.85));
}
/* 建筑有自己的 hover transform：高亮别叠加位移，只提亮 */
.bld.drop-hint { filter: brightness(1.22) drop-shadow(0 0 8px rgba(255, 250, 190, 0.8)); }
/* 水域高亮走旋涡：冷色调水光 */
.vortex.drop-hint { filter: brightness(1.35) drop-shadow(0 0 8px rgba(160, 220, 255, 0.9)); }
/* v43 小窝高亮：暖光提亮（拖耶耶悬停 = 要放进被窝的预告）；双类选择器压过夜间调光规则 */
.dogbed.drop-hint { filter: brightness(1.3) drop-shadow(0 0 8px rgba(255, 235, 190, 0.85)); }

/* 投放到 bloom 地块：一次性发光强调"快收！"（JS 挂 2s 后摘） */
.plot.drop-flash { animation: drop-flash-pulse 0.66s ease-in-out 3; }
@keyframes drop-flash-pulse {
  0%, 100% { filter: none; }
  50% { filter: brightness(1.55) drop-shadow(0 0 7px rgba(255, 240, 150, 0.95)); }
}

/* 横屏 / 桌面：改为定高居中整景展示（不然 cover 会把上下裁掉太多） */
@media (orientation: landscape) {
  .stage {
    width: 66.67vh; height: 100vh;
    width: 66.67dvh; height: 100dvh;
  }
}

/* 窄屏兜底 */
@media (max-width: 340px) {
  .hud-title { font-size: 12px; }
  .dex-grid { grid-template-columns: repeat(2, 1fr); }
  .plot-label { font-size: 10px; }
}

/* ============================================================
   v34 缝合二期：长按聊天输入条 / 思考三点 / 晚安双选 / 冒险木牌
   ============================================================ */

/* ---------- 长按耶耶：底部滑出像素输入条（农场风 cocoa 边框+像素投影） ---------- */
.chat-bar {
  position: fixed;
  left: 50%; bottom: calc(14px + env(safe-area-inset-bottom, 0px));
  transform: translateX(-50%);
  z-index: 55; /* 抽屉(31)/弹窗(40)之上、toast(60)之下 */
  width: min(94vw, 460px);
  background: var(--cream);
  border: 3px solid var(--cocoa);
  box-shadow: 4px 4px 0 rgba(94,53,53,.4);
  padding: 10px 12px;
  animation: chatbar-in .22s ease-out;
}
@keyframes chatbar-in {
  from { transform: translate(-50%, 28px); opacity: 0; }
}
.chat-bar-top {
  display: flex; justify-content: space-between; align-items: center;
  margin-bottom: 7px;
}
.chat-bar-title {
  font-family: var(--px-font); font-weight: 800; font-size: 11px;
  color: var(--ink-soft);
}
.chat-bar-close {
  width: 24px; height: 24px; padding: 0;
  font-family: var(--px-font); font-weight: 800; font-size: 12px; line-height: 1;
  color: var(--cocoa); background: var(--cream);
  border: 2px solid var(--cocoa);
  box-shadow: 2px 2px 0 rgba(94,53,53,.35);
  cursor: pointer;
}
.chat-bar-close:active { transform: translate(1px,1px); box-shadow: 0 0 0; }
.chat-bar-row { display: flex; gap: 7px; align-items: stretch; }
.chat-bar-input {
  flex: 1; min-width: 0;
  font-family: var(--px-font); font-weight: 700; font-size: 14px;
  color: var(--cocoa); background: #fff;
  border: 2px solid var(--cocoa); border-radius: 0;
  padding: 8px 9px;
  outline: none;
  -webkit-appearance: none;
}
.chat-bar-input:focus { border-color: var(--pink-500); }
.chat-bar-input::placeholder { color: var(--ink-soft); opacity: .7; }
.chat-bar-send { white-space: nowrap; }
.chat-bar-link {
  display: inline-block;
  margin-top: 7px;
  font-family: var(--px-font); font-weight: 800; font-size: 11px;
  color: var(--ink-soft);
  text-decoration: underline;
}

/* ---------- 等回复：头顶"…"像素三点跳动小气泡 ---------- */
.bubble.thinking {
  min-width: 36px;
  padding: 8px 9px 6px;
}
.bubble.thinking i {
  display: inline-block;
  width: 5px; height: 5px;
  margin: 0 2px;
  background: var(--cocoa);
  animation: think-dot .9s infinite;
}
.bubble.thinking i:nth-child(2) { animation-delay: .18s; }
.bubble.thinking i:nth-child(3) { animation-delay: .36s; }
@keyframes think-dot {
  0%, 55%, 100% { transform: translateY(0); }
  28%           { transform: translateY(-4px); }
}

/* ---------- 晚安双选迷你气泡（点睡着的耶耶弹出，点旁白关闭） ---------- */
.gn-menu {
  position: absolute;
  bottom: calc(100% + 8px); left: 50%;
  transform: translateX(-50%);
  z-index: 8;
  width: max-content;
  text-align: center;
  background: var(--cream);
  border: 2px solid var(--cocoa);
  box-shadow: 3px 3px 0 rgba(94,53,53,.35);
  padding: 8px 9px;
  animation: bubble-in .18s ease-out;
}
.gn-menu::after {
  content: ""; position: absolute;
  bottom: -8px; left: 50%; transform: translateX(-50%);
  border: 4px solid transparent; border-top-color: var(--cocoa);
}
.walker.flip .gn-menu { transform: translateX(-50%); } /* 同 .bubble：翻面不跟着镜像 */
.gn-tip {
  font-family: var(--px-font); font-weight: 800; font-size: 11px;
  color: var(--ink-soft);
  margin-bottom: 6px;
}
.gn-btns { display: flex; gap: 6px; justify-content: center; }
.gn-menu .px-btn { font-size: 12px; padding: 6px 10px; }

/* ---------- 冒险离家：空农场的像素木牌（溜达区中央，复用 plant-sign 风） ---------- */
.away-sign {
  position: absolute;
  left: 50%; top: 70%;
  transform: translate(-50%, -50%);
  z-index: 5;
  /* 木牌图 873x806 原生分辨率（不缩放不插值——像素画一 resize 就糊）；
     显示宽取耶耶的 2.2 倍 */
  width: clamp(140px, 31%, 185px);
  aspect-ratio: 1086 / 876;
  background: url('sprites/farm/signboard.png?v=4') center / 100% 100% no-repeat;
  image-rendering: pixelated;
  animation: bubble-in .18s ease-out;
}
/* 文字层：绝对定位落在牌面区内（实测木板占纵 8%~69%），不靠 padding 猜 */
.away-sign > span {
  position: absolute;
  left: 8%; right: 8%; top: 17%; bottom: 40%;  /* 新API木牌实测：板区 y10.2%~66.2%，内缩躲描边与钉 */
  display: flex; align-items: center; justify-content: center;
  text-align: center;
  white-space: pre-line;
  font-family: var(--px-font); font-weight: 800; font-size: 12px;
  line-height: 1.55;
  color: #4a2e14;
  text-shadow: 0 1px 0 rgba(255,238,205,.55);
}
/* 图挂了退回纯 CSS 木牌 */
.away-sign.no-img {
  width: auto; max-width: 230px; aspect-ratio: auto;
  background: #e9c69c;
  border: 3px solid var(--cocoa);
  box-shadow: 3px 3px 0 rgba(94,53,53,.35), inset 0 -4px 0 rgba(169,122,88,.45);
  padding: 9px 11px;
}
.away-sign.no-img > span {
  position: static; display: block; color: var(--cocoa); text-shadow: none;
}

/* hidden 属性必须赢过任何显式 display（否则 overlay/fx 层空壳白条上位） */
[hidden] { display: none !important; }

/* ============================================================
   v35 左上角宠物状态牌（饱食度/心情迷你像素条）
   ============================================================ */
.pet-hud {
  position: fixed;
  left: 12px; top: calc(58px + env(safe-area-inset-top));
  z-index: 20;
  display: flex; flex-direction: column; gap: 5px;
  align-items: flex-start;
  padding: 6px 8px;
  background: var(--cream);
  border: 3px solid var(--cocoa);
  box-shadow: 2px 2px 0 rgba(94,53,53,.4);
  cursor: pointer; touch-action: manipulation;
}
.pet-hud:active { transform: translate(1px,1px); box-shadow: 1px 1px 0 rgba(94,53,53,.4); }
.ph-row { display: flex; align-items: center; gap: 5px; }
.pet-hud.away .ph-row { display: none; } /* 冒险离家：收起条只留字 */
.ph-ico { display: block; width: 14px; height: 14px; }
/* 像素小心形：2px 网格 box-shadow 手画（7x6 格） */
.ph-heart { position: relative; display: block; width: 14px; height: 12px; flex: none; }
.ph-heart::before {
  content: ""; position: absolute; left: 0; top: 0;
  width: 2px; height: 2px; background: transparent;
  box-shadow:
    2px 0 var(--pink-500), 4px 0 var(--pink-500), 8px 0 var(--pink-500), 10px 0 var(--pink-500),
    0 2px var(--pink-500), 2px 2px var(--pink-300), 4px 2px var(--pink-500), 6px 2px var(--pink-500),
    8px 2px var(--pink-500), 10px 2px var(--pink-500), 12px 2px var(--pink-500),
    0 4px var(--pink-500), 2px 4px var(--pink-500), 4px 4px var(--pink-500), 6px 4px var(--pink-500),
    8px 4px var(--pink-500), 10px 4px var(--pink-500), 12px 4px var(--pink-500),
    2px 6px var(--pink-500), 4px 6px var(--pink-500), 6px 6px var(--pink-500),
    8px 6px var(--pink-500), 10px 6px var(--pink-500),
    4px 8px var(--pink-500), 6px 8px var(--pink-500), 8px 8px var(--pink-500),
    6px 10px var(--pink-500);
}
/* 分段条：.pbar 同款 10 段小格 */
.ph-bar { display: flex; gap: 1px; }
.ph-bar i { width: 5px; height: 6px; background: var(--pink-200); }
.ph-bar i.on { background: var(--pink-500); }
.ph-bar.low i.on { background: #f0913f; } /* 低于 40：警示暖橙 */
.ph-away {
  font-family: var(--px-font); font-weight: 800; font-size: 11px;
  color: var(--cocoa); letter-spacing: .05em;
}
/* 点状态牌弹出的文字版迷你气泡 */
.ph-pop {
  position: absolute;
  top: calc(100% + 8px); left: 0;
  display: block;
  width: max-content; max-width: 210px;
  font-size: 11px; line-height: 1.6; text-align: left;
  font-family: var(--px-font); font-weight: 800;
  color: var(--cocoa); background: var(--cream);
  border: 2px solid var(--cocoa);
  box-shadow: 2px 2px 0 rgba(94,53,53,.35);
  padding: 5px 8px;
  white-space: normal;
  animation: bubble-in .18s ease-out;
  pointer-events: none;
}
.ph-pop::after {
  content: ""; position: absolute;
  top: -8px; left: 14px;
  border: 4px solid transparent; border-bottom-color: var(--cocoa);
}

/* ============================================================
   v35 睡眠系统：被踹开的被子团 + 翻身微动
   ============================================================ */
.blanket-off {
  position: absolute;
  width: 7%; min-width: 30px; max-width: 60px; /* 96px 素材 ≈ 耶耶(14%)半宽 */
  z-index: 6; /* 耶耶(z7)之下、场景道具(z4-5)之上 */
  transform: translate(-50%, -50%);
  cursor: grab; touch-action: none; /* 拖被子期间不让页面滚 */
}
.blanket-off img {
  display: block; width: 100%; height: auto;
  animation: blanket-breathe 3s ease-in-out infinite; /* 不拖时轻微起伏呼吸感 */
  -webkit-user-drag: none; user-drag: none;
}
@keyframes blanket-breathe { 50% { transform: scale(1.04, .95); } }
.blanket-off.grabbed { cursor: grabbing; z-index: 10; }
.blanket-off.grabbed img { animation: none; }
.blanket-off.snap { transition: left .3s cubic-bezier(.3,1.4,.5,1), top .3s cubic-bezier(.3,1.4,.5,1); }
.stage.is-night .blanket-off { filter: brightness(.85); }
/* 踹被前的小翻身：一次性挂 .turnover，520ms 后 JS 摘掉 */
.walker.turnover .walker-body { animation: turn-wiggle .5s ease-in-out; }
@keyframes turn-wiggle {
  25% { transform: rotate(-5deg); }
  70% { transform: rotate(4deg); }
}
