/* 🌷 主界面那盆花 —— 与花生同一套像素语言:同样的墨线、纸面、像素描边(--pet-* 变量来自 pet.css)。
   24×32 像素画按 2× 显示 = 48×64;动作动画全部用 steps() 保持像素感。 */

/* ---------- 实体 ---------- */
.plant-float {
  left: 10px;
  bottom: calc(env(safe-area-inset-bottom, 0px) + 86px);
  width: 48px; height: 64px;
  align-items: flex-end; justify-content: center;
  z-index: 40;
  cursor: grab;
  -webkit-tap-highlight-color: transparent;
  -webkit-touch-callout: none;
  user-select: none; -webkit-user-select: none;
  transition: opacity .22s ease, visibility 0s linear 0s;
}
/* 各皮肤给 .fab-float 的圆钮外观对它无效 */
html .fab-float.plant-float, html[data-theme] .fab-float.plant-float {
  width: 48px; height: 64px; padding: 0; border: 0; border-radius: 0;
  background: none; box-shadow: none; backdrop-filter: none; -webkit-backdrop-filter: none;
}
.plant-float:active { transform: none; }
.plant-float:focus-visible { outline: 3px dashed var(--pet-accent, #3B5B7A); outline-offset: 4px; }
.plant-float.held .px-cv { transform: translateY(-2px); }

.px-cv {
  display: block; width: 48px; height: 64px;
  image-rendering: pixelated; image-rendering: crisp-edges;
  transform-origin: 50% 100%;
  filter: drop-shadow(0 3px 0 var(--pet-shadow, rgba(30, 37, 41, .16)));
}
/* 晒饱了:叶子边缘一圈暖光;正在阳光里:光更亮 */
.plant-float.is-sunny .px-cv { filter: drop-shadow(0 3px 0 var(--pet-shadow, rgba(30,37,41,.16))) drop-shadow(0 0 3px rgba(255, 206, 77, .55)); }
.plant-float.in-sun .px-cv { filter: drop-shadow(0 3px 0 var(--pet-shadow, rgba(30,37,41,.16))) drop-shadow(0 0 6px rgba(255, 200, 60, .85)); }

/* 不再常驻留白(用户:「最后一行文字下面一块空白……没必要留」):花盆蹲在输入栏上沿。
   只有它说话 / 展开菜单的那几秒,临时给消息列表底部让位(与花生同一套 ::after,取 min-height 叠加),说完收回 */
/* (r14) 花的气泡/菜单让位改由 world.js Porch.need 统一计算(以前 min-height 被门廊 padding 吞掉,菜单盖住最后一条消息) */

/* 往上翻 / 浮层打开时整株藏起来 */
.plant-float.plant-dim, html.pet-scrolled .plant-float {
  opacity: 0; visibility: hidden; pointer-events: none; transition: opacity .22s ease, visibility 0s linear .22s;
}
body.pet-card-open .plant-float, body.garden-open .plant-float, body.sticker-open .plant-float { visibility: hidden; }
.lock-screen:not(.hidden) ~ .plant-menu, #page-login.active ~ .plant-menu, body.ws-busy .plant-menu { display: none !important; }

/* ---------- 需求小牌(想喝水 / 想晒太阳):8×8 像素图标,和花生头顶的心情牌同款 ---------- */
.plant-need {
  position: absolute; left: 50%; top: var(--need-top, -14px);   /* --need-top 由 plant.js 按植株实际顶端算 */ margin-left: -10px; width: 20px; height: 20px;
  pointer-events: none; background: #FCE3B8 center / 16px 16px no-repeat;
  box-shadow: var(--pet-frame, 0 0 0 2px #2B1C14), 0 2px 0 0 var(--pet-shadow, rgba(0,0,0,.18));
  image-rendering: pixelated;
}
.plant-need[data-need="thirsty"], .plant-need[data-need="thirsty-bad"] {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8' shape-rendering='crispEdges'%3E%3Cpath fill='%233B8FD0' d='M3 0h2v1h1v2h1v3H6v1H2V6H1V3h1V1h1z'/%3E%3Cpath fill='%23BFE3F5' d='M2 4h1v1H2z'/%3E%3C/svg%3E");
}
.plant-need[data-need="thirsty-bad"] { background-color: #F6C3B8; }
.plant-need[data-need="sun"] {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8' shape-rendering='crispEdges'%3E%3Cpath fill='%23E7A92A' d='M3 0h2v1H3zM0 3h1v2H0zM7 3h1v2H7zM3 7h2v1H3z'/%3E%3Cpath fill='%23FFD24A' d='M2 2h4v4H2z'/%3E%3Cpath fill='%23FFF1B8' d='M3 3h1v1H3z'/%3E%3C/svg%3E");
}

/* ---------- 头顶小气泡(与花生头顶气泡同款) ---------- */
.plant-say {
  position: absolute; left: 50%; bottom: calc(100% + 18px);
  transform: translateX(calc(-30% + var(--say-dx, 0px)));
  width: max-content; max-width: 168px;
  padding: 6px 9px; z-index: 2;
  background: var(--pet-paper-2, #fff); color: var(--pet-text, #1E2529);
  font-size: 13px; font-weight: 700; line-height: 1.45; line-break: strict;
  box-shadow: var(--pet-frame, 0 0 0 3px #2E4256), 0 calc(var(--pet-px, 3px) * 2) 0 0 var(--pet-shadow, rgba(30,37,41,.16));
  pointer-events: none; white-space: normal;
}
.plant-say::after {   /* 像素小尾巴,指向花 */
  content: ''; position: absolute; left: calc(30% - var(--say-dx, 0px)); top: calc(100% + var(--pet-px, 3px));
  width: 6px; height: 6px; background: var(--pet-line, #2E4256);
  box-shadow: 3px -3px 0 0 var(--pet-paper-2, #fff), 0 -3px 0 0 var(--pet-line, #2E4256);
}
/* 有需求小牌时气泡往上让(气泡在 DOM 里排在小牌之前,不能用 ~ 选择器;JS 给实体加 has-need) */
.plant-float.has-need .plant-say { bottom: calc(100% - var(--need-top, -14px) + 6px); }   /* 气泡底边在小牌顶上 6px */
/* 说话期间抬到花生(z41)之上,气泡不会被花生头顶的气泡压住 */
.plant-float.saying { z-index: 42; }
.plant-say.pop { animation: px-say-pop .18s steps(2, jump-none); }
@keyframes px-say-pop { from { transform: translateX(calc(-30% + var(--say-dx, 0px))) scale(.82); } to { transform: translateX(calc(-30% + var(--say-dx, 0px))) scale(1); } }
html.pet-scrolled .plant-say, body.pet-card-open .plant-say, body.sticker-open .plant-say { display: none !important; }

/* ---------- 动作动画 ---------- */
.plant-float.px-perk .px-cv   { animation: px-perk .5s steps(3, jump-none); }
@keyframes px-perk   { 40% { transform: translateY(-4px) scaleY(1.04); } }
.plant-float.px-water .px-cv  { animation: px-water 1.3s steps(6, jump-none); }
@keyframes px-water  { 0% { transform: scaleY(.94); } 30% { transform: scaleY(.92); } 60% { transform: translateY(-3px) scaleY(1.06); } 100% { transform: none; } }
.plant-float.px-fert .px-cv   { animation: px-fert 1.5s steps(6, jump-none); }
@keyframes px-fert   { 25% { transform: translateY(-2px); filter: brightness(1.15) drop-shadow(0 0 4px rgba(150, 230, 120, .9)); } 60% { transform: translateY(-5px) scaleY(1.05); } }
.plant-float.px-sun .px-cv    { animation: px-sun 1.5s steps(5, jump-none); }
@keyframes px-sun    { 50% { filter: brightness(1.12) drop-shadow(0 0 8px rgba(255, 205, 70, .95)); } }
.plant-float.px-wiggle .px-cv { animation: px-wiggle .6s steps(4, jump-none); }
@keyframes px-wiggle { 25% { transform: rotate(-6deg); } 75% { transform: rotate(6deg); } }
.plant-float.px-bloom .px-cv  { animation: px-bloom 1.4s steps(5, jump-none); }
@keyframes px-bloom  { 30% { transform: scale(1.1); } 60% { transform: scale(.98); } }

/* 像素小特效:水滴 / 肥料闪光 / 阳光 / 花瓣 */
.px-fx { position: absolute; pointer-events: none; width: 3px; height: 3px; opacity: 0; }
.px-fx.drop  { top: -10px; width: 3px; height: 5px; background: #3B8FD0; box-shadow: 0 -1px 0 #BFE3F5 inset; animation: px-drop 1s steps(5, jump-none) forwards; }
@keyframes px-drop  { 0% { opacity: 1; transform: translateY(0); } 100% { opacity: 0; transform: translate(var(--dx, 0), 46px); } }
.px-fx.spark { bottom: 22px; background: #8FD46B; box-shadow: 3px 0 0 #FFE9A8, -3px 0 0 #FFE9A8, 0 3px 0 #FFE9A8, 0 -3px 0 #FFE9A8; animation: px-spark 1.3s steps(6, jump-none) forwards; }
@keyframes px-spark { 0% { opacity: 1; transform: translateY(0) scale(.6); } 100% { opacity: 0; transform: translate(var(--dx, 0), -40px) scale(1); } }
.px-fx.ray   { top: -18px; width: 2px; height: 10px; background: #FFD24A; animation: px-ray 1.4s steps(4, jump-none) forwards; }
@keyframes px-ray   { 0% { opacity: 0; } 30% { opacity: .9; } 100% { opacity: 0; transform: translateY(14px); } }
.px-fx.petal { top: 4px; width: 4px; height: 3px; background: #FF8FB0; animation: px-petal 1.4s steps(7, jump-none) forwards; }
@keyframes px-petal { 0% { opacity: 1; transform: translate(0, 0) rotate(0); } 100% { opacity: 0; transform: translate(calc(var(--dx, 0) * 3), -30px) rotate(90deg); } }

/* ---------- 花生来互动时的反应(远看也读得出:每种一个动作 + 一个像素小符号) ---------- */
.plant-float.px-rustle  .px-cv { animation: px-rustle .9s steps(6, jump-none); }
@keyframes px-rustle  { 15%, 55% { transform: rotate(-4deg) translateX(-1px); } 35%, 75% { transform: rotate(4deg) translateX(1px); } }
.plant-float.px-startle .px-cv { animation: px-startle .8s steps(5, jump-none); }
@keyframes px-startle { 20% { transform: translateY(-10px) scale(.94, 1.08); } 45% { transform: translateY(0) scale(1.1, .88); } 70% { transform: scale(.97, 1.03); } }
.plant-float.px-shiver  .px-cv { animation: px-shiver .9s steps(9, jump-none); }
@keyframes px-shiver  { 0%, 100% { transform: none; } 10%, 30%, 50%, 70% { transform: translateX(-2px); } 20%, 40%, 60%, 80% { transform: translateX(2px); } }
.plant-float.px-lean    .px-cv { animation: px-lean 1.4s steps(5, jump-none); }
@keyframes px-lean    { 30%, 70% { transform: rotate(var(--lean, 7deg)); } }
.plant-float.px-hop     .px-cv { animation: px-hop .7s steps(4, jump-none); }
@keyframes px-hop     { 40% { transform: scale(1.06, .92); } 70% { transform: scale(.96, 1.05); } }
.px-fx.dust { bottom: 0; width: 4px; height: 3px; background: var(--pet-shadow, rgba(120, 90, 60, .45)); animation: px-dust .7s steps(4, jump-none) forwards; }
@keyframes px-dust { 0% { opacity: .9; transform: translate(0, 0); } 100% { opacity: 0; transform: translate(calc(var(--dx, 0) * 2), -6px); } }
.px-mark {
  position: absolute; left: 50%; top: -26px; margin-left: -8px; width: 16px; height: 16px; pointer-events: none;
  background: center / 16px 16px no-repeat; image-rendering: pixelated;
  animation: px-mark 1.2s steps(6, jump-none) forwards;
}
@keyframes px-mark { 0% { opacity: 0; transform: translateY(4px) scale(.7); } 20% { opacity: 1; transform: translateY(0) scale(1); } 80% { opacity: 1; } 100% { opacity: 0; transform: translateY(-6px); } }
.plant-float.has-mark .plant-need { visibility: hidden; }   /* 「!」「?」小符号出现时让开需求小牌,别叠在一起 */
.px-mark.q { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8' shape-rendering='crispEdges'%3E%3Cpath fill='%232B1C14' d='M2 0h4v1h1v2H6v1H5v1H3V3h1V2h1V1H3v1H1V1h1zM3 6h2v2H3z'/%3E%3C/svg%3E"); }
.px-mark.ex { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8' shape-rendering='crispEdges'%3E%3Cpath fill='%23E5484D' d='M3 0h2v5H3zM3 6h2v2H3z'/%3E%3C/svg%3E"); }
.px-mark.heart { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8' shape-rendering='crispEdges'%3E%3Cpath fill='%23EF6B7B' d='M1 1h2v1h2V1h2v1h1v2H7v1H6v1H5v1H3V6H2V5H1V4H0V2h1z'/%3E%3Cpath fill='%23FFD3DA' d='M2 2h1v1H2z'/%3E%3C/svg%3E"); }

@media (prefers-reduced-motion: reduce) {
  .plant-float .px-cv, .plant-say.pop, .px-fx, .px-mark { animation: none !important; }
  .px-fx { display: none; }
}

/* ---------- r10(第 9 轮评审 #5/#6/#13) ---------- */
/* 拿到花的状态之前不露面:否则只有地面影子 + 空画布,却会说「晒晒太阳真舒服」 */
.plant-float.plant-pending { visibility: hidden !important; pointer-events: none !important; }
/* 菜单与花生菜单同一套「像素图标 + 文字」格(.pet-menu-grid / .pet-mtile 来自 pet.css) */
.pet-menu.plant-menu.cols-3 { width: 228px; }
.pet-menu.plant-menu.cols-2 { width: 156px; }
.plant-menu .plant-mgrid { grid-template-columns: repeat(3, 1fr); }
.plant-menu.cols-2 .plant-mgrid { grid-template-columns: repeat(2, 1fr); }
/* 5 项:6 栏网格,每格占 2 栏;第二行两格整体居中 */
.plant-menu.odd-row .plant-mgrid { grid-template-columns: repeat(6, 1fr); }
.plant-menu.odd-row .plant-mgrid > .pet-mtile { grid-column: span 2; }
.plant-menu.odd-row .plant-mgrid > .pet-mtile:nth-last-child(2) { grid-column: 2 / span 2; }
.plant-menu .pet-mtile small { white-space: nowrap; }
/* 触屏没有悬停:不让「点过的那格」一直亮着,只在按下/键盘焦点时高亮 */
@media (hover: none) {
  .pet-menu.plant-menu button:not(:disabled):hover:not(:active):not(:focus-visible) { background: transparent; color: inherit; }
  .pet-menu.plant-menu button:not(:disabled):hover:not(:active):not(:focus-visible) small { color: var(--pet-muted); }
}
/* 花被拖到顶上时气泡翻到花下方(不压在线胶囊 / ⚙) */
.plant-say.say-below { bottom: auto; top: calc(100% + 14px); }
.plant-say.say-below::after { top: auto; bottom: calc(100% + var(--pet-px, 3px)); box-shadow: 3px 3px 0 0 var(--pet-paper-2, #fff), 0 3px 0 0 var(--pet-line, #2E4256); }
/* 格子之间不要 .pet-menu button + button 的横线(那是竖排列表用的;格子靠间距分隔) */
.pet-menu.plant-menu .pet-mtile { box-shadow: none; }
/* 说话时先收起需求小牌,气泡尾巴直接指向花(r11 评审小问题);说完小牌回来 */
.plant-float.saying .plant-need { visibility: hidden; }
/* (r14) 自由摆放的花盆找不到不压字的位置时:变淡、点击穿透,消息文字始终可读(r13 评审 FAIL-3) */
.plant-float.plant-veil { opacity: .4; pointer-events: none; transition: opacity .2s steps(3, jump-none); }
.plant-float.plant-veil .plant-say { display: none; }

/* 设置「显示小花」关闭:花盆、气泡、菜单全部不显示(JS 侧同时停说话/占位/当障碍) */
html.hide-plant #plant-float, html.hide-plant .plant-say, html.hide-plant .plant-menu { display: none !important; }

/* ================= 新玩法:访客 · 摘花 · 双色花(2026-10 games) ================= */
.px-visitor {
  position: absolute; z-index: 3; width: 22px; height: 20px; padding: 2px; border: 0; background: transparent;
  cursor: pointer; -webkit-tap-highlight-color: transparent; touch-action: manipulation;
}
.px-visitor::before { content: ''; position: absolute; inset: -11px; }   /* 点击区 ≥44px */
.px-visitor img { position: absolute; left: 3px; top: 3px; image-rendering: pixelated; }
.px-visitor.is-butterfly { top: -2px; right: -12px; }
.px-visitor.is-butterfly img { width: 16px; height: 14px; }
.px-visitor.is-bug { bottom: 20px; left: -4px; }
.px-visitor.is-bug img { width: 14px; height: 10px; top: 5px; }
.px-visitor .v1 { opacity: 0; }
.px-visitor.is-butterfly { animation: vis-bob 1.6s steps(4, jump-none) infinite; }
.px-visitor.is-butterfly .v0 { animation: vis-flap0 .5s steps(1, end) infinite; }
.px-visitor.is-butterfly .v1 { animation: vis-flap1 .5s steps(1, end) infinite; }
.px-visitor.is-bug { animation: vis-crawl 3s steps(10, jump-none) infinite alternate; }
.px-visitor.is-bug .v0 { animation: vis-flap0 .4s steps(1, end) infinite; }
.px-visitor.is-bug .v1 { animation: vis-flap1 .4s steps(1, end) infinite; }
@keyframes vis-flap0 { 0% { opacity: 1; } 50% { opacity: 0; } }
@keyframes vis-flap1 { 0% { opacity: 0; } 50% { opacity: 1; } }
@keyframes vis-bob { 0%, 100% { transform: translate(0, 0); } 25% { transform: translate(-3px, -3px); } 50% { transform: translate(-1px, -5px); } 75% { transform: translate(2px, -2px); } }
@keyframes vis-crawl { from { transform: translateX(0); } to { transform: translateX(14px); } }
/* 接住蝴蝶:落到花心轻轻扇两下再消失;赶走小虫:往外跑;蝴蝶自己飞走 */
.px-visitor.caught { animation: vis-caught 1.4s steps(7, jump-none) forwards; pointer-events: none; }
.px-visitor.flee { animation: vis-flee .8s steps(5, jump-none) forwards; pointer-events: none; }
.px-visitor.leave { animation: vis-leave .9s steps(6, jump-none) forwards; pointer-events: none; }
@keyframes vis-caught { 0% { transform: translate(0, 0); } 40% { transform: translate(-20px, 2px); opacity: 1; } 80% { transform: translate(-20px, 2px); opacity: 1; } 100% { transform: translate(-20px, -6px); opacity: 0; } }
@keyframes vis-flee { to { transform: translateX(-60px) translateY(4px); opacity: 0; } }
@keyframes vis-leave { to { transform: translate(40px, -70px); opacity: 0; } }

/* 摘下的花头:送出时往上飘;对方收到时从屏幕上方飘落,落在输入栏上方停一会儿 */
.px-gift { position: fixed; z-index: 45; width: 72px; height: 42px; pointer-events: none; image-rendering: pixelated; }
.px-gift img { width: 72px; height: 42px; image-rendering: pixelated; display: block; }
.px-gift.lift { animation: gift-lift 1.6s steps(8, jump-none) forwards; }
@keyframes gift-lift { 0% { transform: translateY(0) scale(1); opacity: 1; } 70% { opacity: 1; } 100% { transform: translateY(-140px) rotate(-12deg); opacity: 0; } }
.px-gift.fall { top: -40px; animation: gift-fall 2.4s steps(12, jump-none) forwards; filter: drop-shadow(0 3px 0 rgba(0, 0, 0, .12)); }
@keyframes gift-fall {
  0% { transform: translate(0, 0) rotate(-8deg); }
  25% { transform: translate(18px, calc((var(--land) + 40px) * .25)) rotate(8deg); }
  50% { transform: translate(-10px, calc((var(--land) + 40px) * .5)) rotate(-6deg); }
  75% { transform: translate(12px, calc((var(--land) + 40px) * .75)) rotate(5deg); }
  100% { transform: translate(0, calc(var(--land) + 40px)) rotate(0); }
}
.px-gift.fall.landed { animation: gift-fade .6s steps(3, jump-none) 2s forwards; transform: translate(0, calc(var(--land) + 40px)); }
@keyframes gift-fade { to { opacity: 0; } }
html.hide-plant .px-visitor { display: none !important; }
@media (prefers-reduced-motion: reduce) {
  .px-visitor, .px-visitor img { animation: none !important; }
  .px-visitor .v1 { opacity: 0 !important; }
  .px-visitor.caught, .px-visitor.flee, .px-visitor.leave { opacity: 0; transition: opacity .2s; }
  .px-gift.lift { animation: gift-fade .5s forwards; }
  .px-gift.fall { animation: none; top: 0; transform: translate(0, var(--land)); }
  .px-gift.fall.landed { animation: gift-fade .4s 2s forwards; }
}
/* 花生横幅(z40)别被蹲在输入栏的小花压住字:小花平时降一层;说话时仍抬到 42(v559 预审 F1) */
html .fab-float.plant-float:not(.saying), html[data-theme] .fab-float.plant-float:not(.saying) { z-index: 39; }
html .fab-float.plant-float.has-visitor, html[data-theme] .fab-float.plant-float.has-visitor { z-index: 42; }
/* 访客点击区扩到 44px(外观不变) */
.px-visitor::before { content: ''; position: absolute; inset: -12px; }

/* 深色:访客(蝴蝶/小虫)的深色描边融进深底 —— 一圈淡亮描边让它看得见(v603 设计审计 P3) */
html[data-scheme="dark"] .px-visitor { filter: drop-shadow(0 0 1px rgba(255, 255, 255, .6)); }
