  /* ================= v397：无限画布上的两个「浮窗版」开发预览 =================
     用户口径：
       「无限画布页面右下角新增一个圆形的 icon，点开就是那个 AI 对话（= 开发预览右边那个聊天窗口）；
        左下角第一颗键本来是游戏预览窗口 —— 把当前的布局全删掉，改成开发预览里的**左边**那个窗口。
        相当于：开发预览这一页 = 打开左下角的游戏预览 + 打开右下角的 AI 对话。
        这两个窗口的打开关闭要有缩放动画：游戏预览在左下角 ⇒ 从左下角放大出现、收起时缩回左下角；
        右下角的对话框同理（锚在右下角）。」

     实现口径：**不复制 DOM**（同一份游戏 iframe、同一份对话与流式状态），只给 `.ai-page285`
     套一个浮窗模式类 `ai285-float397`：
       · 容器整层透明 + `pointer-events:none` ⇒ 底下的无限画布**照常可用**（浮窗不是整页替换）；
       · 两栏各自 `position:fixed` 钉到左下 / 右下，恢复吃事件，并带上以**自己所在那个角**为锚点的缩放动画。
     与「开发预览整页」互斥（进整页先收浮窗）；两栏可**同时**开 —— 同时开就是开发预览那一页的浮窗版。 */

  /* ---------- ① 浮窗模式容器：透明 + 不吃事件 ----------
     z 取 48（与开发预览整页同层）：必须**高于**小地图 / 缩放弹层（z47）—— 左栏就摆在小地图那一格上。
     右下角圆钮（z47）在容器之下，但容器整层 pointer-events:none ⇒ 圆钮照样可点、也看得见。 */
  .ai-page285.ai285-float397{
    left:0;right:0;top:0;bottom:0;display:block;background:none;pointer-events:none;z-index:48;
  }
  .ai285-float397>.ai-split285{display:none}   /* 浮窗各占一角，中缝没有意义 */

  /* ---------- ② 左栏 = 左下角「游戏预览」（就是开发预览左窗：游戏画面 + 文件/重启/关闭/角色） ----------
     transform-origin:left bottom ⇒ 出现时**从左下角**放大到实际大小，收起时缩回左下角。
     resize:both 缩的是窗口盒，里面的 iframe 铺满跟着变（与旧游戏预览窗同款手感）。 */
  .ai285-float397>.ai-left285{
    position:fixed;left:14px;bottom:58px;                /* 58px = 让开左下角那颗缩放胶囊 */
    width:460px;height:318px;min-width:260px;min-height:180px;
    transform-origin:left bottom;resize:both;pointer-events:auto;
    box-shadow:var(--shadow);will-change:transform,opacity;
  }
  /* ---------- ③ 右栏 = 右下角「AI 对话」（就是开发预览右窗：消息流 + 排队 + 输入框 + 模型选择） ----------
     transform-origin:right bottom ⇒ 从右下角放大 / 缩回右下角。 */
  .ai285-float397>.ai-right285{
    position:fixed;right:14px;bottom:72px;               /* 72px = 让开右下角那颗圆钮 */
    width:372px;height:min(560px,64vh);min-width:280px;min-height:260px;
    transform-origin:right bottom;resize:both;pointer-events:auto;
    box-shadow:var(--shadow);will-change:transform,opacity;
  }
  .ai285-float397>.ai-left285[hidden],
  .ai285-float397>.ai-right285[hidden]{display:none}      /* 两栏各自开合；flex 子项被 fixed 后 [hidden] 要自己写一条 */

  /* ---------- ④ 缩放动画（收尾由 JS 的定时器负责，不依赖 animationend —— 桩里没有这个事件） ---------- */
  .ai285-float397>.ai-left285.aif-in397,
  .ai285-float397>.ai-right285.aif-in397{animation:aifIn397 .30s cubic-bezier(.2,.9,.25,1.04) both}
  .ai285-float397>.ai-left285.aif-out397,
  .ai285-float397>.ai-right285.aif-out397{animation:aifOut397 .20s cubic-bezier(.4,0,.72,.28) both}
  @keyframes aifIn397{from{transform:scale(.04);opacity:0}to{transform:scale(1);opacity:1}}
  @keyframes aifOut397{from{transform:scale(1);opacity:1}to{transform:scale(.04);opacity:0}}

  /* ---------- ⑤ 右下角那颗圆形 icon（AI 对话开关） ----------
     配色与聊天发送键 `.ai-send285` 同口径：强调色渐变 + `#0b0d12` 图标（全站「强调色实底上的字」统一是它），
     不发明一次性颜色。开着的状态反向（透明底 + 强调色描边与图标），再点一下收起。 */
  .aifab397{
    position:fixed;right:14px;bottom:14px;z-index:47;
    width:46px;height:46px;padding:0;border:0;border-radius:50%;
    background:linear-gradient(135deg,var(--accent),var(--accent-2));color:#0b0d12;
    display:grid;place-items:center;cursor:pointer;box-shadow:var(--shadow);
    transition:transform .15s,background .15s,color .15s,box-shadow .15s;
  }
  .aifab397 svg{width:22px;height:22px;display:block}
  .aifab397:hover{transform:scale(1.06);filter:brightness(1.06)}
  .aifab397:active{transform:scale(.97)}
  .aifab397[aria-pressed="true"]{
    background:var(--card);color:var(--accent);box-shadow:0 0 0 1px var(--accent),var(--shadow);
  }
  /* 开发预览整页时没有浮窗（整页自带那两栏），圆钮收掉；
     项目主页（#homeView，z60 整屏）本来就把 z47 的圆钮整个盖住，不用再写一条。 */
  body.ai285-on .aifab397{display:none!important}
  /* v397：参考图拾取态（body.ref-pick-ui268）圆钮一起下移出画 —— 与左下角缩放胶囊同款让位，
     免得「点画布挑节点」那会儿圆钮正好压在落点上；退出拾取态原路移回。 */
  body.ref-pick-ui268 .aifab397{transition:transform .35s ease;transform:translateY(calc(100% + 60px))}
