/* ============================================================
   css/restaurant-sim.css
   清水河 · 猫猫食堂 V5 —— 2.5D 经营场景样式
   ------------------------------------------------------------
   对应 js/core/restaurant-scene2.js（GB.RSView）
   依赖：global.css（变量 / .gb-modal 框架 / .gb-btn）
        restaurant-art.css（ra-* 关键帧，仅作兼容，本文件自带 rs2-* 关键帧）
   ------------------------------------------------------------
   结构（全部挂在 .gb-modal-body 里）：
     .rs2
       .rs2-head   .rs2-hud（状态药丸）+ .rs2-mode（营业徽章 + 主按钮）
       .rs2-stagewrap（舞台，相对定位）
         .rs2-svg        380×240 viewBox，1:1 逻辑坐标
         .rs2-tip        设施提示
         .rs2-toast      轻提示
         .rs2-settle     结算遮罩（独立手写画面）
         .rs2-panel      功能面板（从舞台底部升起）
       .rs2-bar     8 个功能入口
   ------------------------------------------------------------
   ★ 铁律：SVG 里的元素（.rs2-ent / .rs2-fix / .rs2-furn / .rs2-hit …）
     **绝不能**写 CSS transform —— 会覆盖 transform 属性，元素瞬间跳到原点。
     需要动效一律动画「内部的 .rs2-bob 包装层」或在 HTML 元素上做。
   ============================================================ */

/* ============================================================
   0. 容器：把全屏模态的身体变成「一屏装下、面板内部滚动」
   ============================================================ */
.rs2 {
    width: 100%;
    align-self: stretch;
    display: flex;
    flex-direction: column;
    gap: 8px;
    min-height: 0;
    position: relative;
    color: var(--text-main);
    font-size: 0.86rem;
}

/* 只有「装了 .rs2」的全屏模态才拉满高度（有 :has 才生效，老浏览器降级为自然高度） */
.gb-modal--full .gb-modal-body:has(> .rs2) {
    flex: 1 1 auto;
    min-height: 0;
    gap: 0;
    padding: 6px 10px 10px;
    overflow: hidden;
}
.gb-modal--full .gb-modal-body:has(> .rs2) > .rs2 { flex: 1 1 auto; min-height: 0; }

/* ★★ 2026-10-06 兜底：老内核（微信 X5 / 旧 WKWebView）不支持 :has()，
   上面三条规则在那些机器上**整条失效** —— 模态身体拿不到高度、.rs2 也不长，
   竖屏抽屉（.rs2--sheet > .rs2-panel 是 flex:1 1 0）没有剩余空间可分，
   实测塌成 2px 高，玩家看到的就是「库存/员工只有窄窄一行」（探针复现过）。
   所以 JS 打开餐厅时会给 .gb-modal-body 补一个 .rs2-host 类，
   用普通子选择器把同样的三条规则写一遍 —— 不依赖 :has()，新老内核都吃。 */
.gb-modal--full .gb-modal-body.rs2-host {
    flex: 1 1 auto;
    min-height: 0;
    gap: 0;
    padding: 6px 10px 10px;
    overflow: hidden;
}
.gb-modal--full .gb-modal-body.rs2-host > .rs2 { flex: 1 1 auto; min-height: 0; }
.gb-modal--full .gb-modal-body.rs2-host .rs2-svg { height: 100%; }

/* ============================================================
   1. 顶栏：状态药丸 + 营业徽章 + 主操作
   ============================================================ */
.rs2-head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 6px 10px;
    flex: 0 0 auto;
}
.rs2-hud, .rs2-mode {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
    min-width: 0;
}
.rs2-mode { gap: 8px; }

