/* ============================================================
   WOJIA OS 组件样式 v4 · 微信风
   只消费 tokens.css 变量；不在此处发明颜色。
   结构：顶栏 / 侧导航 / 页面容器 / 卡片 / 单元格列表 /
        按钮 / 表单 / 步骤条 / 页签 / 网格 / 弹层(toast·dialog)
   V2.46.0 桌面化：仅桌面端使用（手机端=小程序/移动H5，见
   docs/mobile-legacy.md 留档册）。保留的 @media 只有两类：
   桌面档宽度调节（窄栏/单列/降列）与 prefers-reduced-motion。
   ============================================================ */

* { box-sizing: border-box; margin: 0; padding: 0; }
html { -webkit-text-size-adjust: 100%; }
body {
  font-family: var(--font-sans);
  font-size: var(--t-body);
  line-height: var(--lh);
  color: var(--text);
  background: var(--bg);
  min-width: var(--app-min-w); /* 桌面底线：更窄出横向滚动，布局不散架 */
  transition: background .2s ease, color .2s ease;
}
img { display: block; max-width: 100%; }
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }
input, textarea, select { font: inherit; color: var(--text); }
a { color: var(--link); text-decoration: none; }
::selection { background: var(--brand-soft); }

/* ================= 顶栏（批一三一 外壳重构） =================
   三段：左 品牌 + 面包屑 / 右 状态群（数据 · 参谋 · 系统·用户），中间留空给内容呼吸。
   改前的问题：费用 + 天气 + 参谋 挤在同一个长胶囊里——三个性质不同的信息塞一块，
   等于都不重要；中间一大片空着，60px 只放了个品牌名。
   现在：① 面包屑回答「我在哪」（状态栏的本职）② 指标片各自独立成片，性质不同就分开
   ③ 参谋提为品牌色描边按钮（实心留给右下主入口，两个实心绿会打架）。 */
.topbar {
  position: fixed; inset: 0 0 auto 0; z-index: 50;
  min-width: var(--app-min-w); /* 与 body 底线同步：出横滚时顶栏跟着滚，不悬空 */
  height: var(--topbar-h);
  display: flex; align-items: center; gap: 12px;
  padding: 0 16px;
  background: var(--topbar);
  border-bottom: 1px solid var(--line);
  transition: box-shadow .22s var(--ease), border-color .22s var(--ease);
}
/* 滚动后才投影（host.js 加 .scrolled）：静止时不抢内容，滚起来才有「浮起」的层 */
.topbar.scrolled { box-shadow: var(--shadow-1); border-bottom-color: transparent; }

/* 侧栏收放：一个按钮管三档（大屏收窄 / 窄屏临时展开 / 小屏抽屉），行为在 host.js */
.nav-toggle {
  width: 32px; height: 32px; flex: none; border-radius: var(--r-m);
  display: grid; place-items: center; color: var(--text-2);
  transition: background .15s var(--ease), color .15s var(--ease);
}
.nav-toggle:hover { background: var(--hover); color: var(--text); }
.nav-toggle svg { width: 18px; height: 18px; }
.nav-toggle:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }

/* 品牌区（A1 左置主角定稿 09-27 + V2.45.0 更名 WOJIA OS；批一三一 加回方形标记；
   批二二三 mark 换柿蒂风车纹 + 五行金底 #B8860B（与 favicon 生产版统一，李叔 10-09 定）） */
.topbar .brand { display: flex; align-items: center; gap: 10px; flex: none; }
.topbar .brand .mark {
  width: 24px; height: 24px; border-radius: 8px; background: #B8860B;
  display: grid; place-items: center; color: var(--on-brand); flex: none;
}
.topbar .brand .mark svg { width: 23px; height: 23px; } /* 24px 底 × 0.958，满铺回缩一档（李叔：太满了，缩一点点） */
.topbar .brand .bn { font-size: 17px; font-weight: 800; letter-spacing: .6px; line-height: 1; }
.topbar .brand .bs { font-size: var(--t-weak); color: var(--t3); line-height: 1; }

/* 面包屑：当前模块 / 当前页（host.js 随 hash 更新）。
   ★ 可被压缩的元素必须 overflow:hidden + 省略号兜底（批一三八）：
   flex 布局里它是唯一 flex-shrink 项，被压扁时文字若裸溢出会画到右侧指标片上——
   这就是李叔 10-07 截图里「设计」叠在天气上的根因之一。挤压时退化为「设…」，不重叠。 */
.crumbs {
  display: flex; align-items: center; gap: 7px;
  min-width: 0; flex: 0 1 auto; overflow: hidden;
  padding-left: 14px; margin-left: 2px; border-left: 1px solid var(--line);
  font-size: var(--t-aux); color: var(--t3);
}
.crumbs .cm { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; flex: 0 1 auto; }
.crumbs .cs { color: var(--line-strong); flex: none; } /* 纯装饰分隔符，不受文字对比度约束 */
.crumbs .cc { color: var(--text); font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; flex: 0 1 auto; }

.top-actions { display: flex; align-items: center; gap: 4px; flex: none; margin-left: auto; }
.vr { width: 1px; height: 18px; background: var(--line); margin: 0 5px; flex: none; }

/* 指标片：icon + 值，各自独立（原来三个性质不同的信息挤一个胶囊里） */
.metric {
  height: 32px; padding: 0 10px; border-radius: var(--r-pill);
  display: flex; align-items: center; gap: 6px;
  font-size: var(--t-aux); color: var(--text-2);
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.metric:hover { background: var(--hover); color: var(--text); }
.metric svg { width: 15px; height: 15px; color: var(--t3); flex: none; }
.metric b { color: var(--text); font-weight: 600; font-variant-numeric: var(--num); }
.metric.clock { font-family: var(--font-mono); font-size: var(--t-weak); letter-spacing: .02em; }
.metric.clock b { font-weight: 500; }

.icon-btn {
  width: 32px; height: 32px; border-radius: var(--r-m);
  display: grid; place-items: center;
  color: var(--text-2);
  transition: background .15s var(--ease), color .15s var(--ease);
}
.icon-btn:hover { background: var(--hover); color: var(--text); }
.icon-btn svg { width: 18px; height: 18px; }
.icon-btn:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }

/* 状态灯：正常时弱化为灰点（不制造噪音），异常才亮色 */
.health { display: flex; align-items: center; gap: 6px; font-size: var(--t-weak); color: var(--t3); padding: 0 8px; }
.health .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--t3); flex: none; transition: background .2s var(--ease), box-shadow .2s var(--ease); }
.health.ok .dot { background: var(--brand); }
.health.bad .dot { background: var(--danger); box-shadow: 0 0 0 3px var(--danger-soft); }

/* 天气：host.js 只写 #weatherChip 的 textContent，样式落在这 */
.weather-chip { font-size: var(--t-aux); color: var(--text-2); white-space: nowrap; }
.metric b.weather-chip { color: var(--text); font-weight: 600; font-variant-numeric: var(--num); }

/* 悬浮提示（批一三一）：一处托管，避免 CSS 浮层撑出横向滚动条的老坑 —— 行为在 host.js */
#tip {
  position: fixed; z-index: 90; pointer-events: none;
  padding: 6px 9px; border-radius: var(--r-s);
  background: var(--card); border: 1px solid var(--line-strong); box-shadow: var(--shadow-2);
  font-size: var(--t-weak); color: var(--text-2); line-height: 1.5; white-space: nowrap;
  opacity: 0; transform: translateY(3px);
  transition: opacity var(--dur-fast) var(--ease), transform var(--dur-fast) var(--ease);
}
#tip.on { opacity: 1; transform: none; }

/* ---- 顶栏溢出收纳（批一三七立四档，批一三八修空档带）----
   优先级从高到低：汉堡 > 品牌 > 参谋 > 用户 > 天气 > 费用三片 > 面包屑 > 时钟。
   断点三档（视口宽）：
     ≤1180  收时钟 + 收费用三片 → 折进右端 ⋯ 菜单（#mmCost 镜像行，数据由 refreshCostChip 同步写）
            ★ 批一三八：费用从 ≤1080 提到 ≤1180。原四档在 1080–1180 留了空档带：
              时钟收了、费用（约 230px）没收，固定项总和超出视口，把唯一可缩的面包屑
              压扁、文字裸溢出画到天气上——李叔第三张截图的重叠就在这段。
     ≤980   收天气（参谋面板里有完整天气，不丢功能只收入口）；AI 状态灯只留点
     ≤900   收面包屑 + 品牌副标（此档侧栏已进抽屉态，汉堡+logo 即可定位）
   ★ #costChip 必须 !important：refreshCostChip 成功后会写内联 style.display=''，
     内联样式压过媒体查询，不加 !important 窄屏下费用三片会杀不干净。
   ★ 面包屑另有省略号兜底（见 .crumbs）：任何挤压段退化为「设…」，绝不画到邻片上。 */
@media (max-width: 1180px) {
  .metric.clock { display: none; }
  #costChip, #costSep { display: none !important; }
  .mm-cost { display: block; }
}
@media (max-width: 980px) {
  .metric.wx { display: none; }
  .health #healthTxt { display: none; }
}
@media (max-width: 900px) {
  .crumbs { display: none; }
  .topbar .brand .bs { display: none; }
  .topbar { gap: 8px; padding: 0 12px; }
}

/* 费用菜单镜像行：窄屏才显示（≤1080），宽屏隐藏——数据与顶栏三片同源同刷 */
.mm-cost { display: none; padding: 9px 14px 7px; border-bottom: 1px solid var(--line); margin-bottom: 4px; }
.mm-cost .mm-c-t { font-size: var(--t-weak); color: var(--t3); letter-spacing: .08em; margin-bottom: 5px; }
.mm-cost .row { display: flex; align-items: center; justify-content: space-between; font-size: var(--t-aux); color: var(--text-2); padding: 2px 0; }
.mm-cost .row b { font-variant-numeric: var(--num); color: var(--text); font-weight: 600; }

/* ================= 侧边栏（V2.20.0 重构） =================
   结构：.sidebar（flex 列）= .nav（滚动分组）+ .side-foot（关于系统 + 环境徽标）
   交互：组可折叠（状态存 localStorage）；选中态 = 浅绿底 + 左侧 3px 指示条；
   响应式三档：≥1281 完整栏 / 901–1280 图标窄栏 / ≤900 隐藏走底部导航 */
.sidebar {
  position: fixed; z-index: 40;
  top: var(--topbar-h); left: 0; bottom: 0;
  width: var(--nav-w);
  background: var(--topbar);
  border-right: 1px solid var(--line);
  display: flex; flex-direction: column;
  transition: width .24s var(--ease), transform .28s var(--ease-soft);
}
.nav { flex: 1; padding: 16px 12px 12px; }
.nav-group { margin-bottom: 24px; } /* 4 网格：22 → 24 */
.nav-group-t {
  display: flex; align-items: center; width: 100%;
  padding: 8px 14px 6px; text-align: left;
  font-size: var(--t-weak); font-weight: 600; color: var(--t3); letter-spacing: .14em;
  border-radius: var(--r-s);
  transition: color .18s var(--ease);
}
.nav-group-t:hover { color: var(--text-2); }
.nav-group-t .chev { width: 12px; height: 12px; margin-left: auto; color: var(--text-3); transition: transform .22s ease; }
.nav-group.closed .nav-group-t .chev { transform: rotate(-90deg); }
.nav-items { display: flex; flex-direction: column; gap: 2px; margin-top: 2px; }
.nav-group.closed .nav-items { display: none; }
.nav-item {
  position: relative;
  display: flex; align-items: center; gap: 10px;
  width: 100%; text-align: left;
  padding: 9px 12px;
  border-radius: var(--r-m);
  color: var(--text-2); font-size: var(--t-body);
  transition: background var(--dur) ease, color var(--dur) ease;
}
.nav-item svg { width: 19px; height: 19px; flex: none; }
.nav-item:hover { background: var(--hover); color: var(--text); }
.nav-item.active { background: var(--brand-soft); color: var(--brand); font-weight: 600; }
.nav-item.active::before {
  content: ''; position: absolute; left: 2px; top: 50%; transform: translateY(-50%);
  width: 3px; height: 18px; border-radius: 2px; background: var(--brand);
}
/* 底部固定区 */
.side-foot { border-top: 1px solid var(--line); padding: 8px 10px 10px; }

/* ================= 环境徽标（侧栏底部区内） =================
   dev = 琥珀系（扳手图标） / prod = 松绿系（对勾图标），一眼区分。 */
