/* ===== 调整型文胸 生图工具 —— Glass 玻璃拟态 + Inter 字体 ===== */
@import url("https://fonts.font.im/css?family=Inter:400,500,600,700");

/* Vue 挂载完成前隐藏整个 #app，避免原始 {{ }} 模板和「安装扩展」弹窗闪现零点几秒 */
[v-cloak] { display: none !important; }

/* 全局细滚动条：默认 15px 灰白条在深色 UI 上太突兀（页面级 + 历史区 .history-grid 等 overflow 容器都受影响）。
   改 8px + 半透明白 thumb（深色背景上很淡、不抢眼）、track 透明、hover 时才稍明显；Firefox 用 scrollbar-width。 */
* { scrollbar-width: thin; scrollbar-color: rgba(255,255,255,.18) transparent; }
*::-webkit-scrollbar { width: 8px; height: 8px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb { background: rgba(255,255,255,.16); border-radius: 999px; }
*::-webkit-scrollbar-thumb:hover { background: rgba(255,255,255,.32); }

:root {
  /* Glass: 深底 + 渐变光斑由 body 提供，其他容器都是半透明白 */
  --bg-base: #0e0e10;
  --panel: rgba(255, 255, 255, 0.04);
  --panel-strong: rgba(255, 255, 255, 0.06);
  --stage: rgba(0, 0, 0, 0.28);
  --card: rgba(255, 255, 255, 0.04);
  --card-hover: rgba(255, 255, 255, 0.08);
  --border: rgba(255, 255, 255, 0.08);
  --border-strong: rgba(255, 255, 255, 0.14);
  --fg: #ececec;
  --muted: #8a8a92;
  --accent: #f76b1c;
  --accent-soft: rgba(247,107,28,0.15);
  --accent-ring: rgba(247,107,28,0.35);
  --bg-chip: #3b82f6; --bg-chip-soft: rgba(59,130,246,.16); --bg-chip-ring: rgba(59,130,246,.5);
  --pose-chip: #22c55e; --pose-chip-soft: rgba(34,197,94,.16); --pose-chip-ring: rgba(34,197,94,.5);
  --on-bg: #000000;
  --on-fg: #f76b1c;
  --danger: #ef4444;
  --radius: 8px;
  --radius-lg: 12px;
  /* 全站唯一等宽字体栈：ID/时间戳/日志/参数都用它，别再各处各写一套 */
  --mono: ui-monospace, SFMono-Regular, Menlo, monospace;
  /* ===== 公共件（2026-08-05 系统排查后确立）=====
     排查发现：输入框 26 个定义、6 种底色；卡片 28 个定义、4 种底色；按钮圆角 3 套。
     同一个东西各写各的，就是「版面有两个颜色」的病根。以后新控件一律用下面这几个变量。 */
  --surface-card: #16161a;    /* 卡片 / 面板 / 弹窗的底 */
  --surface-ctl:  #1d1d22;    /* 独立控件：输入框、参数芯片、下拉 */
  --radius-ctl:   8px;        /* 控件圆角 */
  --radius-card: 14px;        /* 卡片圆角 */
  --h-sm: 32px;               /* 紧凑控件：筛选 pill、小标签 */
  --h-md: 40px;               /* 常规控件：参数芯片、输入框、下拉 */
  /* 方案二「越靠前越亮」（2026-08-05 老板选定）：层级靠亮度递进，符合「浮起来的更亮」的直觉。
     注意别直接改 --card/--panel —— 那俩被按钮、页签、侧栏项也引用着，改了会误伤。 */
  --surface-sub:  #121216;    /* 次级卡片：结果卡、历史卡、统计卡…… 比主卡片更深 */
  --surface-pop:  #1c1c22;    /* 弹窗 / 抽屉 / 下拉：浮在最上，最亮 */
  /* 浮层遮罩（2026-08-05 第四批·扫弹窗抽屉后确立）：
     排查发现 11 个遮罩用了 8 种黑度（.45~.78）、3 种模糊，点不同按钮背景暗下去的程度都不一样。
     收成两档——普通档给所有弹窗抽屉，看图档只给生成弹窗（盯着图看，糊掉背景才有意义）。 */
  --scrim:       rgba(8,8,10,.72);   /* 弹窗 / 抽屉 / 面板，唯一档，不模糊 */
  --scrim-deep:  rgba(8,8,10,.78);   /* 看图档：只给生成弹窗，配 --scrim-blur */
  --scrim-blur:  blur(8px);
  --surface-ctl-pop: #23232a;        /* 浮层里的控件底，见下面「浮层内控件底」那条 */
  /* 交互过渡要动的属性白名单（2026-08-05）：原来 29 处写的是 transition: all——
     all 会把宽高/内外边距这些布局属性也纳入过渡，每帧触发重排、低端机掉帧，
     内容一变还会莫名滑一下。实测这 29 处的 hover/选中态只改下面这些（零布局属性），
     全部走合成层。新增交互样式沿用它，别再写 all。 */
  --t-props: background, border-color, color, box-shadow, transform, opacity, filter, outline-color;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  font-family: "Inter", "PingFang SC", -apple-system, BlinkMacSystemFont, sans-serif;
  color: var(--fg);
  min-height: 100vh;
  /* 灰暗调 + 可见银河：暗罩调到银河清晰可见、整体仍偏灰暗，文字面板照常 */
  /* 图片 URL 带版本号 ?v= ：换图必须改这个号，否则浏览器缓存旧图不更新（踩过坑） */
  background:
    linear-gradient(180deg, rgba(22,22,26,0.80) 0%, rgba(18,18,23,0.90) 100%),
    url('hero-bg.jpg?v=galaxy1') center / cover no-repeat,
    #1b1b1f;
  background-attachment: fixed;
  -webkit-font-smoothing: antialiased;
  letter-spacing: -0.005em;
}

/* ===== 旋转地球背景（全局铺满·除左侧栏·慢转·screen 抠黑融进银河底）=====
   层级：body 银河底(canvas) < .earth-bg(z-index:-1) < #app 内容。
   视频四角纯黑，mix-blend-mode:screen 把黑融掉只留发光地球。转速由 index.html 末尾脚本设(每圈7分钟)。
   铺满：.earth-bg 盖住侧栏(80px)以外整个视口；video 放大到 disc 直径>盒对角线 → 地表铺满无黑角(地球弧边在可视区外)。 */
.earth-bg {
  position: fixed; top: 0; right: 0; bottom: 0; left: 80px; z-index: -1;
  overflow: hidden; pointer-events: none;
}
.earth-bg video {
  position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
  width: max(138vw, 138vh); height: max(138vw, 138vh);   /* 方形·边长=较大视口维138%·disc(85%)铺满盒 */
  object-fit: cover; mix-blend-mode: screen;
  /* 保持地球明亮，只稍压一点点；可读性靠文字提亮+描边(见下方文字增强)，不靠压暗背景 */
  opacity: .5; filter: brightness(.8) saturate(1.0) contrast(1.02);
}
.earth-bg::after {  /* 轻暗罩：只压一点点，不盖掉地球 */
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(8,9,14,.34) 0%, rgba(8,9,14,.18) 45%, rgba(8,9,14,.32) 100%);
}
/* 地球亮底上的文字增强：提亮 + 暗描边 halo，让字在明亮地表上也清楚（不压暗背景）。
   body 前缀提高优先级，盖过后面 .jm-* 原规则；.mod-tab.on / .jm-hint.warn 因更高优先级不受影响保留本色 */
body .jm-title { text-shadow: 0 2px 4px rgba(0,0,0,.7), 0 0 18px rgba(0,0,0,.45); }
body .jm-sub, body .jm-hint { color: #dcdce2; opacity: 1; text-shadow: 0 1px 2px rgba(0,0,0,.9), 0 0 10px rgba(0,0,0,.55); }
body .gal-sub { color: #dcdce2; text-shadow: 0 1px 2px rgba(0,0,0,.9), 0 0 10px rgba(0,0,0,.55); }
body .mod-tab { text-shadow: 0 1px 3px rgba(0,0,0,.75); }
body .mod-tab:not(.on) { color: #d4d4db; }
body .jm-input::placeholder { color: rgba(228,228,235,.82); text-shadow: 0 1px 2px rgba(0,0,0,.6); }
/* 上传框「+ 参考图 选填」也提亮（同样在亮地表上）*/
body .jm-up-add .jm-plus, body .jm-up-add .lbl { color: #d2d2d9; text-shadow: 0 1px 2px rgba(0,0,0,.8); }
body .jm-up-add .jm-opt { color: #c4c4cc; opacity: 1; text-shadow: 0 1px 2px rgba(0,0,0,.8); }

/* ===== 顶部:品牌 + tab ===== */
/* 左侧栏布局：内容区给侧栏让位（折叠时跟随收窄） */
.app { max-width: none; margin: 0; padding: 20px 28px 48px 92px; transition: padding-left .24s ease; }  /* 窄轨80+12缝（V2 方案A，2026-06-12 整体放大一档） */
.app.side-folded { padding-left: 98px; }
/* 统一批量任务面板展开时主区让位（2026-08-10：原来五条线各一个 class，
   本来就是同一个 354px 让位宽度，并成这一个）。 */
.workspace-fission.batch-expanded,
.workspace-hero.batch-expanded { margin-left: 354px; width: calc(100% - 354px); transition: margin-left .24s ease, width .24s ease; }
@media (max-width:1000px){ .workspace-fission.batch-expanded,
  .workspace-hero.batch-expanded { margin-left: 0; width: 100%; } }

/* ===== 左侧栏（S1 小云雀同构，2026-06-12 整体布局定稿） ===== */
.app-side {
  position: fixed; left: 0; top: 0; bottom: 0; width: 256px; z-index: 60;
  display: flex; flex-direction: column;
  background: rgba(18, 18, 21, .85); backdrop-filter: blur(12px);
  border-right: 1px solid var(--border);
  padding: 16px 12px 12px;
  transition: width .25s ease; overflow: hidden; min-width: 0;
}
.app-side.fold { width: 68px; }
.as-brand { display: flex; align-items: center; gap: 10px; padding: 4px 6px 16px; }
.as-brand .brand-logo { flex: 0 0 auto; }
.as-bmeta { min-width: 0; }
.as-bname { font-weight: 650; font-size: 14px; white-space: nowrap; }
.as-bver { font-size: 10px; color: var(--muted); }
.as-fold { margin-left: auto; border: none; background: none; color: var(--muted); cursor: pointer; font-size: 14px; padding: 4px 6px; border-radius: 6px; }
.as-fold:hover { background: var(--panel-strong); color: var(--fg); }
.as-nav { display: flex; flex-direction: column; gap: 3px; }
.as-nv {
  display: flex; align-items: center; gap: 10px; border: none; cursor: pointer; text-align: left;
  background: none; color: var(--fg); font-size: 14px; font-weight: 650;
  padding: 10px 12px; border-radius: 10px; white-space: nowrap; overflow: hidden;
}
.as-nv .as-i { flex: 0 0 18px; text-align: center; }
.as-nv:hover { background: var(--panel-strong); }
.as-nv.on { background: var(--panel-strong); }
.as-sec { display: flex; align-items: center; justify-content: space-between; margin: 18px 12px 8px; white-space: nowrap; }
.as-sec b { font-size: 12px; color: var(--muted); font-weight: 650; }
.as-sec a { font-size: 12px; color: var(--muted); cursor: pointer; }
.as-sec a:hover { color: var(--accent); }
.as-spacer { flex: 1; }  /* 历史列表移到主区 tab 后，用空档把底部用户区压到底 */
.as-hdate { font-size: 10px; color: var(--muted); opacity: .8; letter-spacing: 1px; margin: 8px 12px 3px; white-space: nowrap; }
.as-hdate:first-child { margin-top: 0; }
.as-hrow { display: flex; align-items: center; gap: 10px; padding: 7px 10px; border-radius: 10px; cursor: pointer; white-space: nowrap; overflow: hidden; }
.as-hrow:hover { background: var(--panel-strong); }
.as-hthumb { flex: 0 0 34px; width: 34px; height: 34px; border-radius: 8px; object-fit: cover; background: rgba(255,255,255,.06); }
.as-hmeta { min-width: 0; }
.as-ht { font-size: 12px; font-weight: 650; overflow: hidden; text-overflow: ellipsis; }
.as-hcnt { margin-left: 6px; font-size: 10px; font-weight: 650; color: var(--muted); background: var(--panel-strong); border-radius: 999px; padding: 1px 7px; vertical-align: 1px; }  /* 一组N张 角标 */
.as-hs { font-size: 12px; color: var(--muted); }
.as-foot { margin-top: 8px; padding: 8px 12px; font-size: 12px; color: #7fce8c; white-space: nowrap; overflow: hidden; display: flex; align-items: center; gap: 6px; }
.as-foot i { flex: 0 0 9px; width: 9px; height: 9px; border-radius: 50%; background: #2ea043; box-shadow: 0 0 8px #2ea043; }
/* 折叠态：只剩图标列 */
.app-side.fold .as-bmeta, .app-side.fold .as-nv .as-lbl, .app-side.fold .as-sec,
.app-side.fold .as-hmeta, .app-side.fold .as-hdate, .app-side.fold .as-foot .as-lbl { display: none; }
.app-side.fold .as-brand { padding-left: 0; padding-right: 0; justify-content: center; flex-wrap: wrap; gap: 6px; }
.app-side.fold .as-fold { margin: 0; }
.app-side.fold .as-nv { justify-content: center; padding: 10px 0; }
.app-side.fold .as-hrow { justify-content: center; padding: 6px 0; }
.app-side.fold .as-foot { justify-content: center; padding: 8px 0; }

/* 右上动作区（登录系统落地后由点数胶囊+头像菜单接管） */
.top-acts { position: fixed; top: 14px; right: 18px; z-index: 55; display: flex; gap: 8px; }
.ta-btn {
  border: 1px solid var(--border-strong); background: rgba(18,18,21,.7); backdrop-filter: blur(8px);
  color: var(--muted); font-size: 12px; font-weight: 650; padding: 8px 14px; border-radius: 999px; cursor: pointer;
  display: inline-flex; align-items: center; gap: 5px;
}
.ta-btn:hover { color: var(--fg); border-color: var(--border-strong); }
.ta-btn.on { background: var(--accent); color: #1a1300; border-color: var(--accent); }

/* 窄屏：侧栏让路 */
/* 左侧栏固定常显（2026-06-13 用户要求"钉死不允许隐藏"）：
   原 @media(max-width:960px) 整块（隐藏轨 + 无轨留白补偿）已删——
   缩放/分屏到窄宽度也不再消失，轨始终占 92px 留白由 .app 基础规则保证。 */

.topbar {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 24px; padding-bottom: 16px; margin-bottom: 22px;
  border-bottom: 1px solid var(--border);
}
.brand { display: flex; align-items: center; gap: 12px; }
.brand-logo { flex: 0 0 auto; display: block; }
.brand h1 { font-size: 20px; font-weight: 650; margin: 0; letter-spacing: -0.015em; }
.brand p { font-size: 12px; color: var(--muted); margin: 4px 0 0; }

/* 扩展状态条 */
/* 站点公告条（引擎故障/维护时的一句话提示）：跟扩展横条同一套版式，橙色警示 */
.site-notice-bar { display: flex; align-items: center; gap: 10px; padding: 8px 24px; font-size: 14px; border-bottom: 1px solid var(--border); background: rgba(247,107,28,.10); }
.site-notice-bar .sn-dot { width: 8px; height: 8px; border-radius: 50%; flex: 0 0 auto; background: #f76b1c; box-shadow: 0 0 6px #f76b1c; }
.site-notice-bar .sn-msg { color: #f9a76b; flex: 1 1 auto; min-width: 0; overflow: hidden; }
.site-notice-bar .sn-track { display: inline-flex; white-space: nowrap; }
.site-notice-bar .sn-text { flex: 0 0 auto; }
/* 装不下才滚：两份文案首尾相接，滚过一半正好接上下一份 → 无缝循环 */
.site-notice-bar .sn-msg.scrolling .sn-text { padding-right: 64px; }
.site-notice-bar .sn-msg.scrolling .sn-track { animation: sn-marquee 18s linear infinite; }
@keyframes sn-marquee { from { transform: translateX(0); } to { transform: translateX(-50%); } }
/* 顾客设了「减少动态效果」就别滚了，静止截断即可（无障碍/晕动症） */
@media (prefers-reduced-motion: reduce) {
  .site-notice-bar .sn-msg.scrolling .sn-track { animation: none; }
}
.ext-bar { display: flex; align-items: center; gap: 10px; padding: 8px 24px; font-size: 14px; border-bottom: 1px solid var(--border); }
.ext-bar .ext-dot { width: 8px; height: 8px; border-radius: 50%; flex: 0 0 auto; }
.ext-bar .ext-msg { color: var(--fg); }
.ext-bar.connected { background: rgba(46,160,67,.08); }
.ext-bar.connected .ext-dot { background: #2ea043; box-shadow: 0 0 6px #2ea043; }
.ext-bar.connected .ext-msg { color: #7fce8c; }
.ext-bar.missing, .ext-bar.stale { background: rgba(247,107,28,.10); }
.ext-bar.missing .ext-dot, .ext-bar.stale .ext-dot { background: #f76b1c; box-shadow: 0 0 6px #f76b1c; }
.ext-bar.missing .ext-msg, .ext-bar.stale .ext-msg { color: #f9a76b; }
.ext-bar .ext-btn { margin-left: auto; background: #f76b1c; color: #1a1300; font-weight: 650; font-size: 12px; border: none; border-radius: 6px; padding: 5px 14px; cursor: pointer; font-family: inherit; }
.ext-bar .ext-btn:hover { filter: brightness(1.06); }
/* 点「传图器」时强调顶部「有新版」横幅：背景闪 + 「一键更新」按钮弹几下，引导去点更新 */
.ext-bar.pulse { animation: ext-bar-pulse .55s ease-in-out 3; }
@keyframes ext-bar-pulse { 0%, 100% { background: rgba(247,107,28,.10); } 50% { background: rgba(247,107,28,.34); } }
.ext-bar.pulse .ext-btn { animation: ext-btn-pulse .55s ease-in-out 3; }
@keyframes ext-btn-pulse { 0%, 100% { transform: scale(1); box-shadow: none; } 50% { transform: scale(1.14); box-shadow: 0 0 14px rgba(247,107,28,.85); } }
/* 扩展正常连接：左下角常驻小绿点+小字备注（右下角被裂变历史悬浮按钮占用） */
.ext-dot-corner { position: fixed; left: 14px; bottom: 14px; display: inline-flex; align-items: center; gap: 6px; font-size: 12px; color: #7fce8c; opacity: .75; z-index: 50; cursor: default; }
.ext-dot-corner i { width: 9px; height: 9px; border-radius: 50%; background: #2ea043; box-shadow: 0 0 8px #2ea043; }

/* 安装/更新面板 */
.ext-mask { position: fixed; inset: 0; background: var(--scrim); display: flex; align-items: center; justify-content: center; z-index: 9999; }
.ext-panel { background: var(--surface-pop); border: 1px solid var(--border-strong); border-radius: var(--radius-card); padding: 26px; max-width: 440px; width: 90%; color: var(--fg); box-shadow: 0 24px 64px rgba(0,0,0,.5); }  /* 实底：--panel 4%半透在图墙上糊成一片（同 fz-rtoolbar 的教训）。底既然不透，磨砂就没作用，已去掉 */
.ext-panel h3 { margin: 0 0 6px; font-size: 14px; font-weight: 650; }
.ext-panel-sub { color: var(--muted); font-size: 14px; margin: 0 0 16px; line-height: 1.5; }
.ext-dl { display: inline-flex; align-items: center; background: var(--accent); color: #1a1300; font-weight: 650; text-decoration: none; height: var(--h-md); padding: 0 18px; border-radius: var(--radius-ctl); font-size: 14px; }
.ext-dl:hover { filter: brightness(1.06); }
.ext-steps { margin: 18px 0; padding-left: 20px; font-size: 14px; line-height: 1.9; }
.ext-steps code { background: rgba(255,255,255,.08); padding: 1px 6px; border-radius: 4px; font-size: 12px; }
.ext-note { color: var(--muted); font-size: 12px; line-height: 1.5; margin: 0 0 18px; }
.ext-close { background: transparent; border: 1px solid var(--border); color: var(--fg); height: var(--h-md); padding: 0 18px; border-radius: var(--radius-ctl); cursor: pointer; font-family: inherit; font-size: 14px; }
.ext-close:hover { background: rgba(255,255,255,.06); }
.ext-firsttime { margin-top: 18px; font-size: 12px; color: var(--muted); font-weight: 650; }
.ext-copy { background: rgba(247,107,28,.18); color: #f76b1c; border: 1px solid rgba(247,107,28,.4); border-radius: 6px; font-size: 12px; padding: 1px 8px; cursor: pointer; font-family: inherit; vertical-align: middle; }
.ext-copy:hover { background: rgba(247,107,28,.3); }
.ext-update-note { background: rgba(46,160,67,.08); border: 1px solid rgba(46,160,67,.25); border-radius: 8px; padding: 10px 12px; font-size: 12px; color: #b7e0bf; line-height: 1.6; margin: 4px 0 14px; }
.ext-update-note code { background: rgba(255,255,255,.08); padding: 1px 5px; border-radius: 4px; }
.ext-btn-ghost { background: transparent; color: #f76b1c; border: 1px solid rgba(247,107,28,.5); border-radius: 6px; font-size: 12px; padding: 4px 12px; cursor: pointer; font-family: inherit; }
.ext-btn-ghost:hover:not(:disabled) { background: rgba(247,107,28,.12); }
.ext-btn-ghost:disabled { opacity: .5; cursor: default; }
.ext-reload-block { display: block; width: 100%; padding: 10px; margin: 0 0 14px; font-size: 14px; font-weight: 650; }
/* 安装面板重设计 v137：3步+少文字+拖文件夹示意图 */
.ext-head { display: flex; align-items: baseline; gap: 8px; margin-bottom: 14px; }
.ext-head h3 { margin: 0; }
.ext-quick { margin-left: auto; font-size: 12px; color: var(--muted); }
.ext-dl-big { display: flex; width: 100%; box-sizing: border-box; justify-content: center; align-items: center; gap: 8px; padding: 13px; font-size: 14px; border-radius: 10px; }
.ext-steps2 { margin: 18px 0 4px; display: flex; flex-direction: column; gap: 15px; }
.ext-step { display: flex; gap: 12px; align-items: flex-start; }
.ext-step-n { flex: none; width: 26px; height: 26px; border-radius: 50%; background: rgba(247,107,28,.15); color: #f76b1c; font-size: 14px; font-weight: 650; display: flex; align-items: center; justify-content: center; }
.ext-step-body { flex: 1; min-width: 0; }
.ext-step-t { font-size: 14px; font-weight: 650; }
.ext-step-d { font-size: 12px; color: var(--muted); margin-top: 1px; }
.ext-illust { margin-top: 8px; background: rgba(0,0,0,.25); border: 1px solid var(--border); border-radius: 8px; padding: 11px; display: flex; align-items: center; gap: 9px; }
.ext-il-folder { flex: none; text-align: center; line-height: 1; }
.ext-il-folder span { display: block; font-size: 12px; color: var(--muted); margin-top: 2px; }
.ext-il-arrow { flex: none; color: #f76b1c; font-size: 20px; }
.ext-il-chrome { flex: 1; min-width: 0; background: rgba(255,255,255,.03); border: 1px solid var(--border); border-radius: 6px; padding: 8px; }
.ext-il-top { display: flex; justify-content: space-between; align-items: center; gap: 6px; }
.ext-il-top > span:first-child { font-size: 12px; color: var(--muted); }
.ext-il-dev { font-size: 12px; color: #f76b1c; display: flex; align-items: center; gap: 5px; white-space: nowrap; }
.ext-toggle { width: 24px; height: 13px; background: #f76b1c; border-radius: 7px; position: relative; display: inline-block; }
.ext-toggle::after { content: ''; width: 9px; height: 9px; background: #fff; border-radius: 50%; position: absolute; right: 2px; top: 2px; }
.ext-il-drop { margin-top: 6px; border: 1px dashed #f76b1c; border-radius: 4px; padding: 5px; text-align: center; font-size: 12px; color: #f76b1c; }
.ext-step-cmd { margin-top: 7px; display: flex; align-items: center; gap: 6px; }
.ext-step-cmd code { font-size: 12px; background: rgba(255,255,255,.08); border-radius: 5px; padding: 2px 7px; }
.ext-more { margin: 14px 0; border-top: 1px solid var(--border); padding-top: 12px; }
.ext-more summary { font-size: 12px; color: var(--muted); cursor: pointer; list-style: none; }
.ext-more summary::-webkit-details-marker { display: none; }
.ext-more summary::before { content: '▸ '; }
.ext-more[open] summary::before { content: '▾ '; }
.ext-more .ext-update-note { color: var(--muted); }

.tabs { display: flex; gap: 4px; }
.tab {
  font-size: 14px; padding: 8px 18px; border-radius: var(--radius);
  background: transparent; color: var(--muted); border: 1px solid transparent;
  cursor: pointer; transition-property: var(--t-props); transition-duration: .15s; transition-timing-function: ease;
  font-family: inherit;
  display: inline-flex; align-items: center; gap: 5px;
  line-height: 1.4;
}
.tab:hover { color: var(--fg); background: var(--panel); }
.tab.active {
  background: var(--accent); color: var(--on-bg); font-weight: 650;
  box-shadow: 0 4px 14px rgba(247,107,28,0.25);
}

/* ===== 生成 tab:左右分栏 ===== */
/* 左栏自然高度（settings 内容固定），右栏靠 align-items:stretch 自动跟齐 */
.workspace { display: flex; gap: 20px; }
.panel {
  width: 380px; flex-shrink: 0;
  background:
    linear-gradient(135deg, rgba(255,255,255,0.04), rgba(255,255,255,0.015)),
    rgba(22, 22, 26, 0.88);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg); padding: 20px;
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.35);
}
.stage {
  flex: 1; min-width: 0;
  display: flex; flex-direction: column;  /* history-grid 用 flex:1 吃满剩余 */
  background:
    linear-gradient(135deg, rgba(255,255,255,0.02), rgba(255,255,255,0.005)),
    rgba(14, 14, 18, 0.85);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg); padding: 20px;
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.25);
  overflow: hidden;  /* 内部 .history-grid 负责滚动 */
}

/* ===== 参数组 ===== */
.field { margin-bottom: 18px; }
.field:last-child { margin-bottom: 0; }
.field-label { font-size: 12px; color: var(--muted); margin-bottom: 8px; display: block; font-weight: 400; }
.field-hint { font-size: 12px; color: var(--muted); margin: 8px 0 0; }

/* select：自定义 chevron + glass */
select {
  width: 100%; font-size: 14px; padding: 9px 36px 9px 12px;
  background: var(--card); color: var(--fg);
  border: 1px solid var(--border); border-radius: var(--radius);
  appearance: none; -webkit-appearance: none;
  font-family: inherit;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%238a8a92' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>");
  background-repeat: no-repeat;
  background-position: right 12px center;
  transition-property: var(--t-props); transition-duration: .15s; transition-timing-function: ease;
  cursor: pointer;
}
select:hover { border-color: var(--border-strong); }
select:focus {
  outline: none;
  border-color: var(--accent-ring);
  box-shadow: 0 0 0 3px var(--accent-soft);
}

/* segmented control（iOS 风格分段控件，适合 2-3 个互斥选项） */
.segmented {
  display: flex;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 3px;
  gap: 2px;
}
.seg-btn {
  flex: 1;
  padding: 8px 12px;
  font-size: 12px;
  font-weight: 400;
  background: transparent;
  border: none;
  border-radius: 6px;
  color: var(--muted);
  cursor: pointer;
  font-family: inherit;
  letter-spacing: -0.005em;
  transition-property: var(--t-props); transition-duration: .15s; transition-timing-function: ease;
  white-space: nowrap;
}
.seg-btn:hover:not(.on) { color: var(--fg); background: rgba(255,255,255,0.04); }
.seg-btn.on {
  background: var(--accent);
  color: var(--on-bg);
  font-weight: 650;
  box-shadow: 0 1px 3px rgba(0,0,0,0.25), 0 1px 0 rgba(255,255,255,0.3) inset;
}
/* 风格选择器：显示品牌短名 → 等宽分段；风格多到一行放不下时换行（每行等分） */
.seg-wrap { flex-wrap: wrap; }
.seg-wrap .seg-btn { flex: 1; min-width: 0; }

/* chip / 卡片选项 */
.choices { display: flex; gap: 6px; flex-wrap: wrap; }
.choices-row { flex-wrap: nowrap; }
.choice-aspect { flex: 1; text-align: center; padding: 8px 6px; line-height: 1.4; }
.choice {
  font-size: 12px; padding: 7px 12px; border-radius: var(--radius);
  background: var(--card); color: var(--fg);
  border: 1px solid var(--border); cursor: pointer;
  text-align: left; font-family: inherit;
  transition-property: var(--t-props); transition-duration: .15s; transition-timing-function: ease;
}
.choice:hover { background: var(--card-hover); border-color: var(--border-strong); }
.choice.on {
  background: rgba(247,107,28,0.22);
  color: var(--accent);
  border-color: var(--accent);
  font-weight: 650;
}
.choice-block { display: block; position: relative; }
.preset-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 6px; }

/* 链接裂变：源主图网格（之前漏写，导致源图原始大小铺开撑乱页面） */
.fission-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; margin: 10px 0 14px; }
.fission-card {
  background: var(--surface-sub); border: 2px solid var(--border); border-radius: var(--radius);
  padding: 5px; cursor: pointer; transition: border-color .15s, background .15s;
}
.fission-card:hover { background: var(--card-hover); border-color: var(--border-strong); }
.fission-card.on { border-color: var(--accent); background: var(--accent-soft); box-shadow: 0 0 0 3px var(--accent-ring); }
.fission-card img { width: 100%; aspect-ratio: 3 / 4; object-fit: cover; border-radius: 6px; display: block; }
/* 图片下方的比例标签行 */
.fission-card-label {
  font-size: 12px; color: var(--muted); text-align: center; margin-top: 4px; line-height: 1.3;
}
/* 换背景 / 换姿势 两个 checkbox 并排 */
.fission-card-toggles {
  display: flex; justify-content: center; gap: 8px; margin-top: 4px; flex-wrap: wrap;
}
.fission-card-toggles label {
  display: flex; align-items: center; gap: 3px;
  font-size: 12px; color: var(--muted); cursor: pointer;
}
.fission-card-toggles label input { accent-color: var(--accent); }

/* ===== 链接裂变重设计：选图视图 ===== */
.workspace-fission { flex-direction: column; }
.workspace-fission > .panel { width: 100%; max-width: none; }

/* 链接裂变 · 贴链接输入栏（一体搜索栏：input + 读取按钮拼成一个控件） */
.ia-bar { display: flex; align-items: stretch; height: 46px; border: 1px solid var(--border-strong); border-radius: 11px; overflow: hidden; background: var(--stage); transition: border-color .15s, box-shadow .15s; }
.ia-bar:focus-within { border-color: var(--accent-ring); box-shadow: 0 0 0 3px var(--accent-soft); }
.ia-icon { display: flex; align-items: center; padding: 0 6px 0 14px; color: var(--muted); font-size: 14px; }
.ia-input { flex: 1; border: 0; background: transparent; color: var(--fg); font-size: 14px; padding: 0 12px; outline: none; min-width: 0; }
.ia-btn { border: 0; background: var(--accent); color: #000; font-weight: 650; font-size: 14px; padding: 0 20px; cursor: pointer; white-space: nowrap; transition: opacity .15s; }
.ia-btn:disabled { opacity: .6; cursor: default; }
.ia-sub { font-size: 12px; color: var(--muted); margin: 8px 2px 0; }
.ia-sub.prog { color: var(--accent); }
/* ===== 读图后输入条收缩成右侧小胶囊（点击展开）=====
   宽度动画用 max-width 过渡（width:auto 不可过渡）；margin-left:auto 让条始终右锚，收/展都贴右滑 */
.ia-bar { max-width: 100%; margin-left: auto; transition: max-width .38s cubic-bezier(.4, 0, .2, 1), height .38s ease, border-radius .38s ease, margin .38s cubic-bezier(.4, 0, .2, 1), padding .38s ease, background .38s ease, transform .3s ease, border-color .15s, box-shadow .15s; }
.ia-bar.ia-collapsed { max-width: 112px; height: 34px; margin-bottom: 10px; align-items: center; justify-content: center; cursor: pointer; border-radius: 999px; }
.ia-bar.ia-collapsed:hover { border-color: var(--accent-ring); box-shadow: 0 0 0 3px var(--accent-soft); }
.ia-bar.ia-collapsed .ia-icon { padding: 0 6px 0 0; }
/* 收缩时输入框/按钮只隐藏不删（展开原样还原），残余宽度交给容器 overflow:hidden 裁掉 */
.ia-bar.ia-collapsed .ia-input, .ia-bar.ia-collapsed .ia-btn { opacity: 0; flex: 0 0 0; width: 0; min-width: 0; padding: 0; border: 0; pointer-events: none; }
.ia-input, .ia-btn { transition: opacity .15s ease; }
.ia-mini-label { font-size: 14px; font-weight: 650; white-space: nowrap; }

/* ===== 链接裂变 · 空状态入口「光晕玻璃」（设计稿 B 移植）=====
   空态（!fissionBarCollapsed → .fz-hero-on）：居中 hero + 香槟金氛围光 + 毛玻璃胶囊；
   收缩态：hero 淡出塌高、aurora 熄灭、输入条沿用既有 max-width 动画滑去右上成小胶囊。
   香槟金只在 hero 区生效（变量收在 .fz-panel），nav 的 #f76b1c 不动。 */
.fz-panel { position: relative; min-height: 0; --fz-gold-hi: #ffcaa0; --fz-gold: #f4a86a; --fz-gold-deep: #e0681a;
  transition: padding .45s cubic-bezier(.22, .6, .2, 1), min-height .45s cubic-bezier(.22, .6, .2, 1); }
.fz-panel.fz-hero-on { padding-top: clamp(70px, 15vh, 150px); padding-bottom: 64px; min-height: clamp(440px, 60vh, 660px); }
/* hero 内容压在氛围光之上（aurora 是 absolute 首子元素，positioned 兄弟按 DOM 序绘制） */
.fz-panel > div:not(.fz-aurora-wrap) { position: relative; }
/* 收缩态恢复旧 panel-title（标题行）：淡入接位，避免 hero 大标题消失时生硬弹出 */
.fz-panel:not(.fz-hero-on) .fz-title-row { animation: fzFadeIn .4s ease .15s both; }

/* 氛围光：满铺面板、自带圆角裁切，pointer-events 穿透；静息 .09，聚焦呼吸增强 */
.fz-panel .fz-aurora-wrap { position: absolute; inset: 0; overflow: hidden; border-radius: var(--radius-lg); pointer-events: none; opacity: 0; visibility: hidden; transition: opacity .6s ease, visibility .6s; }
.fz-panel.fz-hero-on .fz-aurora-wrap { opacity: 1; visibility: visible; animation: fzFadeIn .9s ease .25s both; }
.fz-aurora { position: absolute; display: block; border-radius: 50%; filter: blur(70px); opacity: .09; transition: opacity 1.1s cubic-bezier(.22, .6, .2, 1); will-change: opacity; }
.fz-aurora.a1 { width: 920px; height: 520px; left: 50%; top: -30px; transform: translateX(-50%);
  background: radial-gradient(ellipse at center, var(--fz-gold) 0%, rgba(247,107,28,.5) 38%, transparent 72%); }
.fz-aurora.a2 { width: 560px; height: 380px; left: 30%; top: 26%; transform: translateX(-50%);
  background: radial-gradient(ellipse at center, #e0681a 0%, transparent 68%); opacity: .054; }
/* 聚焦输入条 → 整片氛围光吸气式增强 */
.fz-hero-on:has(.ia-bar:focus-within) .fz-aurora.a1 { opacity: .14; }
.fz-hero-on:has(.ia-bar:focus-within) .fz-aurora.a2 { opacity: .084; }
/* 地平线：胶囊下方 1px 金色微光，强化纵深 */
.fz-aurora-wrap::after { content: ''; position: absolute; left: 50%; top: 68%; width: 720px; max-width: 80%; height: 1px; transform: translateX(-50%);
  background: linear-gradient(90deg, transparent, rgba(247,107,28,.22), transparent); }

/* hero 标题区：空态居中显示，收缩态淡出 + 塌高（max-height 过渡）让输入条顺滑上移 */
.fz-hero-head { text-align: center; max-height: 220px; opacity: 1; overflow: hidden;
  transition: max-height .45s cubic-bezier(.4, 0, .2, 1), opacity .3s ease; }
.fz-panel:not(.fz-hero-on) .fz-hero-head { max-height: 0; opacity: 0; }
.fz-hero-on .fz-hero-head { animation: fzHeroIn .55s cubic-bezier(.22,.6,.2,1) .15s both; }
.fz-hero-kicker { display: inline-flex; align-items: center; gap: 8px; font-size: 12px; letter-spacing: 3px; color: var(--fz-gold-hi); opacity: .65; margin-bottom: 16px; }
.fz-hero-kicker::before, .fz-hero-kicker::after { content: ''; width: 28px; height: 1px; background: linear-gradient(90deg, transparent, rgba(247,107,28,.5)); }
.fz-hero-kicker::after { transform: scaleX(-1); }
.fz-hero-title { font-size: 44px; font-weight: 650; letter-spacing: 6px; text-indent: 6px; margin: 0;
  background: linear-gradient(180deg, #fff3ea 30%, #f4a86a 100%); -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; }
.fz-hero-sub { margin: 14px 0 0; font-size: 14px; color: rgba(242,240,234,.56); letter-spacing: 1px; }

/* hero 态毛玻璃胶囊输入条：宽度上限 760、居中（margin-right 用 calc 凑居中→收缩时可过渡回 0 贴右滑） */
.fz-hero-on .ia-bar:not(.ia-collapsed) {
  max-width: min(760px, 100%); margin-right: max(0px, calc((100% - 760px) / 2)); margin-top: 40px;
  height: 62px; align-items: center; padding: 0 8px 0 18px; border-radius: 999px;
  border-color: rgba(255,255,255,.10); background: rgba(255,255,255,.045);
  backdrop-filter: blur(22px) saturate(1.5); -webkit-backdrop-filter: blur(22px) saturate(1.5);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.07), 0 1px 2px rgba(0,0,0,.4), 0 28px 64px -18px rgba(0,0,0,.65);
  animation: fzFadeIn .45s ease .1s both;
  transition: max-width .38s cubic-bezier(.4, 0, .2, 1), height .38s ease, border-radius .38s ease, margin .38s cubic-bezier(.4, 0, .2, 1), padding .38s ease, background .38s ease, transform .35s cubic-bezier(.22, .6, .2, 1), border-color .35s ease, box-shadow .35s ease;
}
.fz-hero-on .ia-bar:hover:not(:focus-within) { border-color: rgba(255,255,255,.16); }
/* 聚焦微交互：描边染金、整条上浮 1px、投影渗一圈极淡金晕（光晕呼吸走上面 :has 规则） */
.fz-hero-on .ia-bar:focus-within {
  border-color: rgba(247,107,28,.45); transform: translateY(-1px);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.10), 0 1px 2px rgba(0,0,0,.4), 0 28px 64px -18px rgba(0,0,0,.65),
    0 0 0 1px rgba(247,107,28,.12), 0 12px 48px -8px rgba(247,107,28,.14);
}
.fz-hero-on .ia-icon { font-size: 20px; opacity: .85; transition: opacity .3s, transform .3s; }
.fz-hero-on .ia-bar:focus-within .ia-icon { opacity: 1; transform: rotate(-8deg); }
.fz-hero-on .ia-input, .fz-hero-on .ia-input:focus { background: transparent; border: 0; border-radius: 0; box-shadow: none; }
.fz-hero-on .ia-input { text-align: center; font-size: 14px; letter-spacing: .3px; caret-color: var(--fz-gold); padding: 0 12px; height: 100%; }
.fz-hero-on .ia-bar:focus-within .ia-input::placeholder { color: rgba(242,240,234,.22); }
/* 读取主图按钮：胶囊内实金小胶囊（香槟渐变） */
.fz-hero-on .ia-btn { height: 46px; padding: 0 28px; border-radius: 999px; font-size: 14px; letter-spacing: 1px; color: #2b1400;
  background: linear-gradient(180deg, var(--fz-gold-hi) 0%, var(--fz-gold) 55%, var(--fz-gold-deep) 130%);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.45), 0 6px 18px -6px rgba(247,107,28,.45);
  transition: filter .15s, box-shadow .15s, transform .15s, opacity .15s ease; }
.fz-hero-on .ia-btn:hover:not(:disabled) { filter: brightness(1.07); box-shadow: inset 0 1px 0 rgba(255,255,255,.5), 0 8px 24px -6px rgba(247,107,28,.6); }
.fz-hero-on .ia-btn:active { transform: translateY(1px); filter: brightness(.96); }
/* hero 提示行：居中、放大一档；进度色收向香槟 */
.fz-hero-on .ia-sub { text-align: center; margin-top: 20px; font-size: 14px; letter-spacing: .6px; color: rgba(242,240,234,.34); animation: fzFadeIn .5s ease .25s both; }
.fz-hero-on .ia-sub.prog { color: var(--fz-gold); }
@keyframes fzFadeIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes fzHeroIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
@media (max-width: 900px) {
  .fz-hero-title { font-size: 32px; letter-spacing: 4px; }
  .fz-hero-on .ia-bar:not(.ia-collapsed) { height: 56px; }
  .fz-panel.fz-hero-on { padding-top: 56px; min-height: 460px; }
}

/* 选图阶段标题行：标题左、紧凑工具条右（h2 保留默认 margin 维持原垂直节奏；窄屏 wrap 到下一行右对齐） */
/* 链接裂变 · 顶部阶段 stepper（workspace 内、panel 之前；暗底金色） */
.fz-stepper { display: flex; align-items: center; gap: 18px; padding: 13px 22px; margin-bottom: 14px;
  background: var(--panel); border: 1px solid var(--border); border-radius: 14px; flex: none; }
.fz-step-back { display: flex; align-items: center; gap: 7px; color: var(--muted); font-size: 14px; font-weight: 650;
  background: transparent; border: 0; cursor: pointer; font-family: inherit; padding: 6px 8px; border-radius: 10px; transition-property: var(--t-props); transition-duration: .15s; transition-timing-function: ease; }
.fz-step-back:hover { color: var(--fg); background: rgba(255,255,255,.05); }
.fz-step-back.disabled { opacity: .3; cursor: default; pointer-events: none; }
.fz-step-title { font-size: 14px; font-weight: 650; letter-spacing: .5px; }
.fz-steps { display: flex; align-items: center; gap: 6px; margin-left: auto; }
.fz-step { display: flex; align-items: center; gap: 9px; padding: 6px 8px; border-radius: 10px; border: 0;
  background: transparent; font-family: inherit; cursor: default; }
.fz-step .dot { width: 26px; height: 26px; border-radius: 50%; display: flex; align-items: center; justify-content: center;
  font-size: 14px; font-weight: 650; flex: none; transition-property: var(--t-props); transition-duration: .15s; transition-timing-function: ease; }
.fz-step .lbl { font-size: 14px; font-weight: 650; white-space: nowrap; transition: color .15s; }
.fz-step.done { cursor: pointer; }
.fz-step.done .dot { background: var(--accent-soft); color: var(--accent); border: 1px solid var(--accent-ring); }
.fz-step.done .lbl { color: var(--fg); }
.fz-step.done:hover { background: rgba(255,255,255,.05); }
.fz-step.done:hover .dot { background: var(--accent); color: #000; }
.fz-step.cur .dot { background: var(--accent); color: #000; box-shadow: 0 0 16px rgba(247,107,28,.45); }
.fz-step.cur .lbl { color: var(--fg); }
.fz-step.future .dot { background: rgba(255,255,255,.06); color: var(--muted); border: 1px solid var(--border); }
.fz-step.future .lbl { color: var(--muted); }
.fz-sep { width: 34px; height: 1px; border-top: 1px dashed var(--border-strong); flex: none; }
.fz-sep.passed { border-top-color: var(--accent-ring); }
@media (max-width: 720px) { .fz-step .lbl { display: none; } .fz-stepper { gap: 10px; padding: 11px 14px; } .fz-sep { width: 18px; } }

.fz-title-row { display: flex; align-items: center; flex-wrap: wrap; gap: 8px 12px; }
.fz-title-acts { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; margin-left: auto; }
.fz-menu-trigger{height:34px;display:inline-flex;align-items:center;gap:7px;padding:0 12px;border:1px solid var(--border);border-radius: 10px;background:var(--panel);color:var(--fg);font:inherit;font-size: 14px;cursor:pointer}
.fz-menu-trigger:hover,.fz-menu-trigger.open{background:var(--panel-strong);border-color:var(--border-strong)}
.fz-action-menu{position:absolute;z-index:60;min-width:190px;padding:5px;border:1px solid var(--border-strong);border-radius:var(--radius-ctl);background:var(--surface-pop);box-shadow:0 14px 34px rgba(0,0,0,.48)}
.fz-action-menu-top{top:calc(100% + 6px);left:0}.fz-action-menu-bottom{right:0;bottom:calc(100% + 6px)}
.fz-action-menu button{display:block;width:100%;padding:8px 10px;border:0;border-radius:6px;background:transparent;color:var(--fg);font:inherit;font-size: 12px;text-align:left;cursor:pointer}
.fz-action-menu button:hover:not(:disabled){background:rgba(255,255,255,.08)}.fz-action-menu button:disabled{opacity:.4;cursor:default}
.fz-mini-btn { background: var(--panel); color: var(--fg); border: 1px solid var(--border); border-radius: 999px;
  font-size: 14px; padding: 6px 14px; cursor: pointer; font-family: inherit; white-space: nowrap;
  transition: background .15s, border-color .15s; }
.fz-mini-btn:hover { background: var(--panel-strong); border-color: var(--border-strong); }
.fz-gen-btn { background: var(--accent); color: var(--on-bg); border: none; border-radius: 10px;
  font-size: 14px; font-weight: 650; padding: 8px 18px; cursor: pointer; font-family: inherit; white-space: nowrap;
  transition: filter .15s; }
.fz-gen-btn:hover:not(:disabled) { filter: brightness(1.06); }
.fz-gen-btn:disabled { background: rgba(255,255,255,.12); color: var(--muted); cursor: not-allowed; }
.fz-aspect-group { margin-bottom: 22px; scroll-margin-top: 64px; }  /* 锚点/聚焦时为吸顶工具栏留空 */
.fz-ag-head { display: flex; align-items: baseline; gap: 10px; margin: 0 0 12px; padding-bottom: 8px; border-bottom: 1px solid var(--border); }
.fz-ag-head .ar { font-size: 14px; font-weight: 650; }
.fz-ag-head .cnt { font-size: 12px; color: var(--muted); }
.fz-ag-grid { display: grid; gap: 14px; grid-template-columns: repeat(auto-fill, minmax(165px, 1fr)); align-items: start; }
.fz-card { background: var(--surface-sub); border: 1px solid var(--border); border-radius: var(--radius-lg); padding: 8px; transition: border-color .15s, box-shadow .15s; }
.fz-card.sel { border-color: var(--border-strong); box-shadow: 0 0 0 1px rgba(255,255,255,.06); }
.fz-thumb { position: relative; border-radius: 8px; overflow: hidden; }
.fz-thumb img { width: 100%; height: auto; display: block; }  /* 按图片真实比例显示，不拉伸不裁切 */
.fz-aspect-pill { position: absolute; top: 8px; left: 8px; font-size: 10px; font-weight: 650; color: #d8d8de; background: rgba(0,0,0,.5); padding: 2px 7px; border-radius: 999px; }
.fz-idx-pill { position: absolute; top: 8px; right: 8px; font-size: 10px; color: #a8a8b0; background: rgba(0,0,0,.4); padding: 2px 7px; border-radius: 999px; }
.fz-card-chips { display: flex; gap: 7px; margin-top: 8px; }
.fz-chip-col { flex: 1; display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.fz-chip-wrap { position: relative; display: flex; }
.fz-chip { width: 100%; font-size: 12px; font-weight: 650; padding: 7px 4px; border-radius: 10px; border: 1px solid var(--border); background: transparent; color: var(--muted); display: flex; align-items: center; justify-content: center; gap: 4px; cursor: pointer; transition-property: var(--t-props); transition-duration: .12s; transition-timing-function: ease; }
.fz-chip.bg.on { background: var(--bg-chip-soft); border-color: var(--bg-chip-ring); color: #bcd3ff; }
.fz-chip.pose.on { background: var(--pose-chip-soft); border-color: var(--pose-chip-ring); color: #aef0c8; }
.fz-chip-pop { position: absolute; bottom: calc(100% + 6px); left: 0; width: 200px; background: var(--surface-pop); border: 1px solid var(--border-strong); border-radius: var(--radius-ctl); padding: 10px; box-shadow: 0 10px 30px rgba(0,0,0,.55); z-index: 30; opacity: 0; visibility: hidden; transform: translateY(5px); transition: opacity .12s, transform .12s; }
/* hover 弹出；focus-within 锁定：点进面板(选项/自定义输入框获焦)后即使鼠标移开也不收起，
   修「自定义文案输入框打字时面板闪退」(纯 hover 面板容不下文本输入) */
.fz-chip-wrap:hover .fz-chip-pop,
.fz-chip-wrap:focus-within .fz-chip-pop { opacity: 1; visibility: visible; transform: none; }
.fz-chip-pop::after { content: ''; position: absolute; top: 100%; left: 0; right: 0; height: 10px; }
.fz-chip-wrap.pose .fz-chip-pop { left: auto; right: 0; }
.fz-chip-pop.down { top: calc(100% + 6px); bottom: auto; }  /* #4 顶排卡片：上方空间不足时改向下弹，不盖比例标题 */
.fz-chip-pop.down::after { top: auto; bottom: 100%; }
.fz-chip-pop .pl { font-size: 12px; font-weight: 650; margin-bottom: 6px; }
.fz-chip-pop .pl.bg { color: #bcd3ff; }
.fz-chip-pop .pl.pose { color: #aef0c8; }
.fz-chip-pop .opt { display: flex; align-items: center; gap: 8px; font-size: 12px; color: #cfcfd6; padding: 5px 6px; border-radius: 6px; cursor: pointer; }
.fz-chip-pop .opt:hover { background: var(--card); }
.fz-chip-pop .opt input { width: auto; accent-color: var(--accent); margin: 0; flex: none; }
.fz-custom { width: 100%; background: var(--stage); border: 1px solid var(--border); border-radius: 7px; color: var(--fg); font-size: 12px; padding: 7px 9px; margin-top: 4px; }
.fz-chip-cap { font-size: 10px; color: var(--muted); text-align: center; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* ===== 链接裂变重设计：结果对比视图 ===== */
.fz-rtoolbar { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; background: rgba(18,18,22,.9); backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px); border: 1px solid var(--border); border-radius: var(--radius-lg); padding: 12px 16px; margin-bottom: 16px; position: sticky; top: 8px; z-index: 20; }  /* 实底+磨砂：sticky 滚动时把下方组标题模糊化盖住，不再透出清晰文字（原 --panel-strong 半透会重叠） */
.fz-breview-toolbar{position:sticky;top:8px;z-index:20;display:flex;align-items:baseline;gap:12px;flex-wrap:wrap;padding:12px 14px;margin-bottom:8px;border:1px solid var(--border);border-radius:8px;background:rgba(18,18,22,.94);backdrop-filter:blur(10px)}
.fz-breview-toolbar b{font-size: 14px}.fz-breview-toolbar span{font-size: 12px;color:#d6d6dc}.fz-breview-toolbar small{margin-left:auto;color:var(--muted);font-size: 12px}
/* 确认页底部的「确认并发布 → 自动跳下一个」操作条（2026-08-10 老板看过演示页拍板）。
   贴底（sticky bottom）：图多的时候滚到哪儿它都在手边，不用滚回顶上找。
   ⚠ 只有「确认并发布」用品牌橙 —— 它是这一屏唯一的主操作；发布方式是二选一开关，
     选中态只给淡橙描边，不跟主按钮抢（老板视觉红线：橙色只留给已选中的值和主操作）。 */
.fz-breview-bar{position:sticky;bottom:0;z-index:20;display:flex;align-items:center;gap:12px;flex-wrap:wrap;
  margin-top:10px;padding:12px 14px;border:1px solid var(--border);border-radius:10px;
  background:rgba(18,18,22,.96);backdrop-filter:blur(10px)}
.fz-breview-mode{display:flex}
.fz-breview-mode button{height:34px;padding:0 14px;font-family:inherit;font-size:12.5px;cursor:pointer;
  border:1px solid var(--border-strong);background:rgba(255,255,255,.05);color:var(--fg);border-radius:0}
.fz-breview-mode button:first-child{border-radius:9px 0 0 9px}
.fz-breview-mode button:last-child{border-radius:0 9px 9px 0;border-left:none}
.fz-breview-mode button.sel{background:rgba(247,107,28,.16);border-color:rgba(247,107,28,.5);color:var(--accent)}
.fz-breview-all{height:34px;padding:0 12px;border-radius:9px;border:1px solid var(--border-strong);
  background:rgba(255,255,255,.05);color:var(--fg);font-family:inherit;font-size:12.5px;cursor:pointer}
.fz-breview-step{margin-left:auto;color:var(--muted);font-size:12.5px;white-space:nowrap}
.fz-breview-step b{color:var(--fg)}
.fz-breview-skip{height:34px;padding:0 14px;border-radius:9px;border:1px solid var(--border-strong);
  background:rgba(255,255,255,.05);color:var(--fg);font-family:inherit;font-size:12.5px;cursor:pointer}
.fz-breview-pub{height:34px;padding:0 20px;border-radius:9px;border:1px solid var(--accent);
  background:var(--accent);color:#1a1300;font-family:inherit;font-size:13px;font-weight:650;cursor:pointer}
/* 一键发完剩余（2026-08-11）：小号描边款，刻意不做实心橙 —— 底栏里实心橙只许有「确认并发布」
   一颗（老板红线：两颗橙按钮并排容易点错，而这颗一点就是一串） */
.fz-breview-puball{height:34px;padding:0 12px;border-radius:9px;border:1px solid rgba(247,107,28,.55);
  background:transparent;color:#f9a76b;font-family:inherit;font-size:12.5px;cursor:pointer}
.fz-breview-puball:hover{background:rgba(247,107,28,.12)}
.fz-breview-puball:disabled{opacity:.45;cursor:default}
.fz-breview-puball-hint{font-size:12px;color:var(--muted)}
.fz-breview-skip:disabled,.fz-breview-pub:disabled{opacity:.45;cursor:default}
/* 确认页每张生成图右上角的勾选圈（2026-08-10 老板：「我都没有勾选的地方」）。
   选中态用品牌橙实底 —— 它就是「已选中的值」，正是老板留给橙色的两种用途之一。 */
.fz-breview-tick{position:absolute;right:8px;top:8px;z-index:3;width:26px;height:26px;border-radius:50%;
  display:flex;align-items:center;justify-content:center;cursor:pointer;font-size:14px;line-height:1;
  border:2px solid rgba(255,255,255,.6);background:rgba(0,0,0,.42);color:transparent;
  font-family:inherit;padding:0;transition:background .15s,border-color .15s,color .15s}
.fz-breview-tick:hover{border-color:#fff}
.fz-breview-tick.on{background:var(--accent);border-color:var(--accent);color:#1a1300}
.fz-breview-group{padding:16px 0 20px;border-bottom:1px solid var(--border)}
.fz-breview-head{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:12px}
.fz-breview-head div{min-width:0}.fz-breview-head b{display:block;font-size: 14px}.fz-breview-head span{display:block;margin-top:3px;color:var(--muted);font-size: 12px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.fz-breview-head small{flex:none;color:#b8bac2;font-size: 12px}
.fz-breview-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(360px,1fr));gap:12px}
.fz-breview-pair{display:grid;grid-template-columns:1fr 1fr;gap:6px;padding:7px;border:1px solid var(--border);border-radius:8px;background:rgba(255,255,255,.025);min-width:0}
.fz-breview-media{position:relative;aspect-ratio:3/4;min-width:0;overflow:hidden;border-radius:6px;background:var(--stage)}
.fz-breview-media>img{width:100%;height:100%;display:block;object-fit:contain}.fz-breview-media .fz-rstate{width:100%;height:100%;aspect-ratio:auto;border-radius:0;padding:10px;text-align:center}.fz-breview-media .fz-rstate span{font-size: 10px;font-weight:400;line-height:1.35;overflow-wrap:anywhere}
.fz-breview-copy-hover{position:absolute;inset:0;z-index:3;display:flex;align-items:center;justify-content:center;background:rgba(10,10,13,.48);opacity:0;transition: opacity .15s}
/* 换装墙的悬停浮层塞了三颗按钮（重发/下载/提示词改图），横排挤不下会被 flex 摊成上中下散点
   （2026-08-11 老板截图点名「排版丑」）——这儿改竖排等距一列、按钮等宽居中。
   裂变那边同类浮层只有 1-2 颗，横排居中挺好，⛔ 别动公共那行，只覆盖换装上下文。 */
.ty-result .fz-breview-copy-hover{flex-direction:column;gap:10px}
.ty-result .fz-breview-copy-hover button{width:138px;justify-content:center}
.fz-breview-generated:hover .fz-breview-copy-hover{opacity:1}
.fz-breview-copy-hover button{display:inline-flex;align-items:center;gap:5px;padding:7px 10px;border:1px solid rgba(247,107,28,.5);border-radius:6px;background:rgba(18,18,22,.92);color:#f9a76b;font-family:inherit;font-size: 12px;line-height:1;font-weight: 650;cursor:pointer}
.fz-breview-copy-hover svg{width:14px;height:14px}
.fz-breview-copy-running{position:absolute;inset:0;z-index:4;display:flex;align-items:center;justify-content:center;gap:7px;background:rgba(10,10,13,.66);color:#f9a76b;font-size:12px;font-weight: 650}
.fz-breview-copy-running .fz-spin{width:16px;height:16px;margin:0}
.fz-breview-copy-editor{position:absolute;inset:7px;z-index:5;display:flex;flex-direction:column;gap:7px;padding:10px;border:1px solid rgba(247,107,28,.5);border-radius:6px;background:rgba(18,18,22,.97);box-shadow:0 12px 30px rgba(0,0,0,.42)}
.fz-breview-copy-editor label{color:#f2f2f4;font-size: 12px;font-weight: 650;padding-right:22px}
.fz-breview-copy-editor textarea{flex:1;min-height:64px;resize:none;border:1px solid var(--border);border-radius: var(--radius-ctl);background: var(--surface-ctl);color:var(--fg);padding:8px;font-family:inherit;font-size: 12px;line-height:1.5;outline:none}
.fz-breview-copy-editor textarea:focus{border-color:var(--accent)}
.fz-breview-copy-editor .err{color:#fca5a5;font-size:10px;line-height:1.3;max-height:40px;overflow:auto}
.fz-breview-copy-close{position:absolute;top:6px;right:6px;width:24px;height:24px;border:0;background:transparent;color:var(--muted);font-size: 20px;line-height:1;cursor:pointer}
.fz-breview-copy-close:hover{color:var(--fg)}
.fz-breview-copy-actions{display:flex;align-items:center;justify-content:space-between;gap:8px}
.fz-breview-copy-actions span{color:var(--muted);font-size: 10px}
.fz-breview-copy-actions button{padding:6px 9px;border:0;border-radius:6px;background:var(--accent);color:#1a1300;font-family:inherit;font-size: 10px;line-height:1;font-weight: 650;cursor:pointer}
.fz-breview-copy-actions button:disabled{opacity:.5;cursor:default}
.fz-breview-pair footer{grid-column:1/-1;display:flex;align-items:center;gap:8px;min-height:28px;padding:2px 3px 0;color:var(--muted);font-size: 12px}.fz-breview-pair footer>span{min-width:0;flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.fz-breview-pair footer button{flex:none;padding:5px 8px;border:1px solid rgba(239,68,68,.35);border-radius:6px;background:rgba(239,68,68,.09);color:#fca5a5;font:inherit;cursor:pointer}.fz-breview-pair footer small{flex:none;color:var(--muted)}
@media(max-width:620px){.fz-breview-grid{grid-template-columns:1fr}.fz-breview-pair{grid-template-columns:1fr}.fz-breview-pair footer{grid-column:1}.fz-breview-toolbar small{width:100%;margin-left:0}}
.fz-rprog { font-size: 14px; font-weight: 650; }
.fz-racts { margin-left: auto; display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
/* 结果视图顶栏：两个并列等大的方向按钮（裂变新链接 / 替换原链接，co-equal 二选一） */
.fz-dir-group { display: flex; align-items: flex-start; gap: 12px; }
.fz-dir-btn {
  width: 220px; box-sizing: border-box;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px;
  padding: 11px 16px; min-height: 56px;
  border-radius: var(--radius); cursor: pointer; font-family: inherit;
  background: var(--accent-soft); border: 1px solid var(--accent); color: var(--accent);
  transition-property: var(--t-props); transition-duration: .15s; transition-timing-function: ease;
}
.fz-dir-btn:hover { background: rgba(247,107,28,0.22); transform: translateY(-1px); box-shadow: 0 8px 22px rgba(247,107,28,0.18); }
.fz-dir-btn:active { transform: translateY(0); }
.fz-dir-main { font-size: 14px; font-weight: 650; line-height: 1.2; }
.fz-dir-sub { font-size: 12px; font-weight: 400; color: var(--muted); line-height: 1.2; }
.fz-rcols { display: flex; flex-wrap: wrap; gap: 12px; align-items: start; }
.fz-rcol { display: flex; flex-direction: column; gap: 8px; width: 150px; }
.fz-rsep { font-size: 12px; color: var(--muted); text-align: center; }
.fz-rcard .fz-thumb { position: relative; }
.fz-rhover { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; gap: 10px; background: rgba(0,0,0,.45); opacity: 0; transition: opacity .12s; z-index: 4; }  /* #2 生成图悬停操作层 */
.fz-rcard .fz-thumb:hover .fz-rhover { opacity: 1; }
.fz-rhover button { width: 34px; height: 34px; border-radius: 50%; border: 1px solid rgba(255,255,255,.55); background: rgba(0,0,0,.5); color: #fff; font-size: 14px; line-height: 1; cursor: pointer; display: flex; align-items: center; justify-content: center; padding: 0; }
.fz-rhover button:hover:not(:disabled) { background: var(--accent); color: #000; border-color: var(--accent); }
.fz-rhover button:disabled { opacity: .45; cursor: not-allowed; }
.fz-rcap { font-size: 12px; color: var(--muted); text-align: center; margin-top: 4px; }
.fz-badge { position: absolute; top: 6px; left: 6px; font-size: 10px; font-weight: 650; padding: 2px 7px; border-radius: 999px; }
.fz-badge.orig { background: rgba(255,255,255,.16); color: #e6e6ea; }
.fz-badge.gen { background: var(--accent); color: #000; }
.fz-badge.keep { background: rgba(255,255,255,.10); color: var(--muted); }
.fz-vtag { position: absolute; bottom: 6px; left: 6px; right: 6px; font-size: 10px; font-weight: 650; text-align: center; padding: 2px 4px; border-radius: 5px; }
.fz-vtag.bg { background: var(--bg-chip-soft); color: #bcd3ff; }
.fz-vtag.pose { background: var(--pose-chip-soft); color: #aef0c8; }
.fz-rstate { aspect-ratio: 3/4; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px; background: var(--stage); border-radius: 8px; font-size: 12px; color: var(--muted); }
.fz-rstate.fail { color: var(--danger); }
.fz-rstate.timeout { color: #e0681a; }  /* 软超时：琥珀色，区别于红色硬失败——图很可能在后台跑完、会进历史 */
.fz-rstate.insufficient { color: #f76b1c; font-weight: 650; background: rgba(247,107,28,.08); }  /* 余额不足·已跳过：品牌橙+浅橙底，点右上角充值后可单张补生成 */
.fz-rstate.queued { color: var(--muted); opacity: .6; }  /* 排队中：比"生成中"更淡、沙漏静态不转，逐张排队时还没轮到的张显示这个 */
/* 裂变结果勾选圈：勾选=采用（完成自动勾上，取消=不推送这张）。仿 .gen-cell-check。
   z-index 必须高于 .fz-rhover(4)：悬停操作层 inset:0 铺满整图，压住圈会让点击全部落空 */
.fz-pick {
  position: absolute; top: 6px; right: 6px;
  width: 22px; height: 22px; border-radius: 50%;
  background: rgba(0,0,0,.55); border: 1.5px solid rgba(255,255,255,.6);
  cursor: pointer; display: inline-flex; align-items: center; justify-content: center;
  padding: 0; color: transparent; transition-property: var(--t-props); transition-duration: .12s; transition-timing-function: ease; z-index: 5;
}
.fz-pick:hover { background: rgba(0,0,0,.75); border-color: #fff; }
.fz-pick.on { background: var(--accent); border-color: var(--accent); color: var(--on-bg); box-shadow: 0 2px 8px rgba(247,107,28,.4); }
.fz-pick svg.lucide { width: 13px; height: 13px; stroke-width: 3; }
.fz-spin { width: 20px; height: 20px; border: 2px solid var(--border-strong); border-top-color: var(--accent); border-radius: 50%; animation: spin .8s linear infinite; }
.choice-desc { font-size: 12px; color: var(--muted); margin-top: 2px; font-weight: 400; }
.choice.on .choice-desc { color: rgba(247,107,28,.7); }
/* 场景角度标签：正面=蓝、侧面=紫，挂在 choice-block 的右上角 */
.preset-view-tag {
  position: absolute; top: 6px; right: 8px;
  font-size: 10px; font-weight: 650;
  padding: 1px 6px; border-radius: 8px;
  letter-spacing: 0.02em;
}
.preset-view-tag.is-front { background: rgba(96, 165, 250, 0.18); color: #93c5fd; }
.preset-view-tag.is-side  { background: rgba(192, 132, 252, 0.18); color: #c4b5fd; }
.choice.on .preset-view-tag.is-front { background: rgba(96, 165, 250, 0.28); color: #bfdbfe; }
.choice.on .preset-view-tag.is-side  { background: rgba(192, 132, 252, 0.28); color: #ddd6fe; }
.choice-num { width: 40px; height: 40px; text-align: center; padding: 0; }

/* radio 列表 */
.radio-list { display: flex; flex-direction: column; gap: 8px; }
.radio-row {
  display: flex; align-items: flex-start; gap: 8px;
  font-size: 14px; cursor: pointer;
}
.radio-row input { margin: 2px 0 0; accent-color: var(--accent); }
.radio-row .r-sub { font-size: 12px; color: var(--muted); }

/* 上传区 */
.upload {
  border: 1px dashed var(--border-strong); border-radius: var(--radius);
  padding: 24px 12px; text-align: center; cursor: pointer;
  color: var(--muted); font-size: 12px; line-height: 1.6;
  background: var(--card);
  transition-property: var(--t-props); transition-duration: .15s; transition-timing-function: ease;
}
.upload:hover, .upload.dragover {
  border-color: var(--accent-ring); background: var(--accent-soft);
  color: var(--fg);
}
.upload-preview { position: relative; display: inline-block; }
.upload-preview img { max-height: 200px; border-radius: var(--radius); display: block; }
.upload-x {
  position: absolute; top: -8px; right: -8px;
  width: 22px; height: 22px; border-radius: 50%;
  background: var(--accent); color: var(--on-bg); border: none;
  font-size: 14px; line-height: 1; cursor: pointer;
  box-shadow: 0 2px 8px rgba(247,107,28,0.35);
}

/* 按钮 */
.btn-primary {
  width: 100%; font-size: 14px; font-weight: 650;
  padding: 10px 16px; border-radius: var(--radius-ctl); cursor: pointer;
  background: var(--accent); color: var(--on-bg); border: none;
  font-family: inherit;
  display: flex; align-items: center; justify-content: center; gap: 6px;
  line-height: 1.4; min-height: 42px;
  transition-property: var(--t-props); transition-duration: .15s; transition-timing-function: ease;
  box-shadow: 0 8px 24px rgba(247,107,28,0.22),
              0 1px 0 rgba(255, 255, 255, 0.3) inset;
}
.btn-primary:hover:not(:disabled) {
  filter: brightness(1.05);
  box-shadow: 0 10px 28px rgba(247,107,28,0.32),
              0 1px 0 rgba(255, 255, 255, 0.3) inset;
  transform: translateY(-1px);
}
.btn-primary:active:not(:disabled) { transform: translateY(0); }
.btn-primary:disabled { opacity: .35; cursor: not-allowed; box-shadow: none; }
.btn-text {
  background: none; border: none; color: var(--muted);
  font-size: 12px; cursor: pointer; text-decoration: underline; padding: 0;
  font-family: inherit;
}
.btn-text:hover { color: var(--fg); }
.btn-pager { display: inline-flex; align-items: center; gap: 4px; }

/* 历史页码栏：完整页码版（[<] 1 2 ... 5 [6] 7 ... 12 [>]） */
.pager-bar {
  display: flex; align-items: center; gap: 4px;
  margin-top: 16px; padding-top: 12px;
  border-top: 1px solid var(--border);
  font-size: 12px;
}
.pager-btn {
  min-width: 28px; height: 28px; padding: 0 8px;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--card); color: var(--muted);
  border: 1px solid var(--border); border-radius: 6px;
  cursor: pointer; font-family: inherit; font-size: 12px;
  transition-property: var(--t-props); transition-duration: .15s; transition-timing-function: ease;
}
.pager-btn:hover:not(:disabled) { background: var(--card-hover); color: var(--fg); border-color: var(--border-strong); }
.pager-btn:disabled { opacity: 0.3; cursor: not-allowed; }
.pager-btn.on {
  background: var(--accent); color: var(--on-bg); border-color: var(--accent);
  font-weight: 650;
}
.pager-arrow svg.lucide { width: 12px; height: 12px; }
.pager-ellipsis { color: var(--muted); padding: 0 4px; }
.pager-info { font-size: 12px; color: var(--muted); margin-left: 10px; }

input[type="text"], textarea {
  width: 100%; font-size: 14px;
  background: var(--surface-ctl); color: var(--fg);
  border: 1px solid var(--border); border-radius: var(--radius-ctl);
  font-family: inherit;
  transition-property: var(--t-props); transition-duration: .15s; transition-timing-function: ease;
}
input[type="text"] { height: var(--h-md); padding: 0 12px; }   /* 单行控件上 --h-md 档 */
textarea { padding: 9px 12px; }                                /* 多行不能锁高 */
input[type="text"]:focus, textarea:focus {
  outline: none;
  border-color: var(--accent-ring);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
textarea { margin-top: 8px; resize: vertical; line-height: 1.6; }

/* ===== 右栏:空状态 / 进度 / 结果 ===== */
.empty {
  min-height: 640px;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  color: var(--muted); font-size: 14px; gap: 18px;
}
.empty-illust { max-width: 280px; width: 60%; opacity: .9; display: block; }
.empty-icon-fallback { stroke-width: 1.5; opacity: .35; }
svg.lucide.empty-icon-fallback { width: 60px; height: 60px; }

/* ===== Lucide 图标通用 ===== */
svg.lucide {
  width: 1em; height: 1em; stroke-width: 2;
  vertical-align: -0.125em; flex-shrink: 0;
}
svg.lucide.inline-icon { width: 0.85em; height: 0.85em; margin-left: 4px; }
/* 三按钮图标·金色点睛版（2026-06-13）：比文字略大、右留间距 */
svg.lucide.bic { width: 15px; height: 15px; margin-right: 5px; vertical-align: -3px; }
.upload-x { display: inline-flex; align-items: center; justify-content: center; }
.upload-x svg.lucide { width: 14px; height: 14px; stroke-width: 2.5; }
/* .tab 已用 flex gap 处理图标-文字间距 */
.btn-primary svg.lucide { width: 1.05em; height: 1.05em; }

.progress-wrap { margin-bottom: 20px; }
.progress-text { font-size: 12px; color: var(--muted); margin: 0 0 8px; }
.progress-track {
  height: 6px; background: var(--card); border-radius: 999px; overflow: hidden;
  border: 1px solid var(--border);
}
.progress-fill {
  height: 100%; background: var(--accent); transition: width .4s ease;
  box-shadow: 0 0 12px rgba(247,107,28,0.5);
}
.indeterminate-bar {
  position: relative; overflow: hidden; height: 6px;
  background: var(--card); border-radius: 999px; border: 1px solid var(--border);
}
.indeterminate-bar::after {
  content: ""; position: absolute; left: -40%; top: 0; bottom: 0;
  width: 40%; background: var(--accent);
  animation: indeterminate 1.2s infinite ease-in-out;
}
@keyframes indeterminate { 0% { left: -40%; } 100% { left: 100%; } }

.section-title { font-size: 14px; font-weight: 650; margin: 0 0 14px; letter-spacing: -0.01em; }

.results { display: grid; grid-template-columns: repeat(2, 1fr); gap: 14px; }
.result-card {
  background: var(--surface-sub); border: 1px solid var(--border);
  border-radius: var(--radius); overflow: hidden;
}
.result-head { padding: 8px 12px; font-size: 12px; color: var(--muted); border-bottom: 1px solid var(--border); }
.result-imgs { display: grid; }
.result-imgs.multi { grid-template-columns: repeat(2, 1fr); }
.result-imgs img { width: 100%; display: block; }
.result-meta { padding: 8px 12px; font-size: 12px; color: var(--muted); }
.fallback-note { color: var(--accent); margin-top: 4px; }
.result-pending, .result-failed { padding: 20px 14px; text-align: left; font-size: 12px; }
.result-pending { color: var(--muted); text-align: center; }
.result-failed { color: var(--danger); }
.result-failed .err-title { font-weight: 650; margin-bottom: 8px; text-align: center; }
.result-failed .err-zh {
  color: var(--fg);
  background: rgba(239,68,68,0.08); border-left: 3px solid var(--danger);
  padding: 8px 10px; border-radius: 4px; line-height: 1.6; margin-bottom: 8px;
}
.result-failed .err-raw { color: var(--muted); font-size: 10px; word-break: break-all; opacity: 0.7; line-height: 1.5; }
.spinner {
  width: 22px; height: 22px; margin: 0 auto 8px;
  border: 2px solid var(--border); border-top-color: var(--accent);
  border-radius: 50%; animation: spin 1s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* ===== 历史 tab — 卡片统一规格 =====
   每张卡固定 320px 高：图区 220px（contain 完整显示，不裁不变形）+ body 100px（紧凑信息） */
.history-grid {
  display: grid; grid-template-columns: repeat(4, 1fr);
  column-gap: 14px; row-gap: 4px;  /* 横向保留，纵向贴紧 */
  flex: 1; min-height: 0;
  overflow-y: auto;
  padding-right: 6px;
  scrollbar-gutter: stable;
}
.history-card {
  height: 320px;
  display: flex; flex-direction: column;
  background: var(--surface-sub); border: 1px solid var(--border);
  border-radius: var(--radius); overflow: hidden;
  transition-property: var(--t-props); transition-duration: .15s; transition-timing-function: ease;
}
.history-card:hover { border-color: var(--border-strong); transform: translateY(-1px); }
/* 图区：固定 220px 高，contain 让任意比例的图都完整显示，留白用深底色 */
.history-card > a {
  height: 220px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  background: #0a0a0a; overflow: hidden;
}
.history-card > a img {
  width: 100%; height: 100%;
  object-fit: contain;
  display: block;
}
/* 缩略图占位：404 兜底（thumb-missing，文件意外缺失）+ 过期自动清理（thumb-purged，retention 删的） */
.history-card > a.thumb-missing, .history-card > a.thumb-purged { background: #1d1d1a; text-decoration: none; }
.history-card > a.thumb-missing img { display: none; }
.history-card > a.thumb-missing::before {
  content: '🗂 图片已清理 / 缺失';
  font-size: 12px; color: #7a7468;
}
.history-card > a.thumb-purged::before {
  content: '🗂 已过期自动清理';
  font-size: 12px; color: #7a7468;
}
/* body：100px 高紧凑信息，3 行内容 + 底部 footer 自动贴底 */
.history-body {
  flex: 1; min-height: 0;
  padding: 10px 12px;
  display: flex; flex-direction: column;
  font-size: 12px;
  overflow: hidden;
}
.history-body .h-preset {
  font-size: 14px; font-weight: 650; color: var(--fg);
  margin-bottom: 4px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.history-body .h-meta {
  color: var(--muted); line-height: 1.5;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.history-body .h-foot {
  color: #666; font-size: 10px;
  margin-top: auto; padding-top: 4px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* ===== 提示词设置 modal ===== */
.modal-backdrop {
  position: fixed; inset: 0; background: var(--scrim);
  display: flex; align-items: center; justify-content: center;
  z-index: 1000;
}
.modal-panel {
  background: var(--surface-pop);
  border: 1px solid var(--border);
  border-radius: var(--radius-card); width: min(720px, 92vw); max-height: 88vh;
  display: flex; flex-direction: column; overflow: hidden;
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.55);
}
.modal-wide {
  width: 96vw;
  max-width: none;
  height: 94vh;
  max-height: 94vh;
}
.modal-wide .modal-body { padding: 18px 24px; }
.modal-wide .prompt-area { min-height: 320px; }
/* 本地保存等小设置：紧凑居中弹窗（按内容高度，不撑满屏），替代撑满屏的 modal-wide */
.modal-compact {
  width: min(440px, 92vw); overflow: visible;
  /* 底不再单开一套：直接继承 .modal-panel 的 --surface-pop 实底
     （原来这里写死 rgb(24,24,28) 还刷了层橙渐变，跟别的弹窗差半个色阶） */
}
.modal-compact .modal-body { padding: 18px 22px; }
.ls-reauth-row { display: flex; align-items: center; gap: 8px; margin-top: 9px; font-size: 12px; color: var(--warn, #e0a23c); }
/* 本地保存重设计：大开关一眼可关 + 「下载到 xxx」一行 + 命名示例一行 */
.ls-switch-row { display: flex; align-items: center; gap: 12px; padding: 12px 14px; background: var(--card); border: 1px solid var(--border); border-radius: var(--radius-ctl); }
.ls-switch-txt { flex: 1; min-width: 0; }
.ls-switch-title { font-size: 14px; font-weight: 650; color: var(--fg); }
.ls-switch-sub { font-size: 12px; color: var(--muted, #8b909b); margin-top: 2px; }
.ls-switch { flex: none; width: 44px; height: 25px; border-radius: 999px; border: none; background: var(--border); cursor: pointer; position: relative; padding: 0; transition: background .15s; }  /* 开关走胶囊档，原来 10px 是圆角矩形，跟里面的圆钮对不上 */
.ls-switch .ls-switch-knob { position: absolute; top: 2.5px; left: 2.5px; width: 20px; height: 20px; border-radius: 50%; background: #fff; transition: transform .15s; box-shadow: 0 1px 3px rgba(0,0,0,.35); }
.ls-switch.on { background: var(--accent, #f76b1c); }
.ls-switch.on .ls-switch-knob { transform: translateX(19px); }
/* 「存到 xxx」一行：点击=弹系统选文件夹框 */
.ls-loc-line { width: 100%; display: flex; align-items: center; gap: 8px; margin-top: 12px; padding: 11px 13px; background: var(--card); color: var(--fg); border: 1px solid var(--border); border-radius: var(--radius); cursor: pointer; font-family: inherit; font-size: 14px; text-align: left; transition: border-color .15s, box-shadow .15s; }
.ls-loc-line:hover:not(:disabled) { border-color: var(--accent, #f76b1c); box-shadow: 0 0 0 3px var(--accent-soft, rgba(247,107,28,0.12)); }
.ls-loc-line:disabled { cursor: default; }
.ls-loc-where { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ls-loc-change { flex: none; color: var(--accent, #f76b1c); font-size: 12px; font-weight: 400; }
.ls-alt { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 8px; }
.ls-alt-link { background: none; border: none; padding: 0; color: var(--muted, #8b909b); font-size: 12px; cursor: pointer; font-family: inherit; }
.ls-alt-link:hover { color: var(--fg); text-decoration: underline; }
.ls-name-line { margin-top: 12px; font-size: 12px; color: var(--muted, #8b909b); line-height: 1.7; }
.ls-name-line code { font-family: var(--mono, ui-monospace, SFMono-Regular, Menlo, monospace); font-size: 12px; color: var(--accent, #f76b1c); word-break: break-all; }
.ls-off-warn { margin-top: 12px; padding: 11px 13px; border: 1px solid var(--accent, #f76b1c); background: var(--accent-soft, rgba(247,107,28,0.10)); border-radius: var(--radius); }
.ls-off-warn-title { font-size: 14px; font-weight: 650; color: var(--accent, #f76b1c); }
.ls-off-warn-sub { font-size: 12px; color: var(--muted, #8b909b); margin-top: 3px; line-height: 1.6; }
.modal-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 14px 18px; border-bottom: 1px solid var(--border);
}
.modal-head h3 { font-size: 14px; margin: 0; letter-spacing: -0.01em; }

/* settings modal 顶部 tabs（提示词/用量/接口） */
.settings-tabs { display: flex; gap: 4px; margin-left: 24px; flex: 1; }
.settings-tab {
  font-size: 12px; padding: 6px 14px; border-radius: var(--radius);
  background: transparent; color: var(--muted); border: 1px solid transparent;
  cursor: pointer; font-family: inherit; transition-property: var(--t-props); transition-duration: .15s; transition-timing-function: ease;
}
.settings-tab:hover { color: var(--fg); background: var(--card); }
.settings-tab.on {
  background: var(--accent); color: var(--on-bg); font-weight: 650;
  border-color: var(--accent);
}

/* 用量统计 - 顶部 stat 卡片网格 */
.usage-summary { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; margin-bottom: 22px; }
.stat-card {
  background: var(--surface-sub); border: 1px solid var(--border); border-radius: var(--radius);
  padding: 14px 16px; text-align: left;
}
.stat-label { font-size: 12px; color: var(--muted); margin-bottom: 4px; }
.stat-val { font-size: 20px; font-weight: 650; letter-spacing: -0.01em; }

/* 通用 settings 表格 */
.settings-section-title { font-size: 14px; margin: 18px 0 8px; font-weight: 650; color: var(--fg); }
.settings-table { width: 100%; border-collapse: collapse; font-size: 12px; }
.settings-table th, .settings-table td {
  text-align: left; padding: 8px 10px;
  border-bottom: 1px solid var(--border);
}
.settings-table th { color: var(--muted); font-weight: 400; background: var(--card); }
.settings-table td.cell-label { color: var(--muted); width: 35%; }

/* 接口配置 - engine 卡片 */
.config-list { display: flex; flex-direction: column; gap: 10px; }
.config-card {
  background: var(--surface-sub); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 12px 14px;
}
.config-row { display: flex; align-items: center; justify-content: space-between; margin-bottom: 6px; }
.config-name { font-weight: 650; font-size: 14px; display: inline-flex; align-items: center; gap: 8px; }
.config-badge {
  padding: 2px 8px; border-radius: 4px; font-size: 10px; font-weight: 650;
  background: var(--accent-soft); color: var(--accent);
}
.config-status { font-size: 12px; font-weight: 650; }
.config-status.ok { color: #4ade80; }
.config-status.miss { color: var(--danger); }
.config-meta { font-size: 12px; color: var(--muted); display: flex; gap: 14px; margin-bottom: 4px; font-family: var(--mono, ui-monospace, SFMono-Regular, Menlo, monospace); }
.config-url { font-size: 12px; color: var(--muted); font-family: var(--mono, ui-monospace, SFMono-Regular, Menlo, monospace); word-break: break-all; }
.config-note { font-size: 12px; color: var(--accent); margin-top: 4px; }

.modal-foot-meta { font-size: 12px; color: var(--muted); }
/* ===== 浮层内控件底（2026-08-05 第四批）=====
   浮层比卡片亮一档（--surface-pop #1c1c22 vs --surface-card #16161a），
   控件底要跟着抬，否则 --surface-ctl #1d1d22 压在 #1c1c22 上只差一个色阶＝看不见框。
   在浮层容器上就地改写 --surface-ctl，里面所有引用它的控件自动跟着抬，不用一处处改。
   抬的幅度跟「卡片底→控件底」保持同一个关系（+7/+7/+8）。 */
.modal-panel,
.gen-modal,
.ext-panel,
.ct-panel,
.ps-bind-card,
.ps-menu,
.ps-rcpop,
.ps-rc-win,
.ps-qr-win,
.jm-prod-pop-card,
.fz-batch-side,
.dd-panel,
.at-pick,
.fz-chip-pop,
.fz-action-menu{
  --surface-ctl: var(--surface-ctl-pop);
}

/* ===== 浮层关闭键（2026-08-05 第四批收敛）=====
   排查发现同一个「关闭」动作有 6 种长相：18~30px 见方、圆角 0/6/10/50%、底色四套。
   统一成 28×28、圆角 8、平时无底、悬停出底。各自那边只留定位，别再写尺寸和底色。
   两点注意：
   ① HTML 里混用了 × (U+00D7) 和 ✕ (U+2715) 两种字符，后者天生大一圈，所以按字符分开给字号；
   ② .fz-batch-close 还兼作「新建批次」的 + 键，所以只统一盒子，不能用伪元素替内容。 */
.modal-x,
.gen-modal-close,
.fz-batch-close,
.ct-x,
.ps-rc-x,
.ps-qr-x{
  width: 28px; height: 28px; flex: none; padding: 0;
  display: inline-flex; align-items: center; justify-content: center;
  border: none; border-radius: var(--radius-ctl);
  background: transparent; color: var(--muted);
  line-height: 1; cursor: pointer; font-family: inherit;
  transition-property: var(--t-props); transition-duration: .12s; transition-timing-function: ease;
}
.modal-x, .gen-modal-close, .fz-batch-close { font-size: 20px; }   /* × U+00D7 */
.ct-x,
.ps-rc-x,
.ps-qr-x{ font-size: 14px; }   /* ✕ U+2715 */
.modal-x:hover,
.gen-modal-close:hover,
.fz-batch-close:hover,
.ct-x:hover,
.ps-rc-x:hover,
.ps-qr-x:hover{ background: var(--card-hover); color: var(--fg); }
.modal-body { padding: 16px 18px; overflow-y: auto; flex: 1; }
.modal-hint { font-size: 12px; color: var(--muted); line-height: 1.7; margin: 0 0 14px; }
.modal-loading, .modal-empty { padding: 40px 20px; text-align: center; color: var(--muted); font-size: 14px; }
.modal-foot {
  padding: 12px 18px; border-top: 1px solid var(--border);
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
}
.modal-foot-right { display: flex; align-items: center; gap: 12px; }
.modal-confirm { width: auto; height: var(--h-md); padding: 0 18px; font-size: 14px; }

/* 全局规则展示区（modal 顶部，可折叠、只读） */
.prompt-global {
  background: linear-gradient(135deg, rgba(247,107,28,0.04), rgba(247,107,28,0.02)),
              rgba(255,255,255,0.03);
  border: 1px solid var(--accent-ring);
  border-radius: var(--radius);
  padding: 12px 14px;
  margin-bottom: 18px;
}
.prompt-global summary {
  cursor: pointer; list-style: none;
  display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
  outline: none;
}
.prompt-global summary::-webkit-details-marker { display: none; }
.prompt-global summary::before {
  content: "▸"; color: var(--muted); font-size: 10px; transition: transform .15s;
}
.prompt-global[open] summary::before { transform: rotate(90deg); }
.prompt-global-body { margin-top: 12px; display: flex; flex-direction: column; gap: 10px; }
.prompt-global-label { font-size: 12px; color: var(--muted); margin-bottom: 4px; font-family: var(--mono, ui-monospace, SFMono-Regular, Menlo, monospace); }
.prompt-readonly {
  background: rgba(0,0,0,0.2);
  color: #c8c8d0;
  cursor: default;
  border-color: rgba(255,255,255,0.06);
}
.prompt-readonly:focus { box-shadow: none; border-color: rgba(255,255,255,0.06); }

/* === 提示词设置 modal 左右两栏布局 ===
   注意：用 .modal-body.settings-split 提升 specificity 到 (0,2,0)，
   平 .modal-wide .modal-body 的 specificity，靠后定义 win；
   不能用 !important，否则会盖住 Vue v-show 的 inline display:none，导致切 tab 时不隐藏。 */
.modal-body.settings-split {
  display: flex;
  padding: 0;
  gap: 0;
  overflow: hidden;
}

/* 左侧导航 */
.settings-sidebar {
  width: 240px; flex-shrink: 0;
  background: rgba(0, 0, 0, 0.18);
  border-right: 1px solid var(--border);
  padding: 18px 12px;
  overflow-y: auto;
  display: flex; flex-direction: column; gap: 18px;
}
.sidebar-section { display: flex; flex-direction: column; gap: 2px; }
.sidebar-label {
  font-size: 10px; color: var(--muted);
  text-transform: uppercase; letter-spacing: 0.6px; font-weight: 650;
  margin-bottom: 4px; padding: 0 10px;
}
.sidebar-loading { color: var(--muted); font-size: 12px; padding: 8px 10px; }
.sidebar-item {
  display: flex; align-items: center; gap: 6px;
  width: 100%; padding: 8px 10px;
  background: transparent; color: var(--muted);
  border: 1px solid transparent; border-radius: 6px;
  font-size: 14px; cursor: pointer; text-align: left;
  font-family: inherit;
  transition-property: var(--t-props); transition-duration: .12s; transition-timing-function: ease;
}
.sidebar-item:hover { background: var(--card); color: var(--fg); }
.sidebar-item.on {
  background: var(--accent-soft); color: var(--accent);
  border-color: var(--accent-ring);
  font-weight: 650;
}
.sidebar-item-name { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sidebar-dot {
  width: 6px; height: 6px; border-radius: 50%;
  background: #4ade80; flex-shrink: 0;
}
.sidebar-flag {
  font-size: 10px; padding: 1px 6px; border-radius: 3px;
  background: rgba(247,107,28,0.18); color: var(--accent);
  font-weight: 650; flex-shrink: 0;
}
.sidebar-item-icon { font-size: 14px; flex-shrink: 0; }
.sidebar-item-global { color: var(--accent); }
.sidebar-item-global:hover { background: rgba(247,107,28,0.06); color: var(--accent); }
.sidebar-item-global.on {
  background: var(--accent); color: var(--on-bg);
  border-color: var(--accent);
}

/* 全局规则（折叠到 sidebar 底部） */
.sidebar-global {
  background: rgba(247,107,28,0.04);
  border: 1px solid var(--accent-ring);
  border-radius: 6px;
  margin-top: auto;
}
.sidebar-global summary {
  list-style: none; cursor: pointer;
  padding: 8px 10px;
  display: flex; align-items: center; justify-content: space-between;
  font-size: 12px; color: var(--accent); font-weight: 650;
  outline: none;
}
.sidebar-global summary::-webkit-details-marker { display: none; }
.sidebar-global summary::after {
  content: "▸"; color: var(--muted); font-size: 10px; transition: transform .15s;
}
.sidebar-global[open] summary::after { transform: rotate(90deg); }
.sidebar-global-hint { color: var(--muted); font-size: 10px; font-weight: 400; margin-right: 6px; }
.sidebar-global-body {
  padding: 10px; border-top: 1px solid var(--accent-ring);
}
.sidebar-global-body .prompt-area { font-size: 12px; padding: 8px; }
.sidebar-global-note { font-size: 10px; color: var(--muted); margin: 8px 0 0; line-height: 1.5; }

/* 右侧内容区 */
.settings-content {
  flex: 1; padding: 22px 26px;
  overflow-y: auto;
  display: flex; flex-direction: column;
  min-width: 0;
}
.content-pane { display: flex; flex-direction: column; height: 100%; min-height: 360px; }
.content-head { margin-bottom: 12px; padding-bottom: 12px; border-bottom: 1px solid var(--border); }
.content-title { font-size: 20px; margin: 0 0 6px; font-weight: 650; letter-spacing: -0.01em; }
.content-meta { font-size: 12px; color: var(--muted); display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.meta-pill {
  padding: 2px 8px; border-radius: 4px; font-size: 12px;
  background: rgba(255, 255, 255, 0.06); color: var(--muted);
}
.meta-pill.active { background: rgba(34, 197, 94, 0.18); color: #4ade80; font-weight: 650; }
.meta-pill.warn { background: rgba(247,107,28,0.18); color: var(--accent); font-weight: 650; }
.content-textarea {
  flex: 1; min-height: 360px;
  font-size: 14px; line-height: 1.65;
}

/* 全局规则满幅展示（替代之前的小框） */
.content-global-grid {
  flex: 1;
  display: grid;
  grid-template-rows: 1fr 1fr;
  gap: 14px;
  min-height: 0;
}
.content-global-block {
  display: flex; flex-direction: column;
  min-height: 0;
}
.content-textarea-readonly {
  flex: 1; min-height: 120px;
  font-size: 12px; line-height: 1.65;
  margin-top: 4px;
}

/* 提示词 modal 的场景目录 chip（旧版，保留兼容用，新版用 sidebar-item） */
.prompt-tabs {
  display: flex; flex-wrap: wrap; gap: 6px;
  margin-bottom: 14px; padding-bottom: 12px;
  border-bottom: 1px solid var(--border);
}
.prompt-tab {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 12px; padding: 7px 12px; border-radius: var(--radius);
  background: var(--card); color: var(--muted);
  border: 1px solid var(--border); cursor: pointer;
  font-family: inherit;
  transition-property: var(--t-props); transition-duration: .15s; transition-timing-function: ease;
}
.prompt-tab:hover { color: var(--fg); border-color: var(--border-strong); }
.prompt-tab.on {
  background: var(--accent); color: var(--on-bg);
  border-color: var(--accent); font-weight: 650;
  box-shadow: 0 2px 8px rgba(247,107,28,0.25);
}
.prompt-tab-dot {
  width: 6px; height: 6px; border-radius: 50%;
  background: #4ade80;
  display: inline-block;
}
.prompt-tab.on .prompt-tab-dot { background: rgba(0,0,0,0.5); }
.prompt-tab-flag {
  padding: 0 6px; border-radius: 3px; font-size: 10px; font-weight: 650;
  background: rgba(247,107,28,0.18); color: var(--accent);
}
.prompt-tab.on .prompt-tab-flag { background: rgba(0,0,0,0.18); color: var(--on-bg); }

.prompt-section { margin-bottom: 16px; }
.prompt-section:last-child { margin-bottom: 0; }
.prompt-section-head {
  display: flex; align-items: center; gap: 10px;
  margin-bottom: 6px; font-size: 12px;
}
.prompt-section-title { color: var(--accent); font-weight: 650; }
.prompt-section-meta { color: var(--muted); }
.prompt-section-tag {
  padding: 2px 8px; border-radius: 4px; font-size: 12px;
  background: rgba(255,255,255,0.06); color: var(--muted);
}
.prompt-section-tag.active {
  background: rgba(34,197,94,0.18); color: #4ade80;
}
.prompt-section-flag {
  margin-left: auto; padding: 2px 8px; border-radius: 4px;
  background: var(--accent-soft); color: var(--accent); font-size: 12px;
}
.prompt-area {
  width: 100%;
  font-family: "SF Mono", "PingFang SC", Menlo, monospace;
  font-size: 12px; line-height: 1.6; padding: 10px;
  background: var(--card); color: var(--fg);
  border: 1px solid var(--border); border-radius: var(--radius);
  resize: vertical; min-height: 200px;
  transition-property: var(--t-props); transition-duration: .15s; transition-timing-function: ease;
}
.prompt-area:focus {
  outline: none;
  border-color: var(--accent-ring);
  box-shadow: 0 0 0 3px var(--accent-soft);
}

/* ===== 模特描述 tab ===== */
.settings-tab-hint {
  margin: 0 0 16px; padding: 10px 12px;
  background: var(--card); border: 1px solid var(--border); border-radius: var(--radius);
  font-size: 12px; color: var(--fg-muted); line-height: 1.5;
}
.body-desc-row { margin-bottom: 18px; }
.body-desc-head {
  display: flex; align-items: center; gap: 10px; margin-bottom: 6px;
}
.body-desc-label { font-size: 14px; font-weight: 400; color: var(--fg); }
.body-desc-row .prompt-area { min-height: 90px; }

/* ===== 图片 lightbox ===== */
.lightbox-backdrop {
  background: rgba(0,0,0,0.94);
  flex-direction: column;
  padding: 24px;
}
.lightbox-close {   /* 尺寸走浮层关闭键公共件（原来单开一档 32px）；大图是全黑底，字色提亮 */
  position: absolute; top: 12px; right: 18px;
  color: var(--fg); z-index: 1002;
}
.lightbox-img {
  max-width: 92vw; max-height: 82vh;
  object-fit: contain; border-radius: var(--radius);
  box-shadow: 0 12px 48px rgba(0,0,0,0.6);
  background: #000;
}
.lightbox-bar {
  margin-bottom: 18px;
  display: flex; align-items: center; gap: 16px;
}
/* lightbox / 编辑面板里的按钮：横排不换行；.btn-primary 默认 width:100% 在这里不适用 */
.lightbox-bar .btn-primary, .lightbox-bar .btn-secondary, .lightbox-bar .btn-text,
.edit-actions .btn-primary, .edit-actions .btn-secondary, .edit-actions .btn-text {
  width: auto;
  white-space: nowrap;
  flex: 0 0 auto;
}
.lightbox-download {
  padding: 9px 22px; font-size: 14px;
  text-decoration: none;
}
.lightbox-tip { font-size: 12px; color: var(--muted); }

/* 提示词改图：lightbox 内输入条独占一行 */
/* 2026-08-11 ④：面板里多了一条报价/回落说明行 → 外层改纵排，原来的横排挪进 .lightbox-iter-line */
.lightbox-iteration-row {
  display: flex; flex-direction: column; gap: 6px;
  margin-bottom: 18px;
  max-width: 720px; width: 100%;
}
.lightbox-iter-line { display: flex; align-items: stretch; gap: 10px; }
.lightbox-iter-meta { color: rgba(255,255,255,.78); font-size: 12px; line-height: 1.5; }
.lightbox-iter-meta em { color: #f9a76b; font-style: normal; }
.lightbox-iteration-input {
  flex: 1; min-width: 0;
  padding: 8px 10px;
  border: 1px solid rgba(255,255,255,0.18);
  border-radius: 8px;
  background: var(--surface-ctl);
  color: #fff;
  font: inherit;
  resize: vertical;
}
.lightbox-iteration-input:focus {
  outline: none;
  border-color: #f76b1c;
  background: rgba(255,255,255,0.10);
}
.lightbox-iteration-row .btn-primary,
.lightbox-iteration-row .btn-secondary {
  width: auto; white-space: nowrap; flex: 0 0 auto;
  padding: 0 18px;
}
.result-card img, .history-card img { cursor: zoom-in; }
/* 2026-08-11 ④：结果页可点开放大的图（四个板块共用一个类，别一线一套） */
.lightbox-openable { cursor: zoom-in; }
.fz-breview-copy-hover { cursor: zoom-in; }   /* 悬浮层盖满整张图，点层本身 = 点图放大 */
/* 画廊翻页箭头 + 计数（结果页点进来才渲染） */
.lightbox-nav {
  position: fixed; top: 50%; transform: translateY(-50%); z-index: 6;
  width: 46px; height: 76px; border: 0; border-radius: 10px;
  background: rgba(18,18,22,.55); color: #fff; font-size: 34px; line-height: 1;
  cursor: pointer; display: flex; align-items: center; justify-content: center;
}
.lightbox-nav:hover { background: rgba(18,18,22,.85); }
.lightbox-nav.prev { left: 14px; }
.lightbox-nav.next { right: 14px; }
.lightbox-count {
  position: fixed; bottom: 16px; left: 50%; transform: translateX(-50%); z-index: 6;
  padding: 3px 10px; border-radius: 999px; background: rgba(18,18,22,.65);
  color: rgba(255,255,255,.85); font-size: 12px;
}
/* lightbox 里的「已选这张」：选中态点亮成橙（与勾选圈同一语义色） */
.lightbox-select.on { border-color: #f76b1c; color: #f9a76b; }

/* lightbox 内的次按钮（"编辑加文案"） */
.btn-secondary {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 9px 18px; font-size: 14px; font-weight: 400;
  background: rgba(255,255,255,0.08); color: var(--fg);
  border: 1px solid rgba(255,255,255,0.2); border-radius: var(--radius);
  cursor: pointer; transition: background .15s;
}
.btn-secondary:hover { background: rgba(255,255,255,0.16); }
.btn-secondary svg.lucide { width: 1.05em; height: 1.05em; }

/* ===== lightbox 编辑模式 ===== */
.edit-stage {
  width: 96vw; max-width: 1400px; height: 90vh;
  display: flex; flex-direction: column;
  background: var(--panel); border: 1px solid var(--border); border-radius: var(--radius);
  overflow: hidden;
}
.edit-toolbar {
  flex: 0 0 auto;
  display: flex; align-items: center; gap: 16px;
  padding: 12px 18px;
  background: var(--panel-strong, #1c1c1c);
  border-bottom: 1px solid var(--border);
}
.edit-back { display: inline-flex; align-items: center; gap: 4px; }
.edit-title { font-size: 14px; font-weight: 400; }
.edit-actions { margin-left: auto; display: flex; gap: 12px; align-items: center; }
.edit-body { flex: 1; display: flex; min-height: 0; }
.edit-panel {
  flex: 0 0 320px; padding: 18px;
  background: var(--surface-sub);
  border-right: 1px solid var(--border);
  overflow-y: auto;
  display: flex; flex-direction: column;
}
.edit-tpl-name {
  font-size: 14px; color: var(--muted);
  margin-bottom: 14px; padding-bottom: 10px;
  border-bottom: 1px solid var(--border);
}
/* 模板选择条 */
.edit-tpl-picker {
  display: flex; flex-direction: column; gap: 8px;
  margin-bottom: 14px; padding-bottom: 12px;
  border-bottom: 1px solid var(--border);
}
.edit-tpl-label { font-size: 12px; color: var(--muted); }
/* 字体样式：可点卡片 2 列 */
.edit-tpl-cards { display: grid; grid-template-columns: 1fr 1fr; gap: 7px; }
.edit-tpl-card {
  display: flex; flex-direction: column; gap: 2px; text-align: left;
  padding: 8px 9px; background: var(--surface-sub); color: #c2c7d0;
  border: 1px solid var(--border); border-radius: 10px; cursor: pointer;
  transition-property: var(--t-props); transition-duration: .15s; font-family: inherit;
}
.edit-tpl-card:hover { border-color: var(--border-strong); color: #fff; }
.edit-tpl-card.on { background: linear-gradient(135deg, #ff8a3d, #f76b1c); border-color: transparent; color: #fff; }
.tpl-card-name { font-size: 12px; font-weight: 650; }
.tpl-card-desc { font-size: 10px; opacity: .72; line-height: 1.3; }
.edit-tpl-card.on .tpl-card-desc { opacity: .92; }
.edit-tpl-actions { display: flex; gap: 6px; }
/* 字体颜色：一排色块 + hex */
.edit-color { margin: 0 0 14px; }
.edit-color-row { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
.edit-sw { width: 24px; height: 24px; border-radius: 6px; border: 2px solid var(--border); cursor: pointer; padding: 0; }
.edit-sw:hover { border-color: var(--border-strong); }
.edit-sw.on { border-color: #f76b1c; }
.edit-sw-hex { display: flex; align-items: center; gap: 3px; font-size: 12px; color: var(--muted); background: var(--card); border: 1px solid var(--border); border-radius: 6px; padding: 3px 7px; }
.edit-sw-hex input { width: 54px; background: transparent; border: 0; outline: none; color: var(--fg); font-size: 12px; font-family: inherit; }
.edit-tpl-select {
  flex: 1; padding: 6px 24px 6px 8px; font-size: 12px;
  background: var(--card); color: var(--fg);
  border: 1px solid var(--border); border-radius: 6px;
  font-family: inherit;
}
.btn-tpl-action {
  width: 28px; height: 28px; border-radius: 6px;
  background: var(--card); color: var(--fg);
  border: 1px solid var(--border); cursor: pointer;
  font-size: 14px; line-height: 1;
}
.btn-tpl-action:hover { background: var(--card-hover); border-color: var(--border-strong); }
.btn-tpl-delete:hover { background: rgba(239, 68, 68, 0.18); border-color: rgba(239, 68, 68, 0.5); color: var(--danger, #ef4444); }
/* B 模式：临时调整状态条 */
.edit-dirty-row {
  display: flex; align-items: center; gap: 8px;
  margin-bottom: 14px; padding: 8px 10px;
  background: var(--card); border: 1px solid var(--border); border-radius: 6px;
  font-size: 12px; color: var(--muted);
}
.edit-dirty-row.dirty {
  background: rgba(247,107,28,0.10);
  border-color: rgba(247,107,28,0.4);
  color: var(--fg);
}
.edit-dirty-state { flex: 1; }
.edit-dirty-actions { display: flex; gap: 6px; }
.btn-save-tpl {
  padding: 4px 10px; font-size: 12px; font-weight: 650;
  background: var(--accent); color: var(--on-bg);
  border: none; border-radius: 6px; cursor: pointer; font-family: inherit;
}
.btn-save-tpl:hover { filter: brightness(1.05); }
.btn-discard {
  padding: 4px 10px; font-size: 12px;
  background: transparent; color: var(--muted);
  border: 1px solid var(--border); border-radius: 6px; cursor: pointer; font-family: inherit;
}
.btn-discard:hover { color: var(--fg); border-color: var(--border-strong); }
/* 尺寸切换 tab */
.edit-aspect-tabs {
  display: flex; gap: 4px;
  background: var(--card); padding: 3px;
  border: 1px solid var(--border); border-radius: 6px;
  margin-bottom: 14px;
}
.edit-aspect-tab {
  flex: 1; padding: 6px 8px; font-size: 12px;
  background: transparent; border: none; border-radius: 6px;
  color: var(--muted); cursor: pointer; font-family: inherit;
  transition-property: var(--t-props); transition-duration: .15s; transition-timing-function: ease;
}
.edit-aspect-tab:hover { color: var(--fg); }
.edit-aspect-tab.on {
  background: var(--accent); color: var(--on-bg); font-weight: 650;
}
.edit-aspect-hint { font-size: 12px; color: var(--muted); margin: 0 0 14px; line-height: 1.5; }
.btn-apply-other {
  width: 100%; padding: 7px 10px; font-size: 12px;
  background: var(--card); color: var(--fg);
  border: 1px solid var(--border); border-radius: 6px;
  cursor: pointer; font-family: inherit;
  margin-bottom: 14px;
  transition-property: var(--t-props); transition-duration: .15s; transition-timing-function: ease;
}
.btn-apply-other:hover { background: var(--card-hover); border-color: var(--border-strong); }
.edit-field { margin-bottom: 14px; }
.edit-field label { display: block; font-size: 12px; color: var(--muted); margin-bottom: 6px; }
.edit-field input[type=text] {
  width: 100%; padding: 9px 11px;
  background: var(--surface-ctl); border: 1px solid var(--border); border-radius: var(--radius-ctl);
  color: var(--fg); font-size: 14px;
}
.edit-field textarea {
  width: 100%; padding: 9px 11px;
  background: var(--surface-ctl); border: 1px solid var(--border); border-radius: var(--radius-ctl);
  color: var(--fg); font-size: 14px; font-family: inherit; line-height: 1.7;
  resize: vertical; min-height: 92px;
}
.edit-size-row {
  display: flex; align-items: center; gap: 8px;
  margin-top: 10px; font-size: 12px; color: var(--muted);
}
.edit-size-label { min-width: 76px; }
.edit-size-btn {
  width: 28px; height: 28px; border-radius: 6px;
  background: #2a2a2a; color: var(--fg); border: 1px solid var(--border);
  cursor: pointer; font-size: 14px; font-weight: 650; line-height: 1;
}
.edit-size-btn:hover { background: #333; border-color: #555; }
.edit-size-val { min-width: 50px; text-align: center; font-variant-numeric: tabular-nums; color: var(--fg); }
.edit-hint { font-size: 12px; color: var(--muted); margin-top: 16px; line-height: 1.6; }
.edit-error { font-size: 12px; color: var(--danger, #ef4444); margin-top: 12px; }
.edit-canvas-wrap {
  flex: 1; display: flex; align-items: center; justify-content: center;
  padding: 20px; background: #0a0a0a; min-width: 0; min-height: 0;
}
/* 画布区域：多图时 inline style 会注入 aspect-ratio + height:100%（按第一张图撑开），
   箭头钉在它的左右边，切图不动；单图时无约束，stage 自适应 canvas 尺寸 */
.edit-canvas-stage {
  position: relative;
  max-width: 100%; max-height: 100%;
  display: flex; align-items: center; justify-content: center;
}
.edit-canvas {
  display: block;
  max-width: 100%; max-height: 100%;
  border: 1px solid var(--border); border-radius: 6px;
  background: #222; user-select: none;
}
.edit-nav-arrow {
  position: absolute; top: 50%; transform: translateY(-50%);
  width: 52px; height: 52px;
  display: flex; align-items: center; justify-content: center;
  border: none; border-radius: 50%;
  background: rgba(255, 255, 255, 0.92); color: #111;
  cursor: pointer; z-index: 5;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.5);
  transition: background .15s, transform .15s;
}
.edit-nav-arrow:hover {
  background: #fff;
  transform: translateY(-50%) scale(1.08);
}
.edit-nav-arrow svg.lucide {
  width: 28px; height: 28px; stroke-width: 2.6;
}
.edit-nav-prev { left: 36px; }
.edit-nav-next { right: 36px; }

/* ===== 历史卡片：编辑型 task 徽章 ===== */
.history-card { position: relative; }
.history-card.is-edit { border-color: #C92C2C; }
.h-edit-badge {
  position: absolute; top: 8px; left: 8px;
  display: inline-flex; align-items: center; gap: 4px;
  padding: 3px 8px; font-size: 12px; font-weight: 400;
  background: rgba(201, 44, 44, 0.92); color: #fff;
  border-radius: 10px;
  pointer-events: none;
}
.h-edit-badge svg.lucide { width: 12px; height: 12px; }

/* ===== 卡片右上角：收藏星标；左上角：拓展尺寸按钮 ===== */
.h-star, .h-expand-btn {
  position: absolute; top: 8px; z-index: 3;
  width: 30px; height: 30px;
  display: flex; align-items: center; justify-content: center;
  border: none; border-radius: 50%;
  background: rgba(0, 0, 0, 0.45); color: rgba(255, 255, 255, 0.7);
  cursor: pointer; font-size: 20px; line-height: 1;
  transition: background .15s, color .15s, transform .15s;
}
.h-star { right: 8px; }
.h-expand-btn { left: 8px; font-size: 14px; }
.h-star:hover, .h-expand-btn:hover { background: rgba(0, 0, 0, 0.75); color: #fff; }
.h-star.on { color: #f76b1c; background: rgba(0, 0, 0, 0.55); }
.h-star.on:hover { transform: scale(1.1); }

/* 拓展 picker：在卡片上覆盖一层选 aspect 的弹层 */
.expand-picker-overlay {
  position: absolute; inset: 0; z-index: 5;
  background: rgba(0, 0, 0, 0.75);
  display: flex; align-items: center; justify-content: center;
  padding: 12px;
}
.expand-picker-overlay .expand-picker {
  display: flex; flex-wrap: wrap; gap: 6px; justify-content: center;
}

/* ===== 响应式:窄屏堆叠回单列 ===== */
@media (max-width: 860px) {
  .topbar { flex-direction: column; align-items: flex-start; gap: 12px; }
  .workspace { flex-direction: column; }
  .panel { width: 100%; }
  .results { grid-template-columns: 1fr; }
  .history-grid { grid-template-columns: repeat(2, 1fr); }
}

/* ===========================================================================
 * 用量与账单页（usage view）
 * 设计跟 frontend/usage-mockup.html 一致；mockup 文件保留作设计参考
 * =========================================================================== */

.usage-view { padding-top: 4px; }

/* —— 顶部 KPI 4 张卡 —— */
.kpi-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; margin-bottom: 14px; }
.kpi-card {
  background: var(--surface-sub);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 16px 18px 14px;
  position: relative;
  transition-property: var(--t-props); transition-duration: .15s; transition-timing-function: ease;
}
.kpi-card:hover { border-color: var(--border-strong); transform: translateY(-1px); }
.kpi-card.kpi-warn { border-color: rgba(247,107,28,0.45); }
.kpi-label { font-size: 12px; color: var(--muted); display: flex; align-items: center; gap: 6px; margin-bottom: 6px; }
.kpi-val { font-size: 28px; font-weight: 650; letter-spacing: -0.01em; line-height: 1.1; font-variant-numeric: tabular-nums; }
.kpi-val-unit { font-size: 14px; color: var(--muted); font-weight: 400; margin-left: 3px; }
.kpi-delta { font-size: 12px; margin-top: 6px; }
.kpi-delta.up { color: #f87171; }
.kpi-delta.down { color: #4ade80; }
.kpi-spark { position: absolute; right: 12px; bottom: 10px; opacity: .5; }

/* —— 对账状态条 —— */
.recon-bar {
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  padding: 12px 16px; margin-bottom: 18px;
  background: rgba(255,255,255,0.03);
  border: 1px solid var(--border); border-radius: var(--radius);
  font-size: 12px;
}
.recon-bar .recon-title { color: var(--muted); flex-shrink: 0; }
.recon-chip {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 10px; border-radius: 999px;
  background: rgba(34,197,94,0.12); color: #4ade80;
  font-weight: 400;
}
.recon-chip.pending { background: rgba(247,107,28,0.15); color: var(--accent); }
.recon-chip.diff-bad { background: rgba(239,68,68,0.15); color: #f87171; }
.recon-chip-dot { width: 5px; height: 5px; border-radius: 50%; background: currentColor; }
.recon-bar .recon-action { margin-left: auto; }

/* —— 主体两栏：图表/表格 + 预算 —— */
.usage-grid { display: grid; grid-template-columns: 1fr 320px; gap: 18px; align-items: flex-start; }

.usage-card {
  background: var(--surface-sub);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 18px 20px;
  margin-bottom: 16px;
}
.usage-card-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 14px; gap: 10px; flex-wrap: wrap; }
.usage-card-title { font-size: 14px; font-weight: 650; letter-spacing: -0.01em; }
.usage-card-sub { font-size: 12px; color: var(--muted); margin-top: 2px; }

/* —— 工具栏（维度/指标/时间切换） —— */
.toolbar { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; font-size: 12px; }
.toolbar-group { display: inline-flex; align-items: center; gap: 6px; }
.toolbar-group-label { color: var(--muted); }
.pill-group {
  display: inline-flex; background: var(--card);
  border: 1px solid var(--border); border-radius: 6px; padding: 2px;
}
.pill {
  height: var(--h-sm); display: inline-flex; align-items: center;
  padding: 0 12px; font-size: 12px; border: none; background: transparent;
  color: var(--muted); cursor: pointer; border-radius: var(--radius-ctl); font-family: inherit;
  transition-property: var(--t-props); transition-duration: .12s; transition-timing-function: ease;
}
.pill:hover { color: var(--fg); }
.pill.on { background: var(--accent); color: var(--on-bg); font-weight: 650; }
/* 历史页两组筛选（内容类型 / 时间）的分界：原来只有一条 .16 透明度的短线，等于没有 */
.pill-group-sep { width: 1px; height: 20px; background: var(--border-strong); margin: 0 14px 0 10px; align-self: center; flex: none; }
.pill-group-lbl { font-size: 12px; color: var(--muted); opacity: .7; margin-right: 4px; align-self: center; flex: none; }
/* 时间组降一档：描边橙而非实心橙——主筛选（内容类型）才配得上实心 */
.pill--day.on { background: var(--accent-soft); color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent-ring); }

/* —— 趋势图（inline SVG） —— */
.chart-wrap { position: relative; height: 260px; margin-top: 8px; }
.chart-legend { display: flex; gap: 14px; font-size: 12px; color: var(--muted); margin-bottom: 6px; flex-wrap: wrap; }
.legend-item { display: inline-flex; align-items: center; gap: 5px; }
.legend-swatch { width: 9px; height: 9px; border-radius: 2px; }
.chart-svg { width: 100%; height: 100%; display: block; }
.chart-axis-label { fill: var(--muted); font-size: 10px; font-family: inherit; }
.chart-bar { transition: opacity .15s; cursor: pointer; }
.chart-bar:hover { opacity: 0.75; }
.chart-empty { display: flex; align-items: center; justify-content: center; height: 100%; color: var(--muted); font-size: 14px; }

/* —— 明细表 —— */
.detail-scroll { max-height: 360px; overflow-y: auto; border: 1px solid var(--border); border-radius: 6px; }
.detail-table { width: 100%; border-collapse: collapse; font-size: 12px; }
.detail-table thead th {
  text-align: left; padding: 10px 8px; font-weight: 400;
  color: var(--muted); background: rgba(0,0,0,0.18);
  border-bottom: 1px solid var(--border);
  position: sticky; top: 0; z-index: 1;
}
.detail-table tbody td { padding: 9px 8px; border-bottom: 1px solid rgba(255,255,255,0.04); }
.detail-table tbody tr:hover { background: rgba(255,255,255,0.025); }
.detail-table tbody tr.row-diff { background: rgba(239,68,68,0.05); }
.num { text-align: right; font-variant-numeric: tabular-nums; }
.mono { font-family: var(--mono, ui-monospace, SFMono-Regular, Menlo, monospace); font-size: 12px; }
.recon-status { display: inline-flex; align-items: center; gap: 4px; padding: 2px 7px; border-radius: 999px; font-size: 10px; font-weight: 650; }
.recon-status.estimated { background: rgba(148,163,184,0.18); color: #cbd5e1; }
.recon-status.matched { background: rgba(34,197,94,0.16); color: #4ade80; }
.recon-status.diff { background: rgba(239,68,68,0.16); color: #f87171; }
.diff-text.up { color: #f87171; }
.diff-text.down { color: #4ade80; }
.req-id { color: var(--muted); cursor: copy; }
.req-id:hover { color: var(--accent); }

/* —— provider badge —— */
.prov-badge { display: inline-flex; align-items: center; gap: 4px; font-size: 12px; padding: 2px 8px; border-radius: 4px; font-weight: 650; }
.prov-badge::before { content: ""; width: 6px; height: 6px; border-radius: 50%; }
.prov-seedream { background: rgba(99,102,241,0.18); color: #a5b4fc; }
.prov-seedream::before { background: #6366f1; }
.prov-seedream-4 { background: rgba(168,85,247,0.18); color: #d8b4fe; }
.prov-seedream-4::before { background: #a855f7; }
.prov-nb2 { background: rgba(34,197,94,0.16); color: #86efac; }
.prov-nb2::before { background: #22c55e; }
.prov-dashscope { background: rgba(148,163,184,0.18); color: #cbd5e1; }
.prov-dashscope::before { background: #94a3b8; }
.prov-other { background: rgba(247,107,28,0.15); color: var(--accent); }
.prov-other::before { background: var(--accent); }

/* —— 筛选 / 工具按钮 —— */
.filter-row { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; margin-bottom: 10px; }
.filter-input {
  padding: 6px 10px; font-size: 12px; min-width: 200px;
  background: var(--card); color: var(--fg);
  border: 1px solid var(--border); border-radius: var(--radius-ctl);
  font-family: inherit;
}
.filter-select {
  padding: 5px 26px 5px 10px; font-size: 12px;
  background: var(--card); color: var(--fg);
  border: 1px solid var(--border); border-radius: 6px;
  font-family: inherit; appearance: none;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%238a8a92' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>");
  background-repeat: no-repeat;
  background-position: right 8px center;
}
.btn-mini {
  font-size: 12px; padding: 5px 10px; border-radius: 6px;
  background: var(--card); color: var(--fg);
  border: 1px solid var(--border); cursor: pointer;
  font-family: inherit;
  display: inline-flex; align-items: center; gap: 4px;
  text-decoration: none;
}
.btn-mini:hover { border-color: var(--border-strong); background: var(--card-hover); }
.btn-mini.primary { background: var(--accent); color: var(--on-bg); border-color: var(--accent); font-weight: 650; }
.btn-mini:disabled { opacity: .35; cursor: not-allowed; }

.footer-pager { display: flex; justify-content: space-between; align-items: center; padding-top: 10px; font-size: 12px; color: var(--muted); }
.usage-loading { padding: 40px 20px; text-align: center; color: var(--muted); font-size: 14px; }

@media (max-width: 1100px) {
  .usage-grid { grid-template-columns: 1fr; }
  .kpi-grid { grid-template-columns: repeat(2, 1fr); }
}

/* ===== 图组（spec 2026-05-16-size-expansion）===== */
.image-set-group {
  grid-column: 1 / -1;            /* 占满 results 网格的一整行 */
  border: 1px solid #d99a6b;
  border-radius: 8px;
  padding: 12px;
  margin: 8px 0;
  background: #fbf9f7;
}
.image-set-header {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 10px;
}
.image-set-header .image-set-label { margin-right: auto; display: inline-flex; align-items: center; gap: 4px; }
.image-set-label svg.lucide { width: 14px; height: 14px; }
/* 加文案图组：红色调跟单卡 is-edit 一致 */
.history-set-group.is-edit-set .image-set-label { color: #C92C2C; }
.history-set-group.is-edit-set { box-shadow: inset 3px 0 0 #C92C2C; padding-left: 8px; }
.image-set-label {
  font-size: 12px;
  color: #7A5A3F;
  font-weight: 650;
  letter-spacing: 0.05em;
}
.btn-set-download {
  font-size: 12px;
  padding: 4px 10px;
  background: #d99a6b;
  color: white;
  border: none;
  border-radius: 6px;
  cursor: pointer;
}
.btn-set-download:hover { opacity: 0.85; }
.btn-set-edit {
  font-size: 12px;
  padding: 4px 10px;
  background: #C92C2C;
  color: #fff;
  border: none;
  border-radius: 6px;
  cursor: pointer;
}
.btn-set-edit:hover { opacity: 0.85; }
.btn-set-push {
  font-size: 12px;
  padding: 4px 10px;
  background: #f76b1c;
  color: #fff;
  border: none;
  border-radius: 6px;
  cursor: pointer;
}
.btn-set-push:hover { opacity: 0.85; }
.btn-set-push.is-pushed {
  background: #27ae60;  /* 绿色：已完成 */
  color: #fff;
}
.btn-set-push.is-pushed:hover { background: #2ecc71; }
/* 图组级星标：跟卡片级 .h-star 视觉一致，但 inline 排在 header 里 */
.set-star {
  width: 28px; height: 28px;
  display: inline-flex; align-items: center; justify-content: center;
  border: none; border-radius: 50%;
  background: rgba(0, 0, 0, 0.35); color: rgba(255, 255, 255, 0.7);
  cursor: pointer; font-size: 20px; line-height: 1;
  transition: background .15s, color .15s, transform .15s;
}
.set-star:hover { background: rgba(0, 0, 0, 0.6); color: #fff; }
.set-star.on { color: #f76b1c; background: rgba(247,107,28,0.15); }
.set-star.on:hover { transform: scale(1.1); }
.image-set-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 12px;
}

/* 历史区图组：横排紧凑 */
.history-set-group {
  grid-column: 1 / -1;
  border: 1px solid #d99a6b;
  border-radius: 8px;
  padding: 10px;
  margin: 6px 0;
  background: #fbf9f7;
}
.history-set-cards {
  display: grid;
  grid-template-columns: repeat(4, 1fr);  /* 跟单张视图同 4 列 */
  gap: 14px;
}

/* 「拓展尺寸」按钮 */
.btn-expand {
  display: inline-block;
  font-size: 12px;
  padding: 4px 12px;
  background: #E8D5BC;
  color: #5C3F2A;
  border: 1px solid #d99a6b;
  border-radius: 6px;
  cursor: pointer;
  margin-top: 8px;
}
.btn-expand:hover:not(:disabled) { background: #DDC4A6; }
.btn-expand:disabled { opacity: 0.4; cursor: not-allowed; }

/* ===== 生成进度弹窗（首页合并后，生成走弹窗；衣架 + 计数器 + 进度条，沿用 empty.svg 调性） ===== */
.gen-modal-backdrop {
  position: fixed; inset: 0; z-index: 800;
  background: var(--scrim-deep);
  backdrop-filter: var(--scrim-blur);
  display: flex; align-items: center; justify-content: center;
  padding: 24px;
}
.gen-modal {
  position: relative;
  background: var(--surface-pop);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-card);
  box-shadow: 0 24px 80px rgba(0,0,0,0.6);
  width: 100%; max-width: 460px;
  overflow: hidden;
}
/* 宽版：左右分栏 — 左侧栏=信息+按钮，右主区=图片占满 */
.gen-modal-wide {
  max-width: min(1400px, 95vw);
  max-height: 92vh;
  display: flex; flex-direction: row;
}

/* 左侧栏：固定宽，顶部信息 + 底部按钮 */
.gen-modal-side {
  width: 260px; flex-shrink: 0;
  background: rgba(0, 0, 0, 0.25);
  border-right: 1px solid var(--border);
  display: flex; flex-direction: column;
  padding: 24px 18px;
  /* 拓展尺寸 picker 浮在按钮右侧（漂出 side 到图片区）必须有 z-index 把整个 side 抬到 main 上面,
     否则 .gen-modal-main 里的图片卡会因为文档顺序在后而盖住 picker。
     overflow 用 visible 不裁切右浮的 picker (内容溢出由弹窗整体滚条管) */
  overflow: visible;
  position: relative;
  z-index: 5;
}
.gen-side-top { text-align: center; }
.gen-hanger-side { width: 120px; height: 96px; margin: 0 auto 14px; display: block; }
.gen-side-bottom {
  margin-top: auto;
  padding-top: 18px;
  display: flex; flex-direction: column; gap: 8px;
}

/* 侧栏按钮：纵排，占满宽度 */
.btn-gen-side {
  width: 100%; justify-content: center;
}

/* 提示词改图 inline 输入框 */
.gen-iteration-input {
  width: 100%;
  min-height: 90px;
  resize: vertical;
  padding: 8px 10px;
  border: 1px solid rgba(255,255,255,0.18);
  border-radius: 8px;
  background: var(--surface-ctl);
  color: inherit;
  font: inherit;
  margin-bottom: 6px;
  box-sizing: border-box;
}
.gen-iteration-input:focus {
  outline: none;
  border-color: #f76b1c;
  background: rgba(255,255,255,0.10);
}

/* 右主区：图片网格占满 */
.gen-modal-main {
  flex: 1;
  padding: 22px;
  overflow-y: auto;
  display: flex; align-items: center; justify-content: center;
  min-width: 0;
}

/* 批量优化弹窗：主区复用 fz-result 配对，顶部对齐可滚动 */
.gen-modal-fission { flex: 1; align-self: stretch; overflow-y: auto; min-width: 0; padding: 4px 4px 4px 0; }
/* 一列一对布局：grid auto-fill 等宽列（180-220px），每列=原图在上+对应生成格在下 */
.gen-modal-fission .fzm-pairs { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 220px)); gap: 18px 12px; align-items: start; }
.gen-modal-fission .fzm-pair { display: flex; flex-direction: column; min-width: 0; }
/* 缩略图固定高 + contain：混合比例(1:1/3:4/2:3)时原图盒/结果盒仍全部水平对齐 */
.gen-modal-fission .fzm-pair .fz-thumb { height: 220px; flex: none; background: var(--stage); }
.gen-modal-fission .fzm-pair .fz-thumb img { width: 100%; height: 100%; object-fit: contain; }
.gen-modal-fission .fzm-pair .fz-rstate { aspect-ratio: auto; height: 100%; }
.gen-modal-fission .fzm-sep { text-align: center; margin: 8px 0 6px; }
.gen-modal-fission .fzm-pair .fz-thumb:hover .fz-rhover { opacity: 1; }  /* 没有 .fz-rcard 包裹，hover 操作层在这里重新挂上 */
/* 弹窗侧栏两个方向按钮：单行紧凑，视觉对齐历史抽屉那对（深炭次按钮 + accent 黄主按钮） */
.gen-modal-fz-acts { display: flex; flex-direction: column; gap: 8px; margin-bottom: 6px; }
.fz-act-line {
  width: 100%; box-sizing: border-box;
  height: var(--h-md); padding: 0 14px;
  display: flex; align-items: center; justify-content: center;
  border: none; border-radius: var(--radius-ctl);
  font-family: inherit; font-size: 14px; font-weight: 650;
  line-height: 1.2; white-space: nowrap;
  cursor: pointer; transition: background .15s, filter .15s;
}
/* 次按钮：深炭底白字（弹窗侧栏本身偏暗，加 1px 描边保证轮廓可辨） */
.fz-act-line.is-fission { background: #1a1a1a; color: #fff; border: 1px solid var(--border-strong); }
.fz-act-line.is-fission:hover { background: #3d3d3d; }
/* 主按钮：accent 黄底深字 */
.fz-act-line.is-replace { background: var(--accent); color: #1a1a1a; }
.fz-act-line.is-replace:hover { filter: brightness(1.07); }

/* 实时结果网格（grid-template-columns + maxWidth 由 :style 动态绑定，按张数自适应） */
.gen-modal-results {
  flex: 1;
  overflow-y: auto;
  padding: 18px 22px;
  display: grid;
  gap: 12px;
  align-content: start;
}
.gen-result-cell { display: flex; flex-direction: column; gap: 6px; }
.gen-result-img-wrap {
  background: var(--card); border: 1px solid var(--border);
  border-radius: 8px; overflow: hidden;
  /* aspect-ratio 由 template 内联 :style 按每张 task 的 aspect_ratio 动态设置；
     这里写 3/4 只是 fallback（pending 态、aspect 缺失等异常情况） */
  aspect-ratio: 3/4;
  display: flex; align-items: center; justify-content: center;
  position: relative;
}
.gen-result-cell img {
  width: 100%; height: 100%; object-fit: cover; display: block;
  cursor: zoom-in;
}
.gen-result-cell.status-done .gen-result-img-wrap {
  border-color: var(--accent-ring);
  box-shadow: 0 2px 12px rgba(247,107,28,0.12);
}
/* 选中态：粗黄边框 + 更明显发光 */
.gen-result-cell.selected .gen-result-img-wrap {
  border-color: var(--accent);
  border-width: 2px;
  box-shadow: 0 4px 20px rgba(247,107,28,0.32);
}

/* 右上角选中圈：未选 = 半透明边框圆；选中 = 黄色实心 + 对勾 */
.gen-cell-check {
  position: absolute; top: 8px; right: 8px;
  width: 24px; height: 24px; border-radius: 50%;
  background: rgba(0, 0, 0, 0.55);
  border: 1.5px solid rgba(255, 255, 255, 0.6);
  cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  padding: 0; color: transparent;
  transition-property: var(--t-props); transition-duration: .12s; transition-timing-function: ease;
  z-index: 2;
}
.gen-cell-check:hover { background: rgba(0, 0, 0, 0.75); border-color: #fff; }
.gen-cell-check.on {
  background: var(--accent); border-color: var(--accent); color: var(--on-bg);
  box-shadow: 0 2px 8px rgba(247,107,28,0.4);
}
.gen-cell-check svg.lucide { width: 14px; height: 14px; stroke-width: 3; }

/* 右下角放大按钮 */
.gen-cell-zoom {
  position: absolute; bottom: 8px; right: 8px;
  width: 26px; height: 26px; border-radius: 6px;
  background: rgba(0, 0, 0, 0.55); border: 1px solid rgba(255, 255, 255, 0.15);
  color: rgba(255, 255, 255, 0.8); cursor: pointer; padding: 0;
  display: inline-flex; align-items: center; justify-content: center;
  opacity: 0; transition: opacity .15s ease, background .15s ease;
  z-index: 2;
}
.gen-result-img-wrap:hover .gen-cell-zoom { opacity: 1; }
.gen-cell-zoom:hover { background: rgba(0, 0, 0, 0.85); color: #fff; }
.gen-cell-zoom svg.lucide { width: 14px; height: 14px; }

/* hover 显示的「单卡重新生成」按钮（done / 失败都可点）：底部居中，不挡右下放大/右上勾选。2026-06-15 */
.gen-cell-regen {
  position: absolute; left: 50%; bottom: 8px; transform: translateX(-50%);
  padding: 5px 12px; border-radius: 10px; white-space: nowrap;
  background: rgba(0, 0, 0, 0.62); border: 1px solid rgba(255, 255, 255, 0.25);
  color: #fff; font-size: 12px; line-height: 1; cursor: pointer;
  opacity: 0; transition: opacity .15s ease, background .15s ease;
  z-index: 3;
}
.gen-result-img-wrap:hover .gen-cell-regen { opacity: 1; }
/* SKU搜索图的单张「重新生成」住在 ff 图墙的格子里（2026-08-16 从生成弹窗搬过来）。
   ⚠ 上面那条显形规则只认 .gen-result-img-wrap（旧结果卡的容器）——按钮放进
   .ff-task-cell 后 opacity 永远是 0：DOM 里有、图上看不见，点都点不着。
   这是渲染台实拍抓到的（当天第三次「渲染出来但用不了」，前两次是生成按钮恒灰、
   会话端点漏字段）。凡是把带 hover 显形的控件挪窝，都要跟着补一条容器规则。 */
.ff-task-cell:hover .gen-cell-regen { opacity: 1; }
.gen-cell-regen:hover { background: var(--accent); border-color: var(--accent); color: var(--on-bg); }
.gen-result-loading {
  display: flex; flex-direction: column; align-items: center; gap: 8px;
  color: var(--muted); font-size: 12px;
}
.gen-result-loading .spinner {
  width: 22px; height: 22px; border-width: 2px;
}
.gen-result-loading-text { font-family: var(--mono, ui-monospace, SFMono-Regular, Menlo, monospace); }
.gen-result-loading-engine {
  font-size: 12px; color: var(--fg-muted, #888);
  margin-top: -2px;
  letter-spacing: 0.02em;
}
.gen-result-fail {
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  color: var(--danger);
}
.gen-result-fail-icon {
  width: 26px; height: 26px; border-radius: 50%;
  background: rgba(239,68,68,0.15); color: var(--danger);
  display: flex; align-items: center; justify-content: center;
  font-weight: 650; font-size: 14px;
}
.gen-result-fail-text { font-size: 12px; font-weight: 650; }
.gen-result-fail-zh {
  font-size: 12px; color: #f87171; font-weight: 400;
  text-align: center; padding: 0 10px; line-height: 1.4;
  display: -webkit-box; -webkit-line-clamp: 4; -webkit-box-orient: vertical; overflow: hidden;
}
.gen-result-fail-raw {
  font-size: 10px; color: #888; font-family: var(--mono, ui-monospace, SFMono-Regular, Menlo, monospace);
  text-align: center; padding: 0 8px; line-height: 1.4; word-break: break-all;
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
  margin-top: 4px;
}
.gen-result-label {
  font-size: 12px; color: var(--muted);
  text-align: center;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.gen-result-engine {
  font-size: 10px; color: var(--muted); opacity: .7;
  text-align: center; margin-top: 1px;
}
.gen-result-engine.is-fallback {
  color: #e0681a; opacity: 1;
}
.fallback-badge {
  font-size: 10px; font-weight: 650;
}
.gen-modal-close {   /* 尺寸/圆角/底色走浮层关闭键公共件，这里只定位 */
  position: absolute; top: 14px; right: 14px; z-index: 2;
}
.gen-hanger-wrap {
  display: flex; justify-content: center;
  margin: 36px 0 24px;
}
.gen-hanger {
  width: 180px; height: 140px;
  animation: gen-hanger-float 3.2s ease-in-out infinite;
}
@keyframes gen-hanger-float {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-6px); }
}
.gen-hanger .sparkle-a, .gen-hanger .sparkle-b, .gen-hanger .sparkle-c {
  animation: gen-sparkle-twinkle 2.4s ease-in-out infinite;
}
.gen-hanger .sparkle-b { animation-delay: 0.7s; }
.gen-hanger .sparkle-c { animation-delay: 1.4s; }
@keyframes gen-sparkle-twinkle {
  0%, 100% { opacity: 0.3; }
  50%      { opacity: 1; }
}
.gen-modal-text {
  text-align: center; padding: 0 32px 8px;
}
.gen-modal-title {
  font-size: 14px; color: var(--muted); margin: 0 0 6px;
}
.gen-modal-counter {
  font-size: 32px; font-weight: 650; letter-spacing: -0.02em;
  color: var(--fg);
  font-variant-numeric: tabular-nums;
  line-height: 1.1;
}
.gen-modal-counter .total {
  color: var(--muted); font-size: 28px; font-weight: 400;
}
.gen-modal-meta {
  font-size: 12px; color: var(--muted);
  margin-top: 10px;
  font-family: var(--mono, ui-monospace, SFMono-Regular, Menlo, monospace);
}
.gen-modal-progress {
  margin: 0 0 10px;
  height: 3px;
  background: var(--panel);
  border-radius: 2px;
  overflow: hidden;
}
.gen-modal-progress-fill {
  height: 100%;
  background: var(--accent);
  border-radius: 1px;
  box-shadow: 0 0 12px var(--accent-soft);
  transition: width .35s ease;
}
.gen-modal-foot {
  padding: 20px 24px 22px;
  display: flex; justify-content: center;
  flex-direction: column; align-items: center; gap: 0;
}
.btn-gen-bg {
  font: inherit; padding: 8px 18px;
  border-radius: 6px; border: 1px solid var(--border-strong);
  background: transparent; color: var(--muted);
  cursor: pointer; font-size: 12px;
  font-family: inherit;
}
.btn-gen-bg:hover { color: var(--fg); background: var(--card-hover); }

/* 生成完成态的批量操作按钮组 */
.gen-modal-actions {
  display: flex; gap: 8px; align-items: center; justify-content: center;
  width: 100%; flex-wrap: wrap;
}
.gen-modal-sel-hint {
  font-size: 12px; color: var(--muted);
  margin-right: 6px;
  font-variant-numeric: tabular-nums;
}
.btn-gen-action {
  display: inline-flex; align-items: center; gap: 6px;
  font: inherit; font-size: 12px; font-family: inherit;
  padding: 8px 14px;
  border-radius: 6px;
  background: var(--accent-soft); color: var(--accent);
  border: 1px solid var(--accent-ring);
  cursor: pointer;
  transition-property: var(--t-props); transition-duration: .15s; transition-timing-function: ease;
}
.btn-gen-action:hover:not(:disabled) {
  background: var(--accent); color: var(--on-bg); border-color: var(--accent);
}
.btn-gen-action:disabled {
  background: rgba(255, 255, 255, 0.04);
  color: var(--muted);
  border-color: var(--border);
  cursor: not-allowed;
  opacity: 1;
}
.btn-gen-action:disabled svg.lucide { opacity: 0.6; }
.btn-gen-action svg.lucide { width: 1em; height: 1em; }
/* 「拓展主图尺寸」按钮：主文案加粗，比例子文案另起一行缩小变淡（侧栏批量按钮 + 灯箱按钮共用） */
.expand-label {
  display: flex; flex-direction: column; align-items: center;
  gap: 1px; line-height: 1.2;
}
.expand-label strong { font-weight: 650; }
.expand-label small { font-size: 10px; opacity: 0.6; font-weight: 400; }

/* 推送到淘宝按钮：橙色突出，跟下载/加文案的黄色区分 */
.btn-gen-action.btn-gen-taobao {
  background: rgba(255, 111, 31, 0.16);
  color: #f76b1c;
  border-color: rgba(255, 111, 31, 0.5);
}
.btn-gen-action.btn-gen-taobao:hover:not(:disabled) {
  background: #f76b1c; color: #fff; border-color: #f76b1c;
}

/* 批量拓展 picker：浮在「拓展尺寸」按钮**右侧**（漂出侧边栏，在图片区里显眼） */
.gen-btn-with-picker { position: relative; }
.gen-batch-expand-picker {
  position: absolute;
  left: calc(100% + 14px);   /* 按钮右边缘 + 间距 */
  top: 0;                     /* 跟按钮顶对齐 */
  width: 280px;
  padding: 14px 16px;
  background: #1a1a1c;        /* 弹窗背景同色，比 var(--card) 实一点 */
  border: 1px solid var(--border-strong);
  border-radius: 8px;
  box-shadow: 0 8px 28px rgba(0,0,0,0.45);
  z-index: 10;
}
.gen-batch-expand-label {
  font-size: 12px; color: var(--muted); margin-bottom: 8px;
}   /* 其余走浮层关闭键公共件 */

/* 拓展尺寸：勾选 picker（点 btn-expand 后原地切到这个，让用户选要拓哪几个尺寸再发请求） */
.expand-picker {
  display: inline-flex; align-items: center; gap: 6px;
  flex-wrap: wrap; font-size: 12px;
}
.expand-chip {
  display: inline-block;
  padding: 4px 10px;
  background: var(--panel);
  color: var(--muted);
  border: 1px solid var(--border-strong);
  border-radius: 6px;
  cursor: pointer; user-select: none;
  font-size: 12px; line-height: 1.2;
  transition-property: var(--t-props); transition-duration: .12s; transition-timing-function: ease;
}
.expand-chip:hover { background: var(--card-hover); color: var(--fg); }
.expand-chip.on {
  background: #E8D5BC; color: #5C3F2A;
  border-color: #d99a6b; font-weight: 650;
}
.btn-expand-confirm {
  font-size: 12px; padding: 4px 10px;
  background: var(--accent); color: var(--on-bg);
  border: 1px solid var(--accent);
  border-radius: 6px; cursor: pointer;
  font-weight: 650; font-family: inherit;
}
.btn-expand-confirm:disabled { opacity: 0.4; cursor: not-allowed; }
.btn-expand-cancel {
  font-size: 12px; padding: 4px 10px;
  background: transparent; color: var(--muted);
  border: 1px solid var(--border);
  border-radius: 6px; cursor: pointer; font-family: inherit;
}
.btn-expand-cancel:hover { color: var(--fg); border-color: var(--border-strong); }

/* lightbox 切换条 */
.lightbox-switcher {
  position: absolute;
  bottom: 20px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  gap: 8px;
  background: rgba(255, 255, 255, 0.95);
  padding: 6px 10px;
  border-radius: 6px;
  box-shadow: 0 2px 8px rgba(0,0,0,0.15);
}
.lightbox-switcher button {
  padding: 4px 14px;
  border: 1px solid #d99a6b;
  background: white;
  cursor: pointer;
  border-radius: 6px;
  font-size: 14px;
  color: #5C3F2A;
}
.lightbox-switcher button.active {
  background: #d99a6b;
  color: white;
}

/* 排队/失败 占位：跟图区一样 220px 高，保持卡片整齐 */
.history-pending-placeholder,
.history-failed-placeholder {
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  background: #f5efe8;
  padding: 12px;
  height: 220px; flex-shrink: 0;
  overflow: hidden;
  text-align: center;
}
.history-pending-placeholder .pending-text {
  margin-top: 8px;
  font-size: 12px;
  color: #7A5A3F;
}
.history-failed-placeholder {
  background: #fdf2f0;
}
.history-failed-placeholder .err-title {
  color: #c92c2c;
  font-weight: 650;
  font-size: 14px;
}
.history-failed-placeholder .err-zh {
  font-size: 12px;
  color: #5C3F2A;
  margin-top: 4px;
}
.history-failed-placeholder .err-zh {
  /* 中文友好提示限制 3 行，超出省略 */
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.history-failed-placeholder .err-raw {
  font-size: 12px;
  color: #999;
  margin-top: 4px;
  word-break: break-all;
  /* 原始错误限制 2 行，鼠标悬停在卡上想看全的话用 title 提示（已有 t.error_message）*/
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
/* pending 卡的文字不再淡化（之前 is-edit 那套灰度可能影响视觉，这里显式覆盖）*/
.history-card.is-pending .history-body,
.history-card.is-failed .history-body {
  opacity: 1;
}

/* 历史 tab 子视图切换：单张 / 图组 */
.history-view-toggle {
  display: flex;
  gap: 8px;
  margin: -8px 0 16px 0;
}
.history-view-pill {
  padding: 6px 16px;
  font-size: 14px;
  background: white;
  color: #7A5A3F;
  border: 1px solid #d99a6b;
  border-radius: 16px;
  cursor: pointer;
  transition-property: var(--t-props); transition-duration: .15s; transition-timing-function: ease;
}
.history-view-pill:hover { background: #f5efe8; }
.history-view-pill.on {
  background: #d99a6b;
  color: white;
  font-weight: 650;
}
.history-empty-hint {
  text-align: center;
  color: var(--muted, #999);
  font-size: 14px;
  margin: 20px 0;
  padding: 16px;
  /* 原来是 #fafafa 纯白 —— 浅色主题时代的遗留，在现在的深色底上是一块刺眼白斑。
     它还真在用（换装页右栏历史区，「本页没有记录」时出现）。2026-08-05 排查发现 */
  background: transparent;
  border-radius: var(--radius-ctl);
}

/* 三个折叠下拉同行：生图引擎 / 输出尺寸 / 输出数量 */
.triple-row { display: flex; gap: 8px; align-items: flex-start; }
.triple-col { flex: 1; min-width: 0; }
.lbl-sub { color: var(--muted); font-weight: 400; opacity: 0.8; }

/* 通用折叠下拉 */
.dd { position: relative; }
.dd-trigger {
  width: 100%; display: flex; align-items: center;
  font-size: 14px; padding: 9px 28px 9px 10px;
  background: var(--card); color: var(--fg);
  border: 1px solid var(--border); border-radius: var(--radius);
  cursor: pointer; font-family: inherit; text-align: left;
  white-space: nowrap; overflow: hidden;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%238a8a92' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>");
  background-repeat: no-repeat; background-position: right 9px center;
  transition-property: var(--t-props); transition-duration: .15s; transition-timing-function: ease;
}
.dd-trigger > span { overflow: hidden; text-overflow: ellipsis; }
.dd-trigger:hover { border-color: var(--border-strong); }
.dd-trigger.open { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.dd-panel {
  position: absolute; top: calc(100% + 4px); left: 0; min-width: 100%; z-index: 30;
  background: var(--surface-pop); border: 1px solid var(--border-strong);
  border-radius: var(--radius-ctl); padding: 4px;
  display: flex; flex-direction: column; gap: 2px;
  box-shadow: 0 8px 24px rgba(0,0,0,0.55);
}
.dd-panel--wide { min-width: 248px; }   /* 引擎面板放得下名字+说明 */
/* 补充要求面板（2026-08-05）：参数排里放不下长文本，收成按钮点开写 */
.dd-panel--note { min-width: 380px; right: 0; left: auto; padding: 10px; gap: 8px; }
/* 微调·四合一面板（2026-08-12 方案A）：段头 + 选项钮排；选项钮复用 .sm-ratio-btn（选中实心橙），
   这儿只补边框和小一号的字，别再造一套选中样式（五条线共用 .on 的教训同理） */
.dd-panel--tweak { width: 340px; padding: 12px 14px; }
.dd-sec { font-size: 11px; color: var(--muted); letter-spacing: .5px; margin: 12px 0 6px; }
.dd-panel--tweak .dd-sec:first-child { margin-top: 2px; }
.dd-seg { display: flex; flex-wrap: wrap; gap: 6px; }
.dd-seg .sm-ratio-btn { border: 1px solid var(--border); font-size: 13px; padding: 4px 10px; }
.dd-seg .sm-ratio-btn.on { border-color: var(--accent); }
.dd-note-ta {
  width: 100%; min-height: 92px; resize: vertical; font: inherit; font-size: 14px; line-height: 1.7;
  background: var(--surface-ctl); border: 1px solid var(--border); border-radius: var(--radius-ctl);
  color: var(--fg); padding: 9px 11px; outline: none;
}
.dd-note-ta:focus { border-color: var(--accent-ring); }
.dd-note-ta::placeholder { color: var(--muted); opacity: .6; }
.dd-note-foot { display: flex; align-items: center; justify-content: space-between; font-size: 12px; color: var(--muted); }
.dd-note-clear { background: none; border: 0; color: var(--muted); font-size: 12px; cursor: pointer; font-family: inherit; padding: 2px 4px; }
.dd-note-clear:hover { color: var(--accent); }
.dd-opt {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 10px; font-size: 14px; white-space: nowrap;
  background: transparent; border: none; border-radius: 6px;
  color: var(--fg); cursor: pointer; font-family: inherit; text-align: left;
  transition: background .12s ease;
}
.dd-opt:hover { background: var(--card-hover); }
.dd-opt.on { color: var(--accent); font-weight: 650; }
.dd-opt--col { flex-direction: column; align-items: flex-start; gap: 2px; }
.dd-opt-main { display: flex; align-items: center; gap: 8px; }
.dd-tick { width: 14px; height: 14px; flex: none; color: var(--accent); }
.dd-ratio { min-width: 30px; }
.dd-opt .r-sub { margin-left: auto; font-size: 12px; color: var(--muted); }
.dd-opt--col .r-sub { margin-left: 22px; }   /* 引擎说明缩进对齐名字 */

/* ===== 文案板块卡片（左面板上半） — 跟元素库视觉对齐，可折叠 ===== */
.copy-panel-section {
  padding: 12px;
  background: rgba(255, 255, 255, 0.025);
  border: 1px solid #2c2c2c;
  border-radius: 10px;
  flex-shrink: 0;
  transition: background .12s;
}
.copy-panel-section.collapsed { padding: 10px 12px; }
.copy-head { cursor: pointer; user-select: none; }
.copy-head:hover h4 { color: #4ea1ff; }
.copy-panel-section .copy-head { margin-bottom: 0; }
.copy-panel-section:not(.collapsed) .copy-head { margin-bottom: 10px; }
.copy-head .caret { font-size: 10px; color: #888; margin-left: 4px; }
.copy-hint { font-size: 12px; color: #888; }
/* 紧凑化内部 fields/picker（覆盖原本 .edit-* 默认的大 padding） */
.copy-panel-section .edit-tpl-picker {
  margin-bottom: 8px; padding-bottom: 8px;
}
.copy-panel-section .edit-aspect-tabs { margin-bottom: 8px; }
.copy-panel-section .edit-field { margin-bottom: 8px; }
.copy-panel-section .edit-field:last-of-type { margin-bottom: 0; }
.copy-panel-section .edit-field label { margin-bottom: 3px; font-size: 12px; }
.copy-panel-section .edit-field input[type=text] {
  padding: 6px 9px; font-size: 12px;
}
.copy-panel-section .edit-field textarea {
  padding: 7px 9px; font-size: 14px; min-height: 80px;
}
.copy-panel-section .edit-aspect-hint { margin: 0 0 8px; font-size: 12px; }

/* ===== 元素库板块（左面板下半，与文案上下并列）— 同款卡片包裹 ===== */
.elem-panel-section {
  margin-top: 12px;
  padding: 12px 12px 10px;
  background: rgba(255, 255, 255, 0.025);
  border: 1px solid #2c2c2c;
  border-radius: 10px;
  display: flex; flex-direction: column;
  flex: 1 1 auto; min-height: 280px;
}
.elem-section-head {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 10px;
}
.elem-section-head h4 {
  margin: 0; font-size: 14px; color: #e0e0e0; font-weight: 650;
}
.elem-upload-btn {
  background: linear-gradient(135deg, #5a8cff, #4a7cef);
  color: #fff; border: 0; padding: 4px 10px;
  border-radius: 6px; cursor: pointer; font-size: 12px;
}
.elem-upload-btn:hover { filter: brightness(1.1); }

.elem-tabs {
  display: flex; gap: 4px; margin-bottom: 8px;
}
.elem-tabs button {
  flex: 1; background: #0e0e0e; border: 1px solid #2a2a2a; color: #aaa;
  padding: 5px 8px; border-radius: 6px; cursor: pointer; font-size: 12px;
}
.elem-tabs button.on { background: #1f2530; color: #eee; border-color: #4ea1ff; }

.elem-search-input {
  width: 100%; padding: 5px 9px; background: var(--surface-ctl); border: 1px solid var(--border);
  color: #eee; border-radius: var(--radius-ctl); font-size: 12px; margin-bottom: 8px;
  box-sizing: border-box;
}

.elem-panel-section .elem-drawer-body {
  flex: 1; overflow-y: auto;
  padding: 4px 0 0; margin: 0;
}
.elem-panel-section .elem-grid {
  grid-template-columns: repeat(3, 1fr); gap: 6px;
}
.elem-panel-section .elem-card { padding: 4px 2px; }
.elem-panel-section .elem-card-name { font-size: 10px; }

/* ===== 元素库抽屉（旧右侧抽屉样式，已废弃，保留以防回退） ===== */
.elem-drawer-toggle {
  position: absolute; top: 12px; right: 12px; z-index: 5;
  background: rgba(20,20,20,0.92); color: #eee; border: 1px solid #333;
  padding: 6px 12px; border-radius: 10px; cursor: pointer; font-size: 12px;
}
.elem-drawer-toggle:hover { background: #2a2a2a; }

.elem-drawer {
  width: 320px; background: #161616; border-left: 1px solid #2a2a2a;
  display: flex; flex-direction: column;
  transition: margin-right 0.2s;
  height: 100%;
}
.elem-drawer.collapsed { margin-right: -320px; }
.elem-drawer-header { padding: 12px; border-bottom: 1px solid #2a2a2a; }
.elem-drawer-tabs { display: flex; gap: 4px; margin-bottom: 10px; }
.elem-drawer-tabs button {
  flex: 1; background: transparent; border: 1px solid #333; color: #aaa;
  padding: 6px 8px; border-radius: 6px; cursor: pointer; font-size: 12px;
}
.elem-drawer-tabs button.on { background: #2a2a2a; color: #eee; border-color: #4ea1ff; }
.elem-drawer-search { display: flex; gap: 6px; }
.elem-drawer-search input {
  flex: 1; padding: 6px 10px; background: var(--surface-ctl); border: 1px solid var(--border);
  color: #eee; border-radius: var(--radius-ctl); font-size: 12px;
}
.elem-drawer-body { flex: 1; overflow-y: auto; padding: 12px; }
.elem-empty { color: #777; font-size: 12px; text-align: center; padding: 20px; }
.elem-cat { margin-bottom: 16px; }
.elem-cat h5 {
  font-size: 12px; color: #aaa; margin: 0 0 8px; display: flex; align-items: center;
}
.elem-cat h5 span { color: #555; font-size: 12px; margin-left: 6px; }
.elem-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 8px; }
/* 元素卡 — 圆形缩略图 + 下方居中文字 */
.elem-card {
  display: flex; flex-direction: column; align-items: center;
  padding: 6px 2px; cursor: pointer; position: relative;
  border-radius: 10px; transition: background .12s;
}
.elem-card:hover { background: rgba(78, 161, 255, 0.08); }
.elem-card.active { background: rgba(78, 161, 255, 0.16); }
.elem-card.active .elem-card-thumb {
  border-color: #4ea1ff;
  box-shadow: 0 0 0 2px rgba(78, 161, 255, 0.35);
}
.elem-card.active .elem-card-name { color: #4ea1ff; font-weight: 650; }

.elem-card-thumb {
  width: 100%; aspect-ratio: 1; border-radius: 50%;
  background: #fafafa;
  overflow: hidden; position: relative;
  border: 2px solid transparent;
  transition: border-color .12s;
}
.elem-card:hover .elem-card-thumb { border-color: #4ea1ff; }
.elem-card-thumb img {
  width: 100%; height: 100%; object-fit: cover; pointer-events: none;
}

.elem-card-name {
  font-size: 12px; color: #ddd; text-align: center;
  margin-top: 5px; line-height: 1.2;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  max-width: 100%;
}

.elem-pinned {
  position: absolute; top: -2px; left: -2px; font-size: 12px;
  background: rgba(255,200,0,0.95); color: #222; padding: 1px 5px;
  border-radius: 10px; font-weight: 650; z-index: 2;
}
.elem-del {
  position: absolute; top: -2px; right: -2px;
  width: 20px; height: 20px; border-radius: 50%;
  background: rgba(0,0,0,0.7); color: #fff; border: 0;
  font-size: 12px; line-height: 18px; cursor: pointer;
  opacity: 0; transition: opacity .15s; padding: 0;
  z-index: 2;
}
.elem-card:hover .elem-del { opacity: 1; }
.elem-del:hover { background: #c92c2c; }

.elem-card-trash .elem-card-thumb { opacity: 0.55; }
.elem-restore {
  font-size: 12px; padding: 3px 8px; margin-top: 4px;
}
.modal-upload-elem { width: 440px; }
.modal-upload-elem .up-row { margin-bottom: 12px; }
.modal-upload-elem .up-row label {
  display: block; font-size: 12px; color: #aaa; margin-bottom: 4px;
}
.modal-upload-elem .up-row input[type="text"],
.modal-upload-elem .up-row input[type="file"] {
  width: 100%; padding: 8px 10px; background: var(--surface-ctl); border: 1px solid var(--border);
  color: #eee; border-radius: var(--radius-ctl); font-size: 14px;
}
.modal-upload-elem .up-checkbox label {
  color: #ddd; font-size: 14px; cursor: pointer;
}
.modal-upload-elem .up-checkbox input { margin-right: 6px; }
.modal-upload-elem .up-actions {
  display: flex; gap: 8px; justify-content: flex-end; margin-top: 16px;
}
.up-mode-tabs {
  display: flex; gap: 6px; margin-bottom: 16px;
  background: #0e0e0e; padding: 4px; border-radius: 8px;
  border: 1px solid #2a2a2a;
}
.up-mode-tabs button {
  flex: 1; background: transparent; border: 0; color: #999;
  padding: 8px 12px; border-radius: 6px; cursor: pointer; font-size: 14px;
  transition-property: var(--t-props); transition-duration: .12s; transition-timing-function: ease;
}
.up-mode-tabs button.on { background: #1f2530; color: #fff; }
.up-mode-tabs button:hover:not(.on) { color: #ccc; }
.up-row select.up-input, .modal-upload-elem .up-row select {
  width: 100%; padding: 8px 10px; background: var(--surface-ctl); border: 1px solid var(--border);
  color: #eee; border-radius: var(--radius-ctl); font-size: 14px;
}
.up-optional { color: #666; font-size: 12px; }
.modal-upload-elem.drag-over {
  outline: 2px dashed #4ea1ff; outline-offset: -4px;
  background: #1a2030;
}
.modal-upload-elem .up-selected {
  margin-top: 6px; font-size: 12px; color: #6ec07a;
}

/* 元素库操作浮动 toast */
.elem-toast {
  position: fixed; bottom: 32px; left: 50%; transform: translateX(-50%);
  padding: 10px 20px; border-radius: 8px; font-size: 14px; color: #fff;
  z-index: 9999; box-shadow: 0 6px 24px rgba(0,0,0,0.4);
  animation: elemToastIn 0.22s ease-out;
}
.elem-toast.out { animation: elemToastOut 0.22s ease-out forwards; }
.elem-toast-ok { background: linear-gradient(135deg, #3ca25f, #2e8b4d); }
.elem-toast-err { background: linear-gradient(135deg, #c9434f, #a8323d); }
@keyframes elemToastIn {
  from { opacity: 0; transform: translate(-50%, 8px); }
  to { opacity: 1; transform: translate(-50%, 0); }
}
@keyframes elemToastOut {
  to { opacity: 0; transform: translate(-50%, -8px); }
}

/* ===== 登录遮罩 + U1 顶栏用户区（auth.js 注入，Vue 之外；AUTH 关闭时这些都不出现）===== */

/* —— 全屏登录遮罩 —— */
#ps-login-mask {
  position: fixed; inset: 0; z-index: 9999;
  display: flex; align-items: center; justify-content: center;
  background: rgba(8, 8, 10, 0.72);              /* 半透明：背后 app 可见,即梦式小窗 */
  backdrop-filter: blur(3px);
  color: var(--fg);
  font-family: "Inter", "PingFang SC", -apple-system, BlinkMacSystemFont, sans-serif;
}
.ps-login-card { position: relative; }            /* 给 ✕ 定位用 */
.ps-login-close {
  position: absolute; top: 12px; right: 14px;
  background: none; border: none; color: var(--fg);
  opacity: .5; font-size: 20px; cursor: pointer; line-height: 1;
}
.ps-login-close:hover { opacity: 1; }
.ps-login-card {
  width: 360px; max-width: 90vw; text-align: center;
  background: rgba(255, 255, 255, 0.035); border: 1px solid var(--border);
  border-radius: 18px; padding: 44px 36px 36px;
  box-shadow: 0 30px 80px rgba(0, 0, 0, 0.5);
}
/* logo 已换成内联品牌 SVG（auth.js，橙印章「素」+白星），这里只当尺寸容器 */
.ps-login-logo { display: block; width: 56px; height: 56px; margin: 0 auto 16px; }
.ps-login-title { font-size: 20px; font-weight: 650; margin: 0 0 8px; letter-spacing: -0.01em; }
.ps-login-sub { color: var(--muted); font-size: 12px; margin: 0 0 18px; }
.ps-login-err { color: #ff5c5c; font-size: 14px; min-height: 18px; margin: 0 0 10px; line-height: 1.5; }
/* 注册赠点钩子：登录按钮正下方一行小字（后端 wallet.SIGNUP_BONUS_POINTS=100）。
   原来做成橙框橙底的提示块，实测抢按钮的戏，改成克制的纯文字 */
.ps-login-gift { margin: 9px 0 0; color: var(--muted); font-size: 12px; line-height: 1.5; }
.ps-login-gift b { color: #e8934f; font-weight: 650; }
.ps-feishu-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 9px;
  width: 100%; height: 48px; border: none; border-radius: 10px; cursor: pointer;
  background: #3370ff; color: #fff; font-size: 14px; font-weight: 650; font-family: inherit;
  transition: filter .15s;
}
.ps-feishu-btn:hover { filter: brightness(1.1); }
.ps-feishu-btn:active { filter: brightness(.92); }
.ps-feishu-btn:disabled { opacity: .6; cursor: default; }
.ps-admin-form { margin-top: 18px; padding-top: 16px; border-top: 1px dashed var(--border); }
.ps-login-input {
  width: 100%; box-sizing: border-box; height: 44px; padding: 0 14px; margin: 5px 0;
  background: rgba(0, 0, 0, 0.32); color: var(--fg);
  border: 1px solid var(--border-strong); border-radius: 10px; font-size: 14px; font-family: inherit;
}
.ps-login-input::placeholder { color: #6b6b73; }
.ps-login-input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.ps-admin-btn {
  width: 100%; height: 44px; margin-top: 8px; border: none; border-radius: 10px; cursor: pointer;
  background: var(--accent); color: var(--on-bg); font-size: 14px; font-weight: 650; letter-spacing: 2px; font-family: inherit;
}
.ps-admin-btn:hover { filter: brightness(1.06); }
.ps-admin-btn:disabled { opacity: .6; cursor: default; }
.ps-admin-link {
  position: absolute; right: 22px; bottom: 18px;
  color: #5d5d66; font-size: 12px; cursor: pointer; user-select: none;
}
.ps-admin-link:hover { color: var(--fg); text-decoration: underline; }

/* —— 手机号验证码视图：验证码输入 + 发码按钮一行 —— */
.ps-code-row { display: flex; gap: 8px; }
.ps-code-row .ps-login-input { flex: 1; }
.ps-code-btn {
  flex: 0 0 auto; height: 44px; margin: 5px 0; padding: 0 14px; white-space: nowrap;
  border: 1px solid var(--border-strong); border-radius: 10px; cursor: pointer;
  background: rgba(255, 255, 255, 0.05); color: var(--fg); font-size: 14px; font-family: inherit;
  transition: border-color .15s, color .15s;
}
.ps-code-btn:hover { border-color: var(--accent-ring); color: var(--accent); }
.ps-code-btn:disabled { opacity: .55; cursor: default; }
/* 开发模式提示（短信未配真发） */
.ps-login-devhint { color: var(--muted); font-size: 12px; margin: 10px 0 0; line-height: 1.5; }
/* 飞书登录次要样式：小链接按钮 */
.ps-alt-row { margin-top: 14px; padding-top: 12px; border-top: 1px dashed var(--border); }
.ps-feishu-link {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  border: none; background: none; cursor: pointer; font-family: inherit;
  color: #6f95e6; font-size: 12px; padding: 4px 6px;
}
.ps-feishu-link:hover { color: #8eaef0; text-decoration: underline; }
.ps-feishu-link:disabled { opacity: .6; cursor: default; }

/* —— 已绑手机号菜单项：不可点（仅展示）—— */
.ps-mi-static { color: var(--muted); cursor: default; }
.ps-mi-static:hover { background: none; }

/* —— 绑定手机号小弹层 —— */
.ps-bind-mask {
  position: fixed; inset: 0; z-index: 9999;
  display: flex; align-items: center; justify-content: center;
  background: var(--scrim);
  font-family: "Inter", "PingFang SC", -apple-system, BlinkMacSystemFont, sans-serif;
}
.ps-bind-card {
  width: 340px; max-width: 90vw;
  background: var(--surface-pop); border: 1px solid var(--border-strong);
  border-radius: var(--radius-card); padding: 22px 22px 18px;
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.6); color: var(--fg);
}
.ps-bind-title { margin: 0 0 14px; font-size: 14px; font-weight: 650; }
.ps-bind-actions { display: flex; gap: 10px; margin-top: 6px; }
.ps-bind-actions .ps-rc-close { flex: 1; width: auto; margin: 0; }
.ps-bind-actions .ps-admin-btn { flex: 1; width: auto; margin: 0; }

/* —— U1 用户区：侧栏左下壳填充（登录后 auth.js 写入 .as-points / .as-avatar）—— */
/* 登录态：member 在侧栏看不到用量与账单（接口本就 admin-only） */
body.ps-member .as-util-usage { display: none; }
/* 登录态侧栏壳：头像实线圈 + 可点（暖橙渐变配套菜单头像;飞书头像 img 覆盖） */
body.ps-authed .as-avatar { border-style: solid; cursor: pointer; overflow: hidden; display: flex; align-items: center; justify-content: center; font-size: 14px; font-weight: 650; color: #1a0d00; background: linear-gradient(135deg, #f7a35c, #e5581b); }
body.ps-authed .as-avatar img { width: 100%; height: 100%; object-fit: cover; border-radius: 50%; }
body.ps-authed .as-points { cursor: pointer; }

/* 菜单内头像（会员卡头内 42px,暖橙渐变归队品牌色;飞书头像 img 覆盖渐变） */
.ps-who-av {
  width: 42px; height: 42px; border-radius: 50%; flex: 0 0 42px;
  background: linear-gradient(135deg, #f7a35c, #e5581b); color: #1a0d00;
  display: flex; align-items: center; justify-content: center; font-size: 14px; font-weight: 650;
  border: 2px solid transparent; overflow: hidden;
}
.ps-who-av img { width: 100%; height: 100%; object-fit: cover; display: block; border-radius: 50%; }

/* —— 头像下拉菜单 + 充值面板：fixed 左下，紧贴侧栏用户区上方 ——
   2026-07-11「会员卡头」原本是磨砂半透，2026-08-05 第四批跟其它浮层一起改实底 */
.ps-menu, .ps-rcpop {
  position: fixed; left: 88px; bottom: 14px; z-index: 200; width: 276px;
  background: var(--surface-pop);
  border: 1px solid var(--border-strong); border-radius: var(--radius-card);
  box-shadow: 0 24px 64px rgba(0, 0, 0, 0.5); padding: 10px;
  display: none;
}
.ps-menu.open, .ps-rcpop.open { display: block; animation: psMenuIn .18s ease; }
@keyframes psMenuIn { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: none; } }
/* 会员卡头：头像+名字+手机号+余额大数字+充值按钮,右上角焦糖辉光 */
.ps-plate {
  position: relative; overflow: hidden;
  background: linear-gradient(160deg, #2b2b31 0%, #1c1c21 70%);
  border: 1px solid var(--border-strong); border-radius: 13px;
  padding: 13px 13px 12px; margin-bottom: 8px;
}
.ps-plate::before {
  content: ""; position: absolute; inset: 0;
  background: radial-gradient(220px 120px at 85% -20%, rgba(247,107,28,.22), transparent 70%);
  pointer-events: none;
}
.ps-prow { display: flex; gap: 11px; align-items: center; position: relative; }
.ps-who-meta b:not(.ps-who-vip) { font-size: 14px; display: block; }
.ps-who-meta i { font-size: 12px; color: var(--muted); font-style: normal; display: block; margin-top: 2px; font-variant-numeric: tabular-nums; }
.ps-brow { display: flex; align-items: flex-end; justify-content: space-between; margin-top: 13px; position: relative; }
.ps-bal-lab { display: block; font-size: 10px; color: var(--muted); letter-spacing: 1px; margin-bottom: 4px; }
.ps-bal-num { display: block; font-size: 28px; font-weight: 650; line-height: 1; color: var(--accent); }
.ps-bal-unit { font-size: 12px; font-weight: 650; color: #c9a284; margin-left: 3px; }
.ps-bal-go {
  border: none; background: var(--accent); color: #1a0d00; font-size: 12px; font-weight: 650;
  padding: 8px 14px; border-radius: 999px; cursor: pointer; font-family: inherit; transition: filter .15s;
}
.ps-bal-go:hover { filter: brightness(1.1); }
/* —— VIP 尊贵态(全站 body.ps-vip 点亮;is_vip 来自 /api/me,读不到当非VIP) ——
   标识=头像下缘黑金「VIP」字牌(伪元素,fillAvatar 重填 textContent 也不丢),弃用 emoji 👑 */
.ps-who-vip { display: none; }
body.ps-vip .ps-who-vip { display: block; margin-top: 3px; font-size: 10px; font-weight: 650; background: linear-gradient(90deg, #ffd79a, #f76b1c); -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; }
body.ps-vip .ps-who-meta b:not(.ps-who-vip) { background: linear-gradient(90deg, #ffd79a, #f76b1c); -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; }
body.ps-vip .ps-who-av { box-shadow: 0 0 0 2px #f76b1c; position: relative; overflow: visible; }
body.ps-vip .ps-who-av::after {
  content: "VIP"; position: absolute; bottom: -6px; left: 50%; transform: translateX(-50%);
  background: linear-gradient(135deg, #2f1f0c, #201409);
  border: 1px solid rgba(247,107,28,.7); border-radius: 999px;
  color: #ffcf8f; font-size: 10px; font-weight: 650; letter-spacing: .6px;
  padding: 2.5px 6.5px; line-height: 1; box-shadow: 0 2px 6px rgba(0,0,0,.55);
  pointer-events: none;
}
body.ps-vip .ps-plate { background: linear-gradient(160deg, #33220e 0%, #201409 70%); border-color: rgba(247,107,28,.6); }
body.ps-vip .ps-plate::before { background: radial-gradient(240px 130px at 85% -20%, rgba(255,190,90,.28), transparent 70%); }
body.ps-vip .ps-bal-lab { color: #c9a284; }
body.ps-vip .ps-bal-num { background: linear-gradient(90deg, #ffd79a, #f76b1c); -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; }
body.ps-vip .ps-bal-unit { -webkit-text-fill-color: #c9a284; }
body.ps-vip .rail2 .as-points { background: linear-gradient(135deg, #2a1c0a, #3a2712); border-color: rgba(247,107,28,.6); }
body.ps-vip .rail2 .as-points .pt-num { color: #ffd79a; }
body.ps-vip .rail2 .as-points .pt-rc { color: #e0a869; opacity: 1; }
body.ps-vip .rail2 .as-avatar { border: 2px solid #f76b1c; box-shadow: 0 0 8px rgba(247,107,28,.45); position: relative; overflow: visible; }
body.ps-vip .rail2 .as-avatar::after {
  content: "VIP"; position: absolute; bottom: -5px; left: 50%; transform: translateX(-50%);
  background: linear-gradient(135deg, #2f1f0c, #201409);
  border: 1px solid rgba(247,107,28,.7); border-radius: 999px;
  color: #ffcf8f; font-size: 10px; font-weight: 650; letter-spacing: .6px;
  padding: 2px 5.5px; line-height: 1; box-shadow: 0 2px 6px rgba(0,0,0,.55);
  pointer-events: none;
}
.ps-mi {
  display: flex; align-items: center; gap: 10px; width: 100%;
  border: none; background: none; color: var(--fg); cursor: pointer; text-align: left;
  font-size: 14px; font-weight: 650; padding: 9px 10px; border-radius: 10px; font-family: inherit;
  transition: background .12s;
}
.ps-mi:hover { background: var(--panel-strong); }
.ps-mi:active { background: rgba(255, 255, 255, 0.1); }
.ps-mi-ic { width: 18px; height: 18px; flex: 0 0 18px; color: var(--muted); }
.ps-mi:hover .ps-mi-ic { color: var(--accent); }
.ps-mi-sep { border-top: 1px solid var(--border); margin: 6px 8px; }
/* 退出登录：常态淡红,悬停才泛红底 */
.ps-mi-red { color: #d98d8d; }
.ps-mi-red .ps-mi-ic { color: #d98d8d; }
.ps-mi-red:hover { background: rgba(239, 68, 68, .1); color: var(--danger); }
.ps-mi-red:hover .ps-mi-ic { color: var(--danger); }
.ps-badge { margin-left: auto; font-size: 10px; background: var(--accent-soft); color: var(--accent); padding: 2px 7px; border-radius: 999px; }

/* —— 充值面板（简化版：余额大数字 + 联系管理员充值）—— */
.ps-rcpop { padding: 16px 16px 14px; }
.ps-rcpop h4 { margin: 0 0 10px; font-size: 14px; }
.ps-rc-balance { text-align: center; margin: 6px 0 2px; }
.ps-rc-balance b { font-size: 32px; color: var(--accent); font-weight: 650; }
.ps-rc-balance span { font-size: 14px; color: var(--muted); margin-left: 4px; }
.ps-rc-hint { text-align: center; color: var(--muted); font-size: 12px; margin: 4px 0 14px; line-height: 1.6; }
.ps-rc-close {
  width: 100%; height: var(--h-md); border: 1px solid var(--border-strong); border-radius: var(--radius-ctl); background: transparent;
  color: var(--fg); font-size: 14px; font-weight: 650; padding: 0; cursor: pointer; font-family: inherit;
}
.ps-rc-close:hover { border-color: var(--accent-ring); color: var(--accent); }
.ps-rc-go {
  display: flex; align-items: center; justify-content: center;
  width: 100%; height: var(--h-md); box-sizing: border-box; text-align: center;
  border: none; border-radius: var(--radius-ctl); background: var(--accent); color: #1a1300;  /* 橙底上的字统一深棕，跟全站主按钮一致（原来这里是白字，压不住） */
  font-size: 14px; font-weight: 650; padding: 0; margin: 4px 0 8px;
  cursor: pointer; text-decoration: none; font-family: inherit;
}
.ps-rc-go:hover { filter: brightness(1.06); }

/* —— 充值小窗口（iframe 弹 /recharge?embed=1，取代整页跳转）2026-06-21 —— */
.ps-rc-modal { position: fixed; inset: 0; z-index: 1000; display: none; align-items: center; justify-content: center; background: var(--scrim); padding: 20px; }
.ps-rc-modal.open { display: flex; animation: psMenuIn .18s ease; }
.ps-rc-win { position: relative; width: 460px; max-width: 94vw; height: 630px; max-height: 90vh; background: var(--surface-pop); border: 1px solid var(--border-strong); border-radius: var(--radius-card); overflow: hidden; box-shadow: 0 30px 80px rgba(0, 0, 0, 0.6); }
.ps-rc-frame { width: 100%; height: 100%; border: 0; display: block; }
.ps-rc-x { position: absolute; top: 11px; right: 13px; z-index: 2; }   /* 其余走浮层关闭键公共件 */

/* ===== 联系客服 / 意见反馈：微信二维码小窗 ===== */
.ps-qr-modal { position: fixed; inset: 0; z-index: 1000; display: none; align-items: center; justify-content: center; background: var(--scrim); padding: 20px; }
.ps-qr-modal.open { display: flex; animation: psMenuIn .18s ease; }
.ps-qr-win { position: relative; width: 300px; max-width: 92vw; background: var(--surface-pop); border: 1px solid var(--border-strong); border-radius: var(--radius-card); padding: 22px 22px 18px; text-align: center; box-shadow: 0 30px 80px rgba(0, 0, 0, 0.6); }
.ps-qr-win h4 { margin: 0 0 16px; font-size: 14px; color: var(--fg); font-weight: 650; }
.ps-qr-img { width: 216px; height: 216px; border-radius: 12px; background: #fff; padding: 9px; display: block; margin: 0 auto; box-sizing: border-box; user-select: none; }
.ps-qr-tip { margin: 14px 2px 0; font-size: 12px; color: var(--muted); line-height: 1.55; }
.ps-qr-x { position: absolute; top: 11px; right: 13px; z-index: 2; }   /* 其余走浮层关闭键公共件 */

/* ===== placed-layer: 画布上的置放元素层 ===== */
.edit-canvas-stage { position: relative; }
.placed-layer {
  position: absolute; inset: 0; pointer-events: none;
}
.placed-layer .placed-item {
  position: absolute; pointer-events: auto; cursor: move; user-select: none;
  border-radius: 50%; overflow: hidden;
  background: #fff;
}
.placed-layer .placed-item img {
  width: 100%; height: 100%; display: block; pointer-events: none;
  object-fit: contain;  /* 圆形内完整显示元素，不裁掉标题/数字等 */
}
.placed-layer .placed-item.selected { outline: 2px solid #4ea1ff; outline-offset: 1px; }
.placed-layer .ph-handle {
  position: absolute; width: 12px; height: 12px; background: #4ea1ff;
  border: 2px solid #fff; border-radius: 50%;
}
.placed-layer .ph-handle.ph-nw { left: -7px; top: -7px; cursor: nwse-resize; }
.placed-layer .ph-handle.ph-ne { right: -7px; top: -7px; cursor: nesw-resize; }
.placed-layer .ph-handle.ph-sw { left: -7px; bottom: -7px; cursor: nesw-resize; }
.placed-layer .ph-handle.ph-se { right: -7px; bottom: -7px; cursor: nwse-resize; }
.placed-layer .placed-toolbar {
  position: absolute; top: -38px; left: 0; display: flex; gap: 4px;
  background: rgba(20,20,20,0.96); padding: 4px 6px; border-radius: 6px;
  white-space: nowrap; box-shadow: 0 4px 12px rgba(0,0,0,0.4);
}
.placed-layer .placed-toolbar button {
  background: transparent; border: 0; color: #ddd; font-size: 12px;
  padding: 4px 8px; cursor: pointer; border-radius: 6px;
}
.placed-layer .placed-toolbar button:hover { background: #333; }
.placed-layer .placed-toolbar button.danger:hover { background: #582020; color: #ff8080; }
.placed-layer .placed-toolbar button:disabled { opacity: 0.35; cursor: default; }
.placed-layer .placed-toolbar button:disabled:hover { background: transparent; }

/* —— 视频生成 tab —— */
/* 合并卡片：素材区 + textarea + 模板按钮共享一个边框，参照即梦 */
.video-compose {
  border: 1px solid #d4cdb8;
  border-radius: 10px;
  padding: 10px;
  background: rgba(255,255,255,0.02);
  display: flex; flex-direction: column; gap: 10px;
}
.video-compose .video-refs { margin: 0; }
.video-compose .video-prompt-input {
  border: 0;
  background: transparent;
  padding: 4px 2px;
  outline: none;
  width: 100%;
  resize: vertical;
}
.video-compose .video-prompt-input:focus { outline: none; }
.video-compose .video-templates { margin-top: 0; }
.field-sublabel { color: #a59f90; font-size: 12px; font-weight: normal; margin-left: 4px; }
.video-refs { display: flex; flex-wrap: wrap; gap: 8px; }
.ref-add {
  width: 80px; height: 80px; border: 2px dashed #d4cdb8;
  border-radius: 10px; display: flex; align-items: center; justify-content: center;
  cursor: pointer; color: #a59f90; flex-direction: column;
}
.ref-card { position: relative; width: 80px; height: 80px; border-radius: 8px; overflow: hidden; }
.ref-card img, .ref-card video { width: 100%; height: 100%; object-fit: cover; }
.ref-badge {
  position: absolute; bottom: 4px; left: 4px;
  background: rgba(0,0,0,0.6); color: #fff; font-size: 12px;
  padding: 1px 5px; border-radius: 3px;
}
.ref-x {
  position: absolute; top: 4px; right: 4px;
  background: rgba(0,0,0,0.6); border: 0; color: #fff; cursor: pointer;
  width: 20px; height: 20px; border-radius: 50%; padding: 0;
  display: flex; align-items: center; justify-content: center;
}
.ref-anon-spinner {
  position: absolute; inset: 0; background: rgba(255,255,255,0.85);
  display: flex; align-items: center; justify-content: center;
  font-size: 12px; color: #6b614e;
}
.ref-upscale-tag {
  position: absolute; bottom: 4px; right: 4px;
  background: rgba(247,107,28,0.92); color: #4a3f1a;
  font-size: 10px; padding: 1px 5px; border-radius: 3px; font-weight: 650;
}
.video-prompt-input { width: 100%; padding: 8px; border-radius: var(--radius-ctl);
  border: 1px solid #d4cdb8; font-size: 14px; resize: vertical; }
.video-templates { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
.template-chip {
  font-size: 12px; padding: 3px 10px; border: 1px solid #d4cdb8;
  background: #fff; border-radius: 999px; cursor: pointer; color: #6b614e;
}
.template-chip:hover { background: #f5f0e1; }
.mention-menu {
  position: fixed; background: #232228; border: 1px solid #4a4750;
  border-radius: 8px; box-shadow: 0 6px 20px rgba(0,0,0,0.55);
  z-index: 1000; min-width: 120px; padding: 4px;
}
.mention-item {
  padding: 8px 14px; cursor: pointer;
  color: #f0ead8; font-size: 14px; font-weight: 400;
  border-radius: 6px;
}
.mention-item:hover { background: #f76b1c; color: #1a1814; }
.cost-estimate { font-size: 14px; color: #6b614e; margin-bottom: 8px; }
.gen-modal-video-area {
  width: 100%; height: 100%;
  display: flex; align-items: center; justify-content: center;
  background: #1a1814; border-radius: 8px;
}
.gen-modal-video { max-width: 100%; max-height: 100%; border-radius: 8px; }
.gen-modal-video-waiting {
  text-align: center; color: #a59f90;
}
.gen-modal-waiting-icon { font-size: 64px; margin-bottom: 12px; }
.gen-modal-waiting-tip { font-size: 12px; opacity: 0.7; margin-top: 4px; }
.gen-modal-counter.video-mode { font-size: 32px; }
.gen-modal-counter.video-mode.is-fail { color: #e5484d; }
/* 视频生成失败：modal 画面里显示中文原因 */
.gen-modal-video-fail {
  max-width: 560px; text-align: center; padding: 32px;
  color: #e8e2d0;
}
.gen-modal-video-fail .vfail-icon {
  width: 56px; height: 56px; line-height: 56px; margin: 0 auto 16px;
  border-radius: 50%; background: rgba(229,72,77,0.15);
  color: #e5484d; font-size: 28px; font-weight: 650;
}
.gen-modal-video-fail .vfail-title {
  font-size: 20px; font-weight: 650; color: #e5484d; margin-bottom: 12px;
}
.gen-modal-video-fail .vfail-reason {
  font-size: 14px; line-height: 1.7; color: #e8e2d0; text-align: left;
  background: rgba(255,255,255,0.04); border: 1px solid rgba(255,255,255,0.1);
  border-radius: 8px; padding: 14px 16px; margin-bottom: 14px;
}
.gen-modal-video-fail .vfail-raw-wrap { text-align: left; }
.gen-modal-video-fail .vfail-raw-wrap summary {
  cursor: pointer; font-size: 12px; color: #a59f90; user-select: none;
}
.gen-modal-video-fail .vfail-raw {
  font-size: 12px; color: #8a8276; word-break: break-all;
  margin-top: 8px; font-family: var(--mono, ui-monospace, SFMono-Regular, Menlo, monospace);
}
.video-status-banner {
  display: flex; align-items: center; gap: 8px;
  background: #fff3ea; border: 1px solid #f76b1c; border-radius: 6px;
  padding: 10px 12px; font-size: 14px; color: #6b614e;
  margin-bottom: 10px;
}
.video-status-spinner {
  display: inline-block; width: 14px; height: 14px;
  border: 2px solid #d4cdb8; border-top-color: #f76b1c;
  border-radius: 50%; animation: spin .8s linear infinite;
}
/* 视频缩略图容器与图片 <a> 容器对齐：固定 220px 高 + 居中 + 黑底 */
.history-thumb-wrap {
  position: relative;
  height: 220px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  background: #0a0a0a; overflow: hidden;
}
.history-thumb.video-thumb {
  cursor: pointer; display: block;
  width: 100%; height: 100%;
  object-fit: contain;
}
.video-play-overlay {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  font-size: 32px; color: rgba(255,255,255,0.9); pointer-events: none;
  text-shadow: 0 1px 4px rgba(0,0,0,0.5);
}

/* ===== 风格蒸馏 / 视频生成 · 即梦式大输入卡板式（jm-*） =====
   居中问候标题 + 980px 大卡 + 卡底胶囊工具条 + 金色圆形生成钮；
   胶囊下拉复用 .dd / .dd-panel / .dd-opt。（历史抽屉 2026-08-05 已删，看历史走左侧导航「历史」页）*/
.workspace-hero { flex-direction: column; }
.workspace-hero > .panel { width: 100%; max-width: none; }
.jm-panel {
  background: none; border: none; box-shadow: none;
  padding: clamp(40px, 9vh, 110px) 0 24px;
}
/* 限宽到跟卡片/页签同一条轴（2026-08-05）：原来标题不限宽、占满 986，卡片是 980 居中，
   两者左边缘差 3px —— 差得不够多，看着就是"没对齐"而不是"有意缩进" */
.jm-title { text-align: center; font-size: 32px; font-weight: 650; letter-spacing: 1px; margin: 0 auto 36px; max-width: 980px; }
.jm-title:has(+ .jm-sub) { margin-bottom: 11px; }   /* 有副标时标题收紧，不动换装/视频的无副标标题 */
/* 无副标的 tab（标题直接接页签）补出等高的副标位 → 5 个 tab 表头同高、切换时输入卡不再上下跳 */
.jm-title:has(+ .mod-tabs) { margin-bottom: 63px; }
/* 两行式大标题（换装/裂变）：行距收紧成一块，下间距相应回收，表头总高与单行 tab 基本持平 */
.jm-title-2l { line-height: 1.34; }
/* 标题里的核心词：品牌橙 + 极淡橙光晕（宁淡勿重，别盖过黑投影的可读性） */
.jm-title .jm-hl { color: var(--accent); text-shadow: 0 2px 4px rgba(0,0,0,.7), 0 0 22px rgba(247,107,28,.32); }
.jm-title-2l:has(+ .mod-tabs) { margin-bottom: 40px; }
/* 副标题恒 1 行（窄屏不换行致下方位移）；过长截断省略 */
.jm-sub { text-align: center; font-size: 14px; color: var(--muted); margin: 0 auto 52px; max-width: 980px; line-height: 1.6; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* ===== 方案 C「高对比效率」（2026-08-05 老板选定）=====
   问题：橙色同时代表三件事（模式选中 / 只读标注 / 主按钮），眼睛不知道看哪；
        控件半透明叠在渐变背景上，透出底纹 → 显脏。
   做法：控件改实底深灰（不再半透明，背景纹理透不上来）、值一律纯白、圆角收小到 8px，
        橙色只留给「主操作」这一件事，并做成全站最重的一块。 */
.jm-card {
  max-width: 980px; margin: 0 auto; position: relative;
  background: #16161a; border: 1px solid rgba(255,255,255,.06);
  border-radius: 14px; padding: 24px 24px 16px;
  box-shadow: 0 20px 60px rgba(0,0,0,.5);
  transition-property: var(--t-props); transition-duration: .15s; transition-timing-function: ease;
}
/* 即梦式板块页签 · B1 精装版：互叠档案夹贴卡顶，悬停轻浮起，选中升高 + 顶沿品牌色发丝线 */
.mod-tabs { display: flex; max-width: 980px; margin: 0 auto; position: relative; }
.mod-tab {
  flex: 1; position: relative; z-index: 1; border: none; cursor: pointer; text-align: center;
  margin-bottom: -14px; padding: 14px 0 28px;
  background: rgba(255,255,255,.045);
  color: var(--muted); font-size: 14px; font-weight: 650;
  border-radius: 22px 22px 0 0;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.05);   /* 顶部内高光：玻璃质感 */
  transition: transform .15s ease, background .15s, color .15s;
}
.mod-tab + .mod-tab { margin-left: -10px; }           /* 页签轻微互叠，档案夹感 */
.mod-tab:hover:not(.on) { color: var(--fg); background: rgba(255,255,255,.08); transform: translateY(-3px); }
.mod-tab.on {
  /* 实色 ≈ 深底 + 4% 白，与半透明卡片视觉一致；选中页签必须不透明才能和卡片无缝接 */
  background: #1b1b1f; color: var(--fg); z-index: 3; font-weight: 650;
  transform: translateY(-5px); padding-bottom: 33px;
  box-shadow: 0 -10px 30px rgba(0,0,0,.3), inset 0 1px 0 rgba(255,255,255,.07);
}
.mod-tab.on::before {                                  /* 顶沿一根品牌色发丝线 */
  content: ''; position: absolute; top: 0; left: 22%; right: 22%; height: 2px;
  border-radius: 99px; background: var(--accent); opacity: .85;
}
svg.lucide.mod-ico { width: 19px; height: 19px; margin-right: 7px; vertical-align: -4px; }  /* 页签品牌图标(方案B双色)，盖过 svg.lucide 的 1em */
.mod-tabs--dense svg.lucide.mod-ico { width: 16px; margin-right: 6px; }                     /* 收缩态略小 */
.mod-badge {
  display: none; margin-left: 8px; font-size: 10px; font-weight: 650; vertical-align: 2px;
  background: var(--accent-soft); color: var(--accent); border-radius: 999px; padding: 2px 8px;
}
.mod-tab.on .mod-badge { display: inline-block; animation: modBadgePop .38s cubic-bezier(.34,1.56,.64,1); }
@keyframes modBadgePop { from { opacity: 0; transform: scale(.5); } to { opacity: 1; transform: scale(1); } }
.mod-tabs + .jm-card { border-top-left-radius: 0; border-top-right-radius: 0; z-index: 2; }
/* 切板块时标题/卡片淡入（v-if 重建 DOM，挂载即播一次） */
.jm-title { animation: jmSwapIn .32s ease; }
.jm-card { animation: jmSwapIn .32s ease; }
@keyframes jmSwapIn { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
/* 收缩态/用量页小条版：不塞卡片后面，独立小页签（保持轻量，不带升降/角标） */
.mod-tabs--dense { margin: 0 0 12px; max-width: 560px; gap: 4px; }
.mod-tabs--dense .mod-tab { padding: 8px 0 9px; margin-bottom: 0; font-size: 12px; border-radius: 10px; box-shadow: none; }
.mod-tabs--dense .mod-tab + .mod-tab { margin-left: 0; }
.mod-tabs--dense .mod-tab:hover:not(.on) { transform: none; }
.mod-tabs--dense .mod-tab.on { background: var(--accent); color: #1a1300; transform: none; padding-bottom: 9px; box-shadow: none; }
.mod-tabs--dense .mod-tab.on::before { display: none; }
.mod-tabs--dense .mod-badge { display: none !important; }
/* 视频生成「未开放」锁已移除（2026-07-12）：擦除/视频放开给会员用，与其它 tab 一致，不再限管理员。 */
.jm-card:focus-within { border-color: var(--accent-ring); box-shadow: 0 18px 60px rgba(0,0,0,.4), 0 0 0 3px var(--accent-soft); }

/* 上传缩略图（斜置）+ 参考素材条 */
.jm-body { display: flex; gap: 18px; align-items: flex-start; flex-wrap: wrap; min-height: 124px; }
.jm-thumb {
  flex: 0 0 auto; width: 96px; height: 122px; border-radius: 10px; cursor: pointer;
  border: 1.5px dashed var(--border-strong); background: rgba(255,255,255,.03);
  display: flex; align-items: center; justify-content: center;
  transform: rotate(-6deg); margin: 4px 6px 0 2px; position: relative;
  transition: border-color .15s, transform .15s;
}
.jm-thumb:hover { border-color: var(--accent-ring); transform: rotate(-3.5deg) scale(1.02); }
.jm-thumb-empty { text-align: center; }
.jm-plus { display: block; font-size: 28px; line-height: 1; color: var(--muted); font-weight: 400; }
.jm-thumb-label { font-size: 12px; color: var(--muted); margin-top: 4px; }
.jm-thumb.has-img { border-style: solid; }
.jm-thumb.has-img img { width: 100%; height: 100%; object-fit: cover; border-radius: 11px; display: block; }
.jm-thumb-x {
  position: absolute; top: -8px; right: -8px; width: 20px; height: 20px; border-radius: 50%;
  border: none; background: #2a2a2e; color: var(--muted); cursor: pointer;
  display: flex; align-items: center; justify-content: center; padding: 0;
}
.jm-thumb-x svg.lucide { width: 11px; height: 11px; }
.jm-thumb-x:hover { color: var(--fg); }
.jm-refs { display: flex; gap: 10px; align-items: flex-start; flex-wrap: wrap; margin-top: 8px; }

/* 主输入 */
.jm-input {
  flex: 1; min-width: 280px; min-height: 110px; resize: none; align-self: stretch;
  background: transparent; border: none; outline: none; box-shadow: none; color: var(--fg);
  font: inherit; font-size: 14px; line-height: 1.7; padding: 12px 4px 0;
}
.jm-input:focus { background: transparent; border: none; box-shadow: none; }
.jm-input::placeholder { color: var(--muted); opacity: .55; }
/* 文字列：商品名 + 补充要求纵向叠放（2026-08-24）。
   ⚠ 加这一列是为了【修排版】：商品名输入框若直接放进 .jm-body 就会强制换行，
     补充要求被顶到第三行、产品图右边整片空着、卡片高出一整行（真机量过）。 */
.jm-textcol { flex: 1 1 0; min-width: 280px; display: flex; flex-direction: column; gap: 8px; align-self: stretch; }

/* 买家秀「这单卖的是什么」。两条都【真机量过是载重的】，别顺手删：
   · min-height:0   —— 不写就吃 .jm-input 的 min-height:110px，单行输入框被撑成 110px 高
   · flex:0 0 auto  —— 不写就吃 .jm-input 的 flex:1，在纵向列里被拉高，跟补充要求平分高度
   ⚠ 外观（背景/边框/40px 高）来自站点通用的 input[type="text"]，优先级(0,1,1)高过本类(0,1,0)——
     所以这里【不要】再写 height/padding，写了也是死的，只会骗下一个读代码的人。 */
.jm-subject { min-height: 0; flex: 0 0 auto; }

/* 胶囊工具条 */
/* 桌面强制单行（2026-08-05）：原来 flex-wrap:wrap + 输入框 flex-grow:1 —— 输入框吃光剩余空间，
   把右下角的提交圆钮顶到下一行（换装页控件最多，模型名一长必翻车）。
   nowrap 后空间不够时由输入框先收缩（它有 flex-shrink 和 min-width 兜底），圆钮始终留在这一行。
   窄屏(≤860px)在下面的 media 里恢复 wrap，那儿 .jm-right 本来就整行靠右。 */
/* 底部控件行：主区被批量抽屉挤窄时必须能换行，否则「生成」按钮会甩出卡片外被切掉
   （2026-08-08 实测：卡片 665px 时溢出 154px，生成按钮超出卡片 129px）。
   ★ 逐宽度量过再改，不是拍脑袋：≥860px 加不加 wrap **完全一样**（高 43、零溢出），
     ≤760px 现状溢出 59~359px、加 wrap 全部归零。没有任何一档变差。
   （对照：同日 .vb-focus-head 加 wrap 反而在 560px 就把按钮踢到第二行，已否决——
     wrap 不是万灵药，必须逐档量。） */
/* 0812 老板红线「生成按钮不许被挤到第二排」：toolbar 本体不再 wrap——
   chips 全托进 .jm-chips 自己换行，.jm-right（点数+生成）是并列列永远钉右。 */
.jm-toolbar { display: flex; align-items: center; gap: 7px; margin-top: 12px; }
.jm-chips { display: flex; align-items: center; gap: 7px; row-gap: 8px; flex-wrap: wrap; flex: 1 1 auto; min-width: 0; }
/* 方案 C：实底深灰（半透明会透出背景渐变→显脏）、圆角 8、标签灰值纯白 */
.jm-pill {
  display: inline-flex; align-items: center; gap: 6px;
  background: #1d1d22; border: 1px solid rgba(255,255,255,.08);
  border-radius: 8px; padding: 9px 13px; color: #fff;
  font: inherit; font-size: 14px; font-weight: 650; cursor: pointer; white-space: nowrap;
  transition-property: var(--t-props); transition-duration: .15s; transition-timing-function: ease;
}
.jm-pill:hover { border-color: rgba(255,255,255,.2); background: #24242a; }
/* 只读信息胶囊（搜推固定模型标注）：不可点就不该抢眼 —— 灰底灰字。
   全站规则（2026-08-05 老板点名"不用选择的就不要加颜色"）：
     灰 = 可选参数 / 只读信息    橙 = 已选中的值 / 要花钱的强提示
   之前它是橙色亮态，比旁边真正要选的「比例」「参考主图」还跳，主次颠倒。 */
.jm-pill--ro { cursor: default; color: var(--muted); border-color: var(--border); background: rgba(255,255,255,.03); }
.jm-pill--ro:hover { border-color: var(--border); background: rgba(255,255,255,.03); }

/* 生成比例分段控件（3:4 默认 / 1:1）：紧凑，选中态主色实底 */
/* 高度对齐参数排其它 pill（2026-08-05 实测：pill 40px、这个 35px、按钮 42px，三种高度看着就参差） */
.sm-ratio { display: inline-flex; align-items: center; height: 40px; gap: 3px; padding: 0 3px; border: 1px solid var(--border); border-radius: var(--radius-ctl); background: var(--surface-ctl); }
.sm-ratio-lbl { font-size: 12px; color: var(--fg); opacity: .55; padding: 0 3px 0 6px; white-space: nowrap; }
.sm-ratio-btn { border: 0; background: transparent; color: var(--fg); font: inherit; font-size: 14px; padding: 5px 11px; border-radius: 10px; cursor: pointer; transition: background .15s, color .15s; }
.sm-ratio-btn:hover { background: rgba(255,255,255,.07); }
/* 方案 C：模式切换（自由创作/高点击率复刻）是「我现在在哪个模式」的强状态，恢复实心橙；
   而搜推那个「比例 3:4|1:1」是普通参数，下面单独降回淡橙——同一个类两种角色，按场景分开 */
.sm-ratio-btn.on { background: var(--accent); color: #150e04; font-weight: 650; }
.sm-ratio:not(.ff-mode) .sm-ratio-btn.on { background: var(--accent-soft); color: var(--accent); font-weight: 650; }
/* 参考主图位置下拉（第1-5张）：贴合分段控件外框，紧凑 */
.sm-pos-sel { border: 0; background: transparent; color: var(--fg); font: inherit; font-size: 14px; padding: 5px 6px; border-radius: 10px; cursor: pointer; }
.sm-pos-sel:hover { background: rgba(255,255,255,.07); }
.sm-pos-sel option { background: var(--bg); color: var(--fg); }
/* 参考主图确认条：读完候选主图先确认/换第几张再出图；缩略图点选与工具栏下拉联动 */
/* 限宽对齐 jm-card（0812 两阶段给确认条加了参数区变高之后，满宽横跨整屏太突兀） */
.sm-pick { max-width: 980px; margin: 10px auto 0; padding: 13px 14px; border: 1px solid var(--accent-ring); border-radius: 14px; background: var(--accent-soft); }
.sm-pick-tip { font-size: 12px; color: var(--fg); opacity: .85; margin-bottom: 10px; }
.sm-pick-tip b { color: var(--accent); }
.sm-pick-row { display: flex; gap: 10px; flex-wrap: wrap; align-items: flex-start; }
.sm-pick-item { position: relative; width: 96px; cursor: pointer; border: 2px solid transparent; border-radius: 10px; overflow: hidden; background: rgba(255,255,255,.05); transition: border-color .15s, transform .12s; }
.sm-pick-item:hover { transform: translateY(-2px); }
.sm-pick-item.on { border-color: var(--accent); }
.sm-pick-item img { width: 96px; height: 96px; object-fit: cover; display: block; }
.sm-pick-item i { position: absolute; left: 0; right: 0; bottom: 0; font-style: normal; font-size: 12px; text-align: center; padding: 3px 0; background: rgba(0,0,0,.55); color: #fff; }
.sm-pick-item.on i { background: var(--accent); font-weight: 650; }
.sm-pick-act { display: flex; gap: 10px; margin-top: 11px; align-items: center; }
.sm-pick-go { border: none; background: var(--accent); color: #fff; font: inherit; font-size: 14px; font-weight: 650; padding: 8px 18px; border-radius: 999px; cursor: pointer; transition: filter .15s; }
.sm-pick-go:hover { filter: brightness(1.1); }
.sm-pick-go:disabled { opacity: .55; cursor: default; }
.sm-pick-cancel { border: none; background: transparent; color: var(--muted); font: inherit; font-size: 12px; cursor: pointer; padding: 8px 10px; }
.sm-pick-cancel:hover { color: var(--fg); }

/* 搜推素材输入列（上传框右侧）：上=贴链接(主·大块) / 细分线 / 下=补充要求(次·单行更矮字更小) */
.sm-input-col { flex: 1; min-width: 280px; align-self: stretch; display: flex; flex-direction: column; }
.sm-input-col .jm-input { min-width: 0; width: 100%; }
.sm-input-col .sm-link-input { flex: 1; min-height: 64px; }
/* 次要输入降一档（2026-08-05）：它跟上面的主输入原来同为 14px 灰字，视觉权重一样，
   两行并排看不出哪个是必填。降到 12px 后主次一眼分明。 */
.sm-extra-input {
  flex: none; min-height: 38px; height: 38px; line-height: 38px;
  padding: 0 4px; font-size: 12px;
}
.sm-extra-input::placeholder { opacity: .45; }

/* 搜推素材抓图期间的醒目状态横幅：替代灰色小字，点 ↑ 后立刻可见，免得顾客以为没反应 */
.sm-grab-banner {
  display: flex; align-items: center; justify-content: center; gap: 10px;
  max-width: 980px; margin: 16px auto 0; padding: 12px 18px;
  background: var(--accent-soft); border: 1px solid var(--accent-ring); border-radius: 12px;
  color: var(--accent); font-size: 14px; font-weight: 650;
}
.sm-grab-spin { width: 18px; height: 18px; margin: 0; flex: none; }            /* 横幅内联 spinner */
.jm-send-spin { width: 20px; height: 20px; margin: 0; border-color: rgba(255,255,255,.18); border-top-color: var(--accent); }  /* ↑ 按钮转圈（禁用态灰底上用橙顶才看得清）*/

/* 搜推素材结果区顶对齐：盖掉 .gen-modal-main 的 align-items:center。
   否则内容超过弹窗高度时会被垂直居中，顶部（坑位切换条）溢出到可视区上方且滚不回去。 */
.gen-modal-sm { align-self: flex-start; width: 100%; }

/* 搜推素材结果：坑位切换条 + 按套展示（9 张图当场重组 1/2/3 套，每套配文案） */
.sm-slot-bar { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin: 2px 2px 14px; }
.sm-slot-lbl { font-size: 14px; color: var(--muted); }
.sm-slot-btn { display: flex; flex-direction: column; align-items: center; gap: 1px; line-height: 1.15;
  background: rgba(255,255,255,.04); border: 1px solid var(--border); border-radius: 10px; padding: 6px 14px;
  color: var(--fg); font: inherit; font-size: 14px; cursor: pointer; transition: border-color .15s, background .15s; }
.sm-slot-btn:hover { border-color: var(--border-strong); }
.sm-slot-btn.on { border-color: var(--accent-ring); background: var(--accent-soft); color: var(--accent); }
.sm-slot-sub { font-size: 10px; opacity: .7; }
/* 2026-08-17 排版修：margin-left:auto 是「把第一颗推到右边」用的——同一条 bar 里再来一颗
   .sm-copy-btn 会各吃一个 auto、把空间劈成两段（老板截图抓的「重写文案悬在半路」）。
   兄弟选择器把后续几颗的 auto 关掉，靠 bar 的 gap:8px 挨着排。 */
.sm-slot-bar .sm-copy-btn ~ .sm-copy-btn { margin-left: 0; }
/* 补问商品ID：紧凑一行靠右，贴着上面的同步钮（08-17 老板嫌原来那坨「位置很怪」）。
   这里的 .sm-copy-btn 不在 slot-bar 里 → 单独关掉它的 auto 边距。 */
/* 商品 ID 补问框。08-25 老板：「排版太丑」。真机量过根因——输入框吃了全局 .jm-input 的
   min-width:280 / min-height:110，又被容器规则给成 flex:1 → 实测被撑成 410×110，
   而且 border:none + 背景全透明，看着不像输入框、像一段飘着的占位文字；整行被顶到 110px 高，
   旁边两颗按钮才 38px，怎么看怎么歪。⚠ min-* 压过 width/height，必须显式清零——同上面
   .ffr-save-name 那条注释记的是同一个坑。
   改后实测：整行 860×110 → 595×60，输入框 240×36，整块收成一张右对齐的小卡贴在
   「上传到搜推素材」正下方（反馈落在点击处附近，与 08-25「框弹到屏幕外」同一口径）。 */
.sm-sync-ask { display: flex; align-items: center; gap: 10px; justify-content: flex-end; flex-wrap: wrap;
  width: fit-content; margin: 6px 2px 12px auto; padding: 10px 12px;
  border: 1px solid var(--border); border-radius: 10px; background: rgba(255, 255, 255, .03); }
.sm-sync-ask > span { color: var(--text-2, #aaa); font-size: 13px; }
.sm-sync-ask .jm-input { flex: 0 0 240px; width: 240px; min-width: 0; min-height: 0;
  height: 36px; box-sizing: border-box; margin: 0; padding: 6px 14px;
  background: rgba(255, 255, 255, .05); border: 1px solid rgba(255, 255, 255, .14);
  border-radius: 999px; font-size: 13px; color: var(--fg); }
.sm-sync-ask .jm-input::placeholder { color: rgba(255, 255, 255, .35); }
.sm-sync-ask .jm-input:focus { outline: none; border-color: var(--accent-ring); }
.sm-sync-ask .sm-copy-btn { margin-left: 0; }
.sm-sync-ask-err { flex: 0 0 100%; text-align: right; color: #e5684f; }
/* 保存命名框（08-18 二合一）：常驻工具条、胶囊态与旁边按钮呼应，占位=默认名。
   ⚠ 必须钉死 flex：工具条语境有规则给 input 上 flex:1（实测撑到 457px 把整条挤换行），
   且此处吃不到 jm-input 的边框底色——全部显式写。 */
.fz-breview-toolbar .ffr-save-name { flex: 0 0 220px; width: 220px; margin: 0;
  align-self: center; height: 34px; box-sizing: border-box;   /* 不钉高会吃 bar 的 stretch 撑成大胶囊（实测 90px 高） */
  min-width: 0; min-height: 0;   /* ⚠ 全局 .jm-input 带 min-width:280/min-height:110，min-* 压过 height/width，必须清零 */
  background: rgba(255, 255, 255, .05); border: 1px solid rgba(255, 255, 255, .14);
  border-radius: 999px; padding: 6px 12px; font-size: 13px; color: var(--fg); }
.fz-breview-toolbar .ffr-save-name::placeholder { color: rgba(255, 255, 255, .35); }
.fz-breview-toolbar .ffr-save-name:focus { outline: none; border-color: var(--accent-ring); }
.sm-copy-btn { margin-left: auto; display: inline-flex; align-items: center; gap: 6px;
  background: rgba(255,255,255,.04); border: 1px solid var(--border); border-radius: 10px; padding: 8px 14px;
  color: var(--fg); font: inherit; font-size: 14px; cursor: pointer; transition: border-color .15s; }
.sm-copy-btn:hover:not(:disabled) { border-color: var(--accent-ring); }
.sm-copy-btn:disabled { opacity: .5; cursor: not-allowed; }
.sm-copy-btn svg.lucide { width: 15px; height: 15px; }
.sm-set { border: 1px solid var(--border); border-radius: 12px; padding: 12px; margin-bottom: 12px; background: rgba(255,255,255,.02); }
.sm-set-head { font-weight: 650; font-size: 14px; margin-bottom: 8px; color: var(--fg); }
.sm-set-hint { color: var(--muted); font-weight: 400; margin-left: 6px; font-size: 12px; }
/* ── 文案生成中（2026-08-27 老板圈图重做）──
   原来：套 .sm-set 大卡片（那是给「3 份切换 + 正文」用的），里面只有一行字 → 下方空一片；
        .spinner 是 22px + margin:0 auto 8px 的【居中大转圈】，塞进一行文字里必然撑高错位。
   现在：一条紧凑的独立行 + 不确定进度条。
   ⚠ 进度条刻意做成【不确定】的来回跑，不画百分比 —— 后端根本不回进度，
     画个假的百分比就是在撒谎，跟「未上报不冒充 0」是同一条规矩。 */
.sm-copy-wait { display:flex; align-items:center; gap:10px; flex-wrap:wrap;
  border:1px solid var(--border); border-radius:12px; padding:10px 12px; margin-bottom:12px;
  background:rgba(255,255,255,.02); }
.sm-copy-wait .sm-slot-lbl { flex:none; }
.sm-copy-wait-txt { color:var(--muted); font-size:12px; flex:1 1 auto; min-width:180px; }
.sm-copy-wait-sec { color:var(--fg); font-variant-numeric:tabular-nums; }
.sm-copy-track { flex:none; width:120px; height:4px; border-radius:2px; overflow:hidden;
  background:var(--border); position:relative; }
.sm-copy-track i { position:absolute; left:0; top:0; bottom:0; width:38%; border-radius:2px;
  background:var(--accent); animation:smCopySlide 1.4s ease-in-out infinite; }
@keyframes smCopySlide { 0%{left:-38%} 100%{left:100%} }
@media (prefers-reduced-motion: reduce){ .sm-copy-track i{ animation:none; left:0; width:100% ; opacity:.5} }
.sm-set-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 190px)); gap: 8px; margin-bottom: 10px; }
.sm-set-grid a { display: block; }
/* 外站素材网格（2026-08-25）：张数不定（实测 6/7 张都有），不能套 .sm-set-grid 那套
   写死 3 列×190px —— 那是给九宫格 3×3 定制的，总宽卡在 590px，卡片右边空一大片
   （老板 08-25 截图点名）。这里按容器宽度自适应铺满，列数随宽度走。 */
.sm-outer-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(170px, 1fr)); gap: 8px; margin-bottom: 10px; }
.sm-outer-grid img { width: 100%; aspect-ratio: 3 / 4; object-fit: cover; border-radius: 7px; display: block; cursor: zoom-in; }
/* 素材与文案左右分栏（08-25 老板要）：左＝抓回来的图/视频，右＝3 份文案。
   原来上下堆着，选第 2/3 份文案时素材已经滚出屏幕——「对着素材挑文案」这件事根本做不了。
   ⚠ 分栏里必须把缩略图最小宽 170 → 140：不收的话 6 张图在 491px 的左栏里掉成 2 列 3 行，
     左栏 950px 高而右栏只有 250px，右下大片空白且还是得滚（08-25 真机量过这一版才改的）。
   ⚠ 只剩一块时（文案还没出来 / 文案生成失败）退回单列，否则素材被压成半幅、右边空着。
   ⚠ 窄屏回落上下：两栏各半宽以后图和正文都挤成条。 */
.sm-outer-split { display: grid; grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr); gap: 12px; align-items: start; }
.sm-outer-split > .sm-set { margin-bottom: 0; }
.sm-outer-split .sm-outer-grid { grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); margin-bottom: 0; }
.sm-outer-split:has(> .sm-set:only-child) { grid-template-columns: minmax(0, 1fr); }
@media (max-width: 900px) { .sm-outer-split { grid-template-columns: minmax(0, 1fr); } }
.sm-set-grid img { width: 100%; border-radius: 7px; display: block; }
.sm-set-copy { border-top: 1px dashed var(--border); padding-top: 8px; }
.sm-copy-title { font-weight: 650; margin-bottom: 3px; font-size: 14px; }
.sm-copy-body { white-space: pre-wrap; font-size: 12px; color: #bbb; line-height: 1.6; }
.sm-copy-topics { color: #f76b1c; font-size: 12px; margin-top: 4px; }
.sm-set-copy--empty { color: var(--muted); font-size: 12px; border-top: none; padding-top: 0; }
.jm-pill.open { border-color: var(--accent-ring); box-shadow: 0 0 0 3px var(--accent-soft); }
.jm-caret { font-size: 10px; opacity: .5; }
.jm-badge { background: var(--accent-soft); color: var(--accent); border-radius: 8px; font-size: 12px; padding: 1px 6px; font-weight: 650; }
.jm-pill-sep { width: 1px; height: 14px; background: var(--border-strong); }
.jm-dim { color: var(--muted); }
.jm-toggle.on { border-color: var(--accent-ring); color: var(--accent); background: var(--accent-soft); }
.jm-dd-hint { margin: 4px 6px 4px; font-size: 12px; color: var(--muted); line-height: 1.5; }
.jm-dd-divider { border-top: 1px solid var(--border); margin: 4px 4px; }

/* 右侧：总张数/预估 + 圆形生成钮 */
.jm-right { margin-left: auto; display: flex; align-items: center; gap: 12px; }
.jm-total { font-size: 14px; color: var(--muted); white-space: nowrap; }
.jm-total b { color: var(--fg); font-weight: 650; }
.jm-spark { color: var(--accent); margin-right: 3px; }
.jm-pt-sep { margin: 0 6px; color: var(--border-strong); }   /* 张数 · 点数 之间的分隔点 */
/* 方案 C：圆箭头 → 带字的方按钮，做成全站最重的一块（实心橙 + 橙投影）。
   圆钮不带字、靠位置暗示，新顾客不知道点哪；带字才说得清下一步。 */
.jm-send {
  height: 42px; padding: 0 22px; border-radius: 8px; border: none; cursor: pointer; flex: none;
  background: #f76b1c; color: #150e04;
  font-size: 14px; font-weight: 650; font-family: inherit;
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  box-shadow: 0 4px 16px rgba(247,107,28,.32);
  transition-property: var(--t-props); transition-duration: .15s; transition-timing-function: ease;
}
.jm-send:hover:not(:disabled) { transform: translateY(-1px); box-shadow: 0 10px 28px rgba(247,107,28,.35); }
.jm-send:disabled { background: rgba(255,255,255,.08); color: var(--muted); box-shadow: none; cursor: not-allowed; }
.jm-send-sec { font-size: 12px; font-weight: 650; }

/* 卡下提示行 */
.jm-hint { max-width: 980px; margin: 14px auto 0; text-align: center; color: var(--muted); opacity: .7; font-size: 12px; }
.jm-hint.warn { color: #f76b1c; opacity: 1; }

/* 视频生成状态条在卡内占整行 */
.jm-card .video-status-banner { margin-top: 12px; }

@media (max-width: 860px) {
  .jm-panel { padding-top: 28px; }
  .jm-title { font-size: 28px; margin-bottom: 22px; }
  .jm-card { padding: 16px 14px 12px; }
  .mod-tab { font-size: 12px; padding: 10px 0 24px; }
  .mod-ico { display: none; }
  .jm-toolbar { flex-wrap: wrap; }     /* 窄屏放开换行：控件挤不下时分行，别把输入框压成一条缝 */
  .jm-right { margin-left: 0; width: 100%; justify-content: flex-end; }
}

/* ===== 批量换装 · 模特图批量区（jm-persons，空位常驻虚线格） ===== */
.jm-persons {
  flex: 1; align-self: stretch; min-width: 280px; min-height: 124px; cursor: pointer; border-radius: 10px;
  display: flex; flex-wrap: wrap; gap: 10px; align-content: flex-start; align-items: flex-start;
  padding: 10px 4px 6px; transition: background .15s;
}
.jm-persons:hover { background: rgba(255,255,255,.02); }
.jm-person-card { position: relative; width: 74px; height: 96px; border-radius: 10px; border: 1px solid var(--border-strong); overflow: hidden; cursor: default; }
.jm-person-card img { width: 100%; height: 100%; object-fit: cover; display: block; }
.jm-person-tag { position: absolute; top: 5px; left: 5px; background: rgba(0,0,0,.55); border-radius: 5px; font-size: 10px; padding: 1px 5px; color: #eee; }
.jm-person-x {
  position: absolute; top: 4px; right: 4px; width: 17px; height: 17px; border-radius: 50%;
  border: none; background: rgba(0,0,0,.55); color: #ccc; cursor: pointer; padding: 0;
  display: flex; align-items: center; justify-content: center;
}
.jm-person-x svg.lucide { width: 10px; height: 10px; }
.jm-person-x:hover { color: #fff; background: rgba(0,0,0,.75); }
.jm-person-slot {
  width: 74px; height: 96px; border-radius: 10px; border: 1.5px dashed var(--border-strong);
  background: rgba(255,255,255,.02); color: var(--muted);
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px;
  transition: border-color .15s;
}
.jm-persons:hover .jm-person-slot { border-color: var(--accent-ring); }
.jm-slot-plus { font-size: 20px; line-height: 1; font-weight: 400; }
.jm-slot-label { font-size: 10px; color: var(--muted); opacity: .7; }
.jm-persons-hint { width: 100%; order: 9; margin: 4px 0 0; color: var(--muted); opacity: .6; font-size: 12px; line-height: 1.6; pointer-events: none; }
/* hover 联动：鼠标停在某张产品卡上时给模特区一圈高光，强调「这一款会作用到下面全部模特」（理解层 T8） */
.jm-persons-lit { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 12px; }

/* 活等式：款 × 模特 × 张数 = 总张数（≥2 款才现身，理解层 T8） */
.jm-times-row { flex: 0 0 100%; display: flex; align-items: center; justify-content: center; gap: 10px; margin: 2px 0; }
.jm-times { font-size: 28px; line-height: 1; color: var(--muted); font-weight: 400; }
.jm-equation { font-size: 14px; color: var(--muted); line-height: 1.6; text-align: center; }
.jm-equation b { color: var(--fg); font-weight: 650; }

/* ===== 批量换装 · 产品款式图区（jm-products，可多张：每张=一个款=一组图） ===== */
/* 视觉沿用模特图区那套（同尺寸卡 + 虚线加位），只是宽度按内容收，别把模特区挤没 */
.jm-products {
  flex: 0 1 auto; align-self: stretch; min-width: 116px; max-width: 40%; min-height: 124px;
  cursor: pointer; border-radius: 10px;
  display: flex; flex-wrap: wrap; gap: 10px; align-content: flex-start; align-items: flex-start;
  padding: 10px 4px 6px; transition: background .15s;
}
.jm-products:hover { background: rgba(255,255,255,.02); }
.jm-product-card { position: relative; width: 74px; height: 96px; border-radius: 10px; border: 1px solid var(--border-strong); overflow: hidden; cursor: default; }
.jm-product-card img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* 预检标签（只提示不控制）：压在图上要读得清，所以深底 + accent 淡色调叠一层
   （单用 --accent-soft 透明度太高，压在花色产品图上看不出字） */
/* 单行截断：标签最长 10 个中文字，74px 宽的卡上必换行，换行就顶到上面的 ⚙ 角标里去 */
.jm-prod-garment {
  position: absolute; left: 4px; right: 4px; bottom: 4px;
  padding: 2px 4px; border-radius: 5px; text-align: center;
  font-size: 12px; line-height: 1.25; color: var(--fg);
  background-color: rgba(0,0,0,.62);
  background-image: linear-gradient(var(--accent-soft), var(--accent-soft));
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* 「加款」位：比模特空位窄一截，让人一眼看出这块是产品款式，不是又一排模特 */
.jm-prod-slot { width: 52px; }
.jm-products:hover .jm-prod-slot { border-color: var(--accent-ring); }
/* 一个款都没有时的空态：还原原来那块「产品款式图」虚线格的尺寸 */
.jm-products .jm-thumb-empty {
  width: 96px; height: 122px; border-radius: 12px;
  border: 1.5px dashed var(--border-strong); background: rgba(255,255,255,.03);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  transition: border-color .15s;
}
.jm-products:hover .jm-thumb-empty { border-color: var(--accent-ring); }

/* ===== 批量换装 · 逐款 ⚙ 单独设置（背景/动作微调，2026-07-30） ===== */
/* ⚙ 按钮：贴在删除叉正下方，沿用 .jm-person-x 的圆形小按钮尺寸与 hover */
.jm-prod-gear {
  position: absolute; top: 25px; right: 4px; width: 17px; height: 17px; border-radius: 50%;
  border: none; background: rgba(0,0,0,.55); color: #ccc; cursor: pointer; padding: 0;
  display: flex; align-items: center; justify-content: center;
}
.jm-prod-gear svg.lucide { width: 10px; height: 10px; }
.jm-prod-gear:hover { color: var(--accent); background: rgba(0,0,0,.75); }
/* 改过 ⚙ 的角标：文字直接说改了什么。压在图上要读得清，深底 + accent 淡层（同 .jm-prod-garment）；
   有预检标签时自动垫高一层（~ 兄弟选择器，没标签就贴底，不留空档） */
.jm-prod-tweak {
  position: absolute; left: 4px; right: 4px; bottom: 4px;
  padding: 2px 4px; border-radius: 5px; text-align: center;
  font-size: 10px; line-height: 1.25; color: var(--accent);
  background-color: rgba(0,0,0,.62);
  background-image: linear-gradient(var(--accent-soft), var(--accent-soft));
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.jm-prod-garment ~ .jm-prod-tweak { bottom: 25px; }
/* 补充要求输入框：跟胶囊同高同底，塞在参数条里当一格 */
.jm-note-input {
  /* 基准宽 180→140（2026-08-05）：换装那排 6 个 pill(663) + 输入框(180) + 右侧(50) + 7 个 gap(49)
     = 942 > 卡片可用宽 930，把提交圆钮挤到了下一行。降到 140 后 902，留 28px 余量；
     有富余时 flex-grow 照样把它撑开，窄屏可收缩到 120。 */
  flex: 1 1 140px; min-width: 120px; height: 35px;
  background: var(--surface-ctl); border: 1px solid var(--border); border-radius: 12px;
  color: var(--fg); font: inherit; font-size: 14px; padding: 0 12px; outline: none;
  transition: border-color .15s, background .15s;
}
.jm-note-input:focus { border-color: var(--accent-ring); background: rgba(255,255,255,.07); box-shadow: none; }
.jm-note-input::placeholder { color: var(--muted); opacity: .6; }
/* 逐款设置浮层：居中小弹窗（点背板即关） */
.jm-prod-pop {
  position: fixed; inset: 0; z-index: 1000; background: var(--scrim);
  display: flex; align-items: center; justify-content: center;
}
.jm-prod-pop-card {
  width: min(360px, 92vw); display: flex; flex-direction: column; gap: 10px;
  padding: 18px 20px; border-radius: var(--radius-card); border: 1px solid var(--border);
  background: var(--surface-pop);   /* 原来底上刷了层橙渐变——不代表选中也不代表主操作，纯装饰，去掉 */
  box-shadow: 0 24px 60px rgba(0,0,0,.55);
}
.jm-prod-pop-card > b { font-size: 14px; color: var(--fg); }
.jm-prod-pop-card > small { font-size: 12px; color: var(--muted); margin-top: -6px; }
.jm-prod-pop-card label {
  display: flex; align-items: center; gap: 10px; font-size: 14px; color: var(--muted);
}
.jm-prod-pop-card select, .jm-prod-pop-card input {
  flex: 1; min-width: 0; height: 34px;
  background: rgba(255,255,255,.04); border: 1px solid var(--border); border-radius: 10px;
  color: var(--fg); font: inherit; font-size: 14px; padding: 0 10px; outline: none;
}
.jm-prod-pop-card select:focus, .jm-prod-pop-card input:focus { border-color: var(--accent-ring); box-shadow: none; }
.jm-prod-pop-card select option { background: var(--bg-base); color: var(--fg); }
.jm-prod-pop-card > .jm-pill { align-self: flex-end; margin-top: 4px; }

/* ===== 批量换装 · 开跑确认单 + 批次抽屉行动作（2026-07-30） ===== */
/* 确认单沿用 ⚙ 浮层的卡底（.jm-prod-pop / .jm-prod-pop-card），这里只放加宽 + 列表滚动 */
.jm-confirm-card { width: min(460px, 94vw); }
.jm-confirm-list { display: flex; flex-direction: column; gap: 8px; max-height: min(46vh, 380px); overflow: auto; padding-right: 2px; }
.jm-confirm-row {
  display: grid; grid-template-columns: 38px minmax(0, 1fr) auto; align-items: center; gap: 10px;
  padding: 7px 8px; border: 1px solid var(--border); border-radius: 10px; background: rgba(255,255,255,.03);
}
.jm-confirm-row img { width: 38px; height: 50px; border-radius: 7px; object-fit: cover; display: block; background: rgba(255,255,255,.08); }
.jm-confirm-row > b { font-size: 12px; color: var(--fg); white-space: nowrap; }
.jm-confirm-mid { min-width: 0; display: flex; flex-direction: column; gap: 2px; font-size: 12px; color: var(--fg); }
.jm-confirm-tweak { color: var(--muted); font-size: 12px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.jm-confirm-warn { color: #fca5a5; font-size: 12px; line-height: 1.5; margin: 0; }
.jm-confirm-total { margin: 0; font-size: 14px; color: var(--fg); }
.jm-confirm-btns { display: flex; align-items: center; justify-content: flex-end; gap: 10px; margin-top: 2px; }
/* 「明白,开跑」「开跑 N 个款」：.jm-send 本体是 50px 圆按钮，装不下字 → 这两处撑成胶囊（单款那颗圆 ↑ 不动） */
/* 方案 C：基础钮已经是带字方按钮，这两个变体只需跟上圆角，不再单独设胶囊形 */
.jm-confirm-go, .jm-send--multi {
  width: auto; height: 42px; border-radius: 8px; padding: 0 20px; font-size: 14px; font-weight: 650;
}
/* 抽屉行右列：状态胶囊 + 行内动作按钮竖排（行不是 button，所以按钮能直接放进去） */
.jm-tb-act { display: flex; flex-direction: column; align-items: flex-end; gap: 6px; }

/* ===== 链接裂变 · 空态即梦式贴链接卡 ===== */
.jm-body--bar { min-height: 64px; align-items: center; flex-wrap: nowrap; gap: 12px; padding: 4px 6px 0; }
.jm-link-ico { font-size: 20px; opacity: .8; flex: none; }
.jm-input--line { min-height: auto; height: 44px; padding: 0 4px; line-height: 44px; font-size: 20px; }
.jm-prog { color: var(--accent); opacity: 1; }
/* 裂变空态面板沿用 jm-panel 透明化；选图阶段恢复 fz-panel 原样 */
.fz-panel.jm-panel .fz-title-row { display: none; }
/* 干掉全局 input[type=text] 的盒样式（特异性持平靠后置胜出），保持卡内无缝观感 */
input.jm-input--line, input.jm-input--line:focus {
  background: transparent; border: none; box-shadow: none; outline: none; border-radius: 0;
}
.ct-mask { position: fixed; inset: 0; background: var(--scrim); z-index: 850; }  /* 850/855 > genModal backdrop(800)：从生成弹窗内点「传图片空间」也能盖在其上，否则面板被遮=点了没反应 */
.ct-panel {
  position: fixed; top: 0; right: 0; height: 100vh; width: min(540px, 94vw); z-index: 855;
  background: var(--surface-pop); border-left: 1px solid var(--border);
  box-shadow: -14px 0 44px rgba(0,0,0,.5); overflow-y: auto; padding: 18px 22px 30px;
  animation: ctSlideIn .22s ease;
}
@keyframes ctSlideIn { from { transform: translateX(60px); opacity: 0; } to { transform: none; opacity: 1; } }
.ct-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 14px; }
.ct-head h2 { margin: 0; font-size: 14px; font-weight: 650; }
.ct-head-sub { font-size: 12px; color: var(--muted); font-weight: 400; }
/* .ct-x 走浮层关闭键公共件 */
/* 输入框不再自己写一套：底/边/圆角/高全部继承全局 input[type=text]（--surface-ctl + --radius-ctl + --h-md）。
   原来这一屏是 4%白半透底 + #1b1b1f + 圆角 8/10/12 + 高 37/46 各写各的 */
.ct-link { outline: none; margin-bottom: 14px; }
.ct-link:focus { border-color: var(--accent-ring); box-shadow: none; }
.ct-row { display: flex; gap: 10px; align-items: center; background: var(--card); border: 1px solid var(--border);
  border-radius: var(--radius-card); padding: 10px; margin-bottom: 10px; }
.ct-thumb { width: 52px; height: 66px; border-radius: 8px; overflow: hidden; flex: none; }
.ct-thumb.sq { height: 52px; }
.ct-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.ct-ar { flex: none; font-size: 12px; font-weight: 650; background: rgba(255,255,255,.07); border-radius: 6px; padding: 2px 7px; }
.ct-ar.a11 { color: #8ec9ff; } .ct-ar.a34 { color: #9be29b; } .ct-ar.a23 { color: #e2b69b; }
.ct-ar.bad { color: #ef8989; }
.ct-dim { font-size: 12px; color: var(--muted); flex: none; }
.ct-slot { flex: 1; min-width: 0; box-sizing: border-box; background: var(--surface-ctl); border: 1px solid var(--border-strong); border-radius: var(--radius-ctl);
  color: var(--fg); font: inherit; font-size: 14px; height: var(--h-md); padding: 0 12px; outline: none; }
.ct-del { background: none; border: none; color: var(--muted); cursor: pointer; font-size: 14px; flex: none; }
.ct-del:hover { color: var(--fg); }
.ct-add { border: 1.5px dashed var(--border-strong); border-radius: var(--radius-ctl); padding: 12px; text-align: center;
  color: var(--muted); opacity: .8; font-size: 12px; cursor: pointer; margin-top: 12px; transition: border-color .15s; }
.ct-add:hover { border-color: var(--accent-ring); }
/* 主按钮跟全站主按钮同一套：实底 accent，不是这里单开的橙渐变 */
.ct-go { margin-top: 16px; width: 100%; height: var(--h-md); padding: 0; border: none; border-radius: var(--radius-ctl); cursor: pointer;
  background: var(--accent); color: #1a1300; font: inherit; font-size: 14px; font-weight: 650; }
.ct-go:disabled { background: rgba(255,255,255,.08); color: var(--muted); cursor: not-allowed; }
.ct-note { margin-top: 10px; font-size: 12px; color: var(--muted); opacity: .75; line-height: 1.7; text-align: center; }

/* 角落工具：传图片空间补充（命名输入 / 文件夹行 / 进度行金色） */
.ct-name { flex: 1; min-width: 0; outline: none; }   /* 其余继承全局 input[type=text] */
.ct-name:focus { border-color: var(--accent-ring); box-shadow: none; }
.ct-folder { display: flex; align-items: center; gap: 10px; margin-top: 14px; }
.ct-prog { color: var(--accent); opacity: 1; }
/* ===== 当日创作页：一天一页，时间线排图 ===== */
/* 创作历史页（导航平级 tab）：主区记录流，自身滚动 */
.hist-view { height: calc(100vh - 56px); overflow-y: auto; padding: 4px 8px 40px; }
/* 板块筛选条：sticky 在历史流最顶（z 高过日期头），日期头 top 顺移到其下方 */
.hist-title { max-width: 1080px; margin: 4px auto 10px; font-size: 20px; font-weight: 650; letter-spacing: .5px; color: var(--fg); }
.hist-filter { position: sticky; top: 0; z-index: 6; max-width: 1080px; margin: 0 auto; padding: 8px 0; background: rgba(14,14,16,.5); backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px); display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }  /* 真毛玻璃：地球背景透出来，不再是实心黑块 */
.hist-keep-hint { font-size: 12px; color: var(--muted); }  /* 保留期须知（对应服务器 retention 3 天） */
.hist-day { margin-bottom: 34px; }
.hist-day-head { font-size: 20px; font-weight: 650; margin: 0 auto 18px; max-width: 1080px; display: flex; align-items: baseline; gap: 10px; position: sticky; top: 44px; z-index: 5; padding: 10px 0; background: rgba(14,14,16,.5); backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px); }
.hist-day-head span { font-size: 12px; font-weight: 650; color: var(--muted); }
.hist-load { text-align: center; color: var(--muted); font-size: 12px; padding: 18px 0 30px; }
.day-empty { margin: 120px auto; text-align: center; color: var(--muted); font-size: 14px; }
.day-empty-t { margin-bottom: 14px; }
.day-empty-cta { font-size: 14px; padding: 8px 18px; border-radius: 999px; cursor: pointer; font-family: inherit;
  background: var(--accent-soft); border: 1px solid var(--accent-ring); color: var(--accent);
  transition-property: var(--t-props); transition-duration: .15s; transition-timing-function: ease; }
.day-empty-cta:hover { background: rgba(247,107,28,.2); }
.day-line { max-width: 1080px; margin: 0 auto; display: flex; flex-direction: column; gap: 30px; }
.day-node { display: grid; grid-template-columns: 120px 1fr; gap: 18px; }
.day-time { position: relative; padding-left: 18px; }
.day-time::before { content: ''; position: absolute; left: 0; top: 7px; width: 9px; height: 9px; border-radius: 50%; background: var(--accent); box-shadow: 0 0 0 4px var(--accent-soft); }
.day-time::after { content: ''; position: absolute; left: 4px; top: 26px; bottom: -30px; width: 1px; background: var(--border); }
.day-node:last-child .day-time::after { display: none; }
.day-time b { display: block; font-size: 14px; }
.day-time span { display: block; font-size: 12px; color: var(--muted); margin-top: 3px; line-height: 1.5; }
/* 历史页商品ID（2026-07-21）：.day-time span 已是 block+小字+muted，这里只补可点复制的手感 */
/* 10.5px + nowrap：时间列可用宽仅 102px，11.5px 下「商品 887766554433」要 108px 会折成
   「商品」「887766554433」两行（实测）。10.5px 需 98px 刚好单行；更长的ID 至多溢出进 18px 列间隙，不压图 */
.day-itemid { cursor: pointer; font-variant-numeric: tabular-nums; font-size: 10px; white-space: nowrap; }
.day-itemid:hover { color: var(--accent); text-decoration: underline; }
.day-time .day-upload-truth { display: inline-block; width: max-content; max-width: 112px; padding: 2px 6px; margin-top: 5px;
  border: 1px solid var(--border); border-radius: 999px; font-size: 10px; line-height: 1.35; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.day-upload-truth.ok { color: #64d99a !important; border-color: rgba(72,199,132,.35) !important; background: rgba(39,150,96,.12); }
.day-upload-truth.partial { color: #f4bc61 !important; border-color: rgba(232,163,55,.38) !important; background: rgba(175,112,25,.12); }
.day-upload-truth.fail { color: #ff7474 !important; border-color: rgba(235,80,80,.38) !important; background: rgba(170,45,45,.12); }
.day-upload-truth.unknown { color: var(--muted) !important; }
/* 商品ID 搜索框：贴在筛选 chips 右侧，与保留期须知同排（margin-left:auto 把两者一起推到右边） */
.hist-search { position: relative; display: flex; align-items: center; flex: none; margin-left: auto; }
.hist-search-input { width: 148px; height: var(--h-md); padding: 0 12px; border-radius: 999px; border: 1px solid var(--border); background: rgba(0,0,0,.25); color: var(--fg); font-size: 12px; outline: none; }
.hist-search-input::placeholder { color: var(--muted); }
.hist-search-input:focus { border-color: var(--accent-ring); }
.hist-search-x { position: absolute; right: 7px; border: 0; background: none; color: var(--muted); cursor: pointer; font-size: 14px; line-height: 1; padding: 2px; }
.hist-search-x:hover { color: var(--fg); }
/* 搜索态下日期 chip 置灰：搜商品ID 跨全部日期，与「只看今天」互斥 */
.pill:disabled { opacity: .38; cursor: not-allowed; }
.day-grid { display: flex; gap: 10px; flex-wrap: wrap; }
.day-grid img { height: 200px; width: auto; border-radius: 12px; border: 1px solid var(--border); cursor: zoom-in; background: rgba(0,0,0,.3); }  /* 统一高、宽随原图比例（1:1/3:4/2:3 原样不裁） */
.day-grid img:hover { border-color: var(--accent-ring); }
/* 视频格（2026-07-17 视频进历史）：与图同高同圆角，宽随视频比例；控制条自带播放/下载 */
.day-vid { height: 200px; width: auto; max-width: 356px; border-radius: 12px; border: 1px solid var(--border); background: rgba(0,0,0,.3); }
.day-vid:hover { border-color: var(--accent-ring); }
/* 旧竖版用户区（.as-user 一套）已删（2026-06-12）：宽侧栏不存在了，残留的 align-self:flex-start
   还把窄轨头像顶去左边 16px；点数胶囊/头像样式现统一走下面 rail2 一套 */
/* 创作历史组操作（取代旧抽屉）：时间列下小按钮竖排 */
/* 历史页组操作钮（2026-08-22 老板：「保存到本地这个按钮有点丑」，四版比稿选的 A）：
   原来是实描边+填充底的按钮，宽度被 120px 的时间列撑满 ≈ 88px —— 一个次要动作的视觉
   重量压过了旁边的时间和小字。改成幽灵态：去描边去底、左对齐、静息用次要灰，鼠标停上去
   才变亮，跟旁边的时间小字回到同一视觉层。
   ⚠ border 留 1px transparent 占位，不然 hover 加边会跳一下。
   ⚠ hover 不再用品牌橙：橙只留给「已选中的值」和主操作（老板 08-05 定的，
      「不用选择的就不要加颜色」）。 */
.day-acts { display: flex; flex-direction: column; gap: 6px; margin-top: 10px; }
.day-act { font-size: 12px; font-weight: 650; padding: 4px 0; border-radius: 8px; border: 1px solid transparent; background: none; color: var(--muted); cursor: pointer; text-align: left; white-space: nowrap; font-family: inherit; }
.day-act:hover { color: var(--fg); }

/* ===== 左侧栏 V2（方案A 即梦式极简窄轨）===== */
/* 2026-06-12 用户反馈"左边logo都太小"：轨72→80、logo34→42、图标19→23、头像32→38 整体放大一档 */
.app-side.rail2 { width: 80px; padding: 14px 0 12px; align-items: center; }
/* logo 可点回创作：明显的金色波纹环 + 弹跳（金=品牌金，跟侧栏系列统一；2026-06-13 加强可见度——
   光晕加在金 logo 上同色融掉看不见，改用实描边圆环从 logo 扩散） */
.rv-logo-btn { position: relative; flex: 0 0 auto; display: block; border: none; background: none;
  padding: 0; margin-bottom: 7px; cursor: pointer; border-radius: 10px; }
.rv-logo { display: block; transition: transform .15s cubic-bezier(.34, 1.56, .64, 1); }
.rv-logo-btn:hover .rv-logo { transform: scale(1.08); }
.rv-logo-btn:active .rv-logo { transform: scale(.9); }
/* 点击：金色圆环从 logo 边缘向外扩散淡出（明显的金色动向）+ logo 明显弹一下 */
.rv-logo-btn::after { content: ''; position: absolute; inset: -3px; border-radius: 15px;
  border: 2.5px solid var(--accent); opacity: 0; pointer-events: none; }
.rv-logo-btn.pulse::after { animation: rvLogoRing .6s ease-out; }
.rv-logo-btn.pulse .rv-logo { animation: rvLogoFlash .6s ease; }
@keyframes rvLogoRing {
  0%   { opacity: .95; transform: scale(.7); }
  100% { opacity: 0;   transform: scale(1.6); }
}
@keyframes rvLogoFlash {
  0%, 100% { transform: scale(1); }
  35%      { transform: scale(1.14); }
}
/* 工具名+版本两行（2026-06-12 找回：窄轨改版时随旧品牌行丢了） */
.rv-meta { display: flex; flex-direction: column; align-items: center; gap: 2px; margin-bottom: 14px; cursor: default; }
.rv-meta b { font-size: 10px; font-weight: 650; color: var(--fg); letter-spacing: 1px; }
.rv-meta span { font-size: 10px; color: var(--muted); letter-spacing: .4px; }
.rv-it { position: relative; display: flex; flex-direction: column; align-items: center; gap: 5px; width: 100%; padding: 10px 0; border: none; background: none; color: var(--muted); cursor: pointer; font-family: inherit; }
.rv-it i { font-style: normal; line-height: 1; display: flex; }
.rv-svg { width: 23px; height: 23px; display: block; transition: transform .15s cubic-bezier(.34, 1.56, .64, 1); }   /* 统一线性图标，currentColor 随三态变色 2026-06-22 */
.rv-it span { font-size: 12px; letter-spacing: .5px; transition: transform .15s cubic-bezier(.34, 1.56, .64, 1); }
.rv-it:hover { color: var(--fg); }
.rv-it.on { color: var(--accent); }                                  /* 激活态金色（SVG currentColor 随之变金，不再靠 emoji 光晕 hack） */
.rv-it:active .rv-svg { transform: scale(1.2); }                     /* 方案C 点击 pop：按下放大、松开弹性回 */
.rv-it:active span { transform: scale(1.08); }
.rv-it::before { content: ''; position: absolute; left: 7px; top: 50%; width: 3px; height: 26px; border-radius: 2px;   /* 方案C 选中态：左侧橙竖条 */
  background: var(--accent); transform: translateY(-50%) scaleY(0); transition: transform .15s cubic-bezier(.34, 1.56, .64, 1); }
.rv-it.on::before { transform: translateY(-50%) scaleY(1); }
/* 「面板开着」的高亮，两颗按钮两套口径（2026-08-12 老板拆开）：
   · 任务面板：挪到「创作」正下方，展开态直接走 .rv-it.on 橙高亮 + 下面那条橙底批章。
     08-05「面板开≠在这页、不许同色」+ 08-10「灰底加重」两版旧口径就此让位——只让这一颗。
   · 自动插件：还是 panel-on 灰底这套（⚠ 08-10 加重过：原 .14 放大 2 倍才看得出，别调回去）。
   钉子在 batch_panel.test.js / fission-batch.test.js。 */
.rv-it.panel-on { color: var(--fg); }
.rv-it.panel-on i { background: rgba(255,255,255,.14); border-radius: 9px; padding: 4px; margin: -4px; }
.fz-batch-nav-btn i{position:relative;width:28px;height:28px;align-items:center;justify-content:center}
.fz-batch-nav-ico{width:28px;height:28px;border-radius:9px;display:flex;align-items:center;justify-content:center;background:rgba(255,255,255,.035);border:1px solid var(--border);color:var(--muted);font-size: 14px;font-weight: 650;letter-spacing:0}
/* 展开态橙底批章：逐字回抄 2026-06-28 在产验过的那条（d54dbd7），深字 #1a1300 是橙底上唯一看得清的字色 */
.fz-batch-nav-btn.on .fz-batch-nav-ico{background:var(--accent);color:#1a1300;border-color:var(--accent)}
.fz-batch-nav-btn b{position:absolute;right:-7px;bottom:-5px;min-width:18px;height:18px;padding:0 5px;border-radius:999px;display:flex;align-items:center;justify-content:center;background:var(--accent);color:#1a1300;font-size:10px;line-height:18px;box-shadow:0 4px 12px rgba(0,0,0,.35)}
.rv-sp { flex: 1; }
.rail2 .as-points { display: inline-flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px; border: 1px solid rgba(247,107,28,.35); background: var(--accent-soft); color: var(--accent); padding: 5px 12px; border-radius: 10px; cursor: pointer; font-family: inherit; margin-bottom: 12px; transition: background .15s, border-color .15s; }
.rail2 .as-points:hover { background: rgba(247,107,28,.22); border-color: rgba(247,107,28,.55); }
.rail2 .as-points .pt-num { font-size: 12px; font-weight: 650; line-height: 1.1; }
.rail2 .as-points .pt-rc { font-size: 10px; font-weight: 400; line-height: 1; opacity: .82; letter-spacing: .3px; }
.rail2 .as-points[hidden] { display: none; }
.rail2 .as-avatar { width: 38px; height: 38px; border-radius: 50%; border: 1px dashed var(--border-strong); background: var(--panel-strong); margin-bottom: 12px; flex: 0 0 auto; }
/* .rv-ico（轨上📊⚙️）已删（2026-06-12）：与头像菜单「用量与账单/设置」重复 */
.rv-dot { width: 9px; height: 9px; border-radius: 50%; background: #2ea043; box-shadow: 0 0 7px #2ea043; margin-top: 8px; flex: 0 0 auto; }
/* 左侧栏固定常显（2026-06-13）：原 @media(max-width:900px) 隐藏 rail2 的规则已去 */

/* —— 公网延迟登录：匿名态弱化 —— */
body.ps-anon .as-auth-only { display: none !important; }   /* 匿名藏历史(及其内的收藏) */
.as-avatar.as-login-btn {                                  /* 头像壳 → 「登录/注册」引导按钮 */
  position: relative; overflow: visible;                   /* 给右上角赠点角标定位（.as-avatar 某些态带 overflow:hidden，这里显式放开） */
  width: 62px; height: 44px;                               /* rail2 宽 80px，左右各余 9px */
  display: flex; align-items: center; justify-content: center;
  font-size: 12px; font-weight: 650; line-height: 1.15; text-align: center;
  color: #fff; background: linear-gradient(135deg, #FF8A3D, #F76B1C);   /* 跟品牌 logo 同一套橙 */
  cursor: pointer; border: none; border-radius: 10px;
  box-shadow: 0 5px 14px rgba(247, 107, 28, .34);
  transition: transform .15s cubic-bezier(.34, 1.56, .64, 1), box-shadow .15s;
}
.as-avatar.as-login-btn .as-login-gift {                   /* 赠点钩子：右上角金色角标 */
  position: absolute; top: -7px; right: -7px;
  padding: 3px 4.5px; border-radius: 7px; white-space: nowrap;
  background: linear-gradient(135deg, #ffd479, #f2a13a); color: #3a2000;
  font-size: 10px; font-weight: 650; line-height: 1; letter-spacing: .2px;
  box-shadow: 0 2px 6px rgba(0, 0, 0, .4);
}
.as-avatar.as-login-btn:hover { transform: translateY(-2px); box-shadow: 0 8px 20px rgba(247, 107, 28, .46); }

/* ===== 大牌风格蒸馏画廊（自由生图板 · 方案A 按品类分组）===== */
.gal { margin: 72px auto 0; max-width: 1080px; }   /* 跨功能区大间距：操作区和素材区之间要有断点，否则一屏 60 多个元素全挤成一坨、分不出哪些是一伙的（2026-08-05）*/   /* 居中收宽：防宽屏卡片过大、跟创作列对齐 */
.gal-group { margin-bottom: 26px; }
.gal-group:last-child { margin-bottom: 0; }
.gal-grp-h { font-size: 14px; font-weight: 650; color: #cfcfd6; margin: 2px 0 12px; display: flex; align-items: center; gap: 8px; }
.gal-grp-h::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: var(--accent); }
.gal-grp-n { font-size: 12px; color: #7d7d86; font-weight: 400; }
.gal-head { display: flex; align-items: center; gap: 11px; margin-bottom: 18px; flex-wrap: wrap; }
/* 竖线改成挂在文字左外侧（绝对定位不占位）：原来它占 4px + 11px gap，
   把品牌区文字整体推到 110px，偏离主轴 15px —— 竖线是装饰，不该带着文字跑 */
.gal-head { position: relative; }
.gal-bar { position: absolute; left: -15px; top: 3px; width: 4px; height: 21px; border-radius: 2px;
           background: linear-gradient(#ff8a3d, #f76b1c); flex: none; }
.gal-h2 { font-size: 20px; font-weight: 650; margin: 0; color: #fff; letter-spacing: .3px; }
.gal-badge { font-size: 12px; font-weight: 650; color: #f9a25e; background: rgba(247, 107, 28, .13); border: 1px solid rgba(247, 107, 28, .28); padding: 2px 9px; border-radius: 20px; }
.gal-sub { color: #8a8a92; font-size: 14px; margin-left: auto; }
.gal-grid { display: grid; grid-template-columns: repeat(5, 1fr); gap: 16px; }
@media (max-width: 1000px) { .gal-grid { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 600px) { .gal-grid { grid-template-columns: repeat(2, 1fr); } }
.gal-card { position: relative; border-radius: 14px; overflow: hidden; cursor: default; border: 1.5px solid rgba(255, 255, 255, .08); background: #1a1a1f; transition: transform .15s, border-color .15s; aspect-ratio: 3 / 4; }
.gal-card img { width: 100%; height: 100%; object-fit: cover; object-position: top center; display: block; transition-property: var(--t-props); transition-duration: .45s; }
.gal-card:hover img { transform: scale(1.05); }
.gal-card:hover { border-color: rgba(247, 107, 28, .55); transform: translateY(-3px); }
.gal-card-ov { position: absolute; inset: auto 0 0 0; padding: 34px 14px 13px; background: linear-gradient(transparent, rgba(0, 0, 0, .9)); pointer-events: none; }
.gal-card-bn { font-size: 20px; font-weight: 650; color: #fff; letter-spacing: .3px; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.gal-card-cat { display: inline-block; margin-top: 7px; font-size: 12px; font-weight: 650; color: #f9b87f; background: rgba(247, 107, 28, .18); border: 1px solid rgba(247, 107, 28, .4); padding: 2px 9px; border-radius: 11px; }
.gal-card-hover { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 9px; opacity: 0; transition-property: var(--t-props); transition-duration: .15s; background: rgba(10, 10, 12, .5); }
.gal-card:hover .gal-card-hover { opacity: 1; }
.gal-card-act { background: rgba(247, 107, 28, .95); border: none; color: #fff; font-size: 14px; padding: 8px 18px; border-radius: 22px; font-weight: 650; cursor: pointer; transition: background .15s; }
.gal-card-act:hover { background: #ff7d33; }
.gal-card-act--ghost { background: rgba(255, 255, 255, .1); border: 1px solid rgba(255, 255, 255, .4); }
.gal-card-act--ghost:hover { background: rgba(255, 255, 255, .2); }
.jm-pill--ghost { color: #9a9aa3; cursor: default; opacity: .75; }

/* 参考图多图上传（自由生图板）—— 用独立 .jm-up，避免和 video tab 的 .jm-refs 撞 */
.jm-up { display: flex; gap: 8px; flex-wrap: wrap; align-items: flex-start; }
.jm-up-item { position: relative; width: 88px; height: 110px; border-radius: 11px; overflow: hidden; border: 1px solid var(--border-strong); flex: none; }
.jm-up-item img { width: 100%; height: 100%; object-fit: cover; display: block; }
.jm-up-x { position: absolute; top: -7px; right: -7px; width: 20px; height: 20px; border-radius: 50%; border: none; background: #2a2a2e; color: var(--muted); cursor: pointer; display: flex; align-items: center; justify-content: center; padding: 0; }
.jm-up-x svg.lucide { width: 11px; height: 11px; }
.jm-up-x:hover { color: var(--fg); }
.jm-up-add { width: 88px; height: 110px; border-radius: 10px; border: 1.5px dashed var(--border-strong); background: rgba(255,255,255,.03); cursor: pointer; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px; flex: none; transition: border-color .15s; }
.jm-up-add:hover { border-color: var(--accent-ring); }
.jm-up-add .jm-plus { font-size: 28px; }
.jm-up-add .lbl { font-size: 12px; color: var(--muted); }
.jm-up-add .jm-opt { font-size: 10px; color: var(--muted); opacity: .6; margin-top: -3px; }   /* 「选填」：参考图下方更小更淡的次提示 */

/* @ 引用图 picker（自由生图板）—— teleport 到 body，浮在光标边上 */
.at-chip { cursor: pointer; }
.at-pick { position: fixed; z-index: 900; display: flex; flex-direction: column; gap: 3px; background: var(--surface-pop); border: 1px solid var(--border-strong); border-radius: var(--radius-ctl); padding: 6px; box-shadow: 0 12px 32px rgba(0,0,0,.5); max-width: 240px; }
.at-pick-empty { font-size: 12px; color: var(--muted); padding: 4px 6px; }
.at-pick-item { display: flex; align-items: center; gap: 8px; background: transparent; border: none; border-radius: var(--radius-ctl); padding: 5px 12px 5px 5px; cursor: pointer; color: var(--fg); font-size: 14px; text-align: left; }
.at-pick-item:hover { background: rgba(255,255,255,.07); }
.at-pick-item img { width: 30px; height: 30px; border-radius: 6px; object-fit: cover; display: block; }

/* ===== 本地保存三态控件 ===== */
.ls-modes { display: flex; gap: 8px; margin-top: 10px; }
.ls-mode {
  flex: 1; padding: 8px 10px; border-radius: 10px; cursor: pointer;
  background: var(--panel-2, #1b1e24); color: var(--ink, #e6e8ec);
  border: 1px solid var(--line, #333a45); font-size: 14px; transition-property: var(--t-props); transition-duration: .15s; transition-timing-function: ease;
}
.ls-mode:hover:not(:disabled) { border-color: var(--brand, #f76b1c); }
.ls-mode.on { background: var(--brand, #f76b1c); color: #fff; border-color: var(--brand, #f76b1c); }
.ls-mode:disabled { opacity: .45; cursor: not-allowed; }
.ls-folder-row {
  display: flex; align-items: center; gap: 10px; margin-top: 10px;
  font-size: 14px; color: var(--muted, #8b909b);
}
.ls-folder-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* 自由生图比例选择器：横排比例小卡（暗色，跟工具栏一致；选中=品牌橙；形状按 w:h 缩略） */
.dd-panel--ratios { min-width: 250px; padding: 9px 11px 11px; }
.rg-lbl { font-size: 12px; color: var(--muted); margin: 1px 0 8px; }
.rg-grid { display: flex; flex-wrap: wrap; gap: 6px; }
.rg-btn { display: flex; flex-direction: column; align-items: center; justify-content: flex-end; gap: 5px; width: 52px; height: 54px; padding: 6px 0 5px; cursor: pointer; background: var(--card); border: 1px solid var(--border); border-radius: 10px; transition: border-color .12s, background .12s; }
.rg-btn:hover { border-color: var(--accent-ring); }
.rg-btn.on { border-color: var(--accent); background: var(--accent-soft); box-shadow: 0 0 0 2px var(--accent-ring); }
.rg-glyph { display: block; border: 1.6px solid var(--muted); border-radius: 3px; }
.rg-btn.on .rg-glyph { border-color: var(--accent); }
.rg-cap { font-size: 12px; line-height: 1; color: var(--fg); }
.rg-btn.on .rg-cap { color: var(--accent); font-weight: 650; }

/* ===== 批量裂变任务侧栏 ===== */
/* 2026-08-05：这个输入框原来自带半透明白底 + 边框 + 圆角，等于在卡片里又套了一层框，
   于是裂变页的卡片有两层底色，而其它四个板块的 .jm-input 是透明无框的 —— 同一个位置
   两套样式，老板一眼看出"版面有两个颜色"。现在拉平成跟 .jm-input 一样，融进卡片。 */
.fz-batch-input{width:100%;border:none;border-radius:0;padding:12px 4px 0;font-size: 14px;line-height:1.7;resize:vertical;outline:none;background:transparent;color:var(--fg)}
.fz-batch-input:focus{border:none;box-shadow:none}
/* 跟 .jm-send 同一套（方案 C）：原来这个按钮是圆角 10、无投影、单独一套尺寸 */
.fz-go-btn{background:#f76b1c;color:#150e04;border:0;border-radius: 8px;height:42px;padding:0 22px;font-size: 14px;font-weight: 650;cursor:pointer;box-shadow:0 4px 16px rgba(247,107,28,.32)}
.fz-go-btn:disabled{background:rgba(255,255,255,.08);color:var(--muted);box-shadow:none;cursor:default;opacity:1}
.fz-batch-side{
  position:fixed;left:94px;top:16px;bottom:16px;width:328px;z-index:42;
  display:flex;flex-direction:column;gap:12px;padding:14px;
  background:var(--surface-pop);border:1px solid var(--border);border-radius:var(--radius-card);
  box-shadow:0 24px 70px rgba(0,0,0,.42);
}
/* 头部一行塞不下就让右侧动作区整体掉到第二行，别去挤标题（2026-08-08 全量清查发现）：
   搜推头部有四件（20/20 完成 + 看全部 + 清空 + ×），标题被压到只剩 49px，
   「搜推批量」断成「搜推批 / 量」，连「看全部」自己都被压成竖排三个字——批次一跑完就这样。
   裂变/换装各两件、视频三件本来就装得下，wrap 永不触发 → 实测那三家零变化。 */
.fz-batch-head{display:flex;flex-wrap:wrap;align-items:flex-start;justify-content:space-between;gap:12px;border-bottom:1px solid var(--border);padding-bottom:12px}
.fz-batch-head>div:first-child{min-width:0;flex:1 1 auto}
.fz-batch-head b{display:block;font-size: 14px}
.fz-batch-head span{display:block;margin-top:3px;color:var(--muted);font-size:12px}
.fz-batch-head-actions{display:flex;align-items:center;gap:8px;flex:0 0 auto;margin-left:auto}
.fz-batch-head-actions button{white-space:nowrap}
/* 统一面板的板块标签条（2026-08-10）。计数用 <i>，不给颜色——
   它是身份标识不是状态，抢眼了会跟失败红字打架（同 .fz-task-kind 的理由）。 */
.fz-batch-tabs{display:flex;flex-wrap:wrap;gap:6px}
.fz-batch-tab{display:inline-flex;align-items:center;gap:4px;height:24px;padding:0 9px;
  font-size:11px;font-family:inherit;cursor:pointer;white-space:nowrap;
  color:var(--muted);background:transparent;border:1px solid var(--border-strong);border-radius:999px}
.fz-batch-tab:hover{color:var(--fg)}
/* 选中态用浅灰不用品牌橙（2026-08-22 老板「分类有点多」那一轮）：橙只留给「已选中的值」
   和主操作（08-05 拍的板），筛选器两样都不是；而且面板展开态本来就用浅灰高亮（08-10 拍的板），
   这里对齐。⛔ 别改回 var(--accent) 实底——那是一屏灰卡片里最重的一块颜色，压过了任务本身。 */
.fz-batch-tab.on{color:var(--fg);background:rgba(255,255,255,.13);border-color:rgba(255,255,255,.30);font-weight:650}
.fz-batch-tab i{font-style:normal;opacity:.7}
/* 「＋ 开新任务」卡（2026-08-22）：跟任务行同宽同圆角，虚线＝"这里还能再加一个"。
   ⚠ 刻意中性色不占品牌橙：它是次要入口，不该跟右下角「生成」抢视觉重量
   （同 .vb-reuse / .fz-task-row.busy 那两条注释里的同一条规矩）。 */
.fz-newtask-card{width:100%;display:flex;align-items:center;justify-content:center;gap:7px;
  border:1px dashed rgba(255,255,255,.24);background:transparent;color:var(--muted);
  border-radius:10px;padding:13px 8px;cursor:pointer;font-family:inherit;font-size:12.5px;font-weight:650}
.fz-newtask-card:hover{border-color:rgba(255,255,255,.42);color:var(--fg);background:rgba(255,255,255,.03)}
.fz-newtask-card span{font-size:15px;line-height:1}
.fz-batch-video-thumb{object-fit:cover;background:#111;pointer-events:none}
.fz-batch-head em{font-style:normal;color:#f9a76b;background:rgba(247,107,28,.12);border:1px solid rgba(247,107,28,.24);border-radius:999px;padding:4px 9px;font-size: 12px;font-weight: 650;white-space:nowrap}
/* .fz-batch-close 走浮层关闭键公共件（本板块里它还兼作「新建批次」的 + 键） */
.fz-batch-abandon{width:100%;min-height:var(--h-sm);border:1px solid rgba(235,100,100,.34);border-radius: var(--radius-ctl);background:rgba(177,52,52,.10);color:#f09a9a;font-size:12px;font-weight: 650;cursor:pointer}
.fz-batch-abandon:hover{border-color:rgba(235,100,100,.58);background:rgba(177,52,52,.18);color:#ffc0c0}
.fz-batch-abandon:disabled{opacity:.45;cursor:not-allowed}
.fz-batch-metrics{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px}
/* 「全部」档带「待处理」时是四格：三列会排成 3+1，最后一格独占一行拉满，看着像坏了 */
.fz-batch-metrics.m-4{grid-template-columns:repeat(2,minmax(0,1fr))}
.fz-batch-metrics span{background:rgba(255,255,255,.045);border:1px solid var(--border);border-radius:8px;padding:8px 9px;color:var(--muted);font-size: 12px}
.fz-batch-metrics b{color:var(--fg);font-size: 14px;margin-right:4px}
.fz-batch-gen-progress{display:flex;flex-direction:column;gap:7px;padding:2px 1px 4px}
.fz-batch-gen-progress>div{display:flex;align-items:center;justify-content:space-between;gap:10px;font-size: 12px}
.fz-batch-gen-progress b{color:var(--fg);font-size:12px}.fz-batch-gen-progress span{color:var(--muted)}
.fz-batch-gen-progress>i{display:block;height:7px;overflow:hidden;border-radius:999px;background:rgba(255,255,255,.10);font-style:normal}
.fz-batch-gen-progress>i>em{display:block;height:100%;border-radius:inherit;background:var(--accent);transition: width .6s ease}
.fz-batch-publish{display:grid;grid-template-columns:1fr;gap:8px;padding:10px;border:1px solid rgba(247,107,28,.22);border-radius:var(--radius-ctl);background:rgba(247,107,28,.07)}
.fz-title-opt{display:inline-flex;align-items:center;gap:7px;min-height:26px;color:#d6d6dc;font-size:12px;line-height:1.2;cursor:pointer;white-space:nowrap}
.fz-title-opt input{width:15px;height:15px;margin:0;accent-color:var(--accent);cursor:pointer}
.fz-racts>.fz-title-opt{margin-right:2px}
.fz-batch-pub-btn{height:36px;border-radius: 10px;border:1px solid var(--border-strong);background:rgba(255,255,255,.055);color:var(--fg);font-family:inherit;font-size: 12px;font-weight: 650;cursor:pointer}
.fz-batch-pub-btn.main{border-color:var(--accent);background:var(--accent);color:#1a1300}
.fz-batch-pub-btn:hover:not(:disabled){filter:brightness(1.06);transform:translateY(-1px)}
.fz-batch-pub-btn:disabled{opacity:.5;cursor:default;transform:none}
.fz-task-list{display:flex;flex-direction:column;gap:8px;overflow:auto;padding-right:2px}
.fz-task-row{width:100%;display:grid;grid-template-columns:40px minmax(0,1fr) auto;align-items:center;gap:10px;text-align:left;
  border:1px solid var(--border);background:rgba(255,255,255,.035);color:var(--fg);border-radius:10px;padding:8px;cursor:pointer;font-family:inherit}
.fz-task-row:hover{border-color:var(--border-strong);background:rgba(255,255,255,.06)}
/* 点下去到界面真的动之间是有间隔的：先播收回动画（实测约 300ms），裂变作为「前一条」被收回时
   还要先 await 一次存盘的网络往返。这段时间必须有反馈，否则顾客眼里就是个坏按钮
   （老板红线：所有点击都需要视觉反馈）。
   ⚠ 刻意不动 opacity：.fz-task-list.has-focus 那条已经在用 opacity 压退底行，两边抢同一个属性会打架。
   ⚠ 刻意不占品牌橙：橙色只留给「已选中的值」和主操作，这只是个「在忙」的过程态。 */
.fz-task-row.busy{cursor:progress;animation:fz-row-busy 1.1s ease-in-out infinite}
@keyframes fz-row-busy{
  0%,100%{background:rgba(255,255,255,.035);border-color:var(--border)}
  50%{background:rgba(255,255,255,.16);border-color:var(--border-strong)}}
/* 行是 <div role="button" tabindex="0">（行内还要放按钮，button 套 button 非法），
   焦点框得自己给一个跟圆角对齐的，不然键盘用户看不出停在哪一行 */
.fz-task-row:focus-visible{outline:2px solid var(--accent);outline-offset:1px}
/* 「再来一条」：跟 × 同排的行头辅助键，描边不实底——它不该跟右下角「生成」抢视觉重量 */
.vb-reuse{flex:none;height:var(--h-sm,32px);padding:0 10px;font-size:12px;cursor:pointer;
  color:var(--muted);background:transparent;border:1px solid var(--border-strong);
  border-radius:var(--radius-ctl,8px);transition:border-color .15s,color .15s}
.vb-reuse:hover{border-color:var(--accent-ring);color:var(--accent,#f76b1c)}

/* 任务类型标签（2026-08-07 老板：要标出来是视频生成还是搜推素材）：贴在名字前的小方牌，
   不用实底也不用彩色——它是身份标识不是状态，抢眼了会跟失败红字打架 */
.fz-task-kind{display:inline-block;margin-right:6px;padding:0 5px;font-size:10px;line-height:16px;
  vertical-align:1px;color:var(--muted);border:1px solid var(--border-strong);border-radius:4px;font-weight:400}

/* 任务时间（2026-08-07 老板：面板里加上时间）：占 grid 第三列，用全站等宽字体栈——
   比例字体下「11:08」比「14:32」窄，一列时间会左右跳。 */
.fz-task-time{font-family:var(--mono);font-size:11px;color:var(--muted);align-self:start;white-space:nowrap}

/* 当前主区正在展示的那条（2026-08-07 老板：要一眼看出在放哪条）。
   ⚠ 不能只改 border-color —— 下一行 .fail 的红边同特异性且写在后面会把它整个盖掉
   （实测三条失败任务并排，完全看不出选中哪条）。改用左侧亮条＋底色，与失败红边正交。 */
/* 有选中项时其余条目退到背景里，主次一眼分明；悬停回一点，提示还能点 */
.fz-task-list.has-focus .fz-task-row:not(.on){opacity:.42}
.fz-task-list.has-focus .fz-task-row:not(.on):hover{opacity:.78}
.fz-task-row.fail{border-color:rgba(239,68,68,.36)}
.fz-task-row.configured{background:rgba(34,197,94,.07)}
.fz-task-row.skipped{opacity:.62}
/* ⚠ .on 必须排在上面这些**状态**规则后面，别挪回去（2026-08-09）：
   同特异性下后写的赢，.configured 的绿底原来盖掉了 .on 的选中底 ——
   裂变一批里配好的行是常态，于是「正在看的那一条」跟旁边一片绿看着一模一样。
   这和老板当天在换装抓到的是同一个毛病：状态色不许压过「在看的那一条」。
   （只挪背景这一层：.skipped 的压暗仍然生效，跳过就是跳过。）*/
.fz-task-row.on{background:var(--accent-soft);
  box-shadow:inset 3px 0 0 var(--accent,#f76b1c),0 0 0 1px rgba(247,107,28,.22)}
.fz-batch-thumb{width:40px;height:52px;min-height:0;flex:none;border-radius:7px;object-fit:cover;background:rgba(255,255,255,.08);display:inline-block}
.fz-batch-thumb-empty{background:linear-gradient(135deg,rgba(255,255,255,.10),rgba(247,107,28,.10))}
.fz-task-main{min-width:0}
.fz-task-main strong{display:block;font-size: 12px;line-height:1.2;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.fz-task-main small{display:block;color:var(--muted);font-size: 12px;line-height:1.35;margin-top:3px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* 上游任务号 task_QBIKSPXy0MF… 是一长串没有断字点的英数串，浏览器找不到地方换行只能往外画
   （2026-08-08 实测横向溢出 63px，面板底下那条横滚动条就是它）。anywhere = 实在没处断就硬断。 */
.fz-task-main small.fz-task-err{color:#fca5a5;font-weight: 650;white-space:normal;overflow:visible;text-overflow:clip;overflow-wrap:anywhere}
/* 失败原因封顶两行（2026-08-08 全量清查）：搜推/裂变/换装的报错里同样会冒出上游长串
   （OutputImageSensitiveContentDetected / insufficient_user_quota_group_gaorui… / task_LTrT1o…），
   一条能把行从 76px 撑到 140px，一批里失败三四个就得多滚两屏——跟视频原来那个病同源。
   全文仍在悬停 title 里（那三家的模板本来就绑了 :title="row.error"），一个字没丢。
   ⚠ 视频那条线不在此列：它走的是「短句 + 详情展开」，短句已在纯函数里按 34 字收口，
     再叠一层裁剪会把行尾那个「详情」也裁掉，点都点不到。
   ⚠ 2026-08-10 五扇抽屉并成一扇之后，作用域从抽屉类名换成行上的 data-line
     （视频行现在跟别的线并排住在同一扇面板里，靠抽屉限定已经分不开了）。 */
.fz-task-row:not([data-line="video"]) .fz-task-main small.fz-task-err{
  display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;overflow:hidden}
.fz-task-main .fz-stage-progress{display:flex;gap:4px;margin-top:7px;font-style:normal}
.fz-task-main .fz-stage{display:flex;width:22px;flex:none;flex-direction:column;align-items:center;gap:4px}
.fz-task-main .seg{width:100%;height:3px;border-radius:999px;background:rgba(255,255,255,.12)}
.fz-task-main .fz-stage-name{color:rgba(255,255,255,.34);font-size: 10px;line-height:1;white-space:nowrap}
.fz-task-main .fz-stage.done .seg{background:rgba(34,197,94,.65)}
.fz-task-main .fz-stage.done .fz-stage-name{color:rgba(134,239,172,.72)}
.fz-task-main .fz-stage.cur .seg{background:var(--accent)}
.fz-task-main .fz-stage.cur .fz-stage-name{color:#f9a76b;font-weight: 650}
.fz-task-main .fz-stage.skip .seg{background:transparent;border:1px dashed rgba(255,255,255,.22)}
.fz-task-main .fz-stage.skip .fz-stage-name{color:rgba(255,255,255,.28)}
.fz-task-main .fz-stage.fail .seg{background:#ef4444}
.fz-task-main .fz-stage.fail .fz-stage-name{color:#fca5a5;font-weight: 650}

/* ===== 2026-08-10 老板拍板「能统一的尽量统一」：任务行右列 ===== */
/* 时间压在状态之上，五条线一个样。x 由结构保证，跟第二行内容无关（放行尾会被长文案挤到换行）。 */
.fz-task-right{display:flex;flex-direction:column;align-items:flex-end;gap:4px;min-width:0}
/* 字号跟第二行(small)统一；等宽数字，位数变化时不左右跳 */
.fz-task-row .fz-task-time{font-size:12px;line-height:1.3;color:var(--muted);
  font-variant-numeric:tabular-nums;white-space:nowrap}
/* 状态胶囊等宽：右列宽度一致，时间才排得成直列 */
.fz-task-right .fz-bstate{min-width:56px;text-align:center}

/* 段条文字互相遮挡的治法（老板 08-10 指出，放大截图可见「传图·写词」压住「生成」）：
   老写法是每段写死 width:22px + 文字 white-space:nowrap 且不截断 —— 5 个字约 50px 硬塞 22px，
   必然溢出压到隔壁；视频那条虽有 flex:1 1 0 的覆盖，面板一窄照样压。
   改成「每段按自己的文字撑开、进度条跟着段宽走」：不动文案、不截断，结构上不可能再压。 */
.fz-task-main .fz-stage{width:auto;flex:0 1 auto;min-width:22px}
.fz-task-main .fz-stage .seg{width:100%}
.fz-task-main .fz-stage-name{padding:0 2px}

/* —— 视频任务行专属修正（2026-08-08 老板：排版乱、有重叠）——
   只圈在视频那条线的行上（2026-08-10 起靠 [data-line="video"]，原来是靠抽屉类名）：
   .fz-task-* 是五条线共用的公共件，另外几家的阶段名都是两个字（20px < 22px 格子）
   本来就不叠，动它们等于白改还担回归风险。 */
/* ① 标题行改 flex：牌子和时间定宽不参与压缩，中间标题独吞剩余宽度并省略号收口。
      时间靠 margin-left:auto 顶到最右，等宽字体下跨行对齐成一列（原来它单独占一网格列，
      正文抢走宽度后它被压成 0px，文字直接糊在「视频」牌子上）。 */
.fz-task-row[data-line="video"] .fz-task-main strong{display:flex;align-items:baseline;gap:6px}
.fz-task-row[data-line="video"] .fz-task-kind{flex:none;margin-right:0}
.fz-task-row[data-line="video"] .fz-task-title{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.fz-task-row[data-line="video"] .fz-task-time{flex:none;margin-left:auto;align-self:baseline}
/* ② 阶段格子别再写死 22px：视频线的段名是「传图 · 写词」(实测 48.5px) 和「抓主图」(30px)，
      硬塞进 22px 就会溢出去盖住下一段，画出来是「写连成」。改成等分整行 —— 视频 tab 主区那条
      (.vb-stage) 本来就是 flex:1，这里是把抽屉对齐到已有做法，不是新发明。 */
.fz-task-row[data-line="video"] .fz-task-main .fz-stage{width:auto;flex:1 1 0;min-width:0}
.fz-task-row[data-line="video"] .fz-task-main .fz-stage-name{max-width:100%;overflow:hidden;text-overflow:ellipsis}
/* ③ 失败原因的「详情」：行本身是 <button>，所以这里只能用 span（button 套 button 是非法 HTML）。
      全文另起一段小字，等宽 + 可断行，方便客服照着任务号反查。 */
.fz-task-row[data-line="video"] .fz-err-more{margin-left:6px;color:var(--muted);font-weight:400;text-decoration:underline;cursor:pointer;white-space:nowrap}
.fz-task-row[data-line="video"] .fz-err-more:hover{color:var(--fg)}
.fz-task-row[data-line="video"] .fz-err-detail{margin-top:4px;padding:6px 7px;border-radius:6px;background:rgba(255,255,255,.05);
  color:var(--muted);font-family:var(--mono);font-size:11px;line-height:1.45;white-space:normal;overflow-wrap:anywhere}
.fz-bstate{font-size: 12px;padding:4px 8px;border-radius:999px;font-weight: 650;display:inline-block;white-space:nowrap}
.fz-bstate.grab{background:rgba(99,102,241,.16);color:#a5b4fc}.fz-bstate.config{background:rgba(59,130,246,.14);color:#93c5fd}
.fz-bstate.generate{background:rgba(247,107,28,.14);color:#f9a76b}.fz-bstate.select{background:rgba(168,85,247,.14);color:#d8b4fe}
.fz-bstate.publish{background:rgba(34,197,94,.15);color:#86efac}
/* 换装批次的两个节点名：queue 对齐 grab 的灰蓝、done 对齐 publish 的成功绿（少了这两行状态胶囊是透明底） */
.fz-bstate.queue{background:rgba(99,102,241,.16);color:#a5b4fc}.fz-bstate.done{background:rgba(34,197,94,.15);color:#86efac}
/* ⚠ .fail 必须钉在整块最后一条：胶囊同时带「节点名 + fail」两个类（queue fail / generate fail），
   权重一样就是后写的赢——放前面会被节点色盖掉，而「点数不足」那行正是要红着提醒去充值。
   以后再加节点色，一律加在这行【之前】。 */
.fz-bstate.fail{background:rgba(239,68,68,.16);color:#fca5a5}
.fz-flowbar{display:flex;align-items:center;justify-content:space-between;gap:14px;margin:0 0 16px;padding:12px 14px;border:1px solid var(--border);border-radius:12px;background:rgba(255,255,255,.045)}
/* 恢复/换看的中间态占位（2026-08-10）：结果还没载回来时顶上这一块，别让配置屏闪出来。
   刻意给足高度——太矮的话占位一消失整片内容往上跳，比闪一下还难看。不用品牌橙：这儿没有要选的东西。 */
.fz-restoring{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6px;min-height:320px;color:var(--muted);font-size:13px}
.fz-flow-meta{min-width:0}
.fz-flow-meta b{display:block;font-size:14px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.fz-flow-meta span{display:block;color:var(--muted);font-size:12px;margin-top:3px}
.fz-flow-meta span.err{color:#fca5a5}
.fz-flow-actions{display:flex;align-items:center;gap:8px;flex-wrap:wrap;justify-content:flex-end}
.fz-more-menu,.fz-bulk-menu{position:relative}
.fz-flow-more{width:36px;height:36px;padding:0;border:1px solid var(--border);border-radius: 10px;background:rgba(255,255,255,.035);color:var(--fg);font-size: 20px;letter-spacing:1px;cursor:pointer}
.fz-flow-more:hover:not(:disabled),.fz-flow-more.open{background:rgba(255,255,255,.08);border-color:var(--border-strong)}.fz-flow-more:disabled{opacity:.45;cursor:default}
.fz-flow-btn{border-radius: 10px;border:1px solid var(--border);padding:8px 12px;font-family:inherit;font-size: 12px;font-weight: 650;cursor:pointer;white-space:nowrap}
.fz-flow-btn.ghost{background:rgba(255,255,255,.035);color:var(--fg)}
.fz-flow-btn.ghost:hover:not(:disabled){background:rgba(255,255,255,.07)}
.fz-flow-btn.main{background:var(--accent);border-color:var(--accent);color:#1a1300}
.fz-flow-btn:disabled{opacity:.48;cursor:default}
/* 窄屏：抽屉改底部全宽浮层。
   ⚠ 断点 2026-08-08 从 1180 降到 1000：Chrome 扩展侧边栏一开，视口被挤到 1150 左右，
   原来正好落进这一档 → 抽屉全宽、**把整张主卡片全盖住**（老板截图实锤）。
   同样 1150px 下实测宽屏布局完全够用：抽屉 94→422、主卡片 446→1122 宽 676px，
   零重叠、无横向溢出、底部控件放得下。1000px 时主卡片还有约 524px，仍可用。
   ★ 这个断点散在四处（裂变让位/视频·换装让位/抽屉形态/换装详情层级），必须同值，
     只改一处 = 「抽屉在左但主区不让位」，比不改还糟。有测试钉着。 */
@media (max-width:1000px){
  .fz-batch-side{position:fixed;left:16px;right:16px;top:auto;bottom:86px;width:auto;max-height:min(520px,calc(100vh - 120px))}
}

/* 搜推批量·整批结果总览一屏（每品一段 9 图，点图新标签打开/下载）*/
.sm-ov-btn{font-size:12px;font-weight: 650;color:var(--accent);background:var(--accent-soft);border:1px solid var(--accent-ring);border-radius:999px;padding:2px 10px;cursor:pointer}
.sm-ov-btn:hover{background:var(--accent);color:#1a1300}
/* 「整批结果总览一屏」的样式整段已删（2026-08-09 老板拍板去掉那个入口）。
   ⚠ .sm-ov-btn 不能删——换装抽屉的行内按钮还在用同一个类（上面两行）。 */
/* 搜推任务区：那一条商品的 9 图+文案，从弹窗搬进主区后落在 .jm-panel 里。
   里面的坑位条/每套卡片全复用原弹窗那套 .sm-slot-* / .sm-set-*，没有新样式。 */
.sm-task-view{display:flex;flex-direction:column;gap:12px}
.sm-task-head{display:flex;align-items:baseline;gap:10px;padding-bottom:10px;border-bottom:1px solid var(--border)}
.sm-task-head b{font-size:14px;font-weight:650;color:var(--fg);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* 2026-08-27 老板圈图：原来这里是 `margin-left:auto` 把计数顶到最右，收起钮再跟在它
   屁股后面 —— 标题与它俩之间空一大片，右端两个元素挤成一坨。
   改成：计数紧跟标题做成 chip（复用 08-11 定的 .ffr-chip 语汇），收起钮独占最右。 */
.sm-task-head span{font-size:12px;color:var(--muted);flex:none;
  border:1px solid var(--border);border-radius:999px;padding:2px 10px;white-space:nowrap;line-height:1.5}
.sm-task-head .sm-copy-btn{margin-left:auto}
/* 自由生图任务区（2026-08-09 第 5 条线）：头部复用 .sm-task-head，这儿只加图墙网格。
   一次生成最多 4 张，两列足够；格子用 aspect-ratio 撑高，图没到齐也量得准飞行起点。 */
/* 结果页 A 版（2026-08-11 三版比稿老板选 A·丰满化）：结果区套进与创作台面同款的卡片，
   图放大铺满 —— 治的就是他圈的「空、小、陋」；chips=头部信息条的统一小胶囊 */
.ff-task-view{display:flex;flex-direction:column;gap:12px;background:var(--card);border:1px solid var(--border);border-radius:18px;padding:18px 20px}
.ffr-title{font-size:14px;max-width:56%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ffr-chip{font-size:12px;color:var(--muted);border:1px solid var(--border);border-radius:999px;padding:2px 10px;white-space:nowrap}
.ffr-chip.ok{color:#86efac;border-color:rgba(134,239,172,.35)}
/* ⚠ 别写 repeat(2,1fr)：一次生成常常只有 1 张，1fr 会把它撑成半屏宽 × 780px 高的巨图（实测）。
   固定格宽 + auto-fill，1 张就是 1 张的大小，4 张自动排满一行。 */
/* 2026-08-11 ④ 排布 A（老板 08-10 拍板）：等宽自适应、高度随图、⛔不裁不留黑边。
   缩略图刻意不堆大 —— 一屏多扫几张，看清楚交给 lightbox（网格负责「选」，点开负责「判」）。
   align-items:start 少不了：不设的话 grid 会把同行格子拉成一样高，矮图下面又是一条黑边。 */
.ff-task-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(340px,1fr));gap:16px;align-items:start}   /* A 版：170→340 图放大铺满 */
.ff-task-cell{position:relative;border-radius:10px;overflow:hidden;background:var(--card);
  border:1px solid var(--border)}
.ff-task-cell img{display:block;width:100%;height:auto}   /* 高度随图，整张给你看（原来的 cover 裁图口径已去 —— 它是五个板块里唯一会裁的） */
.ff-task-cell .fz-rstate{aspect-ratio:3/4;display:flex}   /* 还没出图的格子保住占位比例，别塌成一条线 */
@media (max-width:900px){.ff-task-grid{grid-template-columns:repeat(auto-fill,minmax(240px,1fr))}}
.sm-clear-btn{font-size:12px;font-weight: 650;color:var(--danger);background:rgba(239,68,68,.12);border:1px solid rgba(239,68,68,.32);border-radius:999px;padding:2px 10px;cursor:pointer}
.sm-clear-btn:hover,.sm-clear-btn.armed{background:var(--danger);color:#fff}

/* ═══════ A方案·画廊墨黑 × 得意黑 · STEP1（2026-07-10）═══════
   改动面：①背景——银河图+旋转地球视频退场，换纯墨黑渐变（客户少下一个视频+一张大图）
          ②门面字——大标题/风格区标题/卡名/tab/一键开跑 换「得意黑」（SIL OFL 免费商用）
   字体文件：/static/lib/SmileySans-subset.woff2（GB2312一级字库子集 503KB）
   回滚：删掉本段 + index.html 恢复备份即可 */
@font-face {
  font-family: "Smiley Sans";
  src: url("lib/SmileySans-subset.woff2?v=1") format("woff2");
  font-display: swap;
}
body {
  background:
    radial-gradient(1200px 520px at 50% -10%, rgba(247,107,28,.05), transparent 60%),
    linear-gradient(180deg, #0C0C0E 0%, #101013 100%);
  background-attachment: fixed;
}
.earth-bg { display: none; }  /* 地球视频退役；index 的 div 已删，这行兜底老缓存页 */

/* 门面字：得意黑只有一个字重，统一 400 防伪加粗发糊；正文/说明/芯片仍走系统字 */
.jm-title { font-family: "Smiley Sans", "PingFang SC", "Microsoft YaHei", sans-serif; font-weight: 400; letter-spacing: 1.5px; }
.gal-h2,
.gal-card-bn { letter-spacing: .5px; }
.mod-tab { letter-spacing: .5px; }
.mod-badge { font-family: "Inter", "PingFang SC", sans-serif; }  /* tab 上的小徽标（铺量/保真/新）回系统字 */
.fz-go-btn { font-size: 14px; letter-spacing: .8px; }

/* ═══════ A方案·STEP2（2026-07-10）：页签细线化 + 风格卡4列降噪 + 悬停钮实白 ═══════
   回滚：删本段 + index.html 版本号回 213 */
/* 页签：档案夹块状 → 文字+底部细线（创作台与用量页共用这组类；≤860px 的字号规则不受影响） */
.mod-tabs { justify-content: center; gap: 6px; border-bottom: 1px solid rgba(239,235,227,.09); }
.mod-tab { flex: 0 1 auto; margin-bottom: 0; padding: 12px 18px 15px; background: transparent; box-shadow: none; border-radius: 0; }
.mod-tab + .mod-tab { margin-left: 0; }
.mod-tab:hover:not(.on) { background: transparent; transform: none; color: var(--fg); }
.mod-tab.on { background: transparent; box-shadow: none; transform: none; padding-bottom: 15px; font-weight: 400; }
.mod-tab.on::before { top: auto; bottom: -1px; left: 16px; right: 16px; height: 2px; background: #EFEBE3; opacity: 1; }
.mod-tabs + .jm-card { border-top-left-radius: 26px; border-top-right-radius: 26px; margin-top: 18px; }
/* 风格蒸馏：与创作列同宽(980)对齐；宽屏 4 列大卡（≤1000px 的 3/2 列响应规则保留）；橙饰件降噪 */
.gal { max-width: 980px; }
@media (min-width: 1001px) { .gal-grid { grid-template-columns: repeat(4, 1fr); } }
.gal-bar { background: #EFEBE3; }
.gal-badge { color: rgba(239,235,227,.65); background: rgba(255,255,255,.05); border-color: rgba(255,255,255,.17); }
.gal-card:hover { border-color: rgba(239,235,227,.4); }
.gal-card-cat { color: rgba(239,235,227,.62); background: rgba(255,255,255,.06); border-color: rgba(255,255,255,.17); }
.gal-card-act { background: rgba(239,235,227,.94); color: #161616; }
.gal-card-act:hover { background: #fff; }
.gal-card-act--ghost { background: rgba(20,20,24,.45); color: #EFEBE3; }
.gal-card-act--ghost:hover { background: rgba(20,20,24,.65); }

/* ═══════ A方案·STEP3（2026-07-10）：批量任务常驻空态 ═══════ */
.fz-batch-empty { padding: 30px 18px; text-align: center; color: var(--muted); font-size: 14px; line-height: 2; }
.fz-batch-empty small { color: rgba(138,138,146,.65); font-size: 12px; }

/* ═══════ A方案·STEP3b（2026-07-10）：历史「即将过期」角标（选择器压过 .hist-day-head span 的通配） ═══════ */
.hist-day-head .hist-expire { display: inline-block; margin-left: 6px; margin-right: 2px; font-size: 12px; color: #fff; background: rgba(210,105,94,.92); border-radius: 999px; padding: 2px 10px; font-weight: 650; letter-spacing: .02em; }

/* ═══════ A方案·收尾微调（2026-07-10）：芯片标签 + 蒸馏区说明归位 ═══════ */
/* 参数芯片前缀标签：模型/比例/画质/数量/时长——新客户一眼读懂灰片是什么 */
.jm-pk { font-style: normal; font-size: 12px; color: rgba(138,138,146,.75); margin-right: 5px; letter-spacing: .02em; }
.jm-pill.open .jm-pk, .jm-pill:hover .jm-pk { color: rgba(138,138,146,.95); }
/* 「大牌风格蒸馏」说明文字从最右边归位到标题下方一行 */
.gal-sub { margin-left: 0; flex-basis: 100%; margin-top: -2px; }   /* 竖线不再占位，说明文字回主轴 */
/* ===== 视频批量（一品一片） ===== */
.jm-card-title { font-weight: 650; font-size: 14px; margin: 2px 2px 14px; color: var(--fg); }
.vb-input { width: 100%; }
.vb-pill-static { opacity: .75; cursor: default; }
.vb-action-input { margin: 6px 8px; width: calc(100% - 16px); }
.vb-row {
  max-width: 980px; margin: 10px auto 0;
  background: var(--card); border: 1px solid var(--border);
  border-radius: 12px; padding: 12px 14px;
}
.vb-row-head { display: flex; align-items: center; gap: 10px; }
.vb-rm { border: none; background: none; color: var(--muted); font-size: 20px; line-height: 1; cursor: pointer; padding: 0 4px; }
.vb-rm:hover { color: var(--danger); }
.vb-title { font-weight: 650; flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.vb-id { opacity: .55; font-size: 12px; }
.vb-status { font-size: 12px; opacity: .8; }
.vb-row.st-failed .vb-status, .vb-row.st-no_balance .vb-status, .vb-row.st-grab_failed .vb-status { color: #fca5a5; }
.vb-row.st-done .vb-status { color: #86efac; }
.vb-err { color: #fca5a5; font-size: 12px; margin-top: 4px; }
/* 行内 AI 提示词框（固定流程 2026-08-01）：出词后过目/可改；生成中/完成转只读小字留档 */
.vb-prompt { display: flex; gap: 8px; align-items: flex-start; margin: 8px 0 2px; }
.vb-prompt-tag { flex: none; font-size: 12px; color: var(--muted); border: 1px solid rgba(228,228,235,.28); border-radius: 5px; padding: 1px 7px; margin-top: 5px; white-space: nowrap; }
.vb-prompt-tag.ai { color: #fbbf77; border-color: rgba(251,191,119,.45); }   /* AI 看图=焦糖橙点缀；通用词=灰 */
.vb-prompt-input { flex: 1; font-size: 12px; line-height: 1.5; color: var(--ink, #e4e4eb); background: rgba(0,0,0,.22); border: 1px solid rgba(228,228,235,.22); border-radius: 8px; padding: 6px 9px; resize: vertical; min-height: 40px; }
.vb-prompt-input:focus { outline: none; border-color: rgba(251,191,119,.6); }
.vb-prompt-text { flex: 1; font-size: 12px; line-height: 1.5; color: var(--muted); padding-top: 4px; }

/* 提示词聚焦区（2026-08-01 老板验收反馈重排·同日二修去空旷）：出词起图海退场——左=选中主图小卡，
   右=词卡（高度随内容，不再拉满留白）；换图走图下"↺ 换图"回选图态 */
.vb-focus { display: flex; gap: 14px; margin: 10px 0 4px; }
.vb-focus-img { flex: none; width: 118px; position: relative; }
.vb-focus-img img { width: 100%; max-height: 158px; object-fit: cover; border-radius: 10px; display: block; border: 1px solid rgba(228,228,235,.14); }
.vb-focus-swap { position: absolute; left: 50%; transform: translateX(-50%); bottom: 6px; font-size: 12px; color: #e4e4eb; background: rgba(0,0,0,.58); border: 1px solid rgba(228,228,235,.32); border-radius: 999px; padding: 2px 10px; cursor: pointer; backdrop-filter: blur(4px); white-space: nowrap; }
.vb-focus-swap:hover { border-color: rgba(251,191,119,.7); color: #fbbf77; }
.vb-focus-prompt { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 7px; }
.vb-focus-head { display: flex; align-items: center; gap: 8px; }
/* 中间那句提示语挤不下就省略号，别换行（2026-08-08 实测定的）：
   它可伸缩、标签和按钮都 flex:none，窄窗口只能压它——不设 nowrap 会被压成面条
   （聚焦区 340px 时那排从 83px 撑到 182px）。
   ⚠ 试过 flex-wrap:wrap，实测更糟：560px 时按钮就被踢到第二行，行高 32→61，
     拿常见宽度换罕见宽度，赔了。min-width:0 必须有，否则 flex 子项不肯缩到内容以下。 */
.vb-focus-head .vb-focus-hint { min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.vb-focus-head .vb-prompt-tag { margin-top: 0; }
/* 一键优化按钮（2026-08-07）：贴在提示词标题行最右。用描边不用实底——它是辅助动作，
   实底会跟右下角那颗「生成」抢视觉重量（老板："不用选择的不要加颜色"）。 */
.vb-polish, .vb-focus-polish { margin-left: auto; display: inline-flex; align-items: center; gap: 5px; flex: none;
  height: var(--h-sm, 32px); padding: 0 10px; font-size: 12px; cursor: pointer;
  color: var(--fg); background: transparent; border: 1px solid var(--border-strong);
  border-radius: var(--radius-ctl, 8px); transition: border-color .15s, color .15s; }
.vb-polish:hover:not(:disabled), .vb-focus-polish:hover:not(:disabled) { border-color: var(--accent-ring); color: var(--accent, #f76b1c); }
.vb-polish:disabled, .vb-focus-polish:disabled { opacity: .6; cursor: default; }
.vb-polish .spinner, .vb-focus-polish .spinner { margin: 0; width: 12px; height: 12px; }   /* 同 .vb-focus-loading：全局 margin:auto 会把圈挤飞 */
.vb-focus-hint { font-size: 12px; color: var(--muted); }
.vb-prompt-input--lg { font-size: 14px; line-height: 1.7; min-height: 74px; padding: 9px 11px; background: rgba(0,0,0,.28); }
.vb-focus-loading { display: flex; align-items: center; justify-content: center; gap: 10px; font-size: 14px; color: var(--muted); border: 1px dashed rgba(228,228,235,.22); border-radius: 10px; min-height: 74px; }
.vb-focus-loading .spinner { margin: 0; width: 16px; height: 16px; }   /* 全局 .spinner 的 margin:auto 会把圈和文字挤散（08-01 老板截图实锤），局部归零 */
.vb-focus .vb-prompt-text { font-size: 14px; line-height: 1.7; color: var(--ink, #e4e4eb); opacity: .82; border: 1px solid rgba(228,228,235,.12); border-radius: 10px; padding: 9px 11px; }
.vb-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); gap: 8px; margin-top: 10px; }
/* 视频：链接输入区（贴商品链接抓第1张主图） */
.vb-links-input { width: 100%; min-height: 58px; margin: 0 0 10px; resize: vertical; }

/* 图生视频输入区（2026-08-07 老板拍板照自由生图排版）：左边图槽、右边文案，同一个框。
   .jm-body/.jm-up/.jm-up-add/.jm-input 全部沿用自由生图那套，这里只补「润色按钮贴在词框右下」。 */
/* 润色按钮贴文案框右上角：与左边图槽顶边齐平连成一条线。
   放右下角时（08-07 初版）文案只有一行、按钮却吊在框底，中间空 50px，看着像块孤零零的浮件。
   textarea 右侧留出按钮宽度的 padding，文字不会钻到按钮底下。 */
.vb-img-body .jm-input { min-height: 96px; padding-right: 124px; }
.vb-img-prompt { position: relative; flex: 1; min-width: 0; display: flex; }
.vb-img-prompt .jm-input { width: 100%; }
.vb-img-prompt .vb-polish { position: absolute; right: 6px; top: 6px; }

/* 视频流程内「先擦文案」开关 */
/* 去文案选框（底部工具条 pill 形态，2026-07-17 起 2 点/条）：勾上走橙亮态，价签小字 */
.vb-erase-pill { user-select: none; }
.vb-erase-pill input { accent-color: var(--accent); width: 14px; height: 14px; margin: 0; cursor: pointer; }
.vb-erase-pill.on { border-color: var(--accent-ring); background: var(--accent-soft); }
.vb-erase-price { font-size: 12px; color: var(--muted); }
.vb-erase-pill.on .vb-erase-price { color: var(--accent); }

/* ===== 视频：上传图网格（擦文案=行内状态） ===== */
.vb-cell {
  position: relative; aspect-ratio: 3/4; border-radius: 10px; overflow: hidden;
  border: 2px solid transparent; cursor: pointer;
}
.vb-cell img { width: 100%; height: 100%; object-fit: cover; display: block; }
.vb-cell.on { border-color: var(--accent); }
.vb-cell .vb-aspect {
  position: absolute; left: 4px; bottom: 4px; font-size: 10px;
  background: rgba(0,0,0,.55); color: #fff; padding: 1px 5px; border-radius: 4px;
}
.vb-cell .vb-check {
  position: absolute; right: 4px; top: 4px; width: 18px; height: 18px;
  border-radius: 50%; background: var(--accent); color: #fff; font-size: 12px;
  display: flex; align-items: center; justify-content: center;
}
/* —— 视频行阶段条 + ETA + 批次汇总（复刻裂变 .fz-stage 视觉·单深色主题） —— */
/* 搜推双子模式（2026-08-12）：传图模式提示/润色按钮排布。
   页签行已换 .sm-ratio.ff-mode 同款（0812 老板报挤压），原裸行容器类退役删除。 */
.sm-ref-hint { font-size: 12.5px; color: var(--muted); line-height: 1.7; padding: 6px 2px; }
.sm-extra-row { display: flex; gap: 8px; align-items: center; }
.sm-extra-row .sm-extra-input { flex: 1; }
.sm-polish-btn { flex: none; white-space: nowrap; }
/* 参考图生成模式：提示词主输入大框，润色贴右上（照视频 .vb-img-prompt 形态，0812 老板报
   「补充要求没道理，应该就是提示词板块」）。padding-right 给按钮让位，文字不钻按钮底下。 */
.sm-prompt-wrap { position: relative; flex: 1; min-width: 0; display: flex; }
.sm-prompt-wrap .sm-prompt-input { width: 100%; min-height: 96px; padding-right: 138px; resize: vertical; }
.sm-prompt-wrap .sm-polish-btn { position: absolute; right: 6px; top: 6px; }
/* 第二步参数区（0812 两阶段·同日老板「排版不合理」重排）：虚线分隔上面的选图/N款头，
   参考图列在左（最多 2 列 wrap），提示词大框(sm-prompt-wrap 共用 ref 模式那套)占满右侧 */
.sm-pick-extras { margin-top: 12px; padding-top: 12px; border-top: 1px dashed var(--accent-ring); display: flex; gap: 12px; align-items: stretch; }
/* 选图配参面板（08-18 老板：压在候选图底下要滚半天，有人根本看不见）——挪到候选图上面并【吸顶】。
   ⚠ 背景必须不透明：--panel 是半透明白，候选图会从底下透出来糊成一片。 */
.sm-pick-panel { position: sticky; top: 10px; z-index: 6; display: flex; gap: 12px; align-items: stretch;
  background: #1a1a1d; border: 1px solid var(--accent-ring); border-radius: 14px;
  padding: 12px; margin: 2px 0 14px; box-shadow: 0 8px 24px rgba(0, 0, 0, .45); }
.sm-pick-panel .sm-pick-refs { max-width: 196px; }
.sm-pick-panel .jm-up-add, .sm-pick-panel .jm-up-item { height: 84px; width: 84px; }
.sm-pick-panel .jm-up-add .jm-plus { font-size: 20px; }
.sm-pick-panel .sm-prompt-wrap .sm-prompt-input { min-height: 84px; resize: none; }
.sm-pick-panel .sm-pick-go { align-self: center; flex: none; white-space: nowrap; }
.sm-pick-refs { display: flex; gap: 8px; flex-wrap: wrap; flex: none; max-width: 212px; align-content: flex-start; }
/* 出图/开始生成按钮右下角常规位（取消在左，主按钮最右） */
.sm-pick-act { justify-content: flex-end; }
/* 点「开始生成」被拦的原因驻留行（0812 老板真机「点了没反应」）：红字常驻不闪逝 */
.sm-pick-err { margin-top: 10px; font-size: 13px; color: #fca5a5; }

/* 换装结果页开新批的进度占位（0812 老板抓「空白 0 款报告」）：逐款一行转圈+状态 */
.ty-result-pending { display: flex; flex-direction: column; gap: 10px; padding: 28px 8px; }
.ty-pending-row { display: flex; align-items: center; gap: 10px; font-size: 14px; color: var(--muted); }
.ty-pending-row b { color: var(--fg); font-weight: 650; }

/* 原来这儿是视频聚焦区「↑ 生成」钮（.vb-focus-go，0812 解耦时加的行域提交口）。
   2026-08-13 老板「按钮怎么有两个，应该在下面的位置统一」→ 钮已撤、动作回台面 .jm-send，
   这段随之没有任何匹配对象，一并删（本仓惯例：不留死 CSS）。 */

/* ===== 搜推单品聚焦流程（0812 老板「模仿视频那个界面」）：节点条+候选主图大图墙 ===== */
.sm-flow-nodes { display: flex; align-items: center; gap: 10px; margin-bottom: 14px; }
.sm-flow-node {
  display: inline-flex; align-items: center; font-size: 13px; color: var(--muted);
  padding: 5px 12px; border-radius: 999px; border: 1px solid var(--border); white-space: nowrap;
}
.sm-flow-node.on { color: var(--fg); border-color: var(--accent-ring); }
.sm-flow-node.cur { color: #fff; background: var(--accent); border-color: var(--accent); font-weight: 650; }
.sm-flow-line { flex: 0 1 56px; height: 1px; background: var(--border); }
.sm-flow-line.on { background: var(--accent); }
/* 大图墙：照视频 vb-grid 形态但格子放大（老板要的就是「大图可选」，96px 小条是被否的旧形态） */
.sm-flow-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 10px; }
.sm-flow-cell {
  position: relative; aspect-ratio: 1 / 1; cursor: pointer; overflow: hidden;
  border: 2px solid transparent; border-radius: 12px; background: rgba(255,255,255,.05);
  transition: border-color .15s, transform .12s;
}
.sm-flow-cell:hover { transform: translateY(-2px); }
.sm-flow-cell.on { border-color: var(--accent); }
.sm-flow-cell img { width: 100%; height: 100%; object-fit: cover; display: block; }
.sm-flow-idx {
  position: absolute; left: 0; right: 0; bottom: 0; font-size: 12px; text-align: center;
  padding: 3px 0; background: rgba(0,0,0,.55); color: #fff;
}
.sm-flow-cell.on .sm-flow-idx { background: var(--accent); font-weight: 650; }
.sm-flow-check {
  position: absolute; top: 6px; right: 6px; width: 22px; height: 22px; border-radius: 50%;
  background: var(--accent); color: #fff; font-size: 13px; font-weight: 700;
  display: flex; align-items: center; justify-content: center;
}
/* 搜推单品生成中的九格占位（2026-08-12）：3:4 与出图同比例，出图那一刻格换图不跳版 */
.sm-solo-wait .fz-rstate { aspect-ratio: 3/4; display: flex; flex-direction: column; gap: 8px; }
.vb-summary { display: flex; align-items: center; justify-content: space-between; gap: 10px; font-size: 12px; color: var(--muted); margin: 2px 1px 10px; }
/* 统计字删掉后（2026-08-11）行里只剩这颗按钮：保持在右侧老位置，别蹦到左边 */
.vb-summary .vb-clear { margin-left: auto; }
.vb-summary b { color: var(--fg); font-weight: 650; }
.vb-summary-fail b { color: #fca5a5; }
.vb-clear { flex: none; font-size: 12px; color: var(--muted); background: transparent; border: 1px solid var(--border); border-radius: 999px; padding: 3px 11px; cursor: pointer; transition: color .15s, border-color .15s; }
.vb-clear:hover:not(:disabled) { color: var(--fg); border-color: var(--fg); }
.vb-clear:disabled { opacity: .4; cursor: not-allowed; }
.vb-stages { display: flex; gap: 6px; margin: 9px 0 2px; }
.vb-stage { display: flex; flex: 1; flex-direction: column; align-items: center; gap: 4px; }
.vb-stage .vb-seg { box-sizing: border-box; width: 100%; height: 3px; border-radius: 999px; background: rgba(255,255,255,.12); }
.vb-stage em { color: rgba(255,255,255,.34); font-size: 10px; line-height: 1; font-style: normal; white-space: nowrap; }
.vb-stage.done .vb-seg { background: rgba(34,197,94,.65); }
.vb-stage.done em { color: rgba(134,239,172,.72); }
.vb-stage.cur .vb-seg { background: var(--accent); animation: vbPulse 1.1s ease-in-out infinite; }
.vb-stage.cur em { color: #f9a76b; font-weight: 650; }
.vb-stage.skip .vb-seg { background: transparent; border: 1px dashed rgba(255,255,255,.22); }
.vb-stage.skip em { color: rgba(255,255,255,.28); }
.vb-stage.fail .vb-seg { background: #ef4444; }
.vb-stage.fail em { color: #fca5a5; font-weight: 650; }
@keyframes vbPulse { 0%, 100% { opacity: 1; } 50% { opacity: .42; } }
.vb-eta { display: flex; align-items: center; gap: 8px; margin: 3px 1px 0; }
.vb-eta-bar { flex: 1; display: block; height: 5px; overflow: hidden; border-radius: 999px; background: rgba(255,255,255,.10); }
.vb-eta-bar > em { display: block; height: 100%; border-radius: inherit; background: var(--accent); transition: width .6s ease; }
.vb-eta-label { color: var(--muted); font-size: 12px; white-space: nowrap; font-variant-numeric: tabular-nums; }
/* 视频 + AI 文案并排【等高】（2026-08-15 老板：「要保证跟视频框高度什么的是要统一的」）。
   ⚠ 绝不要写 align-items —— flex 默认就是 stretch，写成 flex-start 就是「两个框各长各的」。 */
.vb-result { margin: 10px 0 2px; display: flex; gap: 12px; flex-wrap: wrap; }
.vb-result .vb-video { flex: 0 0 auto; }
/* ⚠ .vb-result 变成 flex 之后，它原有的两个兄弟块（按钮行 / 补问商品ID 框）也成了 flex 子项，
   会挤到同一行去 —— 2026-08-15 实测：补问框跑到按钮行右边（同 top、left 632）。
   它俩必须各自独占一整行，恢复成改动前的上下堆叠。 */
.vb-result > .vb-acts, .vb-result > .vb-sync-ask { flex: 0 0 100%; }
.vb-copy { flex: 1 1 300px; min-width: 260px; display: flex; flex-direction: column;
           padding: 10px 12px; border-radius: 10px;
           background: rgba(0,0,0,.22); border: 1px solid var(--border); }
.vb-copy-head { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; flex: 0 0 auto; }
.vb-copy-tag { font-size: 11px; padding: 1px 7px; border-radius: 999px;
               background: var(--accent); color: var(--on-bg); font-weight: 650; }
.vb-copy-hint { font-size: 11px; color: var(--muted); }
.vb-copy-cp { margin-left: auto; }
/* 列表吃掉剩余高度并在框内滚：文案再长也不把框撑得比视频高，再短也不缩水。
   ⚠ min-height:0 不能漏——flex 子项默认 min-height:auto 不肯收缩，overflow-y 会形同虚设。 */
.vb-copy-list { flex: 1 1 auto; min-height: 0; overflow-y: auto; display: flex; flex-direction: column; gap: 8px; }
.vb-copy-item { padding: 8px 10px; border-radius: 8px; cursor: pointer;
                border: 1px solid var(--border); background: rgba(255,255,255,.02); }
.vb-copy-item:hover { border-color: var(--border-strong); }
.vb-copy-item.on { border-color: var(--accent); background: var(--accent-soft); }
.vb-copy-t { font-size: 13.5px; font-weight: 650; line-height: 1.45; margin-bottom: 4px; }
.vb-copy-b { font-size: 12.5px; line-height: 1.6; color: var(--muted); white-space: pre-wrap; }
.vb-copy-msg { font-size: 12px; color: var(--muted); }
/* 窄屏 wrap 掉成上下后不再有「等高」可言，给个上限免得一屏全是文案 */
@media (max-width: 720px) { .vb-copy-list { max-height: 240px; } }
/* 2026-08-11 ④ 定案第 6 条：240px 的播放器竖版视频根本看不清 → 自适应、上限 ~440 */
.vb-video { display: block; width: 100%; max-width: 440px; border-radius: 10px; background: #000; }
/* ⚠ .vb-dl 是给 <a> 写的纯文字链（无底无框无内边距）。2026-08-15 之前视频结果区的两颗操作
   都挂着它，其中「同步到商品视频」是 <button> —— 复用这个 class 却没做 button reset，
   浏览器默认按钮的灰底+边框整个漏出来，跟旁边纯文字的 <a> 完全不是一路。已改用 .btn-mini。
   本条保留不删：站里别处可能还在引用它。⛔ 别再把它套到 <button> 上。 */
.vb-dl { display: inline-block; margin-top: 7px; font-size: 12px; color: var(--accent); text-decoration: none; }
.vb-dl:hover { text-decoration: underline; }
.vb-result-source{display:flex;gap:14px;align-items:stretch;margin:12px 0;padding:12px;
  border:1px solid var(--border);border-radius:12px;background:rgba(255,255,255,.025)}
.vb-result-source-pics{display:flex;gap:7px;flex:0 0 auto;max-width:52%;overflow:hidden}
.vb-result-source-pics img{width:92px;height:112px;object-fit:cover;border-radius:8px;background:#111}
.vb-result-source-meta{min-width:0;display:flex;flex-direction:column;justify-content:center;gap:7px}
.vb-result-source-meta b{font-size:14px;color:var(--fg)}
.vb-result-source-meta span{font-size:12px;color:#f4ad73;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.vb-result-source-meta small{font-size:12px;line-height:1.45;color:var(--muted);display:-webkit-box;
  -webkit-box-orient:vertical;-webkit-line-clamp:3;overflow:hidden}
@media(max-width:760px){.vb-result-source{display:block}.vb-result-source-pics{max-width:100%;margin-bottom:10px}}
/* 视频结果区那一排操作（2026-08-15）：给两颗按钮一个横向容器 + 间距。
   按钮本身一律用站里现成的 .btn-mini 档位，这里只管排版，不定义按钮长相。 */
/* 任务面板行内「同步到商品视频」的进度小字（2026-08-15）。默认弱化＝进行中；
   成功转绿、失败转红，与本仓既有的 .fz-task-err 同一档字号，不抢阶段条的注意力。
   ⚠⚠ 必须显式覆盖 `.fz-task-main small` 那条（4055 行：overflow:hidden + ellipsis + nowrap）——
      面板里所有 <small> 都被它强制单行截断。第一版没覆盖，真机上显示成
      「↑ 同步商品视频：等…」「✓ 已填好，但发布结…」，老板当场反馈「进度没出现」——
      其实出现了，只是被切得看不出是什么。旁边的 .fz-task-err 早就为同一件事写过覆盖，照抄它。
   封顶两行：文案最长那条（等淘宝转码那句）在面板宽度下正好两行；不封顶的话失败原因
      带上游长串时会把行撑高，跟 08-08 治过的那个病同源。 */
.fz-task-main small.fz-task-sync {
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2;
  white-space: normal; overflow: hidden; text-overflow: clip; overflow-wrap: anywhere;
  font-size: 12px; line-height: 1.45; color: var(--muted); margin-top: 3px;
}
.fz-task-main small.fz-task-sync.ok { color: #86efac; }
.fz-task-main small.fz-task-sync.bad { color: #fca5a5; }
/* 补问商品 ID 的小面板（2026-08-15）：只对图生视频那种没有商品ID的行出现。 */
.vb-sync-ask { margin-top: 8px; padding: 8px 10px; background: rgba(0,0,0,.22);
  border: 1px solid var(--border); border-radius: 8px; max-width: 440px; }
.vb-sync-ask .vb-action-input { margin: 0 0 8px; width: 100%; }
.vb-sync-ask-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.vb-sync-ask-err { font-size: 12px; color: #fca5a5; }
/* 结果区按钮右边的同步进度（2026-08-15 老板指定的位置）。这里横向空间宽裕，
   ⛔ 不要照搬面板那条的两行封顶/省略号 —— 那是被窄列逼出来的，这儿没那个约束。 */
.vb-sync-log { font-size: 12px; line-height: 1.4; color: var(--muted); margin-left: 2px; }
.vb-sync-log.ok { color: #86efac; }
.vb-sync-log.bad { color: #fca5a5; }
.vb-acts { display: flex; align-items: center; gap: 8px; margin-top: 8px; flex-wrap: wrap; }

/* 链接裂变 · SKU 图组标注 */
.fz-thumb.ar-sku img { aspect-ratio: 1 / 1; object-fit: cover; }  /* SKU 方图与 1:1 同款展示 */
.fz-sku-colors {
  font-size: 12px; line-height: 1.5; padding: 2px 6px 0;
  color: var(--muted);                  /* 与 .fz-chip-cap 同级的弱化文本色（对齐既有变量） */
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.fz-sku-same {
  position: absolute; left: 6px; bottom: 6px; z-index: 1;
  background: rgba(247,107,28,.92); color: #fff;
  font-size: 12px; padding: 1px 6px; border-radius: 8px;
}

/* —— 推荐好友二级视图（面板内 pane 切换）2026-07-22 —— */
.ps-rv-back { display: flex; align-items: center; gap: 8px; font-size: 14px; font-weight: 650; padding: 4px 4px 10px; cursor: pointer; color: var(--fg); }
.ps-rv-back .ps-mi-ic { width: 16px; height: 16px; flex: 0 0 16px; }
.ps-rv-back:hover { color: var(--accent); }
.ps-rv-hero { position: relative; overflow: hidden; text-align: center; background: linear-gradient(160deg, #33220e 0%, #201409 75%); border: 1px solid rgba(247,107,28,.45); border-radius: 13px; padding: 16px 12px 14px; margin-bottom: 8px; }
.ps-rv-hero::before { content: ""; position: absolute; inset: 0; background: radial-gradient(220px 120px at 50% -30%, rgba(255,190,90,.3), transparent 70%); }
.ps-rv-big { position: relative; font-size: 20px; font-weight: 650; background: linear-gradient(90deg, #ffd79a, #f76b1c); -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; }
.ps-rv-cap { position: relative; font-size: 12px; color: #c9a284; margin-top: 4px; line-height: 1.6; }
.ps-rv-linkbox { display: flex; gap: 6px; margin: 10px 2px 8px; }
.ps-rv-link { flex: 1; background: var(--panel); border: 1px solid var(--border-strong); border-radius: 10px; padding: 8px 10px; font-size: 12px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-variant-numeric: tabular-nums; }
.ps-rv-copy { border: none; background: var(--accent); color: #1a0d00; font-size: 12px; font-weight: 650; padding: 0 14px; border-radius: 10px; cursor: pointer; font-family: inherit; }
.ps-rv-copy:hover { filter: brightness(1.1); }
.ps-rv-stats { display: flex; gap: 8px; margin: 0 2px 8px; }
.ps-rv-stat { flex: 1; background: var(--panel); border: 1px solid var(--border); border-radius: 10px; padding: 9px 10px; text-align: center; }
.ps-rv-stat b { display: block; font-size: 20px; color: var(--accent); font-weight: 650; }
.ps-rv-stat span { font-size: 10px; color: var(--muted); }
.ps-rv-rule { font-size: 10px; color: var(--muted); line-height: 1.7; margin: 2px 4px 2px; }

/* —— 被邀请横幅（?ref= 匿名访客）2026-07-22 —— */
#ps-invite-bar { position: fixed; top: 12px; left: 50%; transform: translateX(-50%); z-index: 300; display: flex; align-items: center; gap: 10px; background: rgba(24, 24, 28, .96); backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px); border: 1px solid rgba(247,107,28,.5); border-radius: 999px; padding: 8px 10px 8px 16px; box-shadow: 0 10px 32px rgba(0,0,0,.45); animation: psMenuIn .2s ease; }
#ps-invite-bar .ps-iv-txt { font-size: 14px; font-weight: 650; color: var(--fg); white-space: nowrap; }
#ps-invite-bar .ps-iv-go { border: none; background: var(--accent); color: #1a0d00; font-size: 12px; font-weight: 650; padding: 6px 14px; border-radius: 999px; cursor: pointer; font-family: inherit; }
#ps-invite-bar .ps-iv-go:hover { filter: brightness(1.1); }
#ps-invite-bar .ps-iv-x { border: none; background: none; color: var(--muted); font-size: 14px; cursor: pointer; padding: 4px 6px; }
#ps-invite-bar .ps-iv-x:hover { color: var(--fg); }

/* 自由生图「高点击率复刻」模式（2026-07-30）：切换复用 .sm-ratio 分段控件；槽位复用 .jm-up-item/.jm-up-add */
/* 2026-08-09 加第三档「买家秀」：三个按钮比两个宽，窄屏允许换行别把卡片撑破 */
.ff-mode { margin: -4px 0 16px; flex-wrap: wrap; }
/* 三档之间加竖分隔线（2026-08-09 老板要求；2026-08-17 老板报丢失后从分支恢复——
   曾在某轮 style.css 整文件贴片中被旧底抹掉）。
   ⚠ 必须收窄到 .ff-mode：.sm-ratio-btn 是共用件，搜推页的「比例 3:4|1:1」、
     买家秀的档位/比例都在用它，不收窄就是给那几处也糊上线。
   ★ 选中态是实心橙块、hover 态有底色，本身已经是分隔——线贴着它们会显脏，
     所以「自己被选中/hover」和「前一个被选中/hover」这两种情况都不画线。 */
.ff-mode .sm-ratio-btn + .sm-ratio-btn { position: relative; }
.ff-mode .sm-ratio-btn + .sm-ratio-btn::before {
  content: ""; position: absolute; left: -2px; top: 50%; transform: translateY(-50%);
  width: 1px; height: 15px; background: var(--border); pointer-events: none;
  transition: opacity .15s;
}
.ff-mode .sm-ratio-btn.on::before,
.ff-mode .sm-ratio-btn:hover::before,
.ff-mode .sm-ratio-btn.on + .sm-ratio-btn::before,
.ff-mode .sm-ratio-btn:hover + .sm-ratio-btn::before { opacity: 0; }
.ctr-slot { display: flex; flex-direction: column; align-items: center; gap: 4px; }
.ctr-slot-lbl { font-size: 12px; color: var(--fg); opacity: .55; }
/* ===== 换装·提交流精简（2026-07-31）：张级详情面板 + 抽屉丝滑件 ===== */
/* 张级详情停靠在批量任务抽屉右侧（fz-batch-side 是 left:94/width:328 的 fixed 板） */
.ty-batch-detail{left:432px;width:356px;z-index:41}
.ty-detail-grid{flex:1;overflow-y:auto;display:grid;grid-template-columns:1fr 1fr;gap:10px;align-content:start}
.ty-detail-grid .fz-batch-empty{grid-column:1/-1}
.ty-card{position:relative;aspect-ratio:3/4;border-radius:10px;overflow:hidden;border:1px solid var(--border);background:rgba(255,255,255,.03)}
.ty-card img{width:100%;height:100%;object-fit:cover;display:block}
.ty-card-ph{position:absolute;inset:0;display:grid;place-items:center}
.ty-card-st{position:absolute;left:7px;bottom:7px;font-size:10px;font-weight: 650;background:rgba(0,0,0,.55);color:#eee;border-radius:999px;padding:3px 9px;max-width:calc(100% - 14px);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ty-card.done .ty-card-st{color:#86efac}
.ty-card.failed .ty-card-st{color:#fca5a5}
.ty-card-regen{position:absolute;inset:0;display:grid;place-items:center;background:rgba(0,0,0,.45);border:none;cursor:pointer;opacity:0;transition: opacity .15s}
.ty-card:hover .ty-card-regen, .ty-card-regen:focus-visible{opacity:1}
.ty-card-regen i{font-style:normal;font-size: 12px;font-weight: 650;color:#fff;background:rgba(0,0,0,.65);border:1px solid rgba(255,255,255,.35);border-radius:999px;padding:6px 13px}
.ty-card-regen:hover i{border-color:var(--accent);color:var(--accent)}
.ty-card-regen:disabled{cursor:default}
/* 「行可点」已经写在公共件 .fz-task-row 里（cursor:pointer），换装这边原来那条同名规则
   是抽屉时代的重复品，2026-08-10 并面板时一起删了。
   下面两条状态色是换装线独有的（.live/.stopped 只有换装的行会带），
   五扇并一扇之后没有别的线会撞上它们，作用域跟着降到公共件层 —— 同 .configured/.skipped 的先例。 */
/* 2026-08-09 老板：「我点了款2，为什么款1外面还有红色的线框？」
   查出来是量化的：live（正在出图）描边 0.5，比 sel（当前展示）的 0.35 还重 ——
   「在跑」比「在看」还抢眼，看着就像那条被选中了。
   拆开两个通道：**「框」只留给「当前展示的那一条」**（复用视频线早就在用的 .fz-task-row.on：
   左侧 3px 竖条 + 淡 ring，比描边明确得多）；运行状态改成只留一层很淡的暖色底，
   状态本身由「出图中 0/2」和上方进度条表达，不需要再包一个框（老板：运行状态要留，但别抢）。
   换装这边索性直接用 .on 同一个类，两条线共用一条规则，样式不可能再各飘各的。 */
.fz-task-row.live{background:rgba(247,107,28,.06)}
.fz-task-row.stopped{opacity:.55}
/* 整批收束 CTA（绿=完成庆祝；stopped=红条说清完成几款、没多扣） */
.ty-batch-cta{display:flex;align-items:center;gap:8px;padding:9px 12px;font-size:12px;color:#86efac;background:rgba(34,197,94,.09);border:1px solid rgba(34,197,94,.25);border-radius:9px}
.ty-batch-cta.stopped{color:#fca5a5;background:rgba(239,68,68,.08);border-color:rgba(239,68,68,.22)}
.ty-batch-cta button{font-size: 12px;font-weight: 650;color:var(--fg);background:rgba(255,255,255,.06);border:1px solid var(--border-strong);border-radius:999px;padding:4px 11px;cursor:pointer;white-space:nowrap}
.ty-batch-cta button:first-of-type{margin-left:auto}   /* 两颗按钮时只推第一颗：一起靠右排 */
.ty-batch-cta button:hover{border-color:var(--accent-ring);color:var(--accent)}
/* 整批结果大页（复用裂变 fz-breview 皮）：款头缩略 + 「再跑一批」 */
.ty-result{padding:18px 20px 24px;background:var(--card);border:1px solid var(--border);border-radius:18px}   /* A 版卡片化 */
.ty-result .fz-breview-grid{grid-template-columns:repeat(auto-fill,minmax(440px,1fr))}   /* A 版：360→440 对图放大；⚠只锁 .ty-result 域内，裂变确认页共用这皮、不动它 */
.ty-breview-prod{display:flex;align-items:center;gap:10px;min-width:0}
.ty-breview-prod img{flex:none;width:46px;height:46px;object-fit:cover;border-radius:8px;border:1px solid var(--border);background:rgba(255,255,255,.08)}
.ty-result-again{flex:none;padding:7px 12px;border:1px solid rgba(247,107,28,.5);border-radius:999px;background:rgba(247,107,28,.12);color:#f9a76b;font-family:inherit;font-size:12px;font-weight: 650;cursor:pointer}
.ty-result-again:hover{background:rgba(247,107,28,.22)}
/* 结果墙工具栏的中性钮（2026-08-19 老板选 B 方案「全中性、最克制」）。
   起因：换装那一栏三颗钮全是橙的 —— 撞上 08-05 立的红线「不用选择的就不要加颜色，
   橙色只留给已选中的值和主操作」。三块橙并排＝三个主操作，一眼看不出该点哪个。
   ⚠ 不动 .ty-result-again 本身：改比例/SKU 那栏 5 颗还在用它，改了会连坐。
   尺寸/圆角/字号字重与橙钮完全一致 —— 老板红线「一屏里控件高度必须成档」。 */
.ty-result-ghost{flex:none;display:inline-flex;align-items:center;gap:5px;
  padding:7px 12px;border:1px solid rgba(255,255,255,.16);border-radius:999px;
  background:transparent;color:#c6c6ce;font-family:inherit;font-size:12px;font-weight:650;cursor:pointer}
.ty-result-ghost:hover{background:rgba(255,255,255,.06);border-color:rgba(255,255,255,.28)}
.ty-result-ghost:disabled{opacity:.5;cursor:default}
/* 工具栏里的图标：跟 12px 字号配 14px 更稳（svg.lucide 默认 1em＝12px，偏小看不清） */
.fz-breview-toolbar svg.lucide{width:14px;height:14px}
/* 悬停层双按钮（重发 + 提示词改图）：只作用换装结果页，裂变的单按钮布局不动 */
.ty-result .fz-breview-copy-hover{gap:8px;flex-wrap:wrap;padding:0 8px}
/* 提交成功表单淡出一拍再清（硬切太生，学裂变「有任务输入区收起」） */
.ty-draft-fade{transition: opacity .15s}
.ty-draft-fade.ty-draft-fading{opacity:0}
/* 窄屏：抽屉本来就变底部抽屉，详情盖在它上面（z 更高），点 × 就回到抽屉 */
@media (max-width:1000px){
  .ty-batch-detail{z-index:43}
}
/* 系统开了「减弱动态效果」时的全局兜底：装饰动画（衣架漂浮/星星闪烁/logo 脉冲/滑入淡入）全停。
   例外——转圈和进度条是「还在跑」的唯一信号，停了会被当成卡死，所以保留循环、只放慢。 */
@media (prefers-reduced-motion: reduce){
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-delay: 0s !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
  .spinner, .fz-spin, .video-status-spinner,
  .indeterminate-bar::after, .vb-stage.cur .vb-seg {
    animation-duration: 1.6s !important;
    animation-iteration-count: infinite !important;
  }
  .ty-draft-fade, .ty-card-regen { transition: none }
}

/* ===== 平铺图转模特（底部栏胶囊版，2026-08-05 老板要求与设置胶囊同排同款） =====
   button 复用 jm-pill 视觉,补齐 UA 默认样式重置;常显置灰由 :disabled 承担 */
.vb-flatlay-pill { font: inherit; cursor: pointer; }
.vb-flatlay-pill:disabled { opacity: .45; cursor: default; }
.vb-flatlay-pill .spinner { width: 12px; height: 12px; }

/* ===== 转模特 · 参考图与要求 modal（2026-08-08 老板拍板：可选参考图+一句要求）=====
   壳子复用 modal-backdrop/modal-panel/modal-compact 那套收敛件，这里只补内部三块。 */
.fr-hint { color: var(--muted); font-size: 12px; line-height: 1.6; margin-bottom: 14px; }
.fr-label { display: block; font-size: 12px; color: var(--fg); margin: 0 0 6px; }
.fr-opt { color: var(--muted); font-size: 11px; margin-left: 6px; }
.fr-drop { padding: 18px 12px; display: block; }
.fr-thumb-wrap { display: flex; align-items: center; gap: 10px; }
.fr-thumb {
  width: 72px; height: 96px; object-fit: cover; border-radius: var(--radius);
  border: 1px solid var(--border); background: var(--card);
}
.fr-prompt { width: 100%; margin-bottom: 2px; resize: vertical; }
.fr-ref { margin-bottom: 14px; }


/* ===== SKU搜索图二期回填（2026-08-17）：结果页每格底下的色名 + 标题条 =====
   ⛔ 这一段绝不要写 display:none / opacity:0 / visibility:hidden ——
      2026-08-16 撞过「按钮渲染出来了但永远看不见」，bug 整个活在 CSS 里，
      只读 js/html 的测试一条都抓不到。app_sku_backfill.test.js 有一条专门守它。 */
.sku-cell-meta { padding: 6px 4px 2px; display: flex; flex-direction: column; gap: 4px; }
.sku-cell-color { font-size: 12px; color: var(--muted); line-height: 1.3; word-break: break-all; }
.sku-cell-title {
  width: 100%; box-sizing: border-box; font-size: 12px; padding: 6px 8px;
  background: var(--surface-ctl); color: var(--fg);
  border: 1px solid var(--border); border-radius: var(--radius-ctl);
}
.sku-cell-title:focus { outline: none; border-color: var(--accent); }
.sku-cell-short { font-size: 11px; color: #d4772a; }
/* 这颗按钮跟着 .ty-result-again 的皮走，这里只补自己的间距 */
.sku-backfill-btn { margin-left: 4px; }
.sku-backfill-note { font-size: 12px; color: var(--muted); margin-left: 8px; }


/* —— 换装「模特组」（2026-08-19）：胶囊下拉空态 + 管理浮层 —— */
.dd-mg-empty { padding: 14px 12px; color: var(--muted); font-size: 12px; line-height: 1.7; text-align: center; }
.dd-mg-manage { border-top: 1px solid var(--border); margin-top: 4px; color: var(--accent); }
.mg-panel { width: min(760px, 92vw); }
.mg-body { display: flex; gap: 14px; min-height: 340px; }
.mg-side { width: 190px; flex: none; display: flex; flex-direction: column; gap: 6px; border-right: 1px solid var(--border); padding-right: 12px; overflow-y: auto; }
.mg-new { display: flex; gap: 6px; }
.mg-new input { flex: 1; min-width: 0; }
/* 浮层里两处文本框走站内深色（不写这条会掉到浏览器默认白底，跟全站风格打架） */
.mg-new input, .mg-name-row input {
  background: var(--card); border: 1px solid var(--border); border-radius: 8px;
  color: var(--fg); padding: 6px 10px; font-size: 13px; outline: none;
}
.mg-new input:focus, .mg-name-row input:focus { border-color: var(--accent); }
.mg-side-item { display: flex; justify-content: space-between; align-items: center; gap: 8px; padding: 7px 10px; border-radius: 8px; background: transparent; border: 1px solid transparent; color: inherit; cursor: pointer; text-align: left; }
/* 组名旁的首图缩略（下拉与浮层左列共用）：一眼认出是哪批模特（老板 08-19 点名） */
.mg-thumb { width: 30px; height: 38px; border-radius: 6px; object-fit: cover; flex: none; background: var(--card); display: inline-block; }
.mg-thumb-empty { border: 1px dashed var(--border-strong); }
.mg-opt-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; text-align: left; }
.mg-side-item:hover { background: var(--card-hover); }
.mg-side-item.on { border-color: var(--accent); background: rgba(247, 107, 28, 0.08); }
.mg-empty, .mg-main-empty { color: var(--muted); font-size: 12px; padding: 18px 8px; text-align: center; }
.mg-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 10px; }
.mg-main-empty { display: flex; align-items: center; justify-content: center; }
.mg-name-row { display: flex; gap: 8px; align-items: center; }
.mg-name-row input { flex: 1; min-width: 0; }
.mg-del { color: #e66; background: transparent; border: 1px solid rgba(230, 102, 102, 0.4); border-radius: 8px; padding: 5px 10px; cursor: pointer; }
.mg-del:hover { background: rgba(230, 102, 102, 0.12); }
.mg-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; overflow-y: auto; max-height: 46vh; padding: 2px; }
.mg-cell { position: relative; aspect-ratio: 3 / 4; border-radius: 8px; overflow: hidden; background: var(--card); }
.mg-cell img { width: 100%; height: 100%; object-fit: cover; display: block; }
.mg-cell-x { position: absolute; top: 4px; right: 4px; width: 20px; height: 20px; line-height: 18px; border-radius: 50%; border: none; background: rgba(0, 0, 0, 0.55); color: #fff; cursor: pointer; font-size: 13px; }
.mg-cell-x:hover { background: rgba(220, 60, 60, 0.9); }
.mg-add { aspect-ratio: 3 / 4; border: 1px dashed var(--border-strong); border-radius: 8px; background: transparent; color: var(--muted); cursor: pointer; font-size: 13px; }
.mg-add:hover { border-color: var(--accent); color: var(--accent); }
.mg-add:disabled { opacity: 0.6; cursor: default; }
.mg-hint { color: var(--muted); font-size: 12px; margin: 0; }
/* ===== 买家秀 → 商详种草（2026-08-19）。全部收在 .seed-* 类下，不碰通配选择器 ===== */
.seed-sync-ask { display: flex; align-items: center; gap: 8px; justify-content: flex-end; margin: -4px 2px 12px; flex-wrap: wrap; }
.seed-ask-hint { color: var(--text-2, #aaa); font-size: 13px; }
/* 胶囊输入框（ffr-save-name 同款配方，08-18 老板终稿）：这个语境吃不到 jm-input 的边框底色，
   全部显式写；min-* 清零防全局 .jm-input 家族 min-width:280/min-height:110 类规则（v273 血训） */
.seed-ask-input { flex: 0 0 260px; width: 260px; height: 34px; box-sizing: border-box; margin: 0;
  min-width: 0; min-height: 0;
  background: rgba(255, 255, 255, .05); border: 1px solid rgba(255, 255, 255, .14);
  border-radius: 999px; padding: 6px 12px; font-size: 13px; color: var(--fg); }
.seed-ask-input::placeholder { color: rgba(255, 255, 255, .35); }
.seed-ask-input:focus { outline: none; border-color: var(--accent-ring); }
.seed-ask-err { flex: 0 0 100%; text-align: right; color: #e5684f; }
.seed-sync-prog { color: var(--muted, #9a9aa2); font-size: 12px; white-space: nowrap; }
.seed-sync-prog.ok { color: #4caf7d; }
.seed-sync-prog.fail { color: #e5684f; }
.seed-synced-badge { color: #4caf7d; font-size: 12px; border: 1px solid #2e5c44; border-radius: 10px; padding: 1px 8px; white-space: nowrap; }
/* 覆盖层：.ff-task-cell 本就 position:relative（style.css:4211），零共享改动 */
.seed-pick-overlay { position: absolute; inset: 0; cursor: pointer; border: 2px solid transparent; border-radius: 10px; background: rgba(0,0,0,.28); z-index: 3; }
.seed-pick-overlay.on { border-color: #ff7a2f; background: rgba(0,0,0,.06); }
.seed-pick-mark { position: absolute; top: 6px; right: 6px; width: 22px; height: 22px; line-height: 22px; text-align: center; border-radius: 50%; background: rgba(255,255,255,.25); color: #fff; font-size: 14px; }
.seed-pick-overlay.on .seed-pick-mark { background: #ff7a2f; }

/* ===== 自由创作 / 复刻爆款 → 淘宝素材测试（v5.4.59） ===== */
.material-test-ask { display:flex; align-items:center; gap:8px; justify-content:flex-end; margin:-4px 2px 12px; flex-wrap:wrap; }
.material-test-hint { color:var(--text-2, #aaa); font-size:13px; }
.material-test-input { flex:0 0 270px; width:270px; height:34px; box-sizing:border-box; margin:0; min-width:0; min-height:0;
  background:rgba(255,255,255,.05); border:1px solid rgba(255,255,255,.14); border-radius:999px;
  padding:6px 12px; font-size:13px; color:var(--fg); }
.material-test-input::placeholder { color:rgba(255,255,255,.35); }
.material-test-input:focus { outline:none; border-color:var(--accent-ring); }
.material-test-error { flex:0 0 100%; text-align:right; color:#e5684f; }
.material-test-status { flex:0 0 100%; text-align:right; color:var(--muted, #9a9aa2); font-size:12px; }
.material-test-status.ok { color:#4caf7d; }
.material-test-status.fail { color:#e5684f; }
.material-test-overlay { position:absolute; inset:0; cursor:pointer; border:2px solid transparent; border-radius:10px; background:rgba(0,0,0,.28); z-index:4; }
.material-test-overlay.on { border-color:#ff7a2f; background:rgba(0,0,0,.06); }
.material-test-mark { position:absolute; top:6px; right:6px; width:22px; height:22px; line-height:22px; text-align:center;
  border-radius:50%; background:rgba(255,255,255,.25); color:#fff; font-size:14px; }
.material-test-overlay.on .material-test-mark { background:#ff7a2f; }
