/* ★ 本文件是构建产物，勿手改（v664 · css-bundle.js 生成）
   来源 = index.html 里 61 个 <link rel=stylesheet> 按原顺序拼接
   源码仍在那 61 个文件里，一张不少、字节不变。
   回退 = git checkout -- pixel-resizer/index.html（本文件随之不用）*/

/* ══════ 01-tokens.css ══════ */
  :root{
    /* ================= v316：底色 / 品牌色板（全站唯一来源）；v321 拆两支 =================
       ① 底色只有一个概念 —— 首页 / 主界面 / 画布（工作流 + 地图）三处的「底」是同一个 --bg。
          改这一个值 = 全站底部同时改，别再为某个页面单独写底色。
       ② v321 用户口径：「背景色饱和度对了，但高亮的蓝色不要改变，把高亮蓝改回去，
          并确定为全局固定颜色搭配」⇒ 品牌色拆成两支：
          a. 低饱和支（背景面）—— --brand 青灰 #5a8fa3 / --brand-soft 柔光底。
             只喂「大面积面」：柔光底、选中底色、拾取条渐变、主页像素、画布淡填充。
          b. 高亮支（实色）—— --brand-hl 荧光青 #14d6ff / --brand-hl-2 #7ce9ff。
             喂「描边 / 选中实底 / 线条 / ＋ / 渐变按钮 / 聚焦圈 / 高亮光晕」。
             ⚠️ 全局固定：只在 :root 定义一次，暗色块**不覆盖**（两主题同值）。
       ③ semantic（--accent*）= 组件里只用这三个，别直接引 --brand*：
          --accent / --accent-2 取高亮支；--accent-soft 取低饱和支。
       ④ --canvas 语义收窄成「画布底」且恒等于 --bg；「凹面」（输入框 / 气泡 / 次级块）
          换新 token --sunken（比卡片低一档）。 */
    --bg:#f4f5f8;
    --canvas:var(--bg);
    --sunken:#eef0f5;
    --card:#ffffff;
    --line:#e3e5ec;
    --line-strong:#d2d6e0;
    --text:#1a1d26;
    --text-2:#5b6070;
    --text-3:#8b90a0;
    --brand:#5a8fa3;        /* 青灰 · 低饱和 —— 背景面基色（柔光底 / 选中底色 / 大面积面） */
    --brand-soft:#dcebf1;   /* 青灰 · 柔 —— 柔光底 / 选中底色 */
    --brand-hl:#14d6ff;     /* 荧光青 —— 高亮实色（描边 / 选中实底 / 线条 / ＋ / 渐变按钮 / 聚焦圈）· 全局固定，两主题同值 */
    --brand-hl-2:#7ce9ff;   /* 荧光青 · 亮 —— 高亮渐变末端 */
    --accent:var(--brand-hl);
    --accent-2:var(--brand-hl-2);
    --accent-soft:var(--brand-soft);
    --ok:#0f9d70;
    --shadow:0 1px 2px rgba(20,22,35,.04), 0 8px 24px rgba(20,22,35,.06);
    --radius:14px;
    /* v365：补三个「用了但从来没定义」的变量 —— --sans 在全站被 var() 引用了 14 次却没有定义，
       CSS 的 font 简写里含未定义变量 = 计算值阶段整条 font 声明失效 ⇒ 那 14 处按钮 / 提示的
       字号一直退回继承的 14px（设计意图是 12.5px / 20px 等）。--dim / --text-1 同理（颜色退回继承）。 */
    --sans:"PingFang SC","Microsoft YaHei",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;
    --dim:var(--text-3);
    --text-1:var(--text);
  }
  /* v185：深色主题 —— 变量整组翻转；字面色由 <style> 末尾的「深色镜像」规则段覆盖 */
  :root[data-theme="dark"]{
    color-scheme:dark;
    --bg:#0b0d12;
    --canvas:var(--bg);
    --sunken:#0d0d0d;
    --card:#191c24;
    --line:#262a35;
    --line-strong:#323748;
    --text:#e8eaf2;
    --text-2:#a7adbf;
    --text-3:#7d8398;
    --brand-soft:rgba(90,143,163,.20);
    --accent:var(--brand-hl);
    --accent-2:var(--brand-hl-2);
    --accent-soft:var(--brand-soft);
    --ok:#2cc98f;
    --shadow:0 1px 2px rgba(0,0,0,.45), 0 8px 24px rgba(0,0,0,.5);
  }
  *{box-sizing:border-box}
  html{height:100%}
  body{
    background:var(--bg);
    color:var(--text);
    font:14px/1.6 "PingFang SC","Microsoft YaHei",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;
    -webkit-font-smoothing:antialiased;
    padding:0;height:100%;overflow:hidden;
  }

/* ══════ 02-shell.css ══════ */
  /* 全屏画布：.app 铺满视口，所有 UI 都是它上面的浮层 */
  .app{position:fixed;inset:0;overflow:hidden}

  /* ---------- 悬浮顶栏 ---------- */
  .topbar{
    position:absolute;top:12px;left:14px;right:14px;z-index:30;
    display:flex;align-items:flex-start;gap:10px;pointer-events:none;
  }
  /* v287：顶栏三块（左上项目管理 / 中间页面切换 / 右上登录）统一成同一规格 ——
     同一条顶线（都在 .topbar 顶部）、同高 42px、同圆角 14px、同样的 0 12px 内边距；
     内侧控件也统一 30px（.btn / .icon-btn / 项目胶囊）。 */
  .topbar-left,.topbar-right{
    pointer-events:auto;display:flex;align-items:center;gap:10px;
    height:42px;box-sizing:border-box;
    background:rgba(255,255,255,.9);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);
    border:1px solid var(--line);border-radius:14px;padding:0 12px;box-shadow:var(--shadow);
  }
  .topbar-right{margin-left:auto;flex-wrap:nowrap;justify-content:flex-end}
  /* v287：内侧控件同高 30px —— 原来登录区 .btn 是 38px，把整块撑到 54px，比左右两块都高 */
  #acctArea .btn{height:30px;box-sizing:border-box;padding:0 12px}
  #acctArea .icon-btn{width:30px;height:30px;flex:0 0 30px}
  .topbar-left .proj-pill204{height:30px;box-sizing:border-box;padding:0 9px}
  /* v122：左上角只放 Starme 字标图（黑字透明底，浅色顶栏直接用）。
     v124：logo 缩小（26→19px），左上角白盒（框）尺寸保持不变——
     高度 42px / 最小宽 124px 焊死（= 原 26px 字标 + 7/12 内边距 + 边框的占位），logo 居中 */
  .topbar-left{height:42px;box-sizing:border-box;min-width:124px;justify-content:center}
  .brand-logo{display:block;height:19px;width:auto;user-select:none;-webkit-user-drag:none}

  /* ---------- 功能面板（挂在「输出结果」节点下面，跟着节点走） ---------- */
  /* 宽横版：几张卡片并排铺开，不再是 336px 的一长条竖条。
     迭代 51：880 → 1000 —— 三张卡并排时每张 317px（内容 293px），容差滑块那一行
     （识别容差 + 128px 滑块 + 值气泡 ≈ 255px）才装得下，不再挤成两行。
     v246：整体再降一档 1000 → 900（900 时三卡内容 260px 仍 ≥ 255，容差行装得下）。 */
  .sheet{
    position:absolute;left:0;top:0;width:min(900px,calc(100vw - 28px));z-index:32;
    max-height:min(620px,calc(100vh - 130px));
    display:flex;flex-direction:column;overflow:hidden;
    background:rgba(255,255,255,.97);backdrop-filter:blur(16px);-webkit-backdrop-filter:blur(16px);
    border:1px solid var(--line);border-radius:16px;
    box-shadow:0 20px 56px rgba(20,22,35,.24);
    will-change:transform;
    animation:sheetIn .16s ease-out;
  }
  .sheet[hidden]{display:none}
  /* 只淡入：位置由 JS 的 translate 决定，keyframes 里不能再碰 transform */
  @keyframes sheetIn{from{opacity:0}to{opacity:1}}
  /* 顶部只留一行：左边两个模式按钮，右边一个主按钮（下载 PNG / 生成切割） */
  .sheet-bar{
    flex:0 0 auto;display:flex;align-items:center;gap:6px;
    padding:7px 9px;border-bottom:1px solid var(--line);background:#fff;
  }
  .sheet-bar .spacer{flex:1;min-width:0}
  .icon-btn{
    width:26px;height:26px;flex:0 0 26px;border-radius:8px;border:1px solid var(--line);
    background:#fafbfd;color:var(--text-2);font:inherit;font-size:12px;line-height:1;
    cursor:pointer;transition:.15s;
  }
  .icon-btn:hover{border-color:var(--accent);color:var(--accent);background:var(--accent-soft)}
  .icon-btn[hidden]{display:none}
  .sheet-body{flex:1;min-height:0;overflow-y:auto;padding:10px 12px 12px}
  .sheet-foot{
    flex:0 0 auto;border-top:1px solid var(--line);
    background:rgba(250,251,253,.96);padding:10px 14px 12px;
  }
  .sheet-foot[hidden]{display:none}
  .sheet-foot:empty{display:none}
  /* 卡片栅格：宽了自动 3 列，窄了自动 2 列 / 1 列 */
  .sheet-cols{
    display:grid;gap:12px;align-items:start;
    grid-template-columns:repeat(auto-fit,minmax(248px,1fr));
  }
  /* 迭代 49：切割模式只剩「切割参数」这一张卡 —— 尺寸与渲染方式都归像素处理（见
     syncSizeCard / syncFramesCard），单卡自然就在这个栅格里铺满，不再需要给谁排位；
     改让这张卡自己的几项设置横向铺开，免得一张窄卡被拉满一整幅、控件全挤到最右边。
     面板窄下来时 auto-fit 会自己退成一列。 */
  /* 迭代 55：加 :not([hidden]) —— 这条 display:grid 的优先级会压过 [hidden] 的 display:none
     （真浏览器里 hidden 会被它压掉、卡赖着不走）。 */
  .sheet[data-work="slice"] .sheet-cols #panelSlice:not([hidden]){
    display:grid;grid-template-columns:repeat(auto-fit,minmax(262px,1fr));
    gap:6px 24px;align-items:center;
  }
  .sheet[data-work="slice"] .sheet-cols #panelSlice .opt{margin-top:0}
  /* v385：最小图案 / 合并间距 / 四周留白 三档排成一排 —— 滑轨 128 收到 96，
     三列各约 268px（900 面板）时「4 字标签 + 滑轨 + 值」正好装下，面板窄了自己退列。 */
  #panelSlice .rng{width:96px}
  /* 迭代 34：取帧面板 = 帧图墙（不再有动画预览小窗；预览就是画布上那个节点） */
  .frames-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(56px,1fr));gap:6px;
    margin:8px 0 2px;max-height:266px;overflow:auto;padding:2px}
  .frame-cell{position:relative;padding:0;border:1px solid rgba(26,29,38,.14);border-radius:7px;
    background:#fff;cursor:pointer;overflow:hidden;line-height:0;transition:.12s}
  .frame-cell canvas{width:100%;height:auto;display:block}
  .frame-cell b{position:absolute;left:3px;top:3px;font:600 9px/1 system-ui,sans-serif;
    padding:2px 3px;border-radius:4px;background:rgba(26,29,38,.55);color:#fff}
  .frame-cell:hover{border-color:var(--accent)}
  .frame-cell.on{border-color:var(--accent);box-shadow:0 0 0 2px var(--accent-soft)}
  .frame-cell.on b{background:var(--accent);color:#0b0d12}
  .frame-cell.off canvas{opacity:.4}
  .frames-empty{font-size:11px;color:var(--text-2);padding:6px 2px;grid-column:1/-1}
  /* 面板里的卡片改成扁一点，别再套一层阴影 */
  .sheet-body .card{padding:11px 12px;box-shadow:none;background:#fff}
  .sheet-body .card h2{margin:0 0 9px}
  /* ---- v385：功能面板的卡片不再各画一圈「区域框」----
     用户口径：像素 / 切割 / 调色这三块里的「单独区域框」全去掉，整块并成一个平面；
     v387：像素处理并成一张平卡（#cardSize / #cardRender 壳留闸在、内容搬空 :empty 退场）。
     v574：序列帧卡也并入同一口径 —— 面板只留最外面那一圈（.sheet 自身）边框。 */
  #panelSheet .sheet-body .card{border-color:transparent;background:transparent}
  /* ---- v387：像素处理 = 一张平卡（参考图口径）----
     第一行四颗开关（自动抠图 / 连续 / 消除锯齿 / 平滑插值，竖线分隔、说明全进 title），
     下面两列两行：识别容差 | 宽高比例（宽框 + 锁图标 + 高框）、背景 | 常用尺寸。
     v385 的「输出尺寸 / 导出设置」两张卡整卡并入 —— 壳还在（el.cardSize / el.cardRender
     的 hidden 闸一行不动），内容搬空后用 :empty 退出栅格、不占列。 */
  #panelSheet .sheet-body #cardSize:empty,
  #panelSheet .sheet-body #cardRender:empty{display:none}
  /* 开关行：四颗一行，中间一道 var(--line) 竖线（与调色卡两栏分隔同款） */
  .sw-row387{display:flex;align-items:center;gap:14px;flex-wrap:wrap}
  .sw387 + .sw387{border-left:1px solid var(--line);padding-left:14px}
  .sw-row387 .switch{margin-top:0;gap:7px}
  .sw-row387 .switch em{font-size:12px;font-weight:500;color:var(--text-2);white-space:nowrap}
  /* 两列两行：中缝一道竖线，面板窄了自动退一列 */
  .grid387{display:grid;grid-template-columns:1fr 1fr;gap:11px 0;margin-top:13px}
  .cell387{min-width:0;padding-right:20px}
  .cell387:nth-child(even){border-left:1px solid var(--line);padding-left:20px}
  @media (max-width:760px){
    .grid387{grid-template-columns:1fr}
    .cell387{padding-right:0}
    .cell387:nth-child(even){border-left:none;padding-left:0}
  }
  /* 锁图标钮（v387：「锁定比例」开关换成参考图式小锁）—— 勾上 = 合上的锁 + 主题色 */
  .arlock387{position:relative;display:inline-flex;align-items:center;justify-content:center;
    width:30px;height:26px;flex:0 0 auto;border:1px solid var(--line-strong);border-radius:7px;
    cursor:pointer;transition:.15s;color:var(--text-3)}
  .arlock387:hover{border-color:var(--accent)}
  .arlock387 input{position:absolute;opacity:0;pointer-events:none;margin:0}
  .arlock387 .lk387{width:13px;height:13px}
  .arlock387 .lk-on387{display:none}
  .arlock387 input:checked ~ .lk-on387{display:block}
  .arlock387 input:checked ~ .lk-off387{display:none}
  .arlock387 input:checked ~ .lk387{color:var(--accent)}
  /* 识别容差：滑轨在格子里拉长（标签 + 长滑轨 + 数字框，参考图口径） */
  #cutoutPanel .rng-wrap{flex:1 1 auto}
  #cutoutPanel .rng{flex:1 1 auto;width:auto;min-width:96px}
  /* v385：背景那一排选项按钮 —— v387：参考图口径 = 裸文字签（无边框无底色，选中档亮主题色描边） */
  .bg-chips385{display:flex;gap:2px;flex:1 1 auto;min-width:0;margin-left:6px;flex-wrap:nowrap}
  .bg-chips385 .spec-opt249{
    flex:0 1 auto;min-width:0;padding:5px 8px;gap:0;border-radius:8px;
    flex-direction:row;justify-content:center;font-size:12px;
    border-color:transparent;background:transparent;
  }
  .bg-chips385 .spec-opt249:hover{border-color:transparent}
  .bg-chips385 .spec-opt249.on{background:transparent}
  html[data-theme="dark"] .bg-chips385 .spec-opt249{background:transparent}
  html[data-theme="dark"] .bg-chips385 .spec-opt249:hover{background:transparent}
  html[data-theme="dark"] .bg-chips385 .spec-opt249.on{background:transparent}
  /* ---- v386：宫格切割弹窗（切割功能区「宫格切割」键）----
     左列预设复用全站选项类 .spec-opt249（整行、左对齐，与模型弹窗同款行式）；
     右边 5×5 扫格：格子底 var(--sunken)（双主题自带），悬停高亮 var(--accent)，
     中缝一道 var(--line) 竖线 —— 不发明任何一次性颜色。 */
  .grid-pop386{display:flex;align-items:stretch;min-width:0;padding:10px}
  .grid-list386{display:flex;flex-direction:column;gap:4px;width:138px;flex:0 0 auto}
  .grid-list386 .spec-opt249{
    flex:0 0 auto;width:100%;min-width:0;flex-direction:row;align-items:center;
    justify-content:flex-start;gap:0;padding:8px 10px;text-align:left;
  }
  .grid-custom386{flex:1 1 auto;min-width:0;border-left:1px solid var(--line);padding-left:10px;margin-left:10px}
  .grid-custom-head386{display:flex;align-items:center;justify-content:space-between;gap:10px;margin:0 0 8px}
  .grid-custom-head386 .spec-sec249{margin:0}
  .grid-dim386{font:600 12px/1 var(--sans);font-style:normal;color:var(--accent);white-space:nowrap}
  .grid-cells386{display:grid;grid-template-columns:repeat(5,24px);gap:5px}
  .grid-cell386{width:24px;height:24px;padding:0;border:none;border-radius:6px;
    background:var(--sunken);cursor:pointer;transition:background .1s}
  .grid-cell386.on{background:var(--accent)}


/* ══════ 03-params.css ══════ */
  /* ---------- 参数行：一行一个，右边一律是下拉框 ---------- */
  .opt{display:flex;align-items:center;gap:8px;min-height:30px}
  /* 迭代 74：#presetRow（常用尺寸 + 原尺寸）恒显示 —— 隐藏规则与 hidden 切换全撤 */
  /* v208：1/3 卡宽下「常用尺寸 + 滑轨 + 值 + 原尺寸」放不下 —— .rng-wrap 可压缩(min-width:0)
     后内容溢出，数值会压到「原尺寸」按钮上；滑轨 128→96、值位 62→44，整行放得下 */
  #presetRow .rng{width:96px}
  #presetVal{min-width:44px;flex:0 0 auto}
  .opt + .opt{margin-top:5px}
  .opt-name{font-size:12px;color:var(--text-2);flex:0 0 auto}
  /* v138：调色卡左右两栏 —— 左 = 色相 / 饱和度 / 亮度，右 = 色彩平衡（中间一道细分隔线分组） */
  .adj-cols137{display:grid;grid-template-columns:1fr 1fr;gap:0 20px;align-items:start}
  .adj-col137{min-width:0}
  .adj-col137 + .adj-col137{border-left:1px solid var(--line);padding-left:20px}
  /* 面板窄下来时退回一列（不画分隔线了，改成上下的自然间距） */
  @media (max-width:760px){
    .adj-cols137{grid-template-columns:1fr;gap:0}
    .adj-col137 + .adj-col137{border-left:none;padding-left:0}
  }
  .sel{
    margin-left:auto;flex:0 1 auto;min-width:0;max-width:100%;
    font:inherit;font-size:12px;color:var(--text);cursor:pointer;
    padding:5px 6px;border:1px solid var(--line-strong);border-radius:8px;background:#fff;
    outline:none;transition:.15s;
  }
  .sel:focus{border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-soft)}
  .sel:disabled{opacity:.5;cursor:not-allowed}
  /* 迭代 39：切割面板的参数改成滑动条（一行 = 名字 + 滑轨 + 当前值，下面一行写两端档位） */
  .rng-wrap{margin-left:auto;display:flex;align-items:center;gap:9px;flex:0 1 auto;min-width:0}
  .rng{
    -webkit-appearance:none;appearance:none;flex:0 0 auto;
    width:128px;height:16px;background:transparent;cursor:pointer;outline:none;
  }
  .rng::-webkit-slider-runnable-track{height:4px;border-radius:999px;background:var(--line-strong)}
  .rng::-webkit-slider-thumb{
    -webkit-appearance:none;appearance:none;width:14px;height:14px;margin-top:-5px;
    border-radius:50%;background:#fff;border:2px solid var(--accent);
    box-shadow:0 1px 3px rgba(15,23,42,.22);transition:transform .12s;
  }
  .rng:hover::-webkit-slider-thumb{transform:scale(1.08)}
  .rng:focus-visible::-webkit-slider-thumb{box-shadow:0 0 0 4px var(--accent-soft)}
  .rng::-moz-range-track{height:4px;border-radius:999px;background:var(--line-strong)}
  .rng::-moz-range-thumb{width:12px;height:12px;border:2px solid var(--accent);border-radius:50%;background:#fff}
  .rng-val{
    font-size:12px;font-weight:600;color:var(--text);min-width:62px;text-align:right;
    font-variant-numeric:tabular-nums;
  }
  /* v135：色彩平衡三条 —— 轨道画成互补色渐变（青↔红 / 洋红↔绿 / 黄↔蓝），
     往哪边拖就偏哪边的色；滑块照旧白底蓝边，规则要放在 .rng 轨道之后才能盖过去 */
  .rng-bal-r::-webkit-slider-runnable-track{background:linear-gradient(90deg,#22c9c9,#e04646)}
  .rng-bal-g::-webkit-slider-runnable-track{background:linear-gradient(90deg,#d94f9e,#43bd43)}
  .rng-bal-b::-webkit-slider-runnable-track{background:linear-gradient(90deg,#d9c14a,#4a6ed9)}
  .rng-bal-r::-moz-range-track{background:linear-gradient(90deg,#22c9c9,#e04646)}
  .rng-bal-g::-moz-range-track{background:linear-gradient(90deg,#d94f9e,#43bd43)}
  .rng-bal-b::-moz-range-track{background:linear-gradient(90deg,#d9c14a,#4a6ed9)}
  /* v97：调色数值可直接输入（em 换成 number 输入框，复用 rng-val 的排版） */
  .rng-num{
    width:56px;min-width:0;padding:1px 4px;border:1px solid var(--line);border-radius:6px;
    background:var(--card);font:inherit;font-size:12px;font-weight:600;color:var(--text);
    text-align:center;font-variant-numeric:tabular-nums;
  }
  .rng-num:focus{outline:none;border-color:var(--accent)}

  .row-actions .mini-btn{flex:1}

  /* ---------- 模式切换：两个小图标按钮 ---------- */
  .mode-switch{display:flex;gap:4px;flex:0 0 auto}
  /* v396：序列帧节点 —— 功能键把「序列帧」排最前（像素 / 调色跟在后面）；只挪视觉顺序。
     ⚠️ 选择器故意写 `[data-work^="frame"]` 而不是精确等值那种写法（CSS 内联在 <head>、
     按钮在 <body>，「功能键顺序」那几条自查用的是 html.indexOf 取**首次出现**，
     写成后者会让首次命中的位置掉到 CSS 上 ⇒ 顺序断言假红（v396 实测踩过）。 */
  .mode-switch.seqfirst396 button[data-work^="frame"]{order:-1}
  .mode-switch button{
    font:inherit;font-size:11.5px;font-weight:600;cursor:pointer;transition:.15s;
    display:inline-flex;align-items:center;gap:5px;padding:5px 10px;border-radius:8px;
    border:1px solid var(--line);background:#fafbfd;color:var(--text-2);line-height:1;
  }
  .mode-switch .mi{width:14px;height:14px;flex:0 0 14px}
  .mode-switch button:hover{border-color:var(--accent);color:var(--accent)}
  .mode-switch button.on{
    border-color:var(--accent);color:#fff;   /* v226：选中态字改白（用户口径，不要深字） */
    background:linear-gradient(135deg,var(--accent),var(--accent-2));
  }
  /* 迭代 33：功能选项按「前面接的是图片还是视频」自动置灰（置灰态别再用 hover 的强调色）。
     迭代 52：判据从 disabled 属性换成 aria-disabled —— 真浏览器里 disabled 的按钮不派发 click，
     「点了给一句提醒」就永远触发不到；aria-disabled 只是语义标记，点击照旧能冒泡。 */
  .mode-switch button[aria-disabled="true"],.mode-switch button[aria-disabled="true"]:hover{
    opacity:.42;cursor:not-allowed;border-color:var(--line);color:var(--text-2);
    background:#f4f5f8;box-shadow:none;
  }

  @media (max-width:760px){
    .sheet{width:calc(100vw - 16px)}
    .topbar{left:8px;right:8px;gap:8px}
    .seg{top:0}
    .seg button{padding:6px 9px;font-size:11.5px}
    /* v317：窄屏不许换行 —— 一换行 ⚙ 就掉到第二行（y≈47），正好落进主界面右栏 / 页面层
       （z48/60 > 顶栏 z30）里，点上去命中的是页面不是 ⚙ = 用户报的「右上角设置点不开」
       （实测 ≤360px 必现）。改成恒 42px 单行 + 收掉账户名，保证 ⚙ 永远留在第一行。 */
    .topbar-right{flex-wrap:nowrap;height:42px;min-height:42px;row-gap:0}
    .topbar-right .acct-name{display:none}
    .zoom-pill{left:8px;bottom:8px}
    .zoom-pop{left:8px;bottom:52px}
    .zoom-rng{width:84px}
    .ref-pick258{padding-left:180px}
  }

  .card{
    background:var(--card);border:1px solid var(--line);border-radius:var(--radius);
    padding:18px;box-shadow:var(--shadow);
  }
  .card h2{
    margin:0 0 14px;font-size:13px;font-weight:600;color:var(--text-2);
    display:flex;align-items:center;gap:8px;letter-spacing:.3px;
  }
  /* v118：卡片标题行右侧的动作（如调色「还原」）—— 顶到最右 */
  .card h2 .head-act{margin-left:auto}
  .card h3{margin:18px 0 9px;font-size:12px;font-weight:600;color:var(--text-3);letter-spacing:.4px}

  /* 缩略图（面板头上的当前图片） */
  .thumb{
    width:58px;height:58px;flex:0 0 58px;border-radius:10px;overflow:hidden;
    border:1px solid var(--line);display:grid;place-items:center;
  }
  .thumb img{max-width:100%;max-height:100%;display:block}




  /* ---------- Checkerboard ---------- */
  .checker{
    background-color:#fff;
    background-image:
      linear-gradient(45deg,#e6e8ee 25%,transparent 25%),
      linear-gradient(-45deg,#e6e8ee 25%,transparent 25%),
      linear-gradient(45deg,transparent 75%,#e6e8ee 75%),
      linear-gradient(-45deg,transparent 75%,#e6e8ee 75%);
    background-size:14px 14px;
    background-position:0 0,0 7px,7px -7px,-7px 0;
  }

  /* ---------- Size inputs ---------- */
  /* v387：宽高比例行 —— 宽 / 高小字标签内联在数字框左侧，框体复用 .rng-num */
  .size-row{display:flex;align-items:center;gap:7px;flex:1 1 auto;min-width:0}
  .field{display:flex;align-items:center;gap:5px;flex:1;min-width:0}
  .field em.wname{font-style:normal;font-size:11px;color:var(--text-3);flex:0 0 auto}
  .field .rng-num{flex:1;width:100%;min-width:0}
  .tag{
    display:inline-block;margin-left:5px;font-style:normal;font-size:10px;font-weight:600;
    padding:1px 6px;border-radius:20px;background:var(--accent-soft);color:var(--accent);
    vertical-align:1px;
  }
  .tag[hidden]{display:none}
  input[type=number][readonly]{
    background:#f2f3f7;color:var(--text-2);border-style:dashed;cursor:not-allowed;
  }
  input[type=number][readonly]:focus{border-color:var(--line-strong);box-shadow:none}
  input[type=number]{
    width:100%;padding:9px 10px;font-size:14px;font-weight:600;
    border:1px solid var(--line-strong);border-radius:9px;background:#fff;color:var(--text);
    outline:none;transition:.15s;font-family:inherit;
  }
  input[type=number]:focus{border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-soft)}
  input[type=number]::-webkit-outer-spin-button,
  input[type=number]::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}
  input[type=number]{-moz-appearance:textfield}

  .btn{
    font:inherit;font-size:12.5px;border-radius:9px;border:1px solid var(--line-strong);
    background:#fff;color:var(--text);padding:8px 12px;cursor:pointer;transition:.15s;
    display:inline-flex;align-items:center;gap:6px;justify-content:center;white-space:nowrap;
  }
  .btn:hover{border-color:var(--accent);color:var(--accent)}
  .btn:disabled{opacity:.45;cursor:not-allowed}
  .btn:disabled:hover{border-color:var(--line-strong);color:var(--text)}
  .btn.icon{padding:9px 10px;font-size:14px;line-height:1}
  .btn.ghost{background:#fafbfd}
  .btn.on{background:var(--accent-soft);border-color:var(--accent);color:var(--accent);font-weight:600}
  .btn.primary{
    width:100%;padding:13px;font-size:14.5px;font-weight:600;color:#0b0d12;
    background:linear-gradient(135deg,var(--accent),var(--accent-2));border:none;
    margin-top:14px;
  }
  .btn.primary:hover{filter:brightness(1.06);color:#0b0d12}
  .btn.primary:disabled{background:#c9ccd8;box-shadow:none}
  /* 面板那一行右侧的主按钮（下载 PNG / 生成切割）：不能像卡片里的主按钮那样占满整行 */
  /* v228：顶栏「下载 PNG」与「添加」同款 —— 白底描边块（浅色）/深灰块（深色镜像段）、
     彩色渐变与投影退役，高度统一钉 34px（以下载按钮的高度为准） */
  .sheet-bar .sheet-cta{
    width:auto;margin:0;height:34px;padding:0 15px;font-size:12.5px;font-weight:400;border-radius:9px;
    background:#fff;border:1px solid var(--line-strong);color:var(--text);
    box-shadow:none;
  }
  .sheet-bar .sheet-cta:hover{filter:none;background:#fff;border-color:var(--line-strong);color:var(--text)}
  .sheet-bar .add-wrap157 .btn{height:34px;padding:0 13px;border-radius:9px}

  .row-actions{display:flex;gap:8px;margin-top:8px}
  .row-actions .btn{flex:1}


/* ══════ 04-canvas.css ══════ */
  /* ---------- 全屏画布 ---------- */
  .canvas-wrap{
    position:absolute;inset:0;overflow:hidden;touch-action:none;
    background-color:var(--canvas);
    /* 点阵不再是 CSS 背景：改由 drawStage() 画进 #stage 画布本身（见 drawDots），
       跟节点同一次绘制、同一套 view 变换 —— 拖动时必然同步，不再依赖浏览器的背景重绘 */
  }
  .canvas-wrap canvas{display:block;width:100%;height:100%}
  .canvas-wrap.tool-pan{cursor:grab}
  .canvas-wrap.panning{cursor:grabbing}
  .canvas-wrap.tool-select{cursor:default}
  .canvas-wrap.tool-magic{cursor:crosshair}
  .canvas-wrap.over-handle{cursor:nwse-resize}
  .canvas-wrap.over-node{cursor:move}
  .canvas-wrap.over-plus{cursor:pointer}
  .canvas-wrap.over-link{cursor:pointer}
  .canvas-wrap.over-vid330{cursor:pointer}   /* v330：悬浮在视频节点的播放键 / 进度条上 → 手型（排在 .over-node 之后，优先级够） */
  /* v152：悬浮在标题栏右端那颗「显示口径」键上 → 手型（排在 .over-node 之后，优先级够） */
  .canvas-wrap.marquee{cursor:crosshair}
  .canvas-empty{
    position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;
    gap:8px;color:var(--text-3);pointer-events:none;text-align:center;padding:20px;
  }
  .canvas-empty strong{font-size:16px;color:var(--text-2);font-weight:600}
  .canvas-empty span{font-size:12.5px}
  .canvas-empty .dim{font-size:11.5px;opacity:.8}
  .canvas-empty[hidden]{display:none}
  /* v561：空态只留一句主文案 ⇒ 大图标与那颗选图按钮的样式一并撤掉（两个元素都已从
     index.html 删除）。整层继续穿透给画布 —— 见上面 .canvas-empty 的 pointer-events:none：
     拖动画布 / 拖文件进画布的手势都不受影响。 */
  .canvas-wrap.empty{cursor:grab}
  .canvas-wrap.empty.panning{cursor:grabbing}

  /* v116：底部悬浮工具栏已撤，工具按钮住进 dock-head —— .tool 样式保留给切割功能区用
     v294：与顶栏模式切换（像素/切割/调色）完全同款（用户口径「下面的选择样式统一和上面一样」） */
  .tool{
    font:inherit;font-size:11.5px;font-weight:600;cursor:pointer;transition:.15s;
    display:inline-flex;align-items:center;gap:5px;padding:5px 10px;border-radius:8px;
    border:1px solid var(--line);background:#fafbfd;color:var(--text-2);line-height:1;white-space:nowrap;
  }
  .tool:hover{border-color:var(--accent);color:var(--accent)}
  .tool.on{
    border-color:var(--accent);color:#fff;
    background:linear-gradient(135deg,var(--accent),var(--accent-2));
  }

  /* 迭代 71：缩放胶囊挪到左下角（右下角让给图层面板） */
  .zoom-pill{
    position:absolute;left:14px;bottom:14px;z-index:47;
    display:flex;align-items:center;gap:4px;
    background:rgba(255,255,255,.97);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);
    border:1px solid var(--line);border-radius:11px;padding:4px 6px;box-shadow:var(--shadow);
  }
  .zoom-pill[hidden]{display:none}
  /* v133：胶囊里是「回中键（正方形）+ 连线开关 + 百分比」
     v140：配色反过来 —— 胶囊底板改成白色，三个方键走**画布底色**（和画布同色，
     视觉上像从画布上抠下来贴在白框里），不再需要那层投影把白方块顶出来。 */
  .zoom-pill .zoom-sq{
    width:24px;height:24px;padding:0;display:grid;place-items:center;flex:none;
    font-size:12px;line-height:1;border:1px solid var(--line);border-radius:7px;
    background:var(--sunken);color:var(--text);cursor:pointer;transition:.15s;
  }
  .zoom-pill .zoom-sq:hover{border-color:var(--accent);color:var(--accent);background:var(--accent-soft)}
  /* v139：胶囊里三个功能键统一成**正方形图标**（不带文字）—— 从左到右：小地图 / 隐藏连线 / 回中。
     按压态（aria-pressed="true"）走强调底；[hidden] 必须自己写一条盖住 .zoom-sq 的 display:grid
     （地图页没有连线时那个键要让位）。 */
  .zoom-pill .zoom-sq svg{width:13px;height:13px;display:block}
  .zoom-pill .zoom-sq[aria-pressed="true"]{background:var(--accent);border-color:var(--accent);color:#0b0d12;box-shadow:none}
  .zoom-pill .zoom-sq[hidden]{display:none}
  /* ---------- v137：小地图（左下角缩放胶囊上方；只读导航，不吃主画布事件） ---------- */
  .mini-map{
    position:absolute;left:14px;bottom:58px;z-index:47;
    width:190px;height:132px;border-radius:10px;overflow:hidden;
    /* v141：白色主题 —— 与全站浮窗（白底 + --line 边框 + shadow）同族 */
    background:rgba(255,255,255,.97);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);
    border:1px solid var(--line);box-shadow:var(--shadow);
  }
  .mini-map[hidden]{display:none}
  .mini-map canvas{position:absolute;left:0;top:0;width:100%;height:100%;display:block;cursor:crosshair;touch-action:none}
  .mini-close{
    position:absolute;top:4px;right:4px;z-index:2;
    width:18px;height:18px;padding:0;display:grid;place-items:center;
    font-size:10px;line-height:1;border:none;border-radius:6px;
    background:rgba(20,24,40,.07);color:var(--text-2);cursor:pointer;transition:.15s;
  }
  .mini-close:hover{background:rgba(20,24,40,.16);color:var(--text)}

  /* v456：空态主文案后面那颗「Q 版像素鼠标」图标 —— 像素风（16 网格、直角端点、crispEdges 硬边），
     跟正文同一行；颜色走主题 accent（不发明一次性颜色）。 */
  .canvas-empty .ce-mouse{
    width:20px;height:20px;margin-left:6px;vertical-align:-4px;
    color:var(--accent);opacity:.9;
  }

/* ══════ 05-overlays.css ══════ */
  /* v397：原来的「游戏预览小窗」整套样式（fixed 左下半透明窗体 + 标题栏 + 沙盒 iframe + 空态）已下线 ——
     左下角那颗键改成浮出「开发预览」的左栏（同一份 DOM 换个地方摆），样式在 styles/14-ai-float397.css。 */
  /* 迭代 54：多选大框右下角的「打包下载」—— 迭代 67 起一律打包成 ZIP 下载。
     transform:translate(-100%,0) = 按钮右缘贴着大框右缘、整体吊在框外右下角。 */
  .multi-dl{
    position:absolute;z-index:30;transform:translate(-100%,0);
    font:inherit;font-size:12px;font-weight:600;cursor:pointer;white-space:nowrap;
    padding:6px 12px;border-radius:9px;border:1px solid var(--accent);
    background:linear-gradient(135deg,var(--accent),var(--accent-2));color:#0b0d12;
    transition:.15s;
  }
  .multi-dl:hover{filter:brightness(1.06)}
  .multi-dl[hidden]{display:none}
  .zoom-val{
    font:inherit;font-size:11.5px;color:var(--text-2);font-variant-numeric:tabular-nums;
    min-width:42px;text-align:center;cursor:pointer;user-select:none;
    border:1px solid transparent;border-radius:7px;background:transparent;padding:3px 2px;transition:.15s;
  }
  .zoom-val:hover{border-color:var(--accent);color:var(--accent);background:var(--accent-soft)}
  /* v133：缩放拖动条（点百分比在上方弹出；v167 起对数刻度 1%–4000%） */
  .zoom-pop{
    position:absolute;left:14px;bottom:52px;z-index:47;
    display:flex;align-items:center;gap:6px;padding:4px 8px;
    background:rgba(255,255,255,.97);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);
    border:1px solid var(--line);border-radius:10px;box-shadow:var(--shadow);
    opacity:1;transform:translateY(0);transition:opacity .16s ease,transform .16s ease;
  }
  .zoom-pop[hidden]{display:none}
  /* v134：关闭时渐隐 —— 先挂 .fade-out134 淡出（160ms），动画走完 JS 再补 hidden */
  .zoom-pop.fade-out134{opacity:0;transform:translateY(5px);pointer-events:none}
  /* v134：拖动条宽高都收小一圈 —— 轨道 / 滑块自己画（系统默认滑块太大，光缩 height 没用） */
  .zoom-rng{
    -webkit-appearance:none;appearance:none;flex:0 0 auto;
    width:104px;height:14px;background:transparent;cursor:pointer;outline:none;
  }
  .zoom-rng::-webkit-slider-runnable-track{height:4px;border-radius:999px;background:var(--line-strong)}
  .zoom-rng::-webkit-slider-thumb{
    -webkit-appearance:none;appearance:none;width:11px;height:11px;margin-top:-3.5px;
    border-radius:50%;background:#fff;border:2px solid var(--accent);
    box-shadow:0 1px 3px rgba(15,23,42,.22);
  }
  .zoom-rng:focus-visible::-webkit-slider-thumb{box-shadow:0 0 0 3px var(--accent-soft)}
  .zoom-rng::-moz-range-track{height:4px;border-radius:999px;background:var(--line-strong)}
  .zoom-rng::-moz-range-thumb{width:9px;height:9px;border:2px solid var(--accent);border-radius:50%;background:#fff}

  /* 拖文件到全屏画布上的提示层 */
  .drop-veil{
    position:absolute;inset:14px;z-index:45;border-radius:18px;
    border:2px dashed var(--accent);background:rgba(238,240,255,.9);
    display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6px;
    color:var(--accent);pointer-events:none;
  }
  .drop-veil strong{font-size:18px;font-weight:700}
  .drop-veil span{font-size:12.5px;opacity:.85}
  .drop-veil[hidden]{display:none}

  /* ---------- 迭代 21：图片和功能区中间那个小操作框整个删掉了 ----------
     它原本挂在结果节点和功能面板之间，像素模式显示「输出 W×H · 大小 · PNG」，
     切割模式显示「识别到 N 个 + 全选/全不选/反选 + 打包下载 ZIP」，
     等于在图片和功能面板之间又多出一层窗口。现在两拨内容都并进功能面板：
       · 输出信息      → 「输出尺寸」卡最后一行（v385 起这一行整条删掉了）
       · 勾选 / 打包 ZIP → 面板底部「切片预览」那一栏（#sliceDock） */
  .canvas-wrap.space-pan{cursor:grab}
  .canvas-wrap.space-pan.panning{cursor:grabbing}

  .pill{
    font-size:11px;padding:3px 9px;border-radius:20px;background:var(--accent-soft);color:var(--accent);font-weight:600;
  }
  /* 迭代 69：画面正中间的提示（替代底部黑条的「为什么点不动」类说明） */
  .stage-hint{
    position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);
    background:#1a1d26;color:#fff;font-size:13px;padding:10px 18px;border-radius:10px;
    pointer-events:none;z-index:40;max-width:72%;text-align:center;line-height:1.5;
  }
  .stage-hint[hidden]{display:none}
  /* ---------- v71：顶栏中置「当前工作流 / 地图绘制」 ---------- */
  .seg{
    position:absolute;left:50%;top:0;transform:translateX(-50%);
    pointer-events:auto;display:flex;align-items:center;gap:4px;padding:6px;
    height:42px;box-sizing:border-box;border-radius:14px;
    background:rgba(255,255,255,.9);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);
    border:1px solid var(--line);box-shadow:var(--shadow);
  }
  .seg button{
    font:inherit;font-size:12.5px;font-weight:600;border:none;background:transparent;
    padding:7px 16px;border-radius:9px;color:var(--text-2);cursor:pointer;transition:.15s;line-height:1;
  }
  .seg button:hover{color:var(--accent)}

/* ══════ 06-map.css ══════ */
  .seg button.on{background:var(--accent);color:#0b0d12;box-shadow:0 3px 9px rgba(20,214,255,.28)}
  /* ---------- v71：地图绘制窗口 ---------- */
  /* v371：必须**连写 `.modal.map-win`（0,2,0）** —— 单类 `.map-win` 与 `.modal` 同权重（各 0,1,0），
     而 `.modal` 定义在样式表**更靠后** ⇒ 原来的 max-width:640px 被 `.modal` 的 400px 整条压掉
     （v368 子画布 400px 同族；地图配置窗此前一直是 400px 宽）。 */
  .modal.map-win{max-width:640px}
  .map-cfg{display:flex;align-items:flex-end;gap:10px;flex-wrap:wrap;margin:0 0 10px}
  .map-cfg label{display:flex;flex-direction:column;gap:5px;font-size:11.5px;color:var(--text-3)}
  .map-cfg input{
    width:90px;padding:8px 10px;border:1px solid var(--line-strong);border-radius:9px;
    font:inherit;font-size:13px;outline:none;background:#fff;color:var(--text);
  }
  .map-cfg input:focus{border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-soft)}
  .map-echo{font-size:12px;color:var(--text);font-weight:600;margin:0 0 12px;font-variant-numeric:tabular-nums}
  /* v175：PS「画布大小」同款九宫格锚点 —— 3×3 圆点，选中高亮；面板本体不写字，提示只在 title 里 */
  .anchor175{display:grid;grid-template-columns:repeat(3,15px);grid-template-rows:repeat(3,15px);gap:1px;padding:6px;border:1px solid var(--line-strong);border-radius:10px;background:#fff;margin-left:auto;align-self:center}
  .anchor175[hidden]{display:none}
  .anchor175 button{width:15px;height:15px;padding:0;border:0;background:transparent;cursor:pointer;position:relative}
  .anchor175 button::after{content:'';position:absolute;left:50%;top:50%;width:5px;height:5px;margin:-2.5px 0 0 -2.5px;border-radius:50%;background:#c9ccd8}
  .anchor175 button:hover::after{background:var(--accent);transform:scale(1.3)}
  .anchor175 button.on::after{background:var(--accent);transform:scale(1.9)}
  #askOverlay{z-index:90}
  #askMsg{white-space:pre-line}
  /* ---------- v78：地图浮层（素材栏 + 生成地图）—— 网格直接画在主画布上，无容器框 ---------- */
  #mapBar{
    position:fixed;left:50%;bottom:14px;transform:translateX(-50%);z-index:33;
    display:flex;flex-direction:column;gap:14px;max-width:min(1060px,calc(100vw - 60px));
    padding:10px 14px;
    background:rgba(255,255,255,.97);backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);
    border-radius:14px;box-shadow:0 10px 30px rgba(20,22,35,.14);
  }
  #mapBar[hidden]{display:none}
  /* v87/v89：控制排 —— 左侧 随机旋转 / 隐藏网格 / 一键铺满，右侧 新建地图，单独一行摆在素材上面 */
  .map-bar-top{display:flex;align-items:center;gap:18px;flex:0 0 auto}
  .map-bar-left{display:flex;align-items:center;gap:18px;flex:0 0 auto}
  .map-bar-top .spacer{flex:1;min-width:0}
  /* v81：只展示素材图片（无标题 / 无提示 / 无按钮），缩略图 64px */
  /* v173：素材栏布局改造 —— 由「单行横向左右滚动」改成「网格自动换行 + 垂直上下滚动」。
     素材卡片尺寸一个字不动（仍 64px），切换 1 / 2 / 3 排只改容器高度（见下面三档 .rows*-173）。
     scrollbar-gutter:stable 是让滚动条槽一直占着位置 —— 不然素材一多，滚动条一冒出来
     可用宽度就变窄、每排能放几张跟着跳，切档时会看见卡片重排抖动。 */
  .map-asset-list{
    display:grid;grid-template-columns:repeat(auto-fill,64px);grid-auto-rows:64px;gap:8px;align-content:start;
    overflow-x:hidden;overflow-y:auto;scrollbar-gutter:stable;
    /* v109：宽度固定 —— 素材再多也只在容器内部滚动（不再把浮层撑宽）；上留白给小叉 */
    flex:0 0 auto;width:min(860px,62vw);padding:14px 12px;   /* v136：右侧 12px 给最后一张的小叉（原 4px 会被裁掉） */
    scrollbar-width:thin;scrollbar-color:var(--line-strong) transparent;
  }
  /* v173：三档高度 = 上下留白 28 + N 排 ×64 + (N-1)×8 —— 上限锁死 3 排，免得素材栏把画布挡严实 */
  .map-asset-list.rows1-173{height:92px}
  .map-asset-list.rows2-173{height:164px}
  .map-asset-list.rows3-173{height:236px}
  .map-asset-list::-webkit-scrollbar{width:8px}
  .map-asset-list::-webkit-scrollbar-track{background:transparent}
  .map-asset-list::-webkit-scrollbar-thumb{background:var(--line-strong);border-radius:4px}
  .map-asset-list::-webkit-scrollbar-thumb:hover{background:var(--text-3)}
  /* v109：图片与外框尺寸一致（去掉内边距）；四角由内层 .map-shot 按外框倒角做视觉裁剪（纯视觉，像素绘制不变） */
  .map-asset{position:relative;width:64px;height:64px;flex:0 0 64px;border:2px solid var(--line);border-radius:10px;padding:0;cursor:pointer;background:#fff}
  .map-shot{width:100%;height:100%;border-radius:8px;overflow:hidden}
  .map-asset canvas{width:100%;height:100%;display:block;image-rendering:pixelated}
  /* v110：选中边框加重（3px 实色 + 4px 光晕），辨识度拉满 */
  .map-asset.on{border:3px solid var(--accent);box-shadow:0 0 0 4px var(--accent-soft)}
  /* v83：选中素材右上角的小叉（删除该素材，格子引用跟着重排） */
  .map-asset-x{
    position:absolute;top:-9px;right:-9px;width:20px;height:20px;border-radius:50%;
    border:1px solid var(--line);background:#fff;color:var(--text-2);
    font-size:11px;line-height:1;cursor:pointer;display:none;place-items:center;padding:0;z-index:2;
  }
  /* v90：小叉悬浮 / 选中时出现（每个素材都带一个，不再只渲染选中的那个） */
  /* v110：小叉只跟随悬浮（选中态不再常驻，免得满屏叉） */
  .map-asset:hover .map-asset-x{display:grid}
  .map-asset-x:hover{color:#d33;border-color:#d33}
  /* v83：素材末尾永久保留的加号空位（点击回工作流加素材） */
  .map-asset.map-add{
    display:grid;place-items:center;font-size:24px;color:var(--text-3);
    border-style:dashed;background:transparent;user-select:none;
  }
  .map-asset.map-add:hover{color:var(--accent);border-color:var(--accent)}
  /* v109：多选改全局开关（左上角勾选框撤掉）—— 池里选中的卡片照旧高亮 */
  .map-asset.multi{border:3px solid var(--accent);box-shadow:0 0 0 4px var(--accent-soft)}
  /* v157：素材分类切换 —— 分段高亮胶囊，与随机旋转等 .mini-btn 功能按钮明显区分 */
  /* v315：与视频生成选项按钮同款三态（原 accent 实线分段退役） */
  .map-cat{display:flex;flex:0 0 auto;gap:6px}
  .map-cat-btn{appearance:none;border:1px solid var(--line);background:var(--card);color:var(--text);
    font:500 12.5px/1 var(--sans);padding:9px 14px;border-radius:10px;cursor:pointer;white-space:nowrap;transition:.15s}
  .map-cat-btn:hover{border-color:var(--accent);color:var(--accent)}
  .map-cat-btn.on{border-color:var(--accent);background:var(--accent-soft);color:var(--accent)}
  html[data-theme="dark"] .map-cat-btn{background:#232631;border-color:transparent;color:#e8eaf1}
  html[data-theme="dark"] .map-cat-btn:hover{background:#262a35;color:var(--accent)}
  html[data-theme="dark"] .map-cat-btn.on{background:var(--accent-soft);border-color:var(--accent);color:var(--accent)}
  /* v157：工作流【添加】渐变悬浮菜单 —— v159 起弹出层挂 body 用 fixed 定位
     （.sheet 的 overflow:hidden + will-change:transform 会把 absolute 弹层整块裁掉），JS 摆到按钮上方；点窗外关闭、窗内点击不关 */
  .add-wrap157{position:relative;display:inline-flex}
  .add-menu157{position:fixed;z-index:400;
    display:flex;flex-direction:column;gap:6px;min-width:176px;padding:8px;
    border:1px solid var(--line);border-radius:12px;
    background:#fff;                       /* v166：纯白（v160 那条渐变撤掉） */
    box-shadow:0 10px 28px rgba(20,24,40,.18)}
  .add-menu157[hidden]{display:none}
  .add-opt157{appearance:none;border:0;border-radius:9px;background:transparent;
    color:var(--text);font:500 13px system-ui,sans-serif;padding:9px 12px;cursor:pointer;
    text-align:left;white-space:nowrap}
  .add-opt157:hover{color:var(--accent);background:var(--accent-soft)}
  /* v166：地图【随机】设置窗 —— 与【添加】同一套弹层口径（挂 body + fixed 摆到按钮上方；
     点窗外关闭、窗内点击不关），底色纯白；随机旋转单选 / 随机翻转复选 */
  .rand-menu166{position:fixed;z-index:400;
    display:flex;flex-direction:column;gap:4px;min-width:190px;padding:8px;
    border:1px solid var(--line);border-radius:12px;
    background:#fff;
    box-shadow:0 10px 28px rgba(20,24,40,.18)}
  .rand-menu166[hidden]{display:none}
  .rand-cap166{color:var(--text-3);font:600 11px system-ui,sans-serif;padding:4px 8px 2px}
  .rand-opt166{display:flex;align-items:center;gap:8px;padding:7px 8px;border-radius:9px;
    color:var(--text);font:500 13px system-ui,sans-serif;cursor:pointer;white-space:nowrap}
  .rand-opt166:hover{color:var(--accent);background:var(--accent-soft)}
  .rand-opt166 input{accent-color:var(--accent);width:14px;height:14px;margin:0;flex:0 0 14px}
  /* v172：【变化】按钮 = 图标 + 文字（本体还是 .mini-btn，跟【随机】同一套样式）。
     ⚠️ [hidden] 必须显式压回 none —— .mini-btn 一旦带上 display:inline-flex，
     属性选择器 [hidden] 的优先级就盖不住它（装饰模式下按钮要跟着藏）。 */
  .mini-btn.with-ico172{display:inline-flex;align-items:center;gap:5px}
  .mini-btn[hidden]{display:none}
  .mini-btn.with-ico172 svg{width:12px;height:12px;flex:0 0 12px;fill:none;stroke:currentColor;
    stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round}
  /* v173：素材栏右上角那颗「展示行数」按钮 —— 纯图标、界面里没有任何文字，
     几排只看小矩形里有几条横线；文字只活在 title 悬浮提示里。 */
  .mini-btn.ico-only173{display:inline-flex;align-items:center;justify-content:center;padding:5px 7px}
  .mini-btn.ico-only173 svg{width:14px;height:14px;flex:0 0 14px;fill:none;stroke:currentColor;
    stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
  /* v180：【隐藏网格】/【吸附】用 .ico-only173 这套纯图标按钮 —— 必须显式把 [hidden] 压回 none：
     .mini-btn.ico-only173 的 display:inline-flex 定义在上面那条 .mini-btn[hidden] 之后，
     所以【吸附】在「地块绘制」模式下藏不掉。 */
  .mini-btn.ico-only173[hidden]{display:none}
  /* v180：【吸附】设置窗里的步长输入框（只收正整数；1 = 关闭吸附） */
  .snap-inp180{width:100%;box-sizing:border-box;margin:2px 0 4px;padding:7px 9px;
    border:1px solid var(--line);border-radius:9px;
    background:#fff;color:var(--text);font:600 13px system-ui,sans-serif;outline:none}
  .snap-inp180:focus{border-color:var(--accent)}
  /* v109：开着的【多选】按钮（aria-pressed 不用 disabled —— 沙箱与真浏览器都不吞点击） */
  .mini-btn[aria-pressed="true"]{border-color:var(--accent);background:var(--accent);color:#0b0d12}
  /* v90：拖拽排序（拖动中半透明；落点目标虚线高亮） */
  .map-asset.dragging{opacity:.4}
  .map-asset.drag-over{border-style:dashed;border-color:var(--accent)}
  .modal .spacer{flex:1;min-width:0}


/* ══════ 07-layers.css ══════ */
  /* ---------- v71/v79：右侧图层面板（仿 PS）—— v79 起 = 独立矩形窗口（上下留白相等） ---------- */
  .layers{
    position:fixed;top:120px;right:0;bottom:120px;width:280px;z-index:31;
    background:rgba(255,255,255,.97);backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);
    border-left:1px solid var(--line);border-radius:14px 0 0 14px;
    box-shadow:-14px 0 34px rgba(20,22,35,.09);
    display:flex;flex-direction:column;transition:transform .2s;
  }
  .layers.collapsed{transform:translateX(100%)}
  .layers[hidden]{display:none}   /* v268：图层面板只在地图绘制页露出（工作流页 hidden 退役） */
  /* 收纳拉手：钉在面板左缘外侧、**垂直居中** —— 展开收起都在画布右侧中间（v79） */
  /* v113：拉手加高（36 → 68px）+ 箭头字形加大居中；left/top/width 不动 = 位置不变 */
  .layers-tab{
    position:absolute;left:-26px;top:50%;transform:translateY(-50%);width:26px;height:68px;
    border:1px solid var(--line);border-right:none;border-radius:9px 0 0 9px;
    background:#fff;color:var(--text-2);font:inherit;font-size:17px;font-weight:700;cursor:pointer;
    display:grid;place-items:center;padding:0;line-height:1;
    box-shadow:-6px 0 16px rgba(20,22,35,.10);transition:color .15s;
  }
  .layers-tab:hover{color:var(--accent);border-color:var(--accent)}
  /* v81：账号设置小菜单（⚙ 弹出，仅「退出登录」；点窗外才关） */
  .acct-menu{
    position:fixed;top:64px;right:14px;z-index:34;min-width:216px;padding:10px;   /* v350：加头部块 ⇒ 加宽 + 内边距 */
    background:rgba(255,255,255,.97);backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);
    border:1px solid var(--line);border-radius:12px;box-shadow:0 10px 30px rgba(20,22,35,.14);
  }
  .acct-menu[hidden]{display:none}
  .acct-menu .link-btn{width:100%;text-align:center;padding:6px 10px}
  /* v350：菜单头部 = 头像 + 账号名（草图：最上面一整块，区别于下面的功能行）；
     主题色 / 退出登录前加 accent 图标（草图：蓝 = 图标）。颜色全走 var() —— 两套主题自动成立。 */
  .am-head350{display:flex;align-items:center;gap:10px;padding:8px 8px 12px;margin:0 0 8px;border-bottom:1px solid var(--line)}
  .am-ava350{width:34px;height:34px;flex:0 0 34px;display:grid;place-items:center;border-radius:50%;background:var(--accent-soft);color:var(--accent);font-size:15px;font-weight:700;line-height:1}
  .am-name350{font-size:13px;font-weight:600;color:var(--text);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .am-ico350{width:15px;height:15px;flex:0 0 15px;color:var(--accent)}
  .am-ico350 svg{display:block;width:100%;height:100%}
  .am-out350{display:flex;align-items:center;justify-content:flex-start;gap:7px;padding:8px 10px}
  /* v370：快捷键窗口（设置菜单里的「快捷键」按钮点开）——
     v366 的菜单内嵌说明区整块退役；窗口正文 = 分组小标题 + 行（左说明 / 右键帽）。
     全走 token（--line-strong / --sunken / --card / --accent），亮暗两套自动成立。
     v371：**必须连写 `.modal.keys-win370`（0,2,0）** —— 单类写法与 `.modal` 同权重且定义更靠前，
     `width` 与 `max-width:none` 会被 `.modal`（width:100% / max-width:400px）整条压掉（窗口变 400px 窄条）。 */
  .modal.keys-win370{width:min(620px,94vw);max-width:none}
  .keys-body370{margin-top:10px;display:flex;flex-direction:column}
  .keys-g370{margin:12px 0 4px;font-size:11.5px;font-weight:600;letter-spacing:.03em;color:var(--text-3)}
  .keys-body370 .keys-g370:first-child{margin-top:0}
  .keys-r370{display:flex;align-items:center;justify-content:space-between;gap:14px;padding:7px 9px;border-radius:9px;font-size:13px;line-height:1.45;color:var(--text)}
  .keys-r370:hover{background:var(--sunken)}
  .keys-k370{display:flex;align-items:center;gap:4px;flex:0 0 auto}
  .keys-key370{
    min-width:22px;height:22px;padding:0 7px;display:inline-grid;place-items:center;
    font-size:11.5px;font-weight:600;line-height:1;border:1px solid var(--line-strong);
    border-radius:6px;background:var(--card);color:var(--accent);
  }
  /* v351：角色子画布（三类产物）—— 颜色全走 var()，两套主题自动成立 */
  /* v368：窗口按 **16 : 9** 定尺寸（用户口径「子画布尺寸为 16:9」）。
     ⚠️ 选择器必须连写 `.modal.entc-win351`（0,2,0）：`.modal` 在本样式表里**更靠后**且同为单类，
        老写法 `.entc-win351` 的 width / max-height 全被它压掉，连 `.modal` 的 max-width:400px
        也一并生效 ⇒ 实际渲染成 400px 宽的窄条（16:9 根本立不起来）。
     宽度同时受 vw 与 vh 两向夹取（(可用窗高 − 标题栏等文字高度) × 16/9 + 左右内边距）⇒ 整窗 16:9 且永不出屏。
     v393：去掉 1060px 固定上限 —— 放大到视口容得下的最大 16:9（用户红框口径）。 */
  .modal.entc-win351{width:min(94vw,calc((92vh - 104px) * 16 / 9 + 44px));max-width:none;max-height:92vh;overflow:auto}
  /* v356：子画布改迷你节点画布 —— body = 画布容器（overflow hidden），canvas 铺满；
     交互与工作流画布同一套：节点拖拽 / 背景平移 / 滚轮缩放
     v368：画布区**恒 16:9**（aspect-ratio，宽度撑满窗口内宽）+ 底色 var(--canvas)
     （与工作流画布 .canvas-wrap 同款；点阵由 entSubDots356 画进 canvas 本身） */
  .entc-body351{margin-top:10px;position:relative;width:100%;aspect-ratio:16/9;border:1px solid var(--line);border-radius:12px;overflow:hidden;background-color:var(--canvas)}
  .entc-body351 canvas{position:absolute;inset:0;width:100%;height:100%;display:block;touch-action:none;cursor:grab}
  /* v317：版本新鲜度胶囊 —— 顶部居中、顶栏正下方；只在「跑的是旧 build」时出现。
     z 88 = 高于所有页面层（#homeView 60 / .ai-page285 48 / #mapOverlay 80），
     低于 #askOverlay 90 与 #authModal 95。颜色全走 var() → 深浅两套自动成立。 */
  .ver-new317{
    position:fixed;top:62px;left:50%;transform:translateX(-50%);z-index:88;
    appearance:none;border:1px solid var(--accent);background:var(--accent-soft);color:var(--accent);
    font:inherit;font-size:12px;font-weight:600;padding:6px 14px;border-radius:999px;cursor:pointer;
    box-shadow:var(--shadow);
  }
  .ver-new317:hover{filter:brightness(1.04)}
  .ver-new317[hidden]{display:none}
  /* v313：⚙ 菜单里的「主题色」—— 亮色 / 暗色两选一（当前项高亮；无记录 = 默认暗色）。
     顶栏菜单（#acctMenu）与主页菜单（#homeMenu204）共用同一套类名 + 同一个事件委托 + 同一个同步函数；
     以后再加菜单，只要放一份 .at-opt313 就会自动跟上。颜色全走 var() —— 两套主题自动成立。 */
  .at-row313{display:flex;align-items:center;gap:8px;margin:2px 0 8px;padding:0 3px}   /* v350：一行 = 图标 + 标签 左，亮 / 暗 右 */
  .at-lab313{display:flex;align-items:center;gap:6px;flex:1 1 auto;font-size:12px;line-height:1;color:var(--text-2);margin:0;padding:0;text-align:left}
  .at-row313 .at-opt313{flex:0 0 auto;padding:6px 12px}   /* v350：行内定宽（原 flex:1 1 0 在 flex 行里会把宽度挤没） */
  /* v315：全站选项类按钮统一 —— 与视频生成（.spec-opt249）同款三态：
     未选 = line 描边 + card 底 + 正常字色；悬停 = 描边/字色转 accent；已选 = accent 描边 + accent-soft 底 + accent 字色。 */
  .at-pick313{display:flex;gap:6px}
  .at-opt313{
    flex:1 1 0;appearance:none;border:1px solid var(--line);background:var(--card);color:var(--text);
    font:500 12.5px/1 var(--sans);padding:8px 0;border-radius:10px;cursor:pointer;transition:.15s;
  }
  .at-opt313:hover{border-color:var(--accent);color:var(--accent)}
  .at-opt313.on{border-color:var(--accent);background:var(--accent-soft);color:var(--accent)}
  html[data-theme="dark"] .at-opt313{background:#232631;border-color:transparent;color:#e8eaf1}
  html[data-theme="dark"] .at-opt313:hover{background:#262a35;color:var(--accent)}
  html[data-theme="dark"] .at-opt313.on{background:var(--accent-soft);border-color:var(--accent);color:var(--accent)}
  .layers-head{display:flex;align-items:center;gap:7px;padding:10px 12px;border-bottom:1px solid var(--line)}
  .layers-head strong{font-size:12.5px}
  .layers-count{font-size:11px;color:var(--text-3)}
  .layers-list{flex:1;min-height:0;overflow:auto;padding:6px}
  .layers-empty{font-size:11px;color:var(--text-3);padding:10px 8px;line-height:1.6}
  /* v151：条目 = 名称 + 实际像素尺寸（v148 加的那张缩略图撤掉了 ——
     用户口径「图层里面不需要显示缩略图」，要看的是**画布上**那个框的显示尺寸）。
     名称与尺寸仍是两个独立字段、并排左对齐（尺寸不被 flex:1 顶到行尾）。 */
  .layer{
    display:flex;align-items:center;gap:9px;padding:7px 8px;margin-bottom:2px;
    border-radius:9px;border:1px solid transparent;cursor:pointer;user-select:none;position:relative;
  }
  .layer:hover{background:#f5f6fa}
  .layer.on{background:var(--accent-soft);border-color:var(--accent-2)}
  .layer .lrow{flex:1;min-width:0;display:flex;align-items:baseline;gap:8px;overflow:hidden}
  .layer .lname{flex:0 1 auto;min-width:0;font-size:12px;font-weight:600;color:var(--text);
    white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .layer .lmeta{font-size:10.5px;color:var(--text-3);flex:0 0 auto;font-variant-numeric:tabular-nums}
  /* 改名时让名称那一格吃满剩余宽度（输入框才够长）；改完失焦自动收回 */
  .layer .lname:focus-within{flex:1 1 0%;overflow:visible}
  .layer .lname input{width:100%;box-sizing:border-box}
  /* v100：地图图层行的小叉（悬浮 / 选中时出现），工作流行不带 */
  .layer .layer-x{
    flex:0 0 auto;width:18px;height:18px;border:none;border-radius:6px;background:transparent;
    color:var(--text-3);font:inherit;font-size:12px;line-height:1;cursor:pointer;padding:0;
    display:none;place-items:center;
  }
  .layer:hover .layer-x,.layer.on .layer-x{display:grid}
  .layer .layer-x:hover{background:#fde8e8;color:#d33}
  .layer input{
    flex:1;min-width:0;font:inherit;font-size:12px;font-weight:600;color:var(--text);
    padding:3px 6px;border:1px solid var(--accent);border-radius:6px;outline:none;background:#fff;
  }
  /* 画布里的改名输入框：盖在节点标题栏上，字号跟标题栏一起缩放 */
  .head-rename{
    position:absolute;z-index:45;font-family:inherit;font-weight:700;color:var(--text);
    border:2px solid var(--accent);border-radius:7px;background:#fff;padding:0 6px;
    outline:none;box-shadow:0 6px 18px rgba(20,22,35,.22);
  }

  /* ---------- 开关 / 复选 ---------- */
  .switch{display:flex;align-items:center;gap:10px;cursor:pointer;user-select:none;position:relative}
  .switch input{position:absolute;opacity:0;width:0;height:0}
  .switch .track{
    width:38px;height:22px;border-radius:20px;background:#d8dbe4;position:relative;
    transition:.2s;flex:0 0 38px;
  }
  .switch .track::after{
    content:"";position:absolute;top:3px;left:3px;width:16px;height:16px;border-radius:50%;
    background:#fff;transition:.2s;box-shadow:0 1px 3px rgba(0,0,0,.22);
  }
  .switch input:checked + .track{background:#fff}
  .switch input:checked + .track::after{transform:translateX(16px)}
  .switch em{font-style:normal;font-size:12.5px;color:var(--text);font-weight:600;line-height:1.45}



  /* ---------- 参数 ---------- */
  /* 迭代 48：抠图这一段不再折叠 —— 内容常驻可见（v387：它就是像素卡两列栅格里的一格） */
  .note{margin:10px 0 0;font-size:11.5px;color:var(--text-3);line-height:1.7}
  .note.warn{color:#b45309;background:#fffbeb;border:1px solid #fde68a;border-radius:9px;padding:8px 10px}
  .note.ok{color:#0f766e;background:#f0fdfa;border:1px solid #99f6e4;border-radius:9px;padding:8px 10px}
  .note b{color:inherit;font-weight:600}

  /* ---------- 切片结果（面板底部） ---------- */
  .dock{display:flex;flex-direction:column;max-height:214px}
  .dock[hidden]{display:none}
  .dock-head{display:flex;align-items:center;gap:6px;flex-wrap:wrap;margin-bottom:9px}
  .dock-head .count{font-size:12px;font-weight:600;color:var(--text)}
  .dock-head .dock-tip{font-size:10.5px;color:var(--text-3)}
  .dock-head .spacer{flex:1}
  /* 迭代 21：全选/反选 + 打包 ZIP 从"图片下面那个小窗"搬进来，跟缩略图同一栏 */
  .dock-foot{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-top:9px}
  .dock-foot .spacer{flex:1}
  .slice-grid{
    display:flex;flex-wrap:wrap;gap:8px;overflow-y:auto;overflow-x:hidden;padding:2px;
  }
  .slice-item{
    flex:0 0 92px;width:92px;border:1px solid var(--line);border-radius:10px;padding:6px;background:#fff;position:relative;
    transition:.15s;
  }
  .slice-item:hover{border-color:var(--accent);box-shadow:0 4px 14px rgba(20,214,255,.13)}
  .slice-item.off{opacity:.4}
  .slice-item.active{border-color:#f59e0b;box-shadow:0 0 0 2px #fde9c8}
  .slice-thumb{
    height:58px;border-radius:7px;display:grid;place-items:center;overflow:hidden;
  }
  .slice-thumb img{max-width:100%;max-height:100%;display:block;image-rendering:pixelated}
  .slice-meta{
    display:flex;align-items:center;justify-content:space-between;gap:4px;margin-top:7px;
    font-size:10.5px;color:var(--text-3);
  }
  .slice-idx{
    position:absolute;top:6px;left:6px;background:rgba(26,29,38,.78);color:#fff;
    font-size:10px;font-weight:700;border-radius:6px;padding:1px 6px;line-height:1.5;
  }
  .slice-ck{position:absolute;top:6px;right:6px;width:15px;height:15px;cursor:pointer;accent-color:var(--accent);margin:0}
  .mini-btn{
    font:inherit;font-size:11px;padding:4px 9px;border-radius:7px;border:1px solid var(--line);
    background:#fafbfd;color:var(--text-2);cursor:pointer;transition:.15s;white-space:nowrap;
  }
  .mini-btn:hover{border-color:var(--accent);color:var(--accent);background:var(--accent-soft)}
  .busy{
    display:flex;align-items:center;gap:8px;font-size:12px;color:var(--accent);
    padding:10px 0;justify-content:center;
  }



  /* ---------- 账号 ---------- */
  .acct-name{font-size:12.5px;color:var(--text-2);max-width:150px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

  /* ---------- 弹窗 ---------- */
  .overlay{
    position:fixed;inset:0;background:rgba(0,0,0,.45);z-index:80;padding:18px;
    display:flex;align-items:center;justify-content:center;
  }
  .overlay[hidden]{display:none}
  #authModal{z-index:95}
  .modal{
    background:#fff;border-radius:16px;width:100%;max-width:400px;padding:22px;
    box-shadow:0 24px 60px rgba(0,0,0,.3);max-height:92vh;overflow:auto;
  }
  .modal h3{margin:0 0 4px;font-size:16px}
  .modal .sub{margin:0 0 16px;font-size:12px;color:var(--text-3)}
  .modal-close{
    float:right;border:none;background:transparent;font-size:16px;color:var(--text-3);
    cursor:pointer;line-height:1;padding:2px 4px;
  }
  /* v315：与视频生成选项按钮同款三态（原灰底分段控件退役） */
  .tabs{display:flex;gap:6px;margin-bottom:16px}
  .tabs button{
    flex:1;border:1px solid var(--line);background:var(--card);padding:9px 4px;border-radius:10px;
    font:500 12.5px/1 var(--sans);color:var(--text);cursor:pointer;transition:.15s;
  }
  .tabs button:hover{border-color:var(--accent);color:var(--accent)}
  .tabs button.on{border-color:var(--accent);background:var(--accent-soft);color:var(--accent)}
  .fld{margin-bottom:12px}
  .fld label{display:block;font-size:11.5px;color:var(--text-3);margin-bottom:5px}
  .fld input{
    width:100%;padding:10px 11px;border:1px solid var(--line-strong);border-radius:9px;
    font:inherit;font-size:13.5px;color:var(--text);outline:none;transition:.15s;background:#fff;
  }
  .fld input:focus{border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-soft)}
  .code-row{display:flex;gap:8px}
  .code-row input{flex:1;min-width:0}
  .code-hint{font-size:11px;color:var(--text-3);margin:7px 0 0;line-height:1.5}
  .msg{font-size:12px;padding:9px 11px;border-radius:9px;margin-bottom:12px;line-height:1.65}
  .msg.err{background:#fef2f2;color:#b91c1c;border:1px solid #fecaca}
  .msg.ok{background:#f0fdfa;color:#0f766e;border:1px solid #99f6e4}
  .msg.info{background:var(--accent-soft);color:var(--accent);border:1px solid var(--accent-2)}
  .link-btn{
    border:none;background:transparent;color:var(--accent);font:inherit;font-size:12px;
    cursor:pointer;padding:4px 0;text-decoration:underline;
  }
  .modal-foot{margin-top:14px;display:flex;justify-content:space-between;gap:10px;flex-wrap:wrap}

  @media (max-width:640px){
    .sheet{max-height:calc(100vh - 108px)}
    .sheet-cols{gap:10px}
    .sheet-body{padding:10px 12px 12px}
    .sheet-foot{padding:9px 12px 11px}
    .dock-foot{gap:6px}
  }

/* ══════ 08-dark.css ══════ */
  /* ===== v185：深色主题 · 镜像覆盖段
  /* ===== v185：深色主题 · 镜像覆盖段（补丁生成 —— 以后新增含字面色的 CSS 规则，记得来这里同步补深色版） ===== */
  html[data-theme="dark"] .sheet-bar { background:#14151b }
  html[data-theme="dark"] .icon-btn { background:#14161d }
  html[data-theme="dark"] .frame-cell { background:#191c24 }
  /* v225：即梦风卡面 —— 近黑实底、弱描边、16px 大圆角 */
  html[data-theme="dark"] .sheet-body .card { background:#17181d; border-color:#21232b; border-radius:16px }
  /* v242：gen/vgen 整卡只留一层框 —— sheet 自带边框，内卡退成透明无边框（用户口径「边框有两层，只要一层」） */
  .sheet[data-node189="gen"] .sheet-body .card,
  .sheet[data-node189="vgen"] .sheet-body .card{border-color:transparent;background:transparent}
  html[data-theme="dark"] .sheet[data-node189="gen"] .sheet-body .card,
  html[data-theme="dark"] .sheet[data-node189="vgen"] .sheet-body .card{border-color:transparent;background:transparent}
  html[data-theme="dark"] .card h2 { color:#d8dbe6 }
  @media (max-width:760px){
  }
  /* v225：下拉 = 深灰块（无边框、10px 圆角），参考图工具按钮块质感 */
  html[data-theme="dark"] .sel { background:#232631; border-color:transparent; border-radius:10px; padding:7px 10px }
  html[data-theme="dark"] .rng::-webkit-slider-thumb { background:#191c24 }
  html[data-theme="dark"] .rng::-moz-range-thumb { background:#191c24 }
  html[data-theme="dark"] .mode-switch button { background:#14161d }
  html[data-theme="dark"] .mode-switch button[aria-disabled="true"], html[data-theme="dark"] .mode-switch button[aria-disabled="true"]:hover { background:#0b0d12 }
  @media (max-width:760px){
  }
  html[data-theme="dark"] .checker { background-color:#191c24; background-image:
      linear-gradient(45deg,#191c24 25%,transparent 25%),
      linear-gradient(-45deg,#191c24 25%,transparent 25%),
      linear-gradient(45deg,transparent 75%,#191c24 75%),
      linear-gradient(-45deg,transparent 75%,#191c24 75%) }
  html[data-theme="dark"] input[type=number][readonly] { background:#14161d }
  html[data-theme="dark"] input[type=number] { background:#191c24 }
  /* v225：按钮 = 深灰块（无边框、白字），hover 微亮不闪 accent */
  html[data-theme="dark"] .btn { background:#232631; border-color:transparent; color:#e8eaf1 }
  html[data-theme="dark"] .btn:hover { background:#2b2f3b; border-color:transparent; color:#fff }
  /* v228：顶栏「下载 PNG」深色同款块 */
  html[data-theme="dark"] .sheet-bar .sheet-cta { background:#232631; border-color:transparent; color:#e8eaf1 }
  html[data-theme="dark"] .sheet-bar .sheet-cta:hover { background:#2b2f3b; border-color:transparent; color:#fff }
  html[data-theme="dark"] .btn.ghost { background:#14161d }
  html[data-theme="dark"] .btn.primary:disabled { background:#323748 }
  html[data-theme="dark"] .tool { background:#14161d }
  html[data-theme="dark"] .zoom-rng::-webkit-slider-thumb { background:#191c24 }
  html[data-theme="dark"] .zoom-rng::-moz-range-thumb { background:#191c24 }
  html[data-theme="dark"] .stage-hint { background:#e8eaf2;color:#14161d }
  html[data-theme="dark"] .map-cfg input { background:#191c24 }
  html[data-theme="dark"] .anchor175 { background:#191c24 }
  html[data-theme="dark"] .anchor175 button::after { background:#323748 }
  html[data-theme="dark"] .map-asset { background:#191c24 }
  html[data-theme="dark"] .map-asset-x { background:#191c24 }
  html[data-theme="dark"] .add-menu157 { background:#191c24 }
  html[data-theme="dark"] .rand-menu166 { background:#191c24 }
  html[data-theme="dark"] .snap-inp180 { background:#191c24 }
  html[data-theme="dark"] .layers-tab { background:#191c24 }
  html[data-theme="dark"] .layer:hover { background:#14161d }
  html[data-theme="dark"] .layer.on { border-color:rgba(20,214,255,.28) }
  html[data-theme="dark"] .layer .layer-x:hover { background:#2a1616 }
  html[data-theme="dark"] .layer input { background:#191c24 }
  html[data-theme="dark"] .head-rename { background:#191c24 }
  html[data-theme="dark"] .switch .track::after { background:#191c24 }
  html[data-theme="dark"] .note.warn { background:#262014; border:1px solid #3a3218 }
  html[data-theme="dark"] .note.ok { color:#5eead4; background:#10231f }
  html[data-theme="dark"] .slice-item { background:#191c24 }
  html[data-theme="dark"] .slice-item.active { box-shadow:0 0 0 2px #2a2214 }
  html[data-theme="dark"] .mini-btn { background:#14161d }
  html[data-theme="dark"] .modal { background:#191c24 }
  html[data-theme="dark"] .tabs button{background:#232631;border-color:transparent;color:#e8eaf1}
  html[data-theme="dark"] .tabs button:hover{background:#262a35;color:var(--accent)}
  html[data-theme="dark"] .tabs button.on{background:var(--accent-soft);border-color:var(--accent);color:var(--accent)}
  html[data-theme="dark"] .fld input { background:#191c24 }
  html[data-theme="dark"] .msg.err { background:#281414; border:1px solid #4a2222;color:#fca5a5 }
  html[data-theme="dark"] .msg.ok { background:#10231f; color:#5eead4 }
  html[data-theme="dark"] .msg.info { border:1px solid rgba(20,214,255,.28) }
  @media (max-width:640px){
  }

/* ══════ 09-nodes.css ══════ */
  /* ---- v189：拖「＋」选择窗（画布内嵌，跟随平移缩放） + 功能节点面板卡 ---- */
  /* v191：选择窗 UI 参考截图重做 —— 深色圆角面板、小灰字标题、每行「图标 + 文字」；
     颜色全走 var()（两主题自动适配），旧的 plus-win 深色镜像条值与 var 同值，保留不冲突 */
  /* v241：窗口加宽一点（176 → 200）+ 文字放大（标题 12→13、选项 13.5→15、图标 17→18）；v325 再放大一档（窗 248→300、标题 15→17、选项 18→20、图标 22→24），且窗口不再跟随画布缩放 */
  .plus-win189{position:absolute;z-index:34;transform-origin:0 0;min-width:260px;background:var(--card);border:1px solid var(--line);border-radius:14px;box-shadow:0 12px 34px rgba(10,12,20,.22);padding:12px;user-select:none}
  .plus-win189[hidden]{display:none}
  .plus-win-head189{display:flex;align-items:center;justify-content:space-between;font:500 17px/1 var(--sans);color:var(--text-3);padding:6px 8px 12px;cursor:move}
  .plus-win-x189{border:0;background:none;color:var(--text-3);cursor:pointer;font-size:17px;line-height:1;padding:2px 6px;border-radius:6px}
  .plus-win-x189:hover{color:var(--text)}
    /* v270：整窗文字放大一档，窗口跟着加大（min-width 248 / 选项 18 / 图标 22）；v325：窗 300 / 选项 20 / 图标 24，且不再跟随画布缩放 */
  .plus-opt189{display:flex;align-items:center;gap:16px;width:100%;text-align:left;border:0;background:none;font:500 20px/1 var(--sans);color:var(--text);padding:15px 14px;border-radius:9px;cursor:pointer}
  .plus-opt189 svg{width:24px;height:24px;flex:none;color:var(--text-3)}
  /* v328：行间距 +8px（用户口径「减小宽度，增加行间距（对应适配高度调整）」——
     窗子没有固定高，选项行距拉开后高度自然长出来；宽度 300 -> 260 同口径） */
  .plus-opt189 + .plus-opt189{margin-top:8px}
  .plus-opt189:hover{background:var(--sunken)}
  .plus-opt189:hover svg{color:var(--accent)}
  /* v346：「实体节点」母选项 + 悬浮子列表（角色 / 怪物 / NPC / 道具 · 图标 / 地图）整块退役
     —— 三档平铺进「添加节点」窗，与四类功能节点同一行样式（见上面 .plus-opt189）。 */
  /* v192：模式键被功能节点藏掉时必须真消失 —— .mode-switch button 自带 display:inline-flex，会盖掉 [hidden] */
  .mode-switch button[hidden]{display:none!important}

  .prow189 .sel,.prow189 textarea{flex:1;min-width:0}
  .prow189 textarea{resize:vertical;font:inherit;color:var(--text)}
  #typedHint189{margin:0 0 10px;padding:9px 12px;border:1px dashed var(--line);border-radius:8px;font:500 12px/1.5 var(--sans);color:var(--dim)}
  #typedHint189[hidden]{display:none}
  .sheet[data-node189="gen"] .sheet-cols > .card:not(#cardGen189){display:none}
  .sheet[data-node189="vgen"] .sheet-cols > .card:not(#cardVgen189){display:none}
  .sheet[data-node189="vframes"] .sheet-cols > .card:not(#cardFrames){display:none}
  .sheet[data-mixed189="1"] .sheet-body > *:not(#typedHint189){display:none!important}
  html[data-theme="dark"] .plus-win189{background:#191c24;border-color:#262a35;box-shadow:0 10px 30px rgba(0,0,0,.5)}
  html[data-theme="dark"] .plus-win-head189{color:#8b91a3}
  html[data-theme="dark"] .plus-win-x189{color:#8b91a3}
  html[data-theme="dark"] .plus-win-x189:hover{color:#e8eaf1}
  html[data-theme="dark"] .plus-opt189{color:#e8eaf1}
  html[data-theme="dark"] .plus-opt189:hover{background:#262a35;border-color:#323748}

  /* v225：提示词区贴近卡底、弱描边（参考图的无框输入观感） */
  html[data-theme="dark"] .prow189 textarea{color:#e8eaf1;background:#1b1d24;border-color:#21232b;border-radius:10px}
  /* v230：vgen 卡即梦式布局 —— 大提示词区无框无标签；底部一排 = 文字式参数下拉 + 生成钮 */
  /* v246：gen 卡提示词并入 vgen 同款（原只 scope 到 #cardVgen189，gen 的是裸 textarea 小框）——
     输入区铺满整卡内容宽（用户红框范围）、无框无拖拽手柄；min-height 150 即整块红色区域 */
  #cardGen189 .vgen-prompt230, #cardVgen189 .vgen-prompt230{
    display:block;width:100%;resize:none;font:inherit;font-size:13px;line-height:1.7;   /* v242：右下角拖拽调高手柄删 */
    color:var(--text);background:transparent;border:none;outline:none;
    padding:4px 2px;min-height:150px;
  }
  #cardGen189 .vgen-prompt230::placeholder, #cardVgen189 .vgen-prompt230::placeholder{color:var(--text-3)}
  .vgen-bar230{display:flex;align-items:center;gap:14px;margin-top:10px;flex-wrap:wrap}
  .vgen-chip230{
    margin-left:0;flex:0 0 auto;background:transparent;border:none;color:var(--text);
    font:inherit;font-size:12.5px;padding:7px 10px;cursor:pointer;border-radius:10px;transition:.15s;
  }
  .vgen-chip230:hover{background:var(--accent-soft)}
  .vgen-chip230:focus{outline:none;box-shadow:none}
  /* v257：芯片键的**常态 = 与窗口同色**（没有框、没有底色），只有鼠标压上去才显色。
     ⚠️ 默认暗色下看到的那颗「框」来自 `html[data-theme="dark"] .sel{background:#232631}`
     —— 它的优先级（0,2,1）压过 .vgen-chip230（0,1,0），所以要用同权重补一条盖回去。 */
  html[data-theme="dark"] .vgen-chip230{background:transparent;border-color:transparent;color:var(--text)}
  html[data-theme="dark"] .vgen-chip230:hover{background:var(--accent-soft);color:var(--text)}
  /* v249：比例 / 分辨率合并键弹窗（即梦式双段点选；双主题双轨）
     v257：从「卡内 absolute」改成**独立浮层** —— 打开时挂到 body + position:fixed。
     理由跟 v157 菜单 / v166 随机窗完全一样：.sheet 的 overflow:hidden（+ will-change）会把
     卡内 absolute 弹层整块裁掉（用户口径「它应该是另外单独的一个窗口，就算超出了这个窗口
     之外，它也是能显示完整的」）；位置由 JS 按触发按钮的**视口位置**算（与按钮左右居中），
     并从按钮那儿**放大出来**（origin = 底边中点）。 */
  .spec-pop249{
    position:fixed;left:0;top:0;z-index:60;min-width:280px;
    background:var(--card);border:1px solid var(--line);border-radius:14px;
    box-shadow:0 12px 34px rgba(10,12,20,.22);padding:12px;user-select:none;
    transform-origin:50% 100%;animation:specPop257 .15s ease-out;
  }
  .spec-pop249[hidden]{display:none}
  /* v257：从按钮那儿「放大出来」—— 起点压在按钮上（origin = 底边中点），缩放 + 轻微上移 */
  @keyframes specPop257{
    from{opacity:0;transform:scale(.82) translateY(8px)}
    to{opacity:1;transform:none}
  }
  .spec-sec249{font:500 12px/1 var(--sans);color:var(--text-3);margin:2px 2px 8px}
  .spec-sec249 + .spec-row249{margin-bottom:10px}
  .spec-row249{display:flex;flex-wrap:wrap;gap:6px}
  .spec-opt249{
    display:flex;flex-direction:column;align-items:center;justify-content:flex-end;gap:5px;
    min-width:56px;padding:9px 8px 7px;border:1px solid var(--line);border-radius:10px;
    background:var(--card);color:var(--text);font:500 12.5px/1 var(--sans);cursor:pointer;transition:.15s;
    white-space:nowrap;   /* v257：一排挤多个时「21:9」不许折成两行 */
  }
  .spec-opt249 .spec-ico249{display:block;border:1.6px solid currentColor;border-radius:3px;color:var(--text-2)}
  .spec-opt249:hover{border-color:var(--accent);color:var(--accent)}
  .spec-opt249.on{border-color:var(--accent);background:var(--accent-soft);color:var(--accent)}
  .spec-opt249.on .spec-ico249{color:var(--accent)}
  html[data-theme="dark"] .spec-pop249{background:#191c24;border-color:#262a35;box-shadow:0 10px 30px rgba(0,0,0,.5)}
  html[data-theme="dark"] .spec-opt249{background:#232631;border-color:transparent;color:#e8eaf1}
  html[data-theme="dark"] .spec-opt249 .spec-ico249{color:#8b91a3}
  html[data-theme="dark"] .spec-opt249:hover{background:#262a35;color:var(--accent)}
  html[data-theme="dark"] .spec-opt249.on{background:var(--accent-soft);border-color:var(--accent);color:var(--accent)}
  /* ---- v255：规格弹窗口径（图片 / 视频同款）----
     ① 弹窗加宽到 340px —— 用户口径「分辨率右边那块很空，把框拉长」；
     ② 比例行三列铺满（6 档 = 两行三列，小图形不被挤扁）；
     ③ 分辨率行 chip 拉满整宽（flex:1 1 0，几档就均分成几份，不再左边挤一堆右边空着）。 */
  .spec-pop249.spec-pop255{width:340px;min-width:0;max-width:calc(100% - 24px)}
  /* v257：比例**一整排**（6 档 = 一行六列，不再折成两行三列）—— 列窄了就把内边距收一点，
     图标（最宽 20px）与文字（「21:9」约 27px）在 ~48px 的格子里还放得下。 */
  .spec-row249.spec-ratio255{flex-wrap:nowrap}
  .spec-row249.spec-ratio255 .spec-opt249{flex:1 1 calc(16.666% - 5px);min-width:0;padding:7px 3px 6px;gap:4px}
  .spec-row249.spec-res255 .spec-opt249{flex:1 1 0;min-width:0}
  /* v257：模型选择也走同款弹窗 —— 一个框、选项**上下排列**（各占整行、左对齐，不参与均分） */
  .spec-row249.spec-model257{flex-wrap:nowrap;flex-direction:column;gap:4px}
  .spec-row249.spec-model257 .spec-opt249{
    flex:0 0 auto;width:100%;min-width:0;flex-direction:row;align-items:center;
    justify-content:flex-start;gap:8px;padding:8px 10px;text-align:left;
  }
  /* v255：时长弹窗 —— 左进度条 + 右秒数输入框 + 两端刻度（复用 .rng / .rng-num，双主题自带） */
  .dur-row255{display:flex;align-items:center;gap:10px}
  .dur-rng255{width:auto;flex:1 1 auto;min-width:0}
  .dur-val255{flex:0 0 auto;display:flex;align-items:center;gap:3px}
  .dur-val255 em{font:500 11.5px/1 var(--sans);color:var(--text-3);font-style:normal}
  .vgen-sp230{flex:1 1 auto;min-width:0;text-align:right}
  .vgen-bar230 .btn.primary{width:auto;margin:0;height:34px;padding:0 18px;font-size:13px;border-radius:9px}
  /* v232：gen/vgen 即梦式整卡 —— 顶栏隐藏、参考图缩略区、圆形生成钮、右上角面板放大钮 */
  .sheet[data-node189="gen"] .sheet-bar, .sheet[data-node189="vgen"] .sheet-bar{display:none}
  #cardGen189, #cardVgen189{position:relative}
  .panel-max230{
    position:absolute;top:2px;right:2px;z-index:5;width:30px;height:30px;border-radius:8px;
    border:none;background:transparent;color:var(--text-3);cursor:pointer;display:grid;place-items:center;transition:.15s;
  }
  .panel-max230 svg{width:16px;height:16px}
  .panel-max230:hover{background:var(--accent-soft);color:var(--accent)}
  .vgen-ref230{display:flex;gap:8px;margin:0 0 12px;min-height:64px;flex-wrap:wrap}
  .vgen-ref230 img{width:64px;height:64px;object-fit:cover;border-radius:10px;display:block;border:1px solid var(--line)}
  /* v258：加号位改成**常驻**（空态就它一格；有参考图时跟在最后一张后面），可点 → 弹「上传 / 从画布选择」 */
  .vgen-ref-add230{width:64px;height:64px;border-radius:10px;background:var(--card);border:1px dashed var(--line-strong);color:var(--text-3);display:grid;place-items:center;font-size:22px;line-height:1;flex:0 0 auto;cursor:pointer;transition:.15s}
  .vgen-ref-add230:hover{border-color:var(--accent);color:var(--accent);background:var(--accent-soft)}
  html[data-theme="dark"] .vgen-ref-add230:hover{background:rgba(90,143,163,.14)}
  /* v252：参考图可以有**多张**（gen / vgen 接多个上游）—— 每张一个 1:1 缩略块，
     右上角一颗 ✕ 只摘这一张（窗内点击 stopPropagation，不冒泡到「点窗外关」那条） */
  .vgen-ref-it252{position:relative;width:64px;height:64px;flex:0 0 auto}
  .vgen-ref-x252{
    position:absolute;top:-5px;right:-5px;width:18px;height:18px;padding:0;border-radius:50%;
    border:1px solid var(--line);background:var(--card);color:var(--text-2);
    font:inherit;font-size:12px;line-height:1;display:grid;place-items:center;cursor:pointer;transition:.15s;
  }
  .vgen-ref-x252:hover{color:#fff;background:#e0564f;border-color:#e0564f}
  html[data-theme="dark"] .vgen-ref-x252{background:#232631;border-color:#333846;color:#c9cdd8}
  /* v259：参考图「从画布选择」拾取态 —— **整个画面最底部**通栏一条蓝色渐变 + 上飘的像素方块。
     渐变口径（用户原话）：从下往上 —— 下面实（不透明），越往上越虚，到顶完全看不见。
     方块：小、**大小 / 角度都随机**，跟渐变一起从下往上飘、到一定高度淡掉；纯 CSS 动画
     （不占 rAF、不参与 drawStage 重绘，逐格 --x/--s/--r/--o/--t/--d 全硬编码在 nth-child 表里）。
     底条本身 pointer-events:none —— 画布手势（平移 / 缩放 / 点选 / 框选）一个都不挡。
     v260：定位改 **fixed + top:auto + bottom:0** —— 用户环境实锤 canvasWrap 里的 absolute:bottom
     落到了视口**顶**上（同一张截图里 .app 直属的缩放胶囊是对的）⇒ 直接锚视口底，并挪出 canvasWrap
     跟缩放胶囊同层（HTML 一并挪到 .app 直属）；padding-left 让开左下角的缩放胶囊。
     v262：渐变**整体降低透明度**（用户口径「进入功能后界面完全保持原本的样子，只增加下面的蓝色渐变
     就可以了 —— 已有的蓝色渐变整体降低透明度，变的更透明」）；深色主题下条上文字转浅色保可读。 */
  .ref-pick258{
    position:fixed;left:0;right:0;top:auto;bottom:0;z-index:46;height:86px;
    display:flex;align-items:center;gap:14px;padding:0 22px 12px 206px;
    color:#04141b;font-size:14px;font-weight:700;letter-spacing:.2px;
    background:linear-gradient(0deg,rgba(90,143,163,.55) 0%,rgba(90,143,163,.32) 26%,rgba(90,143,163,0) 58%,rgba(90,143,163,0) 100%);
    overflow:hidden;pointer-events:none;
  }
  .ref-pick258[hidden]{display:none}
  .rp-dots258{position:absolute;left:0;right:0;bottom:0;height:86px;overflow:hidden;pointer-events:none}
  .rp-px258{
    position:absolute;left:var(--x,50%);bottom:-10px;width:var(--s,5px);height:var(--s,5px);
    background:rgba(255,255,255,.95);border-radius:1px;opacity:0;
    animation:rpRise258 var(--t,2.8s) linear var(--d,0s) infinite;
  }
  @keyframes rpRise258{
    0%{opacity:0;transform:translateY(0) rotate(var(--r,0deg))}
    12%{opacity:var(--o,.9)}
    58%{opacity:var(--o,.9)}
    100%{opacity:0;transform:translateY(-96px) rotate(calc(var(--r,0deg) + 90deg))}
  }
  .rp-px258:nth-child(1){--x:2%;--s:6px;--r:12deg;--o:0.95;--t:2.6s;--d:-0.2s}
  .rp-px258:nth-child(2){--x:6%;--s:4px;--r:58deg;--o:0.7;--t:3.1s;--d:-1.1s}
  .rp-px258:nth-child(3){--x:10%;--s:5px;--r:132deg;--o:0.85;--t:2.4s;--d:-2.0s}
  .rp-px258:nth-child(4){--x:14%;--s:4px;--r:205deg;--o:0.6;--t:3.4s;--d:-0.6s}
  .rp-px258:nth-child(5){--x:18%;--s:7px;--r:27deg;--o:0.95;--t:2.8s;--d:-1.7s}
  .rp-px258:nth-child(6){--x:23%;--s:5px;--r:88deg;--o:0.75;--t:3.2s;--d:-2.5s}
  .rp-px258:nth-child(7){--x:27%;--s:4px;--r:156deg;--o:0.65;--t:2.5s;--d:-0.9s}
  .rp-px258:nth-child(8){--x:31%;--s:6px;--r:240deg;--o:0.9;--t:3.6s;--d:-1.4s}
  .rp-px258:nth-child(9){--x:36%;--s:5px;--r:311deg;--o:0.8;--t:2.7s;--d:-2.3s}
  .rp-px258:nth-child(10){--x:40%;--s:8px;--r:44deg;--o:1;--t:3.1s;--d:-0.4s}
  .rp-px258:nth-child(11){--x:44%;--s:4px;--r:118deg;--o:0.7;--t:2.9s;--d:-1.9s}
  .rp-px258:nth-child(12){--x:49%;--s:5px;--r:176deg;--o:0.85;--t:3.3s;--d:-0.8s}
  .rp-px258:nth-child(13){--x:53%;--s:6px;--r:262deg;--o:0.9;--t:2.6s;--d:-2.7s}
  .rp-px258:nth-child(14){--x:58%;--s:4px;--r:331deg;--o:0.65;--t:3.5s;--d:-1.2s}
  .rp-px258:nth-child(15){--x:62%;--s:7px;--r:20deg;--o:0.95;--t:2.4s;--d:-2.1s}
  .rp-px258:nth-child(16){--x:67%;--s:5px;--r:96deg;--o:0.75;--t:3.0s;--d:-0.5s}
  .rp-px258:nth-child(17){--x:71%;--s:4px;--r:148deg;--o:0.6;--t:3.4s;--d:-1.6s}
  .rp-px258:nth-child(18){--x:75%;--s:6px;--r:214deg;--o:0.9;--t:2.8s;--d:-2.6s}
  .rp-px258:nth-child(19){--x:80%;--s:5px;--r:287deg;--o:0.8;--t:3.2s;--d:-1.0s}
  .rp-px258:nth-child(20){--x:85%;--s:4px;--r:8deg;--o:0.7;--t:2.5s;--d:-2.4s}
  .rp-px258:nth-child(21){--x:89%;--s:6px;--r:74deg;--o:0.85;--t:3.6s;--d:-1.8s}
  .rp-px258:nth-child(22){--x:93%;--s:5px;--r:190deg;--o:0.95;--t:2.9s;--d:-0.3s}
  .rp-px258:nth-child(23){--x:96%;--s:7px;--r:305deg;--o:0.8;--t:3.3s;--d:-2.2s}
  .rp-px258:nth-child(24){--x:97%;--s:4px;--r:350deg;--o:0.9;--t:2.7s;--d:-1.5s}
  .rp-txt258{position:absolute;left:0;right:0;top:50%;transform:translateY(-50%);text-align:center;z-index:1}
  .rp-cancel258{
    position:relative;z-index:1;margin-left:auto;font:inherit;font-size:13px;font-weight:700;
    padding:7px 16px;border-radius:20px;cursor:pointer;transition:.15s;pointer-events:auto;
    border:1px solid rgba(4,20,27,.45);background:rgba(255,255,255,.62);color:#04141b;
  }
  .rp-cancel258:hover{background:#fff;border-color:rgba(4,20,27,.7)}
  html[data-theme="dark"] .ref-pick258{color:#eafcff}
  /* v268：参考图拾取态 —— 顶栏（logo / 工作流·地图绘制 / 登录区）整体上移出画面、
     左下角缩放胶囊 / 缩放弹层 / 小地图下移出画面（带动画，退出拾取态原路移回）。
     只在 body 挂 ref-pick-ui268 时生效，平时一个像素都不动。 */
  .topbar,.zoom-pill,.zoom-pop,.mini-map{transition:transform .35s ease}
  body.ref-pick-ui268 .topbar{transform:translateY(calc(-100% - 20px))}
  body.ref-pick-ui268 .zoom-pill{transform:translateY(calc(100% + 20px))}
  body.ref-pick-ui268 .zoom-pop{transform:translateY(calc(100% + 80px))}
  body.ref-pick-ui268 .mini-map{transform:translateY(calc(100% + 60px))}
  /* v258：参考图「添加」弹窗比规格弹窗窄（两个短标签） */
  .spec-pop249.spec-pop255.ref-pop258{width:216px}
  .spec-opt249 .rp-ico258{width:15px;height:15px;flex:0 0 auto}
  /* v300：发送键左边的预计积分胶囊（按当前模型 / 规格 / 时长实时换算；成功后才真扣） */
  .cr-hint300{flex:0 0 auto;font:600 12px/1 var(--sans);color:var(--text-2);background:var(--sunken);border:1px solid var(--line);border-radius:999px;padding:7px 10px;white-space:nowrap}
  /* v315：全站发送键统一 —— 34px 圆形 + accent 渐变底 + 深字，悬停 / 禁用 / 停止三态一致 */
  .vgen-bar230 .run-pil230{
    width:34px;height:34px;border-radius:50%;border:none;cursor:pointer;flex:0 0 auto;
    background:linear-gradient(135deg,var(--accent),var(--accent-2));color:#0b0d12;
    display:grid;place-items:center;transition:.15s;
  }
  .vgen-bar230 .run-pil230 svg{width:17px;height:17px}
  .vgen-bar230 .run-pil230:hover{filter:brightness(1.06)}
  .vgen-bar230 .run-pil230[aria-disabled="true"]{opacity:.45;cursor:not-allowed}
  /* v232：面板放大（非全屏）—— 压过 JS 内联定位，钉右上角大卡 */
  .sheet.max230{
    /* v242：大窗上下左右居中（原钉右上角） */
    transform:translate(-50%,-50%) !important;left:50% !important;top:50% !important;right:auto;
    width:min(1200px,calc(100vw - 24px));max-height:min(94vh,calc(100vh - 24px));
  }
  html[data-theme="dark"] #typedHint189{border-color:#262a35;color:#8b91a3}
  /* ================= v458：＋ 窗按四类分组（分类落到界面上） =================
     四个小组标题 + 九颗选项；分组名与顺序取自 js/src/94-nodecat457.js 的 NODE_CAT457。
     配色全走主题变量。⚠️ `.plus-opt189 + .plus-opt189{margin-top:8px}` 是**相邻兄弟**选择器
     （闸门钉着那条原文），跨组的选项不再互为相邻兄弟 ⇒ 跨组间距由 .plus-grp458 自己负责。
     另：窗子从 7 行涨到 9 行 + 4 个组标题 ⇒ 补一个高度上限自己滚（v346 的「窗子永不出屏」
     只钳位置、不限制高度）。 */
  .plus-grp458{font:500 12px/1 var(--sans);color:var(--text-3);letter-spacing:.06em;padding:11px 10px 7px}
  .plus-win189 .plus-opt189{padding:11px 14px}
  .plus-win189{max-height:min(84vh,760px);overflow-y:auto;overflow-x:hidden}

  /* ================= v566：＋ 窗对齐即梦（用户令 5 条） =================
     ① 字号改小对齐即梦（原 17/20/24 一档太大 ⇒ 标题 13 / 选项 14 / 图标 17、行距收紧）；
     ② 组标题小字退役（上面那条 .plus-grp458 变死规则、原文保留 —— 闸门钉着）；
     ③ 分类之间改横线分隔（.plus-sep566）；④ 标题更名「新建节点」；⑤ 右上角关闭钮撤。
     ⚠️ 本块是**文件尾后置覆盖**：上面的原文一字未动（v191 / v241 / v325 / v328 / v458 的钉扎都还钉着原文）。 */
  .plus-win-head189{font:500 13px/1 var(--sans);padding:8px 10px 10px}
  .plus-opt189{font:500 14px/1 var(--sans);gap:12px;padding:9px 12px;border-radius:8px}
  .plus-opt189 svg{width:17px;height:17px}
  .plus-opt189 + .plus-opt189{margin-top:2px}
  .plus-win189 .plus-opt189{padding:9px 12px}
  .plus-sep566{height:1px;background:var(--line);margin:7px 8px}
  html[data-theme="dark"] .plus-sep566{background:#262a35}

  /* ================= v568：＋ 窗宽度收一点（用户令「宽度减少一点」，2026-10-12） =================
     文件尾后置覆盖：窗体 min-width 260 → 236、内边距 12 → 10、选项水平内边距 12 → 11
     （整窗收约 24px；字号 / 行距 / 分隔线 v566 那套一字不动）。 */
  .plus-win189{min-width:236px;padding:10px}
  .plus-win189 .plus-opt189{padding:9px 11px}


  /* ================= v569：GPT 比例两排 4+4（用户令 2026-10-12：
     第一排 1:1 · 2:3 · 3:4 · 9:16 / 第二排 3:2 · 4:3 · 16:9 · 21:9） =================
     .spec-row249 是 flex-wrap 容器（gap 6px）⇒ 一颗 flex-basis:100% 的零高占位就是「强制换行」；
     上下的 6px 间距各吃掉 3px（margin:-3px 0）⇒ 两排之间仍是 6px，与行内间距一致。 */
  .spec-row249 .spec-br568{flex:0 0 100%;height:0;margin:-3px 0}
  /* ================= v581：GPT 8 档比例两排 4+4 铺满（修「选择比例挤成一坨」） =================
     根因：比例行 v257 起是 flex-wrap:nowrap（6 档一排时代口径）；v569 往里塞 flex-basis:100%
     的换行占位（.spec-br568）想排两排 4+4 —— nowrap 容器换不了行，占位反而吃掉整行宽，
     8 颗按钮被压成 0 宽（下面那条 min-width:0 放行了压缩）⇒ 图标叠条、文字竖排。
     修法（09-nodes.css 文件尾后置覆盖，同权重后加载者赢；有占位的行由 102 尾部加
     .spec-ratio2x4 修饰类）：放开换行 + 该类下按钮提到 25% 一档（两排各 4 颗正好铺满）；
     方舟 5 档无类 ⇒ 16.666% 一排照旧（5 × 16.666% = 83% 放得下，不折行）。 */
  .spec-row249.spec-ratio255{flex-wrap:wrap}
  .spec-row249.spec-ratio255.spec-ratio2x4 .spec-opt249{flex:1 1 calc(25% - 5px)}

  /* ================= v583：规格弹窗四段统一满行（用户令 2026-10-12 深夜） =================
     ① 换行占位在 25% 一档下自己占一排、把第一排挤成 3 颗 ⇒ 8 颗按钮本来就是 4+4 等宽，
        占位藏掉就归位（DOM 留着 —— [v568]⑧ / [v581]① 的钉扎与断言不破）；
     ② 画质 / 背景两行 3 等分满行（gap 6px ⇒ calc(33.333% - 5px) 三颗正好铺满）；
        分辨率行本来就是 .spec-res255（flex:1 1 0）⇒ 加到 3 档自动等宽，不用另写。 */
  .spec-row249.spec-ratio255.spec-ratio2x4 .spec-br568{display:none}
  #genQRow568 .spec-opt249{flex:1 1 calc(33.333% - 5px);min-width:0}
  #genBgRow568 .spec-opt249{flex:1 1 calc(33.333% - 5px);min-width:0}


  /* ================= v594：比例行两排等高（用户报 2026-10-13，截图点名） =================
     现象：GPT 比例行 4+4 两排，第一排比第二排高约 8px。
     根因：.spec-opt249 没有固定高度（09-nodes.css:82-87），行高由「这一排里最高的那颗按钮」
           决定；而按钮里的比例图标是**按比例画的方框**（JS 里逐颗给 width/height）——
           第一排含 9:16（图标高 20）与 2:3（18），第二排最高的才 4:3（13）、21:9 只有 9
           ⇒ 第一排被撑到 ~50px，第二排只有 ~42px。
     修法：给比例行的按钮一个统一的最小高度 + 内容居中。两排都被拉到同一高度，
           图标与文字在原位置（justify-content 由 flex-end 改成 center，行内更居中）。
     注：视频的规格弹窗复用同一个 .spec-ratio255 类 ⇒ 一并统一（它本来也是 6 档一排，
         加了 min-height 之后与图片侧观感一致，不算副作用）。
     ⚠️ 上面 104 / 105 / 278 / 279 四条被 verify-page 逐字钉着 —— 一字不动，这里只做后置覆盖。
     ================================================================================ */
  .spec-row249.spec-ratio255 .spec-opt249{min-height:50px;justify-content:center}

/* ══════ 10-main.css ══════ */
  /* ---------- v285：主界面（AI 制作游戏） ----------
     左 = 游戏预览（iframe 沙盒）；右 = 与 AI 对话；中缝可拖拽。
     本页没有左下角功能胶囊：body.ai285-on 时把缩放胶囊 / 小地图整块收掉。 */
  .ai-page285{position:fixed;left:14px;right:14px;top:62px;bottom:10px;z-index:48;display:flex;min-height:0;background:var(--bg)}   /* v316：显式吃页面底，不再靠透 body */
  .ai-page285[hidden]{display:none}
  .ai-left285{position:relative;flex:1 1 auto;min-width:200px;background:var(--card);border:1px solid var(--line);border-radius:14px;overflow:hidden;display:flex;flex-direction:column}
  /* v304：左栏上下两区 —— 上 = 游戏预览区（stage，撑满剩余高度），下 = 功能行（dock，暂空置待定） */
  .ai-stage304{position:relative;flex:1 1 auto;min-height:0}
  .ai-dock304{flex:0 0 56px;border-top:1px solid var(--line);display:flex;align-items:center;gap:8px;padding:0 12px}
  .ai-dock304 .btn{height:28px;font-size:12px;padding:0 14px}
  /* v329：dock 最前面的「代码文件」= 页面切换键（不是功能键）—— 跟同列功能键区分：强调色包边 + 柔光底，
     开着时整颗填充成强调色；文案在「文件 / 返回」之间跟着视图态切换（v333） */
  .ai-switch329{height:28px;display:inline-flex;align-items:center;gap:6px;padding:0 12px;border-radius:8px;border:1px solid var(--accent);background:var(--accent-soft);color:var(--text);font-size:12px;font-weight:600;font-family:inherit;line-height:1;cursor:pointer;margin-right:4px;flex:0 0 auto;transition:background .15s,color .15s}
  .ai-switch329:hover,.ai-switch329.on329{background:var(--accent);border-color:var(--accent);color:#0b0d12}
  .ai-switch329 svg{width:14px;height:14px;flex:0 0 14px}
  /* v329：代码视图 = 盖在游戏预览之上的一层（左 = 文件目录，右 = 代码内容），不占 dock 高度 */
  .ai-code329{position:absolute;inset:0;display:flex;min-height:0;background:var(--card)}
  .ai-code329[hidden]{display:none}
  .ai-tree329{flex:0 0 168px;min-width:0;overflow:auto;padding:8px 6px 12px;border-right:1px solid var(--line);background:var(--sunken)}
  .ai-tree-t329{font-size:11px;color:var(--text-3);padding:2px 8px 8px;letter-spacing:.4px}
  .ai-tree-i329{display:flex;align-items:center;gap:7px;padding:6px 8px;border-radius:7px;font-size:12px;line-height:1.35;color:var(--text-2);cursor:pointer;white-space:nowrap;overflow:hidden}
  .ai-tree-i329:hover{background:var(--line)}
  .ai-tree-i329.on329{background:var(--accent);color:#0b0d12;font-weight:600}
  .ai-tree-i329 svg{width:14px;height:14px;flex:0 0 14px;opacity:.9}
  .ai-tree-i329+.ai-tree-i329{margin-top:2px}
  .ai-tree-i329.sub329{padding-left:22px}
  .ai-tree-i329 em{font-style:normal;font-size:10px;color:var(--text-3);margin-left:auto;padding-left:8px}
  .ai-tree-i329.on329 em{color:#0b0d12;opacity:.7}
  .ai-codepane329{flex:1 1 auto;min-width:0;display:flex;flex-direction:column}
  .ai-codehead329{flex:0 0 36px;display:flex;align-items:center;justify-content:space-between;gap:10px;padding:0 12px;border-bottom:1px solid var(--line)}
  .ai-codefile329{font-size:12px;font-weight:600;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;color:var(--text)}
  .ai-copy329{height:22px;padding:0 10px;border-radius:6px;border:1px solid var(--line);background:var(--sunken);color:var(--text-2);font-size:11px;font-family:inherit;cursor:pointer}
  .ai-copy329:hover{color:var(--text);border-color:var(--accent)}
  .ai-pre329{flex:1 1 auto;margin:0;overflow:auto;padding:10px 12px 18px;font-size:12px;line-height:1.7;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;color:var(--text);tab-size:2}
  .ai-ln329{display:inline-block;width:34px;padding-right:10px;text-align:right;color:var(--text-3);opacity:.5;font-style:normal;-webkit-user-select:none;user-select:none}
  .ai-cm329{color:var(--text-3);font-style:italic}
  .ai-st329{color:#1f8a54}
  .ai-kw329{color:#b3005e}
  .ai-nu329{color:#b26a00}
  .ai-tg329{color:#2b6cb0}
  .ai-tip329{color:var(--text-3);font-size:13px;line-height:1.9;padding:30px 20px;text-align:center}
  html[data-theme="dark"] .ai-st329{color:#6ddba0}
  html[data-theme="dark"] .ai-kw329{color:#ff8fc0}
  html[data-theme="dark"] .ai-nu329{color:#ffc46b}
  html[data-theme="dark"] .ai-tg329{color:#8ab8ff}
  .ai-frame285{position:absolute;inset:0;width:100%;height:100%;border:0;display:block;background:var(--bg)}   /* v316：跟主题走（原来硬编码 #0b0d12，亮色主题下游戏区仍是黑的） */
  .ai-empty285{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:10px;color:var(--text-3);text-align:center;padding:20px;background:var(--card)}   /* v390：补底色 —— 没有游戏时空态盖着的 iframe 是「无 srcdoc 的 about:blank」，沙盒里被渲染成纯白，透明覆盖层 = 暗色主题下整块发白（用户截图实证）；吃 --card 与面板同色，亮暗两态都无缝 */
  .ai-empty285[hidden]{display:none}
  .ai-empty-ico285{color:var(--dim);opacity:.7}
  .ai-empty-t285{font-size:15px;color:var(--text)}
  .ai-empty-s285{font-size:12px;color:var(--text-3);max-width:320px;line-height:1.7}
  .ai-split285{flex:0 0 10px;cursor:col-resize;display:flex;align-items:center;justify-content:center;touch-action:none}
  .ai-split285::before{content:'';width:2px;height:46px;border-radius:2px;background:var(--line);transition:background .15s}
  .ai-split285:hover::before,.ai-split285.on285::before{background:var(--accent)}
  .ai-right285{flex:0 0 380px;min-width:280px;max-width:70%;display:flex;background:var(--card);border:1px solid var(--line);border-radius:14px;overflow:hidden}
  body.ai285-on .zoom-pill,body.ai285-on .mini-map,body.ai285-on .zoom-pop{display:none!important}
  body.ai285-on .layers,body.ai285-on .layers-tab{display:none!important}   /* v288：主界面没有图层面板，右缘那颗收起页签别悬着 */
  body.ai285-on .canvas-wrap{visibility:hidden!important}   /* v307：主界面是独立页面 —— 画布整层（背景网格 / 节点 / 空态）藏掉，不透底；顶栏不在 canvas-wrap 里照常显示 */
  .ai-chat285{flex:1;display:flex;flex-direction:column;min-height:0;width:100%}
  /* v407：右缘与下方输入框对齐 —— 内容右缘 = 滚动条槽（thin）+ 0 内距 ≈ 输入框的 12px 右缘；
     scrollbar-gutter:stable 让槽恒在（不随「当前可不可滚」跳变，左右两侧视觉宽度恒定） */
.ai-msgs285{flex:1;overflow-y:auto;padding:14px 0 6px 14px;scrollbar-gutter:stable;display:flex;flex-direction:column;gap:18px}
  .ai-msg285{font-size:13px;line-height:1.65;word-break:break-word;max-width:100%}
  .ai-msg-u285{align-self:flex-end;background:var(--accent);color:#0b0d12;border-radius:12px 12px 3px 12px;padding:8px 11px;white-space:pre-wrap}
  .ai-msg-a285{align-self:flex-start;background:var(--sunken);border:1px solid var(--line);border-radius:12px 12px 12px 3px;padding:9px 11px}
  /* v309：每条消息下方留白动作行 —— 平时空白（占位 20px），悬停该条消息时浮现「复制」 */
  .ai-item309{display:flex;flex-direction:column;max-width:88%}
  .ai-item309.u{align-self:flex-end;align-items:flex-end}
  .ai-item309.a{align-self:flex-start;align-items:flex-start;max-width:100%}
  .ai-item309 .ai-msg285{max-width:100%}
  .ai-act309{display:flex;justify-content:flex-end;height:20px;margin-top:2px;opacity:0;transition:opacity .15s}
  .ai-item309.a .ai-act309{justify-content:flex-start}
  .ai-item309:hover .ai-act309{opacity:1}
  .ai-copy309{border:none;background:transparent;color:var(--text-3);font-size:11px;line-height:20px;padding:0 6px;cursor:pointer;border-radius:6px;user-select:none}
  .ai-copy309:hover{color:var(--text-1);background:var(--line)}
  /* v311：画面「已关闭」态 —— 默认界面底色 + 居中提示文字 */
  .ai-closed311{position:absolute;inset:0;display:grid;place-items:center;background:var(--bg);color:var(--text-3);font-size:13px;letter-spacing:.12em;z-index:2}
  .ai-closed311[hidden]{display:none}
  .ai-sys285{align-self:center;color:var(--text-3);font-size:11.5px;background:var(--sunken);border-radius:8px;padding:4px 10px;max-width:90%}
  .ai-err285{margin-top:6px;color:#ff7b7b;font-size:12px;white-space:pre-wrap}
  .ai-think285{border:1px dashed var(--line);border-radius:10px;margin-bottom:7px;overflow:hidden}
  .ai-think-h285{display:flex;align-items:center;gap:7px;padding:6px 9px;cursor:pointer;color:var(--text-3);font-size:12px;user-select:none;-webkit-user-select:none}
  .ai-think-h285:hover{color:var(--text)}
  .ai-think285 .dot285{flex:0 0 7px;width:7px;height:7px;border-radius:50%;background:var(--accent);animation:aiPad285 1s ease-in-out infinite}
  .ai-think285.done285 .dot285{background:var(--dim);animation:none;opacity:.5}
  @keyframes aiPad285{0%,100%{opacity:.25}50%{opacity:1}}
  .ai-think-b285{display:none;padding:0 9px 8px;color:var(--text-3);font-size:12px;line-height:1.6;white-space:pre-wrap;max-height:200px;overflow-y:auto}
  .ai-think285.open .ai-think-b285{display:block}
  /* v334：思考完成 = 缩略（收成无框一行小字；点击展开才回完整虚线框） */
  .ai-think285.done285{border:0;margin-bottom:3px}
  .ai-think285.done285 .ai-think-h285{padding:2px 0;font-size:11.5px}
  .ai-think285.done285.open{border:1px dashed var(--line)}
  .ai-think285.done285.open .ai-think-h285{padding:6px 9px;font-size:12px}
  .ai-body285{white-space:pre-wrap}
  .ai-usage306{font-size:11px;line-height:1.6;color:var(--text-3);padding:3px 2px 0;user-select:text}   /* v306：本条回答的 token / 积分消耗脚注 */
  .ai-cont337{margin-top:9px;padding-top:6px;border-top:1px dashed var(--line);font-size:11px;line-height:1.6;color:var(--text-3)}   /* v337：自动续写分隔行（只做提示，不进正文） */
  .ai-pre285{background:var(--sunken);border:1px solid var(--line);border-radius:8px;padding:8px;overflow:auto;max-height:240px;font-size:11.5px;line-height:1.5;margin:6px 0;white-space:pre;font-family:ui-monospace,Consolas,monospace}
  /* v288：聊天输入改成大面板 —— 上面大片打字区，底行左模型、右发送（用户示意：整块一个圆角面板） */
  .ai-input285{margin:4px 12px 12px;border:1px solid var(--line);border-radius:14px;background:var(--sunken);padding:10px 12px;display:flex;flex-direction:column;gap:6px}
  .ai-input285:focus-within{border-color:var(--accent)}
  .ai-inrow285{display:flex;gap:8px;align-items:center}
  /* v339：排队任务条（生成 / 思考中发的消息排在这里，当前任务结束自动依次执行） */
  .ai-queue339{margin:0 12px 8px;border:1px solid var(--line);border-radius:12px;background:var(--sunken);padding:8px 10px}
  .ai-queue-h339{display:flex;align-items:center;gap:6px;font-size:11px;color:var(--text-3)}
  .ai-queue-clear339{margin-left:auto;border:0;background:none;padding:0;font-size:11px;color:var(--accent);cursor:pointer}
  .ai-qit339{display:flex;align-items:center;gap:8px;margin-top:5px;padding:5px 8px;border-radius:8px;background:var(--card)}
  .ai-qn339{flex:0 0 auto;font-size:10.5px;color:var(--accent);background:var(--accent-soft);border-radius:6px;padding:1px 6px}
  .ai-qtx339{flex:1 1 auto;min-width:0;font-size:12px;color:var(--text-2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .ai-qx339{flex:0 0 auto;border:0;background:none;padding:0 2px;font-size:12px;color:var(--text-3);cursor:pointer}
  .ai-qx339:hover{color:#ff7b7b}
  .ai-model-btn285{display:flex;align-items:center;gap:5px;flex:0 0 auto;background:var(--sunken);border:1px solid var(--line);border-radius:9px;color:var(--text);font:inherit;font-size:12px;padding:7px 9px;cursor:pointer}
  .ai-model-btn285:hover{border-color:var(--accent)}
  .ai-model-btn285 .ai-chev285{color:var(--text-3)}
  .ai-ta285{flex:1;resize:none;background:transparent;border:0;border-radius:0;color:var(--text);padding:2px 2px 0;font:inherit;font-size:13px;line-height:1.55;min-height:120px;max-height:260px;outline:none;box-sizing:border-box}
  .ai-ta285::placeholder{color:var(--text-3)}
  .ai-send285{width:34px;height:34px;flex:0 0 34px;margin-left:auto;border-radius:50%;border:0;background:linear-gradient(135deg,var(--accent),var(--accent-2));color:#0b0d12;display:grid;place-items:center;cursor:pointer;transition:.15s}
  .ai-send285 svg{width:17px;height:17px}
  .ai-send285:hover{filter:brightness(1.06)}
  .ai-send285.stop285{background:#e5484d;color:#fff}
  .ai-model-pop285{position:fixed;z-index:60;min-width:240px;background:var(--card);border:1px solid var(--line);border-radius:12px;padding:6px;box-shadow:var(--shadow);display:flex;flex-direction:column;gap:6px}
  .ai-model-pop285[hidden]{display:none}
  /* ---- v331：主界面工具（PS 式）—— dock「角色」键 + 预览区工具层（人偶可拖 / 滚轮缩放 / 选色卡 / 应用键）----
     工具层整面盖在 iframe 上但 pointer-events:none，只有人偶本体吃事件（点一下还得给游戏） */
  .ai-roles331{position:absolute;inset:0;z-index:3;pointer-events:none}
  .ai-roles331[hidden]{display:none}
  .ai-role331{position:absolute;left:0;top:0;width:40px;height:60px;pointer-events:auto;cursor:grab;touch-action:none;transform-origin:0 0;box-sizing:border-box;border:1.5px dashed transparent;border-radius:8px}
  .ai-role331:active{cursor:grabbing}
  .ai-role331.sel331{border-color:var(--accent)}
  .ai-role331 svg{width:100%;height:100%;display:block;pointer-events:none}
  .ai-role-x331{position:absolute;right:-9px;top:-9px;width:18px;height:18px;border-radius:50%;border:1px solid var(--line);background:var(--card);color:var(--text-2);font-size:10px;line-height:16px;text-align:center;cursor:pointer;user-select:none;-webkit-user-select:none;display:none;font-style:normal}
  .ai-role331.sel331 .ai-role-x331{display:block}
  .ai-role-x331:hover{color:#e5484d;border-color:#e5484d}
  .ai-pallet331{position:absolute;left:50%;bottom:12px;transform:translateX(-50%);z-index:4;display:flex;gap:10px;align-items:center;background:var(--card);border:1px solid var(--line);border-radius:999px;padding:8px 14px;box-shadow:var(--shadow)}
  .ai-pallet331[hidden]{display:none}
  .ai-dot331{width:16px;height:16px;border-radius:50%;cursor:pointer;display:block;border:2px solid transparent;box-sizing:border-box;transition:transform .12s}
  .ai-dot331:hover{transform:scale(1.18)}
  .ai-dot331.on331{border-color:var(--text)}
  .ai-apply331{position:absolute;right:12px;bottom:12px;z-index:4;height:32px;padding:0 16px;border-radius:9px;border:1px solid var(--accent);background:var(--accent);color:#0b0d12;font-size:12px;font-weight:600;font-family:inherit;line-height:1;cursor:pointer;box-shadow:var(--shadow)}
  .ai-apply331[hidden]{display:none}
  .ai-apply331:hover{filter:brightness(1.06)}
  .ai-apply331:disabled{opacity:.6;cursor:default}
  /* v331：对话框图片附件（小缩略图，点开放大 / 悬停可移除；用户气泡里一排小图） */
  .ai-pics331{display:flex;gap:8px;flex-wrap:wrap}
  .ai-pics331[hidden]{display:none}
  .ai-pic331{position:relative;width:46px;height:46px;border-radius:8px;overflow:hidden;border:1px solid var(--line);cursor:pointer;flex:0 0 46px;background:var(--card)}
  .ai-pic331 img{width:100%;height:100%;object-fit:cover;display:block}
  .ai-pic331 .ai-pic-x331{position:absolute;right:2px;top:2px;width:15px;height:15px;border-radius:50%;background:rgba(0,0,0,.62);color:#fff;font-size:10px;line-height:15px;text-align:center;display:none;font-style:normal}
  .ai-pic331:hover .ai-pic-x331{display:block}
  .ai-upics331{display:flex;gap:6px;flex-wrap:wrap;margin:0 0 5px;justify-content:flex-end}
  .ai-upics331 img{width:64px;height:64px;object-fit:cover;border-radius:8px;cursor:zoom-in;border:1px solid rgba(0,0,0,.18);display:block}
  .ai-imgview331{position:fixed;inset:0;z-index:80;background:rgba(0,0,0,.72);display:grid;place-items:center;padding:30px}
  .ai-imgview331[hidden]{display:none}
  .ai-imgview331 img{max-width:92vw;max-height:86vh;border-radius:10px;box-shadow:var(--shadow);background:var(--card)}
  .ai-imgview-x331{position:absolute;right:14px;top:12px;width:32px;height:32px;border-radius:50%;border:1px solid rgba(255,255,255,.35);background:rgba(0,0,0,.4);color:#fff;font-size:14px;cursor:pointer;font-family:inherit}
  .ai-imgview-x331:hover{background:rgba(0,0,0,.6)}
  /* v332：模型选择弹窗 = 往左下角缩放的开 / 关动画（gen / vgen / 主界面三颗同步；
     transform-origin 钉左下角 = 触发按钮的方向 —— 窗子从按钮那儿长出来、收回按钮那儿去） */
  .model-pop257,#aiModelPop285{transform-origin:0 100%;animation:popBl332 .16s ease-out}
  @keyframes popBl332{from{opacity:0;transform:scale(.82)}to{opacity:1;transform:none}}
  .pop-bl-out332{animation:popBlOut332 .16s ease-in forwards!important}
  @keyframes popBlOut332{from{opacity:1;transform:none}to{opacity:0;transform:scale(.82)}}
  /* v315：与视频生成选项按钮同款三态（横向大块：模型名 + 一行说明） */
  .ai-model-it285{display:block;width:100%;text-align:left;border:1px solid var(--line);background:var(--card);color:var(--text);padding:9px 10px;border-radius:10px;cursor:pointer;font:500 12.5px/1 var(--sans);transition:.15s}
  .ai-model-it285:hover{border-color:var(--accent);color:var(--accent)}
  .ai-model-it285 span{display:block;color:var(--text-3);font-size:11px;line-height:1.25;margin-top:3px}
  .ai-model-it285.on{border-color:var(--accent);background:var(--accent-soft);color:var(--accent)}
  html[data-theme="dark"] .ai-model-it285{background:#232631;border-color:transparent;color:#e8eaf1}
  html[data-theme="dark"] .ai-model-it285:hover{background:#262a35;color:var(--accent)}
  html[data-theme="dark"] .ai-model-it285.on{background:var(--accent-soft);border-color:var(--accent);color:var(--accent)}

  /* ---- v190：深色补漏（工作流/地图绘制胶囊 / 左下角功能胶囊 / 右上角账号区 / ⚙ 菜单 / 登录弹窗）——
     这六处原本写死白色/浅色，深色主题下一直没跟着变；底色整体再压黑一档 ---- */
  html[data-theme="dark"] .seg{background:rgba(13,15,21,.92)}
  html[data-theme="dark"] .zoom-pill{background:rgba(13,15,21,.95)}
  html[data-theme="dark"] .topbar-right{background:rgba(13,15,21,.92)}
  html[data-theme="dark"] .acct-menu{background:rgba(19,22,29,.97)}
  html[data-theme="dark"] .modal{background:#191c24}
  /* ---------- v203：深色补漏 —— 审计出的一批漏镜像浮层（入口：用户报地图绘制底部区域没改） ---------- */
  html[data-theme="dark"] .topbar-left { background:rgba(13,15,21,.92) }
  html[data-theme="dark"] .sheet { background:rgba(19,20,26,.97); box-shadow:0 20px 56px rgba(0,0,0,.5) }
  html[data-theme="dark"] .sheet-foot { background:rgba(13,15,21,.96) }
  html[data-theme="dark"] .mini-map { background:rgba(19,22,29,.97) }
  html[data-theme="dark"] .zoom-pop { background:rgba(13,15,21,.95) }
  html[data-theme="dark"] .drop-veil { background:rgba(38,42,53,.9) }
  html[data-theme="dark"] #mapBar { background:rgba(19,22,29,.97); box-shadow:0 10px 30px rgba(0,0,0,.5) }
  html[data-theme="dark"] .layers { background:rgba(19,22,29,.97); box-shadow:-14px 0 34px rgba(0,0,0,.4) }
  html[data-theme="dark"] .switch .track { background:#323748 }
  /* v208：开启态 = 白色亮轨（用户口径「开启变白色，亮色，所有开启按钮相同」）—— 上面这条深色
     轨道灰与 checked 高亮同优先级且靠后，会把开启态盖回灰；这里显式钉白（选择子更强），
     开启态旋钮转深色保证白轨上可见；全站开关（含 mini 锁定比例）统一生效 */
  html[data-theme="dark"] .switch input:checked + .track { background:#fff }
  .switch input:checked + .track::after { background:#191c24 }

/* ══════ 11-home.css ══════ */
  /* ---------- v204：主页（项目层） ---------- */
  #homeView{position:fixed;inset:0;z-index:60;background:var(--bg);overflow-y:auto}
  #homeView[hidden]{display:none}
  /* v297：主页底部视觉 = 复用「从画布选择」的蓝渐变 + 上浮像素方块（.rp-dots258/.rp-px258 原类零改动直接复用） */
  .home-glow297{position:fixed;left:0;right:0;bottom:0;height:86px;z-index:-1;pointer-events:none;overflow:hidden}   /* v310：渐变撤掉，只留上浮像素方块 */
  /* v313：主页底部像素方块 —— v310 撤掉渐变后只剩白方块，白方块在亮色浅底上几乎看不见，
     所以亮色改用品牌青蓝；暗色仍保持白色（v310 用户口径「只保留像素」）。 */
  .home-glow297 .rp-px258{background:rgba(90,143,163,.85)}
  html[data-theme="dark"] .home-glow297 .rp-px258{background:rgba(255,255,255,.95)}
  .home-acct{position:absolute;top:12px;right:14px;display:flex;align-items:center;gap:8px;z-index:1}
  /* v280：积分（右上角胶囊 + 小窗 + 充值窗） */
  /* v319：星尘胶囊去掉按钮框 —— 常态与窗口同色（无框、无底色），只有鼠标压上去才显色；
     与生产节点底部 chip 键（.vgen-chip230）同款。⚠️ 胶囊 HTML 带 btn ghost 两个类，
     暗色下 html[data-theme="dark"] .btn.ghost 的底色优先级更高 ⇒ 必须用 .btn.ghost.credit-pill280
     这种更高权重（0,3,0 / 暗色 0,4,0）才盖得住。 */
  .credit-pill280{display:inline-flex;align-items:center;gap:6px;font-variant-numeric:tabular-nums}
  .btn.ghost.credit-pill280{background:transparent;border:none;color:var(--text);padding:7px 10px;border-radius:10px;transition:.15s}
  html[data-theme="dark"] .btn.ghost.credit-pill280{background:transparent;border-color:transparent;color:var(--text)}
  .btn.ghost.credit-pill280:hover{background:var(--accent-soft);color:var(--text)}
  html[data-theme="dark"] .btn.ghost.credit-pill280:hover{background:var(--accent-soft);color:var(--text)}
  .credit-pill280:focus{outline:none;box-shadow:none}
  .credit-pill280 b{color:var(--accent);font-weight:700}
  /* v322：右上角 ⚙ 改正方形（用户口径「右上角的设置按钮改为正方形」）——
     两处 ⚙（顶栏 #acctGear / 主页 #homeGear204）边长统一 30px（= 顶栏既有按钮高 30px，
     与同排「星尘」胶囊等高）。⚠️ 顶栏那条必须连 #acctArea 一起写，才压得过
     `#acctArea .btn` 的 padding 覆盖（id 权重 > 单类）；主页那条因容器 .home-acct
     没给高度，必须显式写 height，否则会缩成一行文字的高度。
     v350：正方形 → 圆头像（账户名首字母；没名字 = 「?」），「⚙」字形全站退役。 */
  #acctArea #acctGear,
  #homeGear204{
    width:30px;height:30px;flex:0 0 30px;padding:0;box-sizing:border-box;
    border-radius:50%;background:var(--accent-soft);border-color:var(--accent);
    color:var(--accent);font-weight:700;font-size:13.5px;line-height:1;
  }
  #acctArea #acctGear:hover,
  #homeGear204:hover{background:var(--accent);border-color:var(--accent);color:#fff}
  .credit-pop280{position:fixed;z-index:80;width:272px;max-height:calc(100vh - 24px);overflow:auto;padding:12px;background:var(--card);border:1px solid var(--line);border-radius:12px;box-shadow:0 12px 34px rgba(10,12,20,.35)}
  .credit-pop280[hidden]{display:none}
  .cp-head280{font-size:12px;font-weight:600;color:var(--text);padding:0 2px 8px}
  .cp-bal280{display:flex;align-items:baseline;gap:6px;padding:0 2px 8px}
  .cp-bal280 b{font-size:26px;font-weight:700;color:var(--accent);font-variant-numeric:tabular-nums}
  .cp-bal280 span{font-size:12px;color:var(--text-3)}
  .cp-note280{font-size:11px;color:var(--text-3);line-height:1.55;padding:0 2px 8px}
  .cp-rows280{max-height:186px;overflow:auto;border-top:1px solid var(--line);padding-top:6px}
  .cp-row280{display:flex;align-items:center;justify-content:space-between;gap:10px;font-size:12px;color:var(--text-2);padding:5px 2px}
  .cp-row280 i{font-style:normal;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .cp-row280 em{font-style:normal;font-variant-numeric:tabular-nums;color:var(--text-3);white-space:nowrap}
  .cp-row280.minus em{color:#e04646}
  .cp-act280{display:flex;justify-content:flex-end;gap:8px;padding-top:10px}
  .cp-btn280{appearance:none;border:1px solid var(--line);background:transparent;color:var(--text);font:inherit;font-size:12.5px;padding:6px 14px;border-radius:8px;cursor:pointer}
  .cp-btn280:hover{border-color:var(--accent);color:var(--accent)}
  .cp-btn280.primary{background:var(--accent);border-color:var(--accent);color:#0b0d12;font-weight:600}
  .cp-btn280.primary:hover{filter:brightness(1.08);color:#0b0d12}
  .cp-tiers280{display:grid;grid-template-columns:1fr 1fr;gap:8px;padding:0 2px 8px}
  .cp-tier280{appearance:none;border:1px solid var(--line);background:var(--sunken);color:var(--text);font:inherit;font-size:13px;padding:9px 8px;border-radius:9px;cursor:pointer;text-align:center;line-height:1.4}
  .cp-tier280:hover{border-color:var(--accent);color:var(--accent)}
  .cp-tier280 b{display:block;font-size:15px;font-weight:700}
  .cp-tier280 span{font-size:11px;color:var(--text-3)}
  /* v281：真实支付区（微信扫码 / 支付宝跳转） */
  .cp-pay281{border-top:1px solid var(--line);margin:0 2px 8px;padding:10px 0 0}
  .cp-pay281[hidden]{display:none}
  .cp-pay-ch281{display:grid;grid-template-columns:1fr 1fr;gap:8px;padding-bottom:9px}
  /* v315：与视频生成选项按钮同款三态 */
  .cp-ch281{appearance:none;border:1px solid var(--line);background:var(--card);color:var(--text);font:500 12.5px/1 var(--sans);padding:9px 4px;border-radius:10px;cursor:pointer;white-space:nowrap;transition:.15s}
  .cp-ch281:hover{border-color:var(--accent);color:var(--accent)}
  .cp-ch281.on{border-color:var(--accent);background:var(--accent-soft);color:var(--accent)}
  html[data-theme="dark"] .cp-ch281{background:#232631;border-color:transparent;color:#e8eaf1}
  html[data-theme="dark"] .cp-ch281:hover{background:#262a35;color:var(--accent)}
  html[data-theme="dark"] .cp-ch281.on{background:var(--accent-soft);border-color:var(--accent);color:var(--accent)}
  .cp-qr281{width:176px;height:176px;margin:0 auto 6px;padding:8px;background:#fff;border-radius:10px;display:grid;place-items:center}
  .cp-qr281 svg{width:100%;height:100%;display:block}
  .cp-go281{appearance:none;width:100%;border:1px solid var(--accent);background:var(--accent);color:#06121a;font:inherit;font-size:13px;font-weight:600;padding:10px;border-radius:9px;cursor:pointer}
  .cp-go281:hover{filter:brightness(1.08)}
  .cp-pay-tip281{font-size:11px;color:var(--text-3);line-height:1.6;padding:6px 2px 0;word-break:break-all;text-align:center}
  .home-hero{margin:16vh auto 22px;text-align:center;pointer-events:none}
  /* v299：主页输入对话框 —— 发送即新建项目并进主界面，内容预填到主界面聊天框 */
  .home-ask299{width:min(680px,calc(100vw - 80px));margin:0 auto 40px;border:1px solid var(--line);border-radius:14px;background:var(--card);padding:10px 12px;display:flex;align-items:flex-end;gap:8px;transition:border-color .15s}
  .home-ask299:focus-within{border-color:var(--accent)}
  .home-ask-ta299{flex:1;min-width:0;border:0;outline:0;background:transparent;color:var(--text);font:500 13.5px/1.5 var(--sans);resize:none;height:24px;max-height:120px;padding:0}
  .home-ask-ta299::placeholder{color:var(--text-3)}
  .home-ask-go299{width:34px;height:34px;flex:0 0 34px;border-radius:50%;border:0;background:linear-gradient(135deg,var(--accent),var(--accent-2));color:#0b0d12;display:grid;place-items:center;cursor:pointer;transition:.15s}
  .home-ask-go299 svg{width:17px;height:17px}
  .home-ask-go299:hover{filter:brightness(1.06)}
  .home-title{font-size:34px;font-weight:700;color:var(--text);letter-spacing:.04em}
  .home-grid{width:min(1240px,calc(100vw - 80px));margin:0 auto;display:grid;grid-template-columns:repeat(4,1fr);gap:16px;padding-bottom:60px}
  @media (max-width:980px){.home-grid{grid-template-columns:repeat(2,1fr)}}
  .home-card{position:relative;aspect-ratio:16/10;border-radius:14px;overflow:hidden;border:1px solid var(--line);background:var(--card);cursor:pointer;padding:0;font:inherit;text-align:left;transition:.15s}
  .home-card:hover{transform:translateY(-2px);border-color:var(--line-strong)}
  .home-card img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block}
  .home-card .scrim204{position:absolute;left:0;right:0;bottom:0;height:56px;background:linear-gradient(transparent,rgba(0,0,0,.55));border:0}
  .home-card .nm{position:absolute;left:12px;bottom:9px;right:12px;color:#fff;font-size:13px;font-weight:600;z-index:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;text-shadow:0 1px 4px rgba(0,0,0,.55)}
  .home-more278{position:absolute;right:8px;bottom:8px;z-index:2;width:26px;height:26px;border-radius:8px;background:rgba(10,12,20,.55);display:grid;place-items:center;color:#fff;opacity:0;transition:opacity .15s;cursor:pointer}
  .home-card:hover .home-more278{opacity:1}
  .home-more278:hover{background:rgba(10,12,20,.8);color:var(--accent)}
  .home-more278 svg{display:block}
  .home-card.new{background:transparent;border:1.5px dashed var(--line-strong);display:flex;flex-direction:column;align-items:center;justify-content:center;gap:10px;color:var(--text-2);font-size:12.5px}
  .home-card.new .plus{width:44px;height:44px;border-radius:12px;background:var(--card);border:1px solid var(--line);display:grid;place-items:center;font-size:20px;color:var(--text);line-height:1}
  .home-card.new:hover{border-color:var(--accent);color:var(--accent)}
  /* 项目切换胶囊（画布左上角：logo = 回主页，胶囊 = 项目下拉） */
  .proj-logo204{appearance:none;border:0;background:transparent;padding:2px 4px;cursor:pointer;display:inline-flex;align-items:center;border-radius:8px}
  .proj-logo204 .brand-logo{height:22px;border-radius:5px;display:block}
  .proj-pill204{appearance:none;border:0;background:transparent;color:var(--text);font:inherit;font-size:13px;font-weight:600;cursor:pointer;display:inline-flex;align-items:center;gap:6px;padding:5px 9px;border-radius:9px}
  .proj-pill204:hover{background:var(--accent-soft)}
  .proj-pill204 .proj-chev204{display:block;opacity:.6}
  .proj-menu204{position:fixed;z-index:70;min-width:210px;padding:6px;background:var(--card);border:1px solid var(--line);border-radius:12px;box-shadow:0 12px 34px rgba(10,12,20,.25)}
  .proj-menu204[hidden]{display:none}

  /* ---------- v348：左上角项目键拆两颗 + 项目全局设置面板 ---------- */
  .proj-split348{display:inline-flex;align-items:center;gap:4px}
  .topbar-left .proj-chev348{padding:0 7px}   /* 箭头键窄一点（名称键保持 0 9px） */
  .proj-chev348 .proj-chev204{display:block;opacity:.6}

  .modal.projset348{max-width:640px;padding:22px}
  .ps-sec348{margin-top:18px;padding-top:16px;border-top:1px solid var(--line)}
  .ps-sec348:first-of-type{border-top:0;padding-top:0}
  .ps-sec-t348{font-size:13.5px;font-weight:600;color:var(--text)}
  .ps-sec-s348{margin-top:4px;font-size:11.5px;line-height:1.65;color:var(--text-3)}
  .ps-sec-s348.warn348{color:#c2703a}   /* 警示口径（深色另配一支） */
  html[data-theme="dark"] .ps-sec-s348.warn348{color:#e5a76b}
  /* v349：美术风格改「按钮组」—— 生图 / 生视频下方选择按钮（.spec-opt249 / .at-opt313）同款三态，不再用下拉。
     ⚠️ 字体别抄 var(--sans)（全站没定义，那条 shorthand 是哑的）；行标签走 .at-lab313 同款小灰字。 */
  .ps-rows348{margin-top:12px;display:flex;flex-direction:column;gap:14px}
  .ps-lab348{display:block;font-size:11.5px;line-height:1;color:var(--text-3);margin:0 0 7px;padding-left:2px}
  .ps-pick348{display:flex;flex-wrap:wrap;gap:6px}
  .ps-art348{appearance:none;border:1px solid var(--line);background:var(--card);color:var(--text);
    font-family:inherit;font-size:12.5px;font-weight:500;line-height:1;padding:8px 12px;border-radius:10px;
    cursor:pointer;transition:.15s}
  /* v354：按钮左右放满 —— flex-wrap 下每行按钮等比拉开铺满整行（末行同样铺满），四组共用一次改齐 */
  .ps-art348{flex:1 1 auto;min-width:0;text-align:center}
  /* v358：头身比例组 = 一排 3 个等宽对齐（6 项正好 3×2，行行铺满不留空） */
  .ps-3col358 .ps-art348{flex:0 0 calc((100% - 12px) / 3)}
  .ps-art348:hover{border-color:var(--accent);color:var(--accent)}
  .ps-art348.on348{border-color:var(--accent);background:var(--accent-soft);color:var(--accent)}
  html[data-theme="dark"] .ps-art348{background:#232631;border-color:transparent;color:#e8eaf1}
  html[data-theme="dark"] .ps-art348:hover{background:#262a35;color:var(--accent)}
  html[data-theme="dark"] .ps-art348.on348{background:var(--accent-soft);border-color:var(--accent);color:var(--accent)}
  /* v349：标题旁小问号 + 说明浮层（浮层挂 body、JS 摆位 —— 左右不出屏、底下放不下翻上面） */
  .ps-q348{appearance:none;border:1px solid var(--line-strong);background:var(--sunken);color:var(--text-3);
    width:16px;height:16px;border-radius:50%;font-family:inherit;font-size:10.5px;line-height:1;font-weight:600;
    display:inline-grid;place-items:center;cursor:help;margin-left:6px;vertical-align:1px;padding:0;transition:.15s}
  .ps-q348:hover{border-color:var(--accent);color:var(--accent)}
  .ps-tip348{position:fixed;left:0;top:0;z-index:90;max-width:320px;padding:8px 10px;background:var(--card);
    color:var(--text);border:1px solid var(--line);border-radius:10px;box-shadow:var(--shadow);
    font-size:11.5px;line-height:1.6;font-weight:400;pointer-events:none}
  .ps-tip348[hidden]{display:none}
  html[data-theme="dark"] .ps-tip348{background:#191c24;border-color:#262a35}
  .ps-cards348{margin-top:12px;display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:8px}
  .ps-cards348.is-two348{grid-template-columns:repeat(2,minmax(0,1fr))}
  .ps-card348{appearance:none;border:1px solid var(--line);background:var(--card);color:var(--text);
    border-radius:11px;padding:10px 9px;cursor:pointer;transition:.15s;
    display:flex;flex-direction:column;gap:4px;min-width:0;text-align:left;font:inherit}
  .ps-card348:hover{border-color:var(--accent);color:var(--accent)}
  .ps-card348 b{font-size:12px;font-weight:600;line-height:1.3}
  .ps-card348 i{font-style:normal;font-size:10.5px;line-height:1.35;color:var(--text-3)}
  .ps-card348.on348{border-color:var(--accent);background:var(--accent-soft);color:var(--accent)}
  .ps-card348.on348 i{color:var(--accent);opacity:.9}
  .proj-menu-head204{font-size:11px;color:var(--text-3);padding:5px 10px 3px}
  .proj-menu-it204{appearance:none;border:0;background:transparent;width:100%;display:flex;align-items:center;justify-content:space-between;gap:10px;color:var(--text);font:inherit;font-size:13px;padding:8px 10px;border-radius:8px;cursor:pointer;text-align:left}
  .proj-menu-it204:hover{background:var(--accent-soft);color:var(--accent)}
  .proj-menu-it204.on{background:var(--accent-soft)}
  .proj-more278{appearance:none;border:0;background:transparent;color:var(--text-3);width:22px;height:22px;flex:none;display:grid;place-items:center;border-radius:6px;cursor:pointer;padding:0}
  .proj-more278:hover{background:var(--sunken);color:var(--accent)}
  .proj-more278 svg{display:block}
  .proj-menu-sep204{height:1px;background:var(--line);margin:5px 4px}
  .proj-menu-new204{appearance:none;border:0;background:transparent;width:100%;display:flex;align-items:center;justify-content:space-between;color:var(--text);font:inherit;font-size:13px;padding:8px 10px;border-radius:8px;cursor:pointer}
  .proj-menu-new204:hover{background:var(--accent-soft);color:var(--accent)}
  .proj-menu-new204 .plus{width:22px;display:grid;place-items:center;line-height:1}   /* v279：＋ 收进与三点同宽的列，两列圆心对齐 */
  .proj-ren278{position:fixed;z-index:80;width:232px;padding:10px;background:var(--card);border:1px solid var(--line);border-radius:12px;box-shadow:0 12px 34px rgba(10,12,20,.35)}
  .proj-ren278[hidden]{display:none}
  .proj-ren278 .hd278{font-size:11px;color:var(--text-3);padding:2px 2px 6px}
  .proj-ren278 input{width:100%;box-sizing:border-box;background:var(--sunken);border:1px solid var(--line);color:var(--text);font:inherit;font-size:13px;padding:7px 9px;border-radius:8px;outline:none}
  .proj-ren278 input:focus{border-color:var(--accent)}
  .proj-ren278 .row278{display:flex;justify-content:flex-end;padding-top:8px}
  .proj-ren278 .ok278{appearance:none;border:0;background:var(--accent);color:#0b0d12;font:inherit;font-size:12.5px;font-weight:600;padding:6px 14px;border-radius:8px;cursor:pointer}
  .proj-ren278 .ok278:hover{filter:brightness(1.08)}
  /* v291：项目三点菜单（重命名 / 删除） */
  .proj-more291{position:fixed;z-index:80;min-width:112px;padding:4px;background:var(--card);border:1px solid var(--line);border-radius:10px;box-shadow:0 12px 34px rgba(10,12,20,.35)}
  .proj-more291[hidden]{display:none}
  .proj-more-it291{appearance:none;display:block;width:100%;box-sizing:border-box;border:0;background:transparent;color:var(--text);font:inherit;font-size:12.5px;text-align:left;padding:7px 10px;border-radius:7px;cursor:pointer}
  .proj-more-it291:hover{background:var(--sunken)}
  .proj-more-it291.danger291{color:#e5636a}
  .proj-more-it291.danger291:hover{background:rgba(229,99,106,.12)}
  #homeMenu204{z-index:70}
  /* v314：顶栏 ⚙ 菜单同款提层 —— 主界面整页层 .ai-page285（z48、top:62px 起）与主页 #homeView（z60）
     都盖得过 z34 的菜单（菜单 top:64px 起，正好撞进层里）= 用户报的「已登录时 ⚙ 设置点不开」。
     主页那份当年已提到 70，顶栏这份漏了（同类一次改齐）。星尘窗（.credit-pop280 z80）/ 充值窗同层 / 登录弹窗（z95）本来就盖得住，不用动。 */
  #acctMenu{z-index:70}

/* ══════ 12-resume389.css ══════ */
  /* ================= v389：刷新后保持在当前页面 =================
     只在启动「恢复上次的项目 / 分段」期间盖一层，恢复完立刻移除
     （元素由 js/src/69-remember-page389.js 建，这里只描外观 + 转圈）。
     目的：项目列表要从云端拉（段 2 的 refreshAuth），这中间不能让用户先看到主页或空工作区。
     ⚠️ 配色走全站主题 token（--bg / --text-2 / --line-strong / --accent），不发明一次性颜色。
     z-index：主页 #homeView 是 60，弹层 80~95，浮层菜单 400 —— 取 300，盖住前两档、不干扰浮层。 */
  .resume-mask389{
    position:fixed;inset:0;z-index:300;
    display:flex;align-items:center;justify-content:center;
    background:var(--bg);
  }
  .resume-box389{
    display:flex;align-items:center;gap:10px;
    color:var(--text-2);font-size:13px;letter-spacing:.2px;
  }
  .resume-spin389{
    width:15px;height:15px;border-radius:50%;
    border:2px solid var(--line-strong);
    border-top-color:var(--accent);
    animation:resume-spin389 .7s linear infinite;
  }
  @keyframes resume-spin389{ to{ transform:rotate(360deg) } }

/* ══════ 13-ent-chain394.css ══════ */
/* v394：角色动作链 —— 子画布内的「节点参数面板」（浮层）
   点子画布里的节点弹出：图片生成（提示词 / 参考图 / 比例 / 分辨率 / 模型）、
   图片处理（自动抠图 / 识别容差 / 连续 / 消除锯齿 / 平滑插值 / 宫格行列）、
   序列帧（帧率 / 帧数）、切片（只读）。
   配色一律走全站主题变量（--card / --line / --text* / --sunken / --accent*），
   亮暗主题自动跟随，**不出现任何裸色值**。 */
.entc-win351{position:relative}
.entcp394{position:absolute;top:54px;right:14px;z-index:6;
  width:min(336px,38%);max-height:calc(100% - 82px);overflow:auto;
  box-sizing:border-box;padding:12px 12px 14px;
  background:var(--card);border:1px solid var(--line);border-radius:var(--radius);
  box-shadow:var(--shadow);
  font:12px/1.6 var(--sans);color:var(--text)}
.entcp394[hidden]{display:none}
.entcp-h394{font-weight:700;font-size:12.5px;color:var(--text);
  margin:0 0 9px;padding-bottom:8px;border-bottom:1px solid var(--line)}
.entcp-h394 .entcp-sub394{color:var(--text-2);font-weight:400;margin-left:6px}
.entcp-r394{display:flex;align-items:center;gap:8px;margin:0 0 8px}
.entcp-r394>span{flex:0 0 60px;color:var(--text-2)}
.entcp-r394>b{color:var(--text);font-weight:600;min-width:34px;text-align:right}
.entcp-ta394{display:block;width:100%;box-sizing:border-box;resize:vertical;
  margin:0 0 9px;padding:7px 8px;
  background:var(--sunken);color:var(--text);
  border:1px solid var(--line);border-radius:8px;
  font:12px/1.55 var(--sans)}
.entcp-sel394{flex:1 1 auto;min-width:0;
  padding:5px 6px;background:var(--sunken);color:var(--text);
  border:1px solid var(--line);border-radius:8px;font:12px var(--sans)}
.entcp-sw394{display:flex;align-items:center;gap:8px;margin:0 0 7px;color:var(--text-2);cursor:pointer}
.entcp-sw394 input{margin:0;width:14px;height:14px;accent-color:var(--accent)}
.entcp-rng394{flex:1 1 auto;min-width:0;accent-color:var(--accent)}
.entcp-thumb394{display:flex;align-items:center;justify-content:center;
  flex:1 1 auto;min-width:0;aspect-ratio:16/9;overflow:hidden;
  background:var(--sunken);border:1px solid var(--line);border-radius:8px;
  color:var(--text-3);font-weight:400;text-align:center}
.entcp-thumb394 canvas{max-width:100%;max-height:100%;image-rendering:pixelated}
.entcp-b394{display:flex;gap:8px;margin-top:10px}
.entcp-btn394{flex:1 1 auto;padding:7px 10px;cursor:pointer;
  background:var(--sunken);color:var(--text);
  border:1px solid var(--line);border-radius:8px;
  font:600 12px var(--sans)}
.entcp-btn394:hover{border-color:var(--accent);color:var(--accent)}
.entcp-tip394{margin:0 0 8px;color:var(--text-3)}

/* ══════ 14-ai-float397.css ══════ */
  /* ================= 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))}

/* ══════ 15-sub-full398.css ══════ */
/* v398：子画布 = 完整的「小号无限画布」 —— 参数面板**从「钉在右上角」改成「紧贴选中节点下沿」**
   （与 18-sheet-ui.js 的 layoutNodeUI 同一套几何：水平居中于节点 + 垂直紧贴下沿 + 夹在画布内，
   下面塞不下就翻到节点上方）。面板 DOM（#entChainPanel394 / .entcp394）由
   73-subcanvas-full398.js 从 .entc-win351 挪进 .entc-body351，位置只用 transform:translate——
   所以这里必须把 13-ent-chain394.css 里那套 top / right 定位整个接管掉。
   配色一律走全站主题变量（--card / --line / --text* / --sunken / --accent*），不出现任何裸色值。 */
.entc-body351>.entcp394{position:absolute;left:0;top:0;right:auto;
  width:min(336px,78%);max-height:calc(100% - 16px);
  transform:translate(0,0);transform-origin:0 0;will-change:transform;
  z-index:7;pointer-events:auto}
.entc-body351>.entcp394[hidden]{display:none}

/* v398：子画布里的「连线断开 ✕ / 手动接线 ＋」都是画在 canvas 上的（不是 DOM），
   这一条只负责让画布在拖「＋」时给出十字光标 —— 与主画布的 grab / marquee 同一族口径。 */
.entc-body351 canvas{cursor:default}
.entc-body351 canvas.sub398-move{cursor:move}
.entc-body351 canvas.sub398-link{cursor:pointer}
.entc-body351 canvas.sub398-plus{cursor:crosshair}

/* ══════ 16-ai-float400.css ══════ */
  /* ================= v400：「开发预览」= 无限画布上的两个浮层窗口 =================
     用户口径（原话）：
       · 「"开发预览" 不是独立页面，而是在无限画布上同时打开两个浮层窗口：游戏预览窗口 + AI 聊天窗口。
          点击 "开发预览" 按钮 = 同时打开这两个窗口，并在两个窗口增加一个和画布底色相同颜色的颜色层
          （渐变出现，用于视觉上达到无限画布上节点隐藏的效果，只要这两个任意窗口关闭，颜色层渐变消失）。」
       · AI 聊天窗口（右下角）：高度与开发预览页面的聊天框一致；窗口顶部有最小化按钮（收回右下角小按钮）；
          展开时右下角的聊天小按钮隐藏；**只能按住窗口左边缘**左右拖动调整宽度。
       · 游戏预览窗口（左下角）：高度同上；有最小化按钮（收回左下角那颗键的位置）；
          展开时左下角的功能按钮区域（.zoom-pill）整块隐藏；**只能按住窗口右边缘**左右拖动调整宽度。
     ⚠️ v402 起「同角那组键整块隐藏」这条**作废**：两窗下沿抬到 84px 之后底部按钮区照常可见可用
        （用户令「不遮挡底部按钮区」）；另加「游戏预览窗右上角那颗小窗口键」→ 见 styles/18-ai-pip402.css。

     层叠：颜色层是浮窗容器里的**第一个**子元素，两窗在它之后 ⇒ 同层内按 DOM 顺序，两窗恒在颜色层之上。
     浮窗状态机在 js/src/72-ai-float397.js（本文件只补外壳），挂载与同步在 js/src/74-ai-float400.js。 */

  /* ---------- ① 两窗尺寸 ----------
     v400 原本照抄整页那两栏（top:62 / bottom:10 = 视口高 - 72px）；
     **v402 起下沿抬到 84px**（用户令「底部高度往上移动，不遮挡底部按钮区」）⇒ 比整页矮 74px。 */
  /* v402：下沿 10px → **84px**（用户令「底部高度往上移动，不遮挡底部按钮区」）。
     让开的是三块同角的东西：左下角缩放胶囊（14~46）/ 右下角对话圆钮（14~60）/ 缩放拖动条（52~76）。 */
  .ai285-float397>.ai-left285{
    top:62px;bottom:84px;height:auto;left:14px;width:460px;
  }
  /* v402：默认宽度 372px → **16vw**（≈ 页面宽度的 16%；1440 屏下约 230px）。
     `min-width` 必须跟着放到 176（styles/14 那条 `min-width:280px` 会顶住 width ⇒ 16vw 落不下来）。 */
  .ai285-float397>.ai-right285{
    top:62px;bottom:84px;height:auto;right:14px;width:16vw;min-width:352px;max-width:calc(100vw - 28px);
    flex-direction:column;      /* 整页那会儿是左右排（只装聊天区）；浮窗多了顶栏 ⇒ 改成上下排 */
  }
  /* v400：v397 的 `resize:both` 退役 —— 改由「指定那一条边」的手柄调宽（见 ④） */
  .ai285-float397>.ai-left285,
  .ai285-float397>.ai-right285{resize:none}

  /* ---------- ② 颜色层：和画布底色同色，盖住无限画布上的节点 ----------
     口径：**两窗都开**才亮（关掉任意一个 ⇒ 渐变灭）。所以开单窗（V 键 / 右下角圆钮）时画布照常可见。
     `.aiveil400` 的底色取 `--canvas`（= 全站「画布底」，与 --bg 同一个值），不发明一次性颜色。
     顶栏留出来（top:62px 起）—— 否则两窗全开后顶栏被盖住就出不来了。 */
  .aiveil400{
    /* v402：下沿抬到 84px —— 颜色层亮着时是 `pointer-events:auto`，压到底部按钮区会把它们一起吞掉。 */
    position:fixed;left:0;right:0;top:62px;bottom:84px;z-index:0;
    /* ⚠️ 必须写 `background-color:` 这个**完整属性名** —— 与画布本体（styles/04-canvas.css 的
       .canvas-wrap）同一写法；别图省事缩写成 `background:` 简写。 */
    background-color:var(--canvas);
    opacity:0;pointer-events:none;transition:opacity .28s ease;
  }
  .aiveil400.on400{opacity:1;pointer-events:auto}   /* 亮起来顺带把画布交互也吞掉：看不见的节点不该还能点到 */
  /* 「渐变出现」必须走 **animation**，不能只靠 transition：开两窗时 `.ai-page285` 刚从
     `hidden`（display:none）里翻出来，同一帧里浏览器**不会**给「上一帧不在渲染树上的元素」
     补间 ⇒ transition 会直接以 opacity:1 出现、渐变看不见。animation 不吃这条限制 ——
     元素一进渲染树就从 from 帧播。渐变**消失**那边（关掉任一窗、页面还留着）照旧吃上面那条
     transition（元素本来就在渲染树里，1 → 0 正常补间）。 */
  @keyframes aiveilIn400{from{opacity:0}to{opacity:1}}
  .aiveil400.on400{animation:aiveilIn400 .28s ease both}

  /* ---------- ③ 窗口顶栏（只在浮窗模式出现）：标题 + 最小化键 ---------- */
  .aibar400{
    display:none;flex:0 0 30px;align-items:center;gap:8px;padding:0 6px 0 12px;
    border-bottom:1px solid var(--line);background:var(--card);
    font-size:12px;font-weight:600;color:var(--text);user-select:none;
  }
  .ai285-float397>.ai-left285>.aibar400,
  .ai285-float397>.ai-right285>.aibar400{display:flex}
  .aibar-t400{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .aibar-min400{
    flex:0 0 auto;width:22px;height:22px;padding:0;border:1px solid transparent;border-radius:6px;
    background:transparent;color:var(--text-2);display:grid;place-items:center;cursor:pointer;
    transition:background .15s,color .15s,border-color .15s;
  }
  .aibar-min400:hover{background:var(--sunken);border-color:var(--line);color:var(--accent)}
  .aibar-min400 svg{width:13px;height:13px;display:block}

  /* ---------- ④ 单边拖宽手柄：左窗只认**右缘**、右窗只认**左缘** ----------
     6px 细条贴在窗口内侧那条边上；两窗各自的「自由边」正好朝画面中间，拖起来手感一致。 */
  .aigrip400{
    display:none;position:absolute;top:0;bottom:0;width:6px;z-index:3;
    cursor:col-resize;touch-action:none;background:transparent;
    transition:background .15s;
  }
  .ai285-float397>.ai-left285>.aigrip400{display:block;right:0}
  .ai285-float397>.ai-right285>.aigrip400{display:block;left:0}
  .aigrip400:hover,.aigrip400.on400{background:var(--accent-soft)}
  body.aif-resize400{cursor:col-resize}
  body.aif-resize400 .ai-left285,body.aif-resize400 .ai-right285{user-select:none}

  /* ---------- ⑤ 展开时收掉同角那组键（免得和窗口叠在一起） ---------- */
  /* ---------- ⑤ v402：底部按钮区**不再收掉** ----------
     用户令「底部高度往上移动，不遮挡底部按钮区」⇒ 两窗下沿抬到 84px 之后，左下角功能键区
     （V / M / L / S / C + 缩放）与右下角那颗对话圆钮整块露出来，照常可见可用。
     旧口径「窗口盖住它们 ⇒ 一并收掉」是权宜之计，作废。 */
  /* 只剩小地图仍要收：它 190×132（left:14 bottom:58），下沿比窗口还低 26px ⇒ 展开时必然与游戏窗叠在一起。 */
  body.aif-l400 .mini-map{display:none!important}

  /* ---------- ⑥ 两窗都开着时，顶栏那颗「开发预览」键给个「正在用」的视觉 ----------
     它不再是分段（点了不再进整页），所以不去抢 flow 那侧的高亮，只描一圈强调色。
     ⚠️ `.seg button` 是 `border:none` ⇒ 只写 `border-color` 什么都看不见，必须用
     `box-shadow` 描边（与右下角圆钮的 `aria-pressed` 态同款写法），也不会顶动布局。 */
  body.aif-l400.aif-r400 #workSeg [data-seg="home"]{color:var(--accent);box-shadow:0 0 0 1px var(--accent)}

  /* ================= v405：两窗再往下点 / 圆钮缩小换 icon / 滚动条默认隐藏 =================
     用户口径（原话）：「让两个高度统一的同时，把那个游戏预览的高度再往下移一点；右边那个
       是不是会变得很紧？那就把右下角那个对话的按钮要缩小，把那个聊天的图标缩小；然后现在
       这个图标不好看，改一下。然后 AI 对话里面那个上下滑动的条，正常情况下是隐藏的，只有
       鼠标移动到那个位置、或者说正在滑动的时候才显示。」 */

  /* ---------- ⑦ 两窗下沿 84px -> **68px**（整体往下 16px；两窗 top / bottom 仍相同 => 高度继续统一） ----------
     68px 的量化依据（与 v402 那三块同源）：
       缩放胶囊 14~48 完整让开；缩放拖动条 52~76 只压掉底缘 8px（轨道中心 ~64，11px 滑块完整可见）；
       对话圆钮缩到 38px 后 = 14~52 => 窗下沿距圆钮顶还留 16px。
     ⚠️ 颜色层 `.aiveil400` **必须同拍跟随**：它亮着时是 `pointer-events:auto`，压到底部按钮区会把它们一起吞掉。
     ⚠️ 上面 v402 那条 `bottom:84px` 原文一字未动（闸门钉着）—— 这里走**同选择器后置规则覆盖**。 */
  .ai285-float397>.ai-left285,
  .ai285-float397>.ai-right285{top:62px;bottom:68px}
  .aiveil400{top:62px;bottom:68px}

  /* ---------- ⑧ 右下角那颗圆钮缩小：46px -> **38px**（icon 22px -> 19px） ----------
     口径与 v402 同源：窗子往下压会把右下角挤紧 => 把圆钮收一圈，窗下沿与圆钮之间重新留出 16px。
     `bottom:14px` 锚点不动（它与左下角缩放胶囊、左边那组功能键同在 14 这一条线上）。 */
  .aifab397{width:38px;height:38px}
  .aifab397 svg{width:19px;height:19px}

  /* ---------- ⑨ AI 对话（两个浮窗里所有滚动区）滚动条**默认隐藏**，鼠标进入 / 正在滑动时才显形 ----------
     `:hover` 一条就同时覆盖两种情形 —— 滚轮滚 / 拖滑块时指针必然落在滚动区里。
     颜色取主题变量 `--line-strong`（与地图素材列表 `.map-asset-list` 同款），不发明一次性颜色。
     下面两组：标准属性（新版 Chrome / Firefox 认，认了就会忽略 webkit 那组）+ webkit 兜底（旧内核）。 */
  .ai-msgs285,.ai-think-b285,.ai-pre285,.ai-ta285,.ai-tree329,.ai-pre329{
    scrollbar-width:thin;scrollbar-color:transparent transparent;
  }
  .ai-msgs285:hover,.ai-think-b285:hover,.ai-pre285:hover,.ai-ta285:hover,.ai-tree329:hover,.ai-pre329:hover{
    scrollbar-color:var(--line-strong) transparent;
  }
  .ai-msgs285::-webkit-scrollbar,.ai-think-b285::-webkit-scrollbar,.ai-pre285::-webkit-scrollbar,
  .ai-ta285::-webkit-scrollbar,.ai-tree329::-webkit-scrollbar,.ai-pre329::-webkit-scrollbar{width:8px;height:8px}
  .ai-msgs285::-webkit-scrollbar-track,.ai-think-b285::-webkit-scrollbar-track,.ai-pre285::-webkit-scrollbar-track,
  .ai-ta285::-webkit-scrollbar-track,.ai-tree329::-webkit-scrollbar-track,.ai-pre329::-webkit-scrollbar-track{background:transparent}
  .ai-msgs285::-webkit-scrollbar-thumb,.ai-think-b285::-webkit-scrollbar-thumb,.ai-pre285::-webkit-scrollbar-thumb,
  .ai-ta285::-webkit-scrollbar-thumb,.ai-tree329::-webkit-scrollbar-thumb,.ai-pre329::-webkit-scrollbar-thumb{background:transparent;border-radius:4px}
  .ai-msgs285:hover::-webkit-scrollbar-thumb,.ai-think-b285:hover::-webkit-scrollbar-thumb,.ai-pre285:hover::-webkit-scrollbar-thumb,
  .ai-ta285:hover::-webkit-scrollbar-thumb,.ai-tree329:hover::-webkit-scrollbar-thumb,.ai-pre329:hover::-webkit-scrollbar-thumb{background:var(--line-strong)}

  /* ---------- ⑪ v407：颜色层盖满整个视口 + 合并态顶栏提到 49 ----------
     用户口径（原话）：「之前用于达到视觉上节点隐藏效果的颜色层，没有完全覆盖画布，现在只隐藏了
       中景区域，上下没有隐藏，更改为遮住整个画面。」
     v405 那条 `top:62px;bottom:68px` 原文一字未动（闸门钉着）—— 这里同选择器后置覆盖成 top/bottom 双 0。
     ⚠️ 顶栏 z30 低于浮窗容器 z48：盖满后顶栏会被颜色层压住（关闭 / 切换键点不到）⇒
        两窗都开（body.aif-l400.aif-r400）时把顶栏提到 49。颜色层的新触发条件见 js/src/74 的 aifTouch407。 */
  .aiveil400{top:0;bottom:0}
  body.aif-l400.aif-r400 .topbar{z-index:49}

  /* ================= v409：默认贴在一起 / 顶栏「开发预览」键同款高亮 / 底部两区抬到颜色层之上 =================
     用户口径（原话）：
       · 「把上面的开发预览的那个按钮模式和无限画布地图绘制显示弄成一样的」
       · 「点它的时候，这个游戏预览的窗口和那个 AI 对话的那个窗口默认是贴在一起的」
       · 「现在它那个颜色层把左下角和右下角的图标也遮住了，我的目的只是想让它遮住画布…不要遮住那个
          左下角和右下角的图标 ⇒ 将那两个图标区域的图层，比这个颜色层的图层更高就行了」 */

  /* ---------- ① 顶栏「开发预览」键的「正在用」态 = 与「无限画布 / 地图绘制」那份 .on **一模一样** ----------
     JS 侧（74-ai-float400.js 的 aifSegHome409）在两窗都开时给这颗键挂上 `.on`（互斥：另两颗摘掉），
     所以这里只要**抵消 v400 那条描边口径**（`color:var(--accent);box-shadow:0 0 0 1px`）—— 那句原文一字未动，
     用同选择器后置覆盖成 `.seg button.on` 的同一组值（实底强调色 + `#0b0d12` 字 + 同一条投影）。 */
  body.aif-l400.aif-r400 #workSeg [data-seg="home"]{
    background:var(--accent);color:#0b0d12;box-shadow:0 3px 9px rgba(20,214,255,.28);
  }

  /* ---------- ② 默认布局：两窗**贴在一起**（各占一半，中缝 = AIF_GAP407 的 12px） ----------
     40px = 左 14 + 右 14 + 中缝 12 ⇒ 两窗等宽 ⇒ 右窗左缘正好落在「左窗右缘 + 12」上。
     上面 v400/v402 那两条默认宽度（`width:460px` / `width:16vw;min-width:352px`）原文一字未动（闸门钉着），
     这里同选择器后置覆盖 width（右窗的 min-width 不动 —— 窄视口仍由 352px 兜底）。 */
  .ai285-float397>.ai-left285{width:calc((100vw - 40px) / 2)}
  .ai285-float397>.ai-right285{width:calc((100vw - 40px) / 2)}

  /* ---------- ③ 左下角功能胶囊（含缩放拖动条）+ 右下角圆钮：**抬到颜色层之上** ----------
     颜色层是浮窗容器（z48）里的第一个子元素 ⇒ 容器里的东西都压在 z47 这两块之上（用户报「把图标也遮住了」）。
     口径：只把这两个「功能入口」抬到 49（与 v407 的合并态顶栏同一条线），**画布照旧被颜色层盖住**。
     `.zoom-pop` 一起抬 —— 它是胶囊里那颗百分比弹出来的拖动条，不抬就点不开（看不见）。 */
  body.aif-l400.aif-r400 .zoom-pill{z-index:49}
  body.aif-l400.aif-r400 .zoom-pop{z-index:49}
  body.aif-l400.aif-r400 .aifab397{z-index:49}

/* ══════ 17-sub-canvas401.css ══════ */
/* v401：子画布 = 真·无限画布 —— 打开时把主画布**整层借过来用**
   （75-sub-canvas401.js 把 state.items 换成子条目一个、view 换成子视野），
   所以这里只有两件事：
     ① 藏掉主画布的周边 UI（顶栏 / 缩放胶囊 / 小地图 / 图层面板 / 底部 dock）；
     ② 给「窗口」描一圈边 + 一条顶栏（标题 + 关闭键）。
   ⚠️ 没有遮罩层：画布本身就是子画布的画布，**节点 / 连线 / 空白**都要能直接点到，
     所以整层 pointer-events:none，只有关闭键那一颗收回点击。
   ⚠️ z-index 只给 20（低于 .sheet 的 32）—— 参数面板 / 新建节点窗 / 提示全都自动在它上面。

   v404：窗口尺寸回到 v393 / v398 那扇「窗口」（用户报「子画布窗口怎么变成全屏了，
   保持之前的尺寸，尺寸不要变」）—— v401 曾把边框铺到整个视口（16px 四边留白）= 看着全屏。
   现在窗口恒 **16:9**、双上限 **94vw / 92vh**（数值与旧 `.modal.entc-win351` 完全一致，
   `(92vh - 104px) * 16 / 9` 里的 104 = 旧窗的头 + 上下留白），居中摆放；
   窗口之外的主画布整层 `clip-path` 裁掉（**同时裁掉命中区** ⇒ 窗外的节点既看不见也点不到）。 */
body.sub401-on .topbar,
body.sub401-on .zoom-pill,
body.sub401-on .zoom-pop,
body.sub401-on .mini-map,
body.sub401-on .layers,
body.sub401-on .layers-tab,
body.sub401-on .dock:not(#sliceDock),   /* v423：全站 .dock 类只有 #sliceDock —— 这条本意藏主底栏，实际只误伤切割面板底部（识别行 / 宫格切割 / 打包下载），排除它 */
body.sub401-on #mapBar,
body.sub401-on .aifab397{display:none!important}

.sub401{position:fixed;inset:0;z-index:20;pointer-events:none}
.sub401[hidden]{display:none}
/* v404：同一选择器的**补充规则**（上一行被闸门钉死、一字不动）——
   把它变成居中容器：窗口 + 标题栏同宽同轴（column-reverse：DOM 里 frame 在前，
   视觉上标题栏在上） */
body.sub401-on{--sub401w:min(calc(94vw - 44px),calc((92vh - 104px) * 16 / 9))}
.sub401{display:flex;flex-direction:column-reverse;align-items:center;justify-content:center;gap:8px}

.sub401-frame{position:relative;width:var(--sub401w);height:auto;aspect-ratio:16/9;
  border:1px solid var(--line);border-radius:16px;
  box-shadow:0 18px 60px rgba(8,10,18,.16);pointer-events:none}

.sub401-bar{position:relative;width:var(--sub401w);height:32px;
  display:flex;align-items:center;gap:10px;pointer-events:none}
.sub401-title{font-size:13px;font-weight:600;color:var(--text-2)}
.sub401-hint{font-size:11.5px;color:var(--text-3);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.sub401-x{margin-left:auto;pointer-events:auto;width:26px;height:26px;flex:0 0 26px;
  border-radius:8px;border:1px solid var(--line);background:var(--card);color:var(--text-2);
  font:inherit;font-size:12px;line-height:1;cursor:pointer;transition:.15s}
.sub401-x:hover{border-color:var(--accent);color:var(--accent);background:var(--accent-soft)}

/* v404：窗口之外不再露主画布（也不可点）—— 画布整层按窗口矩形裁剪；
   inset 的四条边都用「50% − 窗口半宽/半高」算出来，与 .sub401 的居中口径同一份数值。 */
body.sub401-on #canvasWrap{clip-path:inset(calc(50% - var(--sub401w) * 9 / 16 / 2) calc(50% - var(--sub401w) / 2) calc(50% - var(--sub401w) * 9 / 16 / 2) calc(50% - var(--sub401w) / 2) round 16px)}

/* ================= v421：参数面板在子画布里不许高过窗口内框 =================
   v404 的 clip-path 会把出框部分裁掉 —— 用户报「切割功能显示不完全」；
   layoutNodeUI 已把面板位置整个夹进 frame（18-sheet-ui.js v421 段），这里给面板本身限高兜底。 */
body.sub401-on .sheet{max-height:calc(var(--sub401w) * 9 / 16 - 20px)}

/* v423：切割面板底部 dock（#sliceDock）恢复显示后整块更高 —— max-height 之下允许滚动兜底，
   不再静默裁掉下半段（.sheet 默认 overflow:hidden 会吞内容）。 */
body.sub401-on .sheet{overflow-y:auto}

/* ══════ 18-ai-pip402.css ══════ */
  /* ================= v402：游戏预览「小窗口」显示（在页面内随意缩放 / 移动） =================
     用户口径（原话）：「游戏预览窗口右上角增加新按钮：小窗口显示，在页面内，可以随意缩放和移动位置。」
     逻辑在 js/src/76-ai-pip402.js（拖动 / 缩放写**行内样式**），本文件只负责「盒子怎么摆」与两颗键的样子。 */

  /* ---------- ① 顶栏那颗「小窗口」键（游戏预览窗右上角，最小化键**左边**） ---------- */
  .aibar-pip402{
    flex:0 0 auto;width:22px;height:22px;padding:0;border:1px solid transparent;border-radius:6px;
    background:transparent;color:var(--text-2);display:grid;place-items:center;cursor:pointer;
    transition:background .15s,color .15s,border-color .15s;
  }
  .aibar-pip402:hover{background:var(--sunken);border-color:var(--line);color:var(--accent)}
  .aibar-pip402 svg{width:13px;height:13px;display:block}
  /* 开着的状态：强调色包边 + 柔光底（与顶栏最小化键、右下角圆钮同一族写法，不发明一次性颜色） */
  .aibar-pip402[aria-pressed="true"]{background:var(--accent-soft);border-color:var(--accent);color:var(--accent)}

  /* ---------- ② 右下角那枚「改大小」角标（只在小窗模式出现） ----------
     用两条边线画一个角，不用图片、不用裸色值 —— 与全站浮窗边框同族（--line-strong / --accent）。 */
  .aifpip-g402{
    display:none;position:absolute;right:0;bottom:0;width:16px;height:16px;z-index:4;
    cursor:nwse-resize;touch-action:none;pointer-events:auto;
    border-right:2px solid var(--line-strong);border-bottom:2px solid var(--line-strong);
    border-bottom-right-radius:6px;
  }
  .aifpip-g402:hover{border-color:var(--accent)}

  /* ---------- ③ 小窗模式本体 ----------
     ⚠️ 只改「盒子怎么摆」，不动里面任何东西 —— 顶栏 / 游戏 iframe / 底部功能行照旧。
     位置与尺寸走**行内样式**（拖动 / 缩放直接写 `el.style`），这里只负责把它从「钉在左下角」
     还原成「普通小盒子」：清掉 right / bottom 锚点、关掉锚角缩放动画、把单边拖宽手柄让给角标。 */
  body.aif-pip402 .ai285-float397>.ai-left285{
    right:auto;bottom:auto;
    min-width:0;min-height:0;max-width:none;max-height:none;
    /* 关掉 aifIn397 / aifOut397 的锚角缩放 —— 否则拖动时整块会跟着被缩放 */
    transform:none!important;
    resize:none;z-index:55;              /* 高于同层的对话窗（auto）与颜色层（z 0） */
    box-shadow:var(--shadow);
  }
  body.aif-pip402 .ai285-float397>.ai-left285>.aigrip400{display:none!important}
  body.aif-pip402 .ai285-float397>.ai-left285>.aifpip-g402{display:block}
  body.aif-pip402 .ai285-float397>.ai-left285>.aibar400{cursor:move}
  body.aif-pip402{cursor:default}

  /* ---------- ④ v564：角标的倒角跟窗体对齐（用户报「右下角的拖拽图标的倒角和窗口的倒角不一致」） ----------
     窗体 `.ai-left285` 是 `border:1px solid` + `border-radius:14px` + `overflow:hidden`
     ⇒ 子元素被裁出来的圆角是 **14 - 1 = 13px**；角标原来写 6px ⇒ 它那截 L 形边线的外角
     正好落在裁剪弧**之外**、被窗体削掉 ⇒ 角上缺一块、跟窗体的弧对不上。
     改成 13px：角标边线的外缘正好贴着窗体内壁的弧走（hover 变强调色时也一样贴）。
     ⚠️ 不能写 14 —— 比裁剪弧还大 ⇒ 外角又被削掉，等于没改。 */
  .aifpip-g402{border-bottom-right-radius:13px}

/* ══════ 19-ent-actionbar403.css ══════ */
  /* ================= v403：角色节点「生成动作条」（节点下方细长操作条） =================
     用户口径（2026-10-10 原话要点）：
       单选角色节点 → 节点下方出现一条细长操作条，四个模块：
       ① 生成动作 —— 隐藏式按钮（不 hover 看不到样式，样式 = 右上角「星尘余额」同款），
          点开 = 多选框：待机 / 移动 / 攻击 / 死亡 / 受击，带「全选」「取消」；默认 待机
       ② 生成模式 —— 同款隐藏式按钮，两个选项：普通模式（生图 → 抠图切割 → 帧动画）/
          高级模式（生视频 → 取帧）；默认 高级模式
       ③ 消耗星尘 —— 黄色字（用户明令黄色，特例于全站主题色口径），按勾选数 × 单价换算；
          换算口径以后变了同步改这里
       ④ 生成 —— 有颜色的实底按钮
     与节点内 5 颗动作按钮**共存**（用户拍板）。选择状态存 n.p.eab403（快照白名单放行）。 */

#entActBar403{position:fixed;left:0;top:0;z-index:47;display:flex;align-items:center;gap:2px;padding:3px 6px;border-radius:12px;background:var(--card);border:1px solid var(--line);box-shadow:var(--shadow);font-size:12.5px}
#entActBar403[hidden]{display:none}
/* 隐藏式双钮 —— .btn.ghost.credit-pill280 同款：平时全透明，hover 才亮柔光底 */
.eab-pill403{flex:0 0 auto;background:transparent;border:none;color:var(--text);padding:7px 10px;border-radius:10px;font-size:12.5px;font-family:inherit;line-height:1;display:inline-flex;align-items:center;gap:6px;cursor:pointer;transition:background .15s,color .15s;font-variant-numeric:tabular-nums}
.eab-pill403:hover{background:var(--accent-soft);color:var(--text)}
.eab-pill403:focus{outline:none;box-shadow:none}
.eab-pill403 b{color:var(--accent);font-weight:700;max-width:150px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* 消耗星尘 —— 黄色字（用户 2026-10-10 明令，主题色口径的明示特例） */
.eab-cost403{flex:0 0 auto;display:inline-flex;align-items:center;gap:4px;padding:0 8px;color:#f5c542;font-size:12px;font-variant-numeric:tabular-nums;white-space:nowrap}
.eab-cost403 b{font-weight:700}
/* 生成 —— 实底主按钮（.ai-apply331 同族） */
.eab-go403{flex:0 0 auto;height:28px;padding:0 16px;border-radius:9px;border:1px solid var(--accent);background:var(--accent);color:#0b0d12;font-size:12.5px;font-weight:600;font-family:inherit;line-height:1;cursor:pointer;box-shadow:var(--shadow);transition:background .15s}
.eab-go403:hover{background:var(--accent-2)}
.eab-go403:disabled{opacity:.5;cursor:default}
/* 下拉卡（点窗内不关 / 点窗外空白才关 —— 全站交互口径） */
.eab-drop403{position:absolute;top:calc(100% + 6px);min-width:176px;background:var(--card);border:1px solid var(--line);border-radius:12px;box-shadow:var(--shadow);padding:6px;display:flex;flex-direction:column;gap:2px;z-index:3}
.eab-drop403[hidden]{display:none}
.eab-opt403{display:flex;align-items:center;gap:8px;padding:7px 9px;border-radius:8px;font-size:12.5px;color:var(--text);cursor:pointer;user-select:none}
.eab-opt403:hover{background:var(--sunken)}
.eab-opt403 input{accent-color:var(--accent);margin:0}
.eab-foot403{display:flex;gap:6px;padding:6px 4px 2px;border-top:1px solid var(--line);margin-top:4px}
.eab-foot403 button{flex:1;height:26px;border-radius:8px;border:1px solid var(--line);background:transparent;color:var(--text-2);font-size:12px;font-family:inherit;line-height:1;cursor:pointer;transition:background .15s,color .15s}
.eab-foot403 button:hover{background:var(--accent-soft);color:var(--text)}
.eab-mopt403{display:flex;flex-direction:column;gap:2px;text-align:left;padding:8px 10px;border-radius:8px;border:none;background:transparent;color:var(--text);font-size:12.5px;font-family:inherit;line-height:1.35;cursor:pointer;transition:background .15s,color .15s}
.eab-mopt403:hover{background:var(--sunken)}
.eab-mopt403.on{background:var(--accent-soft);color:var(--accent)}
.eab-mopt403 span{font-size:11px;color:var(--text-3)}
.eab-mopt403.on span{color:var(--accent)}

/* ================= v406：白字退役 / 全站「星尘」图标 =================
   用户口径（2026-10-10 原话）：
     ① 下面这一条功能区域删除白色字部分（=「生成动作」「生成模式」「消耗星尘」三个白字标签，只留值 / 图标）
     ② 该功能区和节点居中对齐（几何在 js/src/77 的 eabSync403：量实时宽度回中，DOM 串被闸门钉着的原文一字未动）
     ③ 功能区往下移动，和选择框保持间距（EAB403.GAP = 14）
     ④ 星尘 icon：菱形星星形状；「消耗星尘」替换为 icon；其他所有星尘显示的地方都替换为星尘图标+数字。 */

/* —— 全站「星尘」图标（菱形星星）：mask 填 currentColor ⇒ 永远跟所在容器同色，不发明一次性颜色。
      配色原则只有一条「数字什么色 icon 就什么色」—— 余额胶囊 / 弹层大数字是 --accent ⇒ icon 也是 --accent；
      动作条消耗是用户明令的黄 #f5c542 ⇒ icon 跟着黄（继承 currentColor，不用再写一条）。 */
.cr-ico406{display:inline-block;flex:0 0 auto;width:12px;height:12px;background-color:currentColor;-webkit-mask:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M12 1.6l3 7.4 7.4 3-7.4 3-3 7.4-3-7.4-7.4-3 7.4-3z'/></svg>") center/contain no-repeat;mask:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M12 1.6l3 7.4 7.4 3-7.4 3-3 7.4-3-7.4-7.4-3 7.4-3z'/></svg>") center/contain no-repeat}
.credit-pill280 .cr-ico406{color:var(--accent)}
.cp-bal280 .cr-ico406{width:18px;height:18px;color:var(--accent);align-self:center}
.cr-hint300 .cr-ico406{color:var(--accent);margin-right:3px;vertical-align:-1px}
.eab-cost403 .cr-ico406{width:13px;height:13px}

/* ---------- v408：消耗星尘统一白 logo+数字 / 双钮白字 / 竖线分隔 + 间距 ----------
   用户原话：「① 所有生成需要显示消耗星尘数量的地方，全部统一为白色logo和数字
   ③ 2个按钮都显示为白色字体。④ 两个按钮之间增加 | 浅色竖线分隔，增加第二个按钮和后面一个元素（星尘消耗数量）之间的间距」
   旧口径（.eab-cost403 的黄 #f5c542 / .eab-pill403 b 与 .cr-hint300 icon 的 accent / .cr-hint300 数字的 text-2）
   原文均一字未动（闸门钉着）—— 全部走同选择器后置覆盖。白色 = var(--text)（主题正文字色，暗色下即白）。 */
/* ① 消耗位统一白：动作条消耗（覆盖黄）+ 生成消耗提示（数字 text-2 -> 白；④ 同拍把与第二钮的间距 padding-left 8 -> 14） */
.eab-cost403{color:var(--text);padding:0 8px 0 14px}
.cr-hint300{color:var(--text)}
.cr-hint300 .cr-ico406{color:var(--text)}
/* ③ 两颗隐藏式钮白字（覆盖 accent） */
.eab-pill403 b{color:var(--text)}
/* ④ 双钮之间的浅色竖线 */
.eab-sep403{flex:0 0 auto;width:1px;height:14px;background:var(--line)}

/* ================= v412：动作条间距 =================
   用户口径（2026-10-10）：① 两颗按钮和中间竖线（杠杆）的间距变大一点 —— 竖线左右各加 7px 外距
   （叠加容器 gap 2px ⇒ 每侧约 9px）；② 高级模式按钮和后面星尘元素之间的间距增大两三倍 ——
   消耗位左 padding 14 → 38（约 2.7 倍）；③ 多选折叠「第一个 +N」在 js/src/77 的 eabSyncLabel403，
   CSS 不参与（选择窗 / 确认弹窗里仍是完整动作清单）。 */
.eab-sep403{margin:0 7px}
.eab-cost403{padding:0 8px 0 38px}

/* ══════ 20-ent-stepwin416.css ══════ */
  /* ================= v416：分步核对窗口（子画布内临时功能窗） =================
     用户口径（2026-10-11 原话要点）：
       「把每一步都设置成一个按钮 我需要一步一步跟你核对脚本是否真确
         每一步一个按钮，组成一个功能临时窗口，临时放在子画布中，我要一步一步检查」
     JS 在 js/src/79-ent-stepwin416.js；配色全走主题色变量（铁律：不发明一次性颜色）。
     另含 v416 动作条「分步」按钮（.eab-step403）的样式 —— 按钮本体在 77 的 DOM 模板里。 */

.stw416{position:fixed;left:0;top:0;z-index:95;pointer-events:auto;min-width:232px;max-width:288px;background:var(--card);border:1px solid var(--line);border-radius:14px;box-shadow:var(--shadow);padding:10px;display:flex;flex-direction:column;gap:8px;font-size:12.5px;color:var(--text)}
.stw416[hidden]{display:none}
.stw416-h{display:flex;align-items:center;justify-content:space-between;gap:8px}
.stw416-h b{font-size:13px}
.stw416-x{flex:0 0 auto;width:22px;height:22px;border-radius:7px;border:1px solid var(--line);background:transparent;color:var(--text-2);font-size:12px;line-height:1;cursor:pointer;transition:background .15s,color .15s}
.stw416-x:hover{background:var(--accent-soft);color:var(--text)}
.stw416-meta{font-size:11.5px;color:var(--text-2)}
.stw416-step{height:32px;border-radius:9px;border:1px solid var(--accent);background:transparent;color:var(--accent);font-size:12.5px;font-weight:600;font-family:inherit;line-height:1;cursor:pointer;text-align:left;padding:0 12px;transition:background .15s,color .15s}
.stw416-step:hover{background:var(--accent-soft)}
.stw416-step:disabled{opacity:.45;cursor:default;background:transparent}
.stw416-step.done{border-color:var(--line);color:var(--text)}
.stw416-step.done::after{content:' ✓';color:var(--accent)}
.stw416-say{font-size:11.5px;color:var(--text-2);line-height:1.45}

/* 动作条「分步」按钮 —— 描边次级按钮（与实底「生成」区分，主题色描边） */
.eab-step403{flex:0 0 auto;height:28px;padding:0 12px;border-radius:9px;border:1px solid var(--accent);background:transparent;color:var(--accent);font-size:12.5px;font-weight:600;font-family:inherit;line-height:1;cursor:pointer;transition:background .15s,color .15s}
.eab-step403:hover{background:var(--accent-soft)}

/* ══════ 21-ai-agent422.css ══════ */
  /* ================= v422：AI 编码 Agent 守则弹窗（.modal.agent-win422） =================
     外壳铁律：连写 `.modal.agent-win422` + 显式 max-width:none（单类选择器与 .modal 同权重，
     .modal 定义更靠后 ⇒ 不连写会被压成 400px 窄条）。配色全走主题变量。 */
  .modal.agent-win422{
    max-width:none;width:min(780px,94vw);
  }
  .agent-pre422{
    margin:0;padding:14px 16px;border:1px solid var(--line);border-radius:10px;
    background:var(--sunken);color:var(--text);
    font:12.5px/1.75 var(--sans);
    white-space:pre-wrap;word-break:break-word;
    max-height:min(58vh,560px);overflow:auto;
  }

/* ══════ 22-adv-stepwin425.css ══════ */
  /* ================= v425：分步核对窗 · 高级模式段（样式） =================
     模式段（普通 / 高级）走全站分段控件三态同款；高级按钮复用 .stw416-step。配色全走主题变量。 */
  .stw416-adv425{display:flex;flex-direction:column;gap:6px}
  .stw416-seg425{display:flex;gap:4px;margin:0 0 2px}
  .stw416-seg425 button{
    flex:1;border:1px solid var(--line);background:var(--card);color:var(--text-2);
    font:600 11px/1 var(--sans);padding:6px 0;border-radius:7px;cursor:pointer;transition:.15s;
  }
  .stw416-seg425 button:hover{border-color:var(--accent);color:var(--accent)}
  .stw416-seg425 button.on{border-color:var(--accent);background:var(--accent-soft);color:var(--accent)}
  .stw416-advrow425{display:flex;flex-direction:column;gap:6px}
  .stw416-advnote425{font-size:10.5px;line-height:1.5;color:var(--text-3);padding:0 2px}

/* ══════ 23-node-doc457.css ══════ */
  /* ================= v457：节点说明弹窗（.modal.node-doc-win457） =================
     用户口径：「把四类节点的口径写成说明文档，放到右上角设置里」——
     弹窗正文由 js/src/94-nodecat457.js 的 NODE_CAT457 **渲染**出来（分类与说明单一源头），
     本文件只管长相。
     外壳铁律：连写 `.modal.node-doc-win457` + 显式 max-width:none（单类选择器与 .modal 同权重、
     .modal 定义更靠后 ⇒ 不连写会被压成 400px 窄条）。配色一律走主题变量，不发明一次性颜色。 */
  .modal.node-doc-win457{max-width:none;width:min(780px,94vw)}
  /* v422 那套弹窗正文的滚动口径沿用（长内容自己滚，弹窗外壳不被撑高） */
  .nd-body457{margin-top:2px;max-height:min(62vh,620px);overflow:auto;padding-right:4px}
  .nd-sec457{border-top:1px solid var(--line);padding:13px 0 3px}
  .nd-sec457:first-child{border-top:none;padding-top:2px}
  .nd-head457{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
  .nd-no457{
    flex:none;width:20px;height:20px;border-radius:6px;font-style:normal;text-align:center;
    font:600 11.5px/20px var(--sans);background:var(--accent-soft);color:var(--accent);
  }
  .nd-name457{font-size:14px;color:var(--text)}
  .nd-one457{font-size:11.5px;color:var(--text-3)}
  .nd-tip457{margin:7px 0 9px;font-size:12px;line-height:1.75;color:var(--text-2)}
  .nd-card457{
    border:1px solid var(--line);border-radius:12px;background:var(--sunken);
    padding:11px 13px;margin-bottom:9px;
  }
  .nd-ct457{display:flex;align-items:baseline;gap:8px;flex-wrap:wrap}
  .nd-cname457{font-size:13px;color:var(--text)}
  .nd-chip457{
    font:11px/1.7 var(--sans);color:var(--text-3);background:var(--card);
    border:1px solid var(--line);border-radius:6px;padding:0 6px;
  }
  .nd-rows457{
    margin:8px 0 0;display:grid;grid-template-columns:76px 1fr;gap:4px 10px;
  }
  .nd-k457{margin:0;font-size:11.5px;color:var(--text-3)}
  .nd-v457{margin:0;font-size:12.5px;line-height:1.7;color:var(--text)}
  .nd-rules457{margin:8px 0 0;padding-left:17px}
  .nd-rules457 li{font-size:12px;line-height:1.8;color:var(--text-2)}
  .nd-rules457 li::marker{color:var(--accent)}

/* ══════ 24-dragshield562.css ══════ */
  /* ============================================================================
     v562 · 拖拽期间让「游戏 iframe」不吃指针
     ----------------------------------------------------------------------------
     用户报（2026-10-12）：「游戏预览界面，在启动时，按住鼠标拖拽调整该界面宽度时，
     拖拽移动到画面中会卡住，只有在游戏启动时会有，关闭时不会。」

     ★ 真因：单边拖宽（74-ai-float400）与小窗拖动 / 缩放（76-ai-pip402）都把
       `pointermove` / `pointerup` 挂在**父 window** 上；游戏一启动，盖在画面上的
       `#aiEmpty285`（空态）/ `#aiClosed311`（已关闭）两片实心层都 hidden
       （`[hidden]{display:none}`）⇒ 指针直接命中 `#aiFrame285`（<iframe>，铺满游戏区）
       ⇒ **事件被子文档吃掉、父文档收不到 `pointermove`** ⇒ 宽度停在原地 = 「卡住」。
       游戏没启动 / 已关闭时命中落在父文档自己的 div 上 ⇒ 事件照常到父 window ⇒ 不卡。

     ★ 做法：手势起手时 `js/src/96-dragshield562.js` 给 body 挂 `aif-dragshield562`
       （松手 / 指针取消 / 失焦 / 页面隐藏 任一来即摘），本表让 iframe 指针穿透回父文档。
       走**新类**而不是复用 74 的 `body.aif-resize400`：小窗（76）拖动 / 缩放时也要屏蔽，
       而那个类只在单边拖宽时加、还带 `cursor:col-resize`。

     ⚠️ 只改这一个属性：游戏照常跑、键盘照常收、脚本照常执行；类一摘立刻恢复鼠标交互。
     ============================================================================ */
  body.aif-dragshield562 #aiFrame285{pointer-events:none}

/* ══════ 25-ai-split563.css ══════ */
/* ================= v563②：两窗贴在一起时，中缝那颗「同时拖拽」手柄 =================
   用户口径（原话）：「当 2 个窗口切在一起时，触发一个同时拖拽按钮，在两个窗口的间距间，
     拖拽这个按钮，可同时调整两个窗口宽度」。

   `#aiSplit285` 是 v285 就有的老元素（title 原本是「左右拖拽调整两边宽度」），一直是**空壳**
   —— 没有任何拖拽处理器；浮窗模式下还被 styles/14 那句「浮窗各占一角，中缝没有意义」
   `display:none` 收掉。v563 把它复活成「共用手柄」：手势在 js/src/98-splitdrag563.js，
   这里只补「浮窗模式下的定位 / 显隐 / 拖动态」。

   竖条本身沿用 styles/10 里的 `.ai-split285::before`（2px 圆角条 + hover 变强调色）——
   配色全走主题变量（--line / --accent），不发明一次性颜色。 */

/* ① 浮窗模式下从「flex 分隔条」变成「贴着中缝的一根定位条」——
     位置与尺寸全由 JS 按两窗真实几何写行内样式（见 98 的 splitSync563）。
     ⚠️ 必须显式 `pointer-events:auto`：浮窗容器整层是 none（styles/14 ①）。 */
.ai285-float397>#aiSplit285{
  display:none;position:fixed;z-index:4;
  align-items:center;justify-content:center;
  background:transparent;cursor:col-resize;touch-action:none;pointer-events:auto;
}
/* ② 只在「两窗贴在一起」时露出（JS 加 .aif-s563）——
      判据 = 74 的 aifTouch407()（两窗都开 + 不在小窗模式 + 间距 ≤ 12px），
      与颜色层 / 画布守卫同一份口径。 */
.ai285-float397>#aiSplit285.aif-s563{display:flex}
/* ③ 拖它的时候：整页光标保持 col-resize（指针会滑到两窗上面去）、禁用选中 ——
      与 styles/16 里单边拖宽那对 `body.aif-resize400` 同款手感。 */
body.aif-split563{cursor:col-resize}
body.aif-split563 .ai-left285,body.aif-split563 .ai-right285{user-select:none}
/* ④ 拖动中那颗竖条保持强调色（`styles/10` 的 `.ai-split285:hover::before` 只在指针压着
      那 10px 时才亮，拖到窗子上就没了 —— 这里给拖动态一条更靠后的同值规则兜住）。 */
.ai285-float397>#aiSplit285.aif-sdrag563::before{background:var(--accent)}

/* ══════ 26-seqpanel571.css ══════ */
  /* ============================================================================
     v571 / v572 · 序列帧功能区（用户令 2026-10-12）
     ----------------------------------------------------------------------------
     v571：上面一排按钮（进入编辑 / 选中帧数 / 播放帧率 / 打包下载）+ 下面帧图墙；
           卡片标题（h2 那行「序列帧」）与「已取 N 帧…」说明行整个删掉。
     v572：① 面板顶排（模式徽标 + 添加 / 生成）在序列帧面板**整排不显示** —— 与
             gen / vgen 面板同款待遇（09-nodes.css 里那条原文被闸门逐字钉着 ⇒ 在这里
             后置补一条，原文一字不动）；
           ② 长横线删掉；③ 打包下载挪到按钮排最右；④ 按钮排里的胶囊 / 按钮
             边框全去掉（只保留卡片最外面那一圈边框）。
     配色一律走主题变量（--card / --line / --line-strong / --text / --text-2 / --accent-soft）。
     ============================================================================ */

  /* ---------- 顶排整排不显示（序列帧面板；gen / vgen 同款，09 原文未动） ---------- */
  .sheet[data-node189="vframes"] .sheet-bar{display:none}

  /* ---------- 功能一排（v574：挪到帧图墙下面） ---------- */
  #cardFrames .seqbar571{display:flex;flex-wrap:wrap;align-items:center;gap:8px;margin-top:8px}
  /* 下拉胶囊：只有「名字 + 下拉」本体 —— 不带框不带底（v572：区块边框全去掉） */
  #cardFrames .seqchip571{display:inline-flex;align-items:center;gap:6px}
  #cardFrames .seqchip571 i{font-style:normal;font-size:12px;color:var(--text-2);flex:0 0 auto}
  #cardFrames .seqchip571 .sel{margin-left:0;border:none;background:transparent;padding:3px 6px;box-shadow:none}
  #cardFrames .seqchip571 .sel:focus{box-shadow:0 0 0 3px var(--accent-soft)}
  html[data-theme="dark"] #cardFrames .seqchip571 .sel{background:transparent}
  /* v574：进入编辑 / 打包下载恢复全站可见式 —— .mini-btn 本体自带描边（悬停变主题色），
     这里不再压平；旧口径两条已从各闸门同步退役 */
  /* 打包下载恒在最右 */
  #cardFrames .seqbar571 #framesZipBtn{margin-left:auto}

/* ══════ 27-seqedit573.css ══════ */
  /* ============================================================================
     v573 头注
     ----------------------------------------------------------------------------
     用户令（2026-10-12）：① 窗口 = 整页大小基础上四边各留一点点边距 + 圆角边框；
       ② 上 =「序列帧编辑画布」（XY 轴 + 原点坐标，**可隐藏**，单位为像素）；
       ③ 下 ≈ 1/4 高 = 功能区 + 所有序列帧图片。
     DOM 由 104（壳）+ 105（内容）建；本表只管外观。
     配色一律走主题变量（--card / --sunken / --line / --line-strong / --text / --text-2 /
     --text-3 / --accent / --accent-soft / --sans / --shadow），不发明裸色；
     遮罩底色沿用站内既有 0,0,0,.45 那一档（07-layers.css:211 同款），不另挑色。
     ============================================================================ */

  /* ---------- 遮罩 + 窗（四边各留一点边距 + 圆角边框） ---------- */
  .seqedit-mask571{position:fixed;inset:0;z-index:120;background:rgba(0,0,0,.45)}
  .seqedit-mask571[hidden]{display:none}
  .seqedit-win571{position:absolute;inset:12px;display:flex;flex-direction:column;
    border:1px solid var(--line-strong);border-radius:14px;background:var(--card);
    box-shadow:var(--shadow);overflow:hidden}
  .seqedit-head571{display:flex;align-items:center;gap:8px;padding:9px 12px;
    border-bottom:1px solid var(--line)}
  .seqedit-head571 b{flex:1;min-width:0;font:600 13px/1 var(--sans);color:var(--text)}
  .seqedit-x571{flex:0 0 auto;width:26px;height:26px;padding:0;border-radius:8px;
    border:1px solid var(--line);background:var(--card);color:var(--text-2);
    font:12px/1 var(--sans);cursor:pointer}
  .seqedit-x571:hover{border-color:var(--accent);color:var(--accent)}
  .seqedit-body571{flex:1;min-height:0;display:flex;flex-direction:column}

  /* ---------- 上区：序列帧编辑画布 ---------- */
  .seqedit-stage573{flex:1;min-height:0;display:flex;flex-direction:column}
  .seqedit-sbar573{display:flex;align-items:center;gap:8px;padding:8px 12px;
    border-bottom:1px solid var(--line)}
  .seqedit-stitle573{flex:1;min-width:0;font:600 12.5px/1 var(--sans);color:var(--text)}
  .seqedit-cvbox573{position:relative;flex:1;min-height:0;background:var(--sunken)}
  /* touch-action:none —— 画布上的拖动（移动已放置的帧 / 从帧图墙拖过来）在触屏 / 触控笔下不被浏览器抢去滚动 */
  .seqedit-cv573{display:block;width:100%;height:100%;touch-action:none}

  /* ---------- 下区（约占 1/4 高）：功能区 + 所有序列帧图片 ---------- */
  .seqedit-foot573{flex:0 0 25%;min-height:132px;display:flex;border-top:1px solid var(--line)}
  /* v573 下半段：功能区多了「调色 / 像素」两组 ⇒ 加宽 + 超高自己滚（下区仍是 1/4 高） */
  .seqedit-func573{flex:0 0 auto;width:430px;display:flex;flex-direction:column;gap:8px;
    padding:10px 12px;border-right:1px solid var(--line);overflow:auto}
  .seqedit-ftitle573{font:600 12.5px/1 var(--sans);color:var(--text-2)}
  .seqedit-row573{display:flex;align-items:center;gap:6px}
  .seqedit-row573 i{flex:0 0 auto;width:60px;font-style:normal;font-size:12px;color:var(--text-2)}
  .seqedit-row573 .sel{margin-left:0;flex:1;min-width:0}
  .seqedit-btns573{display:flex;flex-wrap:wrap;gap:6px}
  .seqedit-note573{font-size:11.5px;line-height:1.5;color:var(--text-3)}
  /* 帧图墙本体复用站内 .frames-grid / .frame-cell（帧池全列，配色跟主题）——
     原带的 max-height:266px / margin 是给面板里那块定的，这里按窗的下区高度走，覆盖掉 */
  .seqedit-grid573{flex:1;min-width:0;margin:0;max-height:none;overflow:auto;
    padding:10px 12px;align-content:start}
  /* 正在播的那一帧：与「已选中」(`.on` 的描边) 区分开，只用一层浅底 */
  .seqedit-grid573 .frame-cell.now573{background:var(--accent-soft)}

  /* ---------- v573 下半段：画布摆放（读数 / 落点） ---------- */
  .seqedit-est573{flex:0 0 auto;font-size:11.5px;color:var(--text-3)}

  /* ---------- v573 下半段：功能区两组参数（调色 / 像素） ---------- */
  .seqedit-grp573{display:flex;flex-direction:column;gap:5px;min-width:0}
  .seqedit-gtitle573{display:flex;align-items:center;gap:6px;
    font:600 11.5px/1 var(--sans);color:var(--text-2)}
  .seqedit-gtitle573::after{content:'';flex:1;height:1px;background:var(--line)}
  .seqedit-rngs573{display:grid;grid-template-columns:1fr 1fr;gap:4px 12px;min-width:0}
  .seqedit-rng573{display:flex;align-items:center;gap:6px;min-width:0}
  .seqedit-rng573 em{flex:0 0 auto;width:50px;font-style:normal;font-size:11.5px;color:var(--text-2)}
  .seqedit-rng573 input[type="range"]{flex:1;min-width:0;height:16px;margin:0;accent-color:var(--accent)}
  .seqedit-rng573 .seqedit-num573{flex:0 0 auto;width:46px;padding:2px 4px;border-radius:6px;
    border:1px solid var(--line);background:var(--card);color:var(--text);
    font:11.5px/1.4 var(--sans);text-align:right}
  .seqedit-chks573{display:flex;flex-wrap:wrap;gap:12px;align-items:center}
  .seqedit-chks573 label{display:inline-flex;align-items:center;gap:4px;font-size:11.5px;color:var(--text-2)}
  .seqedit-chks573 input[type="checkbox"]{margin:0;accent-color:var(--accent)}

/* ══════ 28-seqctl575.css ══════ */
  /* ============================================================================
     v575 / v576 · 序列帧「已选帧数 / 播放帧率」两个控件（新模块 —— 独立文件，别往 26 号表里堆）
     ----------------------------------------------------------------------------
     用户令（2026-10-12 深夜，两段）：
       · 卡片内框删掉后「间距没跟着调」⇒ 卡片自己的内边距退役（.sheet-body 已经给了一圈）；
       · 帧数档位换成 全选 / 6 / 12 / 24，档位文字读「已选 x 帧」；
       · 播放帧率要**和生视频的那个一样 —— 按钮和点开之后的**：键上显示当前值，
         点开弹层里是滑杆 + 隐藏式数字框（无边框 / 小字 / 小高，点一下就能直接输入）。
     控件 DOM：面板那套写在 index.html（静态，与 #vgenDur255 / #durPop255 同一种写法），
     编辑窗那套由 106-seqctl575.js 现建；本表只管外观。
     配色一律走主题变量（--line / --text / --text-2 / --text-3 / --accent / --accent-soft /
     --sans），不发明裸色。
     ⚠️ 别在这份头注里照抄被闸门钉住的那两条属性串（26 号表里已有同款教训：
        注释里引用被钉子串，计数钉一样会撞）。
     ============================================================================ */

  /* ---------- ① 卡片自己的内边距退役：面板只剩最外面那一圈框，间距才对齐 ---------- */
  #cardFrames{padding:0}
  /* 帧图墙原带的 8 / 2px 外边距是给旧的内边距垫的，现在一起去掉（四周交给 .sheet-body 的 10 / 12px） */
  #cardFrames .frames-grid{margin:0}
  /* 功能一排与帧图墙之间留一档 */
  #cardFrames .seqbar571{margin-top:10px}

  /* ---------- ② 播放帧率 = 胶囊键 + 弹层（与生视频的「时长」键同款） ----------
     键本身复用站点那颗芯片样式（.sel.vgen-chip230，与 #vgenDur255 逐项同款：无框无底、悬停主题色），
     这里只把它的默认外边距归零 —— .sel 自带 margin-left:auto，那是给「一行一个参数」版式用的 */
  #cardFrames .seqfps-chip576{margin-left:0}
  /* 弹层比站点那颗时长弹层多一条：**层级要压过「进入编辑」窗**（.seqedit-mask571 是 120） */
  .seqfps-pop576{z-index:130}
  /* 弹层里的数字框：隐藏式 —— 平时就是一段数字，点一下直接输入（无边框 / 小字 / 小高） */
  .seqfps-num575{
    width:26px;min-width:0;height:16px;padding:0;margin:0;
    border:none;background:transparent;box-shadow:none;
    font:600 11px/16px var(--sans);color:var(--text);text-align:right;
    font-variant-numeric:tabular-nums;border-radius:4px;
  }
  .seqfps-num575:hover{color:var(--accent)}
  .seqfps-num575:focus{outline:none;background:var(--accent-soft);color:var(--accent)}
  /* 数字框自带的上下箭头收起来（高度才压得住） */
  .seqfps-num575::-webkit-outer-spin-button,
  .seqfps-num575::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}
  .seqfps-num575[type=number]{-moz-appearance:textfield;appearance:textfield}

  /* 退成取值载体的下拉 / 关着的弹层：留在 DOM 里给老链读写，界面上一律不露面
     （真 DOM 里 [hidden] 会被作者样式的 display 压掉 ⇒ 这里显式钉一条） */
  #cardFrames .seqchip571 #playFpsSel[hidden],
  #cardFrames .seqbar571 #playFpsSel[hidden],
  #cardFrames .seqfps-pop576[hidden],
  .seqedit-func573 #seqEditFps573[hidden],
  .seqedit-func573 .seqfps-pop576[hidden]{display:none}

  /* ---------- ③ v591：编辑窗那套播放帧率弹层 —— 排版钉死（对齐主面板静态版：
     一行放下不折行；数字框回到隐藏式（无边框 / 透明底 / 26px）；宽度与主面板同款 340px。
     编辑窗那套是 JS 现建的 DOM，真机上吃过多层上下文样式 ⇒ 这里按类名整组钉住，
     不管中间被谁压过都以这份为准） ---------- */
  .seqfps-pop576{width:340px;min-width:0;max-width:calc(100vw - 24px)}
  .seqfps-pop576 .dur-row255{flex-wrap:nowrap}
  .seqfps-pop576 .dur-row255 .rng{flex:0 0 auto;width:128px}
  .seqfps-pop576 .dur-val255{flex:0 0 auto;white-space:nowrap}
  .seqfps-pop576 .dur-val255 .seqfps-num575{
    width:26px;min-width:0;height:16px;padding:0;margin:0;
    border:none;background:transparent;box-shadow:none;
  }
  .seqfps-pop576 .dur-val255 em{white-space:nowrap}

/* ══════ 29-seqlayout580.css ══════ */
  /* ============================================================================
     v580 头注（新模块 = 新文件）
     ----------------------------------------------------------------------------
     用户令（2026-10-12，附截图，两条）：
       ①「红色一栏删除」—— 上区「序列帧编辑画布」工具条退役（DOM 由 107 搬迁，本表只管外观）；
       ②「功能为一排，图片在下面」—— 下区改「上功能一行 + 下帧图墙占满剩余高」。
     本表全是**尾部覆盖**：同权重选择器、后加载者赢 ⇒ 必须排在 27 号（27-seqedit573.css）之后。
     配色一律走主题变量（--line / --text-2 / --sans 等），不发明裸色。
     ============================================================================ */

  /* ---------- 下区转纵排：功能一行在上，帧图墙在下占满 ---------- */
  .seqedit-foot573{flex-direction:column}
  .seqedit-func573{width:auto;flex:0 0 auto;flex-direction:row;align-items:center;gap:8px;
    padding:8px 12px;border-right:none;border-bottom:1px solid var(--line);overflow:visible}
  .seqedit-ftitle573{flex:0 0 auto}
  .seqedit-row573{flex:0 0 auto}
  /* 27 号表原文是 .sel{flex:1}（竖列里撑满）—— 行布局里改成固定宽，别把读数挤没 */
  .seqedit-row573 .sel{flex:0 0 auto;width:110px}
  .seqedit-btns573{flex:0 0 auto;flex-wrap:nowrap}
  .seqedit-note573{display:none}          /* 空占位（v573 起没人往里写文本），行里不占位 */
  /* 读数：flex:1 靠右，超长省略；没内容时整条退场 */
  .seqedit-est573{flex:1;min-width:0;text-align:right;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .seqedit-est573:empty{display:none}
  /* 帧图墙：纵排里 flex:1 的主轴是纵向 ⇒ 占满剩余高；min-height:0 允许收缩滚动 */
  .seqedit-grid573{min-height:0}

  /* ---------- 「调色 / 像素」弹层（与 v576 帧率弹层同壳：spec-pop249/255） ---------- */
  /* z-index 130：压过「进入编辑」窗（.seqedit-mask571 = 120），与 106 的帧率弹层同档 */
  .seqlay-pop580{z-index:130;width:560px;max-width:calc(100vw - 24px);
    display:flex;flex-direction:column;gap:10px;padding:12px}
  /* 106 踩过的同一条坑：真 DOM 里 [hidden] 会被作者样式的 display 压掉 ⇒ 自带一条 */
  .seqlay-pop580[hidden]{display:none}
  .seqlay-pop580 .seqedit-grp573{gap:6px}
  .seqlay-pop580 .seqedit-rngs573{grid-template-columns:1fr 1fr}
  @media (max-width:640px){ .seqlay-pop580 .seqedit-rngs573{grid-template-columns:1fr} }

/* ══════ 30-seqedit582.css ══════ */
  /* ============================================================================
     v582 · 序列帧编辑窗 v582 三条样式（新表 —— 别往 27 / 29 里追加）
     ----------------------------------------------------------------------------
     ③ 蓝色读数退役：.seqedit-est573（「画布 N 张 · 选中 #n @ (x, y) px · 双击移除」那条）
        display:none —— DOM 留着（test-canvas 钉的是「edNote 在 func 里的结构位置」，藏掉不碰结构；
        105 的回显链照写不误，只是不再显示）。
     ④ 功能区拖拽改高：func 是把手（.seqdrag-grip582）的定位基准；把手悬停给一条淡色提示。
     ============================================================================ */
  .seqedit-est573{display:none}
  .seqedit-func573{position:relative}
  .seqdrag-grip582{position:absolute;top:-5px;left:0;right:0;height:9px;cursor:ns-resize;z-index:6}
  .seqdrag-grip582:hover{background:var(--accent-soft)}

/* ══════ 31-seqstyle586.css ══════ */
  /* ============================================================================
     31 号样式表 · v586 序列帧编辑窗大改版（seqstyle586）
     ----------------------------------------------------------------------------
     全部是**尾部覆盖**：同权重选择器、本表后加载 ⇒ 压过 27 / 29 号表的同名规则。
     配色一律走主题变量（--accent / --accent-soft / --line / --sunken / --panel /
     --text / --text-2），不发明裸色。
     ============================================================================ */

  /* ---- ② 窗整体变小（原 inset:12px = 几乎占满）+ 居中 ---- */
  .seqedit-win571{inset:auto;left:50%;top:50%;transform:translate(-50%,-50%);
    width:min(92vw,960px);height:min(88vh,660px)}

  /* ---- ④ 三板块：body 从纵排改横排（左参数栏 | 右侧上下） ---- */
  .seqedit-body571{flex-direction:row}
  .seqedit-right586{flex:1;min-width:0;min-height:0;display:flex;flex-direction:column}
  .seqedit-right586 .seqedit-stage573{flex:1;min-height:0}
  .seqedit-right586 .seqedit-foot573{flex:0 0 30%;max-height:46%}

  /* ---- ① 左栏（像素处理参数 + 调色） ---- */
  .seqedit-left586{flex:0 0 258px;min-width:0;overflow:auto;border-right:1px solid var(--line);
    background:var(--sunken);padding:10px;display:flex;flex-direction:column;gap:10px}
  .seqedit-left586 .seqedit-grp573{display:flex;flex-direction:column;gap:6px}
  .seqedit-left586 .seqedit-gtitle573{font:600 11.5px/1 var(--sans);color:var(--text-2)}
  .seqedit-left586 .seqedit-rngs573{grid-template-columns:1fr}
  .seqedit-chks586{display:grid;grid-template-columns:1fr 1fr;gap:6px 10px}
  .seqedit-chk586{display:flex;align-items:center;gap:6px;margin:0;cursor:pointer;
    font:400 11.5px/1 var(--sans);color:var(--text-2)}
  .seqedit-chk586 input{accent-color:var(--accent);margin:0}
  .seqedit-chk586 input[type="checkbox"]{width:26px;height:15px;appearance:auto}

  /* 背景六档 */
  .seqedit-bgrow586{display:flex;align-items:center;gap:5px;flex-wrap:wrap}
  .seqedit-bgrow586 em,.seqedit-whrow586 em{font-style:normal;flex:0 0 auto;
    font:400 11.5px/1 var(--sans);color:var(--text-2)}
  .seqedit-bgbtn586{border:1px solid var(--line);background:transparent;color:var(--text-2);
    font:400 11px/1 var(--sans);padding:4px 9px;border-radius:999px;cursor:pointer}
  .seqedit-bgbtn586:hover{border-color:var(--accent);color:var(--accent)}
  .seqedit-bgbtn586.on{border-color:var(--accent);color:var(--accent);background:var(--accent-soft)}

  /* 宽高比例 */
  .seqedit-whrow586{display:flex;align-items:center;gap:5px;flex-wrap:wrap}
  .seqedit-whrow586 span{font:400 11.5px/1 var(--sans);color:var(--text-2)}
  .seqedit-wh586{width:56px;flex:0 0 auto}
  .seqedit-lock586{border:1px solid var(--line);background:transparent;color:var(--text-2);
    font:600 10.5px/1 var(--sans);padding:4px 7px;border-radius:6px;cursor:pointer}
  .seqedit-lock586.on{border-color:var(--accent);color:var(--accent);background:var(--accent-soft)}

  /* 尺寸滑条 + 原尺寸 */
  .seqedit-szrow586{display:flex;align-items:center;gap:8px}
  .seqedit-szrow586 input[type="range"]{flex:1;min-width:0}
  .seqedit-szval586{flex:0 0 auto;font:600 12px/1 var(--sans);color:var(--text)}

  /* ---- ⑤ 画布：素材尺寸 1:1 显示（比例恒等；超大素材等比缩到容器内） ---- */
  .seqedit-cvbox586{display:flex;align-items:center;justify-content:center;
    background:var(--sunken)}
  .seqedit-cv586{display:block;width:auto;height:auto;max-width:calc(100% - 16px);
    max-height:calc(100% - 16px);border:1px solid var(--line);background:var(--sunken)}

  /* ---- ⑦ 功能行：控制键 + 打包下载压行尾 ---- */
  .seqedit-func573 .seqedit-btns573{margin-left:auto}
  .seqedit-ctl586{flex:0 0 auto}
  .seqedit-ctl586.on{border-color:var(--accent);color:var(--accent);background:var(--accent-soft)}
  .seqstl-chip586{flex:0 0 auto}

  /* 本模块的胶囊弹层（层级压过编辑窗 120，与 106 / 107 同档） */
  .seqstl-pop586{z-index:130;width:300px;max-width:calc(100vw - 24px)}
  .seqstl-pop586[hidden]{display:none}
  .seqstl-pop586 .sel{width:100%}

  /* v580 的「调色 / 像素」胶囊退役（JS 里已摘 DOM —— 这里兜底防回归） */
  .seqlay-chip580{display:none!important}

/* ══════ 32-genpanel587.css ══════ */
/* ============================================================================
   32 号样式表 · v587 · 生成面板（gen / vgen 卡）状态小字的基样式
   ----------------------------------------------------------------------------
   为什么有它：
     `#genState189` / `#vgenState189` 这两颗 span 身上写着 class="dock-tip"，
     但 `.dock-tip` 的基样式只写在 07-layers.css 的 `.dock-head .dock-tip` 里 ——
     它们长在 `.vgen-bar230` 里，从来没吃到那份「小字 + 弱色」，
     于是状态串一直按面板的正文色号显示（比按钮还抢眼）。

     本版状态文案变长（网络类失败要点名代理域名 + 给下一步）⇒ 一并给一条
     「一行截断」的边；完整内容挂在元素的 title 上（见 112-genpanel587.js 的 genpShow587）。

   口径：配色只用全站主题变量（--text-3），不发明一次性颜色。
   ============================================================================ */
#genState189, #vgenState189{
  font-size:10.5px;color:var(--text-3);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}

/* ══════ 33-seqstyle588.css ══════ */
  /* ============================================================================
     33 号样式表 · v588 序列帧编辑窗第二轮（seqstyle588）
     ----------------------------------------------------------------------------
     全部是**尾部覆盖**：同权重选择器、本表后加载 ⇒ 压过 27 / 29 / 31 / 13 号表的同名规则。
     配色一律走主题变量（--accent / --accent-soft / --line / --sunken / --text / --text-2），
     不发明裸色（开关旋钮 / 滑块白底 = 全站 .rng 规范同款，不是新色）。
     ============================================================================ */

  /* ---- ① 两枚开关（自动抠图 / 连续）：checkbox 换装胶囊开关（旋钮白底 = .rng 滑块同款） ---- */
  .seqedit-chk586 input[type="checkbox"].seqedit-sw588{
    -webkit-appearance:none;appearance:none;flex:0 0 auto;margin:0;
    width:32px;height:18px;border-radius:999px;outline:none;cursor:pointer;
    background-color:var(--line-strong);
    background-image:radial-gradient(circle at 9px 9px,#fff 6px,transparent 7px);
    background-repeat:no-repeat;background-position:0 0;transition:background-color .15s;
  }
  .seqedit-chk586 input[type="checkbox"].seqedit-sw588:checked{
    background-color:var(--accent);background-position:14px 0;
  }

  /* ---- ② 吸管键 + 吸管模式下的画布光标 ---- */
  .seqedit-eyebtn588{flex:0 0 auto;align-self:flex-start}
  .seqedit-eyebtn588.on{border-color:var(--accent);color:var(--accent);background:var(--accent-soft)}
  .seqedit-eye588{cursor:crosshair}

  /* ---- ④ 滑条统一：滑条本体由 JS 挂 .rng / .rng-num / .rng-bal-* 类（03 号表的规范样式
         自动生效）；这里只把编辑窗里的数字框对齐 .rng-num 的口径（27 号表把它压窄了） ---- */
  .seqedit-rng573 .rng-num{width:56px;text-align:center;font-weight:600;font-size:12px}
  /* 实体节点子链的滑条（全站唯一没换装的原生 accent-color 滑条）—— 一并统一到 .rng 口径 */
  .entcp-rng394{
    -webkit-appearance:none;appearance:none;height:16px;background:transparent;
    cursor:pointer;outline:none;accent-color:var(--accent);
  }
  .entcp-rng394::-webkit-slider-runnable-track{height:4px;border-radius:999px;background:var(--line-strong)}
  .entcp-rng394::-webkit-slider-thumb{
    -webkit-appearance:none;appearance:none;width:14px;height:14px;margin-top:-5px;
    border-radius:50%;background:#fff;border:2px solid var(--accent);
    box-shadow:0 1px 3px rgba(15,23,42,.22);transition:transform .12s;
  }
  .entcp-rng394:hover::-webkit-slider-thumb{transform:scale(1.08)}
  .entcp-rng394:focus-visible::-webkit-slider-thumb{box-shadow:0 0 0 4px var(--accent-soft)}
  .entcp-rng394::-moz-range-track{height:4px;border-radius:999px;background:var(--line-strong)}
  .entcp-rng394::-moz-range-thumb{width:12px;height:12px;border:2px solid var(--accent);border-radius:50%;background:#fff}

  /* ---- ⑤ 排版：背景六档收一行（绿不再掉行）+ 宽高一排（不再折两行） ---- */
  .seqedit-bgrow586{gap:4px;flex-wrap:nowrap}
  .seqedit-bgbtn586{padding:3px 7px;font-size:10.5px}
  .seqedit-whrow586{gap:4px;flex-wrap:nowrap}
  .seqedit-wh586{width:44px}

  /* ---- ⑤ 调色组与上方区域间距加大 ---- */
  .seqedit-left586 .seqedit-grp573 + .seqedit-grp573{margin-top:14px}

  /* ---- ⑥ 画布（红框）高度占满：高度顶满上区、宽度按素材比例跟（比例恒等不破）；
         pixelated = 缓冲被放大时保持像素风硬边（素材比画布大时照旧等比缩小） ---- */
  .seqedit-cv586{height:calc(100% - 16px);width:auto;image-rendering:pixelated}

/* ══════ 34-numspec593.css ══════ */
/* ============================================================================
   34-numspec593.css · v593
   ----------------------------------------------------------------------------
   为什么有它：03 号表的全局兜底 `input[type=number]{width:100%;padding:9px 10px}`
   是给「表单整宽框」用的，特异性 0-1-1 会压过组件行内数字框的 0-1-0 宽度规则
   ⇒ v586 宽高行实测：框撑满整行还溢出（用户截图，v593 收口）。
   ★ 规矩（v593 起入规范，闸门 _numspec593.js 机器把关）：
     行内 number 输入框必须挂「已批准类」，且宽度必须以「≥0-2-0 作用域规则」落表。
   已批准类与各自的救援链：
     .rng-num          ← 03:146 .field .rng-num ／ 33:28 .seqedit-rng573 .rng-num
     .seqedit-num573   ← 27:67 .seqedit-rng573 .seqedit-num573
     .seqfps-num575    ← 28:60 .seqfps-pop576 .dur-val255 .seqfps-num575
     .seqedit-wh586    ← 本表（此前只有裸 .seqedit-wh586{width:44px}，被全局压过）
   规格数值（规范文档 6.2「行内数字框」节同源）：
     带框式 = 宽 44~56px ／ 内距 2×4 ／ 12px·600 ／ 居中 ／ tabular-nums ／ --line 描边 + --card 底
     隐藏式 = 宽 26px ／ 无边框透明底 ／ 11px·600
   ============================================================================ */

/* 宽高行两个数字框：作用域提到 0-2-0 压过全局 0-1-1，观感对齐 .rng-num（带框式） */
.seqedit-whrow586 .seqedit-wh586{
  width:44px;min-width:0;flex:0 0 auto;padding:2px 4px;
  font:600 12px/1 var(--sans);color:var(--text);text-align:center;
  border:1px solid var(--line);border-radius:6px;background:var(--card);
  font-variant-numeric:tabular-nums;
}
.seqedit-whrow586 .seqedit-wh586:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-soft)}

/* ══════ 35-seqleft595.css ══════ */
/* ============================================================================
   35 号样式表 · v595 序列帧编辑窗左栏排版整改（seqleft595）
   ----------------------------------------------------------------------------
   用户令（2026-10-13 傍晚，附 4 张截图）：
     · 「红色区域变成一行」→ 自动抠图 / 连续 / 吸管 三件并排一行（原来吸管独占一行）；
     · 「行间距拿出来」  → 行距 6→10、组距 10→14、内距 10→12（原来挤成一堆）；
     · 「文字左对齐，功能右对齐」→ 每行标签贴左、控件整簇贴右（标签 margin-right:auto 吃余量）；
     · 「该适当加宽的加宽」→ 左栏 258 → 280px（尺寸行 + 背景六档才排得开）；
     · 「宽高锁定的锁改为图标 不要使用文字」→ 锁 = 主题色描边图标（.on 上锁 / 未 .on 开锁）；
     · 「识别容差 → 容差」「宽高比例 → 尺寸」→ 文案在 119-seqlayout595.js 里改（本表只管排版）。
   全部是**尾部覆盖**：31 / 33 号表的原文一字不动，本表后加载压过它们。
   配色一律走主题变量（--accent / --line / --sans / --text-2 等），不发明裸色。
   ============================================================================ */

/* ---- ① 左栏加宽 + 内距 / 行距 / 组距拉开 ---- */
.seqedit-left586{flex:0 0 280px;padding:12px;gap:14px}
.seqedit-left586 .seqedit-grp573{gap:10px}

/* ---- ② 开关行：两枚开关并排靠左 + 吸管键靠右（红区收成一行） ---- */
.seqedit-chks586{display:flex;align-items:center;justify-content:flex-start;gap:12px}
.seqedit-chks586 .seqedit-chk586{flex:0 0 auto}
.seqedit-chks586 .seqedit-eyebtn588{
  margin-left:auto;align-self:center;flex:0 0 auto;padding:4px 9px;
  font:400 11px/1 var(--sans);
}

/* ---- ③ 每行「文字左对齐、功能右对齐」：标签吃掉余量，控件整簇靠右 ---- */
.seqedit-whrow586 em,.seqedit-bgrow586 em{margin-right:auto}

/* ---- ④ 滑块行（容差 / 调色六条）：行高统一、控件贴右 ---- */
.seqedit-left586 .seqedit-rng573{align-items:center;gap:8px}

/* ---- ⑤ 宽高锁定：文字「锁」→ 主题色图标（currentColor 跟随 .on 的 accent） ---- */
.seqedit-lock586{
  width:26px;height:22px;display:inline-flex;align-items:center;justify-content:center;padding:0;
}
.ico-lock595{
  position:relative;display:block;width:11px;height:8px;margin-top:4px;
  border:1.4px solid currentColor;border-radius:2px;
}
.ico-lock595::before{
  content:'';position:absolute;top:-5px;left:1px;width:7px;height:5px;
  border:1.4px solid currentColor;border-bottom:0;border-radius:4px 4px 0 0;
}
/* 未 .on = 开锁（锁梁抬起、靠右收窄） */
.seqedit-lock586:not(.on) .ico-lock595::before{
  left:auto;right:-1px;width:5px;height:4px;border-radius:4px 4px 0 0;
}

/* ══════ 36-seqview595.css ══════ */
/* ============================================================================
   36 号样式表 · v595 序列帧编辑画布：滚轮缩放「这个框」（seqview595）
   ----------------------------------------------------------------------------
   用户令（2026-10-13 傍晚，附截图）：「现在鼠标滚轮的缩放是缩放的这帧图片，
   我要求缩放这个框；帧图片的缩放（图片需要有一个边框可选）需要拖动图片边缘进行缩放
   （最小单位按像素）」。
   ⇒ 滚轮 = 视口缩放（.seqedit-cvzoom595 时画布按 z 倍显形，超出就滚动查看）；
      图片边框 = 120 号在画布上画的那圈主题色描边（抓边缘改尺寸的把手提示）；
      帧图尺寸 = 拖图片边缘，按整数像素改 pose.w / pose.h。
   ----------------------------------------------------------------------------
   全部是**尾部覆盖**：27 / 31 / 33 号表的原文一字不动。
   ============================================================================ */

/* 视口：放大后可滚动查看（配 120 号的 margin:auto —— 内容居中、超出时两端都能滚到） */
.seqedit-cvbox586{overflow:auto}
.seqedit-cv586{margin:auto}

/* 放大态：撤掉 31 号表的 max 限制（33 号表的 height 填充让位给行内尺寸） */
.seqedit-cv586.seqedit-cvzoom595{max-width:none;max-height:none}

/* 抓边缘时的光标由 120 号按命中位置写行内 cursor；吸管开着时仍是十字（33 号表同款） */
.seqedit-cv586.seqedit-eye588{cursor:crosshair!important}

/* ══════ 37-seqsize597.css ══════ */
/* ============================================================================
   37 号样式表 · v597 —— 序列帧编辑窗：画布右上角尺寸标签
   （配套 123-seqsize597.js；配色只用主题 token，不发明裸色）
   ============================================================================ */

  /* 标签挂在 cvbox 右上角；cvbox 要做定位基准（36 号表的 overflow:auto 原样保留） */
  .seqedit-cvbox586{position:relative}
  .seqedit-szlbl597{position:absolute;top:8px;right:12px;z-index:2;pointer-events:none;
    font:600 11px/1 var(--sans);color:var(--accent);background:var(--card);
    border:1px solid var(--line);border-radius:6px;padding:3px 7px;white-space:nowrap}
  .seqedit-szlbl597[hidden]{display:none}

/* ══════ 38-aifsplits599.css ══════ */
/* ============================================================================
   38 号样式表 · v599 —— 开发预览两窗：中缝收窄一点 + 中缝手柄加高加宽
   （用户令 2026-10-13 晚，附截图：「开发预览中间这个拖动条，高度增加，宽度增加一点点，
     2 个窗口间距减少一点点」）
   ----------------------------------------------------------------------------
   ① 两窗间距 12px → 8px：默认「贴在一起」布局的宽度算式是
      `calc((100vw - 40px) / 2)`（40 = 左右边距 14×2 + 中缝 12，见 16 号表 v409 段），
      那两条被 verify-page / test-canvas **逐字钉着** ⇒ 这里后置覆盖成 36px
      （36 = 28 边距 + 中缝 8）。74 号的 `AIF_GAP407 = 12` 是「不可重叠的最小间距 +
      贴在一起的判据」，8 ≤ 12.5 ⇒ 手柄显隐 / 颜色层 / 画布守卫全部照常，JS 一字不动。
   ② 手柄竖条 46×2 → 84×3：更好认、更好抓；hover / 拖动中的强调色沿用 10 号表
      `.ai-split285:hover::before` 那条原规则（这里只覆盖尺寸，不碰配色）。
      命中区（98 号的 SPLIT_HW563 = 5 ⇒ 10px）不动 —— 落在 8px 中缝里两边各让 1px，正合适。
   ============================================================================ */

  /* ① 中缝收窄（后置覆盖 16 号表 v409 段那两条） */
  .ai285-float397>.ai-left285{width:calc((100vw - 36px) / 2)}
  .ai285-float397>.ai-right285{width:calc((100vw - 36px) / 2)}

  /* ② 手柄竖条加高加宽（后置覆盖 10 号表的 46×2） */
  .ai-split285::before{width:3px;height:84px}

/* ══════ 39-nologin605.css ══════ */
  /* ================= 39-nologin605：临时关闭「必须登录」时的登录入口隐藏 =================
     用户口径（2026-10-14）：「直接改为无需登录……（暂时关闭，不用删除代码，后面可以需要了直接恢复）」。
     配套模块：js/src/132-nologin605.js —— 它负责给 <html> 挂 / 摘 .px-nologin。

     撤销两种方式（都不用动本文件）：
       · 运行时：控制台 __PXNOLOGIN605(false)（写 localStorage['px.nologin']='0' 并立刻生效）
       · 构建期：js/src/132-nologin605.js 里 PX_NO_LOGIN605 改成 false 后重新构建

     ⚠️ 只隐藏这两颗按钮本身，不动它们所在的容器 —— 顶栏账号区 / 主页账号区里还住着
        积分胶囊与头像菜单，以后恢复登录时它们要照常出现。
     ⚠️ 两颗按钮都是 innerHTML 现写进去的（段 2 cloud.js 的 renderAccount、
        61-projects.js 的 renderHomeAcct204），重渲染会重建元素 ⇒ 只能靠类名，
        不能靠「删掉那个节点」。
     ⚠️ 用 !important：.btn 自带 display 规则，这里不跟它比选择器权重。 */
  html.px-nologin #loginBtn,
  html.px-nologin #homeLogin204 {
    display: none !important;
  }

/* ══════ 40-mapnode608.css ══════ */
/* ============================================================================
   v608 · 地图绘制功能区 → 地图节点下方面板（工单 W608-01）
   ----------------------------------------------------------------------------
   配合 135-mapnode608.js：运行时把 #mapBar 整块搬进本面板容器 #mapSheet608。
   本文件只做**后置覆盖**（06-map.css / 10-main.css / 17-sub-canvas401.css 原文一字未动），
   由星桥在 pixel-resizer/index.html 挂 <link>（位置 = 39-nologin605.css 之后）。

   口径 ②：「宽度统一」= 统一「尺」不是统一像素值 —— 面板本体复用 .sheet 那把尺
   （边框 / 圆角 / 阴影 / 暗色底 / body.sub401-on .sheet 限高），宽度按内容自适应
   （**不硬压 336**，10+ 颗按钮装不下就在工具排里自动换行）。
   ============================================================================ */

/* ---------- 面板容器：与 .sheet 同族，宽度改「按内容自适应」 ---------- */
#mapSheet608{
  width:max-content;                     /* 内容多宽就多宽（不套 336 / 900 的死值） */
  max-width:calc(100vw - 28px);          /* 与 .sheet 的 min(900px,100vw-28px) 同一个上限口径 */
}

/* ---------- 工具排 / 素材栏：装不下自动换行（口径 ②） ---------- */
#mapSheet608 .map-bar-top{flex-wrap:wrap;row-gap:10px}
#mapSheet608 .map-bar-left{flex-wrap:wrap;row-gap:10px}

/* ---------- 里层 #mapBar：不再是页级固定底部 dock，改回普通文档流 ----------
   06-map.css:25 那条页级 dock 的定位（fixed + 水平居中 transform + z-index）进了面板要整条让位
   —— 面板本体已经是那张壳：底色 / 阴影 / 圆角都在这儿。
   ⚠️ 只在本面板**里面**覆盖（选择器 = 两个 id），页级那条规则原文、以及
      10-main.css 的暗色镜像 / 17-sub-canvas401.css 的 sub401 隐藏规则一处都不改。 */
#mapSheet608 #mapBar{
  position:static;left:auto;right:auto;bottom:auto;transform:none;z-index:auto;
  max-width:none;width:auto;padding:0;
  background:transparent;backdrop-filter:none;-webkit-backdrop-filter:none;
  box-shadow:none;border-radius:0;
}

/* ---------- 子画布里整块隐藏（迁移自 17-sub-canvas401.css:22 那条隐藏规则） ----------
   那条仍在、且对本面板里层的 #mapBar 照旧生效（面板藏了它也就露不出来）；
   这里对**新面板本体**补一条同款 —— 于是「子画布打开 = 地图功能区整体让位」，不留死规则。 */
body.sub401-on #mapSheet608{display:none!important}

/* ══════ 41-subcanvas610.css ══════ */
  /* ================= v610：角色子画布容器 → 照 AI 对话框那套（工单 W608-03） =================
     用户口径（原话）：「把角色的子画布改成 AI 对话框那种 —— 高度用对话框那套、默认宽度半个视口、
     可以从左边框拖拽调宽」。

     样板（styles/16-ai-float400.css）与本文件的三点对应：
       ① 高度：`.ai285-float397>.ai-left285/.ai-right285{top:62px;bottom:68px}`（= 视口高 − 130px）
          ⇒ 这里 `.sub401{top:62px;bottom:68px}`（纯 CSS，无 JS 参与）。
       ② 默认宽：`.ai285-float397>.ai-left285/.ai-right285{width:calc((100vw - 40px) / 2)}`
          ⇒ 这里 `body.sub401-on{--sub401w:calc((100vw - 40px) / 2)}`。
       ③ 左框拖宽：手柄外观 + 拖拽交互（JS 在 js/src/136-subcanvas610.js，写**行内 style.width**）。

     ⚠️ 既有片段原文一字未动（four 套闸门钉着 17-sub-canvas401.css 里那几条字面量：
        `body.sub401-on{--sub401w:min(...)}` / `.sub401-frame{...aspect-ratio:16/9` /
        `.sub401-bar{...height:32px` / `body.sub401-on #canvasWrap{clip-path:inset(`）。
        本文件只用**同选择器后置规则覆盖**，不改它们；本文件的 `<link>` 必须挂在 17 之后。
     ⚠️ 没动子画布**逻辑**：窗口矩形( #sub401Frame )是 75-sub-canvas401.js 每帧实时量的
        （sub401FrameRect）⇒ 容器一改尺寸，fr421 面板夹取 / 取景 / 站窗自动跟着走。 */

  /* ---------- ① 默认宽 = 半个视口（同选择器后置覆盖 17 的 min(...) 口径） ---------- */
  body.sub401-on{--sub401w:calc((100vw - 40px) / 2)}

  /* ---------- ② 容器 = 右锚窗口 + 对话框那套高度（top:62 / bottom:68） ----------
     17 的 `.sub401{position:fixed;inset:0;...}` 原文未动，这里把四边收窄成右侧窗口：
     left:auto + right:14px ⇒ 右锚；top/bottom 钉成对话框那套（= 视口高 − 130px）。 */
  .sub401{
    top:62px;bottom:68px;right:14px;left:auto;
    width:var(--sub401w);height:auto;
  }

  /* ---------- ③ 标题栏在上、画布窗口撑满余下高度 ----------
     `.sub401` 是 column-reverse（17 原文），DOM 里 frame 在前 ⇒ 视觉上标题栏在上、frame 在下；
     frame 取剩余高度（= 视口高 − 130px − 标题栏 32px − 间隙 8px），不再是 16:9 定比。 */
  .sub401-bar{width:100%;flex:0 0 auto}
  .sub401-frame{width:100%;flex:1 1 auto;min-height:0;height:auto;aspect-ratio:auto}

  /* ---------- ④ 窗外整层裁剪（同 v404「窗外不露主画布、也不可点」的口径，矩形跟着新容器走） ----------
     inset(top right bottom left)：top = 62(容器顶) + 32(标题栏) + 8(间隙) = 102px；
     right = 14px；bottom = 68px；left = 14px + --sub401w（窗口宽由 CSS 变量驱动 ⇒ 拖宽时同拍跟随）。 */
  body.sub401-on #canvasWrap{
    clip-path:inset(102px 14px 68px calc(14px + var(--sub401w)) round 16px);
  }

  /* ---------- ⑤ 子画布里的参数面板：限高跟着新窗口高（17 那条按 16:9 算的已不适用） ----------
     窗口高 = 100vh − 130px；再让开标题栏 32 + 间隙 8 + 一点内边距 ⇒ 面板最多 100vh − 190px。 */
  body.sub401-on .sheet{max-height:calc(100vh - 190px)}

  /* ---------- ⑥ 左边框拖宽手柄（图样 = #aiGripR400；作用对象是子画布窗口 #sub401） ---------- */
  .subgrip610{
    position:absolute;left:0;top:0;bottom:0;width:6px;z-index:3;
    cursor:col-resize;touch-action:none;background:transparent;
    pointer-events:auto;transition:background .15s;
  }
  .subgrip610:hover,.subgrip610.on610{background:var(--accent-soft)}
  body.sub610-resize{cursor:col-resize}

/* ══════ 42-subfloat613.css ══════ */
/* ================= v613：角色子画布 —— 浮在画布上的独立浮层（工单 W613-01） =================
   用户口径（原话）：
     ①「子画布打开时，就在画布的基础上打开，和 AI 对话框一样，可以正常看到和操作无限画布的节点」
     ②（截图）窗左缘外漏一条 ~12px 白边
     ③ 顶部提示条去掉（星桥已删 index.html 的 .sub401-hint —— 与本表无关）

   两条口径 + 一块画布：
     ① 撤掉「窗外整层裁剪」（后置覆盖 41-subcanvas610.css:39 的同选择器规则；17-sub-canvas401.css:49 原文一字不动）
        ⇒ 窗外恢复成**主画布本色**：看得见、点得到、框选得了、滚轮缩放平移照常 ⇒ 12px 白边随之消失。
     ② 子画布窗口里那块**自己的画布** #sub401Stage613（JS 由 140-subfloat613.js 惰性建、挂在 #sub401 下）：
        它**视口大小、原点钉在视口原点**，再用 clip-path 精确裁到窗口内框 —— 于是：
          · 与主画布同一套视口坐标 ⇒ 75 的取景 / 18 的参数面板 fr421 夹取 / 79 的分步窗定位**全部不用改**；
          · 窗口区由它盖住（不透明底色遮掉底下的主画布），窗外则完全不碰主画布。

   ⚠️ 为什么不做成「窗口大小」的画布：那样 view 得整体换算成窗口局部坐标，
      而参数面板 / 分步窗 / 圆形手柄这些 **DOM 浮层按视口坐标绝对定位** —— 会整体歪掉。
      做成「视口大小 + clip-path 裁窗口区」= 零坐标换算，既有几何一处不动。

   ⚠️ 本表必须挂在 41 之后（同选择器后置规则才能赢）。既有表原文一字未动。 */

/* ---------- ① 撤掉窗外整层裁剪（覆盖 41 那条同选择器规则） ---------- */
body.sub401-on #canvasWrap{clip-path:none}

/* ---------- ② 子画布窗口那块画布：视口大小、原点在视口原点、clip-path 裁到窗口内框 ----------
   定位（左/上）：相对 #sub401 的 padding box（= 窗口矩形，无 border/padding）。
     窗口左缘 = 100vw − 14 − --sub401w ⇒ left = −(窗口左缘) = --sub401w − 100vw + 14px；
     #sub401 顶部 = 62px ⇒ top = −62px。
   裁剪（inset 相对本画布的 border box = 视口）：上 = 62 + 32(标题栏) + 8(间隙) = 102px；
     右 = 14px；下 = 68px；左 = 100vw − 14 − --sub401w（= 窗口左缘）；圆角与 .sub401-frame 同 16px。 */
.sub401-stage613{
  position:absolute;
  left:calc(var(--sub401w) - 100vw + 14px);
  top:-62px;
  width:100vw;height:100vh;
  pointer-events:none;
  /* ★ v316 闸门：全站禁用 background 简写带 --canvas（会重置 background-image），必须用 background-color */
  background-color:var(--canvas);
  clip-path:inset(102px 14px 68px calc(100vw - 14px - var(--sub401w)) round 16px);
}

/* ══════ 43-subwin614.css ══════ */
/* ================= v614：角色子画布窗口改造（工单 W614-01，7 条 UI 需求） =================
   配套 JS = js/src/141-subwin614.js（后置覆盖，既有片段一字未动）。
   ★ 本表必须挂在 17 / 41 / 42 之后（同选择器后置规则才赢；层叠顺序 = index.html 里 <link> 的位置）。
   ★ 既有样式表一字未动：全部是「同选择器后置规则覆盖」。

   七条需求 → 本表的落点：
     B) 主画布周边 UI 恢复显示（除 .aifab397）—— 盖掉 17-sub-canvas401.css:15-23 那条 display:none!important
     C) .aifab397 保持隐藏，但改「渐变」（opacity + pointer-events + transition，不用 display:none）
     D) 子画布开关动画：开 = 从右往左滑入 / 关 = 从左往右滑出（keyframes + JS 收尾见 141）
     E) 标题文字去掉 + 叉移进框内右上角（.sub401-x 定位；空标题条随 .sub614-xin614 收起）
     F) 内部框上移 + 边框加强（边框 2px + --line-strong；裁剪区顶部跟着上移，见文末）
     G) 取景缩小在 JS 里（141 的 sub401Fit401 包层），本表不参与
   ⚠️ 全站禁「background 简写带 --canvas」（v316 会重置 background-image）—— 本表不写底色。

   ⚠️ 几何联动（F 的连带影响，必须一起改）：
     原布局 = 容器顶 62px → 标题条 32px → 间隙 8px → 框顶 102px（41 号表把裁剪区顶部也钉成 102px）。
     本表把空标题条（.sub614-xin614 时）收起 ⇒ 只剩 frame 一个流内子项 ⇒ 框顶 = 62px。
     42-subfloat613.css 里 #sub401Stage613 的 clip-path 顶部 102px = 旧框顶 ⇒ 文末同选择器后置改成 62px，
     否则「画这块」与「边框」会错开 40px。 */

/* ---------- B：主画布周边 UI 全部恢复显示（除右下角 AI 圆钮） ----------
   display 值按各元素**原始口径**给（去 01~16 号表查过，不是一律 block）：
     .topbar(02) = flex / .zoom-pill(04) = flex / .zoom-pop(05) = flex /
     .layers(07) = flex / .dock(07) = flex / #mapBar(06) = flex / .layers-tab(07) = grid / .mini-map(04) = block
   :not([hidden]) —— 元素自己 [hidden]（用户关掉的小地图 / 非地图页的图层 / 非地图模式的地图栏）仍按老规矩藏，
   别把它们点亮。 */
body.sub401-on .topbar:not([hidden]),
body.sub401-on .zoom-pill:not([hidden]),
body.sub401-on .zoom-pop:not([hidden]),
body.sub401-on .layers:not([hidden]),
body.sub401-on .dock:not(#sliceDock):not([hidden]),
body.sub401-on #mapBar:not([hidden]){display:flex!important}
body.sub401-on .mini-map:not([hidden]){display:block!important}
body.sub401-on .layers-tab:not([hidden]){display:grid!important}

/* ---------- C：右下角 AI 对话圆钮 —— 保持隐藏，但改成「渐变」 ----------
   transition 挂在**基础** .aifab397 上（开 / 关两个方向都要过渡；只写在 body.sub401-on 里的话，
   关窗时那条规则一起失效 ⇒ 渐现就没了）。开窗 → opacity:0 + pointer-events:none；关窗自动回基础态 ⇒ 渐现。
   ⚠️ 不用 display:none（display 不参与过渡，会直接闪没）。 */
.aifab397{transition:opacity .28s ease,transform .15s,background .15s,color .15s,box-shadow .15s}
body.sub401-on .aifab397{display:grid!important;opacity:0!important;pointer-events:none!important}

/* ---------- E：去掉标题文字 + 叉移到框内（右上角内侧） ----------
   标题：75-sub-canvas401.js 每次打开都会写 #sub401Title 的 textContent（删 index.html 文字没用）⇒ 这里 display 收口。
   叉：#sub401Close 由 141 的 JS 搬进 .sub401-frame（监听器随节点走）⇒ 这里只定位到框内右上角。 */
.sub401-title{display:none!important}
.sub401-frame{position:relative}
.sub401-x{position:absolute!important;top:8px!important;right:8px!important;margin-left:0!important;z-index:6!important}
/* 空标题条整条收起（JS 搬运成功后才加 .sub614-xin614 ⇒ JS 没跑时标题条照旧挂着叉，窗口关得掉） */
body.sub401-on .sub401.sub614-xin614 .sub401-bar{display:none!important}

/* ---------- D：开关动画（开 = 从右往左滑入；关 = 从左往右滑出） ----------
   窗口右锚（right:14px）⇒ 右移「100% + 24px」= 整个滑出右缘。 */
@keyframes sub614In614{from{transform:translateX(calc(100% + 24px))}to{transform:translateX(0)}}
@keyframes sub614Out614{from{transform:translateX(0)}to{transform:translateX(calc(100% + 24px))}}
.sub401.sub614-in614{animation:sub614In614 .30s cubic-bezier(.4,0,.2,1) both}
.sub401.sub614-out614{animation:sub614Out614 .30s cubic-bezier(.4,0,.2,1) both}

/* ---------- F：内部框上移 + 边框加强 ----------
   上移：标题条收起后 .sub401 只剩 frame 一个流内子项 ⇒ 框从容器顶 62px 起铺到底（原来 62+32+8 = 102 起）——
         整体往上移 40px（用户「往上移一点」）。
   边框：1px --line → 2px --line-strong（用户「边框有点太弱」）。 */
.sub401-frame{border-width:2px;border-color:var(--line-strong)}

/* F（连带）：画布的裁剪区顶部从旧框顶 102px 改到新框顶 62px（同选择器后置覆盖 42-subfloat613.css） */
.sub401-stage613{clip-path:inset(62px 14px 68px calc(100vw - 14px - var(--sub401w)) round 16px)}

/* ══════ 44-subzoom621.css ══════ */
/* ================= v621：子画布左下角的缩放读数 =================
   配套 JS = js/src/151-subzoom621.js（把 #sub401Title 搬进 .sub401-frame，每帧写百分比）。
   ★ 本表必须挂在 17 / 41 / 42 / 43 之后（同选择器后置规则才赢；层叠顺序 = index.html 里 <link> 的位置）。

   为什么是 .sub401-title 而不是新 id：
     v614 去掉了「角色 · 子画布」标题，写的是 `.sub401-title{display:none!important}`；
     那枚 span 仍在 index.html 里 ⇒ 本版复用它当缩放读数，**全站零新增 id**
     （四闸门有一条「引用但不存在的 id 保持为 0」的检查，新建成 id 会被盯上）。

   观感照主画布左下角那枚缩放胶囊（styles/04-canvas.css 的 .zoom-pill/.zoom-val 同款：
   白底 + 细边 + 圆角 + 投影 + tabular-nums 等宽数字），尺寸小一号 —— 它是「附在窗口角上的读数」，
   不是主画布那套带三颗方键的工具胶囊。
   ⚠️ 只读（pointer-events:none）：点它不改缩放，避免与主画布那颗「点一下调缩放」的口径混淆。 */
.sub401-title{
  display:block!important;
  position:absolute;left:12px;bottom:12px;z-index:5;
  padding:6px 10px;border-radius:10px;
  background:rgba(255,255,255,.97);
  backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);
  border:1px solid var(--line);
  box-shadow:var(--shadow);
  color:var(--text-2);font-size:12px;line-height:1;
  font-weight:600;font-variant-numeric:tabular-nums;
  pointer-events:none;user-select:none;
}

/* ══════ 45-seqwin629.css ══════ */
/* ================= v629：序列帧编辑窗 —— 加高 + 下区（帧图墙）占位加大 =================
   工单 W629-01。用户原话（2026-10-15 下午，附截图）：
     「在序列帧编辑窗口里面，把这个窗口高度增加」

   现状（styles/31-seqstyle586.css）：
     · 窗：width min(92vw,960px) / height **min(88vh,660px)**
     · 三板块：左参数栏 | 右侧（上=预览 stage / 下=foot）
     · 下区 foot：flex 0 0 30% / max-height 46%
   ⇒ 24 帧的帧图墙挤在 660px 窗高的三成里，一行放不下、要换行成 3 行。

   本表（**只改尺寸，不动任何布局结构**）：
     ① 窗高 660 → **min(94vh, 880px)**（几乎吃满视口但不顶穿）；
     ② 下区 foot 30% → **38%**、max-height 46% → **56%** —— 给「选中帧单行 + 左右滑动」
        那块留出高度（后面几步会往里放帧行与拖动排序）。
   ★ 只覆盖这两个数：宽、左栏、stage 全部不动 —— 出问题删本文件即完全回退。 */
.seqedit-win571{
  height:min(94vh,880px)!important;
}
.seqedit-right586 .seqedit-foot573{
  flex:0 0 38%!important;
  max-height:56%!important;
}

/* ══════ 46-seqgrid630.css ══════ */
/* ================= v630：编辑窗帧图墙 —— 只留选中帧、一行、左右滑动（像剪映时间轴） =================
   工单 W630-02（用户 2026-10-15 下午第二条）：「右边下面区域的只显示为选中帧，选中帧只有一行，
   数量太多的话左右滑动，类似于剪映的时间轴」。

   配合 JS：`157-seqgrid630.js` 包 `seqEditGrid573`，把 DOM **按 `p.pick` 的顺序重排**、
   并给未选中的格子打 `.off630`（本表隐藏它们）—— 于是「墙上有什么 / 什么顺序」完全跟着
   选中帧走，下一步做拖动排序时改的就是同一个 `p.pick` 数组。 */
.seqedit-grid573{
  display:flex!important;
  flex-wrap:nowrap!important;          /* ★ 一行，不换行 */
  overflow-x:auto!important;          /* ★ 放不下就左右滑 */
  overflow-y:hidden!important;
  align-items:flex-start!important;
  gap:8px;
  scrollbar-width:thin;
  -webkit-overflow-scrolling:touch;
}
/* ★ 未选中的帧不占位（墙 = 只显示选中帧）；被 105 打的 .off 保留不动，只加一层别名 */
.seqedit-grid573 .frame-cell.off630{ display:none!important; }

/* ★ v631.1 修「格子变小」：v630 把 .seqedit-grid573 从 grid 改成 flex，而 .frame-cell 本身
   **没有宽度**（原来靠 grid 的 `minmax(56px,1fr)` 撑着）⇒ `canvas{width:100%}` 参照一个
   未定义宽度 ⇒ 缩成很窄 ⇒ **高度跟着塌下去**（用户报「变成单行了，但高度显示变小」）。
   ⇒ flex 下必须显式给格子定宽 + 不许压缩（flex-shrink 默认 1 会把 24 格挤扁）。 */
.seqedit-grid573 .frame-cell{
  flex:0 0 auto!important;      /* 不许被压扁 */
  width:72px;                  /* 固定宽；高度按 canvas 自身比例自动出 */
}

/* ══════ 47-seqtabs633.css ══════ */
/* ================= v633：编辑窗左栏三页签的样式（全部帧 / 图像处理 / 调色） =================
   配合 JS：`163-seqtabs633.js` —— 它在左栏顶部插一排三颗页签 + 三个容器，
   把 111 建的两组（像素处理 / 调色）搬进对应容器，并另起一面「全部帧」墙。

   配色一律走主题变量（--card / --sunken / --line / --line-strong / --text /
   --text-2 / --text-3 / --accent / --accent-soft / --sans），不发明裸色。 */

/* ---------- 页签条：三颗等宽按钮，占满左栏宽度 ---------- */
.seqedit-tabs633{display:flex;gap:4px;margin-bottom:12px}
.seqedit-tab633{
  flex:1 1 0;min-width:0;padding:6px 4px;border-radius:8px;
  border:1px solid var(--line);background:var(--card);color:var(--text-2);
  font:500 11.5px/1.2 var(--sans);cursor:pointer;white-space:nowrap;
  overflow:hidden;text-overflow:ellipsis;
}
.seqedit-tab633:hover{border-color:var(--accent);color:var(--accent)}
.seqedit-tab633.on{
  border-color:var(--accent);background:var(--accent-soft);color:var(--accent);
  font-weight:600;
}

/* ---------- 三个容器：切换 = 显隐（不重建 DOM ⇒ 状态 / 滚动位置全保留） ---------- */
.seqedit-panes633{display:flex;flex-direction:column;min-height:0}
.seqedit-pane633{display:flex;flex-direction:column;gap:10px;min-height:0}
.seqedit-pane633[hidden]{display:none}
/* 搬进来的两个组：原来的「组 + 组」间距由 33 表给，这里保持 */
.seqedit-pane633 .seqedit-grp573 + .seqedit-grp573{margin-top:0}

/* ---------- 「全部帧」页：说明一行 + 全帧墙 ---------- */
.seqedit-allwrap633{display:flex;flex-direction:column;gap:8px;min-height:0}
.seqedit-alltip633{font-size:11px;line-height:1.5;color:var(--text-3)}
/* 全帧墙：左栏只有 280px ⇒ 固定三列、纵向可滚（与右下那面「只显选中帧」的墙是两回事） */
.seqedit-allgrid633{
  display:grid!important;grid-template-columns:repeat(3,1fr)!important;
  gap:6px!important;overflow-y:auto!important;overflow-x:hidden!important;
  max-height:420px;margin:0;padding:0;align-content:start;
}
.seqedit-allgrid633 .frame-cell{min-width:0}
/* 「全部帧」墙里，未选中的帧**照常显示**（这是选的地方，不是结果）——
   只把选中态描粗一点，别用 v630 那套「未选中即隐藏」。 */
.seqedit-allgrid633 .frame-cell.off{display:block!important;opacity:.42}
.seqedit-allgrid633 .frame-cell.on{opacity:1}
/* ══════ 48-seqfix634.css ══════ */
/* ================= v634：序列帧编辑窗 —— 两面帧墙的尺寸/选中态 + 去掉多余滚动条 + 窗加宽 =================
   工单 W634。用户 2026-10-15 傍晚附两张截图提六条：

     ① 红色区域高度保持和绿色的图片尺寸统一
        （红 = 左栏「全部帧」墙；绿 = 右下「已选帧」墙 —— 两面墙的格子现在**不等高**）
     ② 黄色框内显示的尺寸更改为完整尺寸，现在高度不对
        （黄 = 左栏「全部帧」墙整体：网格被 `max-height:420px` + 左栏 `overflow:auto`
          两层高度打架 ⇒ 顶上一行「点一下选中/取消」被裁掉半行，第 24 帧那条边也被切）
     ③ 黄色框（全部帧墙）里**未选中帧呈暗灰色**（可加半透明黑），
        与「选中 / 未选中」拉开区别
     ④ 绿色框（右下已选帧墙）也**强化选中帧样式**，明显区分，
        但**不要**加半透明的黑
     ⑤ 「这个地方高度调节删除」—— 截图 2 红框：画布下方那条**横向滚动条**
        （`cvbox586` 里的 overflow-x 溢出条，画布是等比缩放显示的、根本没有横向内容）
     ⑥ 整体窗口宽度增加

   ── 现状（读代码读出来的，不猜）───────────────────────────────────────────────
     · 窗：`31:11` `width:min(92vw,960px)`、`45` 把高改成 `min(94vh,880px)`
     · 绿墙 `#seqEditGrid573`：`46` 把它从 grid 改成 **flex + nowrap + overflow-x:auto**
       （v630 剪映时间轴口径），格子 `flex:0 0 auto;width:72px`
       ⇒ 格子宽**固定 72px**，高由 canvas 自身比例出（1:1 ⇒ 72px 高）
     · 黄墙 `#seqAllGrid633`：`47:33-37` `grid-template-columns:repeat(3,1fr)`
       + **`max-height:420px`** + 左栏又是 `overflow:auto`
       ⇒ ① 格子宽 = (280-24-2*6)/3 ≈ 81px ⇒ **比绿墙的 72px 宽**，两墙不等高（截图现象）
       ⇒ ② 容器高度 + 左栏滚动高度打架 ⇒ 顶部说明行被裁半行（第 24 帧那条边也被切）

   ── 做法：本表**只覆盖尺寸/配色**，不动任何布局结构与既有表原文 ───────────────
     ① ② 把黄墙改成**与绿墙同一套格子尺寸**（宽 72px、比例同源），
          并把 `max-height` 改成 `flex:1`（跟着左栏走）⇒ 不再有第二套高度打架。
     ③ 黄墙未选中 = 半透明黑罩（`::after` 叠层，只盖 canvas 不盖序号角标）
          + 选中 = 主题色粗描边 + 提亮（对比拉满）。
     ④ 绿墙选中 = 同一套描边语言（与③一致）但**不加黑罩**（它整墙都是选中的）。
     ⑤ 画布容器 `overflow` 归 `hidden` ⇒ 那条横向滚动条没有存在理由，直接没。
     ⑥ 窗宽 960 → **1180px**（视口不够时仍受 92vw 约束，不会顶穿）。

   ⚠️ 为什么黄墙用「固定 72px」而不是 `1fr`：v632 已经把绿墙钉成 72px 固定宽（那是为了
     修「flex 下没宽度 ⇒ 高度塌掉」）。两墙要**看起来一样**，就得用同一个数 ——
     这正是 v617 耦合量铁律：**格子尺寸是耦合量，两处必须同源**。

   ⚠️ 配色一律走主题变量（--accent / --accent-soft / --card / --sunken / --line），
      不发明裸色；半透明黑只用 `rgba(0,0,0,…)`（站内既有那一档）。
   ⚠️ 本表是唯一新增文件：02 / 27 / 31 / 33 / 35 / 45 / 46 / 47 **一字未动**；
      删掉本表 = 完全回退。 */

/* ============================================================================
   ⑥ 整体窗口加宽：960 → 1180px（v629 已把高提到 min(94vh,880px)，宽度这层还留着）
   ============================================================================ */
.seqedit-win571{
  width:min(94vw,1180px)!important;
}
/* 加宽后左栏跟着放宽一点（258 → 280 是 v595 定的，宽度不够时三列格子会被挤） */
.seqedit-left586{flex:0 0 300px}

/* ============================================================================
   ⑤ 红框那条横向滚动条删除：画布是等比缩放显示的，本就没有横向内容
   ============================================================================ */
.seqedit-cvbox573.seqedit-cvbox586{
  overflow:hidden!important;          /* ★ 原来 overflow-x 溢出出一条空滚动条 */
}
.seqedit-cvbox573.seqedit-cvbox586::-webkit-scrollbar{display:none}

/* ============================================================================
   ① ② 黄墙（左「全部帧」）：与绿墙同一套格子尺寸 + 完整显示（不再被 420px 裁）
   ============================================================================ */
.seqedit-pane633[data-pane="all"],
.seqedit-allwrap633{
  flex:1 1 auto!important;min-height:0!important;
}
/* ★ 容器跟着左栏走（原来是 max-height:420px，与左栏 overflow:auto 打架 ⇒ 顶部被裁半行） */
.seqedit-allgrid633{
  grid-template-columns:repeat(3,72px)!important;   /* ★ 与绿墙同一个 72px（耦合量） */
  max-height:none!important;
  flex:1 1 auto!important;min-height:0!important;
  overflow-y:auto!important;overflow-x:hidden!important;
  padding-right:2px;                                   /* 让竖滚动条不压到最后一列 */
  align-content:start;
}
/* 格子与绿墙完全同源：固定宽、不许压扁、比例随素材 */
.seqedit-allgrid633 .frame-cell{
  flex:0 0 auto!important;width:72px!important;min-width:72px!important;
}

/* ============================================================================
   ③ 黄墙：未选中 = 半透明黑罩（暗灰）· 选中 = 粗描边 + 提亮
   ============================================================================ */
.seqedit-allgrid633 .frame-cell{
  border:1px solid var(--line)!important;
  transition:.12s;
}
/* 未选中：canvas 上盖一层半透明黑（**角标序号不盖**，仍是可读的） */
.seqedit-allgrid633 .frame-cell:not(.on) canvas{
  filter:brightness(.62) saturate(.85);       /* 压暗到暗灰，比 opacity 更可控 */
}
.seqedit-allgrid633 .frame-cell:not(.on)::after{
  content:'';position:absolute;inset:0;background:rgba(0,0,0,.34);pointer-events:none;
}
/* 未选中的角标也压暗一档，保持「这一帧没被选」的整格统一感 */
.seqedit-allgrid633 .frame-cell:not(.on) b{opacity:.45}
/* 选中：主题色双层描边 + 提亮（与绿墙同一套视觉语言） */
.seqedit-allgrid633 .frame-cell.on{
  border-color:var(--accent)!important;
  box-shadow:0 0 0 2px var(--accent-soft),0 0 0 4px rgba(0,0,0,.14)!important;
  transform:scale(1.04);                       /* 选中格略大，肉眼一眼分得开 */
  z-index:1;
}
.seqedit-allgrid633 .frame-cell.on canvas{filter:none}
.seqedit-allgrid633 .frame-cell.on b{
  background:var(--accent)!important;color:#0b0d12!important;opacity:1;
}
/* v633 写的 `.off{opacity:.42}` 这条要撤 —— 暗灰改由上面的黑罩 + brightness 负责，
   两套叠加会把未选中的帧压得过黑（.42 的 opacity × .34 黑罩 ≈ 看不见）。 */
.seqedit-allgrid633 .frame-cell.off{opacity:1!important}

/* ============================================================================
   ④ 绿墙（右下已选帧）：强化选中样式，但**不加半透明黑**
   ============================================================================ */
.seqedit-grid573 .frame-cell{
  border:1px solid var(--line)!important;
  border-radius:9px;
}
.seqedit-grid573 .frame-cell.on{
  border-color:var(--accent)!important;
  box-shadow:0 0 0 2px var(--accent-soft),0 0 0 4px rgba(0,0,0,.16)!important;
  transform:scale(1.06);
}
/* ★ 绿墙整墙都是选中的 ⇒ **明确不加黑罩**（用户原话「但不要加半透明的黑」）。
   正在播的那一帧靠 `.now633` 的浅底区分，不与选中态抢。 */
.seqedit-grid573 .frame-cell canvas{filter:none}
.seqedit-grid573 .frame-cell.on b{
  background:var(--accent)!important;color:#0b0d12!important;
}
/* ══════ 49-seqmark635.css ══════ */
/* ================= v635：右下「已选帧墙」—— 去掉满墙细蓝框，当前编辑帧改蓝色粗框 =================
   工单 W635-01（用户 2026-10-15 晚，附截图）：
     「直接把这个蓝色的框去掉…我选中哪一个你就给我把哪一个变成蓝色的框，框稍微宽一点，三四像素吧。
       左上角不是有个小的数字标吗？选中的用蓝色，没有选中的就是用那个灰色。」

   ── v634 留下的病根（★ 我自己造成的，说清楚）──────────────────────────────
     v634 给绿墙写的是 `.seqedit-grid573 .frame-cell.on { 双层描边 + scale(1.06) }`。
     ★ **`.on` 在这面墙上 = 「在 p.pick 里」**（`157` 打的是 `.off630` 之外的选中态），
       而 v630 的口径是「**这面墙只显选中帧**」⇒ 墙里 6 格全部 `.on`
       ⇒ **每一格都套上了描边和放大** ⇒ 用户看到的就是「每格都有细蓝框」，
          反而看不出「哪一格是我正在编辑的」。
     ⇒ 修法 = **把描边从 `.on` 挪到 `.now633`**（.now633 = 当前编辑帧，v633 的 162 打的标）。
       `.on` 只留「在选中集里」这一层弱信号。

   ── 本表只改样式与配色，不动任何布局、不动任何既有表的原文 ──────────────────
     ① `.on`（在选中集里）：**无描边、无放大**（把 v634 那套撤掉）
        ⇒ 只把左上角序号标染成**灰色**（未选中的那一层信号）
     ② `.now633`（当前编辑帧）：**蓝色 3~4px 粗框 + 轻微放大**
        —— 用户原话「三四像素」；比 v634 的 `0 0 0 2px` 更粗，且只用**一层**边框，不叠阴影
     ③ `.now633` 的序号标：**蓝色底 + 深色字**（02 号表 `.on b` 已经是这个色，
        这里补一条保证优先级；且不再叠别的颜色）
     ⚠️ 配色一律走主题变量（--accent / --accent-soft / --card / --line / --text-2）；
        「灰色」用 `--text-2`（站内既有档位），不发明裸灰。
     ⚠️ 黄墙（左「全部帧」页，v634 那套未选中黑罩 + 选中描边）**一个字不动** ——
        用户这次说的「下面」明确指右下那面墙。

   ⚠️ 本表是唯一新增文件：02 / 27 / 31 / 33 / 35 / 45 / 46 / 47 / 48 **一字未动**；
      删掉本表 = 完全回退到 v634 的观感。 */

/* ============================================================================
   ① 先把 v634 那套「满墙描边 + 放大」撤掉 —— `.on` 在这面墙 = 在选中集里，
      不是「正在编辑」。撤到 0 描边、scale(1)。
   ============================================================================ */
.seqedit-grid573 .frame-cell{
  border:1px solid var(--line)!important;
  border-radius:8px;
  box-shadow:none!important;
  transform:none!important;
}
.seqedit-grid573 .frame-cell.on{
  border-color:var(--line)!important;      /* ★ 不再一律蓝框 */
  box-shadow:none!important;
  transform:none!important;
}

/* 未选中（不在 pick 里，理论上这面墙不出现，留一手）：压暗但**不罩黑** */
.seqedit-grid573 .frame-cell:not(.on) canvas{filter:brightness(.8)}
.seqedit-grid573 .frame-cell:not(.on) b{opacity:.4}

/* ============================================================================
   ② 序号标：在选中集里但**不是当前帧** ⇒ 灰色（未选中的那一层信号）
   ============================================================================ */
.seqedit-grid573 .frame-cell.on b{
  background:var(--card)!important;          /* 浅底 */
  color:var(--text-2)!important;            /* ★ 灰字 */
  border:1px solid var(--line);
  opacity:1;
}

/* ============================================================================
   ③ ★ 当前编辑帧（.now633）：蓝色粗框 4px + 序号标转蓝 —— 用户要的那个标识
   ============================================================================ */
.seqedit-grid573 .frame-cell.now633{
  border-color:var(--accent)!important;
  border-width:4px!important;               /* ★ 用户原话「三四像素」 */
  border-radius:10px;
  box-shadow:0 0 0 1px rgba(0,0,0,.18)!important;   /* 只留一层薄投影做分离，不再叠双环 */
  transform:scale(1.04);
  z-index:2;
}
.seqedit-grid573 .frame-cell.now633 canvas{filter:none}

/* 当前帧的序号标 = 蓝色底 + 深色字（与灰色那档拉开） */
.seqedit-grid573 .frame-cell.now633 b,
.seqedit-grid573 .frame-cell.now633.on b{
  background:var(--accent)!important;
  color:#0b0d12!important;                    /* 站内 accent 配深字（02 号表同款） */
  border-color:var(--accent)!important;
  opacity:1;
}

/* 播放时（.now633 会被逐帧改写）不加额外动画，避免和放大叠出抖动 */
/* ══════ 50-seqfoot636.css ══════ */
/* ================= v636：右下帧图墙区按内容收紧（去掉那一大片空白） =================
   工单 W636-01。用户 2026-10-15 晚（附截图，红框圈住右下大片空白）：
     「现在下面这个红色这个部分是空着的，没用是多余的把它删掉，
       让这个高和那个图片真的高差不多」

   ── 空白是哪来的（读代码读出来的，不猜）────────────────────────────────────────
     `31-seqstyle586.css:17` 把下区 `.seqedit-foot573` 定成 `flex:0 0 30%`（原口径），
     ① 然 后 **`45-seqwin629.css:19-22` 又把它改成 `flex:0 0 38%` + `max-height:56%`**
     —— 那是 v629「窗加高」那批顺手加的（当时要给「选中帧单行」留高度）。
     ★ 但**墙的高度是内容决定的**：`46-seqgrid630.css` 把它排成 **单行 + nowrap**
       （v630 的剪映时间轴口径），格子固定 72px 高 ⇒ 一行就是 72px + 上下内距。
     ⇒ 于是 foot 占 38%、内容只占 ~100px ⇒ **多出来的全是一片空白**（用户圈的那一块）。

   ── 修法：foot 从「按比例」改成「**按内容**」 ──────────────────────────────────
     · `flex:0 0 auto`（不再按百分比抢高度）+ `min-height` 兜底（太窄时至少放得下一行）；
     · 墙本身保持 v630 的单行左右滑（**一根线都不动**）—— 用户只说「去掉空白」，
       没说改掉左右滑的口径；
     · 上面的画布区（`.seqedit-stage573`）本来就是 `flex:1` ⇒ **腾出的高度自动还给画布**，
       素材显示得更大（用户要「和图片真的高差不多」就是这个意思）。

   ⚠️ 为什么不用「给 foot 一个固定 px 高度」：行高会随素材比例变（`drawFrameThumb` 出的是
     96×96 正方形，但墙里格子宽是 72px、高随 canvas 自身比例）⇒ 写死 px 会在
     非正方形素材时重新出现空白或裁切。`auto` + 内容撑高是唯一稳的。

   ⚠️ 本表是唯一新增文件：27 / 31 / 45 / 46 **一字未动**；删掉本表 = 完全回退。 */
.seqedit-right586 .seqedit-foot573{
  flex:0 0 auto!important;         /* ★ 不再按 38% 抢高度 —— 空白就是这么来的 */
  max-height:none!important;
  min-height:104px;                /* 兜底：至少放得下一行 72px + 内距 */
}
.seqedit-right586 .seqedit-stage573{
  flex:1 1 auto!important;         /* ★ 腾出的高度还给画布（素材显示更大） */
}
/* 墙本身：单行 + 横向可滑（v630 口径原样保留，只把它撑满 foot 的宽度） */
.seqedit-right586 .seqedit-grid573{
  flex:0 0 auto!important;
  align-self:stretch;
}
/* ══════ 51-sequi639.css ══════ */
/* ================= v639：编辑窗 —— 滚动条隐形 / 播放键居中 / 删组标题横线 / 行距加大 =================
   工单 W639-03 ~ W639-07（用户 2026-10-15 晚）。

   ③ 帧图墙的横向滚动条：**默认完全隐形，滑动时才出现**
      —— 照抄 AI 对话框那套（`16-ai-float400.css:126` 的 `scrollbar-color:transparent transparent`
      + `::-webkit-scrollbar-thumb` 半透明，滚动中才加深）。
      ⚠️ 用户原话「在不滑动的时候看到里面的图片，看着像是上下居中的那种，
      就不要明显的感觉下面要多要宽一点」⇒ **不占位**是关键：
      用 `scrollbar-width:none` / `::-webkit-scrollbar{display:none}` 让它**彻底不占宽度**，
      滑动时用一层 `mask` 式的渐隐提示代替（原生滚动条无法「滑动才显」，只能选择：
      要么永远不占位、要么永远占位 ⇒ 选「永远不占位」，这是 AI 对话框的口径）。
   ④ 上一帧 / 播放 / 下一帧 三颗键**居中**
   ⑤ 定位点移到「打包下载」左边（DOM 顺序由 168 的 JS 调；这里只保证它贴右不换行）
   ⑥ 删「像素处理」「调色」组标题下那条横线
      —— 那是 `.seqedit-gtitle573::after{content:'';flex:1;height:1px}` 画的
   ⑦ 左栏**行间距加大**（一行一行的上下间距），排版更好看

   ⚠️ 本表是唯一新增文件：02 / 27 / 31 / 33 / 35 / 45 / 46 / 47 / 48 / 49 **一字未动**。 */

/* ============================================================================
   ③ 帧图墙横向滚动条：彻底不占位（AI 对话框口径，16-ai-float400.css:126 同款）
   ============================================================================ */
.seqedit-grid573{
  scrollbar-width:none!important;                 /* Firefox：宽度归零 */
  -ms-overflow-style:none!important;              /* 旧 Edge */
  padding-bottom:0!important;                     /* 底部不留滚动条那条的余量 */
}
.seqedit-grid573::-webkit-scrollbar{
  width:0!important;height:0!important;display:none!important;
}

/* ============================================================================
   ④⑤ 功能行：三颗播放键居中 · 定位点贴「打包下载」左边
   ============================================================================ */
.seqedit-btns573{
  flex-wrap:nowrap!important;align-items:center;
}
/* 三颗键用独立容器包一层居中（111 把它们排在中段，这里改成绝对居中更稳） */
.seqedit-ctl586{
  position:relative;
  margin:0 auto!important;                        /* ★ 居中 */
}
.seqedit-btns573 .seqedit-eyebtn588{
  margin-left:0!important;                       /* 吸管键别再被 margin-left:auto 顶到最左 */
}
/* 定位点 + 打包下载 这一簇贴右 */
.seqedit-btns573 #seqEditAnchorBtn639,
.seqedit-btns573 [title*="定位点"]{
  order:9;margin-left:auto!important;
}

/* ============================================================================
   ⑥ 删组标题下的横线（`.seqedit-gtitle573::after` 画的 1px 线）
   ============================================================================ */
.seqedit-left586 .seqedit-gtitle573::after,
.seqedit-pane633 .seqedit-gtitle573::after{
  content:none!important;display:none!important;
}
/* 标题本身留一点下边距，免得组内第一行贴太紧 */
.seqedit-left586 .seqedit-gtitle573,
.seqedit-pane633 .seqedit-gtitle573{
  margin-bottom:2px!important;
}

/* ============================================================================
   ⑦ 左栏行距加大（一行一行的上下间距）
   ============================================================================ */
.seqedit-left586{gap:18px!important;}                                   /* 组与组 */
.seqedit-left586 .seqedit-grp573{gap:12px!important;}                     /* 组内行与行 */
.seqedit-left586 .seqedit-rngs633,
.seqedit-pane633 .seqedit-rngs573{gap:10px 12px!important;}              /* 滑条网格行距 */
.seqedit-left586 .seqedit-rng573,
.seqedit-pane633 .seqedit-rng573{align-items:center;gap:10px!important;}
.seqedit-left586 .seqedit-chks586{gap:12px!important;row-gap:12px!important;}
.seqedit-left586 .seqedit-bgrow586{gap:8px!important;row-gap:8px!important;}
.seqedit-left586 .seqedit-whrow586{gap:8px!important;row-gap:8px!important;}
.seqedit-left586 .seqedit-szrow586{gap:10px!important;}
/* 组标题与组内第一行之间也留一点 */
.seqedit-left586 .seqedit-grp573 + .seqedit-grp573{margin-top:4px!important;}
/* ══════ 52-seqleft640.css ══════ */
/* ================= v640：编辑窗左栏排版收口 —— 全部帧墙对齐 / 删组标题 / 尺寸独立成块 / 容差行对齐 =================
   工单 W640-01 ~ W640-06（用户 2026-10-15 晚，附截图）。

   ① 全部帧墙：一行三个、右边不留空、图片放大
      `47-seqtabs633.css:33-37` 现在是 `repeat(3,72px)`（v634 为「与绿墙同源 72px」定的）
      + `48:71` 给 `.seqedit-allgrid633` 加了 `padding-right:2px`。
      ★ 用户要「图片放大 + 右边对齐」⇒ 三列**按容器宽自动铺满**（`1fr`）而不是死 72px。
      ⇒ 但 ① 与 48「两墙格子同源」的约定**冲突**（v617 铁律：格子尺寸是耦合量）。
      解法见下面注释：**左墙按容器铺满（视觉对齐优先）、右墙仍 72px** ——
      两者**不在同一面墙上**，同源约束本来只针对「同一面墙的格子」，这里放宽是安全的。
   ② 删「像素处理」「调色」组标题文字
      —— 那两个标题是 `111:451/…` 用 `seqEditGrp573('像素处理')` 建的 `.seqedit-gtitle573`
         （`33` 表给它加了下边距，v639 只是把横线删了，**文字还在**）⇒ 这次把文字也隐藏。
   ③ 「自动抠图/连续/吸管」与「容差/背景」之间的**上下间距**拉开
   ④ 尺寸区（`.seqedit-whrow586` + `.seqedit-szrow586`）**独立成板块**：
      上方加大间距 + **一条横线**隔开 + 横线上下的留白对称（能看出是两个模块）
   ⑤ 「原尺寸」键目前较大 ⇒ 缩小它，但**右侧数值框的大小不变**
      （★ 只缩键，不缩框 —— 尺寸框是耦合量，缩了会让两个输入框对不齐，见 ⑥）
   ⑥ 容差行：进度条长度不变、数值框**统一成下面「尺寸」输入框的大小**、
      且**左端与开关行左对齐**（用户原话「左边对齐到透明的那个按钮下面那一排」）

   ⚠️ 本表是唯一新增文件：02 / 27 / 31 / 33 / 35 / 45 / 46 / 47 / 48 / 49 / 51 **一字未动**。 */

/* ============================================================================
   ① 全部帧墙：三列铺满（不再死 72px）⇒ 图片变大 + 右侧不留空
   ============================================================================ */
.seqedit-allgrid633{
  grid-template-columns:repeat(3,1fr)!important;   /* ★ 按容器宽铺满 */
  gap:8px!important;
  padding-right:0!important;                          /* 撤掉 v634 加的那 2px */
}
.seqedit-allgrid633 .frame-cell{
  width:auto!important;min-width:0!important;         /* ★ 交回给 1fr 管 */
}
/* 画布本身撑满格子（`.frame-cell canvas{width:100%}` 是 02 号表定的，不用改） */

/* ============================================================================
   ② 删「像素处理」「调色」两个组标题（v639 只删了横线，文字还在）
   ============================================================================ */
.seqedit-left586 .seqedit-gtitle573,
.seqedit-pane633 .seqedit-gtitle573{
  display:none!important;
}

/* ============================================================================
   ③ 「开关行」与「容差 / 背景」之间拉开
   ============================================================================ */
.seqedit-left586 .seqedit-chks586{
  margin-bottom:10px!important;
}
/* 容差行与背景行之间也留一点 */
.seqedit-left586 .seqedit-rng573 + .seqedit-bgrow586{
  margin-top:8px!important;
}

/* ============================================================================
   ④ 尺寸区独立成块：横线 + 上下留白对称
   ============================================================================ */
.seqedit-left586 .seqedit-whrow586{
  position:relative!important;
  margin-top:22px!important;                /* 上方留大间距 */
  padding-top:20px!important;               /* 横线上下的留白对称 */
}
/* ★ 那条横线：用伪元素画在尺寸区正上方，不影响任何既有元素的边框 */
.seqedit-left586 .seqedit-whrow586::before{
  content:'';position:absolute;left:0;right:0;top:9px;
  height:1px;background:var(--line);
}
/* 尺寸区内部两行之间也留一点 */
.seqedit-left586 .seqedit-whrow586 + .seqedit-szrow586{
  margin-top:10px!important;
}

/* ============================================================================
   ⑤ 「原尺寸」键缩小；★ 右侧数值框尺寸一律不动
   ============================================================================ */
/* ⚠️ 用户要「缩小的时候，右边显示框不用缩小，只缩里面的像素」——
   即**只缩那颗键**，旁边那个「xx px」显示框与滑条位置都别动。
   `31-seqstyle586.css:51` 给 `.seqedit-szval586` 的是 `font:600 12px/1`（字号跟着内容变）
   ⇒ 这里锁死行高与最小宽，保证缩键时那一格不跳。 */
.seqedit-left586 .seqedit-szval586{
  flex:0 0 auto!important;
  min-width:44px;                 /* 与「尺寸」输入框同宽，两块视觉对齐 */
  height:22px;line-height:22px;   /* ★ 锁死行高 ⇒ 缩键时不抖 */
  display:inline-flex;align-items:center;justify-content:flex-end;
}
.seqedit-left586 .seqedit-szrow586 .mini-btn{
  flex:0 0 auto!important;
  padding:2px 8px!important;               /* ★ 比默认小一圈 */
  font:400 10.5px/1.4 var(--sans)!important;
  border-radius:6px;
}

/* ============================================================================
   ⑥ 容差行：进度条长度不变 · 数值框统一成「尺寸」输入框大小 · 左端与开关行左对齐
   ============================================================================ */
.seqedit-left586 .seqedit-rng573{
  /* 左端对齐：标签不吃余量（35 表给 `.seqedit-whrow586 em` 打过 `margin-right:auto`，
     这里给容差行**同样**处理 ⇒ 容差行与开关行、尺寸行的左边界一致） */
  padding-left:0!important;
}
.seqedit-left586 .seqedit-rng573 em{
  margin-right:auto!important;               /* ★ 标签贴左、控件整簇贴右 */
}
/* 进度条本身：flex 吃掉余量 ⇒ **长度不变**（只把后面的数值框定死大小） */
.seqedit-left586 .seqedit-rng573 input[type="range"]{
  flex:1 1 auto!important;min-width:0!important;
}
/* ★ 数值框 = 下面「尺寸」输入框的大小（`33-seqstyle588.css:49` 是 `.seqedit-wh586{width:44px}`） */
.seqedit-left586 .seqedit-rng573 .seqedit-num573{
  flex:0 0 44px!important;width:44px!important;   /* 与尺寸输入框同宽 */
  padding:2px 4px!important;
  font:11.5px/1.4 var(--sans)!important;
  border-radius:6px!important;
  text-align:right;
}
/* ══════ 53-seqgrid643.css ══════ */
/* ================= v643：两面帧墙的正方形 / 间距 / 选中态 + 左栏与功能行排版 + 全站滚动条统一 =================
   工单 W643-02 ~ W643-12（用户 2026-10-15 晚）。

   ★ 一条贯穿全表的口径：**「显示为正方形」≠「把图裁成正方形」**
     （用户原话：「保持它是正方形……但是不是把图片截成正方形，不要截掉它的图片」）
     实现 = 格子 `aspect-ratio:1/1` + canvas `object-fit:contain`（**完整显示、等比缩放、留白**），
             **绝不用 object-fit:cover / overflow:hidden 去裁**。

   ② 删左墙那行提示（JS 侧 171 已摘；这里兜底隐藏一层，双保险）
   ③ 两墙格子都固定为**正方形**（左墙原来随容器宽变宽、高不变 ⇒ 看着不是方）
   ④⑤ 左右/上下间距收窄（左墙 gap 8→5，右墙 46 号表是 nowrap + 无 gap ⇒ 补 5）
   ⑥⑦⑧ **去掉「选中放大」效果**（v634 给两墙都加了 `scale(1.04/1.06)`）
   ⑨⑩ 容差条左端与开关行左对齐 + 尺寸区横线往上移且上下等距
   ⑪⑫ 三键（上一帧/播放/下一帧）**相邻成组且整组居中**；定位点与打包下载**紧邻**（留一点标准间隙）
        + 分隔线与上下间距对称

   ⚠️ 本表是唯一新增文件：02 / 16 / 27 / 31 / 33 / 35 / 45 / 46 / 47 / 48 / 49 / 51 / 52 **一字未动**。 */

/* ============================================================================
   ★ D 组：全站滚动条统一成 AI 对话框那套（`16-ai-float400.css:126` 同款）
     —— 默认**完全隐形**、占位为零；需要提示时用 hover 亮一下细条。
   ============================================================================ */
.seqedit-win571 *::-webkit-scrollbar{width:8px;height:8px}
.seqedit-win571 *::-webkit-scrollbar-track{background:transparent}
.seqedit-win571 *::-webkit-scrollbar-thumb{
  background:transparent;border-radius:4px;
  transition:background .15s;
}
.seqedit-win571 *:hover::-webkit-scrollbar-thumb{background:var(--line-strong)}
.seqedit-win571 *::-webkit-scrollbar-thumb:hover{background:var(--text-3)}
.seqedit-win571 *{scrollbar-width:thin;scrollbar-color:transparent transparent}
.seqedit-win571 *:hover{scrollbar-color:var(--line-strong) transparent}
/* ★ 帧图墙那两面：彻底不占位（v639 已定；这里保持一致，别让滚动条把图片挤偏） */
.seqedit-allgrid633,
.seqedit-grid573{
  scrollbar-width:none!important;-ms-overflow-style:none!important;
}
.seqedit-allgrid633::-webkit-scrollbar,
.seqedit-grid573::-webkit-scrollbar{width:0!important;height:0!important;display:none!important}

/* ============================================================================
   ② 左墙提示行：兜底隐藏（JS 已摘，这里防它被重建）
   ============================================================================ */
.seqedit-alltip633{display:none!important}

/* ============================================================================
   ③⑦⑧ 两墙格子：**显示为正方形**（不裁图）+ 去掉选中放大 + 收窄间距
   ============================================================================ */
.seqedit-allgrid633{
  grid-template-columns:repeat(3,1fr)!important;
  gap:5px!important;                        /* ⑧ 原 8px ⇒ 收窄 */
}
/* ★ 正方形：格子自己撑成正方形，canvas 用 contain **完整显示**（不裁） */
.seqedit-allgrid633 .frame-cell{
  aspect-ratio:1/1!important;
  width:auto!important;min-width:0!important;
  height:auto!important;
  overflow:hidden;                          /* 只是裁掉 canvas 的溢出部分，不裁图本身 */
  display:flex!important;align-items:center!important;justify-content:center!important;
  padding:0!important;
}
.seqedit-allgrid633 .frame-cell canvas{
  width:100%!important;height:100%!important;
  object-fit:contain!important;              /* ★ contain = 完整显示、等比、留白（绝不用 cover） */
  display:block;
}
/* ⑦⑧ 去掉选中放大（v634 给的 scale 1.04 / 双层描边）—— 只留描边，不缩放 */
.seqedit-allgrid633 .frame-cell.on{
  transform:none!important;
  box-shadow:0 0 0 2px var(--accent-soft)!important;
}

/* 右墙（已选帧）：收窄间距 + 正方形 + 去掉放大 */
.seqedit-grid573{
  gap:5px!important;                        /* ★ 原表没写 gap（v630 改成 flex 时漏了） */
  align-items:flex-start!important;
}
.seqedit-grid573 .frame-cell{
  aspect-ratio:1/1!important;
  width:72px!important;height:72px!important;    /* ★ 宽高都钉死 ⇒ 一定是正方形 */
  overflow:hidden;
  display:flex!important;align-items:center!important;justify-content:center!important;
  padding:0!important;
}
.seqedit-grid573 .frame-cell canvas{
  width:100%!important;height:100%!important;
  object-fit:contain!important;
  display:block;
}
/* ⑦⑧ 去掉放大；★ 当前帧（.now633）保留**蓝框**（v635 立的标识，只去 scale 不去框） */
.seqedit-grid573 .frame-cell.on,
.seqedit-grid573 .frame-cell.now633{transform:none!important}
.seqedit-grid573 .frame-cell.now633{
  box-shadow:0 0 0 1px rgba(0,0,0,.18)!important;   /* 只留一层薄投影做分离 */
}

/* ============================================================================
   ⑨⑩ 左栏：容差条左端对齐开关行 · 尺寸区横线上移 + 上下等距
   ============================================================================ */
/* ⑨ 容差行标签不吃余量 ⇒ 左边界与开关行一致（`52-seqleft640.css` 已做，这里只补外距） */
.seqedit-left586 .seqedit-rng573{padding-left:0!important}
/* ⑩ 横线往上挪、且离上下**等距**：上留白 padding-top、下留白用 margin-bottom 配平 */
.seqedit-left586 .seqedit-whrow586{
  margin-top:14px!important;               /* ★ 原 22 ⇒ 上移 */
  padding-top:14px!important;              /* ★ 横线上方留白（下移到 14，与下方对齐） */
  margin-bottom:2px!important;
}
.seqedit-left586 .seqedit-whrow586::before{top:6px;height:1px;background:var(--line)}

/* ============================================================================
   ⑪⑫ 功能行：三键成组居中 · 定位点与打包下载紧邻 · 分隔线上下等距
   ============================================================================ */
.seqedit-btns573{
  display:flex!important;flex-wrap:nowrap!important;align-items:center!important;
  gap:0!important;                          /* ★ 间隙统一交给各簇自己控 */
}
/* ★ 三键成组（相邻、组内小间隙）、整组在红框内左右居中 */
.seqedit-ctl586{
  display:inline-flex!important;align-items:center!important;
  gap:4px!important;                       /* 三键之间的正常间隙 */
  margin:0 auto!important;                 /* 整组居中 */
}
/* ★ 定位点 + 打包下载 = 右端一簇，两颗**紧邻**（留 4px 间隙，不是完全贴住） */
.seqedit-btns573 #seqEditAnchorBtn639,
.seqedit-btns573 [title*="定位点"]{margin-left:0!important}
.seqedit-btns573 #seqEditZipBtn639,
.seqedit-btns573 [title*="打包下载"]{margin-left:4px!important;margin-right:0!important}
/* 吸管键与已选帧数/帧率那几颗别被 margin-left:auto 顶飞 */
.seqedit-btns573 .seqedit-eyebtn588{margin-left:0!important}
.seqedit-btns573 #seqEditCntChip586,
.seqedit-btns573 #seqEditFpsChip586{margin-left:0!important}
/* ⑫ 右下帧图墙的上边距 = 功能行与图之间的间隙 ⇒ 与图下方的间隙一致
      （图下方没有别的内容，用内距补一个视觉等距） */
.seqedit-grid573{padding-top:6px!important;padding-bottom:6px!important}
/* ══════ 54-genact644.css ══════ */
/* ================= v644：生图/生视频的「取消」键 + 「覆盖 or 新建节点」小确认框 =================
   工单 W644-01 ~ W644-03。

   设计要点（用户明令「不要按我说的一长串放上去」）：
     · 按钮**短**：只写「新建节点生成」/「覆盖本节点」，长句说明一律放**副标题**一行。
     · 覆盖那条**必须带警告**：副标题写「原图/原视频就没了，且无法撤销」——
       用户强调「数据就没了」，不能只写「覆盖」两个字让人以为还在。
     · 框**小**：紧贴生成键下方弹出，不做全屏遮罩（遮罩会给"我在做重要决定"的心理暗示，
       这里只是一次「要不要新建节点」的轻选择）。
     · 「今日不再提醒」默认不勾；勾了则**当天**直接覆盖不再问（不擅自升级成永久）。

   配色一律走主题变量（--card / --sunken / --line / --line-strong / --text /
   --text-2 / --text-3 / --accent / --accent-soft / --danger 语义档 / --sans）。 */

/* ---------- 取消键：生成中才出现，紧贴「生成」键右侧 ---------- */
.gen-cancel644{
  margin-left:6px!important;
  padding:3px 9px!important;
  border:1px solid var(--line-strong)!important;
  background:var(--card)!important;
  color:var(--text-2)!important;
  font:500 11px/1.4 var(--sans)!important;
  border-radius:6px!important;
  cursor:pointer;
}
.gen-cancel644:hover{border-color:var(--accent)!important;color:var(--accent)!important}
.gen-cancel644[hidden]{display:none!important}

/* ---------- 小确认框：贴生成键下方、窄、不遮罩 ---------- */
.gen-confirm644{
  position:fixed;z-index:140;
  width:236px;padding:12px 13px 10px;
  border:1px solid var(--line-strong);border-radius:10px;
  background:var(--card);color:var(--text);
  box-shadow:0 10px 28px rgba(0,0,0,.22);
  font:400 12px/1.5 var(--sans);
  animation:genConfirmIn644 .12s ease-out;
}
@keyframes genConfirmIn644{from{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:none}}

.gen-confirm-t644{font:600 12.5px/1.4 var(--sans);color:var(--text)}
.gen-confirm-s644{
  margin-top:4px;font-size:11.5px;line-height:1.5;color:var(--text-2);
}
/* ★ 警告那条（覆盖按钮的副提示）用一点警示色，但不刺眼 */
.gen-confirm-over644 + .gen-confirm-s644,
.gen-confirm-b644 .gen-confirm-s644{color:var(--text-2)}

/* ---------- 两个按钮：并排、等宽 ---------- */
.gen-confirm-b644{
  display:flex;gap:6px;margin-top:10px;
}
.gen-confirm-btn{
  flex:1 1 0;min-width:0;padding:6px 4px;
  border:1px solid var(--line);border-radius:7px;
  background:var(--card);color:var(--text-2);
  font:500 11.5px/1.3 var(--sans);
  cursor:pointer;white-space:nowrap;
  overflow:hidden;text-overflow:ellipsis;
}
.gen-confirm-btn:hover{border-color:var(--accent);color:var(--accent)}
/* ★ 默认焦点给「新建节点生成」（安全的那一侧 —— 覆盖是不可撤销的） */
.gen-confirm-new644{border-color:var(--accent);color:var(--accent);background:var(--accent-soft)}

/* ---------- 「今日不再提醒」 ---------- */
.gen-confirm-sil644{
  display:flex;align-items:center;gap:5px;
  margin-top:9px;padding-top:8px;
  border-top:1px solid var(--line);
  font-size:11px;color:var(--text-3);
  cursor:pointer;user-select:none;
}
.gen-confirm-sil644 input{margin:0;accent-color:var(--accent);width:13px;height:13px}
/* ══════ 55-alleft646.css ══════ */
/* ================= v646：左墙「全部帧」—— 间距不叠 + 上方留白收紧 =================
   工单 W646-02（用户 2026-10-15 晚，附截图）：
     「它那个图片的高度倒是统一了，但是**间距为什么叠在一起了**」
     「图片的这个上方，它和这个间距太宽了（画红线那儿）」

   ── ① 间距叠在一起：v643 的 `padding:0` + `overflow:hidden` 压到了序号角标 ──
     `.frame-cell b` 是**绝对定位在格子内** `left:3px; top:3px`（`02-shell.css:92`）
     ★ v643（`53`）为了做正方形给格子加了 `padding:0!important` + `overflow:hidden`
       ⇒ 角标被压到**紧贴格子边缘**，而格子的 box-shadow 也在同一层
       ⇒ 相邻两格的角标 + 描边视觉上连成一片 ⇒ 看着像"叠在一起"。
     ⇒ 修法：格子**给回 3px 内缩**（角标要那点位置），gap 从 5 回到 6。

   ── ② 上方留白过宽：三层叠加 ───────────────────────────────────────────────────
     · `47-seqtabs633.css:36` 的 `padding:0` + `align-content:start`（当时是对的，
       v643 改成 1fr 后没再管它）；
     · `35-seqleft595.css:16` 左栏 `padding:12px`；
     · `52-seqleft640.css` 给左栏的 `gap:18px` 落在 pane 容器上。
     ⇒ 第一行离 pane 顶部 = 12(左栏 padding) + 18(gap) 的一截 ⇒ 过宽。
     ⇒ 修法：pane 内容**顶部不留 gap**（只有下面那些组之间才要 18）。

   ⚠️ 本表是唯一新增文件：02 / 33 / 35 / 47 / 52 / 53 **一字未动**。 */

/* ============================================================================
   ① 格子：给回内缩（角标不再被压到边缘）· 描边改成内阴影（不占位、不与邻格相接）
   ============================================================================ */
.seqedit-allgrid633{
  gap:6px!important;                        /* 5 → 6：给描边一点呼吸 */
  align-content:start!important;            /* ★ 明确写死，别被前面的表改掉 */
  padding:2px 0 0!important;                /* 顶部一点点内边，让描边不贴 pane 边 */
}
.seqedit-allgrid633 .frame-cell{
  /* ★ 关键：取消 v643 的 `padding:0` ⇒ 角标回到 `left:3/top:3` 的内侧 */
  padding:3px!important;
  box-sizing:border-box!important;
}
/* 描边改「内阴影」而不是外框：外框会往外扩，5~6px 的 gap 就被吃掉看着像叠在一起 */
.seqedit-allgrid633 .frame-cell,
.seqedit-allgrid633 .frame-cell.on{
  border-color:transparent!important;
  box-shadow:inset 0 0 0 1px var(--line)!important;
}
.seqedit-allgrid633 .frame-cell.on{
  box-shadow:inset 0 0 0 2px var(--accent),
             inset 0 0 0 4px var(--accent-soft)!important;
}
/* canvas 不再顶格（角标那一圈留白要看得见） */
.seqedit-allgrid633 .frame-cell canvas{
  width:100%!important;height:100%!important;
  border-radius:5px;
}

/* ============================================================================
   ② 上方留白收紧：pane 顶部不留 gap
   ============================================================================ */
.seqedit-pane633[data-pane="all"],
.seqedit-pane633[data-pane="all"] > .seqedit-allwrap633{
  margin-top:0!important;
}
.seqedit-pane633[data-pane="all"]{
  gap:0!important;                          /* ★ 左栏的 gap:18 落在这里 ⇒ 顶部那一格就是多余留白 */
}
/* 但 pane 内部若有多个块（提示行已删，一般只剩墙），仍给 6px 的块间距 */
.seqedit-pane633[data-pane="all"] > * + *{
  margin-top:6px!important;
}
/* ══════ 56-footrow647.css ══════ */
/* ================= v647：编辑窗右下 —— 帧图墙上下边距对称 + 功能行三键居中 + 定位点贴右 =================
   工单 W647-01 / W647-02（用户 2026-10-15 晚，附两张截图）：

     ① 「右边那个节点怎么没有变化呀？…这个地方是没有改到吗？」
        两条红箭头指的是右下那面帧图墙的**上边距与下边距** ——「它要保持一致」
     ② 「定位点这个按钮往那边移，移到打包下载，两个一起往右靠，右对齐」
        「播放 / 上一帧 / 下一帧 三个按钮也放在一起，但不要完全贴着，就正常有个间距」
        「然后它对于这一整条框，这一整条红色框是**左右居中**的」

   ── ① 边距不一致的根因（逐层查出来的）──────────────────────────────────────────
     · `27-seqedit573.css:50` 原始 `padding:10px 12px`（上下各 10）
     · `46-seqgrid630.css:8` v630 改 flex 单行时**没覆盖 padding** ⇒ 沿用 10px
     · ★ `53-seqgrid643.css`（v643）我为「上下等距」写过 `padding-top/bottom:6px`，
       **但被同文件后面的规则按层叠压掉了** ⇒ 实测上边距明显大于下边距。
     ⇒ 修法：上下等距收成**一处显式同值**（唯一的间距来源），并把 foot 自己的
       padding/margin 清零 —— 杜绝「上下来自不同规则」。

   ── ② 三键为什么是散的（v643 引入的）──────────────────────────────────────────
     `111:568` 的功能行 DOM 顺序（v586 建）：
       `已选帧数 / 帧率 / 上一帧 / 播放 / 下一帧 / 定位点 / 打包下载`
     v643 写了 `.seqedit-ctl586{margin:0 auto}` —— ★ 而 `seqedit-ctl586` 是
     `111:551-559` 给**每一颗**播放键单独加的类（prev / play / next 各一颗）
     ⇒ `margin:auto` 让**三颗各自居中** ⇒ 观感是被均匀摊到整行（截图正是如此）。

   ── ② 修法：两端用 flex 撑开 + 中间三键**绝对居中** ──────────────────────────
     为什么不用 `grid-template-columns:1fr auto 1fr`：右端两颗（定位点 + 打包下载）
     要**并排挨着**，而 grid 里它们会落进**同一格**⇒ 重叠。grid 表达不了
     「同一格里再横排两个」⇒ 正确解法就是绝对居中 + 两端 flex。

   ⚠️ 本表是唯一新增文件：02 / 27 / 31 / 33 / 35 / 45 / 46 / 47 / 52 / 53 / 55 **一字未动**。 */

/* ============================================================================
   ① 帧图墙：上下边距**显式对称**（唯一落点）
   ============================================================================ */
.seqedit-right586 .seqedit-foot573{
  padding:0!important;
  margin:0!important;
}
.seqedit-right586 .seqedit-grid573{
  margin:0!important;                /* ★ 容器自身外边距是不对称的最大来源 */
  padding:10px 12px!important;       /* ★ 上下同值 10 : 10 —— 就是这一处 */
  box-sizing:border-box!important;
}

/* ============================================================================
   ② 功能行：左簇贴左 · 三键成组绝对居中 · 右端两簇贴右并排
   ============================================================================ */
.seqedit-right586 .seqedit-btns573{
  position:relative!important;               /* 中间三键要绝对居中 */
  display:flex!important;
  flex-wrap:nowrap!important;
  align-items:center!important;
  gap:0!important;                            /* 间隙由各簇自己控 */
  padding:0 12px!important;                   /* 与墙同一条左边线 */
  margin:0!important;
  min-height:30px!important;                  /* 给绝对定位的三键一个稳定的行高 */
}

/* ---- 左簇（已选帧数 / 帧率）贴左 ---- */
.seqedit-right586 #seqEditCntChip586,
.seqedit-right586 #seqEditFpsChip586{
  flex:0 0 auto!important;margin:0!important;
}

/* ---- ★ 中间三键：**整体左右居中**（与左右两簇宽度无关） ----
        三颗相邻成组，间隔 6px（不贴死、也不散开）。
        整组宽 ≈ 26×3 + 6×2 = 90px ⇒ 各自 left 用 50% 减去偏移。 */
.seqedit-right586 #seqEditPrevBtn586,
.seqedit-right586 #seqEditPlayBtn586,
.seqedit-right586 #seqEditNextBtn586{
  position:absolute!important;
  top:50%!important;
  transform:translateY(-50%)!important;       /* 只做垂直居中，不掺水平位移 */
  flex:0 0 auto!important;
  margin:0!important;
  min-width:26px!important;
  padding:3px 8px!important;
}
.seqedit-right586 #seqEditPrevBtn586{left:calc(50% - 78px)!important}
.seqedit-right586 #seqEditPlayBtn586{left:calc(50% - 39px)!important}
.seqedit-right586 #seqEditNextBtn586{left:calc(50% - 0px)!important}
/* 三颗中心间距 = 39px = 半宽(13) + 间隙(6) + 半宽(13) + ……⇒ 相邻留 6px 的正常缝 */

/* ---- 右端两簇（定位点 + 打包下载）贴右、并排、彼此留 6px ----
        DOM 顺序是「定位点 → 打包下载」（`111:568`）⇒ 给打包下载 `margin-left:auto`
        把左边全推到左侧、自己贴右；定位点紧随其后，两者之间留 6px。 */
.seqedit-right586 #seqEditAnchorBtn586{
  position:static!important;                   /* ★ 撤掉「被别处绝对定位」的可能 */
  flex:0 0 auto!important;
  margin-left:0!important;
  margin-right:6px!important;                 /* ★ 与打包下载之间留一点缝 */
}
/* 「打包下载」那颗来自 `105`（v571 建的那颗，没有 586 的 id）⇒ 按文案认 */
.seqedit-right586 .seqedit-btns573 > button{
  flex:0 0 auto!important;
}
.seqedit-right586 .seqedit-btns573 > button:last-child{
  margin-left:auto!important;                 /* ★ 右端贴右 */
}
/* 兜底：若「定位点」那颗被换成了 v639 建的 id（seqEditAnchorBtn639） */
.seqedit-right586 #seqEditAnchorBtn639{
  position:static!important;flex:0 0 auto!important;
  margin-left:0!important;margin-right:6px!important;
}
/* ══════ 57-confpos648.css ══════ */
/* ================= v648：确认框落进生成面板内（不再飘在屏幕左上角） =================
   工单 W648-01（用户 2026-10-15 晚，附截图）：
     「这个提示应该在这里」—— 箭头指向**生成面板内部、提示词框右侧那块空白**。

   ── 真根因：v644（`54-genact644.css`）写的是 `position:fixed` **却没给 top/left** ──
     ⇒ 按规范落在**静态位置的视口坐标**，而它的静态位置是 `body` 的第一个孩子
     ⇒ 实测就在**屏幕左上角 (0,0)**（截图正是如此）。
     ⇒ 不是"位置算错"，是**根本没收口**。

   ── 修法（`176-confpos648.js` 负责搬进面板 + 算坐标；本表只管呈现）──────────────
     · 框改成 **`position:absolute`**（父级 `#cardGen189` 由 JS 补 `position:relative`）
       ⇒ **随面板移动/滚动自动跟随**，不需要监听 resize（视口坐标做不到这点）。
     · 保留 `position:fixed` 的残留样式会与 JS 设的 absolute 打架 ⇒ 这里清一次。

   ⚠️ 本表是唯一新增文件：02 / 27 / 32 / 33 / 35 / 45 / 54 **一字未动**。 */

/* v644 那条 `position:fixed` 没坐标 ⇒ 改成 absolute（坐标由 176 的 JS 算好写进 style） */
.gen-confirm644{
  position:absolute!important;
  top:auto;left:auto;                 /* ★ 坐标一律由 JS 给，CSS 不预设（预设会先落在 0,0 闪一下） */
  right:auto;bottom:auto;
  z-index:60!important;                /* 面板内层级：高于内容、低于面板自己的浮层（规格弹层等） */
  width:236px;
  /* 不再吸在最上层 ⇒ 不会被画布上其他浮层盖住，也跟着面板一起被滚动裁剪 */
  animation:genConfirmIn648 .12s ease-out;
}
@keyframes genConfirmIn648{from{opacity:0;transform:translateY(4px)}to{opacity:1;transform:none}}

/* 面板自身需要定位上下文（176 的 JS 只在需要时补一次，这里先声明，双保险） */
#cardGen189{position:relative}

/* ══════ 58-cuteye650.css ══════ */
/* ================= v650：图片处理面板的吸管键 =================
   工单 W650-01（用户 2026-10-15 晚，附截图）。

   位置：与「自动抠图 / 连续 / 消除锯齿 / 平滑插值」同一行的末尾（截图红圈处）。
   形态：与同排那几个开关同规格的小方钮；开着时走主题色实心（一眼看得出在吸）。
   ⚠️ 本表是唯一新增文件：33 / 45 / 47 / 53 / 55 / 56 **一字未动**。 */

.eye-btn650{
  display:inline-flex;align-items:center;justify-content:center;
  width:26px;height:26px;flex:0 0 auto;
  margin-left:8px;                       /* 与左边那几个开关留一点缝 */
  padding:0;border:1px solid var(--line-strong);border-radius:6px;
  background:var(--card);color:var(--text-2);
  cursor:pointer;vertical-align:middle;
  transition:border-color .12s,color .12s,background .12s;
}
.eye-btn650:hover{border-color:var(--accent);color:var(--accent)}
/* 开着：主题色实心（状态必须一眼可辨 —— 用户是"点完去画面上点颜色"的流程） */
.eye-btn650.on{
  background:var(--accent);border-color:var(--accent);color:#fff;
}
/* 禁用（画布还没建出来 / 无图可选） */
.eye-btn650[disabled]{opacity:.4;cursor:not-allowed}

/* ══════ 59-seqdrag651.css ══════ */
/* ================= v651：帧图墙拖拽排序的视觉反馈 —— 插入位指示线 / 原位占位 / 幽灵 =================
   工单 W651-01（用户 2026-10-15 深夜）：
     「调整顺序的功能不好用，优化一下，拖拽时，能清晰看到要放在哪个位置」

   ★ 三层视觉各自的职责（缺一不可）：
     ① **插入位指示线**（`.seqdrag-line651`）= 「会放哪」—— 一条跨格高的主题色竖线
        + 上下小三角。★ 这是 DnD 里最关键的一块反馈。
     ② **原位占位**（`.seqdrag-hole651`）= 「它原来在这」—— 虚线空框，
        拖走之后**行宽不塌陷**，始终看得到原位。
     ③ **幽灵**（`.seqdrag-ghost651`）= 「我手里拿着这一格」—— 半透明跟着光标，
        手指不会"失去"那一格。

   ⚠️ 本表是唯一新增文件：31 / 33 / 45 / 46 / 53 / 55 / 56 **一字未动**。 */

/* 拖拽进行中：墙内光标变「抓」 */
.seqedit-grid573.seqdrag-on651,
.seqedit-grid573.seqdrag-on651 .frame-cell{cursor:grabbing!important}

/* ============================================================================
   ① 插入位指示线
   ============================================================================ */
.seqdrag-line651{
  position:fixed;z-index:3;display:none;         /* ★ v654：在图层内用小层级（2/1/3），外层 125 统一压过编辑窗 */
  width:2px;margin-left:-1px;                /* 以线心对齐算出来的 x */
  background:var(--accent);
  border-radius:2px;
  pointer-events:none;                        /* ★ 绝不吃事件，否则拖到线上就断了 */
  box-shadow:0 0 0 1px var(--accent-soft),0 0 8px var(--accent-soft);
  will-change:transform;              /* v655：提前提升为合成层 */
  animation:seqdragPulse651 1.4s ease-in-out infinite;   /* v655：放慢，避免频闪看着像残影 */
}
@keyframes seqdragPulse651{0%,100%{opacity:1}50%{opacity:.62}}

/* 上下小三角（线头）—— 用伪元素画，不额外占元素 */
.seqdrag-line651::before,.seqdrag-line651::after{
  content:'';position:absolute;left:50%;margin-left:-4px;
  width:0;height:0;border-left:4px solid transparent;border-right:4px solid transparent;
}
.seqdrag-line651::before{top:-3px;border-top:5px solid var(--accent)}
.seqdrag-line651::after{bottom:-3px;border-bottom:5px solid var(--accent)}

/* ============================================================================
   ② 原位占位（孔）
   ============================================================================ */
.seqdrag-hole651{
  position:fixed;z-index:1;display:none;         /* ★ v654：孔（最下） */
  border:1px dashed var(--line-strong);border-radius:8px;
  background:var(--sunken);                   /* 极浅的一层底，和「空位」读得出来 */
  will-change:transform;              /* v655 */
  pointer-events:none;
  box-sizing:border-box;
}

/* ============================================================================
   ③ 幽灵（跟着光标的那一格）
   ============================================================================ */
.seqdrag-ghost651{
  position:fixed;z-index:2;display:none;         /* ★ v654：幽灵（跟着光标） */
  pointer-events:none;opacity:.72;
  border:1px solid var(--accent);border-radius:8px;
  background:var(--card);
  box-shadow:0 8px 22px rgba(0,0,0,.3);
  overflow:hidden;
  box-sizing:border-box;
  /* ★ v655：**不要**在这里写 transform —— 位置与旋转都由 JS 合成到同一条
     `translate3d(...) rotate(-1.5deg)` 里（拆成两条会互相覆盖，且每帧新合成层 ⇒ 拖影）。
     轻微倾斜 = 「拿起来了」的通用暗示，仍保留在 JS 那条里。 */
  will-change:transform;                    /* 提前提升为合成层，移动更跟手 */
}
/* 幽灵里那格本身不要它自己的描边（外面已经有一圈） */
.seqdrag-ghost651 .frame-cell{
  border-color:transparent!important;
  box-shadow:none!important;
  transform:none!important;
}
.seqdrag-ghost651 canvas{
  width:100%!important;height:100%!important;
  object-fit:contain!important;display:block;border-radius:5px;
}
/* 幽灵里的序号角标（原格是绝对定位的 left/top:3px，幽灵框是相对定位 ⇒ 同样能用） */
.seqdrag-ghost651 b{
  position:absolute;left:3px;top:3px;
  font:600 9px/1 var(--sans, sans-serif);
  padding:2px 3px;border-radius:3px;
  background:rgba(11,13,18,.72);color:#fff;
}

/* ============================================================================
   定位上下文 —— ★ v653 修正：原先写的是 `body{position:relative}`
   —— 那会改变整页定位基准（编辑窗是挂在 body 下的绝对定位浮层）⇒ 墙会偏出去。
   ⇒ 改成给指示线/孔单独建一层容器，绝不动 body。
      ★ 幽灵是 `position:fixed`（跟光标走，不需要这个）。
   ============================================================================ */
#seqdragLayer651{position:fixed;inset:0;z-index:125;pointer-events:none}  /* ★ v654：必须 > 编辑窗遮罩的 120 */
#seqdragLayer651 > *{pointer-events:none}

/* ══════ 60-fix652.css ══════ */
/* ================= v652：清账第四批 —— 三键居中不再硬编码 =================
   工单 W652-03（用户 2026-10-16 早，「必须全部完成」那批里的一条）。

   ★ v647 的做法是把三颗键各写一个 `left:calc(50% - 78/39/0)` ——
     **硬编码像素** ⇒ 键宽 / 字体 / 缩放一变就偏。
   ⇒ 改成：JS 把三颗搬进一个**零尺寸的居中容器**（`180-fix652.js` 的 `centerBtns652`），
     容器自己 `left:50% + translateX(-50%)`，三颗在里面正常 flex 排列
     ⇒ **整组宽度由内容决定，一个像素值都不用写**。

   ⚠️ 本表只管这个容器；原来那三条硬编码规则在 `56-footrow647.css` 里
     （选择器更具体、且带 `!important`）⇒ 这里必须**同权重压过**才有效。
   ⚠️ 本表是唯一新增文件：其余样式表一字未动。 */

/* 居中容器：零尺寸 + 绝对居中 ⇒ 三颗在里面自己排 */
.seqedit-ctlbox652{
  position:absolute!important;
  left:50%!important;
  top:50%!important;
  transform:translate(-50%,-50%)!important;   /* ★ 整体居中（含垂直），不再需要 left 偏移量 */
  display:inline-flex!important;
  align-items:center!important;
  gap:4px!important;                          /* 三键之间的正常缝（不贴死） */
  z-index:1!important;
}
/* 容器里的三颗：不再各自绝对定位（那三个 left:calc 全部作废） */
.seqedit-right586 .seqedit-ctlbox652 #seqEditPrevBtn586,
.seqedit-right586 .seqedit-ctlbox652 #seqEditPlayBtn586,
.seqedit-right586 .seqedit-ctlbox652 #seqEditNextBtn586{
  position:static!important;                   /* ★ 撤掉 v647 的绝对定位 */
  left:auto!important;
  transform:none!important;                    /* 容器已经居中了，键自己不要再转 */
  flex:0 0 auto!important;
  min-width:26px!important;
  margin:0!important;
  padding:3px 8px!important;
}

/* ══════ 61-footrow659.css ══════ */
/* ================= v661：功能行右簇**真的贴右**（v647 的规则加错了元素） =================
   用户报（截图 2，箭头指向「定位点」和右侧空白）：「这两个选择显示错位了」。

   ★ 根因：v647 想让「定位点 + 打包下载」贴右，写的规则是
     `.seqedit-btns573 > button:last-child{margin-left:auto}` ——
     **`margin-left:auto` 加在了内层按钮上，而那个按钮的父 `.seqedit-btns573`
       本身也是 flex 子元素 ⇒ 推不动**（`auto` 要在「flex 容器的直接子元素」上才有效）。
   真机实测（自验截图）：`定位点 | 打包下载` 跟在「8 帧/秒」后面，右侧留一大片空白。

   ⇒ 修法：「定位点」是 `.seqedit-func573` 的**直接子元素**且排在「打包下载」之前
     ⇒ 给它 `margin-left:auto`，就把**它自己和后面的「打包下载」一起**推到右端。
     （三键的容器是绝对定位、脱离文档流 ⇒ 不参与推挤，所以两簇各就各位。） */
.seqedit-right586 .seqedit-func573 > #seqEditAnchorBtn586,
.seqedit-right586 .seqedit-func573 > #seqEditAnchorBtn639{
  margin-left:auto!important;        /* ★ 推挤点：把它和它右边的一切顶到最右 */
  margin-right:6px!important;
}
/* 打包下载（在 .seqedit-btns573 里）紧随其后，贴最右 */
.seqedit-right586 .seqedit-func573 > .seqedit-btns573{
  margin-left:0!important;
  margin-right:0!important;
  flex:0 0 auto!important;
}