.env-badge { margin-top: 6px; }
.env-badge .eb-card {
  display: flex; align-items: center; gap: 9px;
  padding: 8px 10px;
  border-radius: var(--r-m);
  border: 1px solid transparent;
  transition: background var(--dur) ease, border-color var(--dur) ease;
}
.env-badge[data-env="dev"] .eb-card {
  background: var(--warn-soft);
  border-color: rgba(250, 157, 59, 0.38);
}
.env-badge[data-env="prod"] .eb-card {
  background: var(--brand-soft);
  border-color: rgba(7, 193, 96, 0.30);
}
.env-badge .eb-ico {
  width: 26px; height: 26px; flex: none;
  display: flex; align-items: center; justify-content: center;
  border-radius: 8px; color: var(--on-brand);
}
.env-badge[data-env="dev"] .eb-ico { background: var(--warn); }
.env-badge[data-env="prod"] .eb-ico { background: var(--brand); }
.env-badge .eb-ico svg { width: 15px; height: 15px; }
.env-badge .eb-txt { min-width: 0; line-height: 1.35; }
.env-badge .eb-env { display: block; font-size: var(--t-aux); font-weight: 600; }
.env-badge[data-env="dev"] .eb-env { color: #C2710A; }
.env-badge[data-env="prod"] .eb-env { color: var(--brand); }
[data-theme="dark"] .env-badge[data-env="dev"] .eb-env { color: var(--warn); }
.env-badge .eb-ver {
  display: block;
  font-size: var(--t-weak); color: var(--text-3);
  font-variant-numeric: var(--num);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* 侧边栏三档（expanded / rail / drawer）的宽度与显隐规则已全部搬去 sidenav.css，
   由 body[data-nav] 状态机驱动（批一三一）。这里只留基础结构，不再按媒体查询硬切——
   硬切的毛病：用户没法在大屏主动收起，也没法在窄屏临时展开。 */

/* ================= 页面容器 ================= */
.main {
  margin-left: var(--nav-w);
  padding: calc(var(--topbar-h) + 26px) 30px 64px;
  transition: margin-left .24s var(--ease);
}
.wrap { max-width: var(--wrap); margin: 0 auto; }
.page-head { margin-bottom: 18px; }
.page-title { font-size: var(--t-page); font-weight: 700; }
.page-desc { font-size: var(--t-aux); color: var(--text-2); margin-top: 4px; }

/* ================= 卡片 ================= */
.card {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--r-l);
  padding: var(--pad);
  box-shadow: var(--shadow-1);
}
.card + .card { margin-top: var(--gap); }
.card-t {
  font-size: var(--t-card); font-weight: 600;
  display: flex; align-items: center; gap: 8px;
  margin-bottom: 12px;
}
.card-t .sub { font-size: var(--t-weak); color: var(--text-3); font-weight: 400; }
/* 五步动线徽标（V2.19.0 UI 重组：①场景/日历 ②内容 ③商品 ④AI画面 ⑤预览） */
.card-t .step { display: inline-flex; min-width: 20px; height: 20px; border-radius: 6px; background: var(--brand); color: var(--on-brand); font-size: 11px; font-weight: 800; align-items: center; justify-content: center; padding: 0 5px; margin-right: 2px; }

/* ================= 生成卡（V2.19.1 三态清晰化 · V2.21.1 瑞士排版） =================
   瑞士排版：单一左轴网格、发丝线结构、数字表格化、零断词换行 */
/* 卡头成本签：决策前置——点按钮前就知道花多少 */
.gen-cost { font-size: var(--t-weak); color: var(--gold); font-weight: 700; font-variant-numeric: var(--num); letter-spacing: .3px; }
/* 就绪条：生成前自检（必填/商品/主视觉），待生成态显示，进行中隐藏 */
.gen-ready { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 12px; }
.gr-chip { font-size: var(--t-weak); padding: 4px 12px; border-radius: var(--r-pill); background: var(--bg); color: var(--text-3); white-space: nowrap; }
.gr-chip.ok { color: var(--brand); background: var(--brand-soft); font-weight: 600; }
.gr-chip.bad { color: var(--danger); background: var(--danger-soft); font-weight: 600; }
/* 信息条：规格表三行（左轴 + 发丝分隔，替三格挤压断词） */
.gen-meta { display: flex; flex-direction: column; margin-top: 14px; padding-top: 8px; border-top: 1px solid var(--line); }
.gen-meta span { display: flex; align-items: center; gap: 8px; padding: 6px 0; font-size: 11.5px; color: var(--text-3); line-height: 1.6; white-space: nowrap; }
.gen-meta span + span { border-top: 1px solid var(--line); }
.gen-meta .gm-ic { width: 14px; flex: none; text-align: center; font-size: 10px; font-style: normal; }
/* 完成态导出按钮呼吸强调 */
.btn.primary.ready { box-shadow: 0 4px 16px rgba(7, 193, 96, .42); }
.card-t .right { margin-left: auto; font-size: var(--t-aux); font-weight: 400; }

/* ================= 批四五五 · 主链重构 v2（flow 相位条/确认关卡/探索/保存夹） =================
   语汇纪律：色值全走 tokens（--brand/--pine/--danger 及 soft 档），字号只走 --t-* 档；
   金＝确认/探索（新相位）、松绿＝已保存（业务资产）、灰＝既有环节。 */
.flow-bar { display: flex; align-items: center; gap: 8px; background: var(--card); border: 1px solid var(--line);
  border-radius: var(--r-m); padding: 7px 12px; font-size: var(--t-aux); }
.flow-bar .fb-lb { color: var(--text-3); flex: none; }
.flow-bar .fb-now { font-weight: 700; color: var(--brand); background: var(--brand-soft); padding: 2px 12px;
  border-radius: var(--r-pill); flex: none; }
.flow-bar .fb-round { font-size: var(--t-weak); color: var(--on-gold); background: var(--gold-soft);
  padding: 1px 8px; border-radius: var(--r-s); flex: none; }
.flow-bar .fb-tray { font-size: var(--t-weak); color: var(--pine); background: var(--card-2);
  padding: 1px 8px; border-radius: var(--r-s); flex: none; cursor: pointer; font-weight: 600; }
.flow-bar .fb-path { color: var(--text-3); font-size: var(--t-weak); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* 阶段面板（确认关卡 P1 / 探索 P2 / 已保存 P4）——挂在本轮任务完成区 */
.flow-zone { margin: 10px 0; }
.flow-zone:empty { display: none; }
.flow-confirm { border: 1px solid var(--brand); background: var(--brand-soft); border-radius: var(--r-m); padding: 12px 14px; }
.flow-confirm .fc-q { font-size: var(--t-body); font-weight: 700; color: var(--on-gold); margin-bottom: 9px; }
.flow-confirm .fc-btns, .flow-saved .fc-btns { display: flex; gap: 8px; flex-wrap: wrap; }
.flow-confirm .fc-btns .btn.primary { background: var(--brand); }
.flow-confirm .fc-faults { display: grid; grid-template-columns: repeat(5, 1fr); gap: 6px; margin: 10px 0 4px; }
.flow-confirm .fc-fault { border: 1px solid var(--line-strong); border-radius: var(--r-btn); background: var(--card);
  padding: 9px 4px; text-align: center; cursor: pointer; display: flex; flex-direction: column; align-items: center; gap: 2px; }
.flow-confirm .fc-fault .fi { font-size: 17px; line-height: 1; }
.flow-confirm .fc-fault b { font-size: var(--t-weak); font-weight: 600; color: var(--text); }
.flow-confirm .fc-fault i { font-style: normal; font-size: 10px; color: var(--text-3); }
.flow-confirm .fc-fault:hover { border-color: var(--brand); background: var(--card); }
.flow-confirm .fc-meta, .flow-explore .fe-meta { display: flex; gap: 12px; flex-wrap: wrap; margin-top: 9px;
  font-size: var(--t-weak); color: var(--on-gold); }
.flow-explore { border: 1px solid var(--brand); background: var(--brand-soft); border-radius: var(--r-m); padding: 12px 14px; }
.flow-explore .fe-t { font-size: var(--t-body); font-weight: 700; color: var(--on-gold); margin-bottom: 4px; }
.flow-explore .fe-d { font-size: var(--t-weak); color: var(--on-gold); margin-bottom: 9px; }
.flow-explore .fe-row { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.flow-saved { border: 1px solid var(--pine); border-left: 3px solid var(--pine); background: var(--card-2);
  border-radius: var(--r-m); padding: 12px 14px; }
.flow-saved .fs-t { font-size: var(--t-body); font-weight: 700; color: var(--pine); margin-bottom: 4px; }
.flow-saved .fs-d { font-size: var(--t-weak); color: var(--text-2); margin-bottom: 9px; }
.flow-saved .fc-btns .btn.primary { background: var(--pine); }
.flow-saved .fc-btns .btn.ghost { border-color: var(--pine); color: var(--pine); }
.prod-lock-badge { font-size: var(--t-weak); color: var(--on-gold); background: var(--gold-soft); font-weight: 600;
  padding: 1px 8px; border-radius: var(--r-s); margin-left: 8px; }
/* 保存夹抽屉（P3） */
.flow-tray { position: fixed; inset: 0; z-index: 960; display: none; }
.flow-tray.show { display: block; }
.flow-tray-mask { position: absolute; inset: 0; background: rgba(0, 0, 0, .35); }
.flow-tray-panel { position: absolute; top: 0; right: 0; bottom: 0; width: 340px; max-width: 92vw; background: var(--card);
  box-shadow: -8px 0 32px rgba(0, 0, 0, .18); display: flex; flex-direction: column; }
.flow-tray-hd { display: flex; align-items: center; gap: 8px; padding: 14px 16px; border-bottom: 1px solid var(--line); }
.flow-tray-hd b { font-size: var(--t-body); }
.flow-tray-hd .sub { font-size: var(--t-weak); color: var(--text-3); }
.flow-tray-bd { flex: 1; overflow: auto; padding: 12px 14px; }
.ft-empty { text-align: center; color: var(--text-3); font-size: var(--t-aux); padding: 36px 0; line-height: 1.8; }
.ft-item { border: 1px solid var(--line); border-radius: var(--r-m); padding: 10px 12px; margin-bottom: 10px; }
.ft-item .ft-t { display: flex; align-items: center; gap: 6px; font-size: var(--t-aux); }
.ft-item .ft-r { font-size: var(--t-weak); color: var(--on-gold); background: var(--gold-soft); border-radius: var(--r-s); padding: 0 6px; }
.ft-item .ft-exp { font-size: var(--t-weak); color: var(--pine); margin-left: auto; }
.ft-item .ft-unexp { font-size: var(--t-weak); color: var(--danger); margin-left: auto; }
.ft-item .ft-m { font-size: var(--t-weak); color: var(--text-2); margin-top: 3px; }
.ft-item .ft-op { margin-top: 7px; display: flex; gap: 12px; }
.ft-item .ft-op span { font-size: var(--t-weak); color: var(--text-2); cursor: pointer; }
.ft-item .ft-op span.del { color: var(--text-3); }

/* ================= 单元格列表（cell） ================= */
.cells { background: var(--card); border: 1px solid var(--line); border-radius: var(--r-l); overflow: hidden; box-shadow: var(--shadow-1); }
.cell {
  display: flex; align-items: center; gap: 12px;
  padding: 13px var(--pad);
  border-bottom: 1px solid var(--line);
}
.cell:last-child { border-bottom: 0; }
.cell .cell-main { flex: 1; min-width: 0; }
.cell .cell-t { font-size: var(--t-body); }
.cell .cell-d { font-size: var(--t-weak); color: var(--text-3); margin-top: 2px; }
.cell .cell-ft { color: var(--text-3); font-size: var(--t-aux); flex: none; }
.cell.tap { cursor: pointer; transition: background .15s; }
.cell.tap:hover { background: var(--hover); }

/* ================= 按钮 ================= */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  min-height: 38px; padding: 0 18px;
  border-radius: var(--r-m);
  font-size: var(--t-body); font-weight: 500;
  border: 1px solid var(--line-strong);
  color: var(--text);
  background: var(--card);
  transition: background .15s, border-color .15s, transform .05s;
  user-select: none;
}
.btn:hover { background: var(--hover); }
.btn:active { transform: scale(0.98); }
.btn.primary { background: var(--brand); border-color: var(--brand); color: var(--on-brand); }
.btn.primary:hover { background: var(--brand-press); }
.btn.primary:disabled { background: var(--text-3); border-color: transparent; cursor: not-allowed; }
.btn.danger { color: var(--danger); border-color: var(--danger); }
.btn.ghost { border-color: transparent; color: var(--brand); }
.btn.ghost:hover { background: var(--brand-soft); }
/* 商品清单一键清空（V2.34.1·渲染稿 prod-clear-mock-v1）：红字无框 ghost，破坏性操作
   不与主操作争视觉；hover 浅红底；清单全空 disabled 防误点 */
.btn-clear { border-color: transparent; background: none; color: var(--danger); }
.btn-clear:hover { background: var(--danger-soft); }
.btn-clear:disabled { color: var(--text-3); background: none; cursor: not-allowed; }
/* 商品表底部操作行：添加/整批重出居左，清空居右（破坏性末端惯例） */
.prod-opsrow { display: flex; align-items: center; margin-top: 8px; }
.prod-opsrow .spacer { flex: 1; }
.btn.small { min-height: 30px; padding: 0 12px; font-size: var(--t-aux); border-radius: var(--r-s); }
.btn.block { width: 100%; min-height: var(--h-ctl); font-size: 15px; }

/* ================= 表单 ================= */
.field { margin-bottom: 14px; }
.field > label { display: block; font-size: var(--t-aux); color: var(--text-2); margin-bottom: 6px; }
/* 机制字段双列网格（V2.20.2）：短字段半宽成对，长文本 .mf-full 整行 */
.mf-grid { display: grid; grid-template-columns: 1fr 1fr; column-gap: 12px; }
.mf-grid .mf-full { grid-column: 1 / -1; }
.field > label .req { color: var(--danger); margin-left: 2px; }
.input, .textarea, .select {
  width: 100%;
  background: var(--card-2);
  border: 1px solid var(--line);
  border-radius: var(--r-m);
  padding: 9px 12px;
  outline: none;
  transition: border-color .15s, background .15s;
}
.input:focus, .textarea:focus, .select:focus { border-color: var(--brand); background: var(--card); }
.textarea { min-height: 84px; resize: vertical; }
.field .tip { font-size: var(--t-weak); color: var(--text-3); margin-top: 4px; }
.field .tip.warn { color: var(--danger); }

/* ================= 画面配方卡（V2.46.0 第四模块重构，渲染稿 module4-prompt-mock-v1 拍板） =================
   风格/场景/氛围三行 + 来源徽标（系统抽/手选/规则）+ 单层「换…」+ 换一签；
   锁定态变灰上锁挂「恢复自动配方」（铁律①：手动改提示词后配方不凭空消失） */
.recipe-card { border: 1.5px solid var(--brand); border-radius: 12px; background: linear-gradient(180deg, var(--brand-soft), var(--card)); padding: 4px 14px 8px; margin-bottom: 8px; }
.recipe-card.locked { border-color: var(--line-strong); background: var(--card-2); }
.recipe-card.locked .rc-row, .recipe-card.locked .rc-foot { opacity: .55; }
.rc-head { display: flex; align-items: center; gap: 8px; padding: 8px 0 6px; border-bottom: 1px dashed var(--line); }
.rc-head b { font-size: var(--t-aux); color: var(--brand); }
.recipe-card.locked .rc-head b { color: var(--text-2); }
.rc-head .rc-tip { font-size: var(--t-weak); color: var(--text-3); }
.rc-redraw { margin-left: auto; display: inline-flex; align-items: center; gap: 4px; font-size: var(--t-weak); font-weight: 700; color: var(--brand); border: 1px solid var(--brand); background: var(--card); border-radius: var(--r-pill); padding: 3px 12px; cursor: pointer; }
.rc-redraw:hover { background: var(--brand); color: var(--on-brand); }
.rc-row { display: flex; align-items: center; gap: 10px; padding: 8px 0; border-bottom: 1px dashed var(--line); }
.rc-row:last-of-type { border-bottom: none; }
.rc-k { flex: none; width: 34px; font-size: var(--t-weak); color: var(--text-3); font-weight: 600; }
.rc-v { font-size: var(--t-aux); font-weight: 700; color: var(--text); }
.rc-v small { font-weight: 400; color: var(--text-3); margin-left: 6px; font-size: var(--t-weak); }
.rc-v.rc-off { color: var(--text-3); font-weight: 400; }
.rc-src { flex: none; font-size: 10px; padding: 1px 8px; border-radius: var(--r-pill); font-weight: 700; white-space: nowrap; }
.rc-src.sys { background: var(--brand-soft); color: var(--brand); }
.rc-src.hand { background: var(--warn-soft); color: var(--gold); }
.rc-src.rule { background: var(--card-2); color: var(--text-3); }
.rc-row .rc-x { margin-left: auto; font-size: var(--t-weak); color: var(--brand); font-weight: 600; cursor: pointer; flex: none; padding: 2px 6px; border-radius: 4px; }
.rc-row .rc-x:hover { background: var(--brand-soft); }
.rc-foot { font-size: var(--t-weak); color: var(--text-3); padding-top: 7px; line-height: 1.7; }
.rc-foot b { color: var(--text-2); }
.rc-lock { display: flex; align-items: center; gap: 10px; background: var(--warn-soft); border: 1px solid var(--gold); border-radius: var(--r-btn); padding: 9px 14px; margin-bottom: 8px; font-size: var(--t-weak); color: var(--gold); }
.rc-lock b { font-size: var(--t-aux); }
.rc-unlock { margin-left: auto; background: var(--brand); color: var(--on-brand); font-size: var(--t-weak); font-weight: 700; border-radius: 8px; padding: 6px 14px; cursor: pointer; white-space: nowrap; }
.rc-unlock:hover { background: var(--brand-press); }
/* 氛围手选内联池（配方卡氛围行「换…」展开） */
.rc-moodpool { border-top: 1px dashed var(--line); padding: 8px 0 2px; }
.rc-mp-t { font-size: var(--t-weak); color: var(--text-3); margin-bottom: 6px; }
/* 批四一二：+flex:none / white-space:nowrap —— 在 .rc-row（flex 容器）里芯片会被压缩成折行
   （UI 实拍：「换光/线」两行），氛围池项与档位芯都受益。 */
.rc-mp-i { display: inline-block; font-size: var(--t-weak); padding: 3px 10px; border: 1px solid var(--line); border-radius: var(--r-pill); margin: 0 6px 6px 0; cursor: pointer; background: var(--card); flex: none; white-space: nowrap; }
.rc-mp-i:hover { border-color: var(--brand); color: var(--brand); }
.rc-mp-i.on { border-color: var(--brand); background: var(--brand-soft); color: var(--brand); font-weight: 700; }

/* 状态条统一（V2.46.0：联动/体检/润色三条同款，固定顺序；nodelink-bar 退役） */
.st-bar { display: flex; align-items: flex-start; gap: 7px; border-radius: 8px; padding: 7px 11px; font-size: var(--t-weak); margin-bottom: 6px; line-height: 1.6; }
.st-bar svg { flex: none; margin-top: 2px; opacity: .7; }
.st-bar.st-green { background: var(--brand-soft); color: var(--brand); }
.st-bar.st-gold { background: var(--warn-soft); color: var(--gold); }
.st-bar.st-grey { background: var(--card-2); color: var(--text-3); }
.st-bar .st-x { margin-left: auto; font-weight: 600; cursor: pointer; flex: none; padding: 0 4px; border-radius: 4px; white-space: nowrap; }
.st-bar.st-green .st-x:hover { background: rgba(0,0,0,.07); }
.st-bar.st-grey .st-x { color: var(--brand); }

/* 「全部风格」抽屉（V2.46.0 风格区收拢）：抽屉内风格库 DOM 原样，仅外层折叠 */
.style-drawer { margin-top: 10px; }
.style-drawer-bar { display: flex; align-items: center; gap: 10px; margin-top: 8px; flex-wrap: wrap; }
.lbl-tip { font-weight: 400; color: var(--text-3); font-size: var(--t-weak); margin-left: 6px; }
/* 提示词字数条（接 prompt-kit budget.bodyMax；超线提示自动降级） */
.p-budget { display: inline-flex; align-items: center; gap: 7px; font-size: var(--t-weak); color: var(--text-3); margin-right: 2px; }
.p-budget .pb-bar { width: 72px; height: 5px; border-radius: 3px; background: var(--line); overflow: hidden; display: inline-block; }
.p-budget .pb-bar i { display: block; height: 100%; background: var(--brand); border-radius: 3px; }
.p-budget .pb-bar i.over { background: var(--warn); }

/* 选项片（比例 / 风格等单选） */
.chips { display: flex; flex-wrap: wrap; gap: 8px; }
/* 预览卡版式 chips（09-27 两行头部定稿）：三颗均分整行，380px 列宽下不挤压不断行 */
.pv-chips { margin: 0 0 12px; flex-wrap: nowrap; }
.pv-chips .chip { flex: 1; text-align: center; white-space: nowrap; padding-left: 6px; padding-right: 6px; }
.chip {
  padding: 7px 14px;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-pill);
  font-size: var(--t-aux);
  color: var(--text-2);
  cursor: pointer;
  transition: all .15s;
  user-select: none;
}
.chip:hover { border-color: var(--brand); color: var(--brand); }
.chip.on { background: var(--brand); border-color: var(--brand); color: var(--on-brand); }
.chip .mini { font-size: var(--t-weak); opacity: .75; margin-left: 4px; }

/* ================= 步骤条 ================= */
.steps { display: flex; align-items: center; gap: 0; margin-bottom: 20px; }
.step { display: flex; align-items: center; gap: 8px; color: var(--text-3); font-size: var(--t-aux); }
.step .no {
  width: 24px; height: 24px; border-radius: 50%;
  border: 1px solid var(--line-strong);
  display: grid; place-items: center;
  font-size: var(--t-weak);
  background: var(--card);
}
.step.on { color: var(--brand); font-weight: 600; }
.step.on .no { background: var(--brand); border-color: var(--brand); color: var(--on-brand); }
.step.done { color: var(--text-2); }
.step.done .no { background: var(--brand-soft); border-color: var(--brand); color: var(--brand); }
.step-line { flex: 1; max-width: 72px; height: 1px; background: var(--line-strong); margin: 0 12px; }

.style-row { display: flex; gap: 10px; flex-wrap: wrap; }
.style-item {
  width: 108px; border: 1px solid var(--line); border-radius: var(--r-m);
  overflow: hidden; cursor: pointer; background: var(--card-2);
  transition: border-color .15s, transform .12s;
  display: flex; flex-direction: column;
  min-height: 154px;
}
.style-item:hover { border-color: var(--brand); transform: var(--lift-1); }
.style-item.on { border-color: var(--brand); box-shadow: 0 0 0 1px var(--brand); }
/* 头图区：swatch 渐变打底 + preview 图片叠加；图片加载失败则隐退显示 swatch */
.style-item .sp-top { position: relative; height: 64px; overflow: hidden; background: var(--card-2); }
.style-item .sp-top.no-preview::after {
  content: '暂无示例图';
  position: absolute; inset: 0;
  display: grid; place-items: center;
  font-size: 11px; color: rgba(255,255,255,.9);
  text-shadow: 0 1px 2px rgba(0,0,0,.35);
  background: rgba(0,0,0,.18);
  pointer-events: none;
}
.style-item .sp-top .sw { position: absolute; inset: 0; height: 100%; display: block; }
.style-item .sp-preview { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; }
/* 图片加载前骨架闪烁 */
.style-item .sp-preview:not([src]) { opacity: 0; }
.style-item .sp-preview[src=""] { opacity: 0; }
.style-item .sp-preview:not([data-loaded]) { background: linear-gradient(90deg, var(--card-2) 25%, var(--card) 50%, var(--card-2) 75%); background-size: 200% 100%; animation: spSkeleton 1.2s infinite; }
@keyframes spSkeleton { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }
.style-item .sp-tags { display: flex; gap: 4px; padding: 6px 8px 0; min-height: 20px; white-space: nowrap; overflow: hidden; }
.style-item .sp-tags:empty { display: none; }
.sp-tag {
  display: inline-flex; align-items: center; font-size: 10px; color: var(--text-2);
  background: var(--card); border: 1px solid var(--line); border-radius: 3px;
  padding: 1px 5px; line-height: 1.3; max-width: 100%;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* 批三〇八（李叔 10-10 截图令「名字截断」）：卡名一行改两行——-webkit-line-clamp:2，
   「剪贴簿拼贴风」「高级电商静物」这类长名完整露出。min-height 钉两行高：单行名与
   两行名的卡片底边对齐（网格里高度不齐观感更差）。⚠ line-clamp 截断依然存在——
   批一七五的教训不变：角标 .lo-badge 依然绝不能进 .sn（进了一样被吞）。 */
.style-item .sn { font-size: 14px; font-weight: 700; color: var(--text); padding: 6px 8px 2px; text-align: center; letter-spacing: .3px; line-height: 1.35; min-height: 37.8px; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.style-item .ss { font-size: var(--t-aux); color: var(--text-2); padding: 2px 8px 8px; text-align: center; line-height: 1.45; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; min-height: 2.9em; }
.style-item .rec-tag { display: inline-block; background: var(--gold); color: var(--on-brand); font-size: 10px; border-radius: 3px; padding: 0 4px; margin-left: 4px; vertical-align: 1px; }
/* V2.41.7 仅排版层风格（卡标 genOff，靠文字成立生图出不来）：灰化+禁选+角标，知识仍走排版层。
   批一七五定谳（李叔 10-07 截图实证）：角标原先挂在名称行尾（.lo-tag 内联在 .sn 里），
   而 .sn 是 nowrap + text-overflow:ellipsis —— 名称一长，角标就被截断吞掉，卡面看着
   跟正常卡一模一样，只有点了才知道选不了。故角标移出名称行，改挂卡片左上角浮标
   （.style-item 自带 position:relative），永不参与名称行的截断计算。
   整卡也不再整体降不透明度：opacity 会连角标一起拖淡，等于「标了又没标」；
   改为缩略图去色 + 名称文字降权，角标本身保持全清晰度。 */
.style-item.layout-only { cursor: not-allowed; border-style: dashed; }
.style-item.layout-only .sp-top { filter: grayscale(1) contrast(.92); opacity: .68; }
.style-item.layout-only .sn { color: var(--text-2); }
.style-item.layout-only:hover { border-color: var(--line); transform: none; }
.style-item .lo-badge {
  position: absolute; left: 4px; top: 4px; z-index: 2;
  display: inline-block; font-size: 10px; font-weight: 700; line-height: 1.5;
  letter-spacing: .2px; padding: 1px 5px; border-radius: 3px;
  background: var(--card); color: var(--text-2); border: 1px solid var(--line);
  box-shadow: 0 1px 3px rgba(0, 0, 0, .28);
  white-space: nowrap; pointer-events: none;
}

/* 知识库推荐区（V2.40.2）：模块→场景→意图/商品 → 风格，附理由与冲突/风险提示。
   只在引擎算出结果时渲染（无结果整块消失，退回原一行说明，不留半截 UI）。 */
.rec-zone { border: 1px solid var(--line); border-radius: var(--r-m); background: var(--card-2); padding: 10px 12px; margin-bottom: 10px; }
.rec-basis { font-size: var(--t-weak); color: var(--text-2); margin-bottom: 8px; }
.rec-basis b { color: var(--text); font-weight: 600; }
.rec-cards { display: flex; gap: 10px; flex-wrap: wrap; }
/* 批三〇八卡面统一（李叔 10-10 令「重构这个页面模块」）：推荐卡与库卡同构（图+名+右上ⓘ），
   只留四等分宽度一条；min-height:180 / sp-top:90 / sn 特例全撤——tags 行与推荐语行已不渲染
   （推荐语进 title 悬停 + 详情浮层），卡面回归基础 .style-item 样式，与下方库卡同一套语言。 */
.rec-cards .style-item { width: calc(25% - 7.5px); }
.rec-warn { margin-top: 8px; font-size: var(--t-aux); line-height: 1.5; border-radius: var(--r-s); padding: 6px 10px; }
.rec-warn.risk { background: rgba(201,162,39,.12); color: var(--on-gold); }
.rec-warn.conflict { background: var(--danger-soft); color: var(--danger); }

/* 风格分组（STYLE_GROUPS 五组分类；A 版布局：每组一行、卡片拉伸铺满） */
.style-group { width: 100%; }
.style-group + .style-group { margin-top: 12px; }
.sg-head { display: flex; align-items: baseline; gap: 8px; margin: 2px 0 8px; }
.sg-name { font-size: var(--t-body); font-weight: 700; color: var(--text); }
.sg-desc { font-size: var(--t-weak); color: var(--text-2); }
.sg-row { display: flex; gap: 10px; flex-wrap: wrap; }
.sg-row .style-item { flex: 1 1 0; width: auto; min-width: 0; min-height: 162px; }
.sg-row .style-item .sp-top { height: 72px; }
.sg-row .style-item .ss { -webkit-line-clamp: 1; min-height: 1.45em; }
/* V2.41.6 扩展风格折叠区：58 张卡挤一行会窄到看不清，必须换行 + 固定栅格宽度 */
.sg-row.sg-more { flex-wrap: wrap; margin-top: 8px; }
.sg-row.sg-more .style-item { flex: 0 0 calc(20% - 8px); min-width: 96px; }
/* 响应式：小屏保证卡片最小可点，中屏 4 列，大屏保持弹性 */
@media (max-width: 820px) {
  .sg-row .style-item { flex: 0 0 calc(25% - 8px); min-width: 88px; }
  .sg-row.sg-more .style-item { flex: 0 0 calc(25% - 8px); }
  .style-row .style-item { width: calc(25% - 8px); }
}
@media (max-width: 560px) {
  .sg-row .style-item { flex: 0 0 calc(33.333% - 7px); }
  .sg-row.sg-more .style-item { flex: 0 0 calc(33.333% - 7px); }
  .style-row .style-item { width: calc(33.333% - 7px); }
  .rec-cards .style-item { width: calc(50% - 5px); }
}
.style-more-bar { display: flex; align-items: center; gap: 10px; margin-top: 12px; flex-wrap: wrap; }
.btn-more {
  font-size: var(--t-weak); color: var(--brand); background: var(--card);
  border: 1px solid var(--brand); border-radius: var(--r-pill); padding: 5px 14px; cursor: pointer;
}
.btn-more:hover { background: var(--brand); color: var(--on-brand); }
.more-tip { font-size: var(--t-weak); color: var(--text-2); }
.style-item { position: relative; }
.style-item .sinfo {
  position: absolute; top: 4px; right: 4px; width: 18px; height: 18px;
  border-radius: 50%; background: rgba(0,0,0,.45); color: var(--on-brand);
  font: italic 700 11px/18px Georgia, serif; text-align: center; cursor: pointer;
}
.style-item .sinfo:hover { background: var(--brand); }

/* 风格详情弹层（批三〇八双列重构，李叔令 3）：左列视觉 / 右列知识。
   李叔 10-10 两轮批注：①「太窄了加宽50%」②「太平了，没有重点，容器也太大了，缩窄30%」。
   🔴 根因（10-10 探针实测抓出）：写作 `.style-dialog` 时宽度**从未生效过**——
     与 .dialog（第 1059 行 width:min(480px,92vw)）同为单类、特异性平手，
     CSS 源序后者胜 → 实际一直按 .dialog 的 min(480px,92vw) 渲染（实测 480px）。
     故必须带 .dialog 前缀抬特异性（0,2,0 > 0,1,0），与源序无关。
   宽度轨迹：480（实际）→ 1140（+50%）→ 798（-30%，=1140×0.7）。
   ⚠ 右列 minmax(0,1fr)：长文本顶宽列的隐含下限是 minmax(auto,1fr)，
   写裸 1fr 会被长段顶爆裁到画布外（CSS grid 铁律，电商长图批三〇五同款教训）。 */
.dialog.style-dialog { width: min(798px, 96vw); }
.style-dialog .d-b { max-height: 68vh; overflow-y: auto; text-align: left; }
.sd-cols { display: grid; grid-template-columns: 250px minmax(0,1fr); align-items: start; }
.sd-left { padding: 12px 14px 14px; border-right: 1px solid var(--line); }
.sd-right { padding: 12px 16px 14px; min-width: 0; }
.sd-preview { position: relative; height: 170px; border-radius: var(--r-btn); border: 1px solid var(--line); overflow: hidden; background: var(--card-2); }
.sd-preview .sd-sw { position: absolute; inset: 0; height: 100%; display: block; }
.sd-preview-img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; }
.sd-tags { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 10px; }
.sd-group {
  display: inline-block; margin-left: 8px; font-size: var(--t-weak); font-weight: 400;
  color: var(--brand); background: rgba(30,122,70,.1); border-radius: 4px;
  padding: 1px 6px; vertical-align: 2px;
}
.sd-short { margin: 8px 0 2px; color: var(--text-2); font-size: var(--t-aux); }
.sd-sec { margin-top: 12px; }
/* 右列分层（批三一四：原五段同字号/同色/同 12px 等距=一条道平铺，李叔「太平了，没有重点」）
   四档：①推荐段=品牌色竖条卡 ②核心特征=主段 16px/600 ③细节四段=弱段 12.5px/--text-2 ④KB 准则=最弱+上分隔线。
   竖条用 inset box-shadow 不用 border-left：圆角不被破。 */
.sd-sec.sd-rec { margin-top: 0; background: var(--card-2); border-radius: var(--r-s); padding: 10px 10px 8px; box-shadow: inset 3px 0 0 var(--brand); }
.sd-sec.sd-rec .sd-v { font-size: var(--t-body); font-weight: 500; }
.sd-sec.sd-lead { margin-top: 16px; }
.sd-sec.sd-lead .sd-k { font-size: var(--t-body); }
.sd-sec.sd-lead .sd-v { font-size: var(--t-card); font-weight: 600; line-height: 1.7; }
.sd-sec.sd-sub { margin-top: 10px; }
.sd-sec.sd-sub .sd-v { font-size: var(--t-aux); color: var(--text-2); line-height: 1.6; }
.sd-sec.sd-kb { margin-top: 14px; padding-top: 10px; border-top: 1px solid var(--line); }
.sd-sec.sd-kb .sd-v { font-size: var(--t-aux); color: var(--text-2); line-height: 1.6; }
.sd-k { font-size: var(--t-aux); font-weight: 700; color: var(--brand); margin-bottom: 3px; }
.sd-v { font-size: var(--t-body); color: var(--text); line-height: 1.65; }
/* 相似风格（批三〇八）：原 flex 横排 96px 色条小卡 → 2×2 带预览图卡，名字不再截断 */
.sd-sim-row { display: grid; grid-template-columns: 1fr 1fr; gap: 7px; }
.sd-sim {
  border: 1px solid var(--line); border-radius: var(--r-s);
  overflow: hidden; cursor: pointer; background: var(--card-2);
  transition: border-color .15s;
}
.sd-sim:hover { border-color: var(--brand); }
.sd-sim-ph { position: relative; height: 40px; display: block; }
.sd-sim-sw { position: absolute; inset: 0; height: 100%; display: block; }
.sd-sim-img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; }
.sd-sim-name { font-size: 12px; font-weight: 600; color: var(--text); padding: 5px 6px; text-align: center; display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sd-sim-tip { margin-top: 7px; font-size: var(--t-weak); color: var(--text-2); }

/* ================= 页签 ================= */
.tabs { display: flex; gap: 4px; border-bottom: 1px solid var(--line); margin-bottom: 16px; }
.tab {
  padding: 9px 14px; font-size: var(--t-body); color: var(--text-2);
  border-bottom: 2px solid transparent; margin-bottom: -1px;
  cursor: pointer; transition: color .15s, border-color .15s;
}
.tab:hover { color: var(--text); }
.tab.on { color: var(--brand); border-bottom-color: var(--brand); font-weight: 600; }

/* ================= 图库网格 ================= */
.grid {
  display: grid; gap: 14px;
  grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
}
.g-item {
  background: var(--card); border: 1px solid var(--line);
  border-radius: var(--r-l); overflow: hidden;
  box-shadow: var(--shadow-1);
  transition: box-shadow .15s, transform .15s;
}
.g-item:hover { box-shadow: var(--shadow-2); transform: var(--lift-2); }
.g-item .g-img { aspect-ratio: 4/5; background: var(--card-2); cursor: zoom-in; width: 100%; object-fit: cover; }
.g-item .g-info { padding: 10px 12px; }
.g-item .g-t { font-size: var(--t-aux); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.g-item .g-d { font-size: var(--t-weak); color: var(--text-3); margin-top: 2px; }
.g-item .g-ops { display: flex; gap: 8px; padding: 0 12px 12px; }

.empty {
  text-align: center; color: var(--text-3);
  padding: 56px 0; font-size: var(--t-aux);
}
.empty .big { font-size: 30px; margin-bottom: 10px; }

/* ================= 海报预览 ================= */
/* 商品图「AI 绘制中」占位扫光（批三〇一，李叔「增加交互进程」）：
   仅预览态消费（studio.gen.running 时挂类）；导出链路生成已结束回落静态「图待补」，
   ::after 伪元素不进导出内联白名单——印出去的画面恒静。 */
.prod-drawing { position: relative; overflow: hidden; }
.prod-drawing::after {
  content: ''; position: absolute; top: 0; right: 0; bottom: 0; left: 0;
  background: linear-gradient(100deg, transparent 30%, rgba(255,255,255,.72) 50%, transparent 70%);
  animation: prodShine 1.4s linear infinite;
}
@keyframes prodShine { 0% { transform: translateX(-100%); } 100% { transform: translateX(100%); } }
@media (prefers-reduced-motion: reduce) { .prod-drawing::after { animation: none; } }

/* ================= V3 做海报工作台（批二九二重构，李叔 10-10 确认原型「落地」） =================
   三栏：左=场景导航（原首屏类型大卡降为常驻侧栏）/ 中=三问卡片流 / 右=预览台合一。
   旧 .studio 两栏、.type-tabs、.scene-grid/.scene-card、.sticky-col 已删（无隐藏残留）。 */
.studio-v3 { display: grid; grid-template-columns: 196px minmax(0,1fr) 400px; gap: 14px; align-items: start; }
.studio-v3 .snav { background: var(--card); border: 1px solid var(--line); border-radius: var(--r-card); padding: 10px; position: sticky; top: calc(var(--topbar-h) + 12px); }
.studio-v3 .snav-t { font-size: var(--t-weak); font-weight: 700; letter-spacing: 2px; color: var(--text-3); padding: 6px 10px 4px; }
.studio-v3 .snav-g { font-size: var(--t-weak); color: var(--text-3); opacity: .8; padding: 10px 10px 4px; margin-top: 6px; border-top: 1px dashed var(--line); }
.studio-v3 .snav-g:first-of-type { border-top: 0; margin-top: 0; }
.studio-v3 .snav-it { display: flex; align-items: center; gap: 9px; padding: 8px 10px; border-radius: 9px; color: var(--text-2); cursor: pointer; }
.studio-v3 .snav-it:hover { background: var(--hover); }
.studio-v3 .snav-it.on { background: var(--brand-soft); color: var(--brand); font-weight: 700; }
.studio-v3 .snav-it .ic { flex: 0 0 28px; width: 28px; height: 28px; border-radius: 8px; background: var(--card-2); display: grid; place-items: center; color: var(--text-2); }
.studio-v3 .snav-it.on .ic { background: var(--brand); color: var(--on-brand); }
.studio-v3 .snav-it .tx { min-width: 0; }
.studio-v3 .snav-it .tx b { display: block; font-size: var(--t-body); font-weight: inherit; }
.studio-v3 .snav-it .tx i { display: block; font-style: normal; font-size: var(--t-weak); color: var(--text-3); margin-top: 1px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.studio-v3 .snav-it.on .tx i { color: var(--brand); opacity: .65; }
.studio-v3 .snav-foot { margin-top: 8px; border-top: 1px solid var(--line); padding-top: 8px; }
/* 一键重置（批三一八，李叔红框定点=左栏底部「历史海报」下方；批三一五的视口左下角
   fixed 位置作废）。文案「重置海报」；**常驻显示**（批三一五~三一七的「出第一张海报才
   出现」隐藏逻辑已随批三一八删净，CSS 里不许再加 display:none）。显眼=品牌金实底白字。 */
.studio-v3 .reset-fab {
  margin-top: 8px; width: 100%; justify-content: center;
  display: flex; align-items: center; gap: 6px;
  background: var(--brand); color: #fff; border: none; border-radius: var(--r-pill);
  padding: 10px 0; font-size: 13px; font-weight: 600; cursor: pointer;
  box-shadow: 0 4px 14px rgba(0,0,0,.14);
  transition: filter .2s var(--ease), transform .2s var(--ease), box-shadow .2s var(--ease);
}
.reset-fab:hover { filter: brightness(1.07); transform: translateY(-1px); box-shadow: 0 10px 28px rgba(0,0,0,.26); }
/* 李叔 10-10 批注「不能滑动了，卡着很难受」：右栏合一卡后高度常超视口——sticky 过高
   会把卡底（导出按钮）钉在视口外，滚到页面最底才「出来」。改为 rail 自身限高内滚：
   任何视口下整卡可达，内滚不劫持页面滚动。 */
.studio-v3 .rail {
  position: sticky; top: calc(var(--topbar-h) + 12px);
  max-height: calc(100vh - var(--topbar-h) - 24px);
  overflow-y: auto; /* 不设 overscroll-behavior:contain——内滚到底须自然链回页面滚动（contain=新的卡住） */
  scrollbar-width: thin; scrollbar-color: var(--line-strong) transparent;
}
.studio-v3 .stagecard { padding: 14px 16px 16px; }
.studio-v3 .stage-tt { font-size: var(--t-card); font-weight: 700; display: flex; align-items: center; gap: 8px; }
.studio-v3 .stage-live { font-size: var(--t-weak); color: var(--brand); background: var(--brand-soft); border-radius: 5px; padding: 2px 7px; font-weight: 600; }
/* 批四二三 · 预览台工具键（李叔 10-13 截图批注「优化icon，优化按钮层级」）
   病根两条：① icon 三套语言混用（底部按钮 SVG / 查看大图 emoji 🔍 / 重置海报字符 ⟲）
   ② 层级倒挂——「查看大图」是工具级功能却整行灰框撑满，视觉重量压过「重新生成 ¥0.20」。
   修法：工具键以 ghost 形态挂标题行右侧（放大的是预览，位置贴功能），无边框无底色，
   hover 才出浅金底——视觉读起来是「链接」不是「按钮」，层级回到工具级；
   icon 全部收进 host.js ICON 家族（SVG 线宽 1.7，跨机不歧形）。颜色一律走令牌。 */
.studio-v3 .stage-tools { margin-left: auto; display: flex; align-items: center; gap: 8px; }
.studio-v3 .tool-ghost {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: var(--t-weak); color: var(--text-2); font-weight: 400;
  padding: 4px 8px; border-radius: 8px; cursor: pointer;
  transition: background .15s ease, color .15s ease;
}
.studio-v3 .tool-ghost:hover { background: var(--brand-soft); color: var(--brand-strong); }
/* 三问卡折叠：卡头点一下收起/展开；卡头内的按钮与 mini-tabs 不触发 */
.studio-v3 .card-t .fold-arw { margin-left: auto; font-size: var(--t-weak); color: var(--text-3); cursor: pointer; flex: 0 0 auto; }
.studio-v3 .card.folded .bd { display: none; }
/* 李叔 10-10 三轮批注定宽口径：①「加宽操作页面」→ 破格撑满（做过头）②「没必要满屏」
   → 回 1080 内三栏（中栏 456）③「中间操作区域再大 40%」→ **定宽 1264 居中**：
   中栏 456→640（+40%），左右栏不动；仍不满屏——两侧对称溢出 .wrap 且随 .main 居中，
   不随窗口无限拉宽。宽度再调只动本段，不碰全站 --wrap。 */
@media (min-width: 1640px) {
  .studio-page.studio-v3 {
    width: 1264px;                              /* 196 + 14 + 640 + 14 + 400 */
    margin-left: calc((100% - 1264px) / 2);     /* 在 .wrap 内对称溢出 = 对 .main 居中 */
  }
}
@media (max-width: 1380px) { .studio-v3 { grid-template-columns: 180px minmax(0,1fr) 360px; } }
@media (max-width: 1180px) {
  .studio-v3 { grid-template-columns: 1fr; }
  .studio-v3 .snav, .studio-v3 .rail { position: static; }
}

.poster-stage {
  background: var(--card-2); border: 1px solid var(--line); border-radius: var(--r-l);
  padding: 18px; display: grid; place-items: center; min-height: 420px;
}
.poster {
  width: 320px; border-radius: var(--r-btn); overflow: hidden;
  box-shadow: var(--shadow-3); background: var(--white);
  position: relative;
  /* cqw 容器：融合版头块字号按 导出px/1080 等比缩放，预览=导出严格一致 */
  container-type: inline-size;
}
.poster .p-img { width: 100%; aspect-ratio: 4/5; object-fit: cover; background: #EDEAE4; }
.poster .p-bar {
  background: var(--poster-pine); color: var(--on-brand);
  padding: 10px 14px 12px;
}
.poster .p-greet { font-size: 17px; font-weight: 700; letter-spacing: 1px; }
.poster .p-wish { font-size: 11.5px; opacity: .92; margin-top: 3px; }
.poster .p-foot {
  display: flex; justify-content: space-between; align-items: center;
  font-size: 10.5px; opacity: .85; margin-top: 8px;
  border-top: 1px solid rgba(255,255,255,.28); padding-top: 7px;
}
.poster .p-ph {
  aspect-ratio: 4/5; display: grid; place-items: center;
  color: var(--text-3); font-size: var(--t-aux);
  background:
    repeating-linear-gradient(45deg, rgba(0,0,0,.02) 0 12px, transparent 12px 24px),
    var(--card-2);
  text-align: center; padding: 20px;
}

/* 经典版·全面屏：1080×2340 比例锁定，画面区自适应填满，色条贴底（与导出一致） */
.poster.classic-full { aspect-ratio: 1080/2340; display: flex; flex-direction: column; }
.poster.classic-full .p-vimg { flex: 1; min-height: 0; position: relative; }
.poster.classic-full .p-vimg .p-img { width: 100%; height: 100%; aspect-ratio: auto; object-fit: cover; display: block; }
.poster.classic-full .p-ph { flex: 1; aspect-ratio: auto; }
.poster.classic-full .p-bar { flex: none; padding: 12px 16px 17px; }
/* 经典版色条四行结构：眉行（品牌·类型+日期）→ 大标题 → 金条副题 → slogan+logo */
.poster.classic-full .pb-top { display: flex; justify-content: space-between; align-items: center; font-size: 10px; font-weight: 600; letter-spacing: 1.5px; opacity: .85; }
.poster.classic-full .p-greet { font-size: 23px; font-weight: 800; letter-spacing: 1px; line-height: 1.2; margin-top: 5px; }
.poster.classic-full .p-wish { display: flex; align-items: center; gap: 8px; font-size: 11.5px; opacity: .95; margin-top: 5px; }
.poster.classic-full .p-wish .pb-bar { width: 22px; height: 3px; background: var(--poster-gold, #C9A227); border-radius: 2px; flex: none; }
.poster.classic-full .p-foot { font-size: 10px; margin-top: 8px; }
.poster.classic-full .pb-logo { height: 13px; width: auto; display: block; }

/* AI 生成进度 → 见 v6 进度条（.gf-*） */
@keyframes pulse { from { opacity: .4 } to { opacity: 1 } }

/* 提示词卡 */
.prompt-box {
  background: var(--card-2); border: 1px solid var(--line);
  border-radius: var(--r-m); padding: 12px 14px;
  font-size: var(--t-aux); color: var(--text-2);
  white-space: pre-wrap; word-break: break-word;
  max-height: 220px; overflow-y: auto;
}

/* 合规提示 */
.comply { display: flex; gap: 8px; align-items: flex-start; font-size: var(--t-aux); border-radius: var(--r-m); padding: 10px 12px; }
.comply.ok { background: var(--brand-soft); color: var(--brand); }
.comply.bad { background: var(--danger-soft); color: var(--danger); }
/* 质检面板标签页（V2.46.3）：合规 / 知识体检 / 排版要点三合一，默认只展开合规 */
.qc-tabs { display: inline-flex; background: var(--card-2); border: 1px solid var(--line); border-radius: 8px; padding: 2px; gap: 2px; margin-bottom: 6px; }
.qc-tab { position: relative; padding: 5px 12px; border-radius: 6px; font-size: var(--t-aux); color: var(--text-2); cursor: pointer; user-select: none; }
.qc-tab.on { background: var(--card); color: var(--brand); font-weight: 600; box-shadow: var(--shadow-1); }
.qc-tab:not(.on):hover { color: var(--text); background: var(--hover); }
.qc-dot { display: inline-block; width: 6px; height: 6px; border-radius: 50%; background: var(--danger); margin-left: 5px; vertical-align: 1px; }
.qc-body { margin-top: 2px; }

/* ================= 知识库 KB v2（五段体系 + 进化引擎） ================= */
/* 顶栏：搜索 + 扫描起草 */
/* ---- V2 渲染稿场景一：体系总览（五段流 + 进化引擎三环） ---- */
.fw-wrap { margin-bottom: 14px; }
.fw-flow { display: flex; gap: 10px; align-items: stretch; }
.fw-seg { flex: 1; background: var(--card); border-radius: var(--r-btn); box-shadow: var(--shadow-1); border-top: 4px solid var(--brand); padding: 12px 12px 10px; position: relative; }
.fw-seg::after { content: "›"; position: absolute; right: -10px; top: 38%; font-size: 20px; color: #bbb; z-index: 2; }
.fw-seg:last-child::after { display: none; }
/* 批一二〇：段色带松绿退场，s2 用矩阵热格同族深绿，s4 走令牌金 */
.fw-seg.s1 { border-top-color: var(--on-gold); } .fw-seg.s2 { border-top-color: #0a7a3d; }
.fw-seg.s3 { border-top-color: var(--brand); } .fw-seg.s4 { border-top-color: var(--gold); } .fw-seg.s5 { border-top-color: var(--link-wechat); }
.fw-no { font-size: 11px; color: #aaa; letter-spacing: 1px; }
.fw-name { font-size: 16px; font-weight: 700; margin: 2px 0 1px; }
.fw-q { font-size: 12px; color: #999; margin-bottom: 8px; }
.fw-layer { font-size: 12px; color: #444; padding: 3px 0; display: flex; justify-content: space-between; }
.fw-layer i { font-style: normal; color: var(--on-brand); background: #c8c9cc; border-radius: 8px; font-size: 10px; min-width: 16px; text-align: center; padding: 1px 4px; height: 16px; line-height: 14px; margin-left: 6px; }
.fw-call { margin-top: 8px; font-size: 11px; color: #07C160; background: #e8f9f0; border-radius: 5px; padding: 4px 7px; line-height: 1.5; }
.fw-call.gray { color: var(--on-gold); background: #faf3e0; }
.fw-call.blue { color: var(--link-wechat); background: var(--link-soft); }
/* 批一二〇：进化引擎介绍带改控制台深色舱（--fx-ink），主色统一后不再深绿渐变 */
.evo-band { margin-top: 14px; background: var(--fx-ink); border-radius: 12px; padding: 16px 18px; color: var(--on-brand); }
.evo-t { font-size: 14px; font-weight: 700; display: flex; align-items: center; gap: 8px; }
.evo-t .evo-pulse { width: 9px; height: 9px; border-radius: 50%; background: #4ade80; box-shadow: 0 0 8px #4ade80; animation: kb2-pulse 1.6s infinite; }
.evo-rings { display: flex; gap: 12px; margin-top: 12px; }
.evo-ring { flex: 1; background: rgba(255,255,255,.09); border: 1px solid rgba(255,255,255,.15); border-radius: var(--r-btn); padding: 11px 13px; position: relative; }
.evo-ring::after { content: "→"; position: absolute; right: -14px; top: 40%; color: rgba(255,255,255,.5); font-size: 15px; }
.evo-ring:last-child::after { content: "↺"; right: -15px; }
.evo-ring h4 { font-size: 13px; font-weight: 700; color: #a7f3c9; }
.evo-ring ul { margin-top: 6px; font-size: 11.5px; line-height: 1.8; color: rgba(255,255,255,.85); list-style: none; padding: 0; }
.evo-ring ul li::before { content: "· "; color: #4ade80; font-weight: 700; }
@media (max-width: 1100px) { .fw-flow, .evo-rings { flex-direction: column; } .fw-seg::after, .evo-ring::after { display: none; } }
/* ↑ ≤1100 为桌面档内调节（横排流程图竖排），保留 */

/* ── 主体：左树（去卡片化，融入底色）+ 右内容流 ── */
.kb2-main { display: flex; gap: 0; align-items: flex-start; }
.kb2-content { flex: 1; min-width: 0; padding-left: 28px; }
.kb2-tree { width: 232px; flex: none; position: sticky; top: 12px; max-height: calc(100vh - 140px); overflow-y: auto; padding: 4px 0; }
.kb2-sec { padding: 9px 14px 4px; font-size: 11.5px; color: var(--text-3); display: flex; justify-content: space-between; }
.kb2-sec b { color: var(--text); font-size: 12.5px; font-weight: 700; }
.kb2-node { position: relative; display: flex; align-items: center; justify-content: space-between; padding: 7px 12px 7px 20px; font-size: var(--t-aux); color: var(--text-2); cursor: pointer; border-radius: var(--r-s); transition: background var(--dur-fast) cubic-bezier(.4,0,.2,1); }
.kb2-node:hover { background: var(--hover); }
.kb2-node.on { background: var(--brand-soft); color: var(--brand); font-weight: 650; }
.kb2-node.on::before { content: ""; position: absolute; left: 4px; top: 8px; bottom: 8px; width: 3px; border-radius: 2px; background: var(--brand); }
.kb2-node .cnt { font-size: 11px; color: var(--text-3); font-variant-numeric: var(--num); }
.kb2-node.on .cnt { color: var(--brand); }
.kb2-dot { display: inline-block; width: 6px; height: 6px; border-radius: 50%; background: var(--gold); margin-left: 5px; vertical-align: 1px; }
/* 进化中心入口：一行平色绿条（保留锚点；圆角与树语言统一） */
.kb2-evo { margin: 2px 0 8px; background: var(--brand); color: var(--on-brand); border-radius: var(--r-m); padding: 10px 12px; font-size: var(--t-aux); cursor: pointer; display: flex; align-items: center; justify-content: space-between; gap: 8px; transition: background var(--dur) cubic-bezier(.4,0,.2,1); }
.kb2-evo:hover { background: var(--brand-strong, #17633A); }
.kb2-evo b { display: flex; align-items: center; gap: 6px; font-size: var(--t-aux); }
.kb2-evo .kb2-evo-n { font-size: 11px; color: rgba(255,255,255,.9); flex: none; }
.kb2-pulse { width: 7px; height: 7px; border-radius: 50%; background: #4ade80; box-shadow: 0 0 6px #4ade80; animation: kb2-pulse 1.6s infinite; }
@keyframes kb2-pulse { 50% { opacity: .4; } }
/* ── 搜索框（挪进分段行，聚焦绿晕）── */
.kb2-bar { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; }
.kb2-search { position: relative; width: 260px; display: flex; align-items: center; }
.kb2-search svg { position: absolute; left: 10px; opacity: .4; pointer-events: none; }
.kb2-search input { width: 100%; height: 30px; border: 1px solid var(--line); border-radius: var(--r-m); background: var(--card); padding: 0 10px 0 30px; font-size: var(--t-aux); color: var(--text); outline: none; transition: border-color var(--dur), box-shadow var(--dur); }
.kb2-search input:focus { border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-soft); }

/* ================= 批一一八 · 知识库 Awwwards 级重构（李叔 10-07 派单） =================
   设计语言：底色米白纸感（--bg-kb）/ 卡面纯白 / 绿=生命与选中语义 / 字阶五级 /
   动效统一 160ms cubic-bezier(.4,0,.2,1)；类名与行为锚点（kbQ/kb2-hcell/kb2-segi）不变。
   ── 卡片：标线式折叠行 → 文档式展开（呼吸感与层级）── */
.kb2-card { border-radius: var(--r-l); background: var(--card); border: 1px solid var(--line); padding: 0; transition: box-shadow var(--dur) cubic-bezier(.4,0,.2,1), transform var(--dur) cubic-bezier(.4,0,.2,1), border-color var(--dur); overflow: hidden; }
.kb2-card.fold { cursor: pointer; padding: 14px 18px; }
.kb2-card.fold:hover { box-shadow: 0 6px 20px rgba(38,34,28,.08); transform: var(--lift-1); border-color: var(--line-strong); }
.kb2-card.open { padding: 0; }
.kb2-card.open > .kb2-t { padding: 14px 18px 0; }
.kb2-t { font-weight: 650; font-size: var(--t-card); display: flex; align-items: center; gap: 9px; flex-wrap: wrap; }
.kb2-t .kb2-health { margin-left: auto; }
.kb2-chev { opacity: .3; flex: none; transition: transform .18s cubic-bezier(.4,0,.2,1); }
.kb2-card.open .kb2-chev, .kb2-card.fold:hover .kb2-chev { opacity: .55; }
.kb2-card.open .kb2-chev { transform: rotate(90deg); }
.kb2-meta { font-size: var(--t-weak); color: var(--text-3); margin: 7px 0 0; display: flex; gap: 10px; flex-wrap: wrap; align-items: center; }
.kb2-meta .sep { width: 3px; height: 3px; border-radius: 50%; background: var(--line-strong); flex: none; }
.kb2-meta .kid { font-family: var(--font-mono); color: var(--text-2); background: var(--hover); padding: 1px 7px; border-radius: var(--r-s); font-size: 10.5px; }
.kb2-custom { color: var(--gold); }
.kb2-health { color: var(--text-3); font-weight: 400; font-variant-numeric: var(--num); }
.kb2-health b { color: var(--brand); font-weight: 700; }
.kb2-b { font-size: var(--t-body); color: var(--text-2); line-height: 1.85; margin: 10px 18px 0; }
.kb2-tags { display: flex; flex-wrap: wrap; gap: 6px; padding: 10px 18px 0; }
.kb2-tg { font-size: 10.5px; color: var(--text-2); background: var(--hover); padding: 3px 9px; border-radius: var(--r-s); }
.kb2-uses { display: flex; gap: 7px; flex-wrap: wrap; margin-top: 9px; align-items: center; }
.kb2-card.open .kb2-uses { padding: 0 18px 2px; margin-top: 6px; }
.kb2-uses .lb { font-size: 11px; color: var(--text-3); }
.kb2-use { font-size: 10.5px; border-radius: var(--r-s); padding: 3px 9px; display: inline-flex; align-items: center; gap: 4px; }
.kb2-use svg { opacity: .6; }
.kb2-use.ai { background: var(--brand-soft); color: var(--brand); }
.kb2-use.qc { background: #f2ecfa; color: #7A5A9E; }
.kb2-use.man { background: var(--hover); color: var(--text-2); }
.kb2-sec-t { font-size: 10.5px; font-weight: 700; letter-spacing: 1.2px; color: var(--text-3); margin: 14px 18px 8px; display: flex; align-items: center; gap: 6px; }
.kb2-sec-t::before { content: ""; width: 8px; height: 8px; border-radius: 3px; background: currentColor; opacity: .5; }
.kb2-sec-t.g { color: var(--brand); }
.kb2-sec-t.r { color: var(--danger); }
.kb2-sec-t.p { color: #7A5A9E; }
.kb2-dir { font-size: var(--t-body); color: var(--text-2); line-height: 1.75; list-style: none; padding: 0 18px; margin: 0; }
.kb2-dir li { padding: 4px 0 4px 22px; position: relative; margin: 2px 0; }
.kb2-dir li::before { content: ""; position: absolute; left: 4px; top: 14px; width: 10px; height: 2px; border-radius: 1px; background: var(--brand); }
.kb2-dir.bad li::before { background: var(--danger); }
.kb2-good { background: var(--brand-soft); border-left: 3px solid var(--brand); border-radius: 0 var(--r-m) var(--r-m) 0; padding: 8px 12px; margin: 0 18px; font-size: var(--t-aux); color: var(--text-2); line-height: 1.7; }
.kb2-qcbox { background: #f2ecfa; border-radius: var(--r-m); padding: 8px 12px; margin: 0 18px; font-size: var(--t-aux); color: #7A5A9E; line-height: 1.7; }
.kb2-en { font-family: var(--font-mono); font-size: 11px; color: var(--text-3); background: var(--card-2); border-radius: var(--r-m); padding: 7px 11px; margin: 0 18px; line-height: 1.7; }
.kb2-stats { display: flex; gap: 18px; padding: 11px 18px; margin-top: 12px; border-top: 1px solid var(--line); font-size: var(--t-weak); color: var(--text-3); flex-wrap: wrap; font-variant-numeric: var(--num); }
.kb2-stats b { color: var(--text-2); font-weight: 650; }
.kb2-ops { display: flex; gap: 8px; margin-top: 11px; flex-wrap: wrap; align-items: center; padding: 0 18px 14px; }
.kb2-later { font-size: 12px; color: var(--text-3); margin-left: auto; }
/* ── 卡片列表/面包屑/层注 ── */
.kb2-list { display: flex; flex-direction: column; gap: 10px; }
.kb2-crumb { font-size: var(--t-aux); color: var(--text-3); margin-bottom: 6px; }
.kb2-crumb b { color: var(--text); font-size: var(--t-card); font-weight: 650; }
.kb2-layernote { background: var(--hover); border-left: 2px solid var(--line-strong); color: var(--text-2); font-size: var(--t-aux); border-radius: 0 var(--r-m) var(--r-m) 0; padding: 8px 13px; line-height: 1.6; margin-bottom: 12px; }
/* 进化中心（V2 稿：胶囊 tab 选中松绿 / 状态行 + 金色扫描钮 / 候选卡阴影无描边） */
.kb2-tabs { display: flex; gap: 8px; margin-bottom: 0; flex-wrap: wrap; }
.kb2-tab { font-size: 13px; padding: 7px 16px; border-radius: var(--r-pill); background: var(--card); color: #555; border: 1px solid #e3e4e6; cursor: pointer; display: inline-flex; align-items: center; gap: 6px; }
.kb2-tab.on { background: var(--brand); border-color: var(--brand); color: var(--on-brand); font-weight: 600; }
.kb2-tab .n { background: rgba(0,0,0,.12); border-radius: 8px; font-size: 11px; padding: 0 6px; }
.kb2-tab.on .n { background: rgba(255,255,255,.22); }
.kb2-evorow { display: flex; justify-content: space-between; align-items: center; margin: 12px 0; gap: 10px; flex-wrap: wrap; }
.kb2-evorow .st { font-size: 12px; color: #888; }
.btn.gold { background: var(--gold); border: var(--gold); color: var(--on-brand); font-weight: 600; }
.btn.gold:hover { background: #b8941f; border-color: #b8941f; }
.kb2-cand { background: var(--card); border-radius: var(--r-btn); box-shadow: var(--shadow-1); border-left: 4px solid #07C160; padding: 14px 17px; margin-bottom: 10px; }
.kb2-cand.conflict { border-left-color: #f0a020; }
.kb2-cand.review { border-left-color: var(--link-wechat); }
.kb2-src { margin-top: 7px; font-size: 12px; color: var(--link-wechat); background: var(--link-soft); border-radius: 6px; padding: 7px 11px; line-height: 1.6; }
.kb2-check { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 8px; }
.kb2-ck { font-size: 11px; border-radius: 4px; padding: 3px 8px; }
.kb2-ck.ok { background: #e8f9f0; color: #07C160; }
.kb2-ck.warn { background: #fdf3e3; color: #b57708; }
.kb2-ck.info { background: var(--link-soft); color: var(--link-wechat); }
.kb2-diff { background: #fffbf3; border: 1px solid #f0e2b8; border-radius: 8px; padding: 10px 13px; margin-top: 9px; font-size: 12.5px; line-height: 1.75; color: #6b5410; }
.kb2-diff b { color: #b57708; }
/* 调用矩阵（V2 稿：段头单行 / hot 深绿字 #0a7a3d / cold #f4f4f5） */
.kb2-mx { width: 100%; border-collapse: separate; border-spacing: 4px; }
.kb2-mx th { font-size: 12px; color: #888; font-weight: 600; padding: 6px 8px; text-align: center; }
.kb2-mx th.rh { text-align: left; color: #1a1a1a; font-size: 12.5px; white-space: nowrap; }
.kb2-mx td { background: var(--card); border-radius: 7px; padding: 9px 10px; font-size: 11.5px; text-align: center; vertical-align: top; }
.kb2-mx td.hot { background: #e8f9f0; color: #0a7a3d; font-weight: 600; }
.kb2-mx td.warm { background: #faf3e0; color: var(--on-gold); }
.kb2-mx td.cold { background: #f4f4f5; color: #b0b0b0; }
.kb2-mx td .how { display: block; font-size: 10px; color: #999; margin-top: 2px; font-weight: 400; }
.kb2-legend { display: flex; gap: 14px; margin-top: 10px; font-size: 11.5px; color: #888; flex-wrap: wrap; }
.kb2-legend i { display: inline-block; width: 11px; height: 11px; border-radius: 3px; margin-right: 4px; vertical-align: -1px; font-style: normal; }
.kb2-empty { text-align: center; color: var(--text-3); font-size: var(--t-aux); padding: 28px 0; }

/* ================= 批一一八 · 头区/健康条/分段控件（沿用批一二〇结构锚点，视觉重做） ================= */
/* 头部：标题动作行（动作收拢一行，主按钮唯一实绿） */
.kb2-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 14px; flex-wrap: wrap; }
.kb2-head-t { font-size: var(--t-card); font-weight: 700; color: var(--text); display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.kb2-head-t svg { color: var(--brand); }
.kb2-head-t .sub { font-size: var(--t-weak); color: var(--text-3); font-weight: 400; }
.kb2-head-ops { display: flex; gap: 8px; flex: none; flex-wrap: wrap; }
/* 库健康条：数字主视觉 + 微标签（有事的亮色、没事的灰）——批一一八去卡片格子感 */
.kb2-hbar { display: flex; gap: 0; margin-bottom: 4px; align-items: stretch; }
.kb2-hcell { flex: 1; padding: 6px 18px; cursor: pointer; border-left: 1px solid var(--line); display: flex; flex-direction: column; justify-content: flex-end; transition: background var(--dur) cubic-bezier(.4,0,.2,1); }
.kb2-hcell:first-child { border-left: 0; padding-left: 0; }
.kb2-hcell:hover { background: var(--hover); border-radius: var(--r-s); }
.kb2-hcell b { font-size: 21px; font-weight: 750; color: var(--text); font-family: var(--font-mono); line-height: 1; font-variant-numeric: var(--num); }
.kb2-hcell span { font-size: var(--t-weak); color: var(--text-3); margin-top: 5px; display: block; }
.kb2-hcell.gold b { color: var(--gold); }
.kb2-hcell.red b { color: var(--danger); }
.kb2-hcell.blue b { color: var(--link-wechat); }
.kb2-hcell.green b { color: var(--brand); }
.kb2-hcell.zero b { color: var(--text-3); }
/* 视图分段控件：下划线式 tab（编辑器语言），与搜索合流行 */
.kb2-seg { display: flex; gap: 18px; align-items: center; margin-bottom: 14px; border-bottom: 1px solid var(--line); padding-bottom: 0; }
.kb2-segi { position: relative; font-size: var(--t-aux); color: var(--text-3); font-weight: 600; padding: 9px 2px 11px; cursor: pointer; white-space: nowrap; transition: color var(--dur); }
.kb2-segi:hover { color: var(--text); }
.kb2-segi.on { color: var(--text); }
.kb2-segi.on::after { content: ""; position: absolute; left: 0; right: 0; bottom: -1px; height: 2px; background: var(--brand); border-radius: 2px; }
.kb2-segi .n { background: var(--brand); color: var(--on-brand); border-radius: 9px; font-size: 10.5px; padding: 0 5px; min-width: 17px; height: 17px; line-height: 17px; text-align: center; margin-left: 5px; display: inline-block; vertical-align: 1px; }
.kb2-seg .kb2-search { margin-left: auto; margin-bottom: 4px; }
/* 五段流总览折叠条（默认折叠态，说明书让位工作台） */
.kb2-ovfold { display: flex; align-items: center; justify-content: space-between; background: var(--card); border: 1px dashed var(--line-strong); border-radius: var(--r-m); padding: 9px 14px; font-size: var(--t-aux); color: var(--text-2); cursor: pointer; margin-bottom: 12px; }
.kb2-ovfold:hover { background: var(--card-2); }
.kb2-ovfold .tg { color: var(--brand); font-weight: 600; }
.kb2-ovfold.on { border-style: solid; margin-bottom: 10px; }
/* 五段树：段组头可折叠、带段卡数 */
.kb2-secg { padding: 8px 14px 5px; display: flex; align-items: baseline; gap: 6px; cursor: pointer; user-select: none; }
.kb2-secg:hover { background: var(--hover); }
.kb2-secg b { color: var(--text); font-size: 12.5px; font-weight: 700; flex: none; }
.kb2-secg .q { font-size: 11px; color: var(--text-3); flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.kb2-secg .cnt { font-size: 10.5px; color: var(--text-3); font-family: var(--font-mono); flex: none; }
.kb2-secg::before { content: "▾"; font-size: 10px; color: var(--text-3); flex: none; transition: transform .15s; }
.kb2-secg.fold::before { transform: rotate(-90deg); }
/* 卡片：生命周期 tag（标题行，圆点前缀） */
.kb2-life { font-size: 10.5px; font-weight: 650; color: var(--brand); background: var(--brand-soft); border-radius: var(--r-pill); padding: 3px 10px; flex: none; display: inline-flex; align-items: center; gap: 5px; }
.kb2-life::before { content: ""; width: 5px; height: 5px; border-radius: 50%; background: currentColor; }
.kb2-life.arch { color: var(--text-3); background: var(--card-2); }
/* 引力连接区（星云·分类回声，仅展示） */
.kb2-grav { margin-top: 10px; padding-top: 10px; border-top: 1px dashed var(--line); }
.kb2-grav .kb2-sec-t { margin-top: 0; }
.kb2-grav-note { font-size: 10.5px; color: var(--text-3); font-weight: 400; margin-left: 8px; }
.kb2-grav-item { display: flex; align-items: center; gap: 8px; font-size: 12px; color: var(--text-2); padding: 5px 8px; border-radius: var(--r-s); cursor: pointer; flex-wrap: wrap; }
.kb2-grav-item:hover { background: var(--hover); }
.kb2-grav-item .t { color: var(--brand); font-weight: 600; }
.kb2-grav-item .ov { font-size: 11px; color: var(--text-3); }
.kb2-grav-cross { font-size: 10px; color: var(--link-wechat); background: var(--link-soft); border-radius: 3px; padding: 1px 6px; }
/* 进化中心 tab 分组：待办组与日志之间的竖线 + 日志虚线胶囊 */
.kb2-tab-sep { width: 1px; align-self: stretch; margin: 4px 2px; background: var(--line-strong); flex: none; }
.kb2-tab.log { border-style: dashed; color: var(--text-3); }
.kb2-tab.log.on { color: var(--on-brand); border-style: solid; }
/* 知识星云观测舱（深色舱 = --fx-ink 底 + --fx-mint 光，与引擎控制台同族） */
.kb2-nebula { background: var(--fx-ink); border-radius: var(--r-l); padding: 16px 18px 14px; color: rgba(255,255,255,.88); }
.kb2-nb-head { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; margin-bottom: 6px; }
.kb2-nb-head b { font-size: var(--t-card); color: var(--on-brand); }
.kb2-nb-head span { font-size: var(--t-weak); color: rgba(255,255,255,.5); }
.kb2-nb-svg { width: 100%; height: auto; display: block; }
.kb2-nb-planet:hover circle:first-of-type { fill: rgba(7,193,96,.3); }
.kb2-nb-gauges { display: flex; gap: 10px; margin-top: 4px; }
.kb2-nb-g { flex: 1; background: rgba(255,255,255,.06); border: 1px solid rgba(255,255,255,.09); border-radius: var(--r-m); padding: 10px 13px; }
.kb2-nb-g b { font-size: 19px; font-weight: 700; color: var(--fx-mint); font-family: var(--font-mono); display: block; }
.kb2-nb-g b.dim { font-size: 13px; color: rgba(255,255,255,.45); padding-top: 4px; }
.kb2-nb-g > span { font-size: 11.5px; color: rgba(255,255,255,.75); display: block; margin-top: 2px; }
.kb2-nb-g .d { display: block; font-size: 10.5px; color: rgba(255,255,255,.4); margin-top: 2px; }
.kb2-nb-foot { margin-top: 12px; font-size: 11px; color: rgba(255,255,255,.45); line-height: 1.7; border-top: 1px dashed rgba(255,255,255,.12); padding-top: 10px; }
@media (max-width: 1100px) { /* 批一一八：健康条窄窗改两列网格（旧行内换行会让分隔线错位）；星云仪表盘照旧换行 */
  .kb2-hbar { display: grid; grid-template-columns: 1fr 1fr; gap: 0 18px; }
  .kb2-hcell { border-left: 0; padding: 6px 0; border-top: 1px solid var(--line); }
  .kb2-hcell:nth-child(-n+2) { border-top: 0; }
  .kb2-nb-gauges { flex-wrap: wrap; }
  .kb2-nb-g { flex: 1 1 30%; }
}
@media (max-width: 760px) { /* 批一一八：手机档——树/内容纵排，树不吸顶，分段控件可横滚 */
  .kb2-main { flex-direction: column; }
  .kb2-tree { position: static; width: 100%; max-height: none; }
  .kb2-content { padding-left: 0; width: 100%; }
  .kb2-seg { overflow-x: auto; gap: 14px; flex-wrap: wrap; }
  .kb2-seg .kb2-search { width: 100%; margin: 0 0 8px; flex: none; }
  .kb2-head { flex-direction: column; align-items: stretch; }
  .kb2-head-ops { width: 100%; }
  .kb2-head-ops .btn { flex: 1 1 auto; }
}
/* 变更日志 */
.kb2-log { font-size: var(--t-aux); color: var(--text-2); }
/* 批一二三 健康月报：账单式（结论条→指标横条→待激活清单→账本脚注），去卡片化 */
.kb2-rpt-lead { background: var(--brand-soft); border-radius: var(--r-m); padding: 11px 14px; font-size: var(--t-aux); color: var(--text); margin-bottom: 14px; }
.kb2-rpt-lead b { color: var(--brand); font-family: var(--font-mono); font-size: 15px; }
.kb2-rpt-lead .warn { color: var(--danger); font-weight: 600; }
.kb2-rpt-row { display: flex; gap: 18px; margin-bottom: 16px; }
.kb2-rpt-g { flex: 1; min-width: 0; }
.kb2-rpt-g .lb { font-size: var(--t-weak); color: var(--text-3); }
.kb2-rpt-g .vl { font-size: 22px; font-weight: 700; font-family: var(--font-mono); color: var(--text); margin: 2px 0 5px; }
.kb2-rpt-g .bar { height: 4px; border-radius: 2px; background: var(--line); overflow: hidden; }
.kb2-rpt-g .bar i { display: block; height: 100%; background: var(--brand); border-radius: 2px; }
.kb2-rpt-g .ln { font-size: 10.5px; margin-top: 5px; line-height: 1.5; color: var(--text-3); }
.kb2-rpt-g .ln.ok { color: var(--brand); }
.kb2-rpt-g .ln.bad { color: var(--danger); }
.kb2-rpt-sec { display: flex; align-items: baseline; gap: 10px; border-top: 1px solid var(--line); padding-top: 12px; margin-bottom: 8px; }
.kb2-rpt-sec b { font-size: var(--t-card); }
.kb2-rpt-sec .sub { font-size: var(--t-weak); color: var(--text-3); flex: 1; }
.kb2-rpt-sec a { font-size: var(--t-weak); color: var(--brand); text-decoration: none; flex: none; }
.kb2-rpt-empty { text-align: center; color: var(--text-3); font-size: var(--t-aux); padding: 20px 0; }
.kb2-rpt-sleep { display: flex; align-items: center; gap: 10px; padding: 7px 4px; border-bottom: 1px dashed var(--line); font-size: var(--t-aux); }
.kb2-rpt-sleep .kid { font-family: var(--font-mono); color: var(--text-3); font-size: var(--t-weak); flex: none; }
.kb2-rpt-sleep .tt { flex: 1; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.kb2-rpt-sleep .dd { flex: none; font-size: var(--t-weak); color: var(--warn); }
.kb2-rpt-more { font-size: var(--t-weak); color: var(--text-3); padding: 7px 4px; }
.kb2-rpt-foot { margin-top: 14px; font-size: 11px; color: var(--text-3); border-top: 1px dashed var(--line); padding-top: 10px; line-height: 1.7; }
@media (max-width: 1100px) { .kb2-rpt-row { flex-wrap: wrap; } .kb2-rpt-g { flex: 1 1 40%; } }
.kb2-log .row { display: flex; gap: 10px; padding: 7px 4px; border-bottom: 1px dashed var(--line); align-items: baseline; }
.kb2-log .ts { color: var(--text-3); font-size: var(--t-weak); flex: none; font-family: ui-monospace, monospace; }
.kb2-log .type { flex: none; font-size: var(--t-weak); border-radius: 4px; padding: 1px 7px; background: var(--card-2); color: var(--text-3); }
.tag { display: inline-block; font-size: var(--t-weak); color: var(--brand); background: var(--brand-soft); border-radius: 4px; padding: 1px 7px; margin: 0 4px 4px 0; }

/* ================= 弹层 ================= */
.toast-wrap { position: fixed; left: 50%; top: 18%; transform: translateX(-50%); z-index: 200; display: flex; flex-direction: column; gap: 8px; align-items: center; pointer-events: none; }
.toast {
  background: rgba(0,0,0,.78); color: var(--on-brand);
  font-size: var(--t-aux);
  border-radius: var(--r-m); padding: 10px 18px;
  max-width: 70vw; text-align: center;
  animation: toast-in .18s ease;
}
@keyframes toast-in { from { opacity: 0; transform: translateY(-8px) } to { opacity: 1 } }

.mask {
  position: fixed; inset: 0; z-index: 150;
  background: var(--mask);
  display: grid; place-items: center;
  animation: toast-in .15s ease;
}
.dialog {
  background: var(--card); border-radius: var(--r-l);
  width: min(480px, 92vw); max-height: 86vh; overflow: auto;
  box-shadow: var(--shadow-3);
}
.dialog .d-t { font-size: var(--t-card); font-weight: 600; padding: 18px var(--pad) 0; text-align: center; }
.dialog .d-b { padding: 14px var(--pad) 18px; color: var(--text-2); font-size: var(--t-body); }
.dialog .d-ops { display: flex; border-top: 1px solid var(--line); }
.dialog .d-ops .btn { flex: 1; border: 0; border-radius: 0; min-height: 46px; }
.dialog .d-ops .btn + .btn { border-left: 1px solid var(--line); }
.viewer { max-width: min(560px, 94vw); }
.viewer img { width: 100%; border-radius: 8px; }

/* ================= 桌面档宽度调节 ================= */
/* 桌面窄窗窄栏：主内容区让位（须晚于 .main 基础规则才生效，V2.20.0 探针 D1 实证） */
@media (min-width: 901px) and (max-width: 1280px) {
  .main { margin-left: var(--rail-w); }
}
/* V2.46.0 桌面化：原 ≤900 小屏块（侧栏隐藏+mobile-nav 底栏）已移除，
   手法留档 docs/mobile-legacy.md；窗口窄于 --app-min-w 由 body 底线出横滚兜底 */

/* ================= 做海报 v5：同页编辑+预览 ================= */
/* 营销日历条 */
.cal-strip { display: flex; gap: 8px; flex-wrap: wrap; }
.cal-item {
  border: 1px solid var(--line); border-radius: var(--r-m);
  background: var(--card-2); padding: 7px 12px;
  font-size: var(--t-aux); cursor: default;
  display: flex; align-items: center; gap: 8px;
  transition: border-color .15s, background .15s;
}
.cal-item .d { color: var(--text-3); font-size: var(--t-weak); }
.cal-item .k { font-size: 10px; border-radius: 3px; padding: 0 4px; background: var(--brand-soft); color: var(--brand); }
.cal-item.today { border-color: var(--gold); }
.cal-item.link { cursor: pointer; }
.cal-item.link:hover { border-color: var(--brand); }
.cal-item.on { border-color: var(--brand); background: var(--brand-soft); }
.cal-item.dim { opacity: .45; }

/* 天气卡 */
.weather-now { display: flex; align-items: center; gap: 14px; }
.weather-now .t { font-size: 24px; font-weight: 700; }
.weather-now .w { font-size: var(--t-aux); color: var(--text-2); }
.weather-days { display: flex; gap: 8px; margin-top: 10px; }
.weather-day {
  flex: 1; text-align: center; border: 1px solid var(--line);
  border-radius: var(--r-m); padding: 7px 4px; background: var(--card-2);
  font-size: var(--t-weak); color: var(--text-2);
}
.weather-day .wd { font-weight: 600; color: var(--text); font-size: var(--t-aux); }

/* 商品录入：模式切换 */
.mini-tabs { display: inline-flex; background: var(--card-2); border: 1px solid var(--line); border-radius: 8px; padding: 2px; gap: 2px; }
.mini-tab { padding: 5px 14px; border-radius: 6px; font-size: var(--t-aux); color: var(--text-2); cursor: pointer; }
.mini-tab.on { background: var(--card); color: var(--brand); font-weight: 600; box-shadow: var(--shadow-1); }

/* 商品清单表（V2.46.3 立 · 批三九九 改微信 B 端列表风 —— 李叔 2026-10-12 拍板）：
   ★ 微信列表口径 = **只有横向分割线，没有竖网格**：表头一条下线、行间一条浅线。
     旧版靠 td:first/last-child 的左右竖边把整表围成一个"盒子"（还带四角圆角），
     那是 Excel 表格的语汇；微信的列表不用盒子——边界交给外层卡片，行之间只用线说话。
   ★ 表头去实底：原来铺一整块 --card-2 当"表头条"，现在只用一条下线分隔，
     层次交给「字号（--t-weak）+ 色阶（--text-2）」承担（微信表头就是浅灰小字）。
   ★ 输入框三层手感（微信表单）：静置全透明 → **悬浮给浅底 --card-2**（不给边，
     给边会在密集表里连成网格）→ **聚焦才显品牌边 + 聚焦晕**（--focus-ring）。
   ★ 本基类三张表共用：手动填写 / 批量导入预览 / 识别核对（单一真源，禁令见批三九五）。 */
.prod-table { width: 100%; table-layout: fixed; border-collapse: separate; border-spacing: 0; }
.prod-table th {
  font-size: var(--t-weak); color: var(--text-2); text-align: left; padding: 7px 8px; font-weight: 500;
  background: transparent; border-bottom: 1px solid var(--line-strong);
  /* 列名「单位/规格*」（李叔 10-12）在 406px 窄栏的 50px 列里放不下 5 个汉字（≈49px > 内容盒 34px）。
     原来 nowrap 会让星号**溢出到邻格**（探针实测 scrollW 61 > clientW 50，出图见星号压在「原价」上）。
     加宽本列要挤走名字列 6%，代价更大 → 改为允许折行（表头本身就有两行设计，核对表同款）。 */
  white-space: normal; line-height: 1.35;
}
.prod-table td { padding: 4px 6px; border-bottom: 1px solid var(--line); }
.prod-table tbody tr:last-child td { border-bottom: 0; }
.prod-table tbody tr:hover td { background: var(--hover); }
.prod-table .input { width: 100%; box-sizing: border-box; padding: 6px 8px; font-size: var(--t-aux); background: transparent; border-color: transparent; }
.prod-table td:hover .input { background: var(--card-2); border-color: transparent; }
.prod-table .input:focus { background: var(--card); border-color: var(--brand); box-shadow: var(--focus-ring); outline: none; }
/* 特价列：省¥徽章置于输入框下方，不挤压输入框 */
.prod-table td .prod-sale-input { display: block; width: 100%; min-width: 60px; }
.prod-save-below { display: inline-flex; align-items: center; margin-top: 2px; padding: 1px 7px; border-radius: var(--r-pill);
  font-size: var(--t-weak); font-weight: 700; color: var(--danger); background: var(--card); border: 1px solid var(--danger);
  white-space: nowrap; font-variant-numeric: var(--num); vertical-align: middle;
}
.prod-table .input.inp-err { border-color: var(--danger); background: var(--danger-soft); }
.prod-del { color: var(--text-3); width: 26px; height: 26px; border-radius: 6px; display: grid; place-items: center; }
.prod-del:hover { color: var(--danger); background: var(--danger-soft); }
/* 商品图重配图入口（V2.24.1）：与删除钮同格并排，hover 品牌色区分语义 */
.prod-re { color: var(--text-3); width: 26px; height: 26px; border-radius: 6px; display: inline-grid; place-items: center; }
.prod-re:hover { color: var(--brand); background: var(--brand-soft); }
.prod-ops { display: inline-flex; align-items: center; gap: 2px; white-space: nowrap; }

/* 生成进度条（V2.21.0 引擎控制台：刻度化 + 前沿光点，条纹遮罩零 JS 分段） */
.gf-track { position: relative; height: 8px; border-radius: 3px; background: var(--card-2); border: 1px solid var(--line); overflow: hidden; }
.gf-track::after {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background: repeating-linear-gradient(90deg, transparent 0 10px, var(--card) 10px 13px);
}
.gf-bar {
  position: relative; height: 100%; width: 0; border-radius: 3px;
  background: linear-gradient(90deg, var(--brand), var(--fx-mint) 160%);
  transition: width .4s ease;
}
.gf-bar::after {
  content: ''; position: absolute; right: -2px; top: 50%; transform: translateY(-50%);
  width: 8px; height: 8px; border-radius: 50%; background: #CFFFF0;
  box-shadow: 0 0 8px 3px rgba(61, 232, 176, .7);
  animation: gf-tipbre 1.1s ease-in-out infinite;
}
@keyframes gf-tipbre { 50% { box-shadow: 0 0 3px 1px rgba(61, 232, 176, .35); } }
.gf-bar.indet {
  width: 38%; transition: none; animation: gf-slide 1.15s infinite ease-in-out, gf-flow 1.8s linear infinite;
  background: linear-gradient(90deg, var(--brand) 0%, var(--fx-mint) 50%, var(--brand) 100%);
  background-size: 200% 100%; border-radius: 3px;
}
@keyframes gf-flow { 0% { background-position: 0% 0; } 100% { background-position: -200% 0; } }
/* 生成小提示（轮换文案 + 淡入动效） */
.gf-tips { margin-top: 6px; font-size: 11.5px; color: var(--text-3); min-height: 16px; }
.gf-tips:empty { display: none; }
.gf-tips.gf-tips-in { animation: gf-tip-in .5s ease; }
@keyframes gf-tip-in { from { opacity: 0; transform: translateY(3px); } to { opacity: 1; transform: none; } }
.gf-bar.err { background: var(--danger); }
.gf-bar.err::after { display: none; }
@keyframes gf-slide { 0% { margin-left: -32%; } 100% { margin-left: 100%; } }
.gf-status { display: flex; align-items: flex-start; gap: 8px; margin-top: 10px; font-size: 13px; color: var(--text-2); min-height: 20px; }
.gf-status .gf-spin { margin-top: 4px; }
.gf-status #gfText { flex: 1; min-width: 0; line-height: 1.5; font-weight: 600; color: var(--text); }
.gf-spin { width: 12px; height: 12px; flex: none; border: 2px solid var(--line-strong); border-top-color: var(--brand); border-radius: 50%; animation: gf-rot .8s linear infinite; }
@keyframes gf-rot { to { transform: rotate(360deg); } }

/* 商品录入必填校验 */
.prod-table .input.inp-err { border-color: var(--danger); background: var(--danger-soft); }
.prod-table th .req { color: var(--danger); }

/* ===== 活动时间自绘日历 CALPOP（V2.39.0 方案B双月，李叔拍板） ===== */
/* 日期框（替代原生 input[type=date]） */
.calwrap { position: relative; }
.calbox {
  display: flex; align-items: center; gap: 8px; min-height: 42px;
  border: 1px solid var(--line-strong); border-radius: var(--r-m);
  background: var(--card); padding: 9px 12px; cursor: pointer;
  font-size: 14.5px; user-select: none;
}
.calbox:hover, .calbox:focus-visible { border-color: var(--brand); outline: none; }
.calbox.open { border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-soft); }
.calbox .cb-d { color: var(--text); white-space: nowrap; }
.calbox .cb-d.pending { color: #FA9D3B; }
.calbox .cb-sep { color: var(--text-3); font-size: 13px; }
.calbox .cb-ico { margin-left: auto; display: flex; color: var(--text-3); }
/* 日历浮层：双月并排 860px，z140（高于风格预览60、低于全局遮罩150） */
.calpop {
  position: absolute; z-index: 140; left: 0; margin-top: 6px;
  width: min(860px, calc(100vw - 40px));
  background: var(--card); border: 1px solid var(--line); border-radius: var(--r-card);
  box-shadow: var(--shadow-3); padding: 18px 20px 14px;
}
.calpop.hidden { display: none; }
.calpop .cp-chips { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 14px; }
.calpop .cp-chips span {
  font-size: 14px; padding: 6px 14px; border-radius: 20px; background: var(--card-2);
  color: var(--text-2); cursor: pointer; white-space: nowrap;
}
.calpop .cp-chips span:hover { background: var(--brand-soft); color: var(--brand); }
.calpop .cp-months { display: flex; gap: 32px; }
.calpop .cp-month { flex: 1; min-width: 0; }
.calpop .cp-mhead {
  display: flex; align-items: center; justify-content: center; gap: 12px;
  font-size: 18px; font-weight: 600; margin-bottom: 12px;
}
.calpop .cp-mhead .cp-nav {
  cursor: pointer; color: var(--text-3); padding: 4px 10px; border-radius: var(--r-s);
  font-weight: 400; user-select: none; font-size: 20px; line-height: 1;
}
.calpop .cp-mhead .cp-nav:hover { background: var(--card-2); color: var(--brand); }
.calpop .cp-mhead .cp-nav.dis { visibility: hidden; }
.calpop .cp-wrow, .calpop .cp-drow { display: grid; grid-template-columns: repeat(7, 1fr); }
.calpop .cp-wrow { font-size: 13px; color: var(--text-3); margin-bottom: 4px; }
.calpop .cp-wrow i { font-style: normal; text-align: center; padding: 2px 0; }
/* 日期格：数字在上、节庆字在下（13px 金粗，V3 终版） */
.calpop .cp-drow i {
  position: relative; cursor: pointer; color: var(--text); user-select: none; font-style: normal;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  height: 64px; border-radius: var(--r-m); line-height: 1.15;
}
.calpop .cp-drow i .cp-dd { font-size: 17px; font-weight: 500; }
.calpop .cp-drow i .cp-nd {
  font-style: normal; font-size: 13px; font-weight: 600; color: var(--gold);
  margin-top: 3px; height: 15px; white-space: nowrap; overflow: hidden; max-width: 100%;
}
.calpop .cp-drow i.dim { color: var(--text-3); cursor: default; background: none !important; }
.calpop .cp-drow i:not(.dim):hover { background: var(--brand-soft); }
.calpop .cp-drow i.today .cp-dd::after {
  content: ''; display: block; margin: 1px auto 0;
  width: 5px; height: 5px; border-radius: 50%; background: var(--brand);
}
.calpop .cp-drow i.inrange { background: var(--brand-soft); border-radius: 0; }
.calpop .cp-drow i.rs, .calpop .cp-drow i.re { background: var(--brand); }
.calpop .cp-drow i.rs .cp-dd, .calpop .cp-drow i.re .cp-dd { color: var(--on-brand); }
.calpop .cp-drow i.rs .cp-nd, .calpop .cp-drow i.re .cp-nd { color: #FFE9A8; }
.calpop .cp-drow i.rs { border-radius: var(--r-m) 0 0 var(--r-m); }
.calpop .cp-drow i.re { border-radius: 0 var(--r-m) var(--r-m) 0; }
.calpop .cp-drow i.rs.re { border-radius: var(--r-m); }
.calpop .cp-foot {
  display: flex; align-items: center; margin-top: 14px; padding-top: 12px;
  border-top: 1px solid var(--line); font-size: 15px; color: var(--text-3);
}
.calpop .cp-foot .sel { color: var(--brand); font-weight: 600; }
.calpop .cp-foot .cp-btns { margin-left: auto; display: flex; gap: 10px; }
.calpop .cp-foot button {
  border: none; border-radius: var(--r-m); font-size: 15px; padding: 8px 22px; cursor: pointer;
}
.calpop .cp-foot .cp-clr { background: none; color: var(--text-3); }
.calpop .cp-foot .cp-ok { background: var(--brand); color: var(--on-brand); }

/* 主题 AI 参考 */
.ai-ref-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }

/* 提示词编辑 */
.prompt-edit { width: 100%; min-height: 150px; background: var(--card-2); border: 1px solid var(--line); border-radius: var(--r-m); padding: 12px 14px; font-size: var(--t-aux); color: var(--text); line-height: var(--lh); outline: none; resize: vertical; }
.prompt-edit:focus { border-color: var(--brand); }
/* 提示词操作头（V2.23.1）：润色/重置按钮收入标签行，与文本域只隔 6px */
.prompt-head { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; }
.prompt-head-label { font-size: var(--t-aux); color: var(--text-2); }
/* V2.46.3：字数条从操作组里挪出来居中，头部成「标签 ｜ 字数条 ｜ 操作」三分区 */
.prompt-head-actions { display: flex; gap: 8px; flex: none; }
.prompt-head .p-budget { margin-left: auto; margin-right: auto; }
/* 提示词结构视图（V2.46.5）：段 chips + 裁决日志——把 Φ1 结构公式与 Φ2 消解公式显性化在界面上。
   零新色零新组件，全部取自 tokens：可裁段用虚线边框区分，裁决动作用品牌色/警示色区分 */
.prompt-struct { margin: 6px 0 8px; }
.ps-row { display: flex; flex-wrap: wrap; gap: 6px; }
.ps-chip { display: inline-flex; align-items: center; gap: 5px; padding: 3px 9px; border: 1px solid var(--line); border-radius: var(--r-pill); background: var(--card-2); font-size: var(--t-weak); color: var(--text-2); }
.ps-chip b { font-weight: 600; font-size: 10px; color: var(--text-3); }
.ps-chip.drop { border-style: dashed; color: var(--text-3); }
.ps-chip i { font-style: normal; font-size: 10px; color: var(--warn); }
.ps-log { margin-top: 7px; padding-top: 6px; border-top: 1px dashed var(--line); font-size: var(--t-weak); color: var(--text-3); }
.ps-log.none { border-top: 0; padding-top: 2px; }
.ps-log-h { color: var(--text-2); font-weight: 600; }
.ps-log-i { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; padding: 2px 0; }
/* 批四四六：裁决动作改中性描边标签——原红字加粗像「删除按钮」（李叔截图点名「看不懂/像按钮」）；
   动作语义由文字承载（非色证据，批三九六口径），颜色不再暗示可点；.ps-dim（英文维度 id）退役。 */
.ps-rm { color: var(--text-2); }
.ps-cri { padding: 0 6px; border: 1px solid var(--line); border-radius: 4px; }
.ps-arrow { color: var(--text-3); }
.ps-act { font-weight: 500; padding: 0 6px; border: 1px solid var(--line); border-radius: 4px; color: var(--text-2); }
.ps-act.kp { color: var(--text-3); }

/* 门店 / 品牌 CRUD */
.cell .ops { display: flex; gap: 6px; flex: none; }
.form-dialog .field { text-align: left; }

/* 工具类 */
.row { display: flex; align-items: center; gap: 10px; }
.row.between { justify-content: space-between; }
.col { display: flex; flex-direction: column; gap: 10px; }
.mt8 { margin-top: 8px; } .mt12 { margin-top: 12px; } .mt16 { margin-top: 16px; }
.muted { color: var(--text-3); font-size: var(--t-weak); }
.hidden { display: none !important; }

/* ================= 登录 / 注册门禁（沃家统一样式：左品牌栏 + 右表单，与沃家账房同族） ================= */
.auth-gate { position: fixed; inset: 0; z-index: 60; background: var(--paper); overflow-y: auto; }
.auth-split { display: flex; min-height: 100vh; }
/* 左：品牌栏（固定深松绿，不随主题变化，保持家族统一） */
.auth-side {
  flex: 1.15; min-width: 0; color: #f2efe5;
  background:
    radial-gradient(circle at 85% 12%, rgba(201,162,39,.16) 0 18%, transparent 45%),
    linear-gradient(160deg, #0f2f1d 0%, #14532f 52%, #1E7A46 100%);
  display: flex; flex-direction: column; padding: 36px 52px 26px;
}
.as-brand { display: flex; align-items: center; gap: 12px; }
.as-brand img { height: 34px; width: auto; }
.as-name { font-size: 17px; font-weight: 700; letter-spacing: 1px; }
.as-sub { font-size: 11px; opacity: .7; margin-top: 2px; }
.as-mid { flex: 1; display: flex; flex-direction: column; justify-content: center; padding: 36px 0; max-width: 560px; }
.as-slogan { font-size: 27px; font-weight: 700; line-height: 1.55; letter-spacing: 1px; }
.as-desc { font-size: 12.5px; opacity: .72; line-height: 1.85; margin-top: 14px; }
.as-feats { margin-top: 36px; display: flex; flex-direction: column; gap: 17px; }
.as-feat { display: flex; gap: 12px; align-items: flex-start; }
.as-fic {
  flex: none; width: 30px; height: 30px; border-radius: 8px;
  background: rgba(255,255,255,.1); display: grid; place-items: center; color: #cde8d7;
}
.as-ft { font-size: 13px; font-weight: 600; letter-spacing: .5px; }
.as-fd { font-size: 11px; opacity: .62; margin-top: 2px; line-height: 1.6; }
.as-foot { font-size: 10.5px; opacity: .5; letter-spacing: .5px; }
/* 右：表单栏（固定浅色，不受明暗主题影响） */
.auth-pane { flex: 1; display: grid; place-items: center; padding: 32px 24px; background: var(--paper); color: #1a1a1a; }
.auth-card2 { width: 340px; max-width: 100%; }
.auth-tabs {
  display: flex; gap: 4px; margin: 4px 0 18px;
  background: #ece7db; border-radius: var(--r-btn); padding: 3px;
}
.auth-tab { flex: 1; padding: 8px 0; border-radius: 8px; font-size: var(--t-body); color: #6b6558; }
.auth-tab.on { background: #fff; color: #1a1a1a; font-weight: 600; box-shadow: 0 1px 4px rgba(0,0,0,.08); }
.auth-pane .field { text-align: left; margin-bottom: 14px; }
.auth-pane .field label { color: #6b6558; }
.auth-pane .input { background: #fff; border: 1px solid #e3ddce; color: #1a1a1a; }
.auth-pane .input:focus { border-color: #1E7A46; }
.pw-wrap { position: relative; }
.pw-wrap .input { width: 100%; padding-right: 38px; box-sizing: border-box; }
.pw-eye { position: absolute; right: 10px; top: 50%; transform: translateY(-50%); cursor: pointer; color: #9a9384; display: grid; place-items: center; }
.pw-eye:hover { color: #1E7A46; }
.auth-submit { width: 100%; margin-top: 6px; padding: 11px 0; font-size: var(--t-body); }
.auth-tip { font-size: var(--t-weak); color: #9a9384; margin-top: 14px; line-height: 1.7; text-align: center; }
.auth-ok { padding: 14px 0 4px; text-align: center; }
.auth-ok-ic { width: 46px; height: 46px; margin: 0 auto; color: #1E7A46; }
.auth-ok-ic svg { width: 100%; height: 100%; }
.auth-ok-t { font-size: 16px; font-weight: 700; margin-top: 10px; }
.auth-ok-s { font-size: var(--t-aux); color: #6b6558; margin: 8px 0 16px; line-height: 1.7; }

/* ================= 顶栏：费用字段 / 用户（A1 定稿 09-27） ================= */
/* cost-chip 现在与顶栏其它状态片同族（32px 胶囊），自身去边框背景 */
.cost-chip {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: var(--t-weak); color: var(--text-2);
  background: none; border: 0; cursor: pointer;
  /* 批一三一：与顶栏其它状态片同族（32px 胶囊 + 悬停底色），不再是个裸按钮 */
  height: 32px; padding: 0 10px; border-radius: var(--r-pill);
  transition: background var(--dur) var(--ease);
}
.cost-chip:hover { background: var(--hover); }
/* 费用与参谋之间的分隔线（原来是 .info-group .sep，胶囊拆了这条得自己立住） */
.top-actions .sep { width: 1px; height: 18px; background: var(--line); margin: 0 5px; flex: none; }
.cost-chip:hover b { text-decoration: underline; }
.cost-chip b { color: var(--poster-red, #C42A1F); font-weight: 700; }
/* 任务一（09-27）：今日/累计/余额三段视觉区分——今日红（当日消耗）、
   累计墨色（历史沉淀）、余额松绿（账户剩余）；竖线分隔，悬停文案见 title */
.cost-chip .cc-item { display: inline-flex; align-items: baseline; gap: 3px; white-space: nowrap; }
.cost-chip .cc-item + .cc-item { border-left: 1px solid var(--line); padding-left: 7px; }
.cost-chip .cc-total b { color: var(--text); }
.cost-chip .cc-bal b { color: var(--brand); }
/* 用户区：名字末字圆形头像 + 姓名/门店
   批一三一：32px 松绿实心头像在顶栏里是最重的一块——顶栏不该有第二视觉中心。
   改成 26px 品牌浅底 + 品牌色字，整块做成可悬停的胶囊，与其它状态片同族。 */
.ugroup {
  display: inline-flex; align-items: center; gap: 8px; cursor: default;
  height: 32px; padding: 0 10px 0 4px; border-radius: var(--r-pill);
  transition: background var(--dur) var(--ease);
}
.ugroup:hover { background: var(--hover); }
.ugroup .avatar {
  width: 26px; height: 26px; border-radius: 50%; flex: none;
  background: var(--brand-soft); color: var(--brand);
  display: grid; place-items: center; font-size: var(--t-aux); font-weight: 700;
}
.ugroup .n { font-weight: 600; color: var(--text); font-size: var(--t-aux); }
.ugroup .s { color: var(--t3); font-size: var(--t-weak); }
.rv-tops { text-align: right; white-space: nowrap; }
.rv-tops .btn { margin-left: 6px; }

/* ================= 页面标题（pg 别名，与 page-head 一致） ================= */
.pg-h { margin-bottom: 18px; }
.pg-h h2 { font-size: var(--t-page); font-weight: 700; }
.pg-h p { font-size: var(--t-aux); color: var(--text-2); margin-top: 4px; }

/* ================= 资源费用页 ================= */
.cost-card { padding: 18px 20px; }
.cost-t { font-size: var(--t-card); font-weight: 700; margin-bottom: 6px; }
.cost-note { font-size: var(--t-weak); color: var(--text-3); margin-bottom: 12px; }
.cost-note b { color: var(--brand); }
.stat-row { display: flex; flex-wrap: wrap; gap: 8px 0; }
.stat { flex: 1 1 90px; min-width: 80px; }
.stat b { display: block; font-size: 22px; font-weight: 800; letter-spacing: -.5px; }
.stat span { font-size: var(--t-weak); color: var(--text-3); }
.cost-div { height: 1px; background: var(--line); margin: 14px -20px; }
.cost-row { display: flex; justify-content: space-between; align-items: center; padding: 7px 0; font-size: var(--t-body); }
.cost-row.big .cr-name { font-weight: 700; }
.cr-name { color: var(--text); font-weight: 600; }
.cr-val { color: var(--text-2); font-size: var(--t-aux); }
.cr-cost { color: var(--poster-red, #C42A1F); font-size: 18px; font-weight: 800; }
.cr-bal { font-size: 16px; font-weight: 800; color: var(--text); }
.cost-prov { margin-top: 14px; }
.cost-prov-h { display: flex; justify-content: space-between; align-items: center; font-size: var(--t-body); }
.bar { flex: 1; height: 8px; border-radius: 4px; background: var(--card-2); overflow: hidden; }
.bar.big { height: 10px; margin: 8px 0 10px; }
.bar i { display: block; height: 100%; background: var(--text); border-radius: 4px; min-width: 2px; opacity: .85; }
.cost-model { display: flex; align-items: center; gap: 10px; padding: 5px 0 5px 14px; }
.cm-name { flex: none; width: 190px; font-size: var(--t-weak); color: var(--text-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cm-val { flex: none; width: 60px; text-align: right; font-size: var(--t-weak); color: var(--text-2); }

/* ================= 表格（日志 / 审核 / 成员消耗） ================= */
.table { width: 100%; border-collapse: collapse; font-size: var(--t-aux); }
.table th { text-align: left; color: var(--text-3); font-weight: 500; font-size: var(--t-weak); padding: 6px 8px; border-bottom: 1px solid var(--line); }
.table td { padding: 8px; border-bottom: 1px solid var(--line); vertical-align: top; }
.table tr:last-child td { border-bottom: 0; }
.table .num, .table td.num { text-align: right; font-weight: 700; }
.table .nowrap { white-space: nowrap; color: var(--text-2); }
.cost-table td:last-child { text-align: right; font-weight: 700; }
.log-act { display: inline-block; background: var(--brand-soft); color: var(--brand); border-radius: 4px; padding: 1px 8px; font-size: var(--t-weak); font-weight: 600; white-space: nowrap; }
.log-detail { color: var(--text-2); word-break: break-all; }
.tag.ok { color: var(--brand); background: var(--brand-soft); }
.tag.bad { color: var(--danger); background: var(--danger-soft); }
.tag.wait { color: #B26A00; background: #FFF3E0; }
[data-theme="dark"] .tag.wait { color: #E5B567; background: rgba(229,181,103,.12); }

/* ================= 注册审核 ================= */
.rv-row { display: flex; align-items: center; gap: 12px; padding: 10px 0; border-bottom: 1px solid var(--line); }
.rv-row:last-child { border-bottom: 0; }
.rv-info { flex: 1; min-width: 0; }
.rv-info b { font-size: var(--t-body); }
.rv-info span { display: block; font-size: var(--t-weak); color: var(--text-3); margin-top: 2px; }
.rv-time { flex: none; font-size: var(--t-weak); color: var(--text-3); }
.rv-ops { flex: none; display: flex; gap: 8px; }

.m-cnt { font-size: var(--t-weak); color: var(--text-3); margin-left: 5px; }

/* ================= 用户管理（V2.14.0）：搜索工具条 / 前端分页条 ================= */
.um-tools { display: flex; align-items: center; gap: 10px; margin: 6px 0 12px; flex-wrap: wrap; }
.um-tools .input { flex: 1 1 200px; min-width: 160px; }
.um-tools select.input { flex: 0 0 auto; width: auto; }
.um-tools .btn { flex: none; }
.um-page { display: flex; align-items: center; justify-content: flex-end; gap: 12px; padding: 12px 0 2px; font-size: var(--t-weak); color: var(--text-3); }

/* ================= 品牌资产：标志版本 / 标准色 ================= */
.logo-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 12px; margin-top: 12px; }
.logo-ver { border: 1px solid var(--line); border-radius: var(--r-m); overflow: hidden; background: var(--card); }
.lv-preview { height: 110px; display: grid; place-items: center; padding: 14px; }
.lv-preview.light { background: var(--paper); }
.lv-preview.dark { background: #17120E; }
.lv-preview img { max-width: 88%; max-height: 70px; object-fit: contain; }
.lv-meta { padding: 9px 12px 2px; display: flex; align-items: baseline; gap: 8px; }
.lv-name { font-size: var(--t-body); font-weight: 700; }
.lv-use { font-size: var(--t-weak); color: var(--text-3); }
.lv-dl {
  display: inline-block; margin: 6px 12px 10px;
  font-size: var(--t-weak); color: var(--brand); font-weight: 600;
  text-decoration: none;
}
.lv-dl:hover { text-decoration: underline; }

.cs-group { margin-top: 6px; }
.cs-group + .cs-group { margin-top: 14px; }
.cs-gt { font-size: var(--t-aux); font-weight: 700; color: var(--text-2); margin-bottom: 8px; }
.cs-row { display: flex; gap: 14px; padding: 8px 0; border-bottom: 1px solid var(--line); }
.cs-row:last-child { border-bottom: 0; }
.cs-sw {
  flex: none; width: 132px; height: 74px; border-radius: var(--r-m);
  display: flex; flex-direction: column; justify-content: flex-end;
  padding: 8px 10px; color: var(--on-brand); box-shadow: inset 0 0 0 1px rgba(0,0,0,.06);
}
.cs-sw span { font-size: var(--t-body); font-weight: 700; text-shadow: 0 1px 3px rgba(0,0,0,.25); }
.cs-sw em { font-style: normal; font-size: 10px; opacity: .85; }
.cs-sw[style*="#F7F5F0"] span, .cs-sw[style*="#f7f5f0"] span { color: #17120E; text-shadow: none; }
.cs-sw[style*="#F7F5F0"] em, .cs-sw[style*="#f7f5f0"] em { color: #6b6558; }
.cs-info { flex: 1; min-width: 0; }
.cs-codes { display: flex; flex-wrap: wrap; gap: 6px; }
.cs-code {
  font-size: var(--t-weak); font-family: Consolas, monospace;
  background: var(--card-2); border: 1px solid var(--line);
  border-radius: 4px; padding: 2px 8px; color: var(--text-2);
}
.cs-code[data-hex] { cursor: pointer; color: var(--brand); font-weight: 700; }
.cs-code[data-hex]:hover { border-color: var(--brand); }
.cs-use { font-size: var(--t-weak); color: var(--text-3); margin-top: 6px; line-height: 1.6; }
.cs-rules { margin-top: 16px; border-top: 1px dashed var(--line); padding-top: 12px; }
.cs-rule { display: flex; gap: 10px; align-items: baseline; padding: 4px 0; }
.cs-rule b {
  flex: none; width: 18px; height: 18px; border-radius: 50%;
  background: var(--brand); color: var(--on-brand); font-size: 11px;
  display: grid; place-items: center;
}
.cs-rule span { font-size: var(--t-aux); color: var(--text-2); line-height: 1.6; }

/* ================= AI 透明化：标识 / 免责 / 来源 ================= */
/* 生成图角标（叠在 AI 生成画面上） */
.p-vimg { position: relative; }
/* object-fit:cover：与导出裁切口径一致（生图 1080×1440，显示区 4/4.4），
   此前缺省 fill 会把图纵向压扁、主体位置与导出/占位态不一致；
   object-position:center top（V2.23.0 主图自适应）：生图主体限上部，保上裁下不裁头 */
.p-vimg .p-img { display: block; width: 100%; height: 100%; object-fit: cover; object-position: center top; }
.ai-badge {
  position: absolute; right: 8px; top: 8px; z-index: 4;
  display: inline-flex; align-items: center; gap: 3px;
  background: rgba(0,0,0,.62); color: var(--on-brand);
  font-size: 10px; font-weight: 600; letter-spacing: .5px;
  border-radius: 4px; padding: 2px 7px;
  backdrop-filter: blur(2px);
}
.ai-badge.static { position: static; backdrop-filter: none; background: var(--text); }
/* 免责 / 来源说明行 */
.ai-note {
  display: flex; align-items: center; gap: 5px;
  font-size: var(--t-weak); color: var(--text-3); line-height: 1.6;
}
.ai-note svg { flex: none; opacity: .7; }

/* ================= AI 生成记录页 ================= */
.gh-card { padding: 14px 16px; }
.gh-head { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
.gh-model { font-size: var(--t-weak); color: var(--text-2); font-family: Consolas, monospace; }
.gh-time { margin-left: auto; font-size: var(--t-weak); color: var(--text-3); }
.gh-prompt {
  font-size: var(--t-weak); color: var(--text-3); margin-bottom: 8px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.gh-img { cursor: zoom-in; border-radius: var(--r-m); overflow: hidden; border: 1px solid var(--line); max-width: 340px; }
.gh-img img { width: 100%; display: block; }
.gh-text {
  font-size: var(--t-aux); color: var(--text-2); line-height: 1.7;
  background: var(--card-2); border-radius: var(--r-m); padding: 10px 12px;
  max-height: 140px; overflow-y: auto; white-space: pre-wrap; word-break: break-word;
}
.gh-ops { display: flex; gap: 8px; margin-top: 10px; }

/* ================= 顶栏 ⋯ 更多菜单 ================= */
.more-wrap { position: relative; display: inline-flex; }
.more-menu {
  position: absolute; right: 0; top: calc(100% + 8px); z-index: 60;
  background: var(--card); border: 1px solid var(--line); border-radius: var(--r-btn);
  box-shadow: 0 8px 28px rgba(0,0,0,.14); padding: 5px; min-width: 138px;
}
.mm-item {
  display: flex; align-items: center; gap: 8px; width: 100%;
  padding: 9px 10px; border: 0; background: none; border-radius: 7px;
  font-size: var(--t-aux); color: var(--text); cursor: pointer; text-align: left;
}
.mm-item:hover { background: var(--hover); }
.mm-item.danger { color: var(--danger); }
.mm-item svg { width: 14px; height: 14px; flex: none; }
.mm-ver { padding: 7px 14px 5px; font-size: 11px; color: var(--text-3); border-bottom: 1px solid var(--line); margin-bottom: 4px; user-select: none; }

/* ================= 顶栏 · 皮肤选择（批二三一 五行皮肤系统） ================= */
.skin-menu { min-width: 196px; }
.skin-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 3px; }
.skin-opt {
  display: flex; align-items: center; gap: 7px; padding: 8px 9px;
  border: 1px solid transparent; border-radius: 7px; background: none;
  font-size: var(--t-aux); color: var(--text); cursor: pointer; text-align: left;
}
.skin-opt:hover { background: var(--hover); }
.skin-opt.on { border-color: var(--brand); background: var(--brand-soft); }
.skin-opt .sw {
  width: 14px; height: 14px; border-radius: 50%; flex: none;
  box-shadow: inset 0 0 0 1px rgba(0,0,0,.08);
}

/* ================= 营销日历 · 折叠月历 ================= */
.cal-month { margin-top: 10px; border-top: 1px dashed var(--line); padding-top: 10px; }
.cal-mhead {
  display: flex; align-items: center; justify-content: space-between;
  font-size: var(--t-aux); font-weight: 600; color: var(--text); margin-bottom: 8px;
}
.cm-btn {
  width: 26px; height: 26px; border-radius: 7px; cursor: pointer; line-height: 1;
  border: 1px solid var(--line); background: var(--card); color: var(--text-2); font-size: 14px;
}
.cm-btn:hover { border-color: var(--brand); color: var(--brand); }
.cal-dows {
  display: grid; grid-template-columns: repeat(7, 1fr);
  text-align: center; font-size: 10px; color: var(--text-3); margin-bottom: 4px;
}
.cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 3px; }
.cal-day {
  min-height: 42px; border-radius: 7px; border: 1px solid transparent;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  padding: 3px 1px; box-sizing: border-box;
}
.cal-day .cd-n { font-size: var(--t-weak); color: var(--text); line-height: 1.2; }
.cal-day .cd-t {
  font-size: 9px; color: var(--brand); line-height: 1.2; max-width: 100%;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; padding: 0 2px;
}
.cal-day.today { border-color: var(--gold); }
.cal-day.today .cd-n { color: var(--gold); font-weight: 700; }
.cal-day.has { cursor: pointer; background: var(--brand-soft); }
.cal-day.has:hover { border-color: var(--brand); }
.cal-day.on { background: var(--brand); border-color: var(--brand); }
.cal-day.on .cd-n, .cal-day.on .cd-t { color: var(--on-brand); }
.cal-day.empty { background: none; }

/* ================= 生成步骤（透明化） ================= */
.gf-time { margin-left: auto; flex: none; color: var(--text-3); font-size: 11px; font-family: var(--font-mono); font-variant-numeric: var(--num); white-space: nowrap; line-height: 20px; }
.gf-steps { margin-top: 10px; display: flex; flex-direction: column; gap: 6px; font-family: var(--font-mono); }
.gf-steps:empty { display: none; }
/* 步骤行：瑞士三栏网格（标记轴 | 名称 | 参数），名称零断词、参数右对齐；
   V2.21.2 dot 列承载状态图标（done✓/err✕/doing 脉冲点），名称列纯文本零前缀 */
.gf-step { display: grid; grid-template-columns: 12px minmax(0, 1fr) auto; column-gap: 8px; align-items: center; padding: 1px 0; font-size: 12px; color: var(--text-3); }
.gf-step .gf-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--line-strong); justify-self: center; }
.gf-step .gf-dot.gf-ic { width: auto; height: auto; background: none; border-radius: 0; font-size: 11px; font-weight: 700; line-height: 1; animation: none; }
.gf-step > span:nth-child(2) { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.gf-step.doing { color: var(--text); }
.gf-step.doing .gf-dot { background: var(--fx-mint); animation: gf-pulse 1s infinite; }
.gf-step.done { color: var(--text-2); }
.gf-step.done .gf-dot { background: var(--brand); }
.gf-step.err { color: var(--danger); }
.gf-step.err .gf-dot { background: var(--danger); }
/* 图标化 dot 不受底色规则影响（同特异性后写胜，须置于 done/err 规则之后） */
.gf-step.done .gf-dot.gf-ic { background: none; color: var(--brand); }
.gf-step.err .gf-dot.gf-ic { background: none; color: var(--danger); }
.gf-step .gf-d { font-size: 11px; color: var(--text-3); text-align: right; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 190px; font-variant-numeric: var(--num); }
@keyframes gf-pulse { 50% { opacity: .3; } }

/* ================= 引擎控制台（V2.21.0 生成中预览覆盖层） =================
   复古未来控制台：深松绿舱底 + 青绿单色 + CRT 纹理 + 等宽字体 + AI 日志流；
   只动 transform/opacity，纯 CSS 循环，零 JS 逐帧（日志/百分比由既有 500ms 计时器驱动） */
.poster-stage { position: relative; }
.holo-fx {
  position: absolute; inset: 0; z-index: 8; border-radius: var(--r-l);
  overflow: hidden;
  background: linear-gradient(165deg, #0A1F15 0%, var(--fx-ink) 60%, #040B08 100%);
  box-shadow: inset 0 0 80px rgba(61, 232, 176, .06), 0 10px 32px rgba(0, 0, 0, .25);
}
.holo-fx .hx-crt { position: absolute; inset: 0; pointer-events: none; opacity: .5;
  background: repeating-linear-gradient(0deg, rgba(61, 232, 176, .03) 0 1px, transparent 1px 3px); }
.holo-fx .hx-grid { position: absolute; inset: 0; opacity: .35;
  background-image: linear-gradient(rgba(61, 232, 176, .05) 1px, transparent 1px), linear-gradient(90deg, rgba(61, 232, 176, .05) 1px, transparent 1px);
  background-size: 44px 44px; }
.holo-fx .hx-scan { position: absolute; left: 0; right: 0; height: 2px; top: -2px;
  background: linear-gradient(90deg, transparent, var(--fx-mint) 35%, var(--fx-mint) 65%, transparent);
  filter: drop-shadow(0 0 8px var(--fx-mint));
  animation: hx-scanline 3.6s cubic-bezier(.45, .05, .55, .95) infinite; }
@keyframes hx-scanline { 0% { top: -2px; opacity: 0; } 8% { opacity: .9; } 92% { opacity: .9; } 100% { top: 100%; opacity: 0; } }
.holo-fx .hx-hud { position: absolute; width: 20px; height: 20px; border: 1.5px solid rgba(61, 232, 176, .55); animation: hx-hudbre 2.8s ease-in-out infinite; }
.holo-fx .hx-hud.tl { top: 12px; left: 12px; border-right: 0; border-bottom: 0; }
.holo-fx .hx-hud.tr { top: 12px; right: 12px; border-left: 0; border-bottom: 0; }
.holo-fx .hx-hud.bl { bottom: 12px; left: 12px; border-right: 0; border-top: 0; }
.holo-fx .hx-hud.br { bottom: 12px; right: 12px; border-left: 0; border-top: 0; }
@keyframes hx-hudbre { 0%, 100% { opacity: .4; } 50% { opacity: .95; } }
.holo-fx .hx-top { position: absolute; top: 16px; left: 18px; right: 18px; display: flex; align-items: center; gap: 8px;
  font-family: var(--font-mono); font-size: 10px; letter-spacing: .12em; color: rgba(61, 232, 176, .55); }
.holo-fx .hx-top .rec { width: 7px; height: 7px; border-radius: 50%; background: var(--fx-mint);
  box-shadow: 0 0 8px var(--fx-mint); animation: hx-rec 1.2s ease-in-out infinite; }
@keyframes hx-rec { 50% { opacity: .25; box-shadow: none; } }
.holo-fx .hx-top .el { margin-left: auto; font-variant-numeric: var(--num); }
.holo-fx .hx-mid { position: absolute; top: 15%; left: 18px; right: 18px; }
.holo-fx .hx-label { font-family: var(--font-mono); font-size: 10px; letter-spacing: .3em; color: rgba(61, 232, 176, .55); margin-bottom: 4px; }
.holo-fx .hx-pct { font-family: var(--font-mono); font-size: 60px; font-weight: 700; letter-spacing: -.04em; line-height: 1;
  color: #D8FFF0; text-shadow: 0 0 24px rgba(61, 232, 176, .45); }
.holo-fx .hx-pct small { font-size: 20px; font-weight: 400; color: rgba(61, 232, 176, .55); }
.holo-fx .hx-phase { margin-top: 8px; font-size: 12.5px; color: rgba(216, 255, 240, .85); letter-spacing: .06em; }
.holo-fx .hx-cells { display: flex; gap: 3px; margin-top: 14px; }
.holo-fx .hx-cells i { width: 14px; height: 5px; background: rgba(61, 232, 176, .15); border-radius: 1px; transition: background .3s, box-shadow .3s; }
.holo-fx .hx-cells i.on { background: var(--fx-mint); box-shadow: 0 0 6px rgba(61, 232, 176, .7); }
.holo-fx .hx-log { position: absolute; left: 18px; right: 18px; bottom: 38px;
  font-family: var(--font-mono); font-size: 10.5px; line-height: 1.9; color: rgba(61, 232, 176, .8); }
.holo-fx .hx-log .ln { opacity: 0; transform: translateX(-4px); transition: opacity .3s, transform .3s;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.holo-fx .hx-log .ln.in { opacity: 1; transform: none; }
.holo-fx .hx-log .ln .ok { color: #8AFFD6; }
.holo-fx .hx-log .ln .dim { color: rgba(61, 232, 176, .45); }
.holo-fx .hx-log .cur { display: inline-block; width: 7px; height: 12px; background: var(--fx-mint); vertical-align: -2px; animation: hx-rec .9s steps(2) infinite; }
.holo-fx .hx-bot { position: absolute; left: 18px; right: 18px; bottom: 14px; display: flex; justify-content: space-between;
  font-family: var(--font-mono); font-size: 9px; letter-spacing: .1em; color: rgba(61, 232, 176, .4); }
/* 完成实体化：glitch 一闪定格（加在预览首个容器上） */
/* V2.49.33 生成中图带骨架（李叔 10-07「期间没有任何加载状态、进度提示」）：
   斜向微光在「主视觉这一格」上扫过——引擎控制台负责「正在跑」的气氛，
   骨架负责把事实说清楚：这一格在等主视觉，不是坏了。两版式（经典/融合 + 促销六形式）共用 */
.p6-skel {
  position: absolute; inset: 0; overflow: hidden; pointer-events: none;
  background: linear-gradient(100deg, rgba(255,255,255,0) 30%, rgba(255,255,255,.16) 50%, rgba(255,255,255,0) 70%);
  background-size: 240% 100%;
  animation: p6-skel-run 1.6s linear infinite;
}
@keyframes p6-skel-run { 0% { background-position: 140% 0; } 100% { background-position: -40% 0; } }
.hx-final { animation: hx-glitch .7s steps(1); }
@keyframes hx-glitch {
  0% { opacity: 0; transform: translateX(-6px); filter: hue-rotate(40deg) saturate(3) brightness(1.8); }
  18% { opacity: 1; transform: translateX(4px); filter: hue-rotate(-30deg) saturate(2); }
  36% { transform: translateX(-2px); filter: none; }
  54% { transform: translateX(1px); }
  100% { opacity: 1; transform: none; filter: none; }
}
/* 降级：系统减弱动效 → 全部静态 */
@media (prefers-reduced-motion: reduce) {
  .holo-fx .hx-scan, .holo-fx .hx-hud, .holo-fx .hx-top .rec, .holo-fx .hx-log .cur,
  .gf-bar::after, .hx-final, .p6-skel { animation: none !important; }
}

/* ================= 图片来源角标 / 记录按钮 ================= */
.p-rec {
  position: absolute; left: 8px; top: 8px; z-index: 4; cursor: pointer;
  background: rgba(0,0,0,.5); color: var(--on-brand); backdrop-filter: blur(2px);
  font-size: 10px; border-radius: 4px; padding: 2px 7px;
}
.p-rec:hover { background: rgba(0,0,0,.72); }
/* 节庆装饰开关 chip（V2.38.0 P2）：「记录」正下方同列，关闭态降透明度 */
.p-deco-toggle {
  position: absolute; left: 8px; top: 34px; z-index: 5; cursor: pointer;
  background: rgba(0,0,0,.5); color: var(--on-brand); backdrop-filter: blur(2px);
  font-size: 10px; border-radius: 4px; padding: 2px 7px;
}
.p-deco-toggle:hover { background: rgba(0,0,0,.72); }
.p-deco-toggle.is-off { opacity: .45; }
.p-re-main {
  position: absolute; right: 8px; bottom: 8px; z-index: 4; cursor: pointer;
  display: inline-flex; align-items: center; gap: 5px;
  background: rgba(0,0,0,.55); color: var(--on-brand); backdrop-filter: blur(2px);
  font-size: 10px; border-radius: 4px; padding: 3px 8px;
}
.p-re-main:hover { background: rgba(30,122,70,.85); }

/* ================= 主图调位（V2.24.0）：图带右上悬浮钮（AI 徽标正下方）+ 调位模式提示条 ================= */
.p-badj {
  position: absolute; right: 8px; top: 34px; z-index: 7; cursor: pointer;
  display: inline-flex; align-items: center; gap: 4px;
  background: rgba(0,0,0,.55); color: var(--on-brand); backdrop-filter: blur(2px);
  font-size: 10px; border-radius: 4px; padding: 3px 8px; user-select: none;
}
.p-badj:hover { background: rgba(0,0,0,.75); }
.p-badj.on { background: var(--brand); }
/* 调位模式：图带虚线高亮；全程禁文本选择（拖拽不蓝屏/白块） */
.band-adj-on { outline: 2px dashed rgba(255,255,255,.9); outline-offset: -2px; }
.band-adj-on, .band-adj-on * { user-select: none; -webkit-user-select: none; }
/* 调位提示条：图带内顶部居中（两角徽标不挡、不压底部标题），不进导出（导出走模板字符串非 DOM） */
.band-adj-bar {
  position: absolute; left: 50%; top: 10px; transform: translateX(-50%); z-index: 8;
  display: flex; align-items: center; gap: 8px; white-space: nowrap;
  max-width: calc(100% - 12px);
  background: rgba(0,0,0,.66); color: var(--on-brand); backdrop-filter: blur(3px);
  font-size: 11px; border-radius: var(--r-pill); padding: 5px 8px 5px 14px;
}
.band-adj-bar .bab-t { opacity: .85; overflow: hidden; text-overflow: ellipsis; }
.band-adj-bar .bab-btn {
  border: 1px solid rgba(255,255,255,.45); background: transparent; color: var(--on-brand);
  border-radius: var(--r-pill); padding: 3px 12px; font-size: 11px; cursor: pointer; font-family: inherit;
}
.band-adj-bar .bab-btn:hover { background: rgba(255,255,255,.14); }
.band-adj-bar .bab-btn.on { background: var(--brand); border-color: var(--brand); }

/* ================= 融合版头图 3.0（满幅画面；白卡容器 / 渐变压字 两种底块） ================= */
.p-vimg.fuse { position: relative; }
.p-vimg.fuse .p-img { width: 100%; height: 100%; display: block; object-fit: cover; }

/* 融合·白卡：底部白色容器，层级 = 眉毛行 → 取色大标题 → 金条副标题 → 小字脚 */
.pf-card {
  position: absolute; left: 12px; right: 12px; bottom: 12px; z-index: 2;
  background: var(--white); border-radius: 16px; box-shadow: 0 12px 32px rgba(0,0,0,.24);
  padding: 14px 17px 12px; color: #1a1a1a;
}
.pf-card .pc-top { display: flex; justify-content: space-between; align-items: center; font-size: 9.5px; letter-spacing: 2px; color: #999; }
.pf-card .pc-brand { font-weight: 600; }
.pf-card .pc-date { border: 1.5px solid currentColor; border-radius: var(--r-pill); padding: 1px 10px; font-weight: 600; font-size: 9.5px; color: #888; }
.pf-card .pc-title { font-size: 26px; font-weight: 800; letter-spacing: 1px; line-height: 1.24; margin-top: 9px; }
.pf-card .pc-sub { display: flex; align-items: center; gap: 8px; font-size: 11.5px; color: #666; margin-top: 7px; }
.pf-card .pc-sub .bar { width: 20px; height: 3px; background: var(--poster-gold, #C9A227); border-radius: 2px; flex: none; }
.pf-card .pc-foot {
  display: flex; justify-content: space-between; align-items: center;
  margin-top: 10px; padding-top: 8px; border-top: 1px solid #f0f0f0;
  font-size: 9.5px; color: #999; letter-spacing: 1px;
}

/* 融合·渐变（v9 定稿 F5-a）：顶部暗纱+logo / 金眉行+拖尾线 / 大标题 / 金短线 / 商品清单+省金 / slogan+门店地址
   —— cqw 等比体系（导出 px / 1080 × 100）：预览即导出的严格等比缩略，断行点一致 —— */
.p-gradshade {
  position: absolute; left: 0; right: 0; top: 0; height: 38.9cqw; z-index: 2; pointer-events: none;
  background: linear-gradient(180deg, rgba(21,33,29,.55), rgba(21,33,29,0));
}
.p-gradlogo {
  position: absolute; left: 5.19cqw; top: 13.9cqw; height: 6.67cqw; width: auto; z-index: 2; display: block;
  filter: drop-shadow(0 0.19cqw 0.74cqw rgba(0,0,0,.35));
}
.pf-grad {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 2;
  padding: 38.9cqw 5.19cqw 5.19cqw; color: var(--on-brand);
}
.pf-grad .pg-brow { display: flex; align-items: center; }
/* 时间副标题（V2.13.1 动态配色）：字色/阴影/眉线色由 JS browStyleOf() 按主图背景
   WCAG 对比度计算后内联注入（见 app.js fuseGradHtml），此处 color 仅作首绘前兜底 */
.pf-grad .pg-brow-t { font-size: 2.78cqw; font-weight: 700; letter-spacing: 0.56cqw; color: #E8C65A; white-space: nowrap; }
.pf-grad .pg-brow-line { flex: 1; height: 0.19cqw; background: rgba(232,198,90,.4); margin-left: 2.22cqw; }
.pf-grad .pg-title { font-size: 11.1cqw; font-weight: 900; letter-spacing: 0.37cqw; line-height: 1.16; margin-top: 1.48cqw; text-shadow: 0 0.37cqw 2.22cqw rgba(0,0,0,.4); }
.pf-grad .pg-goldbar { width: 5.93cqw; height: 0.74cqw; background: var(--poster-gold, #C9A227); border-radius: 0.37cqw; margin-top: 2.22cqw; }
.pf-grad .pg-sub { font-size: 3.33cqw; font-weight: 700; letter-spacing: 0.19cqw; opacity: .92; margin-top: 1.85cqw; }
.pf-grad .pg-items { margin-top: 2.22cqw; }
.pf-grad .pg-item {
  display: flex; justify-content: space-between; align-items: baseline;
  padding: 1.85cqw 0; border-bottom: 0.19cqw solid rgba(255,255,255,.14);
}
.pf-grad .pgi-name { font-size: 4.44cqw; font-weight: 700; letter-spacing: 0.09cqw; }
.pf-grad .pgi-price { text-align: right; line-height: 1; white-space: nowrap; }
.pf-grad .pgi-price .yen { font-size: 2.78cqw; font-weight: 800; }
.pf-grad .pgi-price .int { font-size: 6.67cqw; font-weight: 900; letter-spacing: -0.09cqw; }
.pf-grad .pgi-price .dec { font-size: 3.33cqw; font-weight: 900; }
.pf-grad .pgi-price .unit { font-size: 2.41cqw; font-weight: 600; opacity: .6; }
.pf-grad .pgi-price .save { display: block; font-size: 2.41cqw; font-weight: 700; color: #E8C65A; letter-spacing: 0.05cqw; margin-top: 0.56cqw; }
.pf-grad .pg-foot {
  display: flex; justify-content: space-between; align-items: center;
  margin-top: 2.96cqw; padding-top: 2.59cqw; border-top: 0.19cqw solid rgba(255,255,255,.14);
  font-size: 2.41cqw; letter-spacing: 0.28cqw; opacity: .85;
}
.pf-grad .pg-addr { color: #E8C65A; font-weight: 700; opacity: 1; max-width: 58%; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; text-align: right; }

/* 数字排版统一：价格 / 表格数字等宽对齐，多位数字上下不跳动 */
.pf-grad .pgi-price, .table .num, .table td.num { font-variant-numeric: var(--num); }

.poster.fuse { padding: 0; overflow: hidden; }
.poster.fuse .p-vimg { border-radius: 0; }
/* 长图融合占位：必须显式 text-align:left——.poster .p-ph 基类带 text-align:center，
   会继承进绝对定位的 .pf-grad 头块，导致生成前标题/副标题居中、生成后左对齐（前后排版不一致 BUG） */
.p-ph.fuse { position: relative; display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: left; }
/* 渐变占位提示：墨底胶囊钉顶部居中（浅灰占位底上清晰可见），避免与底部头块挤一起 */
.p-ph.fuse .p-ph-hint {
  position: absolute; top: 26px; left: 50%; transform: translateX(-50%); z-index: 2;
  width: max-content; max-width: 86%; padding: 8px 16px 9px; border-radius: var(--r-pill);
  background: rgba(21,33,29,.42);
  text-align: center; color: rgba(255,255,255,.92); font-size: 11px; letter-spacing: 2px;
  pointer-events: none;
}
.p-ph.fuse .p-ph-hint span { font-size: 9.5px; letter-spacing: .5px; opacity: .85; }
.p-ph-fuse {
  position: absolute; inset: 0; z-index: 2; display: flex; flex-direction: column;
  align-items: center; justify-content: flex-start; padding-top: 30px; color: rgba(255,255,255,.92);
  font-size: 13px; text-align: center; text-shadow: 0 1px 6px rgba(0,0,0,.4); pointer-events: none;
}
.p-ph-fuse span { font-size: 11px; opacity: .85; margin-top: 4px; }
/* 占位提示胶囊：半透明墨底，浅灰占位/图上均清晰可见 */
.p-ph-fuse .p-ph-chip {
  display: inline-block; font-style: normal; background: rgba(21,33,29,.42);
  padding: 9px 18px 10px; border-radius: var(--r-pill); backdrop-filter: blur(2px);
}
.p-ph-fuse .p-ph-chip span { display: block; }

/* ================= 瀑布流卡片（AI记录 / 图库 / 我的产出） ================= */
.masonry { column-count: 3; column-gap: 12px; }
@media (max-width: 1280px) { .masonry { column-count: 2; } }
/* 图片型网格（全员/我的产出、商品图库）6 列高密度瀑布流（李叔 09-27：双列/三列信息密度过低）。
   按桌面视口逐级降列，卡片宽度保持可读 */
.masonry.gal6 { column-count: 6; column-gap: 10px; }
.masonry.gal6 .m-item { margin-bottom: 10px; }
@media (max-width: 1500px) { .masonry.gal6 { column-count: 5; } }
@media (max-width: 1200px) { .masonry.gal6 { column-count: 4; } }
.m-item {
  /* position:relative（V2.35.0）：商品图库卡片右上角 ✎ 改名钮靠它定位 */
  position: relative;
  break-inside: avoid; margin-bottom: 12px; cursor: pointer;
  background: var(--card); border: 1px solid var(--line); border-radius: var(--r-btn); overflow: hidden;
  transition: box-shadow .15s ease, transform .15s ease;
}
.m-item:hover { box-shadow: 0 6px 18px rgba(0,0,0,.10); transform: var(--lift-1); }
.m-item .m-img { width: 100%; display: block; background: var(--hover); }
.m-meta { padding: 8px 10px 10px; }
.m-t { font-size: var(--t-aux); font-weight: 600; color: var(--text); display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.m-d { font-size: var(--t-aux); color: var(--text-2); margin-top: 3px; line-height: 1.5; }
.m-text {
  padding: 10px 12px; font-size: var(--t-aux); color: var(--text-2); line-height: 1.7;
  max-height: 132px; overflow: hidden; position: relative;
}
.m-text::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 40px;
  background: linear-gradient(transparent, var(--card));
}
.m-kind {
  display: inline-block; font-size: 10px; border-radius: 4px; padding: 1px 6px; flex: none;
  background: var(--brand-soft); color: var(--brand);
}
.m-kind.llm { background: rgba(201,162,39,.14); color: #9a7b14; }
/* 图片用途角标（V2.27.0）：主图=品牌松绿（默认），商品图=淡蓝，未标注=中性灰 */
.m-kind.prod { background: rgba(43,108,176,.12); color: #2b6cb0; }
.m-kind.unknown { background: rgba(120,120,120,.12); color: #6b6b6b; }

/* 图片详情浮层 */
/* V2.36.0 方案A：详情弹窗重排（李叔 09-30 截图派单）
   旧版操作按钮排在右侧 45% 窄栏（.id-side .d-ops），5 钮各分不到 60px 导致文字竖断，
   本版改为弹窗通栏底条 .d-opsbar（已删除旧的 .id-side .d-ops 规则，无残留） */
.id-dialog {
  width: min(760px, 92vw); max-height: 88vh;
  display: flex; flex-direction: column; position: relative; overflow: hidden;
}
.id-imgwrap {
  flex: 1 1 55%; min-width: 0; display: flex; align-items: flex-start; justify-content: center;
  background: var(--hover); border-radius: var(--r-btn); overflow: hidden;
}
.id-imgwrap img { max-width: 100%; max-height: 76vh; display: block; object-fit: contain; cursor: zoom-in; }
.id-body { display: flex; gap: 16px; padding: 16px; flex: 1; min-height: 0; overflow: auto; }
.id-side { flex: 1 1 45%; min-width: 0; display: flex; flex-direction: column; }
.id-side .d-b { flex: 1; }
/* 右上独立关闭：位置让位给通栏操作条后，∁ 不再与危险操作争）
   z-index 5 保证压在标题与信息之上 */
.id-x {
  position: absolute; top: 10px; right: 12px; z-index: 5;
  width: 30px; height: 30px; border: 0; border-radius: 50%;
  background: var(--hover); color: var(--text-2); font-size: 15px; line-height: 1;
  display: grid; place-items: center; cursor: pointer; transition: background .15s, color .15s;
}
.id-x:hover { background: rgba(0, 0, 0, .1); color: var(--text); }
/* 通栏操作条：宽由 45% 窄栏 → 弹窗全宽，每钮 ≥120px 不再竖字；主钮独占富余宽度 */
.d-opsbar { border-top: 1px solid var(--line); background: var(--card); padding: 12px 16px; display: flex; gap: 10px; align-items: center; }
/* min-width 保底：按钮再多也不至于被挤成窄条（删除这类短钮同样体面、好点） */
.d-opsbar .btn { min-height: 40px; min-width: 104px; white-space: nowrap; flex: none; }
.d-opsbar .btn.primary { flex: 1; }
.d-opsbar .btn .ic { font-size: 15px; line-height: 1; }
/* 信息分组小标题（文件 / 导出 / 图源） */
.d-grp { margin-top: 12px; }
.d-grp:first-child { margin-top: 10px; }
.d-grp .gt { font-size: var(--t-aux); color: var(--text-3); letter-spacing: 2px; margin-bottom: 2px; }
.rec-row b.hl { color: var(--brand); font-weight: 600; }
.rec-row b.mut { color: var(--text-3); font-weight: 400; }
.rec-row b.brand { color: var(--brand); }
.id-prompt {
  margin-top: 8px; padding: 8px 10px; background: var(--hover); border-radius: 8px;
  font-size: var(--t-weak); color: var(--text-2); line-height: 1.6;
  max-height: 160px; overflow: auto; word-break: break-all; user-select: text;
}

/* ================= 生成记录弹窗 ================= */
.rec-row {
  display: flex; align-items: baseline; gap: 10px; font-size: var(--t-aux);
  padding: 4px 0; border-bottom: 1px dashed var(--line);
}
.rec-row span { flex: none; width: 76px; color: var(--text-3); font-size: var(--t-weak); }
.rec-row b { color: var(--text); font-weight: 600; word-break: break-all; }
.rec-prompt {
  margin-top: 8px; font-size: var(--t-weak); color: var(--text-2); line-height: 1.7;
  background: var(--card-2); border-radius: var(--r-m); padding: 10px 12px;
  max-height: 130px; overflow-y: auto; white-space: pre-wrap; word-break: break-word;
}

/* ================= 风格头图悬停大图预览 ================= */
#stylePreview {
  position: fixed; z-index: 90; width: 240px; pointer-events: none;
  background: var(--card); border: 1px solid var(--line); border-radius: 12px;
  box-shadow: 0 12px 40px rgba(0,0,0,.18); padding: 10px; box-sizing: border-box;
  opacity: 0; transform: translateY(6px) scale(.96);
  transition: opacity var(--dur) ease, transform var(--dur) ease;
}
#stylePreview.show { opacity: 1; transform: translateY(0) scale(1); }
#stylePreview.below { transform: translateY(-6px) scale(.96); }
#stylePreview.below.show { transform: translateY(0) scale(1); }
#stylePreview .sp-top { height: 140px; border-radius: 8px; border: 1px solid var(--line); overflow: hidden; position: relative; }
#stylePreview .sp-top .sw { position: absolute; inset: 0; height: 100%; display: block; }
#stylePreview .sp-preview { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; }
#stylePreview .sp-name { font-size: 14px; font-weight: 700; color: var(--text); margin-top: 8px; }
#stylePreview .sp-short { font-size: var(--t-aux); color: var(--text-2); margin-top: 2px; }
#stylePreview .sp-tip { font-size: 10px; color: var(--brand); margin-top: 6px; }
/* 批一七五：仅排版层卡的浮层提示——不写绿色（绿色=可点），降为副文字色 */
#stylePreview .sp-tip.locked { color: var(--text-2); }

/* ================= 新版本提示横幅 ================= */
.ver-banner {
  display: flex; align-items: center; justify-content: center; gap: 12px;
  padding: 8px 16px; font-size: var(--t-weak);
  background: var(--brand-soft); color: var(--brand);
  border-bottom: 1px solid var(--line);
}
.ver-banner button {
  border: 1px solid var(--brand); background: var(--brand); color: var(--on-brand);
  font-size: var(--t-weak); border-radius: 6px; padding: 3px 12px; cursor: pointer;
}
.ver-banner button:hover { background: var(--brand-press); }

/* ================= 批量导入向导（三步） ================= */
.imp-steps { display: flex; align-items: center; gap: 8px; margin-bottom: 12px; }
.imp-step {
  display: flex; align-items: center; gap: 6px;
  font-size: var(--t-aux); color: var(--text-3);
  transition: color .2s ease;
}
.imp-step i {
  width: 20px; height: 20px; border-radius: 50%;
  display: grid; place-items: center;
  font-size: var(--t-weak); font-style: normal;
  background: var(--hover); color: var(--text-3);
  transition: background .2s ease, color .2s ease;
}
.imp-step.on { color: var(--text); font-weight: 600; }
.imp-step.on i { background: var(--brand); color: var(--on-brand); }
.imp-step.done { color: var(--brand); }
.imp-step.done i { background: var(--brand-soft); color: var(--brand); }
.imp-step-sep { flex: 0 0 22px; height: 1px; background: var(--line-strong); }

/* 第①步：拖拽上传区 */
.imp-drop {
  border: 1.5px dashed var(--line-strong);
  border-radius: var(--r-l);
  background: var(--card-2);
  padding: 30px 16px;
  text-align: center;
  cursor: pointer;
  transition: border-color .2s ease, background .2s ease;
}
.imp-drop:hover { border-color: var(--brand); }
.imp-drop.over {
  border-color: var(--brand);
  background: var(--brand-soft);
}
.imp-drop-ico { color: var(--brand); margin-bottom: 8px; }
.imp-drop-t { font-size: var(--t-body); color: var(--text); }
.imp-drop-t .imp-link { color: var(--brand); font-weight: 600; text-decoration: underline; }
.imp-drop-s { font-size: var(--t-weak); color: var(--text-3); margin-top: 6px; }
.imp-paste-tg {
  margin-top: 10px;
  font-size: var(--t-aux); color: var(--text-2);
  display: flex; align-items: center; gap: 4px;
  border-radius: var(--r-s); padding: 4px 6px;
  transition: background .15s, color .15s;
}
.imp-paste-tg:hover { background: var(--hover); color: var(--text); }
.imp-paste-tg .imp-paste-arrow { transition: transform .2s ease; }
.imp-paste-tg.open .imp-paste-arrow { transform: rotate(180deg); }

/* 第②步：映射 + 预览 */
.imp-file-line {
  display: flex; align-items: center; gap: 6px;
  font-size: var(--t-aux); color: var(--text-2); margin-bottom: 10px;
}
.imp-nohd {
  margin-left: 6px; padding: 1px 7px;
  font-size: var(--t-weak); color: var(--warn);
  background: var(--warn-soft); border-radius: 5px;
}
/* 批四四〇 · 表头行 / 数据起始行的确认条（自适应表头识别）
   为什么必须给：真样本表头在第 2 行，系统固定取第 1 行 ⇒ 62 行全错且无从自救。 */
.imp-hdrbar {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 9px 11px; margin-bottom: 9px;
  background: var(--brand-soft); border: 1px solid var(--brand); border-radius: var(--r-m);
}
.imp-hdrbar label { font-size: var(--t-weak); color: var(--text-2); }
.imp-hdr-s { padding: 4px 7px; font-size: var(--t-weak); min-width: 84px; }
.imp-cands { display: flex; align-items: center; gap: 6px; font-size: var(--t-weak); color: var(--text-2); }
.imp-cand-b {
  padding: 3px 9px; border: 1px solid var(--brand); background: var(--card);
  color: var(--brand); border-radius: 12px; font-size: var(--t-weak); cursor: pointer;
}
.imp-cand-b:hover { background: var(--brand-soft); }
.imp-cand-b.on { background: var(--brand); color: #fff; }
.imp-why {
  font-size: var(--t-weak); color: var(--text-2); line-height: 1.75;
  background: var(--card-2); border-left: 3px solid var(--brand);
  padding: 7px 11px; border-radius: 0 var(--r-m) var(--r-m) 0; margin-bottom: 10px;
}
.imp-why b { color: var(--brand); }
.imp-map { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 10px; }
.imp-col {
  display: flex; flex-direction: column; gap: 4px;
  min-width: 108px; max-width: 150px;
  padding: 7px 9px;
  border: 1px solid var(--line); border-radius: var(--r-m);
  background: var(--card-2);
  transition: opacity .2s ease, border-color .2s ease;
}
.imp-col.off { opacity: .55; }
.imp-col-h {
  font-size: var(--t-weak); color: var(--text-2);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* 源列示例值（批四四〇）：真样本 23 列，只看列名（销售规格 / 销售单位）
   根本判断不出该选哪个——必须让用户看见这一列装的什么。 */
.imp-col-ex {
  font-size: var(--t-weak); color: var(--text-2); opacity: .78;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  font-family: ui-monospace, Menlo, Consolas, monospace;
}
/* 并列歧义：标黄提示人工确认，绝不静默拍板（机器没有立场判断零售口径） */
.imp-col.amb { border-color: var(--warn); background: var(--warn-soft); opacity: 1; }
.imp-col-s { padding: 4px 6px; font-size: var(--t-weak); }
.imp-sum { font-size: var(--t-aux); color: var(--text-2); margin-bottom: 6px; }
.imp-ok { color: var(--brand); font-weight: 600; }
.imp-bad-t { color: var(--danger); }
.imp-prev {
  max-height: 320px; overflow-y: auto;
  border: 1px solid var(--line); border-radius: var(--r-m);
  padding: 4px 8px;
}
.imp-table td { font-size: var(--t-aux); padding: 5px 6px; }
.imp-table .imp-no { color: var(--text-3); width: 30px; }
.imp-table .imp-empty { color: var(--text-3); }
.imp-table tr.imp-bad td { background: var(--danger-soft); }
.imp-table tr.imp-bad td:first-child { border-radius: var(--r-s) 0 0 var(--r-s); }
.imp-table tr.imp-bad td:last-child { border-radius: 0 var(--r-s) var(--r-s) 0; }

/* 第③步：结果 */
.imp-result { padding-top: 2px; }
.imp-res-counts { display: flex; gap: 18px; font-size: var(--t-card); margin-bottom: 12px; }
.imp-sec {
  border: 1px solid var(--line); border-radius: var(--r-m);
  background: var(--card-2);
  padding: 8px 12px; margin-bottom: 8px;
}
.imp-sec summary { font-size: var(--t-aux); color: var(--text-2); cursor: pointer; }
.imp-sec .imp-names { font-size: var(--t-aux); color: var(--text); margin-top: 6px; line-height: 1.7; }
.imp-sec-t { font-size: var(--t-aux); font-weight: 600; color: var(--text); margin-bottom: 6px; }
.imp-fail {
  display: flex; align-items: baseline; gap: 10px;
  font-size: var(--t-aux); padding: 3px 0;
}
.imp-fail-no { color: var(--text-3); flex: none; }
.imp-fail-t { color: var(--danger); flex: none; }
.imp-fail-raw {
  color: var(--text-3); font-size: var(--t-weak);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* ================= 图片识别（批三八四 · 李叔 2026-10-12） =================
   与 imp-* 同语言：步骤条/拖放区/汇总行/预览表全部复用；此处只补识别专有件。
   三态配色沿用系统既有语义：✅=--brand（同 imp-ok）/ ⚠️=--warn / ❌=--danger。 */
.ir-files { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 10px; }
.ir-file {
  display: inline-flex; align-items: center; gap: 8px;
  max-width: 100%; padding: 5px 10px;
  background: var(--card); border: 1px solid var(--line);
  border-radius: var(--r-pill, 999px); font-size: var(--t-weak);
}
.ir-file-nm {
  max-width: 180px; color: var(--text-2);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.ir-file-st { flex: none; font-weight: 600; }
.ir-file-st.st-done { color: var(--brand); }
.ir-file-st.st-err { color: var(--danger); }
.ir-file-st.st-wait { color: var(--text-3); }
.ir-file-rm { flex: none; color: var(--text-3); cursor: pointer; padding: 0 2px; }
.ir-file-rm:hover { color: var(--danger); }
/* 识别中「当前任务卡」（批四〇二 · 李叔「重复进度展示」+「太平了」→ 批四一五 · 李叔「太大太空」
   → 批四五四 · 李叔「UI界面和动效反馈，太粗俗了」）
   ─────────────────────────────────────────────────────────────────────────────────────────
   ① 去重：文件 chip 的「上传识别中 49%」与扫描卡的进度条/百分比/文件名/阶段末段是
      **同一份信息说两遍**，合并为一张卡——文件身份归头、进度归身；
      🔴 批四一五 再改：**动作不再归脚**——卡片自带「重新上传/中断」＝底部 #irBack/#irStop2
      的第二份，同屏两份才是「不符合整体设计理念」最硬的一条，动作一律回操作栏。
   ② 🔴🔴 批四五四「太粗俗」五连修（李叔 2026-10-14 截图报障，渲染图方案 A 拍板）：
      a. **十分位秒表撤卡**——旧头行「已用 6.6s」300ms 一跳、末位每秒跳 3 次，
         是监控仪表盘语汇，越等越焦（主凶）。活着证明交给条子本体的缓动滑行；
         「第 N/M 张」已回答批量进度。elapsedMs 保留在 stat 里但不上屏。
      b. **百分比降为侍读**——从头流 21.5px 品牌色粗体（--t-page 大字段）降为状态行
         12.5px 灰字（--t-aux）。扫描段进度本是缓动估值，大字号＝给假精确加冕。
      c. **进度条去渐变**——linear-gradient(--brand→--gold) 是全仓唯一渐变条（闪光语汇），
         改素色 --brand；6px→4px；过渡 --dur .16s → --dur-glide .5s + --ease-soft，
         与 500ms 心跳同频 ⇒ 连续滑行，不再小步蠕颤。
      d. **✓三段清单 → 单态胶囊**——「✓读取·✓压缩·[上传识别]」是公文勾选语汇，
         只留当前段一枚胶囊（读取中/压缩中/识别中），已完成段不打勾、未到段不罗列。
      e. **单心跳**——报点（irScanOne 内 setInterval）与绘点（irTick）统一 500ms，
         数字/条宽/阶段同帧出，不再两个时钟互相追赶。
   ③ 批四一五 瘦身（李叔「视觉太大太空了」）：旧版六层堆叠——38px 图标 / 26px 大数字 /
      10px 粗条 / 「预计 10–60 秒」提示句 / 带 border-top 的阶段条 / 页脚按钮行，
      静态实量 **313px**（早先注释里的 230px 是手算、漏了页脚按钮行与各层 padding，已订正）；
      而同页同级卡片（.io-partial、.ir-sum-line）都在 60–110px，
      它就是屏上最"胖"的一块 ⇒ 这才是"太空"的真身。现为三行：
      头行（图标+文件名+第 N/M 张+✕）/ 4px 全宽细线 / 状态行（当前段胶囊+侍读百分比）。
   ④ 零裸色：色值全走 tokens.css；字号只用 --t-aux / --t-body / --t-card / --t-page（零写死字号）。 */
.ir-run {
  position: relative; margin: 10px 0; overflow: hidden;
  background: var(--card); border-radius: var(--r-card); box-shadow: var(--shadow-2);
}
.ir-run::before { content: ''; position: absolute; left: 0; top: 0; bottom: 0; width: 3px; background: var(--brand); }
.ir-run-hd {
  display: flex; align-items: center; gap: 10px;
  padding: 12px 14px; min-height: 32px;
}
.ir-run-ic {
  width: 32px; height: 32px; flex: none; border-radius: var(--r-btn);
  background: var(--brand-soft); color: var(--brand);
  display: flex; align-items: center; justify-content: center;
}
/* 名字吃掉剩余宽度，右簇＝第 N/M 张 · 百分比 · 已用时 · ✕。
   ★ 长文件名必须单行省略：一换行就变两行，瘦身等于白做。 */
.ir-run-nm {
  flex: 1 1 auto; min-width: 0;
  font-size: var(--t-body); font-weight: 600; color: var(--text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* 百分比（批四五四 · 李叔「UI界面和动效反馈，太粗俗了」）：
   从头流 21.5px 品牌色粗体大数字 **降为状态行侍读**——12.5px 灰字、字号档 --t-aux、
   挪到阶段行右端（margin-left:auto）。三条理由：
   ① 头部六件套（图标+名+第N/M+%+秒+✕）密度过高，百分比与秒表凑成"仪表盘四件套"；
   ② 扫描段进度本是 irScanPct 缓动估值（封顶 95%），大字号＝给假精确加冕；
   ③ 卡片的安静感靠"只有一个轻声说话的东西"——现在那是阶段胶囊，百分比只作陪侍。
   （progress 仍是真节点：data-irscanpct 局部刷新，守闸钉着，不许退成静态串。） */
.ir-run-pct {
  flex: none; margin-left: auto;
  font-size: var(--t-aux); font-weight: 500; color: var(--text-2);
  font-variant-numeric: var(--num); line-height: 1;
}
.ir-run-x {
  width: 26px; height: 26px; flex: none; border: 0; background: transparent;
  color: var(--text-3); border-radius: 50%; cursor: pointer; font-size: var(--t-aux);
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.ir-run-x:hover { background: var(--line); color: var(--text); }
/* 4px 全宽细线（批四五四）：6px→4px、**去渐变改素色品牌线**、圆角、滑行 0.5s。
   旧版 linear-gradient(90deg, --brand, --gold) 是全仓唯一一处渐变条——"闪光"语汇，
   与素色体系打架；160ms 过渡配 300ms 心跳＝条子小步蠕颤（李叔「粗俗」的动效主凶）。
   现在：宽度过渡走 --dur-glide(.5s) + --ease-soft，与 500ms 心跳同频 ⇒ 连续滑行。
   槽底仍吃 --card-2（浅灰）与白卡身形成对比，不加 inset 阴影（那要写裸色值）。 */
.ir-run-bar {
  height: 4px; background: var(--card-2); overflow: hidden; border-radius: var(--r-pill);
}
.ir-run-bar > i {
  display: block; height: 100%;
  background: var(--brand); border-radius: var(--r-pill);
  transition: width var(--dur-glide) var(--ease-soft);
}
.ir-run-st { padding: 9px 14px 11px; }
/* 阶段行（批四〇〇 去步骤条化 → 批四〇二 当前段升为胶囊 → 批四五四 单态短语）：
   只回答一个问题——**现在卡在哪一段**。旧版三段罗列（✓读取·✓压缩·[上传识别]）是
   公文勾选清单语汇：已完成段打勾堆在当前段胶囊旁，三种视觉重量抢一件事（李叔判粗）。
   现在只留**当前段一枚胶囊**（品牌浅底+品牌色），右端陪侍百分比（.ir-run-pct）。
   不画圆圈、不画连接线、不打勾、不罗列未到段——它不是路线图，是"现在进行到哪儿"。
   批四五四 连带删除两条规则：段间 5px 圆点（单态下无段间可分隔）与已完成段灰字
   （✓清单退役后没有"已过段"这个态）——死规则留着＝下次又被抄回来。 */
.ir-stages {
  display: flex; align-items: center; gap: 8px;
  font-size: var(--t-aux);
}
.ir-stage { padding: 3px 10px; border-radius: var(--r-pill); color: var(--text-2); white-space: nowrap; }
.ir-stage.on { background: var(--brand-soft); color: var(--brand); font-weight: 700; }
/* 🔴 表格内的输入框不许被「表单控件」的 min-height 兜底撑高（批三九五，探针量出来的）：
   `.studio-page .input { min-height: var(--h-ctl) }`（44px，2963 行）是给**表单页**的兜底，
   商品表继承了它 → 每个单元格 44px，核对行「同格上下排」直接翻倍到 **93px/行**
   （李叔判"识别太占位置"）。表格要的是紧凑一行，不是表单控件。
   ★ 特异性必须抬到 (0,3,0)：只写 `.ir-table .cell-in`(0,2,0) 会被**更靠后**的同特异性
     选择器反吃掉 —— 批三一一「.style-dialog 写 760 渲 480」是同一种病。
   ★ 位置必须写在 :hover/:focus **之前**：同为 (0,3,0) 时由顺序决胜，写后面会把
     focus 的白底吃掉（聚焦没反馈）。 */
.studio-page .prod-table .input,
.studio-page .prod-table .cell-in {
  min-height: 0; padding: 3px 6px; line-height: 1.35;
  background: transparent;
}
/* 核对表内的可编辑字段：观感与「手动填写」的商品表一致（平时无框、hover/focus 才显形）。
   宽度靠 table-layout:fixed + 列宽百分比分——fixed 布局下列宽之和超表宽时等比压缩，
   不产生横向滚动（旧表的病根是「列宽下限 + 横滚」，不是列数）。 */
/* ★ 批四三九 P0-2：表格导入的预览表改可编辑后，单元格输入件**直接复用识别通道的
   .ir-table .cell-in 规格**（并列选择器，零新增规则）——两条录入通道的手感必须一样：
   平时无框、hover 给浅底、focus 显品牌边 + 聚焦晕。自造一套＝两通道漂移的老路。 */
.ir-table .cell-in,
.imp-table .cell-in {
  width: 100%; min-width: 0; padding: 4px 6px;
  background: transparent; border: 1px solid transparent; border-radius: var(--r-s, 6px);
  font-size: var(--t-aux); color: var(--text);
}
/* 悬浮/聚焦手感与基类同口径（批三九九）：悬浮给浅底不给边（给边会在密集表里连成网格），
   聚焦才显品牌边 + 聚焦晕。这里必须与 .prod-table 保持一致，否则同表两套手感。 */
.ir-table .cell-in:hover,
.imp-table .cell-in:hover { border-color: transparent; background: var(--card-2); }
.ir-table .cell-in:focus,
.imp-table .cell-in:focus { border-color: var(--brand); background: var(--card); box-shadow: var(--focus-ring); outline: none; }
.ir-p500 { white-space: nowrap; }
.ir-p500 .price-500 { color: var(--brand); font-weight: 700; font-size: var(--t-body, 13px); }
.ir-p500 .price-500 i { font-style: normal; font-size: var(--t-weak); color: var(--text-3); font-weight: 400; margin-left: 2px; }
.ir-p500-none { color: var(--text-3); }
/* 品类只读列：走 categoryOf 单一真源，静态呈现（无输入框，防第二真源） */
.ir-cate { color: var(--text-2); font-size: var(--t-weak); white-space: nowrap; }

/* ================= 商品录入 IO 内核（prodio）件（批三九〇 · 2026-10-12 商品清单重构）=================
   两通道共用：上传区 / 文件队列 / 空态卡 / 部分失败块。配色一律走既有语义令牌
   （--brand 已完成 / --warn 待处理 / --danger 失败），不新造色。 */
.io-drop {
  border: 1.5px dashed var(--line-strong);
  border-radius: var(--r-l);
  background: var(--card-2);
  padding: 30px 16px;
  text-align: center;
  cursor: pointer;
  transition: border-color .2s ease, background .2s ease;
}
.io-drop:hover { border-color: var(--brand); }
.io-drop.over { border-color: var(--brand); background: var(--brand-soft); }
.io-drop.compact { padding: 14px 12px; }
.io-drop-ico { color: var(--brand); margin-bottom: 8px; }
.io-drop-t { font-size: var(--t-body); color: var(--text); }
.io-drop-link { color: var(--brand); font-weight: 600; text-decoration: underline; }
.io-drop-s { font-size: var(--t-weak); color: var(--text-3); margin-top: 6px; }

/* 图片识别第①步的上传区（批三九六 李叔拍板「上传步只做上传」）：
   选了图之后压成**一行窄条**——把纵向空间让给队列与「开始识别」，
   格式说明只在空态出现（那时才是选图的决策点）。
   作用域钉在 .ir-zone：批量导入那条通道的密度另论，不跟着变。 */
.ir-zone .io-drop { padding: 22px 14px; }
.ir-zone .io-drop.compact { padding: 11px 14px; }
.ir-zone .io-drop.compact .io-drop-ico { display: none; }
.ir-zone .io-drop.compact .io-drop-t { font-size: var(--t-aux); }

/* 排版控件（商品卡布局 / 首行商品卡）只在清单有货时出现（显隐由 JS 写 hidden）。
   ★ 这条是**保险，不是闸**：变异验活（mut-396 N2）证明抽掉它探针照样全绿——
     .layout-field 自身没有 display 规则，UA 的 [hidden] 自己就拦住了。
     留着它只为防将来有人给 .layout-field 加 display（那时 [hidden] 会被推翻）。
     守闸钉的是 JS 里 `f.hidden = n === 0` 那一行，不是这条 CSS——别把闸挂在纸面上。 */
.layout-field[hidden] { display: none; }

/* 🔴 批四一五（李叔 2026-10-13 拍板）：促销原价依据声明块整条删除，对省钱标签与原价标签
   **不审、不卡** ⇒ .orig-basis / .ob-row / .ob-warn 一组样式随之退役（留着＝死规则，
   下次有人照着类名抄回 UI 就又是一条没人要的闸）。法条口径仍在 KB 卡 COMPLIANCE-ORIGIN
   里备查：撤的是闸门，不是知识。回退只需把这一组样式加回来。 */

.io-queue { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
.io-item {
  display: inline-flex; align-items: center; gap: 8px;
  max-width: 100%; padding: 5px 10px;
  background: var(--card); border: 1px solid var(--line);
  border-radius: var(--r-pill, 999px); font-size: var(--t-weak);
}
.io-item.io-working { border-color: var(--brand); background: var(--brand-soft); }
.io-item.io-error { border-color: var(--danger); background: var(--danger-soft); }
.io-thumb { width: 22px; height: 22px; border-radius: 4px; object-fit: cover; flex: none; }
.io-item-nm { max-width: 180px; color: var(--text-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.io-item-sz { color: var(--text-3); flex: none; }
.io-st-done { color: var(--brand); font-weight: 600; }
.io-st-err { color: var(--danger); font-weight: 600; }
.io-st-work { color: var(--brand); font-weight: 600; }
.io-st-idle { color: var(--text-3); }
.io-st-work .spin, .io-st-work .gf-spin {
  display: inline-block; width: 11px; height: 11px; vertical-align: -1px;
  border: 2px solid var(--line-strong); border-top-color: var(--brand);
  border-radius: 50%; animation: gf-rot .8s linear infinite;
}
.io-x { flex: none; color: var(--text-3); cursor: pointer; padding: 0 2px; }
.io-x:hover { color: var(--danger); }
.io-x-retry:hover { color: var(--brand); }

/* 空态卡（识别失败 / 空列表）：给原因 + 给出路，不留空白 */
.io-empty {
  margin-top: 10px; padding: 26px 16px; text-align: center;
  border: 1px dashed var(--line-strong); border-radius: var(--r-l); background: var(--card-2);
}
.io-empty-bad { border-color: var(--danger); background: var(--danger-tint, var(--danger-soft)); }
.io-empty-ic { font-size: 26px; line-height: 1.2; }
/* 批四三一：空态卡图标由 emoji 换成 ICON SVG（stroke=currentColor）后，
   危险态的颜色得显式给——emoji 自带黄，SVG 不自带。沿用既有的 --danger 令牌，不自造色。 */
.io-empty-bad .io-empty-ic { color: var(--danger); }
.io-empty-t { margin-top: 8px; font-size: var(--t-body); font-weight: 600; color: var(--text); }
.io-empty-d { margin-top: 6px; font-size: var(--t-aux); color: var(--text-2); line-height: 1.7; }
.io-empty-ops { margin-top: 12px; display: flex; gap: 8px; justify-content: center; }

/* 部分失败块（成功项照常核对，失败项单独一块） */
.io-partial {
  margin-top: 10px; padding: 8px 10px;
  border-left: 3px solid var(--warn); background: var(--warn-soft); border-radius: var(--r-s);
}
.io-partial-t { font-size: var(--t-aux); font-weight: 600; color: var(--on-warn, #B25E09); margin-bottom: 4px; }
.io-partial-ops { margin-left: auto; display: flex; gap: 8px; flex: none; }
.io-mini { cursor: pointer; color: var(--brand); font-weight: 600; white-space: nowrap; }
.io-mini.ghost { color: var(--text-3); font-weight: 400; }
.io-mini:hover { text-decoration: underline; }

/* ================= 批四三九 · 双链路复核落地新增的三件小样式 =================
     为什么只有三件、且都贴着既有范式长：
       .io-resume      暂存恢复条 —— 照抄 .io-partial（3px 左边条 + 浅底 + r-s），色走 --warn
       .toast-act      带「撤销」的气泡 —— 只补 pointer-events，观感仍是 .toast
       .io-thumb-wrap  可点缩略图 —— 只补 cursor，图本身仍是 .io-thumb
     一律消费既有令牌：--warn / --warn-soft / --on-warn / --gold / --text-2，零新色。 */
.io-resume {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 8px 10px; margin-top: 10px;
  border-left: 3px solid var(--warn); background: var(--warn-soft);
  border-radius: var(--r-s, 6px);
}
.io-resume > svg { flex: none; vertical-align: -2px; }
.io-resume-t { flex: 1 1 auto; min-width: 0; font-size: var(--t-aux); color: var(--on-warn, #B25E09); }
.io-resume-t b { font-weight: 700; }
.io-resume-ops { margin-left: auto; display: flex; gap: 10px; flex: none; }
/* 带操作的气泡：容器 .toast-wrap 是 pointer-events:none（防挡住底下的表格），
   带撤销键的这一条必须自己把点击打开，否则键位看得见、按不动。 */
.toast.toast-act { pointer-events: auto; display: flex; align-items: center; gap: 14px; }
.toast-act .io-undo {
  border: 0; background: transparent; cursor: pointer; padding: 0;
  font-family: inherit; font-size: var(--t-aux); font-weight: 700; color: var(--gold);
  white-space: nowrap;
}
.toast-act .io-undo:hover { text-decoration: underline; }
/* 缩略图可点开看原图（P1-6）：只在 .io-thumb 外再包一层，图本身不动 */
.io-thumb-wrap { display: inline-flex; flex: none; cursor: zoom-in; }
.io-thumb-wrap:hover { opacity: .82; }
/* 导入预览表：与 .ir-table 同款 fixed 布局（列宽之和超表宽时等比压缩，永不横滚） */
.imp-table { table-layout: fixed; }
.imp-table .imp-no-th, .imp-table .imp-no { width: 30px; }
.imp-table .imp-ops-th, .imp-table .imp-ops-td { width: 30px; padding: 3px 4px; text-align: center; }
.imp-table .imp-st-th { text-align: left; }

/* ================= 核对表 =「手动填写」商品清单表的同一件组件（李叔 2026-10-12 拍板）=================
   ★ 为什么从层叠卡片改回表格：卡片一品四层 ≈150px，识 12 品就多滚一屏；李叔判
     「识别太占位置了，复用手动录入界面UI组件」。改 `.prod-table` 同款表：一行一品 ≈30px，
     输入即算／操作列／拖拽与手动填写完全同一套——两套承载必漂移，所以不再自造。
   ★ 列宽用 table-layout:fixed + 百分比（名字吃剩余宽）：fixed 布局下列宽之和超表宽时
     等比压缩、**永不产生横向滚动**。旧 11 列表真正的病根是「列宽下限 + 横滚 + 数 td 索引」，
     不是列数本身——这三条这里一条都不占（状态按 data-irst 显式定位，不数索引）。
   活闸：probes/prodio-ui-smoke.mjs D 组量真几何（无横向溢出 / 名字列 ≥90px / 行高 ≤36px）。 */
.ir-table { table-layout: fixed; }
/* 表头允许折行（批三九九）：基类已定「表头可折行」，这里若还写 nowrap 会因同特异性
   靠后反吃基类，「单位/规格*」的星号又会溢出到邻格（批三九七 手动表踩过的坑，本表同款）。 */
/* 表头允许折行（批三九九）：基类已定「表头可折行」，这里若还写 nowrap 会因同特异性
   靠后反吃基类，「单位/规格*」的星号又会溢出到邻格（批三九七 手动表踩过的坑，本表同款）。
   横向内边距 8→5px：字号提到 11px 后，「单位/规格*」要 ~58px，15% 列的 45px 内容盒装不下
   （探针实测折成 2 行、"主词不折行"当场红）。收 3px 内边距 + 把该列加宽到 18%（见 imgrec.js），
   内容盒 63px，一次给足余量。 */
.ir-table th { white-space: normal; vertical-align: bottom; padding-left: 5px; padding-right: 5px; }
.ir-table .ir-ck-th, .ir-table .ir-ck-td { width: 26px; padding: 3px 4px; }
.ir-table .ir-ops-th, .ir-table .ir-ops-td { width: 30px; padding: 3px 4px; text-align: center; }
.ir-table .ir-name-td { padding: 3px 5px; }
.ir-table .ir-name-td .cell-in { font-size: var(--t-body, 13px); }
/* 表头第二行（「/ 原单位」「/ 海报价」）：列宽只有 60-70px，合成一行会折出参差 */
.ir-th-2 { display: block; font-size: var(--t-weak); font-weight: 400; color: var(--text-3); }
.irc-ck { width: 15px; height: 15px; accent-color: var(--brand); }
/* 同格上下排双输入（规格+原单位）：两个独立信息挤一列，是为了把宽度让给名字列。
   旧 11 列表把它们各占一列 → 每列 23px，压得点不进去。 */
.ir-table .ir-2in { padding: 2px 3px; }
.ir-table .ir-2in > .input { display: block; width: 100%; }
.ir-table .ir-unit-in { font-size: var(--t-weak); color: var(--text-3); padding: 1px 6px; }
/* 名字列副行：待配图（图片列口径）· 品类（categoryOf 单源，只读）。
   这两项不单独占列——独立成列会把名字挤到 100px 以内（当初卡片化的起因）。
   批三九九：字号从 10px 提到 --t-weak(11px)。**层次改由色阶承担，不再靠压字号**——
   全项目可读性底线是「要被读到的字 ≥ 11px」（tokens.css --t3 段立的），9/10px 是历史欠账。 */
.ir-sub { display: block; font-size: var(--t-weak); color: var(--text-3); margin-top: 1px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ir-sub .ir-cate { color: var(--text-2); }
/* 图片列口径（李叔 2026-10-12）：识别阶段没有商品图 → 副行标「待配图」，
   不再单独占列（那会把名字挤窄），收成虚线小标——口径在，列宽不动。
   批三九九：9px → --t-weak，弱化改走虚线边 + --text-3，不靠缩字。 */
.ir-img-ph {
  display: inline-block; margin-right: 3px; padding: 0 3px;
  border: 1px dashed var(--line-strong); border-radius: 3px;
  font-size: var(--t-weak); line-height: 1.45; color: var(--text-3);
}
/* 海报价（只读）排在特价输入框下方——沿用「手动填写」里「省¥X」的框下小字位。
   允许换行：406px 栏里这列只有 ~65px，「0.98 元/500g」一行放不下；
   真正会坏的是单位小字被块级化（那会在有空间时也强行断行），故 .ir-table .ir-p500 i { display:inline } 必须钉死。 */
.ir-table .ir-p500 { display: block; margin-top: 1px; font-size: var(--t-weak); font-weight: 400; color: var(--text-3); line-height: 1.3; }
.ir-table .ir-p500 .price-500 { font-size: var(--t-weak); font-weight: 700; color: var(--pine); }
.ir-table .ir-p500 .price-500 i { display: inline; font-style: normal; font-weight: 400; font-size: var(--t-weak); color: var(--text-3); margin-left: 1px; }
.ir-table .ir-st-td { padding: 3px 5px; }
/* 🔴 徽章必须允许换行（批三九〇补② 的老病，批三九二 迁卡片时原样回归过一次）：
     .badge 默认 nowrap，长状态文案一行撑到 300px+，把表格顶宽、名字格被挤到 14px（探针实测）。
     教训：换承载形状时先问「旧版那些防溢出的补丁，新版靠什么接住」——这条就是答案。 */
.ir-table .ir-st-td .badge { white-space: normal; padding: 2px 6px; }
.ir-table .ir-p500-none { color: var(--text-3); }
/* 异常行：整行浅色底 + 原因**贴在出问题的那一格**（批四〇一 · 李叔拍板「短提示贴字段」）。
   旧版是每个 warn/bad 行插一条 colspan=7 的 .ir-why-row 铺满 25 字长句 ⇒
   两行同样的毛病就是两条**逐字相同**的句子（李叔截图红框指认「功能不要重复」）。 */
.ir-table tr.s-warn > td { background: var(--warn-soft); }
.ir-table tr.s-bad > td { background: var(--danger-tint); }
/* 原因短词：11px（全项目可读性底线），贴在该格最下面一行；:empty 时不占位——
   ok 行三个格全空，行高与旧版一致（只有真出问题的格才多出这一行小字）。
   ⚠ 颜色与 .b-warn 同源（--on-warn），bad 行转 danger；全走令牌，不写裸色。 */
.ir-table .ir-fix { display: block; font-size: var(--t-weak); line-height: 1.25; margin-top: 1px; color: var(--on-warn, #B25E09); }
.ir-table .ir-fix:empty { display: none; }
.ir-table tr.s-bad .ir-fix { color: var(--danger); }
/* 缺失/待填字段的显著标记（与必填红框区分：这里是「识别没给到」，黄框黄底） */
.ir-table .cell-in.cell-in-miss,
.imp-table .cell-in.cell-in-miss { border-color: var(--warn); background: var(--warn-soft); }

/* 已加入页的绿提示条：一行说完，紧跟「手动填写」那张表（不再另做大结果面板与折叠列表）。
   ★ 形状照抄既有范式 .io-partial（3px 左边条 + 浅底 + r-s 圆角），底色用中性 --card-2：
     令牌是单一真源，**不许自造 `--pine-soft`**（tokens.css 里没有它，写了就是未定义引用，
     tokens-guard ① 会当场红——本批实测就是这样被自己拦下的）。绿语义由左条 + 绿字承担。 */
.ir-done-bar {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 8px 10px; margin-bottom: 8px;
  border-left: 3px solid var(--pine);
  background: var(--card-2); border-radius: var(--r-s, 6px);
}
.ir-done-ok { font-weight: 700; color: var(--pine); white-space: nowrap; }
.ir-done-tip { flex: 1 1 auto; min-width: 0; font-size: var(--t-weak); color: var(--text-2); }

/* ================= 识别核对页 · 去重后的三件小样式（批三九九 · 李叔拍板「功能不要重复」）=================
   为什么这三件不是"又造了一套"：它们各自替代的都是**同一信息的第二遍**——
     .ir-crumb    替代三段式向导条（导航职责已由卡片头那三个 tab 承担，不再双排导航）
     .ir-ops-bar  替代 5 个 ghost 按钮平铺（只留一个实底主按钮，其余降左侧文字链）
     .ir-sum-tip  替代那两行长灰字规则（"未处理的不加入清单"并进汇总行尾句）
   一律消费既有令牌：字号 --t-aux/--t-weak，色阶 --text-2/--text-3/--danger，主色 --brand，
   落账绿由 .btn-green 的 --pine 承担——不新造任何颜色、圆角、时长。 */
.ir-crumb { font-size: var(--t-aux); color: var(--text-2); margin-bottom: 8px; }
.ir-crumb-done { margin-left: 8px; font-size: var(--t-weak); color: var(--text-3); }
.ir-ops-bar { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-top: 10px; }
.ir-ops-links { display: flex; align-items: center; gap: 14px; flex: 1 1 auto; min-width: 0; flex-wrap: wrap; }
.ir-link {
  border: 0; background: transparent; padding: 2px 0; margin: 0; cursor: pointer;
  font-family: inherit; font-size: var(--t-aux); line-height: 1.5; color: var(--text-2);
  white-space: nowrap; transition: color var(--dur);
}
.ir-link:hover { color: var(--brand); }
.ir-link-warn { color: var(--danger); }
.ir-link-warn:hover { color: var(--danger); text-decoration: underline; }
.ir-sum-tip { color: var(--text-3); }
/* 汇总行「⚠ N 品缺重量 / 缺价格」用 warn 色（批四〇一：与徽章 .b-warn 同源）。
   旧版这半截借用 .imp-bad-t（danger 红）——"缺重量"是待补不是异常，用红是语义错位。 */
.ir-sum-warn { color: var(--on-warn, #B25E09); }

/* 状态徽标三色（与 imp-ok/imp-bad-t 同一套语义：✅=brand / ⚠️=warn / ❌=danger） */
.badge {
  display: inline-flex; align-items: center; gap: 3px;
  padding: 2px 8px; border-radius: var(--r-pill, 999px);
  font-size: var(--t-weak); white-space: nowrap; line-height: 1.5;
}
.b-ok { background: var(--brand-soft, rgba(184, 134, 11, .12)); color: var(--brand); }
.b-warn { background: var(--warn-soft); color: var(--on-warn, #B25E09); }
.b-err { background: var(--danger-soft); color: var(--danger); }
/* 按件销售（批四〇二 · 李叔「本身就是记件销售的，没有规格的，需要一个方案可以通过」）：
   它与「可加入」**同为可加入**，只是报价口径不同（海报照样按件报价）。
   用微信链接蓝一档（--link-soft / --link-wechat）：既区别于金的「可加入」、黄的「待处理」、红的「异常」，
   又不像落账绿那样暗示「已加入完成」。★ 不许自造色，两个令牌都在 tokens.css 里。 */
.b-piece { background: var(--link-soft); color: var(--link-wechat); }
/* 确认键（图片识别·加入清单）：海报品牌松绿——与生成主键的金分工，确认=内容落账 */
.btn-green { background: var(--pine, #1E7A46); color: var(--on-brand); border: none; }
.btn-green:hover { filter: brightness(1.08); }
.btn-green[disabled] { opacity: .45; cursor: not-allowed; filter: none; }

/* ================= 手动填写 · 拖拽排序 ================= */
.prod-grip { width: 26px; padding-right: 0 !important; }
.prod-grip-h { width: 26px; }
.prod-table .grip {
  display: grid; place-items: center;
  width: 22px; height: 26px;
  color: var(--text-3);
  border-radius: 6px;
  cursor: grab;
  transition: color .15s, background .15s;
}
.prod-table .grip:hover { color: var(--brand); background: var(--brand-soft); }
.prod-table .grip:active { cursor: grabbing; }
.prod-table tr.dragging { opacity: .45; }
.prod-table tr.drop-before td { box-shadow: inset 0 2px 0 var(--brand); }
.prod-table tr.drop-after td { box-shadow: inset 0 -2px 0 var(--brand); }

/* ================= 版本更新弹窗（V2.16.0，设计稿 v2 定稿） =================
   【硬编码·品牌展示色】金绿细线/大版本号的深绿 #155E35 为品牌色，不进功能组件；
   【动态主题色】卡片/文字/线/按钮一律走 var(--*) 跟随明暗主题 */
.upd-dialog { width: min(430px, 92vw); max-width: 92vw; padding: 0; overflow: hidden; }
.upd-dialog::before { content: ''; display: block; height: 3px; background: linear-gradient(90deg, #1E7A46, var(--gold)); }
.upd-in { padding: 24px 28px 22px; }
.upd-brow { font-size: 12px; letter-spacing: 2.5px; color: var(--text-3); font-weight: 600; }
.upd-ver { display: flex; align-items: baseline; gap: 10px; margin-top: 8px; }
.upd-ver .v { font-size: 27px; font-weight: 800; color: #155E35; letter-spacing: .5px; }
[data-theme="dark"] .upd-ver .v { color: var(--brand-bright); }
.upd-ver .d { font-size: 12px; color: var(--text-3); }
.upd-rule { height: 1px; background: var(--line); margin: 15px 0 4px; }
.upd-list { padding: 4px 0 2px; max-height: 264px; overflow-y: auto; }
.upd-li { display: flex; gap: 11px; padding: 8px 0; }
.upd-li .mk { flex: none; color: var(--gold); font-size: 13px; line-height: 1.75; }
.upd-li .tx { font-size: 13.5px; line-height: 1.75; color: var(--text); }
.upd-li .tx b { color: #155E35; font-weight: 600; }
[data-theme="dark"] .upd-li .tx b { color: var(--brand-bright); }
.upd-btn { width: 100%; height: var(--h-ctl); margin-top: 14px; font-size: 15px; font-weight: 600; letter-spacing: 1px; }
.upd-note { text-align: center; font-size: 11.5px; color: var(--text-3); margin-top: 10px; }
.upd-note b { color: var(--on-gold); font-weight: 600; cursor: pointer; }
[data-theme="dark"] .upd-note b { color: var(--gold); }

/* ================= 关于软件页（V2.16.0，设计稿 v2 定稿） =================
   【硬编码·品牌展示色】墨绿品牌卡 #0F3D24 + 金 #C9A227 为品牌形象色，明暗主题通用；
   其余卡片/文字走主题变量 */
.ab { max-width: 1080px; }
.ab-hero { background: #0F3D24; border-radius: var(--r-card); padding: 34px 36px 30px; color: var(--on-brand); position: relative; overflow: hidden; }
.ab-hero::after { content: ''; position: absolute; right: -70px; top: -70px; width: 240px; height: 240px; border-radius: 50%; background: rgba(201,162,39,.12); }
.ab-hero::before { content: ''; position: absolute; right: 30px; bottom: -100px; width: 180px; height: 180px; border-radius: 50%; background: rgba(255,255,255,.05); }
.ab-hero-top { display: flex; align-items: center; gap: 18px; position: relative; z-index: 1; }
.ab-lg { height: 64px; padding: 0 22px; background: var(--white); border-radius: var(--r-card); display: grid; place-items: center; flex: none; }
.ab-lg img { height: 26px; width: auto; display: block; } /* 横版 logo（465×86）按高度撑，白砖自适应宽度 */
.ab-nm { font-size: 24px; font-weight: 800; letter-spacing: 1px; }
.ab-sb { font-size: 12.5px; opacity: .68; margin-top: 3px; letter-spacing: 1px; }
.ab-ver { margin-left: auto; text-align: right; flex: none; position: relative; z-index: 1; }
.ab-ver .v { display: inline-block; border: 1px solid rgba(201,162,39,.55); color: var(--gold); border-radius: var(--r-pill); padding: 4px 15px; font-size: 13.5px; font-weight: 700; letter-spacing: .5px; }
.ab-ver .u { font-size: 11px; opacity: .6; margin-top: 7px; }
.ab-slogan { position: relative; z-index: 1; margin-top: 24px; padding-top: 20px; border-top: 1px solid rgba(255,255,255,.14); }
.ab-slogan .cn { font-size: 19px; font-weight: 600; letter-spacing: 1.5px; color: #F3E3A8; }
.ab-slogan .en { font-size: 11px; letter-spacing: 3px; opacity: .5; margin-top: 6px; }
.ab-card { background: var(--card); border-radius: 12px; padding: 22px 26px; margin-top: 14px; }
.ab-sec-t { display: flex; align-items: center; gap: 9px; font-size: 15px; font-weight: 700; margin-bottom: 12px; color: var(--text); }
.ab-sec-t::before { content: ''; width: 4px; height: 15px; border-radius: 2px; background: var(--gold); }
.ab-who { font-size: 13.5px; line-height: 1.95; color: var(--text-2); }
.ab-pillars { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; margin-top: 14px; }
.ab-pl { background: var(--card); border-radius: 12px; padding: 20px 20px 18px; border-top: 3px solid #1E7A46; }
.ab-pl .no { font-size: 11px; letter-spacing: 2px; color: var(--on-gold); font-weight: 700; }
[data-theme="dark"] .ab-pl .no { color: var(--gold); }
.ab-pl h4 { font-size: 14.5px; font-weight: 700; margin: 7px 0 8px; color: var(--text); }
.ab-pl p { font-size: 12.5px; line-height: 1.8; color: var(--text-2); }
.ab-val { display: grid; grid-template-columns: repeat(3, 1fr); }
.ab-vl { padding: 4px 18px 4px 0; }
.ab-vl + .ab-vl { border-left: 1px solid var(--line); padding-left: 20px; }
.ab-vl h5 { font-size: 13.5px; font-weight: 700; color: #155E35; margin-bottom: 6px; }
[data-theme="dark"] .ab-vl h5 { color: var(--brand-bright); }
.ab-vl p { font-size: 12.5px; line-height: 1.8; color: var(--text-2); }
.rel-item { display: flex; gap: 14px; padding: 13px 0; border-bottom: 1px solid var(--line); }
.rel-item:last-child { border-bottom: 0; padding-bottom: 2px; }
.rel-rail { flex: none; display: flex; flex-direction: column; align-items: center; width: 14px; }
.rel-rail .r-dot { width: 9px; height: 9px; border-radius: 50%; background: var(--gold); margin-top: 6px; box-shadow: 0 0 0 3px rgba(201,162,39,.16); }
.rel-item.old .r-dot { background: #CBCDD3; box-shadow: none; }
.rel-rail .r-line { flex: 1; width: 1px; background: var(--line); margin-top: 5px; }
.rel-item:last-child .r-line { display: none; }
.rel-main { flex: 1; min-width: 0; }
.rel-head { display: flex; align-items: baseline; gap: 10px; }
.rel-v { font-size: 14px; font-weight: 700; color: #155E35; }
[data-theme="dark"] .rel-v { color: var(--brand-bright); }
.rel-item.old .rel-v { color: var(--text); font-weight: 600; }
.rel-d { font-size: 12px; color: var(--text-3); }
.rel-tag { font-size: 11px; color: var(--on-gold); border: 1px solid rgba(201,162,39,.4); border-radius: 4px; padding: 0 6px; }
[data-theme="dark"] .rel-tag { color: var(--gold); }
.rel-list { margin-top: 5px; font-size: 12.5px; line-height: 1.8; color: var(--text-2); padding-left: 0; }
.rel-list li { margin-left: 15px; }

/* ================= 促销六形式（V10 新骨架） ================= */
/* 预览：1080 定宽模板 + JS 实测缩放，保证预览=导出像素级一致 */
.promo6-wrap { position: relative; width: 100%; overflow: hidden; border-radius: var(--r-l, 14px); box-shadow: 0 10px 32px rgba(0,0,0,.22); }
.promo6-scale { width: 1080px; transform-origin: top left; }
.promo6-wrap .ai-badge { z-index: 6; }
.promo6-wrap .p-rec, .promo6-wrap .p-re-main { z-index: 6; }

/* ============================================================
   图片重生成 + 版本历史 · 方案 A「微信清爽风」V2.28.1
   设计要点：标题左对齐+信息副标 / 分段控件 Tab / 提示词内嵌卡 /
   主按钮留边圆角 / 说明文字归入按钮下方
   颜色一律走 tokens.css 变量，不写死色值。
   注：UI 主色 = 微信绿（--brand）；品牌松绿（--poster-pine）按规范
   只用于海报内容，不进界面组件。若李叔要这张弹窗改松绿，把 --ih-accent 换成 var(--poster-pine) 即可。
   ============================================================ */
.ih-dialog { --ih-accent: var(--brand); --ih-accent-press: var(--brand-press); width: 480px; max-width: 94vw; padding: 0; overflow: hidden; border-radius: var(--r-l); }

/* 头部：主标题 + 副标（模型 · 耗时 · 旧版存历史）+ 圆形关闭 */
.ih-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; padding: 16px 18px 12px; }
.ih-head-l { min-width: 0; }
.ih-t { font-size: var(--t-card); font-weight: 600; color: var(--text); line-height: 1.4; }
.ih-sub { font-size: var(--t-weak); color: var(--text-2); margin-top: 4px; line-height: 1.5; }
.ih-x { flex: none; width: 26px; height: 26px; border-radius: 50%; background: var(--bg); color: var(--text-2); display: flex; align-items: center; justify-content: center; font-size: 13px; cursor: pointer; }
.ih-x:hover { background: var(--line-strong); color: var(--text); }

/* 分段控件（微信风：灰底滑块 + 选中白底） */
.ih-seg { margin: 0 18px 2px; background: var(--bg); border-radius: var(--r-m); padding: 3px; display: flex; gap: 3px; }
.ih-seg-i { flex: 1; text-align: center; padding: 7px 0; border-radius: 6px; font-size: var(--t-aux); color: var(--text-2); cursor: pointer; transition: all .15s ease; }
.ih-seg-i.on { background: var(--card); color: var(--ih-accent); font-weight: 600; box-shadow: 0 1px 3px var(--line); }

/* 内容区 */
.ih-body { padding: 14px 18px 16px; }
.ih-fld-h { display: flex; align-items: center; justify-content: space-between; margin-bottom: 7px; }
.ih-fld-t { font-size: var(--t-aux); font-weight: 600; color: var(--text); }
.ih-chip { font-size: var(--t-weak); color: var(--ih-accent); background: var(--brand-soft); padding: 2px 8px; border-radius: var(--r-pill); }
.ih-fld-r { display: flex; align-items: center; gap: 9px; }
.ih-link { background: none; border: none; padding: 0; font-size: var(--t-weak); color: var(--link); cursor: pointer; font-family: inherit; }
.ih-link:hover { text-decoration: underline; }
.ih-link:disabled { opacity: .5; cursor: default; }
.ih-ta { width: 100%; box-sizing: border-box; background: var(--card-2); border: 1px solid transparent; border-radius: var(--r-m); padding: 11px 12px; font-size: var(--t-aux); line-height: 1.75; color: var(--text); resize: vertical; min-height: 152px; font-family: inherit; }
.ih-ta:focus { outline: none; border-color: var(--ih-accent); background: var(--card); }

/* 主按钮：两侧留边、圆角 8px，费用写进按钮 */
.ih-go { display: block; width: 100%; margin-top: 14px; background: var(--ih-accent); color: var(--on-brand); border: none; border-radius: var(--r-m); padding: 11px 0; font-size: var(--t-body); font-weight: 600; cursor: pointer; font-family: inherit; }
.ih-go:hover { background: var(--ih-accent-press); }
.ih-go:disabled { opacity: .6; cursor: default; }
.ih-note { font-size: var(--t-weak); color: var(--text-2); text-align: center; margin-top: 9px; line-height: 1.6; }

/* 加载 / 空态 */
.ih-loading { padding: 34px 10px; text-align: center; font-size: var(--t-aux); color: var(--text-2); }
.ih-empty { padding: 26px 10px 22px; text-align: center; }
.ih-empty-ic { font-size: 30px; opacity: .45; }
.ih-empty-t { font-size: var(--t-body); color: var(--text); margin-top: 8px; }
.ih-empty-d { font-size: var(--t-weak); color: var(--text-2); margin-top: 4px; line-height: 1.6; }

/* 图库三级分组 */
.ih-grp { margin-bottom: 14px; }
.ih-grp-t { font-size: var(--t-weak); font-weight: 600; color: var(--text-2); margin-bottom: 8px; letter-spacing: .3px; }
.ih-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(92px, 1fr)); gap: 9px; }
.ih-item { position: relative; border-radius: var(--r-m); overflow: hidden; cursor: pointer; border: 2px solid transparent; background: var(--card-2); }
.ih-item img { width: 100%; aspect-ratio: 1/1; object-fit: cover; display: block; }
.ih-item:hover { border-color: var(--ih-accent); }
.ih-item.picking { opacity: .55; pointer-events: none; }
/* 批三三五 降级链：图库图加载失败的占位与提示（优先 图库→AI→上传 顺序不变） */
.ih-item.ih-bad { cursor: not-allowed; }
.ih-item.ih-bad:hover { border-color: transparent; }
.ih-item.ih-bad img { visibility: hidden; }
.ih-item.ih-bad::before { content: '加载失败'; position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; font-size: 12px; letter-spacing: 2px; color: var(--t3); background: var(--card-2); }
.ih-libstat { margin: 10px 2px 0; padding: 7px 10px; border-radius: 8px; background: #fdf3e7; border: 1px solid #f3ddba; color: #92610f; font-size: 12px; line-height: 1.7; }
.ih-degrade { margin-bottom: 10px; padding: 8px 12px; border-radius: 8px; background: #fdf3e7; border: 1px solid #f3ddba; color: #92610f; font-size: 12px; line-height: 1.7; }
.ih-item-m { position: absolute; left: 0; right: 0; bottom: 0; padding: 14px 6px 4px; font-size: var(--t-weak); color: var(--on-brand); background: linear-gradient(transparent, rgba(0,0,0,.66)); display: flex; justify-content: space-between; gap: 4px; }
.ih-item-m span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ============================================================
   批四一九 ·「换画面」分流弹层（rp-*）——对齐小程序批三四〇分流浮层
   复用 #layer + .mask/.dialog 基础设施与 ih-head 头部（不重造弹窗骨架）；
   两选项卡走微信列表观感：浅底圆角卡 + hover 品牌描边，一眼看出「二选一」。
   颜色一律走 tokens.css 变量，不写死色值（check-tokens 严格门禁）。
   ============================================================ */
.rp-opt { display: flex; align-items: flex-start; gap: 12px; padding: 12px 14px; margin-bottom: 10px; border: 1px solid var(--line); border-radius: var(--r-m); background: var(--card-2); cursor: pointer; transition: all .15s ease; }
.rp-opt:hover { border-color: var(--brand); background: var(--brand-soft); }
.rp-ic { flex: none; width: 34px; height: 34px; border-radius: var(--r-m); background: var(--brand-soft); display: flex; align-items: center; justify-content: center; font-size: 17px; line-height: 1; }
.rp-main { min-width: 0; flex: 1; }
.rp-t { font-size: var(--t-body); font-weight: 600; color: var(--text); line-height: 1.4; }
.rp-d { font-size: var(--t-aux); color: var(--text-2); margin-top: 3px; line-height: 1.55; }
.rp-cancel { text-align: center; padding: 9px 0; font-size: var(--t-aux); color: var(--text-2); cursor: pointer; border-radius: var(--r-m); }
.rp-cancel:hover { background: var(--bg); color: var(--text); }

/* 「换个风格」聚焦提示条（贴在风格抽屉上方——PC 风格墙是内嵌的，用聚焦代替再弹一层） */
.rp-tip { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; padding: 10px 12px; border-radius: var(--r-m); background: var(--brand-soft); border: 1px solid var(--brand); font-size: var(--t-aux); color: var(--text); line-height: 1.5; }
.rp-tip-t { flex: 1; min-width: 0; }
.rp-tip-go { flex: none; background: var(--brand); color: var(--on-brand); border: none; border-radius: var(--r-m); padding: 7px 12px; font-size: var(--t-aux); font-weight: 600; cursor: pointer; font-family: inherit; white-space: nowrap; }
.rp-tip-go:hover { background: var(--brand-press); }
.rp-tip-x { flex: none; background: none; border: none; padding: 4px 6px; font-size: var(--t-aux); color: var(--text-2); cursor: pointer; font-family: inherit; white-space: nowrap; }
.rp-tip-x:hover { color: var(--text); }
/* 批四二一（李叔「交互很不显眼」）：换风格聚焦期给风格墙描边脉冲 + 去重画按钮禁用态。
   动画只动 box-shadow（不动布局属性，不引发重排）；脉冲色走 --brand-soft token（零硬编码） */
.rp-focus { animation: rpPulse 1.6s ease-in-out 3; border-radius: var(--r-m); }
@keyframes rpPulse {
  0%, 100% { box-shadow: 0 0 0 0 transparent; }
  50% { box-shadow: 0 0 0 4px var(--brand-soft); }
}
.rp-tip-go:disabled { background: var(--line); color: var(--text-2); cursor: not-allowed; opacity: .7; }
/* 批四二九（李叔复测「还是很不显眼，半天没反应过来」）：反馈必须发生在视线内。
   ① 入场滑入 + ② .rp-tip-live 持续呼吸光晕（显眼态与「还没选卡」任务绑定，选卡即摘）
   + ③ .rp-go-flash 选卡瞬间 Go 键金光脉冲 2 次。动画只动 opacity/transform/box-shadow（不重排）；
   光晕色走 --brand-soft / --brand token，零硬编码。 */
.rp-tip { animation: rpTipIn .35s ease-out; }
@keyframes rpTipIn {
  from { opacity: 0; transform: translateY(-6px); }
  to { opacity: 1; transform: translateY(0); }
}
.rp-tip-live { animation: rpTipIn .35s ease-out, rpTipBreath 1.8s ease-in-out infinite; }
@keyframes rpTipBreath {
  0%, 100% { box-shadow: 0 0 0 0 transparent; }
  50% { box-shadow: 0 0 0 5px var(--brand-soft); }
}
.rp-go-flash { animation: rpGoFlash 1.1s ease-in-out 2; }
@keyframes rpGoFlash {
  0%, 100% { box-shadow: 0 0 0 0 transparent; }
  50% { box-shadow: 0 0 0 6px var(--brand-soft); }
}
/* 批四四八（李叔「提示条不显眼 + 下滑就看不到」）：提示条改**吸底悬浮任务条**。
   ① .rp-tip-dock = fixed 居中钉视口底部（bottom 78px 让开 .iq-bar 生成任务条 z-index 900 那条，
      本条 902 在其上；两者同时出现时上下分层不打架）；
   ② 白底金边胶囊 + 投影：与页面内容分层，扫视即见（旧版浅黄小字埋在文档流里、一滚就没）；
   ③ .rp-dock-ico 引导 ✨ / 已选 green ✓ 两态；.rp-tip-go.ready 已选金底实心——
      「现在能点了」不用读文字也看得出来。
   ⚠ 居中用 left/right:0 + margin auto + width:fit-content（不用 transform），
      让 .rp-tip 的入场动画 rpTipIn（translateY）不被 transform 占用而失效。
   ⚠ 颜色一律 token，零硬编码（check-tokens 段内口径）。 */
.rp-tip-dock {
  position: fixed; left: 0; right: 0; margin: 0 auto;
  width: fit-content; max-width: calc(100% - 32px); bottom: 78px; z-index: 902;
  background: var(--card); border: 2px solid var(--gold); border-radius: var(--r-pill);
  padding: 10px 14px; box-shadow: 0 8px 28px var(--mask); align-items: center;
}
.rp-dock-ico {
  flex: none; width: 30px; height: 30px; border-radius: 50%;
  background: var(--warn-soft); border: 1px solid var(--gold);
  display: flex; align-items: center; justify-content: center; font-size: 15px;
}
.rp-dock-ico.ok { background: var(--brand); border-color: var(--brand); color: var(--on-brand); }
.rp-tip-hint { color: var(--text-2); font-size: var(--t-weak); }
.rp-tip-go.ready { background: var(--gold); color: var(--on-brand); box-shadow: 0 2px 10px var(--mask); }
/* hover 走 filter 而非自造 --gold-press（tokens 里没有这个变量，凭空写等于死值） */
.rp-tip-go.ready:hover { filter: brightness(.92); }
/* 换风格聚焦期：金描边**常亮**（原只脉冲 3 次就撤）——模式期间风格墙边界始终可辨 */
.rp-focus { border: 2px solid var(--gold); box-shadow: 0 0 0 3px var(--warn-soft); }

/* 版本历史抽屉（同款头部与按钮） */
.ih-hist { --ih-accent: var(--brand); --ih-accent-press: var(--brand-press); width: 720px; max-width: 94vw; padding: 0; overflow: hidden; border-radius: var(--r-l); }
.ih-hist-body { padding: 14px 18px 16px; display: grid; grid-template-columns: 1fr 200px; gap: 14px; }
.ih-hist-main { background: var(--bg); border-radius: var(--r-m); min-height: 280px; display: flex; align-items: center; justify-content: center; overflow: hidden; }
.ih-hist-main img { max-width: 100%; max-height: 46vh; object-fit: contain; display: block; }
.ih-hist-side { max-height: 46vh; overflow-y: auto; display: flex; flex-direction: column; gap: 6px; }
.ih-ver { display: flex; gap: 8px; align-items: center; padding: 6px; border-radius: var(--r-m); cursor: pointer; border: 1px solid transparent; }
.ih-ver:hover { background: var(--bg); }
.ih-ver.on { border-color: var(--ih-accent); background: var(--brand-soft); }
.ih-ver img { width: 46px; height: 46px; border-radius: 7px; object-fit: cover; flex: none; }
.ih-ver-m { min-width: 0; }
.ih-ver-t { font-size: var(--t-aux); font-weight: 600; color: var(--text); }
.ih-ver-d { font-size: var(--t-weak); color: var(--text-2); margin-top: 2px; }
.ih-hist-foot { grid-column: 1 / -1; display: flex; align-items: center; gap: 12px; border-top: 1px solid var(--line); padding-top: 12px; }
.ih-hist-info { flex: 1; font-size: var(--t-aux); color: var(--text-2); line-height: 1.6; }
.ih-hist-foot .ih-go { width: auto; flex: none; margin-top: 0; padding: 9px 22px; }

/* 入口旁「历史 N」角标 */
.ih-badge { display: inline-flex; align-items: center; gap: 3px; margin-left: 6px; font-size: var(--t-weak); line-height: 1; padding: 3px 7px; border-radius: var(--r-pill); background: var(--brand-soft); color: var(--brand); cursor: pointer; border: 1px solid var(--line-strong); white-space: nowrap; }
.ih-badge:hover { background: var(--brand); color: var(--on-brand); }
.p-re-main .ih-badge, .prod-re .ih-badge { margin-left: 4px; }
/* 商品表操作列：角标作为 .prod-ops 第四个 flex 子项一排排列，防压缩防换行（V2.30.1 堆叠修复） */
.prod-ops .ih-badge { flex: none; align-self: center; margin-left: 4px; }

/* 促销六形式商品图换图入口 V3（V2.28.4 渲染稿 fix3b 李叔拍板）：
   海报内零按钮——V2.28.3 双层按钮随海报 0.37 缩放只剩 16px「看都看不到」；
   改 body 层悬浮操作条（fixed、屏幕尺寸恒定 36px）+ 图描边；.p6-img 为无样式定位标记。 */
.p6-opsbar { position: fixed; z-index: 950; display: none; align-items: center; gap: 4px; background: var(--card); border-radius: var(--r-pill); padding: 4px; box-shadow: 0 6px 24px rgba(0,0,0,.18), 0 0 0 1px rgba(0,0,0,.06); transform: translateX(-50%); }
.p6-opsbar.show { display: flex; animation: p6opsin var(--dur) ease; }
@keyframes p6opsin { from { opacity: 0; transform: translateX(-50%) translateY(4px); } to { opacity: 1; transform: translateX(-50%) translateY(0); } }
.p6-opsbar button { display: flex; align-items: center; gap: 6px; height: 36px; padding: 0 14px; border: none; background: transparent; border-radius: var(--r-pill); font-size: 13.5px; font-weight: 600; color: var(--text); cursor: pointer; white-space: nowrap; transition: background .12s; font-family: inherit; }
.p6-opsbar button:hover { background: var(--card-2); }
.p6-opsbar button.p6-ops-regen { color: var(--brand); }
.p6-opsbar button.p6-ops-regen:hover { background: var(--brand-soft); }
.p6-opsbar button i { font-style: normal; font-size: 15px; line-height: 1; }
.p6-ops-sep { width: 1px; height: 18px; background: var(--line); }
.p6-opsbar::after { content: ''; position: absolute; left: 50%; bottom: -5px; transform: translateX(-50%); width: 10px; height: 10px; background: var(--card); box-shadow: 2px 2px 4px rgba(0,0,0,.06); rotate: 45deg; border-radius: 2px; }
.p6-opsbar.flip::after { bottom: auto; top: -5px; box-shadow: -2px -2px 4px rgba(0,0,0,.05); }
.p6-opsring { position: fixed; z-index: 949; display: none; border: 2px solid var(--brand); border-radius: var(--r-btn); pointer-events: none; box-shadow: 0 0 0 3px var(--brand-soft); }
.p6-opsring.show { display: block; }
/* 生成中动效（后台任务挂起时叠在商品图上）：微光扫过 + 进度环 + 百分比 */
.p6-genov { position: absolute; inset: 0; z-index: 6; overflow: hidden; background: rgba(255,255,255,.22); }
.p6-genov::after { content: ''; position: absolute; inset: 0; background: linear-gradient(100deg, transparent 30%, rgba(255,255,255,.55) 50%, transparent 70%); background-size: 220% 100%; animation: p6shine 1.6s linear infinite; }
@keyframes p6shine { from { background-position: 130% 0; } to { background-position: -90% 0; } }
.p6-gen-ring { position: absolute; left: 50%; top: 50%; transform: translate(-50%,-50%); width: 58px; height: 58px; border-radius: 50%; background: conic-gradient(var(--brand) 0 30%, rgba(255,255,255,.55) 30% 100%); display: flex; align-items: center; justify-content: center; box-shadow: 0 4px 14px rgba(0,0,0,.22); }
/* 内圈尺寸由 JS 内联 --inner 驱动（V2.29.3：环直径按图盒短边×0.62 自适应，不再用固定档位） */
.p6-gen-ring::before { content: ''; position: absolute; width: var(--inner, 46px); height: var(--inner, 46px); border-radius: 50%; background: rgba(30,20,12,.45); }
.p6-gen-ring b { position: relative; color: var(--on-brand); font-size: 13px; font-variant-numeric: var(--num); }
/* 主视觉生成中大环（吸收 fix4 动效）：promo6 图带在 scale 坐标系内，
   海报坐标 200px 环 ≈ 屏幕 74px，文案 40px ≈ 屏幕 15px——观感不随缩放缩水 */
.p6-gen-ring.p6-xl { width: 200px; height: 200px; }
.p6-gen-ring.p6-xl::before { width: 156px; height: 156px; }
.p6-gen-ring.p6-xl b { font-size: 52px; }
.p6-gen-txt { position: absolute; left: 0; right: 0; bottom: 10%; text-align: center; font-size: 12.5px; color: var(--on-brand); text-shadow: 0 1px 4px rgba(0,0,0,.5); }
.p6-gen-txt.p6-xl { font-size: 40px; bottom: 8%; text-shadow: 0 3px 10px rgba(0,0,0,.55); letter-spacing: 2px; }

/* 底部生成任务条 + 任务面板（图片生成后台化 V2.28.3）：弹窗点完即收，任务条全程播报 */
.iq-bar { position: fixed; left: 50%; bottom: 18px; transform: translateX(-50%); z-index: 900; background: rgba(38,34,28,.92); color: var(--on-brand); border-radius: var(--r-pill); display: flex; align-items: center; gap: 12px; padding: 10px 12px 10px 18px; box-shadow: 0 12px 32px rgba(0,0,0,.30); white-space: nowrap; font-size: 13.5px; cursor: pointer; user-select: none; }
.iq-bar .iq-spin { display: inline-block; animation: iqrot 1.1s linear infinite; font-style: normal; }
@keyframes iqrot { to { transform: rotate(360deg); } }
.iq-bar .iq-cnt { font-weight: 800; }
.iq-bar .iq-names { color: rgba(255,255,255,.72); max-width: 200px; overflow: hidden; text-overflow: ellipsis; }
.iq-bar .iq-prog { font-variant-numeric: var(--num); color: #7CE7A8; font-weight: 700; }
.iq-bar .iq-up { background: rgba(255,255,255,.14); border-radius: var(--r-pill); padding: 6px 14px; font-size: 12.5px; }
.iq-pop { position: fixed; right: 22px; bottom: 74px; z-index: 901; width: 330px; max-width: calc(100vw - 32px); background: var(--card); border-radius: 18px; box-shadow: 0 18px 48px rgba(0,0,0,.22); border: 1px solid var(--line); overflow: hidden; }
.iq-pop .iq-hd { padding: 14px 18px; font-size: 14px; font-weight: 800; display: flex; justify-content: space-between; align-items: center; border-bottom: 1px solid var(--line); background: var(--card-2); }
.iq-pop .iq-hd span { font-size: 12px; color: var(--brand-press); font-weight: 700; }
.iq-pop .iq-x { cursor: pointer; color: var(--text-2); font-size: 15px; padding: 2px 6px; }
.iq-trow { display: flex; align-items: center; gap: 12px; padding: 13px 18px; border-bottom: 1px solid var(--line); }
.iq-trow:last-child { border-bottom: 0; }
.iq-trow .iq-ic { width: 34px; height: 34px; border-radius: var(--r-btn); flex: none; display: flex; align-items: center; justify-content: center; font-style: normal; font-size: 16px; background: var(--card-2); color: var(--text-2); }
.iq-trow.run .iq-ic { color: var(--brand-press); }
.iq-trow.done .iq-ic { background: #EAF7EE; color: var(--brand-press); }
.iq-trow.err .iq-ic { background: #FDF1EF; color: var(--danger); }
.iq-trow .iq-tt { font-size: 13.5px; font-weight: 700; color: var(--text); }
.iq-trow .iq-ts { font-size: 11.5px; color: var(--text-3, #9A938A); margin-top: 3px; }
.iq-trow .iq-bar2 { height: 5px; border-radius: 99px; background: var(--line); margin-top: 7px; overflow: hidden; }
.iq-trow .iq-bar2 i { display: block; height: 100%; background: var(--brand); border-radius: 99px; transition: width .6s ease; }
.iq-trow .iq-x { margin-left: auto; color: var(--text-3); font-size: 12px; flex: none; cursor: pointer; }
.iq-trow .iq-x:hover { color: var(--danger); }

/* 生成任务迷你胶囊（V2.46.2 修 D3/D4）：全部终态后看板立即折叠，右下角留结果摘要+时间；
   ▴ 展开看历史 / ✕ 彻底关闭；新任务入队自动让位整板。
   批一〇九（李叔 10-06「完成 30 秒后自动收掉、只在出图时出现」）：由「常驻摘要」改为
   「限时回执」——出现后 30 秒自己淡出收掉（时长常量 MINI_KEEP_MS 在 imgqueue.js，改一处即可）。
   悬停暂停倒计时、点 ▴ 展开面板视为接管不再自动收、出图过程中根本不显示。 */
/* 避让（批一〇七，李叔 10-06 截图「完全遮挡死了」）：右下角是运营参谋浮球的常驻位置
   （.adv 固定 right 24 / bottom 24，胶囊宽约 110–130，见 css/advisor.css）。
   原先本胶囊 right 22 + bottom 18 与浮球同格，且 z-index 901 压住浮球 60——
   浮球被整块盖死、点都点不到。规则：临时的让常驻的，任务胶囊挪到浮球左侧成组排列。
   右边距 = 浮球右距 24 + 浮球实测宽 140（含数字徽标）+ 间隙 26 = 190；
   浮球若改文案/徽标位数，这里跟着量一次（Chrome 里量 .adv-fab 的 getBoundingClientRect）。 */
.iq-mini { position: fixed; right: 190px; bottom: 24px; z-index: 901; display: flex; align-items: center; gap: 8px; background: var(--card); border: 1px solid var(--line); border-radius: var(--r-pill); padding: 8px 10px 8px 14px; box-shadow: 0 8px 24px rgba(0,0,0,.16); font-size: 12.5px; color: var(--text-2); user-select: none; transition: opacity .38s ease, transform .38s ease; }
/* 到点自收：先淡出（.38s，与 imgqueue.js MINI_FADE_MS 一致）再摘掉 display */
.iq-mini.iq-mini-out { opacity: 0; transform: translateY(8px); pointer-events: none; }
.iq-mini .iq-mini-ck { width: 20px; height: 20px; border-radius: 50%; background: #EAF7EE; color: var(--brand-press); display: inline-flex; align-items: center; justify-content: center; font-size: 12px; font-weight: 800; flex: none; }
.iq-mini .iq-mini-ck.warn { background: #FFF3D6; color: var(--on-gold); }
.iq-mini .iq-mini-tt { font-weight: 700; color: var(--text); max-width: 180px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.iq-mini .iq-mini-tm { color: var(--text-3, #9A938A); font-variant-numeric: var(--num); }
.iq-mini .iq-mini-btn { cursor: pointer; color: var(--text-2); padding: 2px 6px; border-radius: 6px; }
.iq-mini .iq-mini-btn:hover { background: var(--card-2); }
/* 屏幕适配（批一四一，李叔 10-07「没有做屏幕尺寸适配」）：
   默认 right:190px 是给右下参谋 FAB 让位；≤760 参谋转底部全宽抽屉（advisor.css 同档），
   胶囊若留在原档必与全宽 FAB 叠罗汉——挪到它上方并贴右边距，标题缩短防溢出 */
@media (max-width: 760px) {
  .iq-mini { right: 12px; bottom: 76px; max-width: calc(100vw - 24px); }
  .iq-mini .iq-mini-tt { max-width: 110px; }
}

/* 生成区完成卡（V2.46.2 genPhase 完成态）：✓ 主文案 + 来源徽标（本次生成/后台任务/断线续跑） */
.gf-done { color: var(--brand-press); font-weight: 700; }
.gf-src { display: inline-block; background: var(--card-2); color: var(--text-2); border-radius: 6px; font-size: 11.5px; padding: 2px 8px; margin-left: 6px; font-weight: 400; }

/* 导出完成行动卡（V2.29.2）：自动下载被浏览器「多文件下载拦截」静默丢弃时的手动保存兜底。
   右下固定、避开底部任务条（bottom:18 的 .iq-bar）；「保存到本地」是用户手势点击不触发拦截 */
.export-done { position: fixed; right: 22px; bottom: 86px; z-index: 950; width: 300px; background: var(--card); border: 1px solid var(--line); border-radius: 16px; box-shadow: 0 16px 44px var(--mask); padding: 16px 18px 14px; }
.export-done .ed-t { font-size: 14.5px; font-weight: 800; color: var(--text); }
.export-done .ed-n { font-size: 12px; color: var(--text-3); margin-top: 5px; word-break: break-all; }
.export-done .ed-ops { display: flex; align-items: center; gap: 10px; margin-top: 12px; }
.export-done .ed-btn { font-size: 13px; font-weight: 700; border-radius: var(--r-pill); padding: 7px 16px; border: 1px solid var(--line); background: var(--card-2); color: var(--text-2); cursor: pointer; text-decoration: none; display: inline-block; }
.export-done .ed-btn.ed-primary { background: var(--brand); border-color: var(--brand); color: var(--on-brand); }
.export-done .ed-btn.ed-primary:hover { background: var(--brand-press); }
.export-done .ed-x { margin-left: auto; color: var(--text-3); cursor: pointer; font-size: 13px; background: none; border: none; padding: 4px 6px; }
.export-done .ed-x:hover { color: var(--text); }
.export-done .ed-tip { margin-top: 10px; font-size: 12px; color: var(--danger); }
/* 任务面板底部「重跑失败 N 张」（吸收 fix4 动效稿） */
.iq-ft { padding: 10px 12px; border-top: 1px solid var(--line); background: var(--card-2); }
.iq-ft-btn { display: block; text-align: center; font-size: 12.5px; font-weight: 700; padding: 7px 0; border-radius: 8px; background: var(--brand); color: var(--on-brand); cursor: pointer; }
.iq-ft-btn:hover { background: var(--brand-press); }

/* ============================================================
   商品图上传五步弹窗（V2.30.0 · gallery.js openProdUpload）
   结构：#layer > .mask#pupMask > .dialog.pup-dialog
   ============================================================ */
.pup-dialog { width: 560px; max-width: 94vw; padding: 0; overflow: hidden; border-radius: var(--r-l); max-height: 92vh; display: flex; flex-direction: column; }
.pup-head { display: flex; align-items: center; padding: 16px var(--pad) 0; }
.pup-t { flex: 1; font-size: var(--t-card); font-weight: 700; }
.pup-x { width: 28px; height: 28px; border-radius: 8px; display: grid; place-items: center; color: var(--text-3); cursor: pointer; font-size: 14px; }
.pup-x:hover { background: var(--card-2); color: var(--text); }
.pup-sub { padding: 4px var(--pad) 12px; font-size: var(--t-aux); color: var(--text-2); border-bottom: 1px solid var(--line); }
.pup-body { padding: 16px var(--pad) 18px; overflow-y: auto; }
/* ① 拖放选图区 */
.pup-drop { border: 2px dashed var(--line-strong); border-radius: var(--r-m); padding: 34px 16px; text-align: center; cursor: pointer; transition: border-color .15s, background .15s; }
.pup-drop:hover, .pup-drop.over { border-color: var(--brand); background: var(--brand-soft); }
.pup-drop-ic { font-size: 34px; }
.pup-drop-t { font-size: var(--t-body); font-weight: 700; margin-top: 8px; }
.pup-drop-d { font-size: var(--t-aux); color: var(--text-3); margin-top: 6px; }
/* ② 识别 / ④ 优化 等待 */
.pup-row { display: flex; gap: 14px; align-items: flex-start; }
.pup-thumb { width: 96px; height: 96px; object-fit: cover; border-radius: var(--r-m); border: 1px solid var(--line); flex: none; background: var(--card-2); }
.pup-vinfo { flex: 1; min-width: 0; }
.pup-loading { display: flex; align-items: center; gap: 8px; font-size: var(--t-body); color: var(--text); font-weight: 600; }
.pup-loading .spin { width: 14px; height: 14px; flex: none; border: 2px solid var(--line-strong); border-top-color: var(--brand); border-radius: 50%; animation: gf-rot .8s linear infinite; }

/* ---------- ④ AI 优化中（V2.33.0 方案B：进度环 + 三阶段点亮）----------
   替掉原「一根转圈 + 一行秒数」——40–65 秒干等分不清在跑还是死了，且看不到优化的哪张图。
   三块：原图卡（扫光表示在处理）/ 进度环（与海报主视觉 iQ 环同款）/ 三阶段（按秒点亮）。
   全走令牌：明/暗双主题自动继承，无硬编码色值——色条与描边一律 var(--brand)/var(--line-*)。 */
.pup-opt { display: flex; flex-direction: column; align-items: center; }
.pup-opt-goods { position: relative; width: 260px; height: 150px; border: 1px solid var(--line); border-radius: var(--r-l); overflow: hidden; background: var(--card-2); }
.pup-opt-goods img { width: 100%; height: 100%; object-fit: contain; display: block; }
/* 扫光：与 .p6-band 主视觉生成微光同源语汇（不同实现：扫光不遮商品本体） */
.pup-opt-goods::after { content: ''; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(105deg, transparent 38%, rgba(255, 255, 255, 0.5) 50%, transparent 62%);
  background-size: 250% 100%; animation: pup-shim 2.2s linear infinite; }
@media (prefers-reduced-motion: reduce) { .pup-opt-goods::after { animation: none; } }
.pup-opt-tag { position: absolute; left: 10px; top: 10px; z-index: 2; font-size: var(--t-weak); color: var(--on-brand);
  background: rgba(0, 0, 0, 0.45); border-radius: 4px; padding: 2px 8px; }
.pup-opt-row { display: flex; align-items: center; gap: 26px; margin-top: 18px; flex-wrap: wrap; justify-content: center; }
.pup-opt-ring { position: relative; width: 148px; height: 148px; flex: none; }
.pup-opt-ring svg { transform: rotate(-90deg); }
.pup-opt-num { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; }
.pup-opt-num b { font-size: 30px; font-weight: 700; color: var(--text); font-variant-numeric: var(--num); line-height: 1.1; }
.pup-opt-num b small { font-size: var(--t-aux); font-weight: 400; color: var(--text-3); margin-left: 2px; }
.pup-opt-num span { font-size: var(--t-weak); color: var(--text-3); margin-top: 2px; }
.pup-opt-side { min-width: 232px; }
.pup-opt-title { font-size: var(--t-card); font-weight: 700; color: var(--text); }
.pup-opt-title small { font-weight: 400; font-size: var(--t-aux); color: var(--text-3); margin-left: 6px; }
.pup-opt-steps { margin-top: 12px; }
.pup-opt-step { position: relative; display: flex; align-items: center; gap: 10px; padding: 7px 0; font-size: var(--t-body); color: var(--text-3); transition: color .3s; }
.pup-opt-step::before { content: ''; position: absolute; left: 10px; top: -8px; height: 16px; border-left: 2px dashed var(--line); transition: border-color .3s; }
.pup-opt-step:first-child::before { display: none; }
.pup-opt-dot { position: relative; z-index: 1; flex: none; width: 22px; height: 22px; border-radius: 50%; border: 2px solid var(--line); background: var(--card); font-style: normal; font-size: var(--t-weak); font-weight: 700; color: var(--text-3); display: flex; align-items: center; justify-content: center; transition: all .3s; }
.pup-opt-step.doing { color: var(--text); font-weight: 600; }
.pup-opt-step.doing .pup-opt-dot { border-color: var(--brand); color: var(--brand); box-shadow: 0 0 0 4px var(--brand-soft); }
.pup-opt-step.done { color: var(--text-2); }
.pup-opt-step.done .pup-opt-dot { background: var(--brand); border-color: var(--brand); color: var(--on-brand); }
.pup-opt-step.done::before { border-left-color: var(--brand); }
.pup-opt-note { font-size: var(--t-aux); color: var(--text-3); margin-top: 14px; line-height: 1.6; }
.pup-opt-ops { margin-top: 16px; display: flex; flex-direction: column; align-items: center; gap: 6px; }
.pup-opt-ops .btn { min-width: 210px; }
.pup-opt-tip { font-size: var(--t-weak); color: var(--text-3); }
@keyframes pup-shim { from { background-position: 120% 0; } to { background-position: -120% 0; } }
/* 入库中提示里的 spin（.pup-note 容器内），与 loading 同款小圈（V2.30.2 补：此前只在 .pup-loading 内有样式，pupMsg 里的是死圈） */
.pup-note .spin { display: inline-block; width: 12px; height: 12px; border: 2px solid var(--line-strong); border-top-color: var(--brand); border-radius: 50%; animation: gf-rot .8s linear infinite; vertical-align: -2px; }
.pup-note { font-size: var(--t-aux); color: var(--text-3); margin-top: 10px; line-height: 1.6; }
.pup-evi { font-size: var(--t-aux); color: var(--text-2); background: var(--card-2); border-radius: 8px; padding: 8px 10px; }
.pup-warn { font-size: var(--t-aux); color: var(--danger); background: var(--danger-soft); border-radius: 8px; padding: 8px 10px; margin-top: 8px; line-height: 1.5; }
/* ---- V2.34.0 入库名字二次确认（方案C）：确认页黄条 + 末尾入库确认层 ---- */
.pup-cfwarn { font-size: var(--t-aux); color: var(--warn); background: var(--warn-soft); border-radius: 8px; padding: 8px 10px; margin-top: 10px; line-height: 1.55; }
.pup-cfwarn b { color: var(--warn); }
.pup-cfops { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 8px; }
.pup-mini { font-size: var(--t-weak); padding: 4px 10px; border-radius: var(--r-pill); border: 1px dashed var(--brand); color: var(--brand); background: var(--card); cursor: pointer; }
.pup-mini:hover { background: var(--brand-soft); }
.pup-mini.ghost { border-style: solid; border-color: var(--line-strong); color: var(--text-2); }
.pup-mini.ghost:hover { color: var(--text); background: var(--card-2); }
/* z-index 必须 > .mask 的 150（pup 弹窗遮罩）——首版 60 被整个压在弹窗下面：
   DOM 断言全绿（被盖住的元素照样响应事件），用户却一个像素都看不见（Edge 实测抓的） */
.pup-cfmask { position: fixed; inset: 0; z-index: 160; background: rgba(0, 0, 0, .45); display: flex; align-items: center; justify-content: center; padding: 20px; animation: pup-cffade .18s; }
@keyframes pup-cffade { from { opacity: 0; } }
.pup-cf { width: 460px; max-width: 100%; max-height: 88vh; overflow-y: auto; background: var(--card); border-radius: var(--r-l); padding: 18px var(--pad) 16px; box-shadow: 0 12px 40px rgba(0, 0, 0, .22); animation: pup-cfup .22s; }
@keyframes pup-cfup { from { transform: translateY(18px); opacity: .4; } }
.pup-cf-h { font-size: var(--t-card); font-weight: 700; color: var(--text); }
.pup-cf-s { font-size: var(--t-weak); color: var(--text-3); margin-top: 4px; }
.pup-cf-row { display: flex; gap: 14px; align-items: flex-start; margin-top: 14px; }
.pup-cf-img { width: 88px; height: 88px; object-fit: cover; border-radius: var(--r-m); border: 1px solid var(--line); background: var(--card-2); flex: none; }
.pup-cf-main { flex: 1; min-width: 0; }
.pup-cf-lab { font-size: var(--t-aux); color: var(--text-2); margin-bottom: 6px; }
.pup-cf-lab b { color: var(--text); }
.pup-cf-ref { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font-size: var(--t-weak); color: var(--text-3); margin-top: 8px; }
.pup-cf-ref b { color: var(--text-2); font-weight: 600; }
.pup-cf .btn { width: 100%; margin-top: 8px; }
.input.bad { border-color: var(--danger); }
@media (prefers-reduced-motion: reduce) {
  .pup-cfmask, .pup-cf { animation: none; }
}
/* ③ 确认：建议名 chips + 并入提示 + 档位卡 */
.pup-chips { display: flex; flex-wrap: wrap; gap: 8px; margin: 14px 0 10px; }
.pup-chip { font-size: var(--t-aux); padding: 6px 12px; border-radius: var(--r-pill); border: 1px solid var(--line-strong); color: var(--text-2); cursor: pointer; }
.pup-chip:hover { border-color: var(--brand); color: var(--brand); }
.pup-chip.on { background: var(--brand); border-color: var(--brand); color: var(--on-brand); font-weight: 700; }
.pup-merge { font-size: var(--t-aux); color: var(--brand); background: var(--brand-soft); border-radius: 8px; padding: 7px 10px; margin-bottom: 10px; }
.pup-tiers { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; margin-top: 14px; }
.pup-tier { border: 1.5px solid var(--line); border-radius: var(--r-m); padding: 10px 12px; cursor: pointer; transition: border-color .15s, background .15s; }
.pup-tier:hover { border-color: var(--brand); }
.pup-tier.on { border-color: var(--brand); background: var(--brand-soft); }
.pup-tier-t { font-size: var(--t-aux); font-weight: 700; display: flex; align-items: center; gap: 6px; }
.pup-rec { font-size: 10px; background: var(--brand); color: var(--on-brand); border-radius: 4px; padding: 1px 5px; font-weight: 700; }
.pup-tier-c { font-size: var(--t-card); font-weight: 800; color: var(--brand); margin-top: 4px; font-variant-numeric: var(--num); }
.pup-tier-d { font-size: 11px; color: var(--text-3); margin-top: 4px; line-height: 1.5; }
.pup-go { display: block; width: 100%; margin-top: 16px; background: var(--brand); color: var(--on-brand); border: none; border-radius: var(--r-m); padding: 12px 0; font-size: var(--t-body); font-weight: 700; cursor: pointer; font-family: inherit; }
.pup-go:hover { background: var(--brand-press); }
.pup-go:disabled { opacity: .6; cursor: default; }
.pup-ops2 { display: flex; gap: 10px; justify-content: center; margin-top: 10px; }
/* ⑤ 原图 vs 优化版 对比 */
.pup-vs { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.pup-vs-i img { width: 100%; aspect-ratio: 1; object-fit: cover; border-radius: var(--r-m); border: 1px solid var(--line); background: var(--card-2); display: block; }
.pup-vs-t { text-align: center; font-size: var(--t-aux); color: var(--text-2); margin-top: 6px; font-weight: 600; }
/* 商品表行内上传按钮（与 .prod-re 同规格） */
.prod-up { color: var(--text-3); width: 26px; height: 26px; border-radius: 6px; display: inline-grid; place-items: center; }
.prod-up:hover { color: var(--brand); background: var(--brand-soft); }

/* ============================================================
   商品图库 · 改名（V2.35.0 李叔 09-29 派单②，方案 C）
   卡片 ✎ 悬浮钮 + 完整改名层；视觉语言对齐 V2.34.0 入库确认层（.pup-cf*）
   ============================================================ */
/* 卡片 ✎：常态可见（不 hover 也看得见——藏起来等于没有入口，李叔 09-29 定的） */
.gal-re { position: absolute; right: 8px; top: 8px; width: 28px; height: 28px; border-radius: 50%; background: rgba(255, 255, 255, .96); border: 1px solid var(--line-strong); display: grid; place-items: center; font-size: 14px; color: var(--text-2); box-shadow: 0 2px 8px rgba(0, 0, 0, .14); cursor: pointer; z-index: 2; }
.gal-re:hover { color: var(--brand); border-color: var(--brand); background: var(--card); }
.gal-re:active { transform: scale(.92); }
/* 别名角标：改名时留了旧名 → 旧名照样命中 */
.m-alias { font-size: var(--t-weak); color: var(--text-2); background: var(--card-2); border: 1px dashed var(--line-strong); border-radius: var(--r-s); padding: 0 4px; }
/* z-index 160 硬约束：必须 > .mask 的 150，否则被弹窗遮罩压住（V2.34.0 实测坑：断言绿≠眼睛绿） */
.gal-ren-mask { position: fixed; inset: 0; z-index: 160; background: rgba(0, 0, 0, .45); display: flex; align-items: center; justify-content: center; padding: 20px; animation: gal-ren-fade .18s; }
@keyframes gal-ren-fade { from { opacity: 0; } }
.gal-ren { width: 460px; max-width: 100%; max-height: 88vh; overflow-y: auto; background: var(--card); border-radius: var(--r-l); padding: 18px var(--pad) 16px; box-shadow: 0 12px 40px rgba(0, 0, 0, .22); animation: gal-ren-up .22s; }
@keyframes gal-ren-up { from { transform: translateY(18px); opacity: .4; } }
.gal-ren-h { font-size: var(--t-card); font-weight: 700; color: var(--text); }
.gal-ren-s { font-size: var(--t-weak); color: var(--text-3); margin-top: 4px; }
.gal-ren-row { display: flex; gap: 14px; align-items: flex-start; margin-top: 14px; }
.gal-ren-img { width: 76px; height: 76px; object-fit: cover; border-radius: var(--r-m); border: 1px solid var(--line); background: var(--card-2); flex: none; }
.gal-ren-main { flex: 1; min-width: 0; }
.gal-ren-lab { font-size: var(--t-aux); color: var(--text-2); margin-bottom: 6px; }
.gal-ren-lab b { color: var(--text); }
/* 提示条：琥珀=后果/撞名（--warn），红=空名拦截（--danger）——两种警示不许混色 */
.gal-ren-alert { display: none; font-size: var(--t-aux); color: var(--warn); background: var(--warn-soft); border-radius: var(--r-m); padding: 8px 10px; margin-top: 10px; line-height: 1.55; }
.gal-ren-alert.show { display: block; }
.gal-ren-alert.bad { color: var(--danger); background: var(--danger-soft); }
.gal-ren-alert b { color: inherit; }
.gal-ren-chk { display: flex; align-items: center; gap: 8px; font-size: var(--t-aux); color: var(--text-2); margin-top: 12px; cursor: pointer; }
.gal-ren-chk input { width: 16px; height: 16px; accent-color: var(--brand); }
.gal-ren-note { font-size: var(--t-weak); color: var(--text-3); margin-top: 8px; line-height: 1.55; }
.gal-ren-ops { display: flex; gap: 10px; margin-top: 14px; }
.gal-ren-ops .btn { flex: 1; margin: 0; }
@media (prefers-reduced-motion: reduce) {
  .gal-ren-mask, .gal-ren { animation: none; }
}

/* ================= 产出下载 · 二次确认（V2.36.0 李叔 09-30 派单③） =================
   下载前确认「这张海报以哪家店名义落款」：店长锁定自己门店、超管可任选。
   ★ z-index 170：必须 > 改名层 160 > 遮罩 150（V2.34.0 教训：断言绿 ≠ 眼睛绿） */
.dl-foot-mask {
  position: fixed; inset: 0; z-index: 170; background: rgba(0, 0, 0, .45);
  display: flex; align-items: center; justify-content: center; padding: 20px;
  animation: gal-ren-fade .18s;
}
.dl-foot {
  background: var(--card); border-radius: var(--r-card); width: 560px; max-width: 100%;
  max-height: 88vh; overflow: auto; box-shadow: 0 8px 24px rgba(0, 0, 0, .14);
  animation: gal-ren-pop .2s cubic-bezier(.16, 1, .3, 1);
}
.dl-h { padding: 16px 18px 10px; position: relative; }
.dl-h .dl-t { font-size: 16px; font-weight: 700; }
.dl-h .dl-s { font-size: var(--t-weak); color: var(--text-2); margin-top: 3px; }
.dl-x {
  position: absolute; top: 12px; right: 14px; width: 30px; height: 30px; border: 0; border-radius: 50%;
  background: var(--hover); color: var(--text-2); font-size: 14px; line-height: 1;
  display: grid; place-items: center; cursor: pointer; transition: background .15s, color .15s;
}
.dl-x:hover { background: var(--line); color: var(--text); }
.dl-b { padding: 0 18px 8px; }
.dl-file { display: flex; gap: 12px; align-items: center; background: var(--hover); border-radius: var(--r-m); padding: 12px; }
.dl-thumb { width: 54px; height: 118px; object-fit: cover; border-radius: 6px; flex: none; background: var(--line); }
.dl-finfo { display: flex; flex-direction: column; gap: 2px; font-size: var(--t-weak); color: var(--text-2); min-width: 0; }
.dl-finfo b { font-size: 13.5px; color: var(--text); font-weight: 600; word-break: break-all; }
.dl-finfo b.hl { color: var(--brand); }
.dl-finfo b.mut { color: var(--text-3); font-weight: 400; }
.dl-lbl { font-size: var(--t-weak); color: var(--text-2); margin: 12px 0 6px; }
.dl-list { border: 1px solid var(--line); border-radius: var(--r-m); overflow: hidden; max-height: 200px; overflow-y: auto; }
.dl-opt { display: flex; align-items: center; gap: 10px; padding: 10px 14px; border-bottom: 1px solid var(--line); cursor: pointer; font-size: 13.5px; }
.dl-opt:last-child { border-bottom: 0; }
.dl-opt:hover { background: var(--hover); }
.dl-opt .dl-ck { width: 18px; flex: none; color: var(--text-3); text-align: center; }
.dl-opt .dl-nm { font-weight: 600; white-space: nowrap; }
.dl-opt .dl-me { font-style: normal; background: var(--brand); color: var(--on-brand); font-size: 10.5px; border-radius: 4px; padding: 0 5px; margin-left: 6px; line-height: 17px; }
.dl-opt .dl-ad { margin-left: auto; color: var(--text-2); font-size: var(--t-aux); text-align: right; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 46%; }
.dl-opt.on { background: var(--brand-soft); }
.dl-opt.on .dl-ck { color: var(--brand); font-weight: 700; }
.dl-opt.on .dl-nm { color: var(--brand); }
.dl-diff { border: 1px solid var(--line); border-radius: var(--r-m); padding: 12px 14px; margin-top: 12px; }
.dl-cap { font-size: var(--t-aux); color: var(--text-3); letter-spacing: 1px; margin-bottom: 8px; }
.dl-fl { display: flex; justify-content: space-between; align-items: center; background: var(--card); border: 1px solid var(--line); border-radius: 6px; padding: 9px 12px; font-size: 11px; color: var(--text-3); }
.dl-fl b { color: var(--text-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 58%; }
.dl-fl b .mut { color: var(--text-3); font-weight: 400; }
.dl-fl.new { outline: 2px solid var(--danger); outline-offset: 2px; }
.dl-fl.new b { color: var(--brand); font-weight: 700; }
.dl-arrow { text-align: center; color: var(--text-3); font-size: var(--t-aux); padding: 6px 0; }
.dl-tip { font-size: var(--t-weak); color: var(--text-2); background: var(--hover); border-radius: var(--r-m); padding: 8px 12px; line-height: 1.7; margin: 12px 0 4px; }
.dl-tip b { color: #8A5A1E; }
.dl-f { padding: 12px 18px 16px; display: flex; gap: 10px; }
.dl-f .btn { flex: 1; min-height: 42px; }
@media (prefers-reduced-motion: reduce) {
  .dl-foot-mask, .dl-foot { animation: none; }
}

/* ============================================================
   风格参考库（V2.47.0 李叔「风格示例图」派单）—— 独立页面 #/styleref
   纪律：卡片高度统一（grid 固定图区 132px，缺图走占位不塌）、标签单行截断、
        缺图/失效一律显示占位并打角标，绝不装作有图。
   ============================================================ */
.sr-page { padding: 4px 0 8px; }
.sr-head { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; margin-bottom: 12px; }
.sr-h1 { font-size: var(--t-page); font-weight: 700; color: var(--text); }
.sr-stat { font-size: 13px; color: var(--text-2); }
.sr-err { color: var(--danger); cursor: help; }
.sr-bar { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; margin-bottom: 12px; }
.sr-bar .sr-q { flex: 1 1 220px; min-width: 180px; }
.sr-bar .sr-sel { flex: 0 0 auto; width: auto; min-width: 108px; }
.sr-view.on { border-color: var(--brand); color: var(--brand); background: var(--brand-soft); }
.sr-fallback { background: var(--warn-soft); border-left: 3px solid var(--warn); padding: 8px 12px; font-size: 13px; color: var(--text-2); border-radius: 6px; margin-bottom: 12px; }

/* 网格：图区固定高度，卡高一致；缺图卡显示占位文字不塌陷 */
.sr-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(168px, 1fr)); gap: 12px; }
.sr-card { background: var(--card); border: 1px solid var(--line); border-radius: var(--r-btn); overflow: hidden; cursor: pointer; transition: border-color .15s, transform .15s; }
.sr-card:hover { border-color: var(--brand); transform: var(--lift-1); }
.sr-card .sr-ph { position: relative; height: 132px; background: var(--card-2); overflow: hidden; }
.sr-card .sr-ph img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; }
/* 占位（缺图 / 图片加载失败）：白字压暗底，与 V2.46.8 的 no-preview 同款手法 */
.sr-card .sr-ph-ph { position: absolute; inset: 0; display: none; align-items: center; justify-content: center; text-align: center; padding: 10px; font-size: 13px; color: var(--on-brand); background: rgba(0, 0, 0, .42); }
.sr-card.missing .sr-ph-ph, .sr-ph.broken .sr-ph-ph { display: flex; }
.sr-card.missing .sr-ph { background: linear-gradient(135deg, var(--card-2), var(--line-strong)); }
.sr-ph-ph.sm { font-size: 11px; }
.sr-meta { padding: 8px 10px 10px; }
.sr-card .sr-t { font-size: 14px; font-weight: 600; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sr-row { display: flex; gap: 4px; flex-wrap: nowrap; overflow: hidden; margin-top: 4px; min-height: 20px; }
.sr-tag, .sr-scene { font-size: 11px; color: var(--text-2); background: var(--card-2); border: 1px solid var(--line); border-radius: 4px; padding: 1px 6px; white-space: nowrap; flex: 0 0 auto; }
.sr-scene { color: var(--brand); border-color: var(--brand); background: var(--brand-soft); }
.sr-badge { position: absolute; top: 6px; right: 6px; font-size: 11px; padding: 2px 7px; border-radius: 20px; color: var(--on-brand); }
.sr-badge.pend { background: var(--warn); }
.sr-badge.stale { background: var(--danger); }
.sr-badge.retire { background: var(--text-3); }

/* 列表：缩略图 44px 方，三栏 */
.sr-list { display: flex; flex-direction: column; gap: 8px; }
.sr-row-item { display: flex; align-items: center; gap: 12px; background: var(--card); border: 1px solid var(--line); border-radius: var(--r-btn); padding: 8px 12px; cursor: pointer; }
.sr-row-item:hover { border-color: var(--brand); }
.sr-thumb { position: relative; flex: 0 0 56px; height: var(--h-ctl); border-radius: 6px; overflow: hidden; background: var(--card-2); }
.sr-thumb img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.sr-thumb .sr-ph-ph { display: none; }
.sr-row-item.missing .sr-thumb { background: linear-gradient(135deg, var(--card-2), var(--line-strong)); }
.sr-row-item.missing .sr-thumb .sr-ph-ph { display: flex; }
.sr-ri-main { flex: 1; min-width: 0; }
.sr-ri-main .sr-t { font-size: 14px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sr-sub { font-size: 12px; color: var(--text-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sr-ri-r { flex: 0 0 auto; display: flex; align-items: center; gap: 8px; }
.sr-src { font-size: 12px; color: var(--text-3); }

/* 灯箱：大图 + 元信息 + 来源 + 版权 */
.sr-dialog { max-width: 760px; }
.sr-big { background: var(--card-2); border-radius: 8px; overflow: hidden; min-height: 200px; display: flex; align-items: center; justify-content: center; }
.sr-big img { max-width: 100%; max-height: 46vh; display: block; object-fit: contain; }
.sr-big-ph { padding: 40px 20px; text-align: center; color: var(--text-2); font-size: 14px; }
.sr-ph-note { font-size: 12px; color: var(--text-3); margin-top: 6px; }
.sr-info { margin-top: 12px; }
.sr-kv { display: flex; gap: 10px; font-size: 13px; padding: 3px 0; }
.sr-kv b { flex: 0 0 62px; font-weight: 600; color: var(--text-2); }
.sr-kv span { flex: 1; color: var(--text); word-break: break-all; }
.sr-note { font-size: 12px; color: var(--text-2); margin-top: 6px; }
.sr-warn { margin-top: 10px; font-size: 12px; color: var(--gold); background: var(--card-2); border: 1px dashed var(--gold); border-radius: 6px; padding: 6px 10px; }
.sr-kid { font-size: 12px; color: var(--text-3); font-weight: 400; }
.sr-nosrc { font-size: 12px; color: var(--danger); margin-right: auto; }
.sr-empty { padding: var(--pad-empty) 20px; text-align: center; color: var(--text-2); font-size: 14px; }
.sr-empty-s { font-size: 12px; color: var(--text-3); margin-top: 8px; line-height: 1.7; }
.sr-loading { padding: 40px; text-align: center; color: var(--text-2); }
.sr-foot { margin-top: 16px; font-size: 12px; color: var(--text-3); line-height: 1.7; border-top: 1px solid var(--line); padding-top: 10px; }

/* ---- V2.47.1 维护闭环：新增/编辑弹层、灯箱操作条、留痕、退役态 ---- */
.sr-editor { max-width: 560px; }
.sr-editor .d-b { max-height: 62vh; overflow-y: auto; text-align: left; }
.sr-editor .field { text-align: left; }
.sr-editor .input { width: 100%; box-sizing: border-box; }
.sr-formerr { display: none; background: var(--danger-soft, rgba(194, 42, 31, .1)); border-left: 3px solid var(--danger); color: var(--danger); font-size: 12px; line-height: 1.7; padding: 8px 10px; border-radius: 6px; white-space: normal; }
/* 灯箱操作条：多个操作横排，右侧放「查看来源/关闭」 */
.sr-opsbar { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; border-top: 1px solid var(--line); padding: 10px 12px; background: var(--card); }
.sr-opsbar .btn { flex: none; }
.sr-gap { flex: 1 1 auto; }
.sr-chk { display: inline-flex; align-items: center; gap: 5px; font-size: 13px; color: var(--text-2); cursor: pointer; white-space: nowrap; }
/* 变更留痕：最新在上，最多列 6 条（多了没意义，真要查去看真源） */
.sr-log { margin-top: 10px; border-top: 1px dashed var(--line); padding-top: 8px; }
.sr-log-t { font-size: 12px; color: var(--text-3); margin-bottom: 4px; }
.sr-log-i { font-size: 11px; color: var(--text-2); line-height: 1.8; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* 退役态：整卡降透明度，但绝不隐藏（留痕可查是纪律） */
.sr-card.retired, .sr-row-item.retired { opacity: .62; }

/* ================= 批一二〇 · 工作室（做海报页）视觉重构（李叔 10-07 拍板「先落地，不行再回退」） =================
   铁律：功能/字段/交互/DOM id/类名零改动，纯视觉层。
   全部选择器以 .studio-page 作用域（form.js renderStudio 包装层），不污染全局通用类；
   回退 = 删本段 + 删 form.js 包装层，一处不多一处不少。 */

/* ---- 页头：字阶拉级 ---- */

/* ---- 卡片：呼吸感（统一 14 圆角 / 22-24 padding / 微阴影） ---- */
.studio-page .card { border-radius: var(--r-card); padding: 22px 24px; box-shadow: var(--shadow-1); }
.studio-page .card + .card { margin-top: 16px; }
.studio-page .card-t { font-size: var(--t-card); font-weight: 700; margin-bottom: 16px; align-items: center; }
.studio-page .card-t .sub { margin-left: 6px; }
/* 步骤徽章：实心绿块 → 圆点 soft 绿（与知识库重构同语言） */
.studio-page .card-t .step { min-width: 24px; height: 24px; border-radius: 50%; background: var(--brand-soft); color: var(--brand); font-size: 13px; font-weight: 700; padding: 0; margin-right: 4px; }

/* ---- 表单：label 加重、输入框 44px + 聚焦绿晕 ---- */
.studio-page .field > label { font-size: var(--t-aux); font-weight: 600; color: var(--text-2); margin-bottom: 6px; }
.studio-page .input, .studio-page .textarea, .studio-page .select { min-height: var(--h-ctl); border-radius: var(--r-btn); background: #FCFCFA; transition: border-color var(--dur), box-shadow var(--dur), background var(--dur); }
.studio-page .textarea { min-height: 60px; }
.studio-page .input:hover, .studio-page .textarea:hover, .studio-page .select:hover { border-color: var(--line-strong); }
.studio-page .input:focus, .studio-page .textarea:focus, .studio-page .select:focus { border-color: var(--brand); background: var(--card); box-shadow: var(--focus-ring); }

/* ---- chips 胶囊：节奏精修 ---- */
.studio-page .chip { transition: background var(--dur-fast), color var(--dur-fast), box-shadow var(--dur-fast); }
.studio-page .chip.on { font-weight: 700; box-shadow: var(--shadow-1); }

/* ---- 商品清单：行 hover + 删除钮灰→红 ---- */
/* 批三九九：裸色值 #FAFAF7 / #CCC 改走既有令牌（--card-2 悬浮底 / --text-3 弱前景，
   与基类 .prod-del/.prod-re 同口径）；.12s 也换 --dur-fast。这三处是历史覆盖，
   本次是把它们收进令牌闸作用域（SCOPE 写 .prod-）时当场暴露的——扩展闸范围的第一件事
   就是把它之前漏掉的欠账照出来。 */
.studio-page .prod-re { transition: background var(--dur-fast); border-radius: 8px; }
.studio-page .prod-re:hover { background: var(--card-2); }
.studio-page .prod-del { color: var(--text-3); transition: color var(--dur-fast); }
.studio-page .prod-del:hover { color: var(--danger); }
.studio-page .mini-tab { transition: background var(--dur-fast), color var(--dur-fast); }
.studio-page .mini-tab.on { font-weight: 700; }

/* ---- 提示词区：等宽体浅卡（深绿大块收敛） ---- */
.studio-page .prompt-edit { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12.5px; line-height: 1.7; background: #FAFAF7; border-radius: var(--r-btn); }
.studio-page .prompt-edit:focus { box-shadow: var(--focus-ring); }
.studio-page .prompt-head-label { font-weight: 600; }
.studio-page .prompt-struct { border-radius: var(--r-btn); }

/* ---- 按钮：主次分明 + 微交互 ---- */
.studio-page .btn { border-radius: var(--r-btn); min-height: 40px; transition: background var(--dur), border-color var(--dur), box-shadow var(--dur), transform var(--dur); }
.studio-page .btn:hover { box-shadow: var(--shadow-1); }
.studio-page .btn.primary:hover { box-shadow: var(--shadow-brand); }
.studio-page .btn.primary:active { transform: translateY(0); }
/* 生成 CTA：权重拉满（原型 52px） */
.studio-page #genBtn, .studio-page #genRetryBtn { min-height: 52px; font-size: 16px; font-weight: 700; border-radius: 12px; letter-spacing: 1px; }
.studio-page #genBtn:hover { transform: var(--lift-1); box-shadow: var(--shadow-brand-lg); }
.studio-page #exportBtn { min-height: 52px; font-size: 16px; font-weight: 700; border-radius: 12px; letter-spacing: 1px; }

/* ---- 右栏预览台：阴影托起（V3：原 sticky-col 首卡 → stagecard） ---- */
.studio-page .rail .stagecard { box-shadow: 0 4px 16px rgba(26,26,26,.06); }

/* ---- 风格抽屉与日历：圆角统一 ---- */
.studio-page .style-drawer, .studio-page .cal-item, .studio-page .cm-cell { border-radius: var(--r-btn); }
.studio-page .cal-item.link { transition: border-color var(--dur), background var(--dur), transform var(--dur); }
.studio-page .cal-item.link:hover { transform: var(--lift-1); }

/* ---- 响应式（V3：断点由 .studio-v3 段自带；窄屏卡距沿用） ---- */
@media (max-width: 760px) {
  .studio-page .card { padding: 16px; }
}

/* ================= 批一四一 · 图库屏视觉重构（李叔 10-07「剩下页面集体重构，直接打磨出代码」） =================
   铁律同批一三〇：功能/字段/交互/DOM id/类名零改动，纯视觉层。
   作用域 .pg-gallery 由 host.js route() 打在 body（#/gallery、#/outputs、#/styleref、#/ai-history 四 hash 同屏；弹层在 body 级 #layer，body 打标才罩得住）；
   回退 = 删本段 + 删 host.js 打标对应行，一处不多一处不少。 */

/* ---- 页头：字阶拉级 ---- */
.pg-gallery .page-title { font-size: 24px; font-weight: 700; letter-spacing: .5px; }
.pg-gallery .page-desc { font-size: var(--t-aux); color: var(--text-3); margin-top: 4px; }

/* ---- tab 条：节奏与下划线精修 ---- */
.pg-gallery .tabs { gap: 6px; margin-bottom: 18px; }
.pg-gallery .tab { padding: 10px 16px; font-weight: 600; letter-spacing: .3px; transition: color var(--dur), border-color var(--dur); }
.pg-gallery .tab:hover { color: var(--brand); }

/* ---- 瀑布流卡：圆角 12 + hover 浮起收敛（原 6px 阴影太冲） ---- */
.pg-gallery .m-item { border-radius: 12px; overflow: hidden; transition: box-shadow .18s, transform .18s; }
.pg-gallery .m-item:hover { box-shadow: 0 8px 24px rgba(26,26,26,.10); transform: var(--lift-2); }
.pg-gallery .m-meta { padding: 10px 12px 12px; }
.pg-gallery .m-kind { border-radius: 6px; }
.pg-gallery .gal-re { border-radius: 8px; transition: background var(--dur-fast), color var(--dur-fast); }

/* ---- chips：节奏精修 ---- */
.pg-gallery .chip { transition: background var(--dur-fast), color var(--dur-fast), border-color var(--dur-fast), box-shadow var(--dur-fast); }
.pg-gallery .chip.on { font-weight: 700; box-shadow: var(--shadow-1); }

/* ---- 输入与按钮：同工作室语言 ---- */
.pg-gallery .input, .pg-gallery .textarea, .pg-gallery .select { min-height: var(--h-ctl); border-radius: var(--r-btn); background: #FCFCFA; transition: border-color var(--dur), box-shadow var(--dur), background var(--dur); }
.pg-gallery .input:hover, .pg-gallery .textarea:hover, .pg-gallery .select:hover { border-color: var(--line-strong); }
.pg-gallery .input:focus, .pg-gallery .textarea:focus, .pg-gallery .select:focus { border-color: var(--brand); background: var(--card); box-shadow: var(--focus-ring); }
.pg-gallery .btn { border-radius: var(--r-btn); min-height: 40px; transition: background var(--dur), border-color var(--dur), box-shadow var(--dur), transform var(--dur); }
.pg-gallery .btn:hover { box-shadow: var(--shadow-1); }
.pg-gallery .btn.primary:hover { box-shadow: var(--shadow-brand); }
.pg-gallery .btn.small { min-height: 32px; border-radius: 8px; }

/* ---- 卡片与提示条 ---- */
.pg-gallery .card { border-radius: var(--r-card); padding: 22px 24px; box-shadow: var(--shadow-1); }
.pg-gallery .card + .card { margin-top: 16px; }
.pg-gallery .card-t { font-size: var(--t-card); font-weight: 700; margin-bottom: 16px; align-items: center; }
.pg-gallery .card-t .sub { margin-left: 6px; }
.pg-gallery .tip { border-radius: var(--r-btn); }

/* ---- 空态：呼吸感 + 图标拉级 ---- */
.pg-gallery .empty { padding: 56px 0; line-height: 1.8; }
.pg-gallery .empty .big { font-size: 40px; margin-bottom: 14px; }

/* ---- 上传弹层（pup）：圆角统一 14 + 拖放区放大 ---- */
.pg-gallery .pup-dialog { border-radius: var(--r-card); }
.pg-gallery .pup-drop { border-radius: 12px; padding: 40px 16px; transition: border-color var(--dur), background var(--dur), transform var(--dur); }
.pg-gallery .pup-drop:hover { transform: var(--lift-1); }
.pg-gallery .pup-thumb { border-radius: var(--r-btn); }

/* ---- AI 生成记录空态（ih-*）：与全站空态同语言 ---- */
.pg-gallery .ih-empty { padding: 56px 0; }
.pg-gallery .ih-empty-ic { font-size: 40px; }

/* ---- 响应式：760 页头收敛 + 瀑布流列数回落 ---- */
@media (max-width: 760px) {
  .pg-gallery .page-title { font-size: 20px; }
  .pg-gallery .card { padding: 16px; }
  .pg-gallery .masonry.gal6 { column-count: 3; }
}
@media (max-width: 460px) {
  .pg-gallery .masonry.gal6 { column-count: 2; }
}

/* ================= 批一三五 · 管理四屏 + 品牌门店屏视觉重构（李叔 10-07「剩下页面集体重构，直接打磨出代码」） =================
   铁律同批一三〇：功能/字段/交互/DOM id/类名零改动，纯视觉层。
   作用域 .pg-admin（#/cost、#/logs、#/review、#/about）与 .pg-brand（#/brand、#/stores）
   由 host.js route() 打在 body；回退 = 删本段 + 删打标对应行。 */

/* ---- 页头：字阶拉级（管理屏用 .pg-h h2/p，品牌屏用 .page-title/.page-desc，同语言两套选择器） ---- */
.pg-admin .pg-h h2, .pg-brand .page-title { font-size: 24px; font-weight: 700; letter-spacing: .5px; }
.pg-admin .pg-h p, .pg-brand .page-desc { font-size: var(--t-aux); color: var(--text-3); margin-top: 4px; }

/* ---- 卡片：呼吸感 ---- */
.pg-admin .card, .pg-brand .card { border-radius: var(--r-card); padding: 22px 24px; box-shadow: var(--shadow-1); }
.pg-admin .card + .card, .pg-brand .card + .card { margin-top: 16px; }
.pg-admin .card-t, .pg-brand .card-t { font-size: var(--t-card); font-weight: 700; margin-bottom: 16px; align-items: center; }
.pg-admin .card-t .sub, .pg-brand .card-t .sub { margin-left: 6px; }
.pg-admin .cost-t { font-size: var(--t-card); font-weight: 700; }
.pg-admin .cost-card { margin-bottom: 16px; }

/* ---- 统计格（资源费用 stat-row）：数字拉级 + 分隔呼吸 ---- */
.pg-admin .stat b { font-size: 24px; }
.pg-admin .stat span { margin-top: 4px; display: block; }
.pg-admin .cost-row { padding: 10px 0; }
.pg-admin .cost-note { line-height: 1.7; }
.pg-admin .bar { border-radius: 5px; }
.pg-admin .bar > i { border-radius: 5px; }

/* ---- tab 条（品牌屏）：节奏精修 ---- */
.pg-brand .tabs { gap: 6px; margin-bottom: 18px; }
.pg-brand .tab { padding: 10px 16px; font-weight: 600; letter-spacing: .3px; transition: color var(--dur), border-color var(--dur); }
.pg-brand .tab:hover { color: var(--brand); }

/* ---- 清单行（cell）：hover 浮面 ---- */
.pg-admin .cell, .pg-brand .cell { border-radius: var(--r-btn); padding: 12px 10px; margin: 0 -10px; transition: background .12s; }
.pg-admin .cell:hover, .pg-brand .cell:hover { background: var(--hover); }

/* ---- 表格：表头收敛 + 行 hover + 数字等宽 ---- */
.pg-admin .table th, .pg-brand .table th { padding: 10px 12px; letter-spacing: .3px; font-size: var(--t-weak); color: var(--text-3); font-weight: 400; }
.pg-admin .table td, .pg-brand .table td { padding: 12px; }
.pg-admin .table tbody tr, .pg-brand .table tbody tr { transition: background .12s; }
.pg-admin .table tbody tr:hover td, .pg-brand .table tbody tr:hover td { background: var(--hover); }
.pg-admin .table td.num, .pg-brand .table td.num { font-variant-numeric: var(--num); }

/* ---- 表单：label 加重 + 输入 44px 聚焦绿晕 ---- */
.pg-admin .field > label, .pg-brand .field > label { font-size: var(--t-aux); font-weight: 600; color: var(--text-2); margin-bottom: 6px; }
.pg-admin .input, .pg-admin .textarea, .pg-admin .select,
.pg-brand .input, .pg-brand .textarea, .pg-brand .select { min-height: var(--h-ctl); border-radius: var(--r-btn); background: #FCFCFA; transition: border-color var(--dur), box-shadow var(--dur), background var(--dur); }
.pg-admin .input:hover, .pg-admin .textarea:hover, .pg-admin .select:hover,
.pg-brand .input:hover, .pg-brand .textarea:hover, .pg-brand .select:hover { border-color: var(--line-strong); }
.pg-admin .input:focus, .pg-admin .textarea:focus, .pg-admin .select:focus,
.pg-brand .input:focus, .pg-brand .textarea:focus, .pg-brand .select:focus { border-color: var(--brand); background: var(--card); box-shadow: var(--focus-ring); }

/* ---- 按钮：10 圆角 + 160ms ---- */
.pg-admin .btn, .pg-brand .btn { border-radius: var(--r-btn); min-height: 40px; transition: background var(--dur), border-color var(--dur), box-shadow var(--dur), transform var(--dur); }
.pg-admin .btn:hover, .pg-brand .btn:hover { box-shadow: var(--shadow-1); }
.pg-admin .btn.primary:hover, .pg-brand .btn.primary:hover { box-shadow: var(--shadow-brand); }
.pg-admin .btn.small, .pg-brand .btn.small { min-height: 32px; border-radius: 8px; }

/* ---- 徽标与提示 ---- */
.pg-admin .tag, .pg-brand .tag { border-radius: 11px; }
.pg-admin .chips .chip, .pg-brand .chips .chip { transition: background var(--dur-fast), color var(--dur-fast), border-color var(--dur-fast), box-shadow var(--dur-fast); }
.pg-admin .chip.on, .pg-brand .chip.on { font-weight: 700; box-shadow: var(--shadow-1); }

/* ---- 空态与关于屏 ---- */
.pg-admin .empty, .pg-brand .empty { padding: var(--pad-empty) 0; line-height: 1.8; }
.pg-admin .ab-card { border-radius: var(--r-card); }
.pg-admin .ab-sec-t { font-weight: 700; }

/* ---- 响应式：760 收敛 ---- */
@media (max-width: 760px) {
  .pg-admin .pg-h h2, .pg-brand .page-title { font-size: 20px; }
  .pg-admin .card, .pg-brand .card { padding: 16px; }
  .pg-admin .stat b { font-size: 20px; }
}

/* ================= 批一四一 · 操作日志「留痕卷轴」（李叔 10-07「重构操作日志页面」） =================
   立意：监控录像带——按天卷轴 + 动作分类徽章 + 端上搜索。
   作用域 .pg-admin 由 host.js route() 打在 body；锚点（pg-h/tabs/data-lt/#logHost/空态文案）零改动。 */

/* ---- KPI 三格：今日 / 窗口 / 活跃成员 ---- */
.pg-admin .lg-kpi { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; margin-bottom: 16px; }
.pg-admin .lg-kcell { background: var(--card); border: 1px solid var(--line); border-radius: var(--r-card); padding: 16px 20px; box-shadow: var(--shadow-1); transition: box-shadow var(--dur), transform var(--dur); }
.pg-admin .lg-kcell:hover { box-shadow: 0 4px 12px rgba(26,26,26,.07); transform: var(--lift-1); }
.pg-admin .lg-kcell b { display: block; font-size: 26px; font-weight: 700; font-variant-numeric: var(--num); letter-spacing: .5px; }
.pg-admin .lg-kcell span { display: block; margin-top: 4px; font-size: var(--t-weak); color: var(--text-3); }

/* ---- 工具行：分类 chips + 搜索 ---- */
.pg-admin .lg-bar { display: flex; align-items: center; gap: 12px; margin-bottom: 16px; flex-wrap: wrap; }
.pg-admin .lg-cats { display: flex; gap: 8px; flex-wrap: wrap; flex: 1; }
.pg-admin .lg-cat { padding: 6px 13px; border-radius: 15px; font-size: var(--t-weak); color: var(--text-2); background: var(--card); border: 1px solid var(--line); cursor: pointer; transition: background var(--dur-fast), color var(--dur-fast), border-color var(--dur-fast), box-shadow var(--dur-fast); user-select: none; }
.pg-admin .lg-cat:hover { border-color: var(--line-strong); box-shadow: var(--shadow-1); }
.pg-admin .lg-cat.on { background: var(--brand); border-color: var(--brand); color: var(--on-brand); font-weight: 700; }
.pg-admin .lg-q { width: 240px; flex: none; }

/* ---- 卷轴卡片：内边距收紧，留给分组 ---- */
.pg-admin #logHost.card { padding: 10px 24px 18px; }

/* ---- 按天分组头：账单式 ---- */
.pg-admin .lg-day + .lg-day { margin-top: 6px; }
.pg-admin .lg-day-h { display: flex; align-items: baseline; gap: 10px; padding: 16px 0 8px; border-bottom: 1px solid var(--line-strong); margin-bottom: 2px; }
.pg-admin .lg-day-h b { font-size: var(--t-card); font-weight: 700; letter-spacing: .3px; }
.pg-admin .lg-day-h span { font-size: var(--t-weak); color: var(--text-3); }

/* ---- 留痕行：时间 | 徽章 | 动作 | 详情 | 成员 ---- */
.pg-admin .lg-row { display: flex; align-items: baseline; gap: 12px; padding: 9px 8px; margin: 0 -8px; border-radius: var(--r-btn); border-bottom: 1px dashed var(--line); transition: background .12s; }
.pg-admin .lg-row:hover { background: var(--hover); }
.pg-admin .lg-day .lg-row:last-child { border-bottom: none; }
.pg-admin .lg-time { flex: none; width: 44px; font-size: var(--t-weak); color: var(--text-3); font-variant-numeric: var(--num); }
.pg-admin .lg-badge { flex: none; font-size: 11px; padding: 2px 9px; border-radius: 9px; font-weight: 600; letter-spacing: .3px; }
.pg-admin .lg-cat-gen { background: var(--brand-soft); color: var(--brand); }
.pg-admin .lg-cat-exp { color: var(--gold); box-shadow: inset 0 0 0 1px var(--gold); }
.pg-admin .lg-cat-goods { color: var(--brand); box-shadow: inset 0 0 0 1px var(--brand); }
.pg-admin .lg-cat-audit { background: var(--warn-soft); color: var(--warn); }
.pg-admin .lg-cat-login, .pg-admin .lg-cat-other { background: var(--card-2); color: var(--text-3); }
.pg-admin .lg-act2 { flex: none; font-weight: 600; font-size: var(--t-body); }
.pg-admin .lg-detail2 { flex: 1; min-width: 0; color: var(--text-2); font-size: var(--t-aux); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pg-admin .lg-detail2:empty::before { content: '—'; color: var(--text-3); }
.pg-admin .lg-user { flex: none; font-size: var(--t-weak); color: var(--text-3); background: var(--card-2); padding: 2px 9px; border-radius: 9px; }
.pg-admin .lg-empty { padding: var(--pad-empty) 0; text-align: center; line-height: 1.8; }

/* ---- 响应式：760 收敛（KPI 纵排、详情换行） ---- */
@media (max-width: 760px) {
  .pg-admin .lg-kpi { grid-template-columns: 1fr 1fr; }
  .pg-admin .lg-q { width: 100%; }
  .pg-admin #logHost.card { padding: 8px 14px 14px; }
  .pg-admin .lg-row { flex-wrap: wrap; gap: 6px 10px; }
  .pg-admin .lg-detail2 { flex-basis: 100%; order: 5; white-space: normal; }
}

/* ================= 批一四三 · 用户管理「人员编制花名册」（李叔 10-07「重构用户管理界面」） =================
   立意：谁在哪家店、什么状态、什么时候来的——一眼点名；待审核有人才摆，没人申请不占认知。
   作用域 .pg-admin 由 host.js route() 打在 body；口径零改动（接口/校验/PAGE_SIZE/文案锚点/data-* 全留）；
   回退 = git revert 本批（JS 与 CSS 同批，一起回）。 */

/* ---- KPI 四格：账号总数 / 待审核 / 可登录 / 已停用 ---- */
.pg-admin .um-kpi { display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; margin-bottom: 16px; }
.pg-admin .um-kcell { background: var(--card); border: 1px solid var(--line); border-radius: var(--r-card); padding: 16px 20px; box-shadow: var(--shadow-1); transition: box-shadow var(--dur), transform var(--dur); }
.pg-admin .um-kcell:hover { box-shadow: 0 4px 12px rgba(26,26,26,.07); transform: var(--lift-1); }
.pg-admin .um-kcell b { display: block; font-size: 26px; font-weight: 700; font-variant-numeric: var(--num); letter-spacing: .5px; }
.pg-admin .um-kcell span { display: block; margin-top: 4px; font-size: var(--t-weak); color: var(--text-3); }

/* ---- 成员头像：姓名首字（待审核用橙底区分） ---- */
.pg-admin .um-av { flex: none; width: 38px; height: 38px; border-radius: 50%; display: flex; align-items: center; justify-content: center; background: var(--brand-soft); color: var(--brand); font-size: 15px; font-weight: 700; }
.pg-admin .um-av.wait { background: var(--warn-soft); color: var(--warn); }

/* ---- 待审核行：橙色引入 + 虚线分隔 ---- */
.pg-admin .um-pend { display: flex; align-items: center; gap: 12px; padding: 12px 8px; margin: 0 -8px; border-radius: 12px; border-bottom: 1px dashed var(--line); background: linear-gradient(90deg, var(--warn-soft) 0%, transparent 42%); transition: box-shadow var(--dur-fast); }
.pg-admin .um-pend:last-child { border-bottom: none; }
.pg-admin .um-pend:hover { box-shadow: 0 2px 10px rgba(26,26,26,.06); }

/* ---- 成员卡行 ---- */
.pg-admin .um-row { display: flex; align-items: center; gap: 12px; padding: 10px 8px; margin: 0 -8px; border-radius: var(--r-btn); border-bottom: 1px dashed var(--line); transition: background .12s; }
.pg-admin .um-row:hover { background: var(--hover); }
.pg-admin .um-row:last-child { border-bottom: none; }
.pg-admin .um-main { flex: 1; min-width: 0; }
.pg-admin .um-nm { display: flex; align-items: center; gap: 8px; font-size: var(--t-body); font-weight: 600; }
.pg-admin .um-sub { margin-top: 3px; font-size: var(--t-aux); color: var(--text-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-variant-numeric: var(--num); }
.pg-admin .um-role { flex: none; font-size: 11px; padding: 2px 8px; border-radius: 9px; background: var(--card-2); color: var(--text-3); font-weight: 400; }
.pg-admin .um-role.adm { color: var(--gold); box-shadow: inset 0 0 0 1px var(--gold); font-weight: 600; }
.pg-admin .um-when { flex: none; font-size: var(--t-weak); color: var(--text-3); }

/* ---- 状态四态徽章 ---- */
.pg-admin .um-st { flex: none; }
.pg-admin .um-st span { display: inline-block; font-size: 11px; padding: 3px 10px; border-radius: 9px; font-weight: 600; letter-spacing: .3px; }
.pg-admin .um-st-ok { background: var(--brand-soft); color: var(--brand); }
.pg-admin .um-st-wait { background: var(--warn-soft); color: var(--warn); }
.pg-admin .um-st-off, .pg-admin .um-st-no { background: var(--danger-soft); color: var(--danger); }

/* ---- 操作区 ---- */
.pg-admin .um-ops { flex: none; display: flex; align-items: center; gap: 6px; }
.pg-admin .um-noop { font-size: var(--t-weak); color: var(--text-3); }

/* ---- 工具行：搜索 + 状态 chips + 新增 ---- */
.pg-admin .um-tools { display: flex; align-items: center; gap: 12px; margin-bottom: 14px; flex-wrap: wrap; }
.pg-admin .um-q { width: 240px; flex: none; min-height: var(--h-ctl); border-radius: var(--r-btn); background: var(--card-2); transition: border-color var(--dur), box-shadow var(--dur), background var(--dur); }
.pg-admin .um-q:focus { border-color: var(--brand); background: var(--card); box-shadow: var(--focus-ring); }
.pg-admin .um-cats { display: flex; gap: 8px; flex-wrap: wrap; flex: 1; }
.pg-admin .um-cat { padding: 6px 13px; border-radius: 15px; font-size: var(--t-weak); color: var(--text-2); background: var(--card); border: 1px solid var(--line); cursor: pointer; transition: background var(--dur-fast), color var(--dur-fast), border-color var(--dur-fast), box-shadow var(--dur-fast); }
.pg-admin .um-cat:hover { border-color: var(--line-strong); box-shadow: var(--shadow-1); }
.pg-admin .um-cat.on { background: var(--brand); border-color: var(--brand); color: var(--on-brand); font-weight: 700; }
.pg-admin .um-tools #umAdd { margin-left: auto; min-height: var(--h-ctl); border-radius: var(--r-btn); font-weight: 700; }

/* ---- 分页与空态 ---- */
.pg-admin .um-page { display: flex; align-items: center; justify-content: center; gap: 12px; padding-top: 14px; margin-top: 6px; border-top: 1px solid var(--line); }
.pg-admin .um-page span { font-size: var(--t-weak); color: var(--text-3); font-variant-numeric: var(--num); }
.pg-admin .um-empty { padding: var(--pad-empty) 0; text-align: center; line-height: 1.8; color: var(--text-3); }

/* ---- 响应式：760 收敛 ---- */
@media (max-width: 760px) {
  .pg-admin .um-kpi { grid-template-columns: 1fr 1fr; }
  .pg-admin .um-q { width: 100%; }
  .pg-admin .um-tools #umAdd { margin-left: 0; width: 100%; }
  .pg-admin .um-row, .pg-admin .um-pend { flex-wrap: wrap; }
  .pg-admin .um-ops { flex-basis: 100%; justify-content: flex-end; }
}

/* ================= 登录 / 注册门禁 · A 方案重构（批一四九，李叔拍板） =================
   原段在 1257 行起：左品牌栏 + 右表单的骨架不变，本段在其后覆盖，同特异性后来者胜。
   改动清单：a 卡宽 340→400 且白卡托底（原来光秃秃漂在米底上） b 输入 42→44px 对齐全站
   c tab 米色胶囊→下划线（与知识库同语） d 字阶拉开 27/12.5/10.5 → 33/14.5/11
   e **≤980 左栏转顶部横条、≤560 卖点收起**——现状 480px 下左右并排硬挤，
     左栏被压成 104px、Slogan 归零、整页拉成 3850px 长卷，这是功能事故不是审美问题
   f 颜色令牌化（原段一把硬编码 #ece7db/#6b6558/#9a9384）。
   功能、字段、data-act、#lgPhone/#lgPw/#lgEye/#lgGo/#tabLogin/#tabReg/#authBody 锚点零改动。
   回退 = 删本段 + 还原 host.js renderAuthGate（三个卖点、欢迎门牌）。 */
.auth-split { min-height: 100vh; }
.auth-side {
  padding: 44px 60px 32px; position: relative; overflow: hidden;
}
.auth-side::after {
  content: ""; position: absolute; left: -80px; bottom: -120px;
  width: 340px; height: 340px; border-radius: 50%;
  background: radial-gradient(circle, rgba(255,255,255,.055), transparent 66%);
}
.as-brand { position: relative; z-index: 1; }
.as-brand img { height: 36px; }
.as-name { font-size: 17px; letter-spacing: 1.2px; }
.as-sub { font-size: 11px; margin-top: 3px; letter-spacing: .6px; }
.as-mid { position: relative; z-index: 1; padding: 44px 0; }
.as-slogan { font-size: 33px; line-height: 1.5; letter-spacing: 1.2px; }
.as-desc { font-size: var(--t-body); line-height: 1.9; margin-top: 16px; }
.as-feats { margin-top: 40px; gap: 14px; }
.as-fic { width: 34px; height: 34px; border-radius: 9px; }
.as-ft { font-size: var(--t-body); }
.as-fd { font-size: var(--t-aux); line-height: 1.65; margin-top: 3px; }
.as-foot { font-size: var(--t-weak); letter-spacing: .6px; }

.auth-pane { padding: 40px 32px; }
.auth-card2 {
  width: 400px; max-width: 100%;
  background: var(--card); border: 1px solid var(--line); border-radius: 16px;
  padding: 34px 34px 30px;
  box-shadow: 0 2px 4px rgba(0,0,0,.03), 0 12px 32px rgba(0,0,0,.05);
}
/* 门牌：以前上来就是 Tab，没有「欢迎」这块招子 */
.auth-head { margin-bottom: 2px; }
.auth-hi { font-size: 22px; font-weight: 700; letter-spacing: .4px; color: var(--text); }
.auth-hs { font-size: var(--t-aux); color: var(--text-2); margin-top: 7px; line-height: 1.6; }
.auth-tabs {
  display: flex; gap: 22px; margin: 24px 0 22px;
  background: none; padding: 0; border-bottom: 1px solid var(--line);
}
.auth-tab {
  flex: none; padding: 0 0 11px; border-radius: 0; background: none;
  border-bottom: 2px solid transparent; color: var(--text-3);
  font-size: var(--t-body); font-weight: 600;
  transition: color var(--dur) var(--ease);
}
.auth-tab.on { background: none; color: var(--text); box-shadow: none; border-bottom-color: var(--brand); }
.auth-pane .field { margin-bottom: 15px; }
.auth-pane .field label { color: var(--text-2); font-size: var(--t-aux); font-weight: 600; }
.auth-pane .input {
  height: var(--h-ctl); padding: 0 13px; border: 1px solid var(--line-strong);
  border-radius: var(--r-l); background: var(--card); color: var(--text); font-size: var(--t-body);
  transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.auth-pane .input::placeholder { color: var(--text-3); }
.auth-pane .input:focus { border-color: var(--brand); box-shadow: var(--focus-ring); }
.pw-wrap .input { padding-right: 42px; }
.pw-eye { right: 12px; color: var(--text-3); transition: color var(--dur) var(--ease); }
.pw-eye:hover { color: var(--brand); }
.auth-submit {
  height: 48px; margin-top: 10px; padding: 0; border-radius: var(--r-btn);
  font-size: var(--t-body); font-weight: 600; letter-spacing: 3px;
  transition: filter var(--dur) var(--ease);
}
.auth-submit:hover { filter: brightness(1.06); }
.auth-tip { color: var(--text-3); font-size: var(--t-weak); margin-top: 16px; line-height: 1.75; }
.auth-ok-s { color: var(--text-2); font-size: var(--t-aux); margin: 8px 0 16px; line-height: 1.7; }

/* ================= V2.54 长图模块自定义面板（电商长图模板） =================
   位置：内容信息卡之后、商品清单卡之前（李叔「录入商品前，自定义长图模块」）。
   一行 = 序号 + 模块名 + 类型 + 版式 A/B/C + 款数 + ↑↓× + 编辑；
   展开改一句话标题 / 补充说明 / 模块主图 / 挂到本模块的商品。 */
.ecom-mod { border: 1px solid var(--line); border-radius: var(--r-m); margin-bottom: 8px; background: var(--card); overflow: hidden; }
.ecom-mod.open { border-color: var(--brand); }
.ecom-mod:last-child { margin-bottom: 0; }
.ecom-mod-hd { display: flex; align-items: center; gap: 8px; padding: 8px 10px; }
.ecom-mod-hd .no { flex: 0 0 auto; font-size: var(--t-weak); font-weight: 700; letter-spacing: 1px; color: var(--text-3); }
.ecom-mod-name { flex: 1 1 auto; min-width: 0; }
.ecom-mod-kind, .ecom-mod-lay { flex: 0 0 auto; width: 92px; padding: 5px 6px; font-size: var(--t-aux); }
.ecom-mod-lay { width: 116px; }
.ecom-mod-cnt { flex: 0 0 auto; font-size: var(--t-weak); color: var(--text-3); }
.ecom-mod-ops { flex: 0 0 auto; display: inline-flex; gap: 2px; }
.ecom-mod-ops button:disabled { opacity: .3; cursor: not-allowed; }
.ecom-mod-toggle { flex: 0 0 auto; }
.ecom-mod-bd { padding: 4px 10px 12px; border-top: 1px solid var(--line); background: var(--card-2); }
.ecom-mod-bd .field { margin-top: 10px; }
.ecom-mod-pic { width: 128px; height: 96px; border-radius: var(--r-s); border: 1px solid var(--line); background: var(--hover); overflow: hidden; display: grid; place-items: center; }
.ecom-mod-pic img { width: 100%; height: 100%; object-fit: cover; }
.ecom-mod-pic .ph { font-size: var(--t-weak); color: var(--text-3); }
.ecom-mod-goods { margin-top: 2px; }

/* ── 窄屏：左品牌栏不该把表单挤下屏 ── */
@media (max-width: 980px) {
  .auth-split { flex-direction: column; }
  .auth-side { flex: none; padding: 28px 32px 24px; }
  .as-mid { padding: 22px 0 8px; max-width: none; }
  .as-slogan { font-size: 26px; }
  .as-desc { display: none; }
  .as-feats { flex-direction: row; flex-wrap: wrap; gap: 10px 26px; margin-top: 22px; }
  .as-foot { display: none; }
  .auth-pane { padding: 26px 20px 40px; }
  .auth-card2 { width: 100%; max-width: 440px; }
}
@media (max-width: 560px) {
  .auth-side { padding: 22px 20px 18px; }
  .as-slogan { font-size: 22px; }
  .as-feats { display: none; }
  .auth-pane { padding: 18px 16px 32px; }
  .auth-card2 { padding: 26px 20px 22px; border-radius: var(--r-card); }
  .auth-tabs { gap: 20px; margin: 20px 0 18px; }
}

/* ─── 批四四二 · 开放模板「叠加浮层文字」开关（PC 预览台 · 模板条下方） ───
   伴生条件见 form.js openOverlayRow()：这块只在「促销场景 + 开放文字模板」渲染，
   其余场景整行不出现（默认模板恒有叠层，给它开关是摆设）。
   状态可辨＝三重非色证据同向：① 轨道底色 ② 滑块位移 ③ 右侧状态字（已显示/已隐藏）
   ——只靠颜色分辨，在深色皮肤 / 投影投屏 / 色弱三种场景都会掉光（批三九六 同族口径）。
   全部走 tokens.css 令牌：另一套皮肤来了自动跟，不自造色值。 */
.ov-row { display: flex; align-items: center; gap: 10px; margin-top: 2px; padding: 8px 10px; border: 1px solid var(--line); border-radius: var(--r-s); background: var(--card-2); }
.ov-sw { display: inline-flex; align-items: center; gap: 8px; padding: 0; border: 0; background: none; cursor: pointer; font: inherit; color: var(--text); }
.ov-sw-tk { position: relative; width: 38px; height: 22px; flex: none; border-radius: var(--r-pill); background: var(--line-strong); transition: background var(--dur) var(--ease); }
.ov-sw-kn { position: absolute; top: 2px; left: 2px; width: 18px; height: 18px; border-radius: 50%; background: var(--white); box-shadow: var(--shadow-knob); transition: transform var(--dur) var(--ease); }
.ov-sw.on .ov-sw-tk { background: var(--brand); }
.ov-sw.on .ov-sw-kn { transform: translateX(16px); }
.ov-sw-tx { font-size: var(--t-body); }
.ov-st { padding: 2px 8px; border-radius: var(--r-pill); background: var(--hover); color: var(--text-3); font-size: var(--t-weak); }
.ov-st.on { background: var(--brand); color: var(--on-brand); font-weight: 700; }