.rs2-chip {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 3px 9px;
    border-radius: 999px;
    background: var(--card-bg);
    border: 1px solid rgba(214, 178, 140, 0.5);
    color: var(--text-soft);
    font-size: 0.78rem;
    line-height: 1.5;
    white-space: nowrap;
    box-shadow: 0 1px 2px rgba(150, 90, 60, 0.08);
}
.rs2-chip b { color: var(--text-main); font-weight: normal; }
.rs2-chip .rs2-icon { margin: 0; }
.rs2-chip.coin {
    color: #a9761f;
    border-color: rgba(226, 176, 84, 0.72);
    background: linear-gradient(180deg, #fff9e8, #fdf0cf);
}
.rs2-chip.coin b { color: #8a5c1a; }
.rs2-chip.clean { color: #4d7f76; border-color: rgba(150, 208, 196, 0.72); }
.rs2-chip.clean.warn { color: #a5552f; border-color: rgba(230, 150, 108, 0.8); background: #fff2e9; }
.rs2-chip.hot { color: #b5432c; border-color: rgba(232, 138, 110, 0.8); background: #fff0ea; }

/* 营业状态徽章 */
.rs2-badge {
    display: inline-flex;
    align-items: center;
    padding: 3px 12px;
    border-radius: 999px;
    font-size: 0.8rem;
    white-space: nowrap;
    border: 1px solid transparent;
}
.rs2-badge.m-closed      { background: #f2ece4; color: #8a7a6a; border-color: #e0d4c6; }
.rs2-badge.m-preparing   { background: #eef4fb; color: #4a6f9c; border-color: #cfe0f2; }
.rs2-badge.m-opening     { background: #e9f6f2; color: #3f7d6e; border-color: #bfe3d9; }
.rs2-badge.m-operating   { background: #fff2e2; color: #a5682a; border-color: #f3d3ab; }
.rs2-badge.m-busy        { background: #ffe8e2; color: #b8452c; border-color: #f6c4b4; }
.rs2-badge.m-closing     { background: #f0eefb; color: #5b5a9c; border-color: #d5d2f0; }
.rs2-badge.m-settlement  { background: #f5ecff; color: #7a4fa0; border-color: #e0cdf2; }

/* 狗宝操作提示（常驻在状态徽章旁边）。比徽章更淡一档，是「说明」不是「状态」；
   窄屏会跟着 .rs2-mode 的 wrap 换行，不用单独做断点。 */
.rs2-doghint {
    display: inline-flex;
    align-items: center;
    font-size: 0.76rem;
    color: var(--text-soft);
    opacity: 0.85;
    white-space: nowrap;
    /* ★ min-width:0 不能省：flex 项默认 min-width:auto = min-content，而这里是 nowrap，
       于是它**不允许被压缩**到内容宽度以下 → 窄屏上整行被它顶出去（横向溢出）。
       给了 0 之后 max-width/overflow/text-overflow 才真的生效，超长就变省略号。 */
    min-width: 0;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
}
.rs2-doghint::before {
    content: "";
    width: 6px; height: 6px;
    border-radius: 50%;
    background: #e79a4e;
    margin-right: 5px;
    flex: 0 0 auto;
    animation: rs2-breathe 2.4s ease-in-out infinite;
}

/* 主按钮 */
.rs2-main {
    border: none;
    border-radius: 999px;
    padding: 6px 16px;
    /* 触摸目标下限：窄屏下原来的 23px 高在手机上点不准（WCAG 2.5.8 要求 ≥24px） */
    min-height: 30px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 0.84rem;
    font-family: inherit;
    color: #fff;
    background: linear-gradient(180deg, #ffb0a0, var(--pink-deep));
    box-shadow: 0 3px 8px rgba(247, 108, 138, 0.3);
    cursor: pointer;
    white-space: nowrap;
    transition: transform 0.12s ease, filter 0.15s ease;
}
.rs2-main:active { transform: scale(0.96); }
.rs2-main.danger { background: linear-gradient(180deg, #f0a4a0, #d56a6a); box-shadow: 0 3px 8px rgba(213, 106, 106, 0.3); }
.rs2-main.go     { background: linear-gradient(180deg, #9fd8c8, #5fae97); box-shadow: 0 3px 8px rgba(95, 174, 151, 0.3); }
/* 「🎬 重新开张」重播按钮：低调的暖棕描边款，不跟主操作（开门/打烊）抢视觉 */
.rs2-main.ghost  {
    background: #fffaf0; color: #8a5c33;
    border: 1.5px solid #d9b98c; box-shadow: 0 2px 5px rgba(138, 92, 51, 0.14);
}
.rs2-main.ghost:active { transform: scale(0.96); }
.rs2-main[disabled] {
    background: #efe6dc; color: #b0a191; box-shadow: none; cursor: default;
}

/* ============================================================
   2. 舞台
   ============================================================ */
.rs2-stagewrap {
    position: relative;
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 16px;
    overflow: hidden;
    /* 底色跟舞台的天空/河面同调：舞台是 520×240（比例 2.17），容器比例随窗口变，
       preserveAspectRatio=meet 缩完还会剩一点留白。背景层已经上下出血去吃掉它，
       这里再给一层同调渐变兜底 —— 极端比例下露出来的也是「天与水」，不是色带。 */
    background: linear-gradient(180deg,
        #d8f0fb 0%, #d8f0fb 9%, #f4fbff 44%, #bfe3f0 60%, #8fc6dd 92%, #8fc6dd 100%);
    box-shadow: inset 0 0 0 1px rgba(107, 74, 47, 0.14), var(--shadow-soft);
    touch-action: pan-y;
}

/* 夜里同一套逻辑，换成夜景色 */
.rs2-stagewrap.rs2-night {
    background: linear-gradient(180deg,
        #232c4a 0%, #232c4a 9%, #39456b 44%, #2c3a58 60%, #1f2c47 92%, #1f2c47 100%);
}
.rs2-svg {
    display: block;
    width: 100%;
    height: auto;              /* 无 :has 支持时按 viewBox 比例自然撑高 */
    user-select: none;
    -webkit-user-select: none;
    /* 显式裁切：背景为了吃掉 meet 留白会上下出血 300 个单位、左右各 70
       （见 RA2 的 BLEED/PAD），超出 viewBox 的部分必须在这里被裁掉。
       不写死的话各家 UA 默认值不一致，窄屏上真的会被画出卡片外。 */
    overflow: hidden;
}
.gb-modal--full .gb-modal-body:has(> .rs2) .rs2-svg { height: 100%; }

/* ---- 舞台内的 SVG 元素（画，不画 style） ---- */
.rs2-svg .rs2-fix,
.rs2-svg .rs2-furn,
.rs2-svg .rs2-deco { cursor: pointer; }
.rs2-svg .rs2-ent { pointer-events: none; }

/* 角色动效包装层：唯一允许写 transform 的地方（它没有 transform 属性） */
.rs2-bob { transform-box: fill-box; transform-origin: 50% 100%; }

.rs2-svg .rs2-hit {
    fill: rgba(255, 255, 255, 0.001);
    stroke: rgba(120, 190, 220, 0.55);
    stroke-width: 1;
    stroke-dasharray: 3 3;
    cursor: move;
}
.rs2-svg .rs2-hit.sel {
    stroke: #e0863c;
    stroke-width: 1.6;
    stroke-dasharray: none;
    fill: rgba(255, 214, 150, 0.2);
}
.rs2-svg .rs2-decor-bg { fill: rgba(60, 40, 26, 0.26); pointer-events: none; }
.rs2-svg .rs2-gl { stroke: rgba(255, 255, 255, 0.26); stroke-width: 0.5; pointer-events: none; }
.rs2-svg .rs2-porchdot { fill: rgba(255, 255, 255, 0.6); pointer-events: none; }
.rs2-svg .rs2-ghost { fill: rgba(255, 255, 255, 0.3); pointer-events: none; stroke-width: 1.6; }
.rs2-svg .rs2-ghost.ok  { stroke: #56a86f; fill: rgba(120, 210, 150, 0.28); }
.rs2-svg .rs2-ghost.bad { stroke: #cf5b4a; fill: rgba(230, 130, 110, 0.28); }
/* 面板里点到的贴附槽位（墙裙/地板/窗/招牌/挂画）—— 在舞台上把这个位置框出来 */
.rs2-svg .rs2-slotbox {
    fill: rgba(255, 236, 190, 0.22);
    stroke: #f0b04a;
    stroke-width: 1.6;
    stroke-dasharray: 5 4;
    pointer-events: none;
    animation: rs2-slotpulse 1.5s ease-in-out infinite;
}
@keyframes rs2-slotpulse { 0%, 100% { opacity: 0.55; } 50% { opacity: 1; } }

/* ---- 装修地图：拖空白处平移（光标给反馈）；摆放中不禁用滚动 ---- */
.rs2-stagewrap.rs2-decor .rs2-svg { cursor: grab; touch-action: none; }
.rs2-stagewrap.rs2-decor.rs2-panning .rs2-svg { cursor: grabbing; }

/* ---- 相机控件（只在装修模式出现，右上角：面板会盖住右下角） ---- */
.rs2-zoom {
    position: absolute;
    right: 8px; top: 8px;
    display: flex; align-items: center; gap: 4px;
    padding: 4px 6px;
    border-radius: 999px;
    background: rgba(255, 253, 247, 0.94);
    border: 1px solid rgba(214, 178, 140, 0.7);
    box-shadow: var(--shadow-soft);
    z-index: 6;
}
.rs2-zoom[hidden] { display: none; }
.rs2-zbtn {
    border: none;
    background: #f7ead9;
    color: #8a6a55;
    border-radius: 999px;
    min-width: 24px; height: 24px;
    padding: 0 8px;
    font-family: inherit; font-size: 0.82rem; line-height: 1;
    cursor: pointer;
}
.rs2-zbtn:active { transform: scale(0.94); }
.rs2-zbtn.wide { font-size: 0.72rem; }
.rs2-zval {
    font-size: 0.7rem; color: var(--text-soft);
    min-width: 34px; text-align: center;
}

/* ---- 选中家具时飘在它上方的工具条（HTML：不随相机缩放，永远好点） ---- */
.rs2-furnbar {
    position: absolute;
    /* left/top 由 JS 按 toScreen() 换算给出，锚点=家具脚下；往上抬一个身位 */
    transform: translate(-50%, -100%);
    margin-top: -8px;
    display: flex; align-items: center; gap: 4px;
    padding: 4px 6px;
    border-radius: 999px;
    background: rgba(255, 250, 240, 0.97);
    border: 1px solid rgba(240, 186, 120, 0.9);
    box-shadow: var(--shadow-lift);
    white-space: nowrap;
    z-index: 7;
}
/* 贴顶的家具 → 翻到它下方（否则会被 stagewrap 的 overflow:hidden 裁掉） */
.rs2-furnbar.below { transform: translate(-50%, 0); margin-top: 16px; }
.rs2-furnbar[hidden] { display: none; }
.rs2-fb {
    border: none;
    background: #fff0dc;
    color: #8a5a2f;
    border-radius: 999px;
    padding: 3px 9px;
    font-family: inherit; font-size: 0.72rem;
    cursor: pointer;
}
.rs2-fb:hover { background: #ffe3c4; }
.rs2-fb:active { transform: scale(0.94); }
.rs2-fb.danger { background: #fde8e2; color: #a54a2a; }
.rs2-fb.ghost { background: #f1ece5; color: #8b7a68; padding: 3px 7px; }
.rs2-fbname { font-size: 0.72rem; color: var(--pink-deep); padding-left: 3px; }
.rs2-fbnote { font-size: 0.68rem; color: #ab9b88; padding: 0 3px; }

/* ---- 素材：嵌套 <svg> 已由美术层补了 width/height，这里只做兜底与动效 ---- */
.rs2-svg .rs2-fxart,
.rs2-svg .rs2-plate,
.rs2-svg .rs2-dirtyplate,
.rs2-svg .rs2-stain,
.rs2-svg .rs2-bub-svg,
.rs2-svg .rs2-cat-svg,
.rs2-svg .rs2-fixart,
.rs2-svg .rs2-fuart { overflow: visible; pointer-events: none; }

/* 特效节点 */
.rs2-svg .rs2-fxnode { pointer-events: none; }
.rs2-svg .rs2-steam,
.rs2-svg .rs2-steamg { animation: rs2-steam 1.7s ease-out infinite; }
.rs2-svg .rs2-bub { animation: rs2-bub 1.5s ease-in-out infinite; }
.rs2-svg .rs2-flameg { animation: rs2-flame 0.6s ease-in-out infinite; transform-box: fill-box; transform-origin: 50% 100%; }
.rs2-svg .rs2-sparkle { animation: rs2-spark 1.1s ease-out infinite; }

/* ---- 菜品品质分级（道具/效果的「档次感」）----
   dishArt 只在「稀有 / 传说」插入 .rs2-qspark / .rs2-qaura 两个装饰组，
   这里只让它们呼吸起来。★ 只动 opacity，不碰 transform —— 这两个 <g> 上没有
   transform 属性，但保持「动效不动几何」的习惯，免得以后加属性时踩坑。 */
.rs2-svg .rs2-qspark path { animation: rs2-qspark 1.6s ease-in-out infinite; }
.rs2-svg .rs2-qspark path:nth-child(2) { animation-delay: 0.55s; }
.rs2-svg .rs2-qaura { animation: rs2-qaura 2.8s ease-in-out infinite; }
@keyframes rs2-qspark { 0%, 100% { opacity: 0.4; } 50% { opacity: 1; } }
@keyframes rs2-qaura { 0%, 100% { opacity: 0.3; } 50% { opacity: 0.92; } }
.rs2-svg .rs2-water { animation: rs2-river 4.6s ease-in-out infinite; }

/* ---- 设备档位 → 特效也跟着换（火焰焰色 / 蒸汽浓度）----
   灶台本体由美术层按 tier 画（旧铁 / 铜圈 / 蓝焰），这里只换同一批特效节点的颜色：
   不必为每个档位写一套特效素材，换舞台类名即可。
   选择器带上 #rs2-stagewrap 是为了稳压原来的 .rs2-svg 规则。 */
#rs2-stagewrap.rs2-eq2 .rs2-flameg path:first-child { fill: #ff8a2c; }
#rs2-stagewrap.rs2-eq3 .rs2-flameg path:first-child { fill: #4f9dff; }
#rs2-stagewrap.rs2-eq3 .rs2-flameg path:last-child { fill: #cbe8ff; }
#rs2-stagewrap.rs2-eq3 .rs2-steamg { stroke-width: 3; }
#rs2-stagewrap.rs2-eq3 .rs2-steam { stroke-width: 1.8; }
#rs2-stagewrap.rs2-eq1 .rs2-fix[data-id="stove01"] .rs2-pot,
#rs2-stagewrap.rs2-eq1 .rs2-fix[data-id="stove02"] .rs2-pot { opacity: 0.95; }
.rs2-svg .rs2-willow { animation: rs2-sway 5.2s ease-in-out infinite; transform-box: fill-box; transform-origin: 20% 0%; }
.rs2-svg .rs2-custtail { animation: rs2-tail 1.6s ease-in-out infinite; }
.rs2-svg .cat-tail { animation: rs2-tail 1.6s ease-in-out infinite; }
.rs2-svg .cat-eye-closed { opacity: 0; }
.rs2-svg .cat-eye-open { animation: ra-blinkOpen 5.6s infinite; }
.rs2-svg .cat-eye-closed { animation: ra-blinkClosed 5.6s infinite; }
/* 每只猫的眨眼错开（旧舞台靠 .rs-cat-svg.cat-xxx 的 animation-delay，
   V5 没有那层外壳 → 得写在 animation 简写**之后**，否则被它重置成 0） */
.rs2-svg .cat-bianbian .cat-eye-open, .rs2-svg .cat-bianbian .cat-eye-closed { animation-delay: 1.3s; }
.rs2-svg .cat-xiaobei .cat-eye-open, .rs2-svg .cat-xiaobei .cat-eye-closed { animation-delay: 2.4s; }
.rs2-svg .cat-huotui .cat-eye-open, .rs2-svg .cat-huotui .cat-eye-closed { animation-delay: 0.6s; }
.rs2-svg .cat-fantuan .cat-eye-open, .rs2-svg .cat-fantuan .cat-eye-closed { animation-delay: 3.4s; }
.rs2-svg .cat-xiaoju .cat-eye-open, .rs2-svg .cat-xiaoju .cat-eye-closed { animation-delay: 4.2s; }
/* 小美：和三只错开；警戒脸（尖眼）眨得慢，圆眼睛眨得快 */
.rs2-svg .cat-xiaomei .cat-eye-open, .rs2-svg .cat-xiaomei .cat-eye-closed { animation-delay: 3.7s; }
.rs2-svg .cat-xiaomei.xm-round .cat-eye-open, .rs2-svg .cat-xiaomei.xm-round .cat-eye-closed { animation-duration: 4.2s; }
.rs2-svg .cat-xiaomei.xm-sharp .cat-eye-open, .rs2-svg .cat-xiaomei.xm-sharp .cat-eye-closed { animation-duration: 7.4s; }
/* ★ 睡着 / 打盹：睁眼组藏起来、闭眼组常驻。
   美术层（RA2.catArt）给困猫打了 .cat-sleepy，这里只需认它 —— 
   没有这条的话闭眼会被眨眼动画压到 98% 的时间都看不见，猫就成了「没有眼睛」。 */
.rs2-svg .cat-sleepy .cat-eye-open { animation: none; opacity: 0; }
.rs2-svg .cat-sleepy .cat-eye-closed { animation: none; opacity: 1; }

/* 耳朵轻摆：ear()/earNotch() 给耳朵路径加了 .cat-ear，绕耳根小幅抖动；
   错峰延迟避免所有猫的耳朵整齐划一地动。纯 CSS，不新增定时器。 */
.rs2-svg .cat-ear {
    transform-box: fill-box; transform-origin: 50% 100%;
    animation: rs2-eartw 5.4s ease-in-out infinite;
}
.rs2-svg .cat-huotui  .cat-ear { animation-delay: 0.5s; }
.rs2-svg .cat-bianbian .cat-ear { animation-delay: 1.9s; }
.rs2-svg .cat-xiaobei .cat-ear { animation-delay: 3.0s; }
.rs2-svg .cat-xiaomei .cat-ear { animation-delay: 4.1s; }
.rs2-svg .cat-fantuan .cat-ear { animation-delay: 2.4s; }
.rs2-svg .cat-xiaoju  .cat-ear { animation-delay: 3.6s; }
@keyframes rs2-eartw {
    0%, 44%, 56%, 100% { transform: rotate(0deg); }
    48% { transform: rotate(-3.5deg); }
    52% { transform: rotate(2.5deg); }
    78% { transform: rotate(2deg); }
    82% { transform: rotate(0deg); }
}

/* ---- 交互反馈：悬停高亮 + 点击脉冲 ----
   角色/设施节点 CSS 上是 pointer-events:none，悬停由场景层坐标命中后加 .rs2-hover；
   只动 filter（不强加 transform），避免覆盖 SVG 的 transform 定位属性导致瞬移。 */
.rs2-svg .rs2-ent.rs2-hover {
    filter: drop-shadow(0 0 2.6px rgba(255,221,150,0.95)) drop-shadow(0 1px 1px rgba(84,52,24,0.40));
}
.rs2-svg .rs2-tbl.rs2-hover {
    filter: drop-shadow(0 0 3px rgba(255,210,140,0.85));
}
.rs2-svg.rs2-cur-ptr { cursor: pointer; }
/* 点击 NPC：一次性脉冲（仅 filter，~0.48s 后由 JS 移除类） */
.rs2-svg .rs2-ent.rs2-clickpulse { animation: rs2-clickpulse 0.48s ease; }
@keyframes rs2-clickpulse {
    0%   { filter: drop-shadow(0 0 0 rgba(255,200,120,0)); }
    30%  { filter: drop-shadow(0 0 6px rgba(255,200,120,1)); }
    100% { filter: drop-shadow(0 0 0 rgba(255,200,120,0)); }
}

/* 角色状态动效（只动 .rs2-bob 包装层） */
.anim-walk .rs2-bob  { animation: rs2-walk 0.82s ease-in-out infinite; }
.anim-cook .rs2-bob  { animation: rs2-cook 1.05s ease-in-out infinite; }
.anim-clean .rs2-bob,
.anim-dish .rs2-bob  { animation: rs2-work 0.88s ease-in-out infinite; }
.anim-serve .rs2-bob { animation: rs2-serve 1.1s ease-in-out infinite; }
.anim-bill .rs2-bob  { animation: rs2-bill 0.9s ease-in-out infinite; }
.anim-rest .rs2-bob  { animation: rs2-breathe 3.4s ease-in-out infinite; }
.anim-idle .rs2-bob  { animation: rs2-breathe 3.6s ease-in-out infinite; }

/* ---- 待机动作（猫咪没活干时在做什么）----
   每种动作一套专属小动效：外层 .rs2-bob 做姿态，内部 .cat-* 小道具做细节。
   ★ 只动内层，绝不碰带 transform 属性的 SVG 元素（会覆盖属性 → 瞬移）。 */
.anim-idle-lookout .rs2-bob { animation: rs2-act-look 5.2s ease-in-out infinite; }
.anim-idle-groom   .rs2-bob { animation: rs2-act-groom 3.2s ease-in-out infinite; }
.anim-idle-stretch .rs2-bob { animation: rs2-act-stretch 4.2s ease-in-out infinite; }
.anim-idle-nap     .rs2-bob { animation: rs2-act-nap 5.6s ease-in-out infinite; }
.anim-idle-tail    .rs2-bob { animation: rs2-act-tail 2.4s ease-in-out infinite; }
.anim-idle-sniff   .rs2-bob { animation: rs2-act-sniff 3.4s ease-in-out infinite; }
.anim-idle-paw     .rs2-bob { animation: rs2-act-paw 2.0s ease-in-out infinite; }
.anim-idle-yawn    .rs2-bob { animation: rs2-act-yawn 4.8s ease-in-out infinite; }
.anim-idle-patrol  .rs2-bob { animation: rs2-act-patrol 6.4s ease-in-out infinite; }

/* 道具级细节（元素本身不带 transform 属性，才能安全地用 CSS transform） */
.anim-idle-tail .cat-swirl,
.anim-idle-paw .cat-star,
.anim-idle-groom .cat-groom g {
    transform-box: fill-box; transform-origin: 50% 50%;
}
.anim-idle-tail .cat-swirl { animation: rs2-act-swirl 1.7s linear infinite; }
.anim-idle-paw .cat-star   { animation: rs2-act-star 1.15s ease-in-out infinite; }
.anim-idle-groom .cat-groom g { animation: rs2-act-sparkle 1.6s ease-in-out infinite; }
.anim-idle-sniff .cat-smell { animation: rs2-act-smell 2.3s ease-in-out infinite; }
.anim-idle-sniff .cat-smell path:nth-child(2) { animation-delay: 0.35s; }
.anim-idle-sniff .cat-smell path:nth-child(3) { animation-delay: 0.7s; }
.anim-idle-lookout .cat-look { animation: rs2-act-gaze 3.2s ease-in-out infinite; }
.anim-idle-lookout .cat-bird { transform-box: fill-box; transform-origin: 50% 100%; animation: rs2-act-hop 1.6s ease-in-out infinite; }
.anim-idle-patrol .cat-dust { animation: rs2-act-dust 2.6s ease-out infinite; }
.anim-idle-yawn .cat-yawn ellipse:first-child { transform-box: fill-box; transform-origin: 50% 20%; animation: rs2-act-gape 4.8s ease-in-out infinite; }

/* ---- 「狗宝能干的活」标记 ----
   浮在客人/桌子上方的小徽章。只做两件事：告诉玩家「这里可以点」，以及「点的是哪件事」。
   ★ pointer-events:none 是硬约束：它和角色节点同住在 g-dyn 里，一旦参与 DOM 命中，
     就会把它下面那张桌子/水槽的点击整块吃掉（本文件「隐形遮罩」那条铁律）。
   ★ 图标尺寸必须在这里写死 px。.rs2-icon 全局是 width:1.05em，在 SVG 里 em 会去继承
     font-size，值随舞台字体漂移；徽章里的图标该多大是设计决定，不该由继承决定。 */
.rs2-svg .rs2-jmark { pointer-events: none; }
.rs2-svg .rs2-jmark .rs2-icon { width: 18px; height: 18px; vertical-align: 0; }
/* 只动没有 transform 属性的内层 g（.rs2-jpulse），外层 <g> 带 translate 属性，不能碰 */
.rs2-svg .rs2-jmark .rs2-jpulse {
    transform-box: fill-box; transform-origin: 50% 100%;
    animation: rs2-act-job 1.5s ease-in-out infinite;
}

/* ---- 狗宝的尾巴 ----
   狗的美术素材（GB.RestaurantArt.player）给尾巴留了 .dog-tail 钩子，老舞台是在
   .rs-player 作用域里挂动画演的。新版舞台把狗**内联**进 RSView 的 SVG，没有那层外壳；
   而且素材里那句 style="transform-origin:68px 76px" 是照着 100×100 的旧 viewBox 写的，
   内联之后它参照的是**舞台的 viewBox**（随相机缩放/平移变）→ 尾巴会绕错支点乱甩。
   所以这里改用 fill-box（相对尾巴自身的包围盒），与相机、缩放全无关。
   ★ 这个 path 只有 style、没有 transform 属性，所以用 CSS transform 是安全的。 */
.rs2-svg .dog-tail {
    transform-box: fill-box; transform-origin: 100% 70%;
    animation: rs2-dogwag 0.9s ease-in-out infinite;
}
/* 干活时摇得快一点（和猫「忙起来动作变快」同一套读法） */
.rs2-svg .anim-cook .dog-tail, .rs2-svg .anim-serve .dog-tail,
.rs2-svg .anim-clean .dog-tail, .rs2-svg .anim-dish .dog-tail { animation-duration: 0.5s; }
.rs2-svg .anim-walk .dog-tail { animation-duration: 0.42s; }
/* 错峰呼吸：错开的是**内层** .rs2-jpulse（动画挂在它身上），不是外层标记 g */
.rs2-svg .rs2-jmark-serve .rs2-jpulse,
.rs2-svg .rs2-jmark-bus   .rs2-jpulse { animation-delay: 0.2s; }
.rs2-svg .rs2-jmark-clean .rs2-jpulse,
.rs2-svg .rs2-jmark-dish  .rs2-jpulse { animation-delay: 0.4s; }

/* ---- 窗外风景（vista）：天气粒子 / 季节飘落 / 水面涟漪 / 雷闪 ----
   全部画在「没有 transform 属性」的 <g> 上，所以可以安全地用 CSS transform。
   雨/雪整片下落用「短距离 + 快速度 + 低透明度」的经典做法：
   到 26px 处回首时肉眼几乎看不出接缝，读起来就是雨丝在落，而不是一层纸在平移。 */
.rs2-svg .rs2-winview { overflow: hidden; pointer-events: none; }
.rs2-svg .rs2-rainfall { animation: rs2-rainfall 0.42s linear infinite; }
.rs2-svg .rs2-snowfall { animation: rs2-snowfall 7.2s linear infinite; }
.rs2-svg .rs2-fall     { animation: rs2-vfall 9.5s linear infinite; }
.rs2-svg .rs2-ripples ellipse {
    transform-box: fill-box; transform-origin: 50% 50%;
    animation: rs2-ripple 2.4s ease-out infinite;
}
.rs2-svg .rs2-ripples ellipse:nth-child(2n) { animation-delay: 0.6s; }
.rs2-svg .rs2-ripples ellipse:nth-child(3n) { animation-delay: 1.2s; }
.rs2-svg .rs2-ripples ellipse:nth-child(4n) { animation-delay: 1.8s; }
/* 雷闪：室外大景与窗景同步闪（同一时刻亮，才像同一道闪电照亮两处） */
.rs2-svg .rs2-flashout,
.rs2-svg .rs2-flashwin { animation: rs2-flash 6.4s linear infinite; }
@media (prefers-reduced-motion: reduce) {
    .rs2-svg .rs2-bob, .rs2-svg .rs2-fxart, .rs2-svg .rs2-water,
    .rs2-svg .rs2-willow, .rs2-svg .cat-tail, .rs2-svg .rs2-custtail,
    .rs2-svg .rs2-rainfall, .rs2-svg .rs2-snowfall, .rs2-svg .rs2-fall,
    .rs2-svg .rs2-ripples ellipse, .rs2-svg .rs2-flashout, .rs2-svg .rs2-flashwin,
    .rs2-svg .rs2-jmark .rs2-jpulse, .rs2-svg .dog-tail { animation: none; }
    .rs2-svg .rs2-flashout, .rs2-svg .rs2-flashwin { opacity: 0; }
}

/* ============================================================
   3. 舞台上的浮层：提示 / 气泡 / 结算
   ============================================================ */
.rs2-tip {
    position: absolute;
    left: 10px; top: 10px;
    max-width: 62%;
    padding: 6px 10px;
    border-radius: 10px;
    background: rgba(255, 253, 247, 0.96);
    border: 1px solid rgba(214, 178, 140, 0.7);
    box-shadow: var(--shadow-soft);
    font-size: 0.78rem;
    line-height: 1.55;
    color: var(--text-main);
    pointer-events: none;
    z-index: 4;
}
.rs2-tip b { color: var(--pink-deep); font-weight: normal; }
/* ★ 提示框整体 pointer-events:none（不挡场景），但里面的交互按钮要能吃点击，
   否则「开始制作」这类入口按钮会点不动（2026-10-09 修复烹饪小游戏入口点不开）。 */
.rs2-tip button { pointer-events: auto; }

.rs2-toast {
    position: absolute;
    left: 50%; bottom: 12px;
    transform: translateX(-50%);
    max-width: 88%;
    padding: 7px 14px;
    border-radius: 999px;
    background: rgba(74, 52, 40, 0.9);
    color: #fff8ee;
    font-size: 0.78rem;
    line-height: 1.5;
    text-align: center;
    pointer-events: none;
    opacity: 0;
    transition: opacity 0.22s ease, transform 0.22s ease;
    z-index: 8;
}
.rs2-toast.show { opacity: 1; }

/* ---- 结算遮罩 ---- */
.rs2-settle {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 12px;
    background: rgba(46, 30, 20, 0.42);
    backdrop-filter: blur(2px);
    z-index: 20;
}
.rs2-settle[hidden] { display: none; }
.rs2-settlecard {
    width: min(340px, 92%);
    max-height: 100%;
    overflow-y: auto;
    padding: 16px 18px 14px;
    border-radius: 20px;
    background: linear-gradient(180deg, #fffdf7, #fff2e6);
    box-shadow: var(--shadow-lift);
    text-align: center;
    animation: rs2-pop 0.32s cubic-bezier(0.2, 1.1, 0.4, 1) both;
}
.rs2-sttitle { font-size: 1.05rem; color: var(--pink-deep); }
.rs2-stdate { font-size: 0.74rem; color: var(--text-soft); margin-bottom: 10px; }
.rs2-strows { display: flex; flex-direction: column; gap: 1px; margin-bottom: 10px; }
.rs2-strow {
    display: flex; align-items: center; justify-content: space-between;
    gap: 10px;
    padding: 5px 8px;
    border-radius: 8px;
    font-size: 0.8rem;
    color: var(--text-soft);
}
.rs2-strow:nth-child(odd) { background: rgba(255, 244, 230, 0.85); }
.rs2-strow b { color: var(--text-main); font-weight: normal; }
.rs2-strow.big {
    margin-top: 4px;
    background: #fff0d8;
    font-size: 0.9rem;
    color: var(--text-main);
}
.rs2-strow.big b { font-size: 1.05rem; }
.rs2-stfoot { display: flex; flex-wrap: wrap; gap: 5px; justify-content: center; margin-bottom: 12px; }
.rs2-stfoot:empty { display: none; }

/* ============================================================
   4. 功能面板（从舞台底部升起）
   ============================================================ */
.rs2-panel {
    position: absolute;
    left: 8px; right: 8px; bottom: 8px;
    max-height: min(64%, 420px);
    display: flex;
    flex-direction: column;
    border-radius: 14px;
    background: rgba(255, 253, 247, 0.97);
    box-shadow: var(--shadow-lift);
    border: 1px solid rgba(214, 178, 140, 0.6);
    overflow: hidden;
    z-index: 12;
    animation: rs2-rise 0.22s ease both;
}
.rs2-panel[hidden] { display: none; }
.rs2-panelhead {
    display: flex; align-items: center; justify-content: space-between;
    gap: 10px;
    padding: 8px 12px;
    background: linear-gradient(180deg, #fff6ea, #ffe9d6);
    border-bottom: 1px solid rgba(214, 178, 140, 0.5);
    flex: 0 0 auto;
}
.rs2-panelhead b { font-weight: normal; color: var(--pink-deep); font-size: 0.9rem; }
.rs2-x {
    border: none; background: #f6e2d6; color: #8a6a55;
    border-radius: 999px; padding: 3px 12px;
    font-size: 0.76rem; font-family: inherit; cursor: pointer;
}
.rs2-x:active { transform: scale(0.95); }
.rs2-panelbody {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    overscroll-behavior: contain;
    padding: 10px 12px 14px;
    touch-action: pan-y;
}

/* ---- 面板内部的小组件 ---- */
.rs2-note {
    font-size: 0.78rem; color: var(--text-soft); line-height: 1.6;
    margin-bottom: 8px;
}
.rs2-note b { color: var(--pink-deep); font-weight: normal; }
.rs2-sub {
    font-size: 0.8rem; color: #a5763f;
    margin: 12px 0 6px;
    padding-left: 8px;
    border-left: 3px solid #f0cf9c;
}
.rs2-empty {
    font-size: 0.78rem; color: #b6a693;
    padding: 12px; text-align: center;
    background: rgba(246, 240, 232, 0.6);
    border-radius: 10px; border: 1px dashed #e2d6c6;
}
.rs2-chips { display: flex; flex-wrap: wrap; gap: 6px; margin: 6px 0; }
.rs2-tag {
    display: inline-flex; align-items: center;
    padding: 2px 9px; border-radius: 999px;
    font-size: 0.73rem;
    background: #f5efe6; color: #8a7a6a; border: 1px solid #e6dbcb;
    white-space: nowrap;
}
.rs2-tag.on { background: #fff3d9; color: #a5763f; border-color: #f0d9a8; }
/* 「看得见的作用」（猫更爱打盹 / 客人会多看一眼）—— 与纯数值标签区分开：
   数值是「算出来的」，这排是「看得见的」，用一点绿意提示它是行为层反馈。 */
.rs2-tag.amb { background: #eef6ec; color: #5c8156; border-color: #d3e6cd; }

.rs2-mini {
    border: 1px solid rgba(214, 178, 140, 0.7);
    background: #fffaf3;
    color: #8a6a55;
    border-radius: 999px;
    padding: 4px 12px;
    font-size: 0.75rem;
    font-family: inherit;
    cursor: pointer;
    white-space: nowrap;
    transition: transform 0.12s ease, background 0.15s ease;
}
.rs2-mini:active { transform: scale(0.95); }
.rs2-mini:hover { background: #fff3e6; }
.rs2-mini.primary { background: linear-gradient(180deg, #ffb0a0, var(--pink-deep)); color: #fff; border-color: transparent; }
.rs2-mini.on { background: #e9f6f2; color: #4d7f76; border-color: #bfe3d9; }
.rs2-mini.off { background: #fdeee9; color: #a5552f; border-color: #f3d3ab; }
.rs2-mini[disabled] { opacity: 0.45; cursor: default; }

/* 列表行 */
.rs2-list { display: flex; flex-direction: column; gap: 4px; }
.rs2-row {
    display: flex; align-items: center; gap: 8px;
    padding: 6px 9px;
    border-radius: 10px;
    background: rgba(252, 246, 238, 0.9);
    border: 1px solid rgba(230, 216, 198, 0.8);
}
.rs2-row.on { background: #fff5e4; border-color: rgba(240, 209, 160, 0.9); }
.rs2-row.dim { opacity: 0.62; }
.rs2-row.fav { border-color: #f0cf9c; background: #fffaf0; }
/* ★ 关键：column flex + align-items:center 的子元素按内容撑宽，
   不写 align-self:stretch 就永远不换行 → 长文本会被静默截断 */
.rs2-rowmain {
    flex: 1 1 auto;
    min-width: 0;
    align-self: stretch;
    display: flex; flex-direction: column; justify-content: center;
}
.rs2-rowmain b { font-weight: normal; font-size: 0.82rem; color: var(--text-main); }
.rs2-rowmain small {
    font-size: 0.72rem; color: var(--text-soft);
    line-height: 1.5;
    white-space: normal;
    word-break: break-word;
}
.rs2-rowmain i { font-style: normal; }
.rs2-rowmain i.lack { color: #c0603a; }
.rs2-rowmain i.new { color: #4d8f76; }
.rs2-lock { font-size: 0.72rem; color: #b6a693; white-space: nowrap; }

/* 卡片网格 */
.rs2-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(132px, 1fr));
    gap: 7px;
}
.rs2-card {
    display: flex; flex-direction: column;
    padding: 8px 10px;
    border-radius: 12px;
    background: #fffcf6;
    border: 1px solid rgba(230, 216, 198, 0.9);
    box-shadow: 0 1px 2px rgba(150, 90, 60, 0.06);
}
.rs2-card.on { border-color: #bfe3d9; background: #f4fbf8; }
.rs2-card.dim { opacity: 0.6; }
.rs2-cardtop { display: flex; align-items: baseline; justify-content: space-between; gap: 6px; }
.rs2-cardtop b { font-weight: normal; font-size: 0.8rem; color: var(--text-main); }
.rs2-price { font-size: 0.74rem; color: #a9761f; white-space: nowrap; }
.rs2-cardsub {
    font-size: 0.71rem; color: var(--text-soft);
    line-height: 1.5; margin: 3px 0 7px;
    flex: 1 1 auto;
}
.rs2-card .rs2-chips { margin: 0; }
.rs2-card .rs2-mini { padding: 3px 9px; font-size: 0.72rem; }

/* 贴附槽位（墙裙 / 地板 / 窗 / 招牌 / 挂画）：一块「房子的部位 + 可选件」
   ——不进 rs2-grid，因为它自带一层内嵌的选项网格 */
.rs2-slot {
    padding: 8px 10px;
    border-radius: 12px;
    background: #fffcf6;
    border: 1px solid rgba(230, 216, 198, 0.9);
    margin-bottom: 8px;
}
.rs2-slot.on { border-color: #f0c37e; background: #fffaf0; }
.rs2-slot .rs2-grid { margin-top: 6px; }
.rs2-slot .rs2-empty { padding: 8px; }

/* 创意厨房表单 */
.rs2-form { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 8px; }
.rs2-field {
    flex: 1 1 132px;
    min-width: 0;
    display: flex; flex-direction: column; gap: 3px;
    font-size: 0.72rem; color: var(--text-soft);
}
.rs2-field span { padding-left: 2px; }
.rs2-field select {
    width: 100%;
    font-family: inherit; font-size: 0.78rem;
    color: var(--text-main);
    padding: 5px 8px;
    border-radius: 9px;
    border: 1px solid rgba(214, 178, 140, 0.8);
    background: #fffaf3;
    -webkit-appearance: none; appearance: none;
}

/* 效率条 / 清洁度 */
.rs2-meter {
    flex: 0 0 auto;
    width: 62px; height: 7px;
    border-radius: 999px;
    background: #eee3d5;
    overflow: hidden;
}
.rs2-meter i { display: block; height: 100%; border-radius: 999px; background: linear-gradient(90deg, #9fd8c8, #5fae97); transition: width 0.4s ease; }
.rs2-meter.big { width: 100%; height: 10px; }
.rs2-bigstat { display: flex; align-items: baseline; gap: 8px; margin: 4px 0 6px; }
.rs2-bigstat b { font-size: 1.6rem; font-weight: normal; color: #4d7f76; }
.rs2-bigstat span { font-size: 0.74rem; color: var(--text-soft); }

/* 报表 */
.rs2-report {
    display: flex; flex-direction: column; gap: 1px;
    padding: 6px 8px;
    border-radius: 12px;
    background: rgba(252, 246, 238, 0.9);
    border: 1px solid rgba(230, 216, 198, 0.8);
}
.rs2-rrow {
    display: flex; align-items: baseline; justify-content: space-between;
    gap: 10px;
    padding: 4px 6px;
    font-size: 0.79rem;
    color: var(--text-soft);
}
.rs2-rrow b { font-weight: normal; color: var(--text-main); white-space: nowrap; }
.rs2-rrow.total {
    margin-top: 4px;
    padding-top: 7px;
    border-top: 1px dashed #e2d6c6;
    font-size: 0.86rem;
    color: var(--text-main);
}
.rs2-rrow.total b { font-size: 1rem; }
.rs2-amt { font-size: 0.8rem; white-space: nowrap; }
.rs2-amt.up, .rs2-rrow b.up { color: #c2543a; }
.rs2-amt.down, .rs2-rrow b.down { color: #3f8a6a; }

/* ============================================================
   5. 底栏（8 个功能）
   ============================================================ */
.rs2-bar {
    flex: 0 0 auto;
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 5px;
}
.rs2-baritem {
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: 2px;
    min-width: 62px;
    padding: 5px 8px;
    border-radius: 12px;
    border: 1px solid rgba(214, 178, 140, 0.6);
    background: var(--card-bg);
    color: var(--text-soft);
    font-family: inherit;
    font-size: 0.68rem;
    cursor: pointer;
    transition: transform 0.12s ease, background 0.15s ease;
}
.rs2-baritem span { white-space: nowrap; }
.rs2-baritem:active { transform: scale(0.95); }
.rs2-baritem.on {
    background: linear-gradient(180deg, #fff6ea, #ffe4cc);
    color: #a5682a;
    border-color: #f0cf9c;
    box-shadow: 0 2px 6px rgba(214, 138, 60, 0.18);
}

/* ============================================================
   6. 内联图标（HTML 上下文，必须给尺寸，否则 SVG 默认 300×150）
   ============================================================ */
.rs2-icon {
    width: 1.05em; height: 1.05em;
    display: inline-block;
    vertical-align: -0.18em;
    flex: 0 0 auto;
    overflow: visible;
}
.rs2-baritem .rs2-icon { width: 1.5em; height: 1.5em; vertical-align: 0; }

/* ============================================================
   7. 关键帧（自带一份，不依赖 restaurant-art.css）
   ============================================================ */
@keyframes rs2-breathe { 0%, 100% { transform: translateY(0) scale(1); } 50% { transform: translateY(-2%) scale(1.012); } }
@keyframes rs2-walk    { 0%, 100% { transform: translateY(0) rotate(-1.6deg); } 50% { transform: translateY(-4%) rotate(1.6deg); } }
@keyframes rs2-work    { 0%, 100% { transform: translateY(0) rotate(0deg); } 30% { transform: translateY(-3%) rotate(-2.4deg); } 65% { transform: translateY(0) rotate(2.4deg); } }
@keyframes rs2-sway    { 0%, 100% { transform: rotate(-2deg); } 50% { transform: rotate(2deg); } }
/* 角色专属工作动效：让「在干活」这件事一眼能看出在干哪种活（不另建状态机，只细化演出） */
@keyframes rs2-cook  { 0%, 100% { transform: rotate(0deg) translateY(0); } 25% { transform: rotate(-3deg) translateY(-1.5%); } 50% { transform: rotate(0deg) translateY(-2.5%); } 75% { transform: rotate(3deg) translateY(-1.5%); } }
@keyframes rs2-serve { 0%, 100% { transform: translateY(0) scale(1, 1); } 50% { transform: translateY(2.5%) scale(1.05, 0.95); } }
@keyframes rs2-bill  { 0%, 100% { transform: rotate(0deg); } 38% { transform: rotate(-4.5deg); } 60% { transform: rotate(-4.5deg); } 82% { transform: rotate(0deg); } }
@keyframes rs2-tail    { 0%, 100% { transform: rotate(-6deg); } 50% { transform: rotate(10deg); } }
@keyframes rs2-steam   { 0% { opacity: 0; } 45% { opacity: 0.75; } 100% { opacity: 0; } }
@keyframes rs2-bub     { 0%, 100% { opacity: 0.5; transform: translateY(0); } 50% { opacity: 0.95; transform: translateY(-1.5px); } }
@keyframes rs2-flame   { 0%, 100% { transform: scaleY(1) scaleX(1); } 50% { transform: scaleY(1.22) scaleX(0.94); } }
@keyframes rs2-spark   { 0% { opacity: 0; } 30% { opacity: 1; } 100% { opacity: 0; } }
@keyframes rs2-river   { 0%, 100% { transform: translateX(0); } 50% { transform: translateX(1.6px); } }
@keyframes rs2-sway2   { 0%, 100% { transform: rotate(-1.6deg); } 50% { transform: rotate(1.6deg); } }
@keyframes rs2-pop     { from { opacity: 0; transform: translateY(10px) scale(0.94); } to { opacity: 1; transform: none; } }
@keyframes rs2-rise    { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }

/* ---- 待机动作关键帧 ---- */
@keyframes rs2-act-look    { 0%, 100% { transform: rotate(0deg); } 28%, 66% { transform: rotate(-3.6deg); } }
@keyframes rs2-act-groom   { 0%, 100% { transform: rotate(0deg) translateY(0); } 30% { transform: rotate(3.2deg) translateY(-1px); } 62% { transform: rotate(-1.8deg); } }
@keyframes rs2-act-stretch { 0%, 100% { transform: translateY(0) scale(1, 1); } 40% { transform: translateY(2.2px) scale(1.06, 0.9); } }
@keyframes rs2-act-nap     { 0%, 100% { transform: translateY(0) rotate(-1.2deg); } 50% { transform: translateY(1.6px) rotate(1.8deg); } }
@keyframes rs2-act-tail    { 0%, 100% { transform: rotate(-2.6deg); } 50% { transform: rotate(3.6deg); } }
@keyframes rs2-act-sniff   { 0%, 100% { transform: translateY(0) rotate(0deg); } 45% { transform: translateY(-1.8px) rotate(1.6deg); } }
@keyframes rs2-act-paw     { 0%, 100% { transform: translateY(0) rotate(0deg); } 50% { transform: translateY(-1.6px) rotate(-2.8deg); } }
@keyframes rs2-act-yawn    { 0%, 100% { transform: scale(1, 1); } 34% { transform: scale(1, 1.035) translateY(-0.8px); } }
@keyframes rs2-act-patrol  { 0%, 100% { transform: translateX(0); } 30% { transform: translateX(-2.4px); } 72% { transform: translateX(2.4px); } }
@keyframes rs2-act-swirl   { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }
/* 「这里有活」标记的呼吸：只做整体缩放，不碰任何带 transform 属性的元素 */
@keyframes rs2-act-job      { 0%, 100% { transform: scale(1) translateY(0); } 50% { transform: scale(1.09) translateY(-1.6px); } }
/* 狗宝摇尾巴（fill-box 原点在尾巴根部，见 .rs2-svg .dog-tail 的注释） */
@keyframes rs2-dogwag       { 0%, 100% { transform: rotate(-7deg); } 50% { transform: rotate(12deg); } }
@keyframes rs2-act-star    { 0%, 100% { opacity: 0.28; transform: scale(0.68); } 50% { opacity: 1; transform: scale(1.18); } }
@keyframes rs2-act-sparkle { 0%, 100% { opacity: 0.35; } 50% { opacity: 0.95; } }
@keyframes rs2-act-smell   { 0% { opacity: 0; transform: translateY(4px); } 45% { opacity: 0.95; } 100% { opacity: 0; transform: translateY(-7px); } }
@keyframes rs2-act-gaze    { 0%, 100% { opacity: 0.35; } 45% { opacity: 0.95; } }
@keyframes rs2-act-hop     { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-1.8px); } }
@keyframes rs2-act-dust    { 0% { opacity: 0.6; transform: translateY(0) scale(1); } 100% { opacity: 0; transform: translateY(-3px) scale(1.5); } }
@keyframes rs2-act-gape    { 0%, 100% { transform: scaleY(1); } 34% { transform: scaleY(1.35); } }
/* ---- 窗外风景动效 ---- */
@keyframes rs2-rainfall { from { transform: translateY(-26px); } to { transform: translateY(0); } }
@keyframes rs2-snowfall { from { transform: translate(0, -30px); } to { transform: translate(6px, 0); } }
@keyframes rs2-vfall    { from { transform: translate(0, -44px); } to { transform: translate(-10px, 0); } }
@keyframes rs2-ripple   { 0% { opacity: 0; transform: scale(0.55); } 32% { opacity: 0.5; } 100% { opacity: 0; transform: scale(1.4); } }
@keyframes rs2-flash {
    0%, 87%, 100% { opacity: 0; }
    88% { opacity: 0.62; }
    89.4% { opacity: 0.06; }
    91% { opacity: 0.46; }
    93% { opacity: 0; }
}

/* ============================================================
   7.5 猫咪生活层浮层（GB.RestaurantLife）
   ------------------------------------------------------------
   舞台里的角色是 SVG <g>，装不下 HTML 气泡，所以气泡挂在「坐标锚点」上：
   JS 用 getScreenCTM 把猫的世界坐标换成像素，写成锚点的 left/top。

   ★ 锚点的 transform 必须在 keyframes 里写全（含 translate(-50%,…)) ——
     入场动画会覆盖 transform，只写 translateY 的话气泡会掉到左上角。
   ★ .rs-say 在锚点内必须是 static 且无动画，否则两套 transform 打架。
   ============================================================ */
.rs2-stagewrap .rs-say-at {
    position: absolute;
    z-index: 31;
    pointer-events: none;               /* 气泡不吃点击，别挡住下面的拖拽/装修 */
    animation: rs2-say-in 0.24s ease forwards;
    transition: opacity 0.3s ease;
}
@keyframes rs2-say-in {
    from { opacity: 0; transform: translate(-50%, calc(-100% + 4px)); }
    to   { opacity: 1; transform: translate(-50%, calc(-100% - 8px)); }
}
.rs2-stagewrap .rs-say-at .rs-say {
    /* ★ 必须保留非行内盒：基础规则里 .rs-say 是 position:absolute（块级盒），
       这里把它改成 static 之后 <span> 会退回**非替换行内元素**，
       而 width / max-width 对行内元素**不适用** → 气泡既不受 168px 上限约束、
       也不会换行（实测长句撑到 370px 单行），再叠加 translate(-50%) 就整条左移、
       不再居中在猫头顶；更糟的是里面的 .rs-say-name 是 display:block，
       行内盒会被切成一堆碎片，padding/border/背景各画一遍（撕裂感）。
       → 用 inline-block 让它重新变成可以设宽度的盒子。 */
    display: inline-block;
    position: static; left: auto; bottom: auto;
    transform: none; animation: none; opacity: 1;
}
.rs2-stagewrap .rs-say-at .rs-say::after { display: none; }  /* 尖角已由锚点间距代替，留着会错位 */
/* 猫贴着后墙站时头顶没有空间放气泡，而容器是 overflow:hidden，上半截会被直接裁掉
   （窄屏尤其明显）→ 翻到脑袋下面去。只换 keyframes，不去动静态 transform：
   定位量必须整段写在 keyframes 里，否则动画一跑气泡就跳回原处。 */
.rs2-stagewrap .rs-say-at.below { animation-name: rs2-say-in-below; }
@keyframes rs2-say-in-below {
    from { opacity: 0; transform: translate(-50%, 20px); }
    to   { opacity: 1; transform: translate(-50%, 14px); }
}
.rs2-stagewrap .rs-say-at.out { opacity: 0; }
/* 多句剧情框直接落在舞台里（CSS 定义在 restaurant.css，这里只对齐圆角风格） */
.rs2-stagewrap .rs-convo { z-index: 40; }

/* ============================================================
   8. 响应式
   ============================================================ */
/* ---- 竖屏「抽屉模式」：面板不再塞在舞台里 ----
   类由 JS 按同一判据加/去（restaurant-scene2.js 的 applySheet / sheetMode），
   这里**不写第二套媒体查询** —— 两处各写一套迟早分叉成
   「JS 把面板搬了爹、CSS 还以为它在舞台里」，面板会突然变成舞台里的一小块。

   背景（都是实测）：竖屏舞台上按宽度缩完只有 ~158px 高，面板被 stagewrap 的 overflow
   夹住 ⇒ 可滚区 73px（内容 1473px、22 行）。而卡片在功能栏以下是整条空白（390×844 空 339px）。
   所以竖屏把面板搬成 .rs2 的流内一项（插在功能栏之前），空白带全归它：
   可滚区 73 → ~300px（平板 190 → ~480px），功能栏也不再被压住。
   宽屏 / 横屏 / 桌面永远看不到这个类 ⇒ 布局与改动前完全一致。 */
.rs2--sheet > .rs2-panel {
    position: static;
    left: auto; right: auto; bottom: auto;
    /* ★ flex-basis 必须是 0：默认 auto 会让「内容高 1473px」变成基础尺寸，
       整行放不下时 flex 按比例压缩 → 旁边的舞台跟着被压扁。
       basis 0 + min-height 0 = 「你只吃剩余空间，内容由内部滚动消化」。
       ★ 2026-10-06：min-height 从 0 改成 min(140px, 24vh) —— 这是「保险丝」，
         正常情况下剩余空间远大于它，行为不变；一旦某个老内核又把布局算塌了，
         面板也至少有 4~5 行可看，而不是 2px 高的一条缝。 */
    flex: 1 1 0;
    min-height: min(140px, 24vh);
    max-height: none;
    margin: 0;
    box-shadow: var(--shadow-soft);
}
/* 舞台钉住自己的比例高度，不被抽屉挤压 */
.rs2--sheet > .rs2-stagewrap { flex: 0 0 auto; }
/* 抽屉占满整卡宽 → 竖屏不再用 2 列卡片（一列 165px 时「买 1 / 买 5 / 买 10」第三个必然换行，
   实测过），改**单列清单**：名称…价格一行、库存一行、三个买按钮一行 —— 手机上反而更好读。 */
.rs2--sheet .rs2-grid { grid-template-columns: 1fr; }

/* ★ 2026-10-06 竖屏可读性：抽屉里行距/字号放宽一档。
   手机上「一眼看清」比「一屏多塞两行」重要；内边距加大也让
   每行的可点面积 ≥ 36px（之前 6px 上下边距在手指下有点挤）。 */
.rs2--sheet .rs2-row { padding: 8px 11px; gap: 10px; }
.rs2--sheet .rs2-rowmain b { font-size: 0.86rem; line-height: 1.45; }
.rs2--sheet .rs2-rowmain small { font-size: 0.75rem; }
.rs2--sheet .rs2-panelbody { padding: 10px 13px 16px; }

/* ---- 竖屏 / 窄屏：舞台是 520×240 的横长条（比例 2.17），容器一旦比它竖得多
   （手机竖屏 390×844、平板竖屏），按宽度缩完上下会空出一大块底色，房子看着
   像悬在半空 —— 这正是「场景很奇怪、像架在河上」的来源之一。
   这里让容器直接取舞台的比例（留白消失），同时把舞台放大 18%：
   房子和猫在手机上大了近两成，两侧只裁掉一点点露台，家具全在视野内。 ---- */
@media (max-aspect-ratio: 6/5) {
    .rs2-stagewrap {
        flex: 0 1 auto;
        aspect-ratio: 520 / 240;
        align-items: stretch;
        max-height: 64vh;          /* 极窄长屏别把下面的功能栏挤没 */
    }
    /* ★ 拆成两条独立规则：选择器列表里只要有一个 :has()，
       老内核会把**整条规则**（连 .rs2-svg 那条一起）当无效丢弃。
       第一条不含 :has()，老内核也能吃到「竖屏放大 18%」的舞台。 */
    .rs2-svg,
    .gb-modal--full .gb-modal-body.rs2-host .rs2-svg {
        width: 118%;
        height: auto;
        flex: 0 0 auto;
    }
    .gb-modal--full .gb-modal-body:has(> .rs2) .rs2-svg {
        width: 118%;
        height: auto;
        flex: 0 0 auto;
    }
}

@media (max-width: 560px) {
    .rs2 { font-size: 0.8rem; gap: 6px; }
    .rs2-chip { padding: 2px 7px; font-size: 0.72rem; }
    .rs2-main { padding: 5px 12px; font-size: 0.8rem; }
    /* ★ 底栏改成**确定性 grid（5 列）**，不再用 flex 比例换行。
       原因（探针实测 2026-09-23）：原来 `flex: 1 1 21%` 一屏只容 4 个，
       底栏从 8 个按钮加到 9 个之后排成 4+4+1 三行、高 40px → 竖屏抽屉的
       可滚区被从 129px 压到 89px（低于 120 的硬要求）。
       固定 5 列 ⇒ 9 个恒为 5+4 两行，增减按钮只动最后一行，不会突然多一行。
       文字靠 .rs2-baritem span{white-space:nowrap} 保不拆行。 */
    .rs2-bar { display: grid; grid-template-columns: repeat(5, 1fr); }
    .rs2-baritem { min-width: 0; padding: 4px 5px; font-size: 0.62rem; }
    .rs2-grid { grid-template-columns: repeat(auto-fill, minmax(112px, 1fr)); gap: 6px; }
    .rs2-panel { left: 6px; right: 6px; bottom: 6px; max-height: 70%; }
    .rs2-stagewrap { border-radius: 12px; }
    .rs2-field { flex: 1 1 100%; }
}
/* 矮屏（横屏手机 / 小笔电）：面板别把舞台顶没 */
@media (max-height: 620px) {
    .rs2-panel { max-height: 78%; }
    .rs2-head { gap: 4px 8px; }
}
@media (min-width: 1000px) {
    .rs2-baritem { min-width: 76px; }
}
